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 000000000..8742b1c65 Binary files /dev/null and b/testdata/drc/drcSimpleTests_48.gds differ diff --git a/testdata/drc/drcSimpleTests_au48.gds b/testdata/drc/drcSimpleTests_au48.gds new file mode 100644 index 000000000..4f81f169a Binary files /dev/null and b/testdata/drc/drcSimpleTests_au48.gds differ