From 06c11d009693a2eee4bad2a058609493ecd3ca76 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 21 Nov 2018 00:32:14 +0100 Subject: [PATCH] WIP: Deep region XOR implemented. --- src/db/db/dbDeepRegion.cc | 98 +++++++++++++++++-------- src/db/db/dbDeepRegion.h | 2 + src/db/unit_tests/dbDeepRegionTests.cc | 47 ++++++++++++ testdata/algo/deep_region_au5.gds | Bin 0 -> 5066 bytes 4 files changed, 118 insertions(+), 29 deletions(-) create mode 100644 testdata/algo/deep_region_au5.gds diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 735cd41c0..1210f81b1 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -325,7 +325,7 @@ DeepRegion::not_with (const Region &other) const // Nothing to do return new EmptyRegion (); - } else if (other.empty () && ! strict_handling ()) { + } else if (other.empty ()) { // Nothing to do return clone (); @@ -356,6 +356,73 @@ DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op) const return dl_out; } +RegionDelegate * +DeepRegion::xor_with (const Region &other) const +{ + const DeepRegion *other_deep = dynamic_cast (other.delegate ()); + + if (empty ()) { + + // Nothing to do + return other.delegate ()->clone (); + + } else if (other.empty ()) { + + // Nothing to do + return clone (); + + } else if (! other_deep) { + + return AsIfFlatRegion::xor_with (other); + + } else { + + // Implement XOR as (A-B)+(B-A) - only this implementation + // is compatible with the local processor scheme + DeepLayer n1 (and_or_not_with (other_deep, false)); + DeepLayer n2 (other_deep->and_or_not_with (this, false)); + + std::auto_ptr r (new DeepRegion (n1)); + r->add_from (n2); + return r.release (); + + } +} + +void +DeepRegion::add_from (const DeepLayer &dl) +{ + if (dl.layout () == deep_layer ().layout ()) { + + // intra-layout merge + + deep_layer ().layout ()->copy_layer (dl.layer (), deep_layer ().layer ()); + + } else { + + // inter-layout merge + + db::cell_index_type into_cell = deep_layer ().initial_cell ()->cell_index (); + db::Layout *into_layout = deep_layer ().layout (); + db::cell_index_type source_cell = dl.initial_cell ()->cell_index (); + const db::Layout *source_layout = dl.layout (); + + db::CellMapping cm; + cm.create_from_geometry_full (*into_layout, into_cell, *source_layout, source_cell); + + // Actually copy the shapes + + std::map lm; + lm.insert (std::make_pair (dl.layer (), deep_layer ().layer ())); + + std::vector source_cells; + source_cells.push_back (source_cell); + db::copy_shapes (*into_layout, *source_layout, db::ICplxTrans (), source_cells, cm.table (), lm); + + } +} + + RegionDelegate * DeepRegion::add_in_place (const Region &other) { @@ -366,34 +433,7 @@ DeepRegion::add_in_place (const Region &other) const DeepRegion *other_deep = dynamic_cast (other.delegate ()); if (other_deep) { - if (other_deep->deep_layer ().layout () == deep_layer ().layout ()) { - - // intra-layout merge - - deep_layer ().layout ()->copy_layer (other_deep->deep_layer ().layer (), deep_layer ().layer ()); - - } else { - - // inter-layout merge - - db::cell_index_type into_cell = deep_layer ().initial_cell ()->cell_index (); - db::Layout *into_layout = deep_layer ().layout (); - db::cell_index_type source_cell = other_deep->deep_layer ().initial_cell ()->cell_index (); - const db::Layout *source_layout = other_deep->deep_layer ().layout (); - - db::CellMapping cm; - cm.create_from_geometry_full (*into_layout, into_cell, *source_layout, source_cell); - - // Actually copy the shapes - - std::map lm; - lm.insert (std::make_pair (other_deep->deep_layer ().layer (), deep_layer ().layer ())); - - std::vector source_cells; - source_cells.push_back (source_cell); - db::copy_shapes (*into_layout, *source_layout, db::ICplxTrans (), source_cells, cm.table (), lm); - - } + add_from (other_deep->deep_layer ()); } else { diff --git a/src/db/db/dbDeepRegion.h b/src/db/db/dbDeepRegion.h index 9cdd7df97..8f6c8a909 100644 --- a/src/db/db/dbDeepRegion.h +++ b/src/db/db/dbDeepRegion.h @@ -72,6 +72,7 @@ public: virtual RegionDelegate *and_with (const Region &other) const; virtual RegionDelegate *not_with (const Region &other) const; + virtual RegionDelegate *xor_with (const Region &other) const; virtual RegionDelegate *add_in_place (const Region &other); virtual RegionDelegate *add (const Region &other) const; @@ -103,6 +104,7 @@ private: void init (); void ensure_merged_polygons_valid () const; DeepLayer and_or_not_with(const DeepRegion *other, bool and_op) const; + void add_from (const DeepLayer &dl); }; } diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index e1a76ecbb..41b148e58 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -241,3 +241,50 @@ TEST(4_Add) db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au4b.gds"); } } + +TEST(5_BoolXOR) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/deep_region_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; + + unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); + unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0)); + unsigned int l42 = ly.get_layer (db::LayerProperties (42, 0)); + + db::Region r2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss); + db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss); + db::Region r42 (db::RecursiveShapeIterator (ly, top_cell, l42), dss); + db::Region box (db::Box (2000, -1000, 6000, 4000)); + + db::Region r2xor3 = r2 ^ r3; + db::Region r2xorbox = r2 ^ box; + db::Region r2xor42 = r2 ^ r42; + db::Region rboxxor3 = box ^ r3; + db::Region r42xor3 = r42 ^ r3; + db::Region r42xor42 = r42 ^ r42; + + 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)), r2xor3); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r2xorbox); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), r2xor42); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (13, 0)), rboxxor3); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (14, 0)), r42xor3); + target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (15, 0)), r42xor42); + + CHECKPOINT(); + db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au5.gds"); +} + diff --git a/testdata/algo/deep_region_au5.gds b/testdata/algo/deep_region_au5.gds new file mode 100644 index 0000000000000000000000000000000000000000..273f7e03e575db55d41544a223d316edd486e44d GIT binary patch literal 5066 zcmb7{UuczO9LJw?c6@g{J6lWLQN~uQH8q_qbvlOIa&2gvYt5Y@GPeo>FGN8wx=Iih zL6H#HRT&6g1d>;QMCg^_g(V0^Hz`O9FCszMRq1+rzR&l3dCt4e^Hw*00RBO{x0-CZCNa#$GXIUEQjo;Sc)`-1zcQ|L8Y87e1ez zF>R~DzCskuOb<_%jmhPWi5jz}V4|k1t5;cRL$e{C-)QnqMv_d|10NLJmGJu z_WSxP`~PSCdXu_S`6wEjJha2)3dR)HXxEC(b#}6o_Q}{Cz%JB|79Q1zMy;7M#@GyY zPd*7`Sg}TVYMqtLTAmFsf73pzMo*lbN<6q%%S${PVE(3^>Y*q0n(@T5PM+1f_8Iru zIV^MMZT(SC>6XFzf6Un*z)T#2^;h{+Md{H@!k^gdQ@Opi_Of1T$szlJB*oiumOtX?^*iCAGOaS9W$br-_1 zXC8%PFYXP;b|z1KqTb;Bu`5AFKR=8miwGk00PI6~~Vs@RyWp6{UlT z6IA6lru8Qmx1_Jrz6|io>nuo5_jhgNx~`4%ZJQOPr~7-{+uoQS_qI2t?-Koem*}s= ztABxs{`+rmUH=XGhW`|$r`I1XaouQ%zKL;Bdb)q|DA!FMrSH&ZqV#nC;VWEs_zHb* z{U%CJ^K;)v zMd-*cLSKK9aZo<-sSAvY&^LU`b>K=r=7LVDZ%;iJ%j)+>W99uhfqM|Xz_{(YgUx$5$n6JauLSN7R;EDdBi^$ut z%={qq=d4GBA3CYL!TN5#O*^@6(@xIyyv>O@LCghRME%X%Sby_2`GWb~d|S#~x24R! zwzPSoZ|EZOZ+(sVLFilG_rzS#N#zaJck^vu;JWP#oU8kHPs{~fMExD7S$~K9D-8Qm z@z*;4Zob}&T-SS%ef1vqME}r5+f%uFPPuWH#Wj`V^|! z&wS^JxuBEE8?5i9vi1zkk_BiC5}$Tj(b`Q3c;i(EIq$iC*k@*i