From 4edf4ab1f7b59433943672ed79c2e06ed1cadd1f Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 18 Jan 2023 16:22:36 +0100 Subject: [PATCH] WIP: Added support for size with properties --- src/db/db/dbAsIfFlatRegion.cc | 21 +++++++++- src/db/db/dbDeepRegion.cc | 2 + src/db/db/dbLocalOperationUtils.h | 8 ++++ src/db/db/dbShapeProcessor.h | 8 ++++ src/db/unit_tests/dbAsIfFlatRegionTests.cc | 45 +++++++++++++++++++- src/db/unit_tests/dbDeepRegionTests.cc | 46 +++++++++++++++++++++ testdata/algo/deep_region_au44.gds | Bin 0 -> 3328 bytes testdata/algo/flat_region_au44.gds | Bin 0 -> 3594 bytes 8 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 testdata/algo/deep_region_au44.gds create mode 100644 testdata/algo/flat_region_au44.gds 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 0000000000000000000000000000000000000000..7d8f7ed62181006cf52e1407c0949d39933dd54c GIT binary patch literal 3328 zcmd6qO=w(I6vxlJnR$84S0>}kWLl#Jsl|RknovxH5=bcGM?fh-N+?~4bR}Jg6e%u5 z3WA8MB3h(KQ5PaEigY0^i-<^(;-W|q5fm3v#D$1B{{Qd1|GRI7q?3gU1CL*Na_+h3 z>z;dSu|?5In=3_AKU>K<);6<;ioaVD#T!qon{~_8)wS1`pSu3xokx#fTe$r0)~3x> zcV1VEJtJ`qF8$Xula* zzhG9|3X~j-4@HP8J{%ui8nM+a`qDp+wVUt(>0^PCgSoB6IM$JF>Brqq`lcyw?|43%zYcHfo!M!Q27xtzJd>It>gP3P;xN0 zr8uWhuDf($!Y*8d+3k9eJ(GOpy+eN)zbH9a%*RL%+eP#sa!A&`@Z5@$gSpRR@vDc@ z`2VLpxX~^ThyR?#*C26_ub7p82`uBRv@4KhWRLdFdyn?cYaO|}Jp8Bqj+s*b)n`lh zRW!G z^=qDIau$1YFL4Grp=DNRWMcD!Ky%iTGNu^@{0z>_FlmGw# literal 0 HcmV?d00001 diff --git a/testdata/algo/flat_region_au44.gds b/testdata/algo/flat_region_au44.gds new file mode 100644 index 0000000000000000000000000000000000000000..2484aecb1fcbff4b3b681388c2f4c6bfaf49f87d GIT binary patch literal 3594 zcmbW4PiS0K6vn?yW?qs>GMS{An6{H9O>2`TA%DhbTPRXX5UoK=$)c1lg19KfMG=uM zintI#5s@M;Y8ORBU5IocQpA-==|V)Llv0X_6m?NVq!cOD_?>s&_x?hedw?_0Vwcj3Kb zE2x+L!!HO{o;eH@JAt6L!017x0APQ$9T@u#s1}{OPXG_z0>s)duy7s_wT=v?!#Fd+ z!X6a+*Tb4~SYv#<80; z&%|!K<9ZwWE&!#|32ncwRo~ZW_YfA#iQT;djD7$ZcTBpkI8o*Oo&ZFxBiF_5 z@;X%PV7pagXCEu3{a5U?%ISH9W&W9;RJ1DC#2X<0N5tTO>uP-DqSv9w8ebQ&GkeCc zo=r>B&^W>vR*$0WWV#-eBmLLb{#r8KoYTi$KT&q-nd8sBuK@jjI;}3OPDI(s4dr4A zcQ8q#-P_>dgtC)ytel#Q``pfA_0*s~c1xn{WL~Ut)Ei-}uCM(}#^LkK_nm}x*64X! zql`aiC?;M6jC0hx!r!9oWUjxhFMR2KJ-58iMcK(Xm!^KnoTXCb%-G3Tkyh_EYBjVM5u-T>r{JcJ&eZkv&gS^Y;_VPR6-3X`VSt?+?`c3+6*EzQH_B zCX}6Q6)V(y^cpq)o->c!eU6$lrdT^f&EKWw5w(ttV>f9&nAW^_(d)su?X=gMXmt`j zPivO)Ut7C>1{hy;S}j>^in5QdW;B=oahtH4=mXY_v2>GjWGSJ|lI}}BYmD};o1#tZ zXZ>yEexl-#aqdlbq`gC3+h)9vjW&BMSJ7r%dD3T`(fU1FzoFPRgY123Wd5PAIC0(2 zENUIuD)zEzX5S3TUH@<7_a_pYnIOII`?_D{39tDt0`tEjPQT#ua~Si?XM4ZaQZz(-SZA zjNh^z$dR9Xj)=08>7GdWvlrNl<9D6YZ?PwS14P-!@BXWQ*b@VPuqW;T#?s^LiGhRz zjMx1dpG6$H!Prw=6VYboR_-S%4jJp%)Dt>;ct^Ire9ZT^Sz;Q9n;ZU2)H-rQv2Fe6 z3m${{hdGK9oVoqa@|_t`>&RBIy(f;aC;s;Ny_a)x%U6K7aFX@#Gyg+Gw0Yb$>+{$s zKeE+c-V@Y6;2w4l)pM-rLkVRk<5)Sh<~