mirror of https://github.com/KLayout/klayout.git
Implemented with_holes for generic DRC too
This commit is contained in:
parent
1c8eca50bf
commit
b3685c6722
|
|
@ -466,6 +466,12 @@ static db::CompoundRegionOperationNode *new_perimeter_sum_filter (db::CompoundRe
|
||||||
return new db::CompoundRegionFilterOperationNode (new db::RegionPerimeterFilter (pmin, pmax, inverse), input, true, true /*sum of set*/);
|
return new db::CompoundRegionFilterOperationNode (new db::RegionPerimeterFilter (pmin, pmax, inverse), input, true, true /*sum of set*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static db::CompoundRegionOperationNode *new_hole_count_filter (db::CompoundRegionOperationNode *input, bool inverse, size_t hmin, size_t hmax)
|
||||||
|
{
|
||||||
|
check_non_null (input, "input");
|
||||||
|
return new db::CompoundRegionFilterOperationNode (new db::HoleCountFilter (hmin, hmax, inverse), input, true);
|
||||||
|
}
|
||||||
|
|
||||||
static db::CompoundRegionOperationNode *new_area_filter (db::CompoundRegionOperationNode *input, bool inverse, db::coord_traits<db::Coord>::area_type amin, db::coord_traits<db::Coord>::area_type amax)
|
static db::CompoundRegionOperationNode *new_area_filter (db::CompoundRegionOperationNode *input, bool inverse, db::coord_traits<db::Coord>::area_type amin, db::coord_traits<db::Coord>::area_type amax)
|
||||||
{
|
{
|
||||||
check_non_null (input, "input");
|
check_non_null (input, "input");
|
||||||
|
|
@ -672,6 +678,11 @@ Class<db::CompoundRegionOperationNode> decl_CompoundRegionOperationNode ("db", "
|
||||||
"@brief Creates a node filtering the input by area sum.\n"
|
"@brief Creates a node filtering the input by area sum.\n"
|
||||||
"Like \\new_area_filter, but applies to the sum of all shapes in the current set.\n"
|
"Like \\new_area_filter, but applies to the sum of all shapes in the current set.\n"
|
||||||
) +
|
) +
|
||||||
|
gsi::constructor ("new_hole_count_filter", &new_hole_count_filter, gsi::arg ("input"), gsi::arg ("inverse", false), gsi::arg ("hmin", 0), gsi::arg ("hmax", std::numeric_limits<size_t>::max (), "max"),
|
||||||
|
"@brief Creates a node filtering the input by number of holes per polygon.\n"
|
||||||
|
"This node renders the input if the hole count is between hmin and hmax (exclusively). If 'inverse' is set to true, the "
|
||||||
|
"input shape is returned if the hole count is less than hmin (exclusively) or larger than hmax (inclusively)."
|
||||||
|
) +
|
||||||
gsi::constructor ("new_bbox_filter", &new_bbox_filter, gsi::arg ("input"), gsi::arg ("parameter"), gsi::arg ("inverse", false), gsi::arg ("pmin", 0), gsi::arg ("pmax", std::numeric_limits<db::coord_traits<db::Coord>::area_type>::max (), "max"),
|
gsi::constructor ("new_bbox_filter", &new_bbox_filter, gsi::arg ("input"), gsi::arg ("parameter"), gsi::arg ("inverse", false), gsi::arg ("pmin", 0), gsi::arg ("pmax", std::numeric_limits<db::coord_traits<db::Coord>::area_type>::max (), "max"),
|
||||||
"@brief Creates a node filtering the input by bounding box parameters.\n"
|
"@brief Creates a node filtering the input by bounding box parameters.\n"
|
||||||
"This node renders the input if the specified bounding box parameter of the input shape is between pmin and pmax (exclusively). If 'inverse' is set to true, the "
|
"This node renders the input if the specified bounding box parameter of the input shape is between pmin and pmax (exclusively). If 'inverse' is set to true, the "
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ module DRC
|
||||||
# @li \global#space @/li
|
# @li \global#space @/li
|
||||||
# @li \global#squares @/li
|
# @li \global#squares @/li
|
||||||
# @li \global#width @/li
|
# @li \global#width @/li
|
||||||
|
# @li \global#with_holes @/li
|
||||||
# @/ul
|
# @/ul
|
||||||
#
|
#
|
||||||
# The following documentation will list the methods available for DRC expression objects.
|
# The following documentation will list the methods available for DRC expression objects.
|
||||||
|
|
@ -434,7 +435,7 @@ CODE
|
||||||
# result. Without "if_any" three corners are returned for each triangle.
|
# result. Without "if_any" three corners are returned for each triangle.
|
||||||
|
|
||||||
def count
|
def count
|
||||||
DRCOpNodeCountFilter::new(@engine, self)
|
DRCOpNodeCountFilter::new(@engine, self, :new_count_filter, "count")
|
||||||
end
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
|
|
@ -1003,6 +1004,24 @@ CODE
|
||||||
return DRCOpNodeFilter::new(@engine, self, :new_edges, "edges")
|
return DRCOpNodeFilter::new(@engine, self, :new_edges, "edges")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name with_holes
|
||||||
|
# @brief Selects all input polygons with the specified number of holes
|
||||||
|
# @synopsis expression.with_holes (in condition)
|
||||||
|
#
|
||||||
|
# This operation can be used as a plain function in which case it acts on primary
|
||||||
|
# shapes or can be used as method on another DRC expression.
|
||||||
|
# The following example selects all polygons with more than 2 holes:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# out = in.drc(with_holes > 2)
|
||||||
|
# out = in.drc(primary.with_holes > 2) # equivalent
|
||||||
|
# @/code
|
||||||
|
|
||||||
|
def with_holes
|
||||||
|
return DRCOpNodeCountFilter::new(@engine, self, :new_hole_count_filter, "with_holes")
|
||||||
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name merged
|
# @name merged
|
||||||
# @brief Returns the merged input polygons, optionally selecting multi-overlap
|
# @brief Returns the merged input polygons, optionally selecting multi-overlap
|
||||||
|
|
@ -1552,16 +1571,19 @@ class DRCOpNodeCountFilter < DRCOpNodeWithCompare
|
||||||
|
|
||||||
attr_accessor :input
|
attr_accessor :input
|
||||||
attr_accessor :inverse
|
attr_accessor :inverse
|
||||||
|
attr_accessor :method
|
||||||
|
attr_accessor :name
|
||||||
|
|
||||||
def initialize(engine, input)
|
def initialize(engine, input, method, name)
|
||||||
super(engine)
|
super(engine)
|
||||||
self.input = input
|
self.input = input
|
||||||
self.inverse = false
|
self.inverse = false
|
||||||
self.description = "count"
|
self.description = name
|
||||||
|
self.method = method
|
||||||
end
|
end
|
||||||
|
|
||||||
def _description_for_dump
|
def _description_for_dump
|
||||||
self.inverse ? "count" : "not_count"
|
self.inverse ? name : "not_" + name
|
||||||
end
|
end
|
||||||
|
|
||||||
def do_create_node(cache)
|
def do_create_node(cache)
|
||||||
|
|
@ -1570,7 +1592,7 @@ class DRCOpNodeCountFilter < DRCOpNodeWithCompare
|
||||||
if self.lt || self.le
|
if self.lt || self.le
|
||||||
args << (self.lt ? @engine._make_numeric_value(self.lt) : @engine._make_numeric_value(self.le) + 1)
|
args << (self.lt ? @engine._make_numeric_value(self.lt) : @engine._make_numeric_value(self.le) + 1)
|
||||||
end
|
end
|
||||||
RBA::CompoundRegionOperationNode::new_count_filter(*args)
|
RBA::CompoundRegionOperationNode::send(self.method, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
def inverted
|
def inverted
|
||||||
|
|
|
||||||
|
|
@ -953,6 +953,19 @@ CODE
|
||||||
CODE
|
CODE
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name with_holes
|
||||||
|
# @brief Selects all input polygons according to their number of holes in DRC expressions
|
||||||
|
# @synopsis with_holes (in condition)
|
||||||
|
#
|
||||||
|
# "with_holes" represents a polygon selector for
|
||||||
|
# \DRC# expressions selecting polygons of the primary by their number of holes
|
||||||
|
# (see \Layer#drc and \DRC#with_holes for more details).
|
||||||
|
|
||||||
|
def with_holes
|
||||||
|
primary.with_holes
|
||||||
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name enclosing
|
# @name enclosing
|
||||||
# @brief Performs an enclosing check
|
# @brief Performs an enclosing check
|
||||||
|
|
|
||||||
|
|
@ -238,3 +238,13 @@ TEST(17d)
|
||||||
{
|
{
|
||||||
run_test (_this, "17", true);
|
run_test (_this, "17", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(18)
|
||||||
|
{
|
||||||
|
run_test (_this, "18", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(18d)
|
||||||
|
{
|
||||||
|
run_test (_this, "18", true);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
source $drc_test_source
|
||||||
|
target $drc_test_target
|
||||||
|
|
||||||
|
if $drc_test_deep
|
||||||
|
deep
|
||||||
|
end
|
||||||
|
|
||||||
|
l1 = input(1, 0)
|
||||||
|
l2 = input(2, 0)
|
||||||
|
l3 = input(3, 0)
|
||||||
|
|
||||||
|
l1.output(1, 0)
|
||||||
|
l2.output(2, 0)
|
||||||
|
l3.output(3, 0)
|
||||||
|
|
||||||
|
h = l1 - l2
|
||||||
|
h.drc(with_holes == 0).output(100, 0)
|
||||||
|
h.drc(with_holes != 0).output(101, 0)
|
||||||
|
h.drc(with_holes == 3).output(102, 0)
|
||||||
|
h.drc(1 <= with_holes < 3).output(103, 0)
|
||||||
|
h.drc(1 <= primary.with_holes <= 1).output(104, 0)
|
||||||
|
h.drc(with_holes >= 2).output(105, 0)
|
||||||
|
h.drc(with_holes >= 0).output(106, 0)
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue