From 6ad8ec5662277c872c1a72b81faf2e7aa3db73f4 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 26 May 2021 00:27:13 +0200 Subject: [PATCH] Bugfix: whole edge output for fragmented second input. No way to fix that for the compound ops. Restrict negative output for two-layer checks on first layer for the same reason. --- src/db/db/dbAsIfFlatRegion.cc | 10 ++++-- src/db/db/dbDeepRegion.cc | 10 ++++-- src/db/db/dbRegionUtils.h | 4 +++ src/db/db/gsiDeclDbRegion.cc | 40 +++++++++++++++++++----- src/drc/unit_tests/drcSimpleTests.cc | 10 ++++++ testdata/drc/drcSimpleTests_48.drc | 44 +++++++++++++++++++++++++++ testdata/drc/drcSimpleTests_48.gds | Bin 0 -> 874 bytes testdata/drc/drcSimpleTests_au48.gds | Bin 0 -> 4586 bytes 8 files changed, 106 insertions(+), 12 deletions(-) create mode 100644 testdata/drc/drcSimpleTests_48.drc create mode 100644 testdata/drc/drcSimpleTests_48.gds create mode 100644 testdata/drc/drcSimpleTests_au48.gds diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index 7129440a2..c2e9f2f08 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -1061,8 +1061,14 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons, others.push_back (begin_merged ()); } else { foreign.push_back (false); - others.push_back (other->begin ()); - other_is_merged = other->is_merged (); + if (options.whole_edges) { + // NOTE: whole edges needs both inputs merged + others.push_back (other->begin_merged ()); + other_is_merged = true; + } else { + others.push_back (other->begin ()); + other_is_merged = other->is_merged (); + } has_other = true; } diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index d4ba5d946..21284422c 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -1645,8 +1645,14 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons if (! other_deep) { return db::AsIfFlatRegion::run_check (rel, different_polygons, other, d, options); } - other_layer = other_deep->deep_layer ().layer (); - other_is_merged = other->is_merged (); + if (options.whole_edges) { + // NOTE: whole edges needs both inputs merged + other_layer = other_deep->merged_deep_layer ().layer (); + other_is_merged = true; + } else { + other_layer = other_deep->deep_layer ().layer (); + other_is_merged = other->is_merged (); + } } const db::DeepLayer &polygons = merged_deep_layer (); diff --git a/src/db/db/dbRegionUtils.h b/src/db/db/dbRegionUtils.h index dbb1ccc4b..cd759cb4f 100644 --- a/src/db/db/dbRegionUtils.h +++ b/src/db/db/dbRegionUtils.h @@ -844,9 +844,13 @@ protected: if (layer == 0) { edge2edge_check::put (db::EdgePair (edge, edge.swapped_points ()), false); } +#if 0 + // NOTE: second-input negative edge output isn't worth a lot as the second input often is not merged, hence + // the outer edges to not represent the actual contour. if (layer == 1) { edge2edge_check::put (db::EdgePair (edge.swapped_points (), edge), false); } +#endif } }; diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index c8ee01b40..86a6dd4e5 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -2589,7 +2589,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "@param max_projection The upper limit of the projected length of one edge onto another\n" "@param opposite_filter Specifies a filter mode for errors happening on opposite sides of inputs shapes\n" "@param rect_filter Specifies an error filter for rectangular input shapes\n" - "@param negative If true, edges not violation the condition will be output as pseudo-edge pairs\n" + "@param negative Negative output from the first input\n" "\n" "If \"whole_edges\" is true, the resulting \\EdgePairs collection will receive the whole " "edges which contribute in the width check.\n" @@ -2617,9 +2617,15 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\"opposite_filter\" specifies whether to require or reject errors happening on opposite sides of a figure. " "\"rect_filter\" allows suppressing specific error configurations on rectangular input figures.\n" "\n" + "If \"negative\" is true, only edges from the first input are output as pseudo edge-pairs where the distance is " + "larger or equal to the limit. This is a way to flag the parts of the first input where the distance to the second " + "input is bigger. Note that only the first input's edges are output. The output is still edge pairs, but each edge pair " + "contains one edge from the original input and the reverse version of the edge as the second edge.\n" + "\n" "Merged semantics applies for the input of this method (see \\merged_semantics= for a description of this concept)\n" "\n" - "The 'shielded', 'negative', 'not_opposite' and 'rect_sides' options have been introduced in version 0.27." + "The 'shielded', 'negative', 'not_opposite' and 'rect_sides' options have been introduced in version 0.27. " + "The interpretation of the 'negative' flag has been restriced to first-layout only output in 0.27.1.\n" ) + method_ext ("overlap_check", &overlap2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::metrics_type::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter, "NoOppositeFilter"), gsi::arg ("rect_filter", db::NoSideAllowed, "NoSideAllowed"), gsi::arg ("negative", false), "@brief Performs an overlap check with options\n" @@ -2632,7 +2638,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "@param max_projection The upper limit of the projected length of one edge onto another\n" "@param opposite_filter Specifies a filter mode for errors happening on opposite sides of inputs shapes\n" "@param rect_filter Specifies an error filter for rectangular input shapes\n" - "@param negative If true, edges not violation the condition will be output as pseudo-edge pairs\n" + "@param negative Negative output from the first input\n" "\n" "If \"whole_edges\" is true, the resulting \\EdgePairs collection will receive the whole " "edges which contribute in the width check.\n" @@ -2660,9 +2666,15 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\"opposite_filter\" specifies whether to require or reject errors happening on opposite sides of a figure. " "\"rect_filter\" allows suppressing specific error configurations on rectangular input figures.\n" "\n" + "If \"negative\" is true, only edges from the first input are output as pseudo edge-pairs where the overlap is " + "larger or equal to the limit. This is a way to flag the parts of the first input where the overlap vs. the second " + "input is bigger. Note that only the first input's edges are output. The output is still edge pairs, but each edge pair " + "contains one edge from the original input and the reverse version of the edge as the second edge.\n" + "\n" "Merged semantics applies for the input of this method (see \\merged_semantics= for a description of this concept)\n" "\n" - "The 'shielded', 'negative', 'not_opposite' and 'rect_sides' options have been introduced in version 0.27." + "The 'shielded', 'negative', 'not_opposite' and 'rect_sides' options have been introduced in version 0.27. " + "The interpretation of the 'negative' flag has been restriced to first-layout only output in 0.27.1.\n" ) + method_ext ("enclosing_check", &enclosing2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::metrics_type::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter, "NoOppositeFilter"), gsi::arg ("rect_filter", db::NoSideAllowed, "NoSideAllowed"), gsi::arg ("negative", false), "@brief Performs an enclosing check with options\n" @@ -2675,7 +2687,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "@param max_projection The upper limit of the projected length of one edge onto another\n" "@param opposite_filter Specifies a filter mode for errors happening on opposite sides of inputs shapes\n" "@param rect_filter Specifies an error filter for rectangular input shapes\n" - "@param negative If true, edges not violation the condition will be output as pseudo-edge pairs\n" + "@param negative Negative output from the first input\n" "\n" "If \"whole_edges\" is true, the resulting \\EdgePairs collection will receive the whole " "edges which contribute in the width check.\n" @@ -2703,9 +2715,15 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\"opposite_filter\" specifies whether to require or reject errors happening on opposite sides of a figure. " "\"rect_filter\" allows suppressing specific error configurations on rectangular input figures.\n" "\n" + "If \"negative\" is true, only edges from the first input are output as pseudo edge-pairs where the enclosure is " + "larger or equal to the limit. This is a way to flag the parts of the first input where the enclosure vs. the second " + "input is bigger. Note that only the first input's edges are output. The output is still edge pairs, but each edge pair " + "contains one edge from the original input and the reverse version of the edge as the second edge.\n" + "\n" "Merged semantics applies for the input of this method (see \\merged_semantics= for a description of this concept)\n" "\n" - "The 'shielded', 'negative', 'not_opposite' and 'rect_sides' options have been introduced in version 0.27." + "The 'shielded', 'negative', 'not_opposite' and 'rect_sides' options have been introduced in version 0.27. " + "The interpretation of the 'negative' flag has been restriced to first-layout only output in 0.27.1.\n" ) + method_ext ("separation_check", &separation2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::metrics_type::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter, "NoOppositeFilter"), gsi::arg ("rect_filter", db::NoSideAllowed, "NoSideAllowed"), gsi::arg ("negative", false), "@brief Performs a separation check with options\n" @@ -2718,7 +2736,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "@param max_projection The upper limit of the projected length of one edge onto another\n" "@param opposite_filter Specifies a filter mode for errors happening on opposite sides of inputs shapes\n" "@param rect_filter Specifies an error filter for rectangular input shapes\n" - "@param negative If true, edges not violation the condition will be output as pseudo-edge pairs\n" + "@param negative Negative output from the first input\n" "\n" "If \"whole_edges\" is true, the resulting \\EdgePairs collection will receive the whole " "edges which contribute in the width check.\n" @@ -2746,9 +2764,15 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\"opposite_filter\" specifies whether to require or reject errors happening on opposite sides of a figure. " "\"rect_filter\" allows suppressing specific error configurations on rectangular input figures.\n" "\n" + "If \"negative\" is true, only edges from the first input are output as pseudo edge-pairs where the separation is " + "larger or equal to the limit. This is a way to flag the parts of the first input where the distance to the second " + "input is bigger. Note that only the first input's edges are output. The output is still edge pairs, but each edge pair " + "contains one edge from the original input and the reverse version of the edge as the second edge.\n" + "\n" "Merged semantics applies for the input of this method (see \\merged_semantics= for a description of this concept)\n" "\n" - "The 'shielded', 'negative', 'not_opposite' and 'rect_sides' options have been introduced in version 0.27." + "The 'shielded', 'negative', 'not_opposite' and 'rect_sides' options have been introduced in version 0.27. " + "The interpretation of the 'negative' flag has been restriced to first-layout only output in 0.27.1.\n" ) + method_ext ("area", &area1, "@brief The area of the region\n" diff --git a/src/drc/unit_tests/drcSimpleTests.cc b/src/drc/unit_tests/drcSimpleTests.cc index aef50bbde..b4d065902 100644 --- a/src/drc/unit_tests/drcSimpleTests.cc +++ b/src/drc/unit_tests/drcSimpleTests.cc @@ -1272,3 +1272,13 @@ TEST(47_fillWithOverlappingBoxesTiled) { run_test (_this, "47", false); } + +TEST(48_drcWithFragments) +{ + run_test (_this, "48", false); +} + +TEST(48d_drcWithFragments) +{ + run_test (_this, "48", true); +} diff --git a/testdata/drc/drcSimpleTests_48.drc b/testdata/drc/drcSimpleTests_48.drc new file mode 100644 index 000000000..672fe9270 --- /dev/null +++ b/testdata/drc/drcSimpleTests_48.drc @@ -0,0 +1,44 @@ + +source $drc_test_source +target $drc_test_target + +if $drc_test_deep + deep +end + +l1 = input(1, 0) +l2 = input(2, 0) + +l1.output(1, 0) +l2.output(2, 0) + +l1.drc(separation(l2, projection) < 1.0).output(100, 0) +l1.drc(separation(l2, whole_edges, projection) < 1.0).output(101, 0) +l1.drc(separation(l2, projection) >= 1.0).output(102, 0) +l1.separation(l2, projection, 1.0).output(110, 0) +l1.separation(l2, projection, 1.0, whole_edges).output(111, 0) + +l2.drc(separation(l1, projection) < 1.0).output(200, 0) +l2.drc(separation(l1, whole_edges, projection) < 1.0).output(201, 0) +l2.drc(separation(l1, projection) >= 1.0).output(202, 0) +l2.separation(l1, projection, 1.0).output(210, 0) +l2.separation(l1, projection, 1.0, whole_edges).output(211, 0) + +(l1 + l2).drc(space(projection) < 1.0).output(300, 0) +(l1 + l2).drc(space(whole_edges, projection) < 1.0).output(301, 0) +(l1 + l2).drc(space(projection) >= 1.0).output(302, 0) +(l1 + l2).space(projection, 1.0).output(310, 0) +(l1 + l2).space(projection, 1.0, whole_edges).output(311, 0) + +l1.drc(enclosing(l2, projection) < 1.0).output(400, 0) +l1.drc(enclosing(l2, whole_edges, projection) < 1.0).output(401, 0) +l1.drc(enclosing(l2, projection) >= 1.0).output(402, 0) +l1.enclosing(l2, projection, 1.0).output(410, 0) +l1.enclosing(l2, projection, 1.0, whole_edges).output(411, 0) + +l1.drc(overlap(l2, projection) < 1.0).output(500, 0) +l1.drc(overlap(l2, whole_edges, projection) < 1.0).output(501, 0) +l1.drc(overlap(l2, projection) >= 1.0).output(502, 0) +l1.overlap(l2, projection, 1.0).output(510, 0) +l1.overlap(l2, projection, 1.0, whole_edges).output(511, 0) + diff --git a/testdata/drc/drcSimpleTests_48.gds b/testdata/drc/drcSimpleTests_48.gds new file mode 100644 index 0000000000000000000000000000000000000000..8742b1c658fcf32586ba4f3974effe60cf1b30cb GIT binary patch literal 874 zcmaLVF-yZh7{>7@m*g6u5d)SYh<}-4w&cmkPe>{n2=_jwQ^fLGR$-Q`% ze){N2FLS@2-iT-EXLqjjGWYx0xp-EO?7P2mrI)$S+x;VYDSdn@o~_RP@6YZZ$R0~S zcj!uA&gGF-BqmM8PPLL<OHUrgNxHz7^aM74b&6v0z zn!v>SLcD))f7ER5oWtK7sWHJ1V?sQ{DsfU%>GSb-F|dMXptVu(6PZf9vf}We&cCr~ zOw`+KlE#b8=ATNY5|4WQ{O@nflM>(fnJMu+?&lltm?tHE>uaXO^SGbidd)m3@!M}R zC7#Fq{Pt7kN#jMV{fkVA=W!p8=Wi3wN__PJ^Q02@uOFVD;pa$+@4lHS@pfGAzuG@M zKgB#L@%1a25^u-7eEm4{q{R14WJ$iB&yN$&S{q|tRN_#7{m5S%;rzm- zD)Eusd8xlPhWFgV`>aYlm;buEf2I9%qln-5%f9I!YU`g5MSKbWek|fkFMo^;bOh8@`Qttm6F1{1cV$KN1*xAV61jF<4eL3OZ3#qeJGt{?A9Zv7u?p6)$GJl%sR&g0JfpJ-n9Kll7*>*C(O0>#t$ zL5=0kzv97`KmRU|^-J#wtEi{#{U=xdcy|Ax^GCdB@%=~hx_*4_tbcmzPknFwpU%s< ze+AE+{VVUEdCik=i~K{s{}ktO$3L5z*Y{6ZH&IXhjUqnrDb_#nt=$I?|Igu5|8%_m zIbQjE9s7^}Khkqx|1Zh;U-5hLzv8ujC@;RZz5fS_M}GKM`fO|eNXK>mQ#|s)KjrT4 vIzRK7fAC%1-zA>wUpvnJA;0Xi_(oLX?)^V#7V(Ks;hV&_9{=E~TdA1;UinrS literal 0 HcmV?d00001