From 01f2868e5de0049ae47c9df7811fb09640614ae7 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 2 Jul 2023 22:14:13 +0200 Subject: [PATCH] Fixed issue #1407 (clip does not support polygons with holes) --- src/db/db/dbClip.cc | 32 ++++++++++--- src/db/db/dbLayoutUtils.cc | 4 +- testdata/ruby/dbLayoutTests1.rb | 79 +++++++++++++++------------------ 3 files changed, 64 insertions(+), 51 deletions(-) diff --git a/src/db/db/dbClip.cc b/src/db/db/dbClip.cc index d3d7bde90..c57283992 100644 --- a/src/db/db/dbClip.cc +++ b/src/db/db/dbClip.cc @@ -363,7 +363,7 @@ clip_cell (const db::Layout &layout, target_cell.shapes (l).insert (db::PathRef (path, target_layout.shape_repository ())); } - } else if (sh->is_polygon () || sh->is_simple_polygon () || sh->is_path ()) { + } else if (sh->is_simple_polygon () || sh->is_path ()) { db::SimplePolygon poly; @@ -371,17 +371,12 @@ clip_cell (const db::Layout &layout, db::Path path; sh->path (path); poly = path.simple_polygon (); - } else if (sh->is_polygon ()) { - db::Polygon ppoly; - sh->polygon (ppoly); - poly = db::SimplePolygon (ppoly); } else { sh->simple_polygon (poly); } - std::vector clipped_polygons; - if (! poly.box ().inside (clip_box)) { + std::vector clipped_polygons; clip_poly (poly, clip_box, clipped_polygons); for (std::vector ::const_iterator cp = clipped_polygons.begin (); cp != clipped_polygons.end (); ++cp) { if (sh->has_prop_id ()) { @@ -398,6 +393,29 @@ clip_cell (const db::Layout &layout, } } + } else if (sh->is_polygon ()) { + + db::Polygon poly; + sh->polygon (poly); + + if (! poly.box ().inside (clip_box)) { + std::vector clipped_polygons; + clip_poly (poly, clip_box, clipped_polygons); + for (std::vector ::const_iterator cp = clipped_polygons.begin (); cp != clipped_polygons.end (); ++cp) { + if (sh->has_prop_id ()) { + target_cell.shapes (l).insert (db::PolygonRefWithProperties (db::PolygonRef (*cp, target_layout.shape_repository ()), sh->prop_id ())); + } else { + target_cell.shapes (l).insert (db::PolygonRef (*cp, target_layout.shape_repository ())); + } + } + } else { + if (sh->has_prop_id ()) { + target_cell.shapes (l).insert (db::PolygonRefWithProperties (db::PolygonRef (poly, target_layout.shape_repository ()), sh->prop_id ())); + } else { + target_cell.shapes (l).insert (db::PolygonRef (poly, target_layout.shape_repository ())); + } + } + } else if (sh->is_text ()) { if (sh->bbox ().inside (clip_box)) { diff --git a/src/db/db/dbLayoutUtils.cc b/src/db/db/dbLayoutUtils.cc index 0e7faf14a..c3ec9efc2 100644 --- a/src/db/db/dbLayoutUtils.cc +++ b/src/db/db/dbLayoutUtils.cc @@ -234,7 +234,7 @@ merge_layouts (db::Layout &target, // provide the property mapper db::PropertyMapper pm (&target, &source); - tl::RelativeProgress progress (tl::to_string (tr ("Merge cells")), all_cells_to_copy.size (), 1); + tl::RelativeProgress progress (tl::to_string (tr ("Merge layouts")), all_cells_to_copy.size (), 1); // actually to the mapping for (std::set::const_iterator c = all_cells_to_copy.begin (); c != all_cells_to_copy.end (); ++c) { @@ -346,7 +346,7 @@ copy_or_move_shapes (db::Layout &target, // provide the property mapper db::PropertyMapper pm (&target, &source); - tl::RelativeProgress progress (tl::to_string (tr ("Merge cells")), all_cells_to_copy.size () * layer_mapping.size (), 1); + tl::RelativeProgress progress (tl::to_string (tr ("Copy shapes")), all_cells_to_copy.size () * layer_mapping.size (), 1); // and copy for (std::set::const_iterator c = all_cells_to_copy.begin (); c != all_cells_to_copy.end (); ++c) { diff --git a/testdata/ruby/dbLayoutTests1.rb b/testdata/ruby/dbLayoutTests1.rb index c6734efb3..fa7c0ebe6 100644 --- a/testdata/ruby/dbLayoutTests1.rb +++ b/testdata/ruby/dbLayoutTests1.rb @@ -25,6 +25,29 @@ load("test_prologue.rb") class DBLayoutTests1_TestClass < TestBase + def dump_layer(l, layer, cell_name) + s = [] + cell_index = l.cell_by_name(cell_name) + iter = l.begin_shapes(cell_index, layer) + while !iter.at_end + poly = iter.shape.polygon.transformed(iter.trans) + s.push(poly.is_box? ? poly.bbox.to_s : poly.to_s) + iter.next + end + return s.join("; ") + end + + def dump_layer_i(l, layer, cell_index) + s = [] + iter = l.begin_shapes(cell_index, layer) + while !iter.at_end + poly = iter.shape.polygon.transformed(iter.trans) + s.push(poly.is_box? ? poly.bbox.to_s : poly.to_s) + iter.next + end + return s.join("; ") + end + def test_1 # LayerInfo tests @@ -659,27 +682,6 @@ class DBLayoutTests1_TestClass < TestBase c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) - def dump_layer(l, layer, cell_name) - s = [] - cell_index = l.cell_by_name(cell_name) - iter = l.begin_shapes(cell_index, layer) - while !iter.at_end - s.push(iter.shape.box.transformed(iter.trans).to_s) - iter.next - end - return s.join("; ") - end - - def dump_layer_i(l, layer, cell_index) - s = [] - iter = l.begin_shapes(cell_index, layer) - while !iter.at_end - s.push(iter.shape.box.transformed(iter.trans).to_s) - iter.next - end - return s.join("; ") - end - assert_equal(dump_layer(l, 0, "c0"), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1100,1100); (1200,0;2200,1100); (-1200,0;-100,1000)") assert_equal(dump_layer(l, 1, "c0"), "") @@ -854,31 +856,11 @@ class DBLayoutTests1_TestClass < TestBase def test_7 - def dump_layer(l, layer, cell_name) - s = [] - cell_index = l.cell_by_name(cell_name) - iter = l.begin_shapes(cell_index, layer) - while !iter.at_end - s.push(iter.shape.box.transformed(iter.trans).to_s) - iter.next - end - return s.join("; ") - end - - def dump_layer_i(l, layer, cell_index) - s = [] - iter = l.begin_shapes(cell_index, layer) - while !iter.at_end - s.push(iter.shape.box.transformed(iter.trans).to_s) - iter.next - end - return s.join("; ") - end - # clip tests l = RBA::Layout.new l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + l.insert_layer_at(1, RBA::LayerInfo.new(2, 0)) c0 = l.cell(l.add_cell("c0")) c1 = l.cell(l.add_cell("c1")) c2 = l.cell(l.add_cell("c2")) @@ -890,14 +872,25 @@ class DBLayoutTests1_TestClass < TestBase c2.shapes(0).insert(b) c3.shapes(0).insert(b) + bh = (RBA::Region.new(RBA::Box.new(0, 100, 1000, 1200)) - RBA::Region.new(RBA::Box.new(100, 200, 900, 1100)))[0] + c0.shapes(1).insert(bh) + c1.shapes(1).insert(bh) + c2.shapes(1).insert(bh) + c3.shapes(1).insert(bh) + tt = RBA::Trans.new c0.insert(RBA::CellInstArray.new(c1.cell_index, tt)) c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100)))) c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1))) c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0)))) + ci = l.clip(c0.cell_index, RBA::Box.new(0, 0, 1000, 1200)) + assert_equal(dump_layer_i(l, 0, ci), "(0,100;1000,1200); (0,100;1000,1200); (100,0;1000,1100)") + assert_equal(dump_layer_i(l, 1, ci), "(0,100;0,1200;1000,1200;1000,100/100,200;900,200;900,1100;100,1100); (0,100;0,1200;1000,1200;1000,100/100,200;900,200;900,1100;100,1100); (100,0;100,1100;1000,1100;1000,1000;200,1000;200,100;1000,100;1000,0)") + ci = l.clip(c0.cell_index, RBA::Box.new(0, 0, 200, 200)) assert_equal(dump_layer_i(l, 0, ci), "(0,100;200,200); (0,100;200,200); (100,0;200,200)") + assert_equal(dump_layer_i(l, 1, ci), "(0,100;200,200); (0,100;200,200); (100,0;200,200)") cic = l.clip(c0, RBA::Box.new(0, 0, 200, 200)) assert_equal(dump_layer_i(l, 0, cic.cell_index), "(0,100;200,200); (0,100;200,200); (100,0;200,200)") @@ -911,6 +904,8 @@ class DBLayoutTests1_TestClass < TestBase ci = l.multi_clip(c0.cell_index, [RBA::Box.new(0, 0, 200, 200),RBA::Box.new(1000, 0, 1300, 200)]) assert_equal(dump_layer_i(l, 0, ci[0]), "(0,100;200,200); (0,100;200,200); (100,0;200,200)") assert_equal(dump_layer_i(l, 0, ci[1]), "(1000,0;1100,200); (1200,0;1300,200)") + assert_equal(dump_layer_i(l, 1, ci[0]), "(0,100;200,200); (0,100;200,200); (100,0;200,200)") + assert_equal(dump_layer_i(l, 1, ci[1]), "(1000,0;1100,200); (1200,0;1300,200)") cic = l.multi_clip(c0, [RBA::Box.new(0, 0, 200, 200),RBA::Box.new(1000, 0, 1300, 200)]) assert_equal(dump_layer_i(l, 0, cic[0].cell_index), "(0,100;200,200); (0,100;200,200); (100,0;200,200)")