From 637968cbc4ae1049b6328d2a4148ef2821313e69 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 6 Mar 2021 00:31:05 +0100 Subject: [PATCH] Centering of bounding box in fill tool - this allows using step vectors alone without a boundary layer --- src/db/db/dbFillTool.cc | 79 ++++++++++++++++++--- src/db/unit_tests/dbFillToolTests.cc | 98 +++++++++++++++++++++++++++ src/lay/lay/layFillDialog.cc | 8 +-- testdata/algo/fill_tool_au3.gds | Bin 1740 -> 2228 bytes testdata/algo/fill_tool_au3a.gds | Bin 0 -> 2142 bytes testdata/algo/fill_tool_au3b.gds | Bin 0 -> 2208 bytes testdata/algo/fill_tool_au3c.gds | Bin 0 -> 2056 bytes 7 files changed, 170 insertions(+), 15 deletions(-) create mode 100644 testdata/algo/fill_tool_au3a.gds create mode 100644 testdata/algo/fill_tool_au3b.gds create mode 100644 testdata/algo/fill_tool_au3c.gds diff --git a/src/db/db/dbFillTool.cc b/src/db/db/dbFillTool.cc index a9024b201..5845bde85 100644 --- a/src/db/db/dbFillTool.cc +++ b/src/db/db/dbFillTool.cc @@ -406,6 +406,73 @@ fill_region (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type fill_ce return fill_region (cell, fp0, fill_cell_index, fc_bbox.p1 () - db::Point (), db::Vector (fc_bbox.width (), 0), db::Vector (0, fc_bbox.height ()), origin, enhanced_fill, remaining_parts, fill_margin); } +static db::Polygon +produce_fill_stripe (const db::Vector &row_step, const db::Vector &column_step, long n) +{ + if (column_step.x () == 0) { + + db::Coord ymin = std::min (0, row_step.y ()); + db::Coord ymax = std::max (0, row_step.y ()) + n * column_step.y (); + + return db::Polygon (db::Box (0, ymin, row_step.x (), ymax)); + + } else { + + db::Coord xmin = 0; + db::Coord xmax = row_step.x (); + + db::Coord ymin = 0; + db::Coord ymax = n * column_step.y (); + + std::vector pts; + pts.reserve (n * 2); + + for (long i = 0; i < n; ++i) { + + db::Coord x = xmin + i * column_step.x (); + db::Coord y = i * column_step.y (); + + if (i == 0) { + pts.push_back (db::Point (x, ymin)); + } else { + pts.push_back (db::Point (x, y)); + } + if (i == n - 1) { + pts.push_back (db::Point (x, ymax)); + } else { + pts.push_back (db::Point (x, y + column_step.y ())); + } + + } + + for (long i = n; i > 0; ) { + + --i; + + db::Coord x = xmax + i * column_step.x (); + db::Coord y = i * column_step.y (); + + if (i == n - 1) { + pts.push_back (db::Point (x, ymax)); + } else { + pts.push_back (db::Point (x, y + column_step.y ())); + } + if (i == 0) { + pts.push_back (db::Point (x, ymin)); + } else { + pts.push_back (db::Point (x, y)); + } + + } + + db::Polygon p; + p.assign_hull (pts.begin (), pts.end ()); + return p; + + } +} + + DB_PUBLIC bool fill_region (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type fill_cell_index, const db::Vector &kernel_origin, const db::Vector &row_step, const db::Vector &column_step, const db::Point &origin, bool enhanced_fill, std::vector *remaining_parts, const db::Vector &fill_margin) @@ -502,17 +569,7 @@ fill_region (db::Cell *cell, const db::Polygon &fp0, db::cell_index_type fill_ce cell->insert (array); if (remaining_parts) { - - db::Point fill_stripe[4] = { - db::Point () + p0 + kernel_origin, - db::Point () + p0 + kernel_origin + column_step * long (jj - j), - db::Point () + p0 + kernel_origin + column_step * long (jj - j) + row_step, - db::Point () + p0 + kernel_origin + row_step - }; - - filled_regions.push_back (db::Polygon ()); - filled_regions.back ().assign_hull (fill_stripe, fill_stripe + 4); - + filled_regions.push_back (produce_fill_stripe (row_step, column_step, long (jj - j)).moved (p0 + kernel_origin)); } any_fill = true; diff --git a/src/db/unit_tests/dbFillToolTests.cc b/src/db/unit_tests/dbFillToolTests.cc index de3fa628b..9bade38cf 100644 --- a/src/db/unit_tests/dbFillToolTests.cc +++ b/src/db/unit_tests/dbFillToolTests.cc @@ -115,3 +115,101 @@ TEST(3) db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/fill_tool_au3.gds"); } +TEST(3a) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/fill_tool3.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type fill_cell = ly.cell_by_name ("FILL_CELL").second; + db::cell_index_type top_cell = ly.cell_by_name ("TOP").second; + unsigned int fill_layer = ly.get_layer (db::LayerProperties (1, 0)); + + db::Region fill_region (db::RecursiveShapeIterator (ly, ly.cell (top_cell), fill_layer)); + + db::Region remaining_parts, remaining_polygons; + + db::Vector ko (-100, -130); + db::Vector rs (230, 40); + db::Vector cs (-40, 230); + db::fill_region (&ly.cell (top_cell), fill_region, fill_cell, ko, rs, cs, db::Point (), true, &remaining_parts, db::Vector (50, 100), &remaining_polygons); + + unsigned int l100 = ly.insert_layer (db::LayerProperties (100, 0)); + unsigned int l101 = ly.insert_layer (db::LayerProperties (101, 0)); + remaining_parts.insert_into (&ly, top_cell, l100); + remaining_polygons.insert_into (&ly, top_cell, l101); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/fill_tool_au3a.gds"); +} + +TEST(3b) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/fill_tool3.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type fill_cell = ly.cell_by_name ("FILL_CELL").second; + db::cell_index_type top_cell = ly.cell_by_name ("TOP").second; + unsigned int fill_layer = ly.get_layer (db::LayerProperties (1, 0)); + + db::Region fill_region (db::RecursiveShapeIterator (ly, ly.cell (top_cell), fill_layer)); + + db::Region remaining_parts, remaining_polygons; + + db::Vector ko (-100, -130); + db::Vector rs (230, -40); + db::Vector cs (40, 230); + db::fill_region (&ly.cell (top_cell), fill_region, fill_cell, ko, rs, cs, db::Point (), true, &remaining_parts, db::Vector (50, 100), &remaining_polygons); + + unsigned int l100 = ly.insert_layer (db::LayerProperties (100, 0)); + unsigned int l101 = ly.insert_layer (db::LayerProperties (101, 0)); + remaining_parts.insert_into (&ly, top_cell, l100); + remaining_polygons.insert_into (&ly, top_cell, l101); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/fill_tool_au3b.gds"); +} + +TEST(3c) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/fill_tool3.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type fill_cell = ly.cell_by_name ("FILL_CELL").second; + db::cell_index_type top_cell = ly.cell_by_name ("TOP").second; + unsigned int fill_layer = ly.get_layer (db::LayerProperties (1, 0)); + + db::Region fill_region (db::RecursiveShapeIterator (ly, ly.cell (top_cell), fill_layer)); + + db::Region remaining_parts, remaining_polygons; + + db::Vector ko (-100, -130); + db::Vector rs (230, -40); + db::Vector cs (-40, 230); + db::fill_region (&ly.cell (top_cell), fill_region, fill_cell, ko, rs, cs, db::Point (), true, &remaining_parts, db::Vector (50, 100), &remaining_polygons); + + unsigned int l100 = ly.insert_layer (db::LayerProperties (100, 0)); + unsigned int l101 = ly.insert_layer (db::LayerProperties (101, 0)); + remaining_parts.insert_into (&ly, top_cell, l100); + remaining_polygons.insert_into (&ly, top_cell, l101); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/fill_tool_au3c.gds"); +} diff --git a/src/lay/lay/layFillDialog.cc b/src/lay/lay/layFillDialog.cc index 6503a453c..f34ad0f80 100644 --- a/src/lay/lay/layFillDialog.cc +++ b/src/lay/lay/layFillDialog.cc @@ -240,7 +240,7 @@ BEGIN_PROTECTED db::Coord distance_y = db::coord_traits::rounded (y / cv->layout ().dbu ()); // read fill cell margin - db::Vector fill_margin (exclude_x, exclude_y); + db::Vector fill_margin; x = 0.0, y = 0.0; s = tl::to_string (fill_margin_le->text ()); ex = tl::Extractor (s.c_str ()); @@ -254,7 +254,7 @@ BEGIN_PROTECTED } // read fill cell 2 margin - db::Vector fill2_margin (exclude_x, exclude_y); + db::Vector fill2_margin; x = 0.0, y = 0.0; s = tl::to_string (fill2_margin_le->text ()); ex = tl::Extractor (s.c_str ()); @@ -525,9 +525,9 @@ BEGIN_PROTECTED } db::Vector rs (row_dx, row_dy), cs (column_dx, column_dy); - db::Vector ko = fc_bbox.center () - db::Point () - (rs + cs) / 2; + db::Vector ko = fc_bbox.center () - db::Point (row_dx / 2, column_dy / 2); - bool any_fill = fill_region (cv.cell (), *fp0, fill_cell->cell_index (), ko, rs, cs, fr_bbox.center (), enhanced_fill, (enhanced_fill || fill_cell2) ? &new_fill_area : 0, fill_margin); + bool any_fill = fill_region (cv.cell (), *fp0, fill_cell->cell_index (), ko, rs, cs, fr_bbox.p1 (), enhanced_fill, (enhanced_fill || fill_cell2) ? &new_fill_area : 0, fill_margin); if (! any_fill) { non_filled_area.push_back (*fp0); } diff --git a/testdata/algo/fill_tool_au3.gds b/testdata/algo/fill_tool_au3.gds index 3d351b3096ab19e463fc6aa14fbce9f9d9f3deb3..7d6e50a8e169bd860e585b36617059584360bd7a 100644 GIT binary patch literal 2228 zcma)-O-PhM7{{M|zt?QB4?bxX!(DmCcJ~?}B{@v#J_75lCyz1$eqF-BA2!f8zQt9U9E2WZ% z7l{OW9qb1M_4inl8^`f$#sfuG`WX)`?Yg3P`%=BLOTWnX3C1G2Q;aT4yRNA9q15#@ z3WDzI$h|!xh5cF2qXP~(38bhzE)Qezc1pYxZ(g5JLm6phTtf90bwd1nCgLyGRpyma zMTBx8W$q0sAH~&jn#?vB7Lw8stYObp^-a6kV5Dr8=ud-CV7V zrcu5pdc*v2D$%Qzrl;wSq^Ad!PvJlu@AN6+n@2>;mej&wG+Od)i*LW#`;}N$Qo1d; zMQ2$$Cq?oTc%0DMPnf+M)(`F$9kR+OYlfe(J;^Y%>oBYD&)%)nPy8KX5PyZ0II8M< zcjo~=x!=*F4CjdFE^|Yb-~5Qqvts$ViZ`XsC;R)Vo;RS*lXdn}(u4)_y1?A>47rqqx9$u!TA5Qf&5T{A>iI)9-kAE>x(D1+Re#0Z^}}u(@f}H-Thq0% zlpS5K3J)=V%Kn7-nVgfbTK$rIxIawaDK^nhj0(4zpJQ(5(0kr3{4{j&JLx||<-gyh z<4{ccTHCL2J~?Z|-&Rd`3(jD3Ow*l(+(1ibh53DTzGiM4URC}XHo+FrpGG~kFjpa_j0nYww-th{WP(Vn}EHF{uelvA$P;-u{&ebT3X2YGM7cSU^g@1^uq ztS?l4G*#UGM}}e8&$mI&v%J9kFmuZ)@0d9+>(8C^ogwyBMp@IoPnLGwzEk{$d!GCS D10)}L delta 551 zcmZvYJ4*vW6ot>u&TgXk*eGILL?sYZurPLF{(z_$f`teQk{}i~X)Fb6ZOnoeT8KYD z1g)(lqzPD9C{|in1_TA!_1vBKC{kR$nKO6JoVhotdUpmclv>5Gr4lc&;lM*0{{Qt+ zCfnamUOV;M$Vj^G%5ovdDgS!X3f0hV6oq%J6V@e5vATpoA>ofCcB1HO1BiJBbgXmV zB(K=g2+nnOe9E%{ROAX^ACQOSJ+&F3(NPKVI#UdDVg*-=?V5U*gM9a zS(2$8+PhDNqMLI*RVsTnKg9V&Wg**}wEJY5XWH}QF-OTdbw+Yu$rO3Z-@MWCfn;2V j1C02LuF>b6y!i2LMUqL)Q|AQ4QzHE`pdOzG+sVam2`Y#% diff --git a/testdata/algo/fill_tool_au3a.gds b/testdata/algo/fill_tool_au3a.gds new file mode 100644 index 0000000000000000000000000000000000000000..edddbc81fac4edaaa35c2f23aba0b887df1ef63c GIT binary patch literal 2142 zcma)-O-NKx6vxlp_c=BVWzuRE5fvd~5<(wHl$j(A6(SK46=BgLLP8=$T(qi)hzJ)Y zAt4m4BwDy=5iVRvxM~$aE@~4Y(XN>0^}Fxh>x?lzT^xU&_wN7PbIv{Qj)bDrSt;dI z^i4boMI;IQnh2_3(krppFbmZQ?6LT+r9_X3bGx_Y?fRuvOb;U63?JJir9z9kr zi}YK4A*_tV${y1m$GNB3OQ=p)I@ zHV(sqQ^@@dBE{zV%;PPJo`h0LGagBj>Q|y#R_`M@Zg$90lGi0v1xNlLLOGPFjP#xy zNH429Ym|18z;`Dyk|>EfrX|9V^=e0@y9B33nwJ`wv3X6c^8di|iSqpbDPuJg2{=3EQD z<4OEK_>P>En!`Zmb- z6F(*Up22UeG1rB!$k$Tm>+(*Sp8J~T@6K;j-(@T348O!o>G^|d6!z4Z8^_o4YAM{h z)hFbalDy~fsn=28kt=L@t{a|rPnr+=`MPH2Ivg|%^sV`xS}lFuBl@t+R`xNvM(4gG zozuI-yJ314(Kp>g?TdNdNSDrcZk#h6Wxf6Wyd`|T!;~LjjPE#QXU9?NjJ{F)37wbU ziRPN2$9Llwi0MeL{ds&xdL2yTTk10p$lo#Ct$RdWmQfLZKlwSXb${4A$frKvE45!+ PVlQIryf65*^?msV8@czk literal 0 HcmV?d00001 diff --git a/testdata/algo/fill_tool_au3b.gds b/testdata/algo/fill_tool_au3b.gds new file mode 100644 index 0000000000000000000000000000000000000000..08057877ce75dc9fe606e064d3dfecf62a6e4572 GIT binary patch literal 2208 zcma)-Pe>I(9LInA=k4w@ld_PAcaSKF2#ScJ2UZ}BFOK6!w0=c;F3<)nZNH-U8>@P^MnBE?C~X?uK3a#R?N?0n zq2ziS1wrRo*YrC-CEb4YEd znLnP;n}@Gh&oaUu#5Q!*d(ngchK_o14iJZ-@McvS$cHB1FKA0C-X?dm*p^+)eTQvH zew=66mRvOV9=4^+xAs3XzWq8rUO=BZNj-Oqd!{+ezH``y{tW9R^Rnu`UEKq9<^t;I zY~{>hDk|IbXX$i()L9EvPR#vwcVctTHC2Byo~76Kukez5H{&Z*uVR5%EDNL9O*G4& ve7DjJ!x83^%N0(s)^%*ljQ7Uum-gpk_5V6~N9?;{-w{jOZ{HL0SWs>!v5Rs6m23sORLK-3*B*GvX!Xe5b z8Z4qg8p5H$DViiA93sr6kcNo1Lf`H4yXPF=)84x@ocDR>-t#@bKj-&5S7Pz~bJFhl z$yW&^77Bt4MQet>@_upPWR}o_jpRj+YpgmHQ&WlCjW08LJY%dQcs5V zdqt9|LZyu}+@+q970ZA+Ne2p*q474HMD>7S8LXh}GD?!Q@jRRKG@@_hbFOgj!0a9M zv6{kg45_u${~u*KkY#J{H3q}v6Q@5>sI>8vTF5??<(Q6=nLS2Hg0zo3+XrJBO>#BM zRxc=tDkS$G9offcG&%C_7w>+v_6sq6t}^H#f8)Hj)H5v2nzJm?V`l%Hwf*S)pr3JU znNcy+Xp>hAOZObs>PKuG=QqZIzpv3wRjHXw-q=jS)$jNhSGo3F{pG!71Am>pTWT+O zs(CTYCgDvwEhi^+jrl;8-YMp{$(>^-`Jxs)OU;+oiQ~WLVC-P8Ui`T~CA|-ah(qtg z9ynH|+9`2oIBKU*hk3^+_5RfJcU1fFBi37PK2KvOw^z@f9?efUgU=n7FNqJI0?Y7< zsUOGnbshEM^FqBn8`Ysdh40j3&Kvl=$lNlXW8OwAmeC(#9LBbz-mBy*vJCm2RF?4B zGMHyh432&)^OM-J^tzdkV#8AUm_NiuPWI-uuds(>MQdb+XO3DU_n13&vDbCxj_dtb zFE5hkIr>0+#F&%*iC!?b+}x+@>+C&F8R&g*x%yq?!LrdSUH>_5?nAzdVJLqAcir38 literal 0 HcmV?d00001