mirror of https://github.com/KLayout/klayout.git
WIP: More documentation for complex DRC ops
This commit is contained in:
parent
7d4310d343
commit
37d62f97e1
|
|
@ -55,6 +55,7 @@ class DRCOpNode
|
||||||
end
|
end
|
||||||
|
|
||||||
def _build_geo_bool_node(other, op)
|
def _build_geo_bool_node(other, op)
|
||||||
|
other = @engine._make_node(other)
|
||||||
if ! other.is_a?(DRCOpNode)
|
if ! other.is_a?(DRCOpNode)
|
||||||
raise("Second argument to #{op.to_s} must be a DRC expression")
|
raise("Second argument to #{op.to_s} must be a DRC expression")
|
||||||
end
|
end
|
||||||
|
|
@ -70,7 +71,7 @@ class DRCOpNode
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name &
|
# @name &
|
||||||
# @brief Boolean AND between the results of two expressions
|
# @brief Boolean AND between the results of two expressions
|
||||||
# @synopsis expr & expr
|
# @synopsis expression & expression
|
||||||
#
|
#
|
||||||
# The & operator will compute the boolean AND between the results
|
# The & operator will compute the boolean AND between the results
|
||||||
# of two expressions. The expression types need to be edge or polygon.
|
# of two expressions. The expression types need to be edge or polygon.
|
||||||
|
|
@ -85,7 +86,7 @@ class DRCOpNode
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name |
|
# @name |
|
||||||
# @brief Boolean OR between the results of two expressions
|
# @brief Boolean OR between the results of two expressions
|
||||||
# @synopsis expr | expr
|
# @synopsis expression | expression
|
||||||
#
|
#
|
||||||
# The | operator will compute the boolean OR between the results of
|
# The | operator will compute the boolean OR between the results of
|
||||||
# two expressions. '+' is basically a synonym. Both expressions
|
# two expressions. '+' is basically a synonym. Both expressions
|
||||||
|
|
@ -94,14 +95,14 @@ class DRCOpNode
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name +
|
# @name +
|
||||||
# @brief Boolean OR between the results of two expressions
|
# @brief Boolean OR between the results of two expressions
|
||||||
# @synopsis expr + expr
|
# @synopsis expression + expression
|
||||||
#
|
#
|
||||||
# The + operator will join the results of two expressions.
|
# The + operator will join the results of two expressions.
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name -
|
# @name -
|
||||||
# @brief Boolean NOT between the results of two expressions
|
# @brief Boolean NOT between the results of two expressions
|
||||||
# @synopsis expr - expr
|
# @synopsis expression - expression
|
||||||
#
|
#
|
||||||
# The - operator will compute the difference between the results
|
# The - operator will compute the difference between the results
|
||||||
# of two expressions. The NOT operation is defined for polygons,
|
# of two expressions. The NOT operation is defined for polygons,
|
||||||
|
|
@ -119,7 +120,7 @@ class DRCOpNode
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name ^
|
# @name ^
|
||||||
# @brief Boolean XOR between the results of two expressions
|
# @brief Boolean XOR between the results of two expressions
|
||||||
# @synopsis expr - expr
|
# @synopsis expression - expression
|
||||||
#
|
#
|
||||||
# The ^ operator will compute the XOR (symmetric difference) between the results
|
# The ^ operator will compute the XOR (symmetric difference) between the results
|
||||||
# of two expressions. The XOR operation is defined for polygons and edges.
|
# of two expressions. The XOR operation is defined for polygons and edges.
|
||||||
|
|
@ -138,7 +139,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name !
|
# @name !
|
||||||
# @brief Logical not
|
# @brief Logical not
|
||||||
# @synopsis ! expr
|
# @synopsis ! expression
|
||||||
#
|
#
|
||||||
# This operator will evaluate the expression after. If this expression renders
|
# This operator will evaluate the expression after. If this expression renders
|
||||||
# an empty result, the operator will return the primary shape. Otherwise it will
|
# an empty result, the operator will return the primary shape. Otherwise it will
|
||||||
|
|
@ -168,7 +169,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name area
|
# @name area
|
||||||
# @brief Selects the primary shape if the area is meeting the condition
|
# @brief Selects the primary shape if the area is meeting the condition
|
||||||
# @synopsis area (in condition)
|
# @synopsis expression.area (in condition)
|
||||||
#
|
#
|
||||||
# This operation is used in conditions to select shapes based on their area.
|
# This operation is used in conditions to select shapes based on their area.
|
||||||
# It is applicable on polygon expressions. The result will be the input
|
# It is applicable on polygon expressions. The result will be the input
|
||||||
|
|
@ -182,6 +183,9 @@ CODE
|
||||||
# out = in.drc(area < 2.0)
|
# out = in.drc(area < 2.0)
|
||||||
# out = in.drc(primary.area < 2.0) # equivalent
|
# out = in.drc(primary.area < 2.0) # equivalent
|
||||||
# @/code
|
# @/code
|
||||||
|
#
|
||||||
|
# The area method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.area".
|
||||||
|
|
||||||
def area
|
def area
|
||||||
DRCOpNodeAreaFilter::new(@engine, self)
|
DRCOpNodeAreaFilter::new(@engine, self)
|
||||||
|
|
@ -190,7 +194,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name count
|
# @name count
|
||||||
# @brief Selects a expression result based on the number of (local) shapes
|
# @brief Selects a expression result based on the number of (local) shapes
|
||||||
# @synopsis count (in condition)
|
# @synopsis expression.count (in condition)
|
||||||
#
|
#
|
||||||
# This operation is used in conditions to select expression results based on their
|
# This operation is used in conditions to select expression results based on their
|
||||||
# count. "count" is used as a method on a expression. It will evaluate the expression locally
|
# count. "count" is used as a method on a expression. It will evaluate the expression locally
|
||||||
|
|
@ -219,7 +223,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name perimeter
|
# @name perimeter
|
||||||
# @brief Selects the primary shape if the perimeter is meeting the condition
|
# @brief Selects the primary shape if the perimeter is meeting the condition
|
||||||
# @synopsis perimeter (in condition)
|
# @synopsis expression.perimeter (in condition)
|
||||||
#
|
#
|
||||||
# This operation is used in conditions to select shapes based on their perimeter.
|
# This operation is used in conditions to select shapes based on their perimeter.
|
||||||
# It is applicable on polygon expressions. The result will be the input
|
# It is applicable on polygon expressions. The result will be the input
|
||||||
|
|
@ -233,6 +237,9 @@ CODE
|
||||||
# out = in.drc(perimeter < 10.0)
|
# out = in.drc(perimeter < 10.0)
|
||||||
# out = in.drc(primary.perimeter < 10.0) # equivalent
|
# out = in.drc(primary.perimeter < 10.0) # equivalent
|
||||||
# @/code
|
# @/code
|
||||||
|
#
|
||||||
|
# The perimeter method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.perimeter".
|
||||||
|
|
||||||
def perimeter
|
def perimeter
|
||||||
DRCOpNodePerimeterFilter::new(@engine, self)
|
DRCOpNodePerimeterFilter::new(@engine, self)
|
||||||
|
|
@ -241,7 +248,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name bbox_min
|
# @name bbox_min
|
||||||
# @brief Selects the primary shape if its bounding box smaller dimension is meeting the condition
|
# @brief Selects the primary shape if its bounding box smaller dimension is meeting the condition
|
||||||
# @synopsis bbox_min (in condition)
|
# @synopsis expression.bbox_min (in condition)
|
||||||
#
|
#
|
||||||
# This operation is used in conditions to select shapes based on smaller dimension of their bounding boxes.
|
# This operation is used in conditions to select shapes based on smaller dimension of their bounding boxes.
|
||||||
# It is applicable on polygon expressions. The result will be the input
|
# It is applicable on polygon expressions. The result will be the input
|
||||||
|
|
@ -256,6 +263,9 @@ CODE
|
||||||
# out = in.drc(bbox_min > 200.nm)
|
# out = in.drc(bbox_min > 200.nm)
|
||||||
# out = in.drc(primary.bbox_min > 200.nm) # equivalent
|
# out = in.drc(primary.bbox_min > 200.nm) # equivalent
|
||||||
# @/code
|
# @/code
|
||||||
|
#
|
||||||
|
# The "bbox_min" method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.bbox_min".
|
||||||
|
|
||||||
def bbox_min
|
def bbox_min
|
||||||
DRCOpNodeBBoxParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::BoxMinDim, self)
|
DRCOpNodeBBoxParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::BoxMinDim, self)
|
||||||
|
|
@ -264,10 +274,13 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name bbox_max
|
# @name bbox_max
|
||||||
# @brief Selects the primary shape if its bounding box larger dimension is meeting the condition
|
# @brief Selects the primary shape if its bounding box larger dimension is meeting the condition
|
||||||
# @synopsis bbox_max (in condition)
|
# @synopsis expression.bbox_max (in condition)
|
||||||
#
|
#
|
||||||
# This operation acts similar to \DRC#bbox_min, but takes the larger dimension of the shape's
|
# This operation acts similar to \DRC#bbox_min, but takes the larger dimension of the shape's
|
||||||
# bounding box.
|
# bounding box.
|
||||||
|
#
|
||||||
|
# The "bbox_max" method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.bbox_max".
|
||||||
|
|
||||||
def bbox_max
|
def bbox_max
|
||||||
DRCOpNodeBBoxParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::BoxMaxDim, self)
|
DRCOpNodeBBoxParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::BoxMaxDim, self)
|
||||||
|
|
@ -276,13 +289,16 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name bbox_width
|
# @name bbox_width
|
||||||
# @brief Selects the primary shape if its bounding box width is meeting the condition
|
# @brief Selects the primary shape if its bounding box width is meeting the condition
|
||||||
# @synopsis bbox_width (in condition)
|
# @synopsis expression.bbox_width (in condition)
|
||||||
#
|
#
|
||||||
# This operation acts similar to \DRC#bbox_min, but takes the width of the shape's
|
# This operation acts similar to \DRC#bbox_min, but takes the width of the shape's
|
||||||
# bounding box. In general, it's more advisable to use \DRC#bbox_min or \DRC#bbox_max
|
# bounding box. In general, it's more advisable to use \DRC#bbox_min or \DRC#bbox_max
|
||||||
# because bbox_width implies a certain orientation. This can imply variant formation in
|
# because bbox_width implies a certain orientation. This can imply variant formation in
|
||||||
# hierarchical contexts: cells rotated by 90 degree have to be treated differently from
|
# hierarchical contexts: cells rotated by 90 degree have to be treated differently from
|
||||||
# ones not rotated. This usually results in a larger computation effort and larger result files.
|
# ones not rotated. This usually results in a larger computation effort and larger result files.
|
||||||
|
#
|
||||||
|
# The "bbox_width" method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.bbox_width".
|
||||||
|
|
||||||
def bbox_width
|
def bbox_width
|
||||||
DRCOpNodeBBoxParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::BoxWidth, self)
|
DRCOpNodeBBoxParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::BoxWidth, self)
|
||||||
|
|
@ -291,13 +307,16 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name bbox_height
|
# @name bbox_height
|
||||||
# @brief Selects the primary shape if its bounding box height is meeting the condition
|
# @brief Selects the primary shape if its bounding box height is meeting the condition
|
||||||
# @synopsis bbox_height (in condition)
|
# @synopsis expression.bbox_height (in condition)
|
||||||
#
|
#
|
||||||
# This operation acts similar to \DRC#bbox_min, but takes the height of the shape's
|
# This operation acts similar to \DRC#bbox_min, but takes the height of the shape's
|
||||||
# bounding box. In general, it's more advisable to use \DRC#bbox_min or \DRC#bbox_max
|
# bounding box. In general, it's more advisable to use \DRC#bbox_min or \DRC#bbox_max
|
||||||
# because bbox_height implies a certain orientation. This can imply variant formation in
|
# because bbox_height implies a certain orientation. This can imply variant formation in
|
||||||
# hierarchical contexts: cells rotated by 90 degree have to be treated differently from
|
# hierarchical contexts: cells rotated by 90 degree have to be treated differently from
|
||||||
# ones not rotated. This usually results in a larger computation effort and larger result files.
|
# ones not rotated. This usually results in a larger computation effort and larger result files.
|
||||||
|
#
|
||||||
|
# The "bbox_height" method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.bbox_height".
|
||||||
|
|
||||||
def bbox_height
|
def bbox_height
|
||||||
DRCOpNodeBBoxParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::BoxHeight, self)
|
DRCOpNodeBBoxParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::BoxHeight, self)
|
||||||
|
|
@ -306,7 +325,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name length
|
# @name length
|
||||||
# @brief Selects edges based on their length
|
# @brief Selects edges based on their length
|
||||||
# @synopsis length (in condition)
|
# @synopsis expression.length (in condition)
|
||||||
#
|
#
|
||||||
# This operation will select those edges which are meeting the length
|
# This operation will select those edges which are meeting the length
|
||||||
# criterion. Non-edge shapes (polygons, edge pairs) will be converted to edges before.
|
# criterion. Non-edge shapes (polygons, edge pairs) will be converted to edges before.
|
||||||
|
|
@ -318,6 +337,9 @@ CODE
|
||||||
# out = in.drc(length >= 1.um)
|
# out = in.drc(length >= 1.um)
|
||||||
# out = in.drc(primary.length >= 1.um) # equivalent
|
# out = in.drc(primary.length >= 1.um) # equivalent
|
||||||
# @/code
|
# @/code
|
||||||
|
#
|
||||||
|
# The "length" method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.length".
|
||||||
|
|
||||||
def length
|
def length
|
||||||
DRCOpNodeEdgeLengthFilter::new(@engine, self)
|
DRCOpNodeEdgeLengthFilter::new(@engine, self)
|
||||||
|
|
@ -326,7 +348,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name angle
|
# @name angle
|
||||||
# @brief Selects edges based on their angle
|
# @brief Selects edges based on their angle
|
||||||
# @synopsis angle (in condition)
|
# @synopsis expression.angle (in condition)
|
||||||
#
|
#
|
||||||
# This operation selects edges by their angle, measured against the horizontal
|
# This operation selects edges by their angle, measured against the horizontal
|
||||||
# axis in the mathematical sense.
|
# axis in the mathematical sense.
|
||||||
|
|
@ -350,6 +372,9 @@ CODE
|
||||||
# are placed unrotated and rotated by 90 degree cannot be considered identical. This imposes
|
# are placed unrotated and rotated by 90 degree cannot be considered identical. This imposes
|
||||||
# a performance penalty in hierarchical mode. If possible, consider using \DRC#rectilinear for
|
# a performance penalty in hierarchical mode. If possible, consider using \DRC#rectilinear for
|
||||||
# example to detect shapes with non-manhattan geometry instead of using angle checks.
|
# example to detect shapes with non-manhattan geometry instead of using angle checks.
|
||||||
|
#
|
||||||
|
# The "angle" method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.angle".
|
||||||
|
|
||||||
def angle
|
def angle
|
||||||
DRCOpNodeEdgeOrientationFilter::new(@engine, self)
|
DRCOpNodeEdgeOrientationFilter::new(@engine, self)
|
||||||
|
|
@ -358,10 +383,13 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name rounded_corners
|
# @name rounded_corners
|
||||||
# @brief Applies corner rounding
|
# @brief Applies corner rounding
|
||||||
# @synopsis rounded_corners(inner, outer, n)
|
# @synopsis expression.rounded_corners(inner, outer, n)
|
||||||
#
|
#
|
||||||
# This operation acts on polygons and applies corner rounding the the given inner
|
# This operation acts on polygons and applies corner rounding the the given inner
|
||||||
# and outer corner radius and the number of points n per full circle.
|
# and outer corner radius and the number of points n per full circle. See \Layer#rounded_corners for more details.
|
||||||
|
#
|
||||||
|
# The "rounded_corners" method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.rounded_corners".
|
||||||
|
|
||||||
def rounded_corners(inner, outer, n)
|
def rounded_corners(inner, outer, n)
|
||||||
@engine._context("rounded_corners") do
|
@engine._context("rounded_corners") do
|
||||||
|
|
@ -373,9 +401,12 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name smoothed
|
# @name smoothed
|
||||||
# @brief Applies smoothing
|
# @brief Applies smoothing
|
||||||
# @synopsis smoothed(d)
|
# @synopsis expression.smoothed(d)
|
||||||
#
|
#
|
||||||
# This operation acts on polygons and applies polygon smoothing with the tolerance d.
|
# This operation acts on polygons and applies polygon smoothing with the tolerance d. See \Layer#smoothed for more details.
|
||||||
|
#
|
||||||
|
# The "smoothed" method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.smoothed".
|
||||||
|
|
||||||
def smoothed(d)
|
def smoothed(d)
|
||||||
@engine._context("smoothed") do
|
@engine._context("smoothed") do
|
||||||
|
|
@ -386,9 +417,9 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name corners (in condition)
|
# @name corners (in condition)
|
||||||
# @brief Applies smoothing
|
# @brief Applies smoothing
|
||||||
# @synopsis corners
|
# @synopsis expression.corners
|
||||||
# @synopsis corners(as_dots)
|
# @synopsis expression.corners(as_dots)
|
||||||
# @synopsis corners(as_boxes)
|
# @synopsis expression.corners(as_boxes)
|
||||||
#
|
#
|
||||||
# This operation acts on polygons and selects the corners of the polygons.
|
# This operation acts on polygons and selects the corners of the polygons.
|
||||||
# It can be put into a condition to select corners by their angles. The angle of
|
# It can be put into a condition to select corners by their angles. The angle of
|
||||||
|
|
@ -412,6 +443,9 @@ CODE
|
||||||
# out = in.drc(corners < 0)
|
# out = in.drc(corners < 0)
|
||||||
# out = in.drc(primary.corners < 0) # equivalent
|
# out = in.drc(primary.corners < 0) # equivalent
|
||||||
# @/code
|
# @/code
|
||||||
|
#
|
||||||
|
# The "corners" method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.corners".
|
||||||
|
|
||||||
def corners(as_dots = DRCAsDots::new(false))
|
def corners(as_dots = DRCAsDots::new(false))
|
||||||
@engine._context("corners") do
|
@engine._context("corners") do
|
||||||
|
|
@ -427,7 +461,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name middle
|
# @name middle
|
||||||
# @brief Returns the centers of polygon bounding boxes
|
# @brief Returns the centers of polygon bounding boxes
|
||||||
# @synopsis middle([ options ])
|
# @synopsis expression.middle([ options ])
|
||||||
#
|
#
|
||||||
# The middle operation acts on polygons and has the same effect than \Layer#middle.
|
# The middle operation acts on polygons and has the same effect than \Layer#middle.
|
||||||
# It takes the same arguments. It is available as a method on \DRC expressions or
|
# It takes the same arguments. It is available as a method on \DRC expressions or
|
||||||
|
|
@ -436,7 +470,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name extent_refs
|
# @name extent_refs
|
||||||
# @brief Returns partial references to the boundings boxes of the polygons
|
# @brief Returns partial references to the boundings boxes of the polygons
|
||||||
# @synopsis extent_refs([ options ])
|
# @synopsis expression.extent_refs([ options ])
|
||||||
#
|
#
|
||||||
# The extent_refs operation acts on polygons and has the same effect than \Layer#extent_refs.
|
# The extent_refs operation acts on polygons and has the same effect than \Layer#extent_refs.
|
||||||
# It takes the same arguments. It is available as a method on \DRC expressions or
|
# It takes the same arguments. It is available as a method on \DRC expressions or
|
||||||
|
|
@ -518,7 +552,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name odd_polygons
|
# @name odd_polygons
|
||||||
# @brief Selects all polygons which are non-orientable
|
# @brief Selects all polygons which are non-orientable
|
||||||
# @synopsis odd_polygons
|
# @synopsis expression.odd_polygons
|
||||||
#
|
#
|
||||||
# Non-orientable polygons are for example "8"-shape polygons. Such polygons are
|
# Non-orientable polygons are for example "8"-shape polygons. Such polygons are
|
||||||
# usually considered harmful as their definition of covered area is depending on the
|
# usually considered harmful as their definition of covered area is depending on the
|
||||||
|
|
@ -534,7 +568,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name rectangles
|
# @name rectangles
|
||||||
# @brief Selects all polygons which are rectangles
|
# @brief Selects all polygons which are rectangles
|
||||||
# @synopsis rectangles
|
# @synopsis expression.rectangles
|
||||||
#
|
#
|
||||||
# This operation can be used as a plain function in which case it acts on primary
|
# 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.
|
# shapes or can be used as method on another DRC expression.
|
||||||
|
|
@ -552,7 +586,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name rectilinear
|
# @name rectilinear
|
||||||
# @brief Selects all polygons which are rectilinear
|
# @brief Selects all polygons which are rectilinear
|
||||||
# @synopsis rectilinear
|
# @synopsis expression.rectilinear
|
||||||
#
|
#
|
||||||
# Rectilinear polygons only have vertical and horizontal edges. Such polygons are also
|
# Rectilinear polygons only have vertical and horizontal edges. Such polygons are also
|
||||||
# called manhattan polygons.
|
# called manhattan polygons.
|
||||||
|
|
@ -573,7 +607,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name holes
|
# @name holes
|
||||||
# @brief Selects all holes from the input polygons
|
# @brief Selects all holes from the input polygons
|
||||||
# @synopsis holes
|
# @synopsis expression.holes
|
||||||
#
|
#
|
||||||
# This operation can be used as a plain function in which case it acts on primary
|
# 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.
|
# shapes or can be used as method on another DRC expression.
|
||||||
|
|
@ -591,7 +625,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name hulls
|
# @name hulls
|
||||||
# @brief Selects all hulls from the input polygons
|
# @brief Selects all hulls from the input polygons
|
||||||
# @synopsis hulls
|
# @synopsis expression.hulls
|
||||||
#
|
#
|
||||||
# The hulls are the outer contours of the input polygons. By selecting hulls only,
|
# The hulls are the outer contours of the input polygons. By selecting hulls only,
|
||||||
# all holes will be closed.
|
# all holes will be closed.
|
||||||
|
|
@ -612,7 +646,7 @@ CODE
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name edges
|
# @name edges
|
||||||
# @brief Converts the input shapes into edges
|
# @brief Converts the input shapes into edges
|
||||||
# @synopsis edges
|
# @synopsis expression.edges
|
||||||
#
|
#
|
||||||
# Polygons will be separated into edges forming their contours. Edge pairs will be
|
# Polygons will be separated into edges forming their contours. Edge pairs will be
|
||||||
# decomposed into individual edges.
|
# decomposed into individual edges.
|
||||||
|
|
@ -633,8 +667,8 @@ CODE
|
||||||
# %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
|
||||||
# @synopsis merged
|
# @synopsis expression.merged
|
||||||
# @synopsis merged(min_count)
|
# @synopsis expression.merged(min_count)
|
||||||
#
|
#
|
||||||
# This operation will act on polygons. Without a min_count argument, the merged
|
# This operation will act on polygons. Without a min_count argument, the merged
|
||||||
# polygons will be returned.
|
# polygons will be returned.
|
||||||
|
|
@ -642,6 +676,9 @@ CODE
|
||||||
# With a min_count argument, the result will include only those parts where more
|
# With a min_count argument, the result will include only those parts where more
|
||||||
# than the given number of polygons overlap. As the primary input is merged already,
|
# than the given number of polygons overlap. As the primary input is merged already,
|
||||||
# it will always contribute as one.
|
# it will always contribute as one.
|
||||||
|
#
|
||||||
|
# The "merged" method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.merged".
|
||||||
|
|
||||||
def merged(*args)
|
def merged(*args)
|
||||||
|
|
||||||
|
|
@ -664,7 +701,17 @@ CODE
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# ....
|
# %DRC%
|
||||||
|
# @name sized
|
||||||
|
# @brief Returns the sized version of the input
|
||||||
|
# @synopsis expression.sized(d [, mode])
|
||||||
|
# @synopsis expression.sized(dx, dy [, mode]))
|
||||||
|
#
|
||||||
|
# This method provides the same functionality as \Layer#sized and takes the same
|
||||||
|
# arguments. It acts on polygon expressions.
|
||||||
|
#
|
||||||
|
# The "sized" method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.sized".
|
||||||
|
|
||||||
def sized(*args)
|
def sized(*args)
|
||||||
|
|
||||||
|
|
@ -701,12 +748,40 @@ CODE
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name extents
|
||||||
|
# @brief Returns the bounding box of each input object
|
||||||
|
# @synopsis expression.extents([ enlargement ])
|
||||||
|
#
|
||||||
|
# This method provides the same functionality as \Layer#extents and takes the same
|
||||||
|
# arguments. It returns the bounding boxes of the input objects. It acts on edge
|
||||||
|
# edge pair and polygon expressions.
|
||||||
|
#
|
||||||
|
# The "extents" method is available as a plain function or as a method on \DRC expressions.
|
||||||
|
# The plain function is equivalent to "primary.extents".
|
||||||
|
|
||||||
def extents(e = 0)
|
def extents(e = 0)
|
||||||
@engine._context("extents") do
|
@engine._context("extents") do
|
||||||
DRCOpNodeFilter::new(@engine, self, :new_extents, "extents", @engine._make_value(e))
|
DRCOpNodeFilter::new(@engine, self, :new_extents, "extents", @engine._make_value(e))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name first_edges
|
||||||
|
# @brief Returns the first edges of edge pairs
|
||||||
|
# @synopsis expression.extents([ enlargement ])
|
||||||
|
#
|
||||||
|
# This method acts on edge pair expressions and returns the first edges of the
|
||||||
|
# edge pairs delivered by the expression.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name second_edges
|
||||||
|
# @brief Returns the second edges of edge pairs
|
||||||
|
# @synopsis expression.extents([ enlargement ])
|
||||||
|
#
|
||||||
|
# This method acts on edge pair expressions and returns the second edges of the
|
||||||
|
# edge pairs delivered by the expression.
|
||||||
|
|
||||||
def first_edges
|
def first_edges
|
||||||
DRCOpNodeFilter::new(@engine, self, :new_edge_pair_to_first_edges, "first_edges")
|
DRCOpNodeFilter::new(@engine, self, :new_edge_pair_to_first_edges, "first_edges")
|
||||||
end
|
end
|
||||||
|
|
@ -715,6 +790,33 @@ CODE
|
||||||
DRCOpNodeFilter::new(@engine, self, :new_edge_pair_to_second_edges, "second_edges")
|
DRCOpNodeFilter::new(@engine, self, :new_edge_pair_to_second_edges, "second_edges")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name end_segments
|
||||||
|
# @brief Returns the part at the end of each edge of the input
|
||||||
|
# @synopsis expression.end_segments(length)
|
||||||
|
# @synopsis expression.end_segments(length, fraction)
|
||||||
|
#
|
||||||
|
# This method acts on edge expressions and delivers a specific part of each edge.
|
||||||
|
# See \layer#end_segments for details about this functionality.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name start_segments
|
||||||
|
# @brief Returns the part at the beginning of each edge of the input
|
||||||
|
# @synopsis expression.start_segments(length)
|
||||||
|
# @synopsis expression.start_segments(length, fraction)
|
||||||
|
#
|
||||||
|
# This method acts on edge expressions and delivers a specific part of each edge.
|
||||||
|
# See \layer#start_segments for details about this functionality.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name centers
|
||||||
|
# @brief Returns the part at the center of each edge of the input
|
||||||
|
# @synopsis expression.centers(length)
|
||||||
|
# @synopsis expression.end_segments(length, fraction)
|
||||||
|
#
|
||||||
|
# This method acts on edge expressions and delivers a specific part of each edge.
|
||||||
|
# See \layer#centers for details about this functionality.
|
||||||
|
|
||||||
def end_segments(length, fraction = 0.0)
|
def end_segments(length, fraction = 0.0)
|
||||||
@engine._context("end_segments") do
|
@engine._context("end_segments") do
|
||||||
@engine._check_numeric(fraction)
|
@engine._check_numeric(fraction)
|
||||||
|
|
@ -735,6 +837,18 @@ CODE
|
||||||
DRCOpNodeFilter::new(@engine, self, :new_centers, "centers", @engine._make_value(length), fraction)
|
DRCOpNodeFilter::new(@engine, self, :new_centers, "centers", @engine._make_value(length), fraction)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name extended
|
||||||
|
# @brief Returns polygons describing an area along the edges of the input
|
||||||
|
# @synopsis expression.extended([:begin => b,] [:end => e,] [:out => o,] [:in => i], [:joined => true])
|
||||||
|
# @synopsis expression.extended(b, e, o, i)
|
||||||
|
#
|
||||||
|
# This method acts on edge expressions.
|
||||||
|
# It will create a polygon for each edge
|
||||||
|
# tracing the edge with certain offsets to the edge. "o" is the offset applied to the
|
||||||
|
# outer side of the edge, "i" is the offset applied to the inner side of the edge.
|
||||||
|
# "b" is the offset applied at the beginning and "e" is the offset applied at the end.
|
||||||
|
|
||||||
def extended(*args)
|
def extended(*args)
|
||||||
|
|
||||||
|
|
@ -761,6 +875,30 @@ CODE
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name extended_in
|
||||||
|
# @brief Returns polygons describing an area along the edges of the input
|
||||||
|
# @synopsis expression.extended_in(d)
|
||||||
|
#
|
||||||
|
# This method acts on edge expressions. Polygons are generated for
|
||||||
|
# each edge describing the edge drawn with a certain width extending into
|
||||||
|
# the "inside" (the right side when looking from start to end).
|
||||||
|
# This method is basically equivalent to the \extended method:
|
||||||
|
# "extended(0, 0, 0, dist)".
|
||||||
|
# A version extending to the outside is \extended_out.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name extended_out
|
||||||
|
# @brief Returns polygons describing an area along the edges of the input
|
||||||
|
# @synopsis expression.extended_out(d)
|
||||||
|
#
|
||||||
|
# This method acts on edge expressions. Polygons are generated for
|
||||||
|
# each edge describing the edge drawn with a certain width extending into
|
||||||
|
# the "outside" (the left side when looking from start to end).
|
||||||
|
# This method is basically equivalent to the \extended method:
|
||||||
|
# "extended(0, 0, dist, 0)".
|
||||||
|
# A version extending to the inside is \extended_in.
|
||||||
|
|
||||||
def extended_in(e)
|
def extended_in(e)
|
||||||
@engine._context("extended_in") do
|
@engine._context("extended_in") do
|
||||||
DRCOpNodeFilter::new(@engine, self, :new_extended_in, "extended_in", self._make_value(e))
|
DRCOpNodeFilter::new(@engine, self, :new_extended_in, "extended_in", self._make_value(e))
|
||||||
|
|
@ -773,9 +911,30 @@ CODE
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def polygons
|
# %DRC%
|
||||||
|
# @name polygons
|
||||||
|
# @brief Converts the input shapes into polygons
|
||||||
|
# @synopsis expression.polygons([ enlargement ])
|
||||||
|
#
|
||||||
|
# Generates polygons from the input shapes. Polygons stay polygons. Edges and edge pairs
|
||||||
|
# are converted to polygons. For this, the enlargement parameter will specify the
|
||||||
|
# edge thickness or augmentation applied to edge pairs. With the default enlargement
|
||||||
|
# of zero edges will not be converted to valid polygons and degenerated edge pairs
|
||||||
|
# will not become valid polygons as well.
|
||||||
|
#
|
||||||
|
# Contrary most other operations, "polygons" does not have a plain function equivalent
|
||||||
|
# as this is reserved for the function generating a polygon layer.
|
||||||
|
#
|
||||||
|
# This method is useful for generating polygons from DRC violation markers as shown in
|
||||||
|
# the following example:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# out = in.drc((width < 0.5.um).polygons)
|
||||||
|
# @/code
|
||||||
|
|
||||||
|
def polygons(e = 0)
|
||||||
@engine._context("polygons") do
|
@engine._context("polygons") do
|
||||||
DRCOpNodeFilter::new(@engine, self, :new_polygons, "polygons")
|
DRCOpNodeFilter::new(@engine, self, :new_polygons, "polygons", self._make_value(e))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,73 @@ module DRC
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name drc
|
# @name drc
|
||||||
# @brief Universal DRC function
|
# @brief Provides a generic DRC function for use with \DRC expressions
|
||||||
# @synopsis drc(...)
|
# @synopsis layer.drc(expression)
|
||||||
#
|
#
|
||||||
# TODO: add doc
|
# This method implement the universal DRC which offers enhanced abilities,
|
||||||
|
# improved performance in some applications and better readability.
|
||||||
|
#
|
||||||
|
# The key concept for this method are DRC expressions. DRC expressions
|
||||||
|
# are formed by using predefined keywords like "width", operators like "&"
|
||||||
|
# and method to build an abstract definition of the operations to perform
|
||||||
|
# within the DRC.
|
||||||
|
#
|
||||||
|
# When the DRC function is executed, it will basically visit all shapes
|
||||||
|
# from the input layer (the one, the "drc" method is called on), collect
|
||||||
|
# the neighbor shapes from all involved other inputs and run the requested
|
||||||
|
# operations on each cluster. Currently, "drc" is only available for polygon
|
||||||
|
# layers.
|
||||||
|
#
|
||||||
|
# The nature of the "drc" operation is that of the loop over all (merged) input
|
||||||
|
# polygons. Within the operation executed on each shape, it's possible to make
|
||||||
|
# decisions such as "if the shape has an area larger than something, apply this
|
||||||
|
# operation" etc. This can be achieved with conventional DRC functions too,
|
||||||
|
# but involves potentially complex and heavy operations such as booleans, interact
|
||||||
|
# etc. For this reason, the "drc" function may provide a performance benefit.
|
||||||
|
#
|
||||||
|
# In addition, within the loop, a single shape from the input layer is presented to
|
||||||
|
# execution engine which runs the operations.
|
||||||
|
# This allows using operations such as "size" without having to consider
|
||||||
|
# neigbor polygons growing into the area of the initial shape. In this sense,
|
||||||
|
# the "drc" function allows seeing the layer as individual polygons rather than
|
||||||
|
# a global "sea of polygons". This enables new applications which are otherwise
|
||||||
|
# difficult to implement.
|
||||||
|
#
|
||||||
|
# An important concept in the context of "drc" expressions is the "primary".
|
||||||
|
# This expression represents a single primary shape. "Secondaries" are shapes
|
||||||
|
# from other inputs. Primary shapes guide the operation - secondaries without
|
||||||
|
# primaries are not seen. The "drc" operation will look for secondaries within
|
||||||
|
# a certain distance which is determined from the operations within the
|
||||||
|
# expression to execute. The secondaries collected in this step will not be
|
||||||
|
# merged, so the secondary polygons may be partial. This is important when
|
||||||
|
# using measurement operations like "area" on secondary polygons.
|
||||||
|
#
|
||||||
|
# Here is an example for a generic DRC operation which performs a width
|
||||||
|
# check for less than 0.5.um on the primary shapes.
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# out = in.drc(width < 0.5.um)
|
||||||
|
# @/code
|
||||||
|
#
|
||||||
|
# Another example computes a boolean AND between two layers before selecting
|
||||||
|
# the ones with an area larger than 1 square micrometer:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# other = ... another layer ..
|
||||||
|
# out = in.drc((primary & other).area > 1.0)
|
||||||
|
# @/code
|
||||||
|
#
|
||||||
|
# The last example shows how the "drc" operation can improve performance: as the
|
||||||
|
# boolean operation is computed locally and the result is discarded when no longer required,
|
||||||
|
# less shapes need to be stored hence reducing the memory overhead and CPU time required
|
||||||
|
# to manage these shapes.
|
||||||
|
#
|
||||||
|
# For more details about the expression see the \DRC class documentation.
|
||||||
|
|
||||||
def drc(op)
|
def drc(op)
|
||||||
@engine._context("drc") do
|
@engine._context("drc") do
|
||||||
requires_region
|
requires_region
|
||||||
|
expr.is_a?(DRCOpNode) || raise("A DRC expression is required for the argument (got #{expr.inspect})")
|
||||||
return DRCLayer::new(@engine, self.data.complex_op(op.create_node({})))
|
return DRCLayer::new(@engine, self.data.complex_op(op.create_node({})))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -52,6 +111,8 @@ module DRC
|
||||||
|
|
||||||
anum = 1
|
anum = 1
|
||||||
|
|
||||||
|
args = args.collect { |a| self._make_node(a) }
|
||||||
|
|
||||||
types = []
|
types = []
|
||||||
args.each do |a|
|
args.each do |a|
|
||||||
if !a.is_a?(DRCOpNode)
|
if !a.is_a?(DRCOpNode)
|
||||||
|
|
@ -116,6 +177,33 @@ module DRC
|
||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name foreign
|
||||||
|
# @brief Represents all other polygons from primary except the current one
|
||||||
|
# @synopsis foreign
|
||||||
|
#
|
||||||
|
# The primary input of the universal DRC function is the layer the \drc function
|
||||||
|
# is called on. This operation represents all "other" primary polygons while
|
||||||
|
# \primary represents the current polygon.
|
||||||
|
#
|
||||||
|
# This feature opens new options for processing layouts beyond the
|
||||||
|
# abilities of the classical DRC concept. For classic DRC, intra-layer interactions
|
||||||
|
# are always symmetric: a polygon cannot be considered separated from it's neighbors
|
||||||
|
# on the same layer.
|
||||||
|
#
|
||||||
|
# The following example computes every part of the input which is closer than
|
||||||
|
# 0.5 micrometers to other (disconnected) polygons on the same layer:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# out = in.drc(primary & foreign.sized(0.5.um))
|
||||||
|
# @/code
|
||||||
|
|
||||||
|
def primary
|
||||||
|
res = DRCOpNode::new(self, RBA::CompoundRegionOperationNode::new_primary)
|
||||||
|
res.description = "primary"
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name if_all
|
# @name if_all
|
||||||
# @brief Evaluates to the primary shape when all condition expression results are non-empty
|
# @brief Evaluates to the primary shape when all condition expression results are non-empty
|
||||||
|
|
@ -160,6 +248,8 @@ module DRC
|
||||||
|
|
||||||
self._context("#{f}") do
|
self._context("#{f}") do
|
||||||
|
|
||||||
|
args = args.collect { |a| self._make_node(a) }
|
||||||
|
|
||||||
args.each_with_index do |a,ia|
|
args.each_with_index do |a,ia|
|
||||||
if ! a.is_a?(DRCOpNode)
|
if ! a.is_a?(DRCOpNode)
|
||||||
raise("Argument #" + (ia + 1).to_s + " to #{f} must be a DRC expression")
|
raise("Argument #" + (ia + 1).to_s + " to #{f} must be a DRC expression")
|
||||||
|
|
@ -223,6 +313,83 @@ CODE
|
||||||
CODE
|
CODE
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name area
|
||||||
|
# @brief Selects the primary shape if the area is meeting the condition
|
||||||
|
# @synopsis area (in condition)
|
||||||
|
# @synopsis area(layer)
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.area" (see \Layer#area). Without a layer
|
||||||
|
# argument, "area" represents an area filter for primary shapes in
|
||||||
|
# \DRC expressions (see \drc and \DRC#area for more details).
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name hulls
|
||||||
|
# @brief Selects all hulls from the input polygons
|
||||||
|
# @synopsis hulls
|
||||||
|
# @synopsis hulls(layer)
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.hulls" (see \Layer#hulls). Without a layer
|
||||||
|
# argument, "hulls" represents a hull contour extractor for primary shapes in
|
||||||
|
# \DRC expressions (see \drc and \DRC#hulls for more details).
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name holes
|
||||||
|
# @brief Selects all holes from the input polygons
|
||||||
|
# @synopsis holes
|
||||||
|
# @synopsis holes(layer)
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.holes" (see \Layer#hulls). Without a layer
|
||||||
|
# argument, "holes" represents a hole extractor for primary shapes in
|
||||||
|
# \DRC expressions (see \drc and \DRC#hulls for more details).
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name odd_polygons
|
||||||
|
# @brief Selects all polygons which are non-orientable
|
||||||
|
# @synopsis odd_polygons
|
||||||
|
# @synopsis odd_polygons(layer)
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.odd_polygons" (see \Layer#odd_polygons). Without a layer
|
||||||
|
# argument, "odd_polygons" represents an odd polygon filter for primary shapes in
|
||||||
|
# \DRC expressions (see \drc and \DRC#odd_polygons for more details).
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name perimeter
|
||||||
|
# @brief Selects the primary shape if the perimeter is meeting the condition
|
||||||
|
# @synopsis perimeter (in condition)
|
||||||
|
# @synopsis perimeter(layer)
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.perimeter" (see \Layer#perimeter). Without a layer
|
||||||
|
# argument, "perimeter" represents a perimeter filter for primary shapes in
|
||||||
|
# \DRC expressions (see \drc and \DRC#perimeter for more details).
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name rectangles
|
||||||
|
# @brief Selects all polygons which are rectangles
|
||||||
|
# @synopsis rectangles
|
||||||
|
# @synopsis rectangles(layer)
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.rectangles" (see \Layer#rectangles). Without a layer
|
||||||
|
# argument, "rectangles" represents the rectangles filter for primary shapes in
|
||||||
|
# \DRC expressions (see \drc and \DRC#rectangles for more details).
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name rectilinear
|
||||||
|
# @brief Selects all polygons which are rectilinear
|
||||||
|
# @synopsis rectilinear
|
||||||
|
# @synopsis rectilinear(layer)
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.rectilinear" (see \Layer#rectilinear). Without a layer
|
||||||
|
# argument, "rectilinear" represents the rectilinear polygons filter for primary shapes in
|
||||||
|
# \DRC expressions (see \drc and \DRC#rectilinear for more details).
|
||||||
|
|
||||||
%w(
|
%w(
|
||||||
area
|
area
|
||||||
holes
|
holes
|
||||||
|
|
@ -240,11 +407,90 @@ CODE
|
||||||
CODE
|
CODE
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name corners
|
||||||
|
# @brief Selects all polygons which are rectilinear
|
||||||
|
# @synopsis corners (in condition)
|
||||||
|
# @synopsis corners(layer)
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.corners" (see \Layer#corners). Without a layer
|
||||||
|
# argument, "corners" represents the corner generator/filter in primary shapes for
|
||||||
|
# \DRC expressions (see \drc and \DRC#corners for more details).
|
||||||
|
|
||||||
def _cop_corners(as_dots = DRCAsDots::new(false))
|
def _cop_corners(as_dots = DRCAsDots::new(false))
|
||||||
# NOTE: this method is a fallback for the respective global ones which route to DRCLayer or here.
|
# NOTE: this method is a fallback for the respective global ones which route to DRCLayer or here.
|
||||||
return primary.corners(as_dots)
|
return primary.corners(as_dots)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name extent_refs
|
||||||
|
# @brief Returns partial references to the boundings boxes of the polygons
|
||||||
|
# @synopsis extent_refs([ options ])
|
||||||
|
# @synopsis extent_refs(layer, [ options ])
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.extent_refs" (see \Layer#extent_refs). Without a layer
|
||||||
|
# argument, "extent_refs" represents the partial extents extractor on primary shapes within
|
||||||
|
# \DRC expressions (see \drc and \DRC#extent_refs for more details).
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name extents
|
||||||
|
# @brief Returns the bounding box of each input object
|
||||||
|
# @synopsis extents([ enlargement ])
|
||||||
|
# @synopsis extents(layer, [ enlargement ])
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.extents" (see \Layer#extents). Without a layer
|
||||||
|
# argument, "extents" represents the extents generator on primary shapes within
|
||||||
|
# \DRC expressions (see \drc and \DRC#extents for more details).
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name middle
|
||||||
|
# @brief Returns the centers of polygon bounding boxes
|
||||||
|
# @synopsis middle([ options ])
|
||||||
|
# @synopsis middle(layer, [ options ])
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.middle" (see \Layer#middle). Without a layer
|
||||||
|
# argument, "middle" represents the bounding box center marker generator on primary shapes within
|
||||||
|
# \DRC expressions (see \drc and \DRC#middle for more details).
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name rounded_corners
|
||||||
|
# @brief Applies corner rounding
|
||||||
|
# @synopsis rounded_corners(inner, outer, n)
|
||||||
|
# @synopsis rounded_corners(layer, inner, outer, n)
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.rounded_corners" (see \Layer#rounded_corners). Without a layer
|
||||||
|
# argument, "rounded_corners" represents the corner rounding algorithm on primary shapes within
|
||||||
|
# \DRC expressions (see \drc and \DRC#rounded_corners for more details).
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name sized
|
||||||
|
# @brief Returns the sized version of the input
|
||||||
|
# @synopsis sized(d [, mode])
|
||||||
|
# @synopsis sized(dx, dy [, mode]))
|
||||||
|
# @synopsis sized(layer, d [, mode])
|
||||||
|
# @synopsis sized(layer, dx, dy [, mode]))
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.sized" (see \Layer#sized). Without a layer
|
||||||
|
# argument, "sized" represents the polygon sizer on primary shapes within
|
||||||
|
# \DRC expressions (see \drc and \DRC#sized for more details).
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name smoothed
|
||||||
|
# @brief Applies smoothing
|
||||||
|
# @synopsis smoothed(d)
|
||||||
|
# @synopsis smoothed(layer, d)
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.smoothed" (see \Layer#smoothed). Without a layer
|
||||||
|
# argument, "smoothed" represents the polygon smoother on primary shapes within
|
||||||
|
# \DRC expressions (see \drc and \DRC#smoothed for more details).
|
||||||
|
|
||||||
%w(
|
%w(
|
||||||
extent_refs
|
extent_refs
|
||||||
extents
|
extents
|
||||||
|
|
@ -261,6 +507,81 @@ CODE
|
||||||
CODE
|
CODE
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name covering
|
||||||
|
# @brief Selects shapes entirely covering other shapes
|
||||||
|
# @synopsis covering(other) (in conditions)
|
||||||
|
# @synopsis covering(layer, other [, options ])
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.covering" (see \Layer#covering).
|
||||||
|
#
|
||||||
|
# Without a layer argument, this method represents the selector of primary shapes
|
||||||
|
# which entirely cover shapes from the other layer. This version can be put into
|
||||||
|
# a condition indicating how many shapes of the other layer need to be covered.
|
||||||
|
# Use this variant within \DRC expressions (also see \drc).
|
||||||
|
#
|
||||||
|
# For example, the following statement selects all input shapes which entirely
|
||||||
|
# cover shapes from the "other" layer:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# out = in.drc(covering(other))
|
||||||
|
# @/code
|
||||||
|
#
|
||||||
|
# This example selects all input shapes which entire cover shapes from
|
||||||
|
# the other layer and there are more than two shapes from "other" inside
|
||||||
|
# primary shapes:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# out = in.drc(covering(other) > 2)
|
||||||
|
# @/code
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name interacting
|
||||||
|
# @brief Selects shapes interacting with other shapes
|
||||||
|
# @synopsis interacting(other) (in conditions)
|
||||||
|
# @synopsis interacting(layer, other [, options ])
|
||||||
|
#
|
||||||
|
# See \covering for a description of the use cases for this function.
|
||||||
|
# When using "interacting", shapes are selected when the interact (overlap, touch)
|
||||||
|
# shapes from the other layer.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name overlapping
|
||||||
|
# @brief Selects shapes overlapping with other shapes
|
||||||
|
# @synopsis overlapping(other) (in conditions)
|
||||||
|
# @synopsis overlapping(layer, other [, options ])
|
||||||
|
#
|
||||||
|
# See \covering for a description of the use cases for this function.
|
||||||
|
# When using "overlapping", shapes are selected when the overlap
|
||||||
|
# shapes from the other layer.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name inside
|
||||||
|
# @brief Selects shapes entirely inside other shapes
|
||||||
|
# @synopsis inside(other)
|
||||||
|
# @synopsis inside(layer, other)
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.inside" (see \Layer#inside).
|
||||||
|
#
|
||||||
|
# Without a layer argument, this method represents the selector of primary shapes
|
||||||
|
# which are entirely inside shapes from the other layer.
|
||||||
|
# Use this variant within \DRC expressions (also see \drc).
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name outside
|
||||||
|
# @brief Selects shapes entirely outside other shapes
|
||||||
|
# @synopsis outside(other)
|
||||||
|
# @synopsis outside(layer, other)
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.outside" (see \Layer#outside).
|
||||||
|
#
|
||||||
|
# Without a layer argument, this method represents the selector of primary shapes
|
||||||
|
# which are entirely outside shapes from the other layer.
|
||||||
|
# Use this variant within \DRC expressions (also see \drc).
|
||||||
|
|
||||||
%w(
|
%w(
|
||||||
covering
|
covering
|
||||||
inside
|
inside
|
||||||
|
|
@ -276,6 +597,106 @@ CODE
|
||||||
CODE
|
CODE
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name enclosing
|
||||||
|
# @brief Performs an enclosing check
|
||||||
|
# @synopsis enclosing(other [, options ]) (in conditions)
|
||||||
|
# @synopsis enclosing(layer, other [, options ])
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.enclosing" (see \Layer#enclosing).
|
||||||
|
#
|
||||||
|
# The version without the first layer is intended for use within \DRC expressions
|
||||||
|
# together with the \drc method. In this case, this function needs to be
|
||||||
|
# put into a condition to specify the check constraints. The other options
|
||||||
|
# of \Layer#enclosing (e.g. metrics, projection constraints, angle limits etc.)
|
||||||
|
# apply to this version too.
|
||||||
|
#
|
||||||
|
# The conditions can involve an upper and lower limit. The following examples
|
||||||
|
# illustrate the use of this function with conditions:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# out = in.drc(enclosing(other) < 0.2.um)
|
||||||
|
# out = in.drc(enclosing(other) <= 0.2.um)
|
||||||
|
# out = in.drc(enclosing(other) > 0.2.um)
|
||||||
|
# out = in.drc(enclosing(other) >= 0.2.um)
|
||||||
|
# out = in.drc(enclosing(other) == 0.2.um)
|
||||||
|
# out = in.drc(0.1.um <= enclosing(other) < 0.2.um)
|
||||||
|
# @/code
|
||||||
|
#
|
||||||
|
# The result of the enclosing check are edge pairs forming the violation
|
||||||
|
# markers. With a lower limit, these markers are formed by two, identical but opposite edges attached to
|
||||||
|
# the primary shape. Without a lower limit, the first edge of the marker is attached to the
|
||||||
|
# primary shape while the second edge is attached to the shape of the "other" layer.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name separation
|
||||||
|
# @brief Performs a separation check
|
||||||
|
# @synopsis separation(other [, options ]) (in conditions)
|
||||||
|
# @synopsis separation(layer, other [, options ])
|
||||||
|
#
|
||||||
|
# Provides a separation check (primary layer vs. another layer). Like \enclosing this
|
||||||
|
# function provides a two-layer check. See there for details how to use this function.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name overlap
|
||||||
|
# @brief Performs an overlap check
|
||||||
|
# @synopsis overlap(other [, options ]) (in conditions)
|
||||||
|
# @synopsis overlap(layer, other [, options ])
|
||||||
|
#
|
||||||
|
# Provides an overlap check (primary layer vs. another layer). Like \enclosing this
|
||||||
|
# function provides a two-layer check. See there for details how to use this function.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name width
|
||||||
|
# @brief Performs a width check
|
||||||
|
# @synopsis width([ options ]) (in conditions)
|
||||||
|
# @synopsis width(layer [, options ])
|
||||||
|
#
|
||||||
|
# This function can be used with a layer argument in which case it
|
||||||
|
# is equivalent to "layer.width" (see \Layer#width).
|
||||||
|
#
|
||||||
|
# The version without a layer it intended for use within \DRC expressions
|
||||||
|
# together with the \drc method. In this case, this function needs to be
|
||||||
|
# put into a condition to specify the check constraints. The other options
|
||||||
|
# of \Layer#width (e.g. metrics, projection constraints, angle limits etc.)
|
||||||
|
# apply to this version too.
|
||||||
|
#
|
||||||
|
# The conditions can involve an upper and lower limit. The following examples
|
||||||
|
# illustrate the use of this function with conditions:
|
||||||
|
#
|
||||||
|
# @code
|
||||||
|
# out = in.drc(width < 0.2.um)
|
||||||
|
# out = in.drc(width <= 0.2.um)
|
||||||
|
# out = in.drc(width > 0.2.um)
|
||||||
|
# out = in.drc(width >= 0.2.um)
|
||||||
|
# out = in.drc(width == 0.2.um)
|
||||||
|
# out = in.drc(0.1.um <= width < 0.2.um)
|
||||||
|
# @/code
|
||||||
|
#
|
||||||
|
# The result of the width check are edge pairs forming the violation
|
||||||
|
# markers. With a lower limit, these markers are formed by two, identical but opposite edges attached to
|
||||||
|
# the primary shape. Without a lower limit, both edges are attached to different sides of the primary
|
||||||
|
# shape.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name space
|
||||||
|
# @brief Performs a space check
|
||||||
|
# @synopsis space([ options ]) (in conditions)
|
||||||
|
# @synopsis space(layer [, options ])
|
||||||
|
#
|
||||||
|
# Provides a space check on the primary layer. Like \width this
|
||||||
|
# function provides a single-layer check. See there for details how to use this function.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name notch
|
||||||
|
# @brief Performs a notch (intra-polygon space) check
|
||||||
|
# @synopsis notch([ options ]) (in conditions)
|
||||||
|
# @synopsis notch(layer [, options ])
|
||||||
|
#
|
||||||
|
# Provides a intra-polygon space check for polygons from the primary layer. Like \width this
|
||||||
|
# function provides a single-layer check. See there for details how to use this function.
|
||||||
|
|
||||||
%w(
|
%w(
|
||||||
enclosing
|
enclosing
|
||||||
isolated
|
isolated
|
||||||
|
|
@ -313,6 +734,8 @@ CODE
|
||||||
alim = a.value
|
alim = a.value
|
||||||
elsif a.is_a?(DRCOpNode)
|
elsif a.is_a?(DRCOpNode)
|
||||||
other = a
|
other = a
|
||||||
|
elsif a.is_a?(DRCLayer)
|
||||||
|
other = self._make_node(a)
|
||||||
elsif a.is_a?(DRCProjectionLimits)
|
elsif a.is_a?(DRCProjectionLimits)
|
||||||
minp = self._make_value(a.min)
|
minp = self._make_value(a.min)
|
||||||
maxp = self._make_value(a.max)
|
maxp = self._make_value(a.max)
|
||||||
|
|
@ -352,6 +775,27 @@ CODE
|
||||||
CODE
|
CODE
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name iso
|
||||||
|
# @brief Synonym for "isolated"
|
||||||
|
# @synopsis iso(...)
|
||||||
|
#
|
||||||
|
# "iso" is the short form for \isolated.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name sep
|
||||||
|
# @brief Synonym for "separation"
|
||||||
|
# @synopsis sep(...)
|
||||||
|
#
|
||||||
|
# "sep" is the short form for \separation.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name enc
|
||||||
|
# @brief Synonym for "enclosing"
|
||||||
|
# @synopsis enc(...)
|
||||||
|
#
|
||||||
|
# "enc" is the short form for \enclosing.
|
||||||
|
|
||||||
def _cop_iso(*args)
|
def _cop_iso(*args)
|
||||||
# NOTE: this method is a fallback for the respective global ones which route to DRCLayer or here.
|
# NOTE: this method is a fallback for the respective global ones which route to DRCLayer or here.
|
||||||
_cop_isolated(*args)
|
_cop_isolated(*args)
|
||||||
|
|
@ -364,7 +808,15 @@ CODE
|
||||||
|
|
||||||
def _cop_enc(*args)
|
def _cop_enc(*args)
|
||||||
# NOTE: this method is a fallback for the respective global ones which route to DRCLayer or here.
|
# NOTE: this method is a fallback for the respective global ones which route to DRCLayer or here.
|
||||||
_cop_separation(*args)
|
_cop_enclosing(*args)
|
||||||
|
end
|
||||||
|
|
||||||
|
def _make_node(arg)
|
||||||
|
if arg.is_a?(DRCLayer)
|
||||||
|
arg = DRCOpNode::new(self, RBA::CompoundRegionOperationNode::new_secondary(arg.data))
|
||||||
|
arg.description = "secondary"
|
||||||
|
end
|
||||||
|
arg
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1518,6 +1518,32 @@ CODE
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# make some DRCLayer methods available as functions
|
||||||
|
# for the engine
|
||||||
|
%w(
|
||||||
|
enc
|
||||||
|
enclosing
|
||||||
|
overlapping
|
||||||
|
sep
|
||||||
|
separation
|
||||||
|
).each do |f|
|
||||||
|
eval <<"CODE"
|
||||||
|
def #{f}(*args)
|
||||||
|
self._context("#{f}") do
|
||||||
|
if args[0].is_a?(DRCLayer) && args[1].is_a?(DRCLayer)
|
||||||
|
obj = args.shift
|
||||||
|
return obj.#{f}(*args)
|
||||||
|
elsif self.respond_to?(:_cop_#{f})
|
||||||
|
# forward to _cop_ implementation for complex DRC operations
|
||||||
|
return self._cop_#{f}(*args)
|
||||||
|
else
|
||||||
|
raise("Function requires at a layer expression for the first two arguments")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
CODE
|
||||||
|
end
|
||||||
|
|
||||||
# make some DRCLayer methods available as functions
|
# make some DRCLayer methods available as functions
|
||||||
# for the engine
|
# for the engine
|
||||||
%w(
|
%w(
|
||||||
|
|
@ -1528,8 +1554,6 @@ CODE
|
||||||
centers
|
centers
|
||||||
corners
|
corners
|
||||||
covering
|
covering
|
||||||
enc
|
|
||||||
enclosing
|
|
||||||
end_segments
|
end_segments
|
||||||
extended
|
extended
|
||||||
extended_in
|
extended_in
|
||||||
|
|
@ -1572,7 +1596,6 @@ CODE
|
||||||
outside
|
outside
|
||||||
outside_part
|
outside_part
|
||||||
overlap
|
overlap
|
||||||
overlapping
|
|
||||||
perimeter
|
perimeter
|
||||||
pull_inside
|
pull_inside
|
||||||
pull_interacting
|
pull_interacting
|
||||||
|
|
@ -1596,8 +1619,6 @@ CODE
|
||||||
select_outside
|
select_outside
|
||||||
select_overlapping
|
select_overlapping
|
||||||
select_touching
|
select_touching
|
||||||
sep
|
|
||||||
separation
|
|
||||||
size
|
size
|
||||||
sized
|
sized
|
||||||
smoothed
|
smoothed
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue