diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 89201171c..99b5ed41e 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -947,6 +947,7 @@ DeepRegion::holes () const const db::Shapes &s = c->shapes (m_merged_polygons.layer ()); db::Shapes &st = c->shapes (res->deep_layer ().layer ()); + db::PolygonRefToShapesGenerator pr (&layout, &st); for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { for (size_t i = 0; i < si->holes (); ++i) { @@ -956,7 +957,7 @@ DeepRegion::holes () const pts.push_back (*p); } h.assign_hull (pts.begin (), pts.end ()); - st.insert (h); + pr.put (h); } } @@ -979,6 +980,7 @@ DeepRegion::hulls () const const db::Shapes &s = c->shapes (m_merged_polygons.layer ()); db::Shapes &st = c->shapes (res->deep_layer ().layer ()); + db::PolygonRefToShapesGenerator pr (&layout, &st); for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { db::Polygon h; @@ -987,7 +989,7 @@ DeepRegion::hulls () const pts.push_back (*p); } h.assign_hull (pts.begin (), pts.end ()); - st.insert (h); + pr.put (h); } } @@ -1007,20 +1009,32 @@ DeepRegion::rounded_corners (double rinner, double router, unsigned int n) const { ensure_merged_polygons_valid (); - // @@@ scaled instances + db::MagnificationReducer red; + db::cell_variants_collector vars (red); + vars.collect (m_merged_polygons.layout (), m_merged_polygons.initial_cell ()); + + // NOTE: m_merged_polygons is mutable, so why is the const_cast needed? + const_cast (m_merged_polygons).separate_variants (vars); db::Layout &layout = m_merged_polygons.layout (); std::auto_ptr res (new db::DeepRegion (m_merged_polygons.new_layer ())); for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { + const std::map &v = vars.variants (c->cell_index ()); + tl_assert (v.size () == size_t (1)); + double mag = v.begin ()->first.mag (); + db::Coord rinner_with_mag = db::coord_traits::rounded (rinner / mag); + db::Coord router_with_mag = db::coord_traits::rounded (router / mag); + const db::Shapes &s = c->shapes (m_merged_polygons.layer ()); db::Shapes &st = c->shapes (res->deep_layer ().layer ()); + db::PolygonRefToShapesGenerator pr (&layout, &st); for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { db::Polygon poly; si->polygon (poly); - st.insert (db::compute_rounded (poly, rinner, router, n)); + pr.put (db::compute_rounded (poly, rinner_with_mag, router_with_mag, n)); } } @@ -1033,20 +1047,31 @@ DeepRegion::smoothed (coord_type d) const { ensure_merged_polygons_valid (); - // @@@ scaled instances + db::MagnificationReducer red; + db::cell_variants_collector vars (red); + vars.collect (m_merged_polygons.layout (), m_merged_polygons.initial_cell ()); + + // NOTE: m_merged_polygons is mutable, so why is the const_cast needed? + const_cast (m_merged_polygons).separate_variants (vars); db::Layout &layout = m_merged_polygons.layout (); std::auto_ptr res (new db::DeepRegion (m_merged_polygons.new_layer ())); for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { + const std::map &v = vars.variants (c->cell_index ()); + tl_assert (v.size () == size_t (1)); + double mag = v.begin ()->first.mag (); + db::Coord d_with_mag = db::coord_traits::rounded (d / mag); + const db::Shapes &s = c->shapes (m_merged_polygons.layer ()); db::Shapes &st = c->shapes (res->deep_layer ().layer ()); + db::PolygonRefToShapesGenerator pr (&layout, &st); for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { db::Polygon poly; si->polygon (poly); - st.insert (db::smooth (poly, d)); + pr.put (db::smooth (poly, d_with_mag)); } } diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index dcc86b417..8c7ddfb35 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -573,6 +573,82 @@ TEST(9_SizingWithBoolean) db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au9e.gds"); } +TEST(10_HullsAndHoles) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/deep_region_area_peri_l1.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + db::DeepShapeStore dss; + dss.set_max_vertex_count (4); + dss.set_threads (0); + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss); + db::Region r1_sized = r1.sized (2000); + r1_sized -= r1; + + db::Region hulls = r1_sized.hulls (); + db::Region holes = r1_sized.holes (); + + db::Layout target; + unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r1_sized); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), hulls); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), holes); + + CHECKPOINT(); + db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au10.gds"); +} + +TEST(11_RoundAndSmoothed) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/deep_region_area_peri_l1.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + db::DeepShapeStore dss; + dss.set_max_vertex_count (4); + dss.set_threads (0); + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss); + db::Region r1_sized = r1.sized (2000); + r1_sized -= r1; + + db::Region rounded = r1_sized.rounded_corners (3000, 5000, 100); + db::Region smoothed = rounded.smoothed (100); + + db::Layout target; + unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r1_sized); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), rounded); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), smoothed); + + CHECKPOINT(); + db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au11.gds"); +} + TEST(100_Integration) { db::Layout ly; diff --git a/testdata/algo/deep_region_au10.gds b/testdata/algo/deep_region_au10.gds new file mode 100644 index 000000000..b06543d13 Binary files /dev/null and b/testdata/algo/deep_region_au10.gds differ diff --git a/testdata/algo/deep_region_au11.gds b/testdata/algo/deep_region_au11.gds new file mode 100644 index 000000000..978dd07ad Binary files /dev/null and b/testdata/algo/deep_region_au11.gds differ