From 9008464268cec47959c5b2edede9226702a96a96 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 27 Nov 2022 10:26:01 +0100 Subject: [PATCH] WIP: hierarchical mode for Region#in and Region#not_in --- src/db/db/dbDeepRegion.cc | 44 +++++++++++--- src/db/db/dbDeepRegion.h | 1 + src/db/db/dbRegionLocalOperations.cc | 77 +++++++++++++++++++++++++ src/db/db/dbRegionLocalOperations.h | 18 ++++++ src/db/unit_tests/dbDeepRegionTests.cc | 49 ++++++++++++++++ testdata/algo/deep_region_au31.gds | Bin 0 -> 9666 bytes testdata/algo/deep_region_l31.gds | Bin 0 -> 2274 bytes 7 files changed, 182 insertions(+), 7 deletions(-) create mode 100644 testdata/algo/deep_region_au31.gds create mode 100644 testdata/algo/deep_region_l31.gds diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index f38d94228..8d1abf149 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -1550,13 +1550,6 @@ DeepRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const return res.release (); } -RegionDelegate * -DeepRegion::in (const Region &other, bool invert) const -{ - // TODO: this can be optimized maybe ... - return db::AsIfFlatRegion::in (other, invert); -} - template static Output *region_cop_impl (DeepRegion *region, db::CompoundRegionOperationNode &node) @@ -1796,6 +1789,43 @@ private: } +RegionDelegate * +DeepRegion::in (const Region &other, bool invert) const +{ + // TODO: we could offer in_and_not_it (both at once) + InteractingOutputMode output_mode = invert ? Negative : Positive; + return in_and_out (other, output_mode).first; +} + +std::pair +DeepRegion::in_and_out (const Region &other, InteractingOutputMode output_mode) const +{ + std::unique_ptr dr_holder; + const db::DeepRegion *other_deep = dynamic_cast (other.delegate ()); + if (! other_deep) { + // if the other region isn't deep, turn into a top-level only deep region to facilitate re-hierarchization + dr_holder.reset (new db::DeepRegion (other, const_cast (*deep_layer ().store ()))); + other_deep = dr_holder.get (); + } + + const db::DeepLayer &polygons = merged_deep_layer (); + const db::DeepLayer &other_polygons = other_deep->merged_deep_layer (); + + db::ContainedLocalOperation op (output_mode); + + db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell (), polygons.breakout_cells (), other_polygons.breakout_cells ()); + proc.set_description (progress_desc ()); + proc.set_report_progress (report_progress ()); + proc.set_base_verbosity (base_verbosity ()); + proc.set_threads (polygons.store ()->threads ()); + + InteractingResultHolder orh (output_mode, merged_semantics (), polygons); + + proc.run (&op, polygons.layer (), other_polygons.layer (), orh.layers ()); + + return orh.result_pair (); +} + std::pair DeepRegion::selected_interacting_generic (const Region &other, int mode, bool touching, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const { diff --git a/src/db/db/dbDeepRegion.h b/src/db/db/dbDeepRegion.h index 75ea1961d..aec863284 100644 --- a/src/db/db/dbDeepRegion.h +++ b/src/db/db/dbDeepRegion.h @@ -155,6 +155,7 @@ protected: virtual std::pair selected_interacting_generic (const Region &other, int mode, bool touching, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const; virtual std::pair selected_interacting_generic (const Edges &other, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const; virtual std::pair selected_interacting_generic (const Texts &other, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const; + virtual std::pair in_and_out (const Region &other, InteractingOutputMode output_mode) const; virtual RegionDelegate *pull_generic (const Region &other, int mode, bool touching) const; virtual EdgesDelegate *pull_generic (const Edges &other) const; virtual TextsDelegate *pull_generic (const Texts &other) const; diff --git a/src/db/db/dbRegionLocalOperations.cc b/src/db/db/dbRegionLocalOperations.cc index d6aa19b9e..9f42af6c6 100644 --- a/src/db/db/dbRegionLocalOperations.cc +++ b/src/db/db/dbRegionLocalOperations.cc @@ -915,6 +915,83 @@ template class DB_PUBLIC interacting_local_operation +contained_local_operation::contained_local_operation (InteractingOutputMode output_mode) + : m_output_mode (output_mode) +{ + // .. nothing yet .. +} + +template +db::Coord contained_local_operation::dist () const +{ + return 0; +} + +template +void contained_local_operation::do_compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const +{ + if (m_output_mode == None) { + return; + } else if (m_output_mode == Positive || m_output_mode == Negative) { + tl_assert (results.size () == 1); + } else { + tl_assert (results.size () == 2); + } + + db::EdgeProcessor ep; + ep.set_base_verbosity (50); + + std::set others; + for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + for (typename shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { + others.insert (interactions.intruder_shape (*j).second); + } + } + + for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + const TS &subject = interactions.subject_shape (i->first); + if (others.find (subject) != others.end ()) { + if (m_output_mode == Positive || m_output_mode == PositiveAndNegative) { + results [0].insert (subject); + } + } else { + if (m_output_mode == Negative) { + results [0].insert (subject); + } else if (m_output_mode == PositiveAndNegative) { + results [1].insert (subject); + } + } + } +} + +template +OnEmptyIntruderHint +contained_local_operation::on_empty_intruder_hint () const +{ + if (m_output_mode == Positive) { + return OnEmptyIntruderHint::Drop; + } else if (m_output_mode == Negative) { + return OnEmptyIntruderHint::Copy; + } else if (m_output_mode == PositiveAndNegative) { + return OnEmptyIntruderHint::CopyToSecond; + } else { + return OnEmptyIntruderHint::Ignore; + } +} + +template +std::string contained_local_operation::description () const +{ + return tl::to_string (tr ("Select polygons contained in other region")); +} + +// explicit instantiations +template class DB_PUBLIC contained_local_operation; +template class DB_PUBLIC contained_local_operation; + +// --------------------------------------------------------------------------------------------------------------- + template pull_local_operation::pull_local_operation (int mode, bool touching) : m_mode (mode), m_touching (touching) diff --git a/src/db/db/dbRegionLocalOperations.h b/src/db/db/dbRegionLocalOperations.h index 6d81c2b0d..7a457e413 100644 --- a/src/db/db/dbRegionLocalOperations.h +++ b/src/db/db/dbRegionLocalOperations.h @@ -351,6 +351,24 @@ public: typedef pull_with_text_local_operation PullWithTextLocalOperation; +template +class contained_local_operation + : public local_operation +{ +public: + contained_local_operation (InteractingOutputMode output_mode); + + virtual db::Coord dist () const; + virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; + virtual OnEmptyIntruderHint on_empty_intruder_hint () const; + virtual std::string description () const; + +private: + InteractingOutputMode m_output_mode; +}; + +typedef contained_local_operation ContainedLocalOperation; + } // namespace db #endif diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index fb1dfffbc..052a2ccea 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -2018,6 +2018,55 @@ TEST(30c_interact_with_count_text) EXPECT_EQ (r.selected_not_interacting (rr, 3, 4).to_string (), "(0,0;0,200;100,200;100,0)"); } +TEST(31_in) +{ + db::Layout ly; + { + std::string fn (tl::testdata ()); + fn += "/algo/deep_region_l31.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)); + unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0)); + + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss); + db::Region r2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss); + db::Region r1r = r1; + r1r.set_merged_semantics (false); + db::Region r2r = r2; + r2r.set_merged_semantics (false); + + 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 (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)), r2.in (r1)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r2.in (r1, true)); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), r2r.in (r1)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (21, 0)), r2r.in (r1, true)); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (30, 0)), r2.in (r1r)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 0)), r2.in (r1r, true)); + + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (40, 0)), r2r.in (r1r)); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (41, 0)), r2r.in (r1r, true)); + + CHECKPOINT(); + db::compare_layouts (_this, target, tl::testdata () + "/algo/deep_region_au31.gds"); +} + TEST(100_Integration) { db::Layout ly; diff --git a/testdata/algo/deep_region_au31.gds b/testdata/algo/deep_region_au31.gds new file mode 100644 index 0000000000000000000000000000000000000000..f079981bf337bb0c5fb0767823e7d9126e85b843 GIT binary patch literal 9666 zcmb`MKWtT19LIlseZ75@f)84x(psvNv?b3{Q;nEZ)7Cl|n*d3NrW3}6ffxr96C_T= zKqQ8k4n)NeH35?j4h#$q4#YS(I50RkFc2pP1_uWQf8TS?xA*>D?+Q#{FWozN z>+7`@8R?1ZvMf_oy&;nAt4U3={WTGpYj%r_{UP$=eb1@7$iZJk$ksn1$45j+j#JhT zMB-&Xh#b{laQc!+-{YLe^zY$S5t8GSW${{AU-4()icY#LLKga>`d-~1en9B@bw4EA zl~H|bT+ip6o`G_5PUPiNIoYms`d)e3Q&`APtt&i*SFp=xG%{8N9)95eeqMKaf|E-k&)yLs*{+Q053H+pQUu)pkshzEgJiohsz3h7>p|#d`g1}b`lI^pF~5Eg z>&AXatUvTe^{sI~ABeSMeiG{m{ZT#QAJcV$6FMH}N3vZR)#Kct1@Y`KH_3KoQP1ko zX4~{pY-2f$jPDN=Z+4q)SlDdKTA|_;FEYuZwhDFGg8Z zF~`2ueCUSyu@^O$UcFqpXID#5`H^ejOLw&{Y3`D!D^urveE~U6S$2jl9^M_)9&onh zYaNMN1vel$PFWVupd2Q};o#eLMa9pWY2XJx5tN zmlG}#`lIuse?osjoGbJs+m%uM%!jIPYE4nXp|J*%?aHYBy(RC);PjBl`}#~txOC`` z>d))h!9zee`Um<;vc1h)`ieJ?3i8Xut02D^FEzi6J|Vx1KID(fj~(Wh(c|vWGwAOS zjVJzAN3va6e7@AX+CTiWz7xNz=V*Q$()G?b!1f6gL*-- zT^ZFc%=vYIqkoCKt+7bVANtGmZXe5f4$u820%G2?^O~pEL{>L)vR_#i$L-_vvab=~ z;9Ze5T@Q)c5&EP0Px}2nK&<~$tS1or2>oSxw~x>6`+b1e$LCGI{x2`(#6H5fvN&!Z zS4aFlK&*dV*F$0-p}$P;>iEqIUJpX|{YFmQJ8!T1`zMHaVSF^+SIe5CEfH|~p~#Q= ze903Uqd_|E#7Mod5SY9+1~cP8$I45csaOl!@p-F+m+GtNB&|Q2p#g9 zWczmdn+<=b0QaaTfA=US?i!)LIR9Y9zGmW8;A@QM@-yMyWb_HXX7mZZMt!Hg#5nF8 z5`2mJPJM-O+&Y49xO}IdkP%;@zEfXd9Jh{8_uYF#KOiH%Kz&udVB%Ha3ykOXm*5Lq z^sN8%1Cs4+zHq2RUoiRvUoiRvUoiRvUoiUi`{)Z#v`*_U7`cxcJ;zapZz+rS+0b9C z%SNBzOGb}-=HUnazRCM1$#!LQ{^C6r<8hBABllP{e}XR>J?@v759Ga*WVre3I(V{O`;G>M^>PdnR8h!iw(4Nnszj&V1cj|+T zYrYR;B(JIO)JGY|?IXcQjlP)Qd@smIepBD64>OM2M}iMi?|ird-()!HzUN^)x1NOitI;RiKey=l{T$9=2jANneS(i0eS(i0eS(i0eS(h~eS(h} zeS(irU)4R8@iyNNey^~@?;DIh!Ph2>?^gxB#&~W&3BE>sr@q8EZXF4}M17~e!Z>an z3BE#or@p{AZXF4}Kz&udz<6#w3BE8@%-aflf$`jW5`4kv6MSKdewV&r^a;LT^a;LT z^a;LT^zHXqeoo`(wvzj-(Q_Pi?f2o(U%U?+eS$9;eZuFvEqdN}@wsRRpYM!5!557_ r;q%=VJ@2{vTt~8989o05U*`N(`7+~e)~8+iveECxm-YYr>vj1b2Yh2s literal 0 HcmV?d00001 diff --git a/testdata/algo/deep_region_l31.gds b/testdata/algo/deep_region_l31.gds new file mode 100644 index 0000000000000000000000000000000000000000..1c6661453820cac7cd0489128ead06045abd5c0f GIT binary patch literal 2274 zcmbuAF-#Oe6o&uXJN8aE;Q*rqFcLWenDfA(5fe0kG)59Ft{_wx8wz7AOiYX=1tu00 z7A9Iym}qHXL1|&EEi5c8jFkn2g{A+$dp~=U9Vy&o^KIVD|K`n`w{H+5iq)5|wMz1hFAvNyB)a=nGouCOkSW2#COAU+-;Lfjhx zSf~|&vCqKSk13~1z`zHn9pcCndr+n>J*l;tQFd) za8bMLqi01Wp8Ar0pXN@7e*vb)$&>&AuoZ4lyuQJwKz+??DJ&(-umt?=V z#S?r6h(q*MzL(K=NgL>sn zT2W`GwN2Z}PQAOs|JJ4b9Mn+~3)eqfN4ArBaUAGfZ{CY(`=L7gYkkdSZ_Ukv?PPF$ z>0NKGKht*C;SpV+634Aux7i1}*(3*Ic7%Ai05ztr<#kd|RXt&D2Po{MF&)fJMy~Er zw3s*YX#4QUa)79&xUb_BvC&O1FXOd1Riyq$YF|l-}_rhvtFGi;T9DLA`DQ%@d`saUZ7b|I#mh zO>YB{c|>a?qi%`zcyN7|VlZtdgZeuw>1`}Fhk(00 eQ&YEedpxM$WbSl_h`Q15^EGYv-NJvORKg!eQR&M7 literal 0 HcmV?d00001