mirror of https://github.com/KLayout/klayout.git
WIP: new ratio filters, squares for DRC
This commit is contained in:
parent
8c8c9a6911
commit
a8f08bffac
|
|
@ -496,6 +496,12 @@ static db::CompoundRegionOperationNode *new_bbox_filter (db::CompoundRegionOpera
|
|||
return new db::CompoundRegionFilterOperationNode (new db::RegionBBoxFilter (vmin, vmax, inverse, parameter), input, true);
|
||||
}
|
||||
|
||||
static db::CompoundRegionOperationNode *new_ratio_filter (db::CompoundRegionOperationNode *input, db::RegionRatioFilter::parameter_type parameter, bool inverse, double vmin, bool vmin_included, double vmax, bool vmax_included)
|
||||
{
|
||||
check_non_null (input, "input");
|
||||
return new db::CompoundRegionFilterOperationNode (new db::RegionRatioFilter (vmin, vmin_included, vmax, vmax_included, inverse, parameter), input, true);
|
||||
}
|
||||
|
||||
static db::CompoundRegionOperationNode *new_start_segments (db::CompoundRegionOperationNode *input, db::Edges::length_type length, double fraction)
|
||||
{
|
||||
check_non_null (input, "input");
|
||||
|
|
@ -663,6 +669,11 @@ Class<db::CompoundRegionOperationNode> decl_CompoundRegionOperationNode ("db", "
|
|||
"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 "
|
||||
"input shape is returned if the parameter is less than pmin (exclusively) or larger than pmax (inclusively)."
|
||||
) +
|
||||
gsi::constructor ("new_ratio_filter", &new_ratio_filter, gsi::arg ("input"), gsi::arg ("parameter"), gsi::arg ("inverse", false), gsi::arg ("pmin", 0.0), gsi::arg ("pmin_included"), gsi::arg ("pmax", std::numeric_limits<double>::max (), "max"), gsi::arg ("pmax_included", true),
|
||||
"@brief Creates a node filtering the input by ratio parameters.\n"
|
||||
"This node renders the input if the specified ratio parameter of the input shape is between pmin and pmax. If 'pmin_included' is true, the range will include pmin. Same for 'pmax_included' and pmax. "
|
||||
"If 'inverse' is set to true, the input shape is returned if the parameter is not within the specified range."
|
||||
) +
|
||||
gsi::constructor ("new_rectilinear_filter", &new_rectilinear_filter, gsi::arg ("input"), gsi::arg ("inverse", false),
|
||||
"@brief Creates a node filtering the input for rectilinear shapes (or non-rectilinear ones with 'inverse' set to 'true').\n"
|
||||
) +
|
||||
|
|
@ -851,5 +862,20 @@ gsi::EnumIn<db::CompoundRegionOperationNode, db::RegionBBoxFilter::parameter_typ
|
|||
"This enum has been introduced in version 0.27."
|
||||
);
|
||||
|
||||
gsi::EnumIn<db::CompoundRegionOperationNode, db::RegionRatioFilter::parameter_type> decl_dbRegionRatioFilter_ParameterType ("db", "ParameterType",
|
||||
gsi::enum_const ("AreaRatio", db::RegionRatioFilter::AreaRatio,
|
||||
"@brief Measures the area ratio (bounding box area / polygon area)\n"
|
||||
) +
|
||||
gsi::enum_const ("AspectRatio", db::RegionRatioFilter::AspectRatio,
|
||||
"@brief Measures the aspect ratio of the bounding box (larger / smaller dimension)\n"
|
||||
) +
|
||||
gsi::enum_const ("RelativeHeight", db::RegionRatioFilter::RelativeHeight,
|
||||
"@brief Measures the relative height (height / width)\n"
|
||||
),
|
||||
"@brief This class represents the parameter type enum used in \\CompoundRegionOperationNode#new_ratio_filter\n"
|
||||
"\n"
|
||||
"This enum has been introduced in version 0.27."
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ module DRC
|
|||
# @ul
|
||||
# @li \global#angle @/li
|
||||
# @li \global#area @/li
|
||||
# @li \global#area_ratio @/li
|
||||
# @li \global#bbox_area_ratio @/li
|
||||
# @li \global#bbox_height @/li
|
||||
# @li \global#bbox_max @/li
|
||||
# @li \global#bbox_min @/li
|
||||
|
|
@ -60,6 +62,7 @@ module DRC
|
|||
# @li \global#primary @/li
|
||||
# @li \global#rectangles @/li
|
||||
# @li \global#rectilinear @/li
|
||||
# @li \global#relative_height @/li
|
||||
# @li \global#rounded_corners @/li
|
||||
# @li \global#secondary @/li
|
||||
# @li \global#separation @/li
|
||||
|
|
@ -67,6 +70,7 @@ module DRC
|
|||
# @li \global#sized @/li
|
||||
# @li \global#smoothed @/li
|
||||
# @li \global#space @/li
|
||||
# @li \global#squares @/li
|
||||
# @li \global#width @/li
|
||||
# @/ul
|
||||
#
|
||||
|
|
@ -269,7 +273,7 @@ CODE
|
|||
|
||||
# %DRC%
|
||||
# @name perimeter
|
||||
# @brief Selects the primary shape if the perimeter is meeting the condition
|
||||
# @brief Selects the input polygon if the perimeter is meeting the condition
|
||||
# @synopsis expression.perimeter (in condition)
|
||||
#
|
||||
# This operation is used in conditions to select shapes based on their perimeter.
|
||||
|
|
@ -294,7 +298,7 @@ CODE
|
|||
|
||||
# %DRC%
|
||||
# @name bbox_min
|
||||
# @brief Selects the primary shape if its bounding box smaller dimension is meeting the condition
|
||||
# @brief Selects the input polygon if its bounding box smaller dimension is meeting the condition
|
||||
# @synopsis expression.bbox_min (in condition)
|
||||
#
|
||||
# This operation is used in conditions to select shapes based on smaller dimension of their bounding boxes.
|
||||
|
|
@ -320,7 +324,7 @@ CODE
|
|||
|
||||
# %DRC%
|
||||
# @name bbox_max
|
||||
# @brief Selects the primary shape if its bounding box larger dimension is meeting the condition
|
||||
# @brief Selects the input polygon if its bounding box larger dimension is meeting the condition
|
||||
# @synopsis expression.bbox_max (in condition)
|
||||
#
|
||||
# This operation acts similar to \DRC#bbox_min, but takes the larger dimension of the shape's
|
||||
|
|
@ -335,7 +339,7 @@ CODE
|
|||
|
||||
# %DRC%
|
||||
# @name bbox_width
|
||||
# @brief Selects the primary shape if its bounding box width is meeting the condition
|
||||
# @brief Selects the input polygon if its bounding box width is meeting the condition
|
||||
# @synopsis expression.bbox_width (in condition)
|
||||
#
|
||||
# This operation acts similar to \DRC#bbox_min, but takes the width of the shape's
|
||||
|
|
@ -353,7 +357,7 @@ CODE
|
|||
|
||||
# %DRC%
|
||||
# @name bbox_height
|
||||
# @brief Selects the primary shape if its bounding box height is meeting the condition
|
||||
# @brief Selects the input polygon if its bounding box height is meeting the condition
|
||||
# @synopsis expression.bbox_height (in condition)
|
||||
#
|
||||
# This operation acts similar to \DRC#bbox_min, but takes the height of the shape's
|
||||
|
|
@ -369,6 +373,95 @@ CODE
|
|||
DRCOpNodeBBoxParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::ParameterType::BoxHeight, self)
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name bbox_aspect_ratio
|
||||
# @brief Selects the input polygon according to the aspect ratio of the bounding box
|
||||
# @synopsis expression.bbox_aspect_ratio (in condition)
|
||||
#
|
||||
# This operation is used in conditions to select shapes based on aspect ratios of their bounding boxes.
|
||||
# The aspect ratio is computed by dividing the larger of width and height by the smaller of both.
|
||||
# The aspect ratio is always larger or equal to 1. Square or square-boxed shapes have a
|
||||
# bounding box aspect ratio of 1.
|
||||
#
|
||||
# This filter is applicable on polygon expressions. The result will be the input
|
||||
# polygon if the bounding box condition is met.
|
||||
#
|
||||
# See \Layer#drc for more details about comparison specs.
|
||||
#
|
||||
# The following example will select all polygons whose bounding box aspect ratio is larger than 3:
|
||||
#
|
||||
# @code
|
||||
# out = in.drc(bbox_aspect_ratio > 3)
|
||||
# out = in.drc(primary.bbox_aspect_ratio > 3) # equivalent
|
||||
# @/code
|
||||
#
|
||||
# The "bbox_aspect_ratio" method is available as a plain function or as a method on \DRC## expressions.
|
||||
# The plain function is equivalent to "primary.bbox_aspect_ratio".
|
||||
|
||||
def bbox_aspect_ratio
|
||||
DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RegionRatioFilter::AspectRatio, self)
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name relative_height
|
||||
# @brief Selects the input polygon according to the height vs. width of the bounding box
|
||||
# @synopsis expression.relative_height (in condition)
|
||||
#
|
||||
# This operation is used in conditions to select shapes based on the ratio of bounding box
|
||||
# height vs. width. The taller the shape, the larger the value. Wide polygons have a value
|
||||
# below 1. A square has a relative height of 1.
|
||||
#
|
||||
# This filter is applicable on polygon expressions. The result will be the input
|
||||
# polygon if the condition is met.
|
||||
#
|
||||
# Don't use this method if you can use \bbox_aspect_ratio, because the latter is
|
||||
# isotropic and can be used hierarchically without generating rotation variants.
|
||||
#
|
||||
# See \Layer#drc for more details about comparison specs.
|
||||
#
|
||||
# The following example will select all polygons whose relative height is larger than 3:
|
||||
#
|
||||
# @code
|
||||
# out = in.drc(relative_height > 3)
|
||||
# out = in.drc(primary.relative_height > 3) # equivalent
|
||||
# @/code
|
||||
#
|
||||
# The "relative_height" method is available as a plain function or as a method on \DRC## expressions.
|
||||
# The plain function is equivalent to "primary.bbox_aspect_ratio".
|
||||
|
||||
def relative_height
|
||||
DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RegionRatioFilter::RelativeHeight, self)
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name area_ratio
|
||||
# @brief Selects the input polygon according to its area ratio (bounding box area by polygon area)
|
||||
# @synopsis expression.area_ratio (in condition)
|
||||
#
|
||||
# This operation is used in conditions to select shapes based on their area ratio.
|
||||
# The area ratio is the ratio of bounding box vs. polygon area. It's a measure how
|
||||
# "sparse" the polygons are and how good an approximation the bounding box is.
|
||||
# The value is always larger or equal than 1. Boxes have a value of 1.
|
||||
#
|
||||
# This filter is applicable on polygon expressions. The result will be the input
|
||||
# polygon if the condition is met.
|
||||
#
|
||||
# See \Layer#drc for more details about comparison specs.
|
||||
#
|
||||
# The following example will select all polygons whose area ratio is larger than 3:
|
||||
#
|
||||
# @code
|
||||
# out = in.drc(area_ratio > 3)
|
||||
# out = in.drc(primary.area_ratio > 3) # equivalent
|
||||
# @/code
|
||||
#
|
||||
# The "area_ratio" method is available as a plain function or as a method on \DRC## expressions.
|
||||
# The plain function is equivalent to "primary.area_ratio".
|
||||
|
||||
def area_ratio
|
||||
DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RegionRatioFilter::AreaRatio, self)
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name length
|
||||
# @brief Selects edges based on their length
|
||||
|
|
@ -627,7 +720,25 @@ CODE
|
|||
# @/code
|
||||
|
||||
def rectangles
|
||||
return DRCOpNodeFilter::new(@engine, self, :new_rectangle_filter, "rectangle")
|
||||
return DRCOpNodeFilter::new(@engine, self, :new_rectangle_filter, "rectangle", false)
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name squares
|
||||
# @brief Selects all polygons which are squares
|
||||
# @synopsis expression.squares
|
||||
#
|
||||
# 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 squares:
|
||||
#
|
||||
# @code
|
||||
# out = in.drc(squares)
|
||||
# out = in.drc(primary.squares) # equivalent
|
||||
# @/code
|
||||
|
||||
def squares
|
||||
return DRCOpNodeFilter::new(@engine, self, :new_rectangle_filter, "rectangle", true)
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
|
|
|
|||
|
|
@ -499,11 +499,35 @@ CODE
|
|||
#
|
||||
# See \Layer#drc, \bbox_min and \DRC#bbox_min for more details.
|
||||
|
||||
# %DRC%
|
||||
# @name bbox_aspect_ratio
|
||||
# @brief Selects primary shapes based on the aspect ratio of their bounding boxes
|
||||
# @synopsis bbox_aspect_ratio (in condition)
|
||||
#
|
||||
# See \Layer#drc, \bbox_aspect_ratio and \DRC#bbox_aspect_ratio for more details.
|
||||
|
||||
# %DRC%
|
||||
# @name relative_height
|
||||
# @brief Selects primary shapes based on the ratio of height and width of their bounding boxes
|
||||
# @synopsis relative_height (in condition)
|
||||
#
|
||||
# See \Layer#drc, \relative_height and \DRC#relative_height for more details.
|
||||
|
||||
# %DRC%
|
||||
# @name area_ratio
|
||||
# @brief Selects primary shapes based on the ratio of bounding box and polygon area
|
||||
# @synopsis area_ratio (in condition)
|
||||
#
|
||||
# See \Layer#drc, \area_ratio and \DRC#area_ratio for more details.
|
||||
|
||||
%w(
|
||||
bbox_height
|
||||
bbox_max
|
||||
bbox_min
|
||||
bbox_width
|
||||
bbox_aspect_ratio
|
||||
area_ratio
|
||||
relative_height
|
||||
).each do |f|
|
||||
eval <<"CODE"
|
||||
def #{f}
|
||||
|
|
@ -584,6 +608,17 @@ CODE
|
|||
# argument, "rectangles" represents the rectangles filter for primary shapes in
|
||||
# \DRC# expressions (see \Layer#drc and \DRC#rectangles for more details).
|
||||
|
||||
# %DRC%
|
||||
# @name squares
|
||||
# @brief Selects all polygons which are squares
|
||||
# @synopsis squares
|
||||
# @synopsis squares(layer)
|
||||
#
|
||||
# This function can be used with a layer argument in which case it
|
||||
# is equivalent to "layer.squares" (see \Layer#squares). Without a layer
|
||||
# argument, "squares" represents the rectangles filter for primary shapes in
|
||||
# \DRC# expressions (see \Layer#drc and \DRC#squares for more details).
|
||||
|
||||
# %DRC%
|
||||
# @name rectilinear
|
||||
# @brief Selects all polygons which are rectilinear
|
||||
|
|
@ -623,6 +658,7 @@ CODE
|
|||
odd_polygons
|
||||
perimeter
|
||||
rectangles
|
||||
squares
|
||||
rectilinear
|
||||
length
|
||||
angle
|
||||
|
|
|
|||
|
|
@ -517,6 +517,106 @@ CODE
|
|||
end
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name with_bbox_aspect_ratio
|
||||
# @brief Selects polygons by the aspect ratio of their bounding box
|
||||
# @synopsis layer.with_bbox_aspect_ratio(min .. max)
|
||||
# @synopsis layer.with_bbox_aspect_ratio(value)
|
||||
# @synopsis layer.with_bbox_aspect_ratio(min, max)
|
||||
# The method selects polygons similar to \with_area or \with_perimeter.
|
||||
# However, the measured value is the aspect ratio of the bounding
|
||||
# box. It is the larger dimensions divided by the smaller one.
|
||||
# The "thinner" the polygon, the larger the aspect ratio. A square
|
||||
# bounding box gives an aspect ratio of 1.
|
||||
#
|
||||
# This method is available for polygon layers only.
|
||||
|
||||
# %DRC%
|
||||
# @name without_bbox_height
|
||||
# @brief Selects polygons by the aspect ratio of their bounding box
|
||||
# @synopsis layer.without_bbox_aspect_ratio(min .. max)
|
||||
# @synopsis layer.without_bbox_aspect_ratio(value)
|
||||
# @synopsis layer.without_bbox_aspect_ratio(min, max)
|
||||
# The method provides the opposite filter for \with_bbox_aspect_ratio.
|
||||
#
|
||||
# This method is available for polygon layers only.
|
||||
|
||||
# %DRC%
|
||||
# @name with_area_ratio
|
||||
# @brief Selects polygons by the ratio of the bounding box area vs. polygon area
|
||||
# @synopsis layer.with_area_ratio(min .. max)
|
||||
# @synopsis layer.with_area_ratio(value)
|
||||
# @synopsis layer.with_area_ratio(min, max)
|
||||
# The area ratio is a measure how far a polygon is approximated by it's
|
||||
# bounding box. The value is always larger or equal to 1. Boxes have a
|
||||
# area ratio of 1. Larger values mean more empty area inside the bounding box.
|
||||
#
|
||||
# This method is available for polygon layers only.
|
||||
|
||||
# %DRC%
|
||||
# @name without_area_ratio
|
||||
# @brief Selects polygons by the aspect ratio of their bounding box
|
||||
# @synopsis layer.without_area_ratio(min .. max)
|
||||
# @synopsis layer.without_area_ratio(value)
|
||||
# @synopsis layer.without_area_ratio(min, max)
|
||||
# The method provides the opposite filter for \with_area_ratio.
|
||||
#
|
||||
# This method is available for polygon layers only.
|
||||
|
||||
# %DRC%
|
||||
# @name with_relative_height
|
||||
# @brief Selects polygons by the ratio of the height vs. width of it's bounding box
|
||||
# @synopsis layer.with_relative_height(min .. max)
|
||||
# @synopsis layer.with_relative_height(value)
|
||||
# @synopsis layer.with_relative_height(min, max)
|
||||
# The relative height is a measure how tall a polygon is. Tall polygons
|
||||
# have values larger than 1, wide polygons have a value smaller than 1.
|
||||
# Squares have a value of 1.
|
||||
#
|
||||
# Don't use this method when you can use \with_area_ratio, which provides a
|
||||
# similar measure but is isotropic.
|
||||
#
|
||||
# This method is available for polygon layers only.
|
||||
|
||||
# %DRC%
|
||||
# @name without_relative_height
|
||||
# @brief Selects polygons by the ratio of the height vs. width
|
||||
# @synopsis layer.without_relative_height(min .. max)
|
||||
# @synopsis layer.without_relative_height(value)
|
||||
# @synopsis layer.without_relative_height(min, max)
|
||||
# The method provides the opposite filter for \with_relative_height.
|
||||
#
|
||||
# This method is available for polygon layers only.
|
||||
|
||||
%w(area_ratio bbox_aspect_ratio relative_height).each do |f|
|
||||
[true, false].each do |inv|
|
||||
mn = (inv ? "without" : "with") + "_" + f
|
||||
eval <<"CODE"
|
||||
def #{mn}(*args)
|
||||
|
||||
@engine._context("#{mn}") do
|
||||
|
||||
requires_region
|
||||
if args.size == 1
|
||||
a = args[0]
|
||||
if a.is_a?(Range)
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._prep_value(a.first), @engine._make_numeric_value(a.last), #{inv.inspect}))
|
||||
else
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._prep_value(a), #{inv.inspect}))
|
||||
end
|
||||
elsif args.size == 2
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._prep_value(args[0]), @engine._make_numeric_value(args[1]), #{inv.inspect}))
|
||||
else
|
||||
raise("Invalid number of arguments (1 or 2 expected)")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
CODE
|
||||
end
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name with_length
|
||||
# @brief Selects edges by their length
|
||||
|
|
@ -2332,13 +2432,22 @@ CODE
|
|||
|
||||
# %DRC%
|
||||
# @name rectangles
|
||||
# @brief Selects all rectangle polygons from the input
|
||||
# @brief Selects all rectangles from the input
|
||||
# @synopsis layer.rectangles
|
||||
#
|
||||
# This method is available for polygon layers. By default "merged" semantics applies,
|
||||
# i.e. all polygons are merged before rectangles are selected (see \clean and \raw).
|
||||
# \non_rectangles will select all non-rectangles.
|
||||
|
||||
# %DRC%
|
||||
# @name squares
|
||||
# @brief Selects all squares from the input
|
||||
# @synopsis layer.squares
|
||||
#
|
||||
# This method is available for polygon layers. By default "merged" semantics applies,
|
||||
# i.e. all polygons are merged before squares are selected (see \clean and \raw).
|
||||
# \non_squares will select all non-rectangles.
|
||||
|
||||
# %DRC%
|
||||
# @name rectilinear
|
||||
# @brief Selects all rectilinear polygons from the input
|
||||
|
|
@ -2348,6 +2457,14 @@ CODE
|
|||
# i.e. all polygons are merged before rectilinear polygons are selected (see \clean and \raw).
|
||||
# \non_rectilinear will select all non-rectangles.
|
||||
|
||||
# %DRC%
|
||||
# @name non_squares
|
||||
# @brief Selects all polygons from the input which are not squares
|
||||
# @synopsis layer.non_rectangles
|
||||
#
|
||||
# This method is available for polygon layers. By default "merged" semantics applies,
|
||||
# i.e. all polygons are merged before non-squares are selected (see \clean and \raw).
|
||||
|
||||
# %DRC%
|
||||
# @name non_rectangles
|
||||
# @brief Selects all polygons from the input which are not rectangles
|
||||
|
|
@ -2400,7 +2517,7 @@ CODE
|
|||
# @/tr
|
||||
# @/table
|
||||
|
||||
%w(rectangles rectilinear non_rectangles non_rectilinear
|
||||
%w(rectangles rectilinear non_rectangles non_rectilinear squares non_squares
|
||||
holes hulls).each do |f|
|
||||
eval <<"CODE"
|
||||
def #{f}
|
||||
|
|
|
|||
Loading…
Reference in New Issue