From c6faa3e6282b2ca0057c8a24da42243bd12fcab3 Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Sun, 11 Jan 2026 22:34:52 +0100
Subject: [PATCH] 'extent_refs' DRC function: enabling for edge pairs and
edges, clarification of documentation
---
src/db/db/gsiDeclDbEdgePairs.cc | 76 +++++++++++++++++++++-
src/db/db/gsiDeclDbEdges.cc | 72 ++++++++++++++++++++
src/doc/doc/about/drc_ref.xml | 2 +-
src/doc/doc/about/drc_ref_drc.xml | 2 +-
src/doc/doc/about/drc_ref_global.xml | 2 +-
src/doc/doc/about/drc_ref_layer.xml | 19 +++---
src/doc/doc/about/drc_ref_netter.xml | 2 +-
src/doc/doc/about/drc_ref_source.xml | 2 +-
src/doc/doc/about/lvs_ref.xml | 2 +-
src/doc/doc/about/lvs_ref_global.xml | 2 +-
src/doc/doc/about/lvs_ref_netter.xml | 2 +-
src/drc/drc/built-in-macros/_drc_layer.rb | 23 ++++---
testdata/drc/drcSimpleTests_2.drc | 6 ++
testdata/drc/drcSimpleTests_au2.gds | Bin 15470 -> 16532 bytes
14 files changed, 183 insertions(+), 29 deletions(-)
diff --git a/src/db/db/gsiDeclDbEdgePairs.cc b/src/db/db/gsiDeclDbEdgePairs.cc
index 3c83fe30c..9d45b739a 100644
--- a/src/db/db/gsiDeclDbEdgePairs.cc
+++ b/src/db/db/gsiDeclDbEdgePairs.cc
@@ -31,6 +31,7 @@
#include "dbEdgesUtils.h"
#include "dbEdgePairFilters.h"
#include "dbPropertiesFilter.h"
+#include "dbRegionProcessors.h"
#include "gsiDeclDbContainerHelpers.h"
#include "gsiDeclDbMeasureHelpers.h"
@@ -531,6 +532,71 @@ static db::Region extents0 (const db::EdgePairs *r)
return extents2 (r, 0, 0);
}
+namespace {
+
+// a combined processor that implements db::RelativeExtents on the edge bounding boxes
+
+class DB_PUBLIC EdgePairsRelativeExtents
+ : virtual public db::EdgePairToPolygonProcessorBase,
+ virtual public db::RelativeExtents
+{
+public:
+ EdgePairsRelativeExtents (double fx1, double fy1, double fx2, double fy2, db::Coord dx, db::Coord dy)
+ : db::RelativeExtents (fx1, fy1, fx2, fy2, dx, dy)
+ {
+ // .. nothing yet ..
+ }
+
+ // not needed, but mutes
+ void process (const db::PolygonWithProperties &poly, std::vector &result) const
+ {
+ db::RelativeExtents::process (poly, result);
+ }
+
+ void process (const db::EdgePairWithProperties &ep, std::vector &result) const
+ {
+ db::RelativeExtents::process (db::Polygon (ep.bbox ()), result);
+ }
+};
+
+class DB_PUBLIC EdgePairsRelativeExtentsAsEdges
+ : virtual public db::EdgePairToEdgeProcessorBase,
+ virtual public db::RelativeExtentsAsEdges
+{
+public:
+ EdgePairsRelativeExtentsAsEdges (double fx1, double fy1, double fx2, double fy2)
+ : db::RelativeExtentsAsEdges (fx1, fy1, fx2, fy2)
+ {
+ // .. nothing yet ..
+ }
+
+ void process (const db::PolygonWithProperties &poly, std::vector &result) const
+ {
+ db::RelativeExtentsAsEdges::process (poly, result);
+ }
+
+ void process (const db::EdgePairWithProperties &ep, std::vector &result) const
+ {
+ db::RelativeExtentsAsEdges::process (db::Polygon (ep.bbox ()), result);
+ }
+};
+
+}
+
+static db::Region extent_refs (const db::EdgePairs *r, double fx1, double fy1, double fx2, double fy2, db::Coord dx, db::Coord dy)
+{
+ db::Region result;
+ r->processed (result, EdgePairsRelativeExtents (fx1, fy1, fx2, fy2, dx, dy));
+ return result;
+}
+
+static db::Edges extent_refs_edges (const db::EdgePairs *r, double fx1, double fy1, double fx2, double fy2)
+{
+ db::Edges result;
+ r->processed (result, EdgePairsRelativeExtentsAsEdges (fx1, fy1, fx2, fy2));
+ return result;
+}
+
static db::Edges edges (const db::EdgePairs *ep)
{
db::Edges e;
@@ -1247,7 +1313,15 @@ Class decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
"The boxes will not be merged, so it is possible to determine overlaps "
"of these boxes for example.\n"
) +
- method_ext ("filter", &filter, gsi::arg ("filter"),
+ method_ext ("extent_refs", &extent_refs,
+ "@hide\n"
+ "This method is provided for DRC implementation.\n"
+ ) +
+ method_ext ("extent_refs_edges", &extent_refs_edges,
+ "@hide\n"
+ "This method is provided for DRC implementation.\n"
+ ) +
+ method_ext ("filter", &filter, gsi::arg ("filter"),
"@brief Applies a generic filter in place (replacing the edge pairs from the EdgePair collection)\n"
"See \\EdgePairFilter for a description of this feature.\n"
"\n"
diff --git a/src/db/db/gsiDeclDbEdges.cc b/src/db/db/gsiDeclDbEdges.cc
index 109101272..a600c1732 100644
--- a/src/db/db/gsiDeclDbEdges.cc
+++ b/src/db/db/gsiDeclDbEdges.cc
@@ -32,6 +32,7 @@
#include "dbOriginalLayerRegion.h"
#include "dbLayoutUtils.h"
#include "dbPropertiesFilter.h"
+#include "dbRegionProcessors.h"
#include "gsiDeclDbContainerHelpers.h"
#include "gsiDeclDbMeasureHelpers.h"
@@ -941,6 +942,69 @@ static std::vector split_interacting_with_region (const db::Edges *r,
return as_2edges_vector (r->selected_interacting_differential (other, min_count, max_count));
}
+namespace {
+
+// a combined processor that implements db::RelativeExtents on the edge bounding boxes
+
+class DB_PUBLIC EdgesRelativeExtents
+ : virtual public db::EdgeToPolygonProcessorBase,
+ virtual public db::RelativeExtents
+{
+public:
+ EdgesRelativeExtents (double fx1, double fy1, double fx2, double fy2, db::Coord dx, db::Coord dy)
+ : db::RelativeExtents (fx1, fy1, fx2, fy2, dx, dy)
+ {
+ // .. nothing yet ..
+ }
+
+ // not needed, but mutes
+ void process (const db::PolygonWithProperties &poly, std::vector &result) const
+ {
+ db::RelativeExtents::process (poly, result);
+ }
+
+ void process (const db::EdgeWithProperties &edge, std::vector &result) const
+ {
+ db::RelativeExtents::process (db::Polygon (edge.bbox ()), result);
+ }
+};
+
+class DB_PUBLIC EdgesRelativeExtentsAsEdges
+ : virtual public db::EdgeProcessorBase,
+ virtual public db::RelativeExtentsAsEdges
+{
+public:
+ EdgesRelativeExtentsAsEdges (double fx1, double fy1, double fx2, double fy2)
+ : db::RelativeExtentsAsEdges (fx1, fy1, fx2, fy2)
+ {
+ // .. nothing yet ..
+ }
+
+ void process (const db::PolygonWithProperties &poly, std::vector &result) const
+ {
+ db::RelativeExtentsAsEdges::process (poly, result);
+ }
+
+ void process (const db::EdgeWithProperties &edge, std::vector &result) const
+ {
+ db::RelativeExtentsAsEdges::process (db::Polygon (edge.bbox ()), result);
+ }
+};
+
+}
+
+static db::Region extent_refs (const db::Edges *r, double fx1, double fy1, double fx2, double fy2, db::Coord dx, db::Coord dy)
+{
+ db::Region result;
+ r->processed (result, EdgesRelativeExtents (fx1, fy1, fx2, fy2, dx, dy));
+ return result;
+}
+
+static db::Edges extent_refs_edges (const db::Edges *r, double fx1, double fy1, double fx2, double fy2)
+{
+ return r->processed (EdgesRelativeExtentsAsEdges (fx1, fy1, fx2, fy2));
+}
+
static tl::Variant nth (const db::Edges *edges, size_t n)
{
const db::Edge *e = edges->nth (n);
@@ -2372,6 +2436,14 @@ Class decl_Edges (decl_dbShapeCollection, "db", "Edges",
"The boxes will not be merged, so it is possible to determine overlaps "
"of these boxes for example.\n"
) +
+ method_ext ("extent_refs", &extent_refs,
+ "@hide\n"
+ "This method is provided for DRC implementation.\n"
+ ) +
+ method_ext ("extent_refs_edges", &extent_refs_edges,
+ "@hide\n"
+ "This method is provided for DRC implementation.\n"
+ ) +
method_ext ("extended_in", &extended_in, gsi::arg ("e"),
"@brief Returns a region with shapes representing the edges with the given width\n"
"@param e The extension width\n"
diff --git a/src/doc/doc/about/drc_ref.xml b/src/doc/doc/about/drc_ref.xml
index 203941a1d..3974cf751 100644
--- a/src/doc/doc/about/drc_ref.xml
+++ b/src/doc/doc/about/drc_ref.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/src/doc/doc/about/drc_ref_drc.xml b/src/doc/doc/about/drc_ref_drc.xml
index a4ad2a239..78e0e1744 100644
--- a/src/doc/doc/about/drc_ref_drc.xml
+++ b/src/doc/doc/about/drc_ref_drc.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/src/doc/doc/about/drc_ref_global.xml b/src/doc/doc/about/drc_ref_global.xml
index 735374f88..da588bf12 100644
--- a/src/doc/doc/about/drc_ref_global.xml
+++ b/src/doc/doc/about/drc_ref_global.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/src/doc/doc/about/drc_ref_layer.xml b/src/doc/doc/about/drc_ref_layer.xml
index df0a8c7cc..0e485e947 100644
--- a/src/doc/doc/about/drc_ref_layer.xml
+++ b/src/doc/doc/about/drc_ref_layer.xml
@@ -1,7 +1,7 @@
-
+
@@ -1182,20 +1182,19 @@ The formal specifiers for lines are:
:right or :r : the right line
-Dots are represented by small (2x2 DBU) boxes or point-like
+The following additional option controls the output format:
+
+
+- as_boxes : with this option, boxes (rectangular polygons) will be produced on output
+- as_dots or as_edges : with this option, edges will be produced on output
+
+
+Dots on are represented by small (2x2 DBU) boxes or point-like
edges with edge output. Lines are represented by narrow or
flat (2 DBU) boxes or edges for edge output. Edges will follow
the orientation convention for the corresponding edges - i.e.
"inside" of the bounding box is on the right side of the edge.
-The following additional option controls the output format:
-
-
-- as_boxes : with this option, small boxes will be produced as markers
-- as_dots or as_edges : with this option, point-like edges will be produced for dots
-and edges will be produced for line-like selections
-
-
The following table shows a few applications:
diff --git a/src/doc/doc/about/drc_ref_netter.xml b/src/doc/doc/about/drc_ref_netter.xml
index 009b97ce4..0157af89f 100644
--- a/src/doc/doc/about/drc_ref_netter.xml
+++ b/src/doc/doc/about/drc_ref_netter.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/src/doc/doc/about/drc_ref_source.xml b/src/doc/doc/about/drc_ref_source.xml
index a746917e3..a3fea2b89 100644
--- a/src/doc/doc/about/drc_ref_source.xml
+++ b/src/doc/doc/about/drc_ref_source.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/src/doc/doc/about/lvs_ref.xml b/src/doc/doc/about/lvs_ref.xml
index 58168f012..842f21820 100644
--- a/src/doc/doc/about/lvs_ref.xml
+++ b/src/doc/doc/about/lvs_ref.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/src/doc/doc/about/lvs_ref_global.xml b/src/doc/doc/about/lvs_ref_global.xml
index 494ef2f6e..d1121526c 100644
--- a/src/doc/doc/about/lvs_ref_global.xml
+++ b/src/doc/doc/about/lvs_ref_global.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/src/doc/doc/about/lvs_ref_netter.xml b/src/doc/doc/about/lvs_ref_netter.xml
index 2e1dbd89e..be3e6e538 100644
--- a/src/doc/doc/about/lvs_ref_netter.xml
+++ b/src/doc/doc/about/lvs_ref_netter.xml
@@ -1,7 +1,7 @@
-
+
diff --git a/src/drc/drc/built-in-macros/_drc_layer.rb b/src/drc/drc/built-in-macros/_drc_layer.rb
index 7bb79f054..eeb76e244 100644
--- a/src/drc/drc/built-in-macros/_drc_layer.rb
+++ b/src/drc/drc/built-in-macros/_drc_layer.rb
@@ -1463,20 +1463,19 @@ CODE
# @li @b :right @/b or @b :r @/b: the right line @/li
# @/ul
#
- # Dots are represented by small (2x2 DBU) boxes or point-like
+ # The following additional option controls the output format:
+ #
+ # @ul
+ # @li @b as_boxes @/b: with this option, boxes (rectangular polygons) will be produced on output @/li
+ # @li @b as_dots @/b or @b as_edges @/b: with this option, edges will be produced on output @/li
+ # @/ul
+ #
+ # Dots on are represented by small (2x2 DBU) boxes or point-like
# edges with edge output. Lines are represented by narrow or
# flat (2 DBU) boxes or edges for edge output. Edges will follow
# the orientation convention for the corresponding edges - i.e.
# "inside" of the bounding box is on the right side of the edge.
#
- # The following additional option controls the output format:
- #
- # @ul
- # @li @b as_boxes @/b: with this option, small boxes will be produced as markers @/li
- # @li @b as_dots @/b or @b as_edges @/b: with this option, point-like edges will be produced for dots
- # and edges will be produced for line-like selections @/li
- # @/ul
- #
# The following table shows a few applications:
#
# @table
@@ -1511,7 +1510,7 @@ CODE
@engine._context("#{f}") do
- requires_region
+ requires_edges_edge_pairs_or_region
f = []
as_edges = false
@@ -6105,6 +6104,10 @@ END
self.data.is_a?(RBA::Edges) || self.data.is_a?(RBA::Region) || raise(name ? "#{name} requires an edge or polygon layer" : "Requires an edge or polygon layer")
end
+ def requires_edges_edge_pairs_or_region(name = nil)
+ self.data.is_a?(RBA::Edges) || self.data.is_a?(RBA::Region) || self.data.is_a?(RBA::EdgePairs) || raise(name ? "#{name} requires an edge, edge pair or polygon layer" : "Requires an edge, edge pair or polygon layer")
+ end
+
def requires_edges_texts_or_region(name = nil)
self.data.is_a?(RBA::Edges) || self.data.is_a?(RBA::Region) || self.data.is_a?(RBA::Texts) || raise(name ? "#{name} requires an edge, text or polygon layer" : "Requires an edge, text or polygon layer")
end
diff --git a/testdata/drc/drcSimpleTests_2.drc b/testdata/drc/drcSimpleTests_2.drc
index e32bffc1e..d77afb552 100644
--- a/testdata/drc/drcSimpleTests_2.drc
+++ b/testdata/drc/drcSimpleTests_2.drc
@@ -64,6 +64,12 @@ a1.extent_refs(:lc).sized(0.05).output(1051, 1)
a1.extent_refs(:right_center).sized(0.05).output(1052, 0)
a1.extent_refs(:rc).sized(0.05).output(1052, 1)
a1.extent_refs(0.25, 0.5, 0.5, 0.75).output(1053, 0)
+a1.extent_refs(0.5, 0.5, 0.25, 0.75, as_edges).output(1054, 0)
+a1.extent_refs(0.5, 0.5, 0.25, 0.75, as_boxes).output(1055, 0)
+a1.extents.width(0.8.um).extent_refs(0.5, 0.5, 0.25, 0.75, as_edges).output(1056, 0)
+a1.extents.width(0.8.um).extent_refs(0.5, 0.5, 0.25, 0.75, as_boxes).output(1057, 0)
+a1.extents.width(0.8.um).first_edges.extent_refs(:center, as_edges).output(1058, 0)
+a1.extents.width(0.8.um).first_edges.extent_refs(:center, as_boxes).output(1059, 0)
a1.corners.sized(0.05).output(1060, 0)
a1.corners(-90.0, as_boxes).sized(0.05).output(1061, 0)
diff --git a/testdata/drc/drcSimpleTests_au2.gds b/testdata/drc/drcSimpleTests_au2.gds
index 6996b4a94cd000b4abb3436256b75b93984cdd57..dc6143932356f985339b2cee7e3f98d2253ff3b4 100644
GIT binary patch
delta 608
zcmaD?F{P0)ih+%Ri7A3XhLMT=6$2v!H-i|1JcBYan}LIg&BxP;fkA|s)y}cg-22$_
z50)-F^cT#I3Sp38#i?&&)ITW>P6h@xUM3c~$qo7vatsU%DgXa}-t_XjxxFp_fvJHP_u5ES#38QA!kfKJpAU