diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index 569200acb..82bd453b1 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -1278,11 +1278,13 @@ AsIfFlatRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const // Generic case std::unique_ptr new_region (new FlatRegion ()); + db::PropertyMapper pm (new_region->properties_repository (), properties_repository ()); db::ShapeGenerator pc (new_region->raw_polygons (), false); db::PolygonGenerator pg (pc, false, true); db::SizingPolygonFilter sf (pg, dx, dy, mode); for (RegionIterator p (begin ()); ! p.at_end (); ++p) { + pc.set_prop_id (pm (p.prop_id ())); sf.put (*p); } @@ -1296,6 +1298,10 @@ AsIfFlatRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const } else { + std::unique_ptr new_region (new FlatRegion ()); + +// old implementation without property support +#if 0 // Generic case - the size operation will merge first db::EdgeProcessor ep (report_progress (), progress_desc ()); ep.set_base_verbosity (base_verbosity ()); @@ -1313,13 +1319,26 @@ AsIfFlatRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const ep.insert (*p, n); } - std::unique_ptr new_region (new FlatRegion ()); db::ShapeGenerator pc (new_region->raw_polygons (), true /*clear*/); db::PolygonGenerator pg2 (pc, false /*don't resolve holes*/, true /*min. coherence*/); db::SizingPolygonFilter siz (pg2, dx, dy, mode); db::PolygonGenerator pg (siz, false /*don't resolve holes*/, min_coherence () /*min. coherence*/); db::BooleanOp op (db::BooleanOp::Or); ep.process (pg, op); +#else + + // Generic case + db::PropertyMapper pm (new_region->properties_repository (), properties_repository ()); + + db::ShapeGenerator pc (new_region->raw_polygons (), false); + db::PolygonGenerator pg (pc, false, true); + db::SizingPolygonFilter sf (pg, dx, dy, mode); + for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p) { + pc.set_prop_id (pm (p.prop_id ())); + sf.put (*p); + } + +#endif // in case of negative sizing the output polygons will still be merged (on positive sizing they might // overlap after size and are not necessarily merged) diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 959ffe916..5d74f8dd6 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -1616,6 +1616,7 @@ DeepRegion::sized (coord_type d, unsigned int mode) const db::SizingPolygonFilter siz (pg2, d_with_mag, d_with_mag, mode); for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { + pr.set_prop_id (si->prop_id ()); db::Polygon poly; si->polygon (poly); siz.put (poly); @@ -1678,6 +1679,7 @@ DeepRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const db::SizingPolygonFilter siz (pg2, dx_with_mag, dy_with_mag, mode); for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) { + pr.set_prop_id (si->prop_id ()); db::Polygon poly; si->polygon (poly); siz.put (poly); diff --git a/src/db/db/dbLocalOperationUtils.h b/src/db/db/dbLocalOperationUtils.h index 436a856bc..e18d975f8 100644 --- a/src/db/db/dbLocalOperationUtils.h +++ b/src/db/db/dbLocalOperationUtils.h @@ -247,6 +247,14 @@ public: */ PolygonRefToShapesGenerator (db::Layout *layout, db::Shapes *shapes, db::properties_id_type prop_id = 0); + /** + * @brief Sets the property ID to be used for the next polygon + */ + void set_prop_id (db::properties_id_type prop_id) + { + m_prop_id = prop_id; + } + /** * @brief Implementation of the PolygonSink interface */ diff --git a/src/db/db/dbShapeProcessor.h b/src/db/db/dbShapeProcessor.h index a5aa2cc4b..95f939ab0 100644 --- a/src/db/db/dbShapeProcessor.h +++ b/src/db/db/dbShapeProcessor.h @@ -64,6 +64,14 @@ public: : PolygonSink (), mp_shapes (&shapes), m_clear_shapes (clear_shapes), m_prop_id (prop_id) { } + /** + * @brief Sets the properties ID to be used for the next polygon + */ + void set_prop_id (db::properties_id_type prop_id) + { + m_prop_id = prop_id; + } + /** * @brief Implementation of the PolygonSink interface */ diff --git a/src/db/unit_tests/dbAsIfFlatRegionTests.cc b/src/db/unit_tests/dbAsIfFlatRegionTests.cc index 1f1a443b1..056aabcae 100644 --- a/src/db/unit_tests/dbAsIfFlatRegionTests.cc +++ b/src/db/unit_tests/dbAsIfFlatRegionTests.cc @@ -1733,7 +1733,6 @@ TEST(41_EdgesWithProperties) unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); - unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0)); // empty db::RecursiveShapeIterator si1 (ly, top_cell, l1); si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); @@ -1905,3 +1904,47 @@ TEST(43_ComplexOpsWithProperties) db::compare_layouts (_this, target, tl::testdata () + "/algo/flat_region_au43.gds"); } +TEST(44_SizeWithProperties) +{ + db::Layout ly; + { + std::string fn (tl::testdata ()); + fn += "/algo/deep_region_42.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); + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); + + db::RecursiveShapeIterator si1 (ly, top_cell, l1); + si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + db::Region r1 (si1); + + db::RecursiveShapeIterator si2 (ly, top_cell, l2); + si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + db::Region r2 (si2); + + db::Layout target; + unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); + + db::RegionCheckOptions opt; + opt.metrics = db::Projection; + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (1, 0)), r1); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (2, 0)), r2); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r1.sized (200)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r1.sized (250, 50)); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), r2.sized (200)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (21, 0)), r2.sized (250, 50)); + + CHECKPOINT(); + db::compare_layouts (_this, target, tl::testdata () + "/algo/flat_region_au44.gds"); +} + diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index 5b2abe509..295714c7d 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -2398,6 +2398,52 @@ TEST(43_ComplexOpsWithProperties) db::compare_layouts (_this, target, tl::testdata () + "/algo/deep_region_au43.gds"); } +TEST(44_SizeWithProperties) +{ + db::Layout ly; + { + std::string fn (tl::testdata ()); + fn += "/algo/deep_region_42.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; + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); + + db::RecursiveShapeIterator si1 (ly, top_cell, l1); + si1.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + db::Region r1 (si1, dss); + + db::RecursiveShapeIterator si2 (ly, top_cell, l2); + si2.shape_flags (db::ShapeIterator::All | db::ShapeIterator::RegardProperties); + db::Region r2 (si2, dss); + + db::Layout target; + unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index)); + + db::RegionCheckOptions opt; + opt.metrics = db::Projection; + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (1, 0)), r1); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (2, 0)), r2); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r1.sized (200)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r1.sized (250, 50)); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), r2.sized (200)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (21, 0)), r2.sized (250, 50)); + + CHECKPOINT(); + db::compare_layouts (_this, target, tl::testdata () + "/algo/deep_region_au44.gds"); +} + TEST(100_Integration) { db::Layout ly; diff --git a/testdata/algo/deep_region_au44.gds b/testdata/algo/deep_region_au44.gds new file mode 100644 index 000000000..7d8f7ed62 Binary files /dev/null and b/testdata/algo/deep_region_au44.gds differ diff --git a/testdata/algo/flat_region_au44.gds b/testdata/algo/flat_region_au44.gds new file mode 100644 index 000000000..2484aecb1 Binary files /dev/null and b/testdata/algo/flat_region_au44.gds differ