mirror of https://github.com/KLayout/klayout.git
Tests for new DRC features (square, new attiribute tests)
This commit is contained in:
parent
a8f08bffac
commit
c5859cd957
|
|
@ -862,7 +862,7 @@ gsi::EnumIn<db::CompoundRegionOperationNode, db::RegionBBoxFilter::parameter_typ
|
||||||
"This enum has been introduced in version 0.27."
|
"This enum has been introduced in version 0.27."
|
||||||
);
|
);
|
||||||
|
|
||||||
gsi::EnumIn<db::CompoundRegionOperationNode, db::RegionRatioFilter::parameter_type> decl_dbRegionRatioFilter_ParameterType ("db", "ParameterType",
|
gsi::EnumIn<db::CompoundRegionOperationNode, db::RegionRatioFilter::parameter_type> decl_dbRegionRatioFilter_ParameterType ("db", "RatioParameterType",
|
||||||
gsi::enum_const ("AreaRatio", db::RegionRatioFilter::AreaRatio,
|
gsi::enum_const ("AreaRatio", db::RegionRatioFilter::AreaRatio,
|
||||||
"@brief Measures the area ratio (bounding box area / polygon area)\n"
|
"@brief Measures the area ratio (bounding box area / polygon area)\n"
|
||||||
) +
|
) +
|
||||||
|
|
|
||||||
|
|
@ -399,7 +399,7 @@ CODE
|
||||||
# The plain function is equivalent to "primary.bbox_aspect_ratio".
|
# The plain function is equivalent to "primary.bbox_aspect_ratio".
|
||||||
|
|
||||||
def bbox_aspect_ratio
|
def bbox_aspect_ratio
|
||||||
DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RegionRatioFilter::AspectRatio, self)
|
DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RatioParameterType::AspectRatio, self)
|
||||||
end
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
|
|
@ -430,7 +430,7 @@ CODE
|
||||||
# The plain function is equivalent to "primary.bbox_aspect_ratio".
|
# The plain function is equivalent to "primary.bbox_aspect_ratio".
|
||||||
|
|
||||||
def relative_height
|
def relative_height
|
||||||
DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RegionRatioFilter::RelativeHeight, self)
|
DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RatioParameterType::RelativeHeight, self)
|
||||||
end
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
|
|
@ -459,7 +459,7 @@ CODE
|
||||||
# The plain function is equivalent to "primary.area_ratio".
|
# The plain function is equivalent to "primary.area_ratio".
|
||||||
|
|
||||||
def area_ratio
|
def area_ratio
|
||||||
DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RegionRatioFilter::AreaRatio, self)
|
DRCOpNodeRatioParameterFilter::new(@engine, RBA::CompoundRegionOperationNode::RatioParameterType::AreaRatio, self)
|
||||||
end
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
|
|
@ -1240,7 +1240,7 @@ class DRCOpNodeWithCompare < DRCOpNode
|
||||||
attr_accessor :reverse
|
attr_accessor :reverse
|
||||||
attr_accessor :original
|
attr_accessor :original
|
||||||
attr_accessor :lt, :le, :gt, :ge, :arg
|
attr_accessor :lt, :le, :gt, :ge, :arg
|
||||||
attr_accessor :ne_allowed
|
attr_accessor :mode_or_supported
|
||||||
attr_accessor :mode_or
|
attr_accessor :mode_or
|
||||||
|
|
||||||
def initialize(engine, original = nil, reverse = false)
|
def initialize(engine, original = nil, reverse = false)
|
||||||
|
|
@ -1249,7 +1249,7 @@ class DRCOpNodeWithCompare < DRCOpNode
|
||||||
self.original = original
|
self.original = original
|
||||||
self.description = original ? original.description : "BasicWithCompare"
|
self.description = original ? original.description : "BasicWithCompare"
|
||||||
self.mode_or = false
|
self.mode_or = false
|
||||||
self.ne_allowed = false
|
self.mode_or_supported = false
|
||||||
end
|
end
|
||||||
|
|
||||||
def _description_for_dump
|
def _description_for_dump
|
||||||
|
|
@ -1313,17 +1313,21 @@ class DRCOpNodeWithCompare < DRCOpNode
|
||||||
end
|
end
|
||||||
|
|
||||||
def !=(other)
|
def !=(other)
|
||||||
if !self.ne_allowed
|
if self.respond_to?(:inverted)
|
||||||
raise("!= operator is not allowed for '" + self.description + "'")
|
res = self.==(other).inverted
|
||||||
|
else
|
||||||
|
if !self.mode_or_supported
|
||||||
|
raise("!= operator is not allowed for '" + self.description + "'")
|
||||||
|
end
|
||||||
|
if !(other.is_a?(Float) || other.is_a?(Integer))
|
||||||
|
raise("!= operator needs a numerical argument for '" + self.description + "' argument")
|
||||||
|
end
|
||||||
|
res = self._self_or_original
|
||||||
|
res.mode_or = true
|
||||||
|
res.set_lt(other)
|
||||||
|
res.set_gt(other)
|
||||||
end
|
end
|
||||||
if !(other.is_a?(Float) || other.is_a?(Integer))
|
res
|
||||||
raise("!= operator needs a numerical argument for '" + self.description + "' argument")
|
|
||||||
end
|
|
||||||
res = self._self_or_original
|
|
||||||
res.mode_or = true
|
|
||||||
res.set_lt(other)
|
|
||||||
res.set_gt(other)
|
|
||||||
return res
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def ==(other)
|
def ==(other)
|
||||||
|
|
@ -1680,7 +1684,7 @@ class DRCOpNodeCheck < DRCOpNodeWithCompare
|
||||||
self.other = other
|
self.other = other
|
||||||
self.args = args
|
self.args = args
|
||||||
self.description = check.to_s
|
self.description = check.to_s
|
||||||
self.ne_allowed = true
|
self.mode_or_supported = true
|
||||||
end
|
end
|
||||||
|
|
||||||
def _description_for_dump
|
def _description_for_dump
|
||||||
|
|
@ -1772,6 +1776,39 @@ class DRCOpNodeBBoxParameterFilter < DRCOpNodeWithCompare
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class DRCOpNodeRatioParameterFilter < DRCOpNodeWithCompare
|
||||||
|
|
||||||
|
attr_accessor :input
|
||||||
|
attr_accessor :parameter
|
||||||
|
attr_accessor :inverse
|
||||||
|
|
||||||
|
def initialize(engine, parameter, input)
|
||||||
|
super(engine)
|
||||||
|
self.parameter = parameter
|
||||||
|
self.input = input
|
||||||
|
self.inverse = false
|
||||||
|
self.description = parameter.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_create_node(cache)
|
||||||
|
args = [ self.input.create_node(cache), self.parameter, self.inverse ]
|
||||||
|
args << (self.gt ? self.gt : (self.ge ? self.ge : 0.0))
|
||||||
|
args << (self.gt ? false : true)
|
||||||
|
if self.lt || self.le
|
||||||
|
args << (self.lt ? self.lt : self.le)
|
||||||
|
args << (self.lt ? false : true)
|
||||||
|
end
|
||||||
|
RBA::CompoundRegionOperationNode::new_ratio_filter(*args)
|
||||||
|
end
|
||||||
|
|
||||||
|
def inverted
|
||||||
|
res = self.dup
|
||||||
|
res.inverse = !res.inverse
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
class DRCOpNodeCornersFilter < DRCOpNodeWithCompare
|
class DRCOpNodeCornersFilter < DRCOpNodeWithCompare
|
||||||
|
|
||||||
attr_accessor :input
|
attr_accessor :input
|
||||||
|
|
|
||||||
|
|
@ -652,16 +652,16 @@ CODE
|
||||||
# the operation acts similar to \Layer#with_angle.
|
# the operation acts similar to \Layer#with_angle.
|
||||||
|
|
||||||
%w(
|
%w(
|
||||||
|
angle
|
||||||
area
|
area
|
||||||
holes
|
holes
|
||||||
hulls
|
hulls
|
||||||
|
length
|
||||||
odd_polygons
|
odd_polygons
|
||||||
perimeter
|
perimeter
|
||||||
rectangles
|
rectangles
|
||||||
squares
|
|
||||||
rectilinear
|
rectilinear
|
||||||
length
|
squares
|
||||||
angle
|
|
||||||
).each do |f|
|
).each do |f|
|
||||||
# NOTE: these methods are fallback for the respective global ones which route to DRCLayer or here.
|
# NOTE: these methods are fallback for the respective global ones which route to DRCLayer or here.
|
||||||
eval <<"CODE"
|
eval <<"CODE"
|
||||||
|
|
|
||||||
|
|
@ -1603,6 +1603,7 @@ CODE
|
||||||
moved
|
moved
|
||||||
non_rectangles
|
non_rectangles
|
||||||
non_rectilinear
|
non_rectilinear
|
||||||
|
non_squares
|
||||||
non_strict
|
non_strict
|
||||||
not
|
not
|
||||||
notch
|
notch
|
||||||
|
|
@ -1646,6 +1647,7 @@ CODE
|
||||||
snap
|
snap
|
||||||
snapped
|
snapped
|
||||||
space
|
space
|
||||||
|
squares
|
||||||
start_segments
|
start_segments
|
||||||
strict
|
strict
|
||||||
texts
|
texts
|
||||||
|
|
@ -1656,7 +1658,9 @@ CODE
|
||||||
width
|
width
|
||||||
with_angle
|
with_angle
|
||||||
with_area
|
with_area
|
||||||
|
with_area_ratio
|
||||||
with_bbox_area
|
with_bbox_area
|
||||||
|
with_bbox_area_ratio
|
||||||
with_bbox_height
|
with_bbox_height
|
||||||
with_bbox_max
|
with_bbox_max
|
||||||
with_bbox_min
|
with_bbox_min
|
||||||
|
|
@ -1664,13 +1668,17 @@ CODE
|
||||||
with_length
|
with_length
|
||||||
without_angle
|
without_angle
|
||||||
without_area
|
without_area
|
||||||
|
without_area_ratio
|
||||||
without_bbox
|
without_bbox
|
||||||
|
without_bbox_area_ratio
|
||||||
without_bbox_height
|
without_bbox_height
|
||||||
without_bbox_max
|
without_bbox_max
|
||||||
without_bbox_min
|
without_bbox_min
|
||||||
without_length
|
without_length
|
||||||
without_perimeter
|
without_perimeter
|
||||||
|
without_relative_height
|
||||||
with_perimeter
|
with_perimeter
|
||||||
|
with_relative_height
|
||||||
xor
|
xor
|
||||||
).each do |f|
|
).each do |f|
|
||||||
eval <<"CODE"
|
eval <<"CODE"
|
||||||
|
|
|
||||||
|
|
@ -600,12 +600,12 @@ CODE
|
||||||
if args.size == 1
|
if args.size == 1
|
||||||
a = args[0]
|
a = args[0]
|
||||||
if a.is_a?(Range)
|
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}))
|
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_numeric_value(a.first), @engine._make_numeric_value(a.last), #{inv.inspect}))
|
||||||
else
|
else
|
||||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._prep_value(a), #{inv.inspect}))
|
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_numeric_value(a), #{inv.inspect}))
|
||||||
end
|
end
|
||||||
elsif args.size == 2
|
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}))
|
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, RBA::Region, :with_#{f}, @engine._make_numeric_value(args[0]), @engine._make_numeric_value(args[1]), #{inv.inspect}))
|
||||||
else
|
else
|
||||||
raise("Invalid number of arguments (1 or 2 expected)")
|
raise("Invalid number of arguments (1 or 2 expected)")
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -198,3 +198,13 @@ TEST(13d)
|
||||||
{
|
{
|
||||||
run_test (_this, "13", true);
|
run_test (_this, "13", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(14)
|
||||||
|
{
|
||||||
|
run_test (_this, "14", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(14d)
|
||||||
|
{
|
||||||
|
run_test (_this, "14", true);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1127,3 +1127,13 @@ TEST(25d_spaceWithOptions)
|
||||||
{
|
{
|
||||||
run_test (_this, "25", true);
|
run_test (_this, "25", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(26_attributes)
|
||||||
|
{
|
||||||
|
run_test (_this, "26", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(26d_attributes)
|
||||||
|
{
|
||||||
|
run_test (_this, "26", true);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
ar = 4.0/3.0 # "L" shape
|
||||||
|
l1.drc(area_ratio == ar).output(100, 0)
|
||||||
|
l1.drc(primary.area_ratio != ar).output(101, 0)
|
||||||
|
l1.drc(primary.area_ratio > ar).output(102, 0)
|
||||||
|
l1.drc(primary.area_ratio < ar).output(103, 0)
|
||||||
|
|
||||||
|
l1.drc(squares).output(110, 0)
|
||||||
|
l1.drc(! primary.squares).output(111, 0)
|
||||||
|
|
||||||
|
l2.drc(bbox_aspect_ratio == 2).output(120, 0)
|
||||||
|
l2.drc(bbox_aspect_ratio == 1).output(121, 0)
|
||||||
|
l2.drc(bbox_aspect_ratio <= 1).output(122, 0)
|
||||||
|
l2.drc(bbox_aspect_ratio > 2).output(123, 0)
|
||||||
|
|
||||||
|
l2.drc(relative_height == 2).output(130, 0)
|
||||||
|
l2.drc(relative_height == 1).output(131, 0)
|
||||||
|
l2.drc(relative_height <= 1).output(132, 0)
|
||||||
|
l2.drc(relative_height > 2).output(133, 0)
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,36 @@
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
ar = 4.0/3.0 # "L" shape
|
||||||
|
l1.with_area_ratio(ar).output(100, 0)
|
||||||
|
l1.without_area_ratio(ar).output(101, 0)
|
||||||
|
l1.without_area_ratio(0..ar).output(102, 0)
|
||||||
|
l1.with_area_ratio(0.0, ar-1e-6).output(103, 0)
|
||||||
|
|
||||||
|
l1.squares.output(110, 0)
|
||||||
|
l1.non_squares.output(111, 0)
|
||||||
|
|
||||||
|
l2.with_bbox_aspect_ratio(2).output(120, 0)
|
||||||
|
l2.with_bbox_aspect_ratio(1).output(121, 0)
|
||||||
|
l2.with_bbox_aspect_ratio(0..1).output(122, 0)
|
||||||
|
l2.without_bbox_aspect_ratio(0..2).output(123, 0)
|
||||||
|
|
||||||
|
l2.with_relative_height(2).output(130, 0)
|
||||||
|
l2.with_relative_height(1).output(131, 0)
|
||||||
|
l2.with_relative_height(0..1).output(132, 0)
|
||||||
|
l2.without_relative_height(0..2).output(133, 0)
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue