diff --git a/src/db/db/dbEdgePairFilters.cc b/src/db/db/dbEdgePairFilters.cc
index 9b8d6ff9f..270c37fe2 100644
--- a/src/db/db/dbEdgePairFilters.cc
+++ b/src/db/db/dbEdgePairFilters.cc
@@ -112,7 +112,17 @@ InternalAngleEdgePairFilter::InternalAngleEdgePairFilter (double amin, bool incl
bool
InternalAngleEdgePairFilter::selected (const db::EdgePair &edge_pair) const
{
- return m_checker (edge_pair.first ().d (), -edge_pair.second ().d ()) != m_inverted;
+ db::Vector d1 = edge_pair.first ().d ();
+ db::Vector d2 = edge_pair.second ().d ();
+
+ if (db::sprod_sign (d1, d2) < 0) {
+ d1 = -d1;
+ }
+ if (db::vprod_sign (d1, d2) < 0) {
+ std::swap (d1, d2);
+ }
+
+ return m_checker (d1, d2) != m_inverted;
}
}
diff --git a/src/db/db/gsiDeclDbEdgePairs.cc b/src/db/db/gsiDeclDbEdgePairs.cc
index f7d3073a0..fa41472e7 100644
--- a/src/db/db/gsiDeclDbEdgePairs.cc
+++ b/src/db/db/gsiDeclDbEdgePairs.cc
@@ -724,10 +724,7 @@ Class decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
"edge pairs with the given angle are returned. If \"inverse\" is true, "
"edge pairs not with the given angle are returned.\n"
"\n"
- "The angle is measured between the two edges. Antiparallel edges have an angle of 0, parallel ones an angle of 180 or -180 degree (whichever fits). "
- "For other configurations, the angle is determined by thinking of the edges as emerging from the same point: if the second edge is rotated clockwise "
- "against the first one, the angle is positive. If the second edge is rotated counterclockwise, the angle is negative. This way, the same angle "
- "definition applies to edges at a corner of a polygon and the same edges appearing in an edge pair.\n"
+ "The angle is measured between the two edges. It is between 0 (parallel or anti-parallel edges) and 90 degree (perpendicular edges).\n"
"\n"
"This method has been added in version 0.27.2.\n"
) +
@@ -737,10 +734,7 @@ Class decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
"edge pairs with an angle between min_angle and max_angle (max_angle itself is excluded) are returned. If \"inverse\" is true, "
"edge pairs not fulfilling this criterion are returned.\n"
"\n"
- "The angle is measured between the two edges. Antiparallel edges have an angle of 0, parallel ones an angle of 180 or -180 degree (whichever fits). "
- "For other configurations, the angle is determined by thinking of the edges as emerging from the same point: if the second edge is rotated clockwise "
- "against the first one, the angle is positive. If the second edge is rotated counterclockwise, the angle is negative. This way, the same angle "
- "definition applies to edges at a corner of a polygon and the same edges appearing in an edge pair.\n"
+ "The angle is measured between the two edges. It is between 0 (parallel or anti-parallel edges) and 90 degree (perpendicular edges).\n"
"\n"
"With \"include_min_angle\" set to true (the default), the minimum angle is included in the criterion while with false, the "
"minimum angle itself is not included. Same for \"include_max_angle\" where the default is false, meaning the maximum angle is not included in the range.\n"
diff --git a/src/db/unit_tests/dbEdgePairsTests.cc b/src/db/unit_tests/dbEdgePairsTests.cc
index e20d543ee..8ec877c12 100644
--- a/src/db/unit_tests/dbEdgePairsTests.cc
+++ b/src/db/unit_tests/dbEdgePairsTests.cc
@@ -24,6 +24,7 @@
#include "tlUnitTest.h"
#include "dbEdgePairs.h"
+#include "dbEdgePairFilters.h"
#include "dbEdges.h"
#include "dbRegion.h"
#include "dbTestSupport.h"
@@ -160,3 +161,42 @@ TEST(4)
db::Region r (db::RecursiveShapeIterator (ly, ly.cell (top_cell), l1));
EXPECT_EQ (db::compare (r, "(-10,-21;9,20;50,51;91,80);(-10,-21;9,20;110,121;91,80)"), true);
}
+
+TEST(5_InternalAngleFilter)
+{
+ db::EdgePair ep0 (db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (100, 0), db::Point (0, 0)));
+ db::EdgePair ep45 (db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 0), db::Point (100, 100)));
+ db::EdgePair ep180 (db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 0), db::Point (100, 0)));
+ db::EdgePair ep90 (db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 0), db::Point (0, 100)));
+ db::EdgePair epm90 (db::Edge (db::Point (0, 0), db::Point (100, 0)), db::Edge (db::Point (0, 100), db::Point (0, 0)));
+
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep0), true);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep180), true);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep90), false);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (epm90), false);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, false).selected (ep45), false);
+
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep0), false);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep180), false);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep90), true);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (epm90), true);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (90.0, false).selected (ep45), false);
+
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep0), false);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep180), false);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep90), false);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (epm90), false);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (45.0, false).selected (ep45), true);
+
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep0), false);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep180), false);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep90), true);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (epm90), true);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true).selected (ep45), true);
+
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep0), true);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep180), true);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep90), false);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (epm90), false);
+ EXPECT_EQ (db::InternalAngleEdgePairFilter (0.0, true, 45.0, true, false).selected (ep45), true);
+}
diff --git a/src/drc/drc/built-in-macros/_drc_layer.rb b/src/drc/drc/built-in-macros/_drc_layer.rb
index 3442b3742..699fe5333 100644
--- a/src/drc/drc/built-in-macros/_drc_layer.rb
+++ b/src/drc/drc/built-in-macros/_drc_layer.rb
@@ -330,28 +330,30 @@ module DRC
# %DRC%
# @name with_area
- # @brief Selects polygons by area
+ # @brief Selects polygons or edge pairs by area
# @synopsis layer.with_area(min .. max)
# @synopsis layer.with_area(value)
# @synopsis layer.with_area(min, max)
- # The first form will select all polygons with an area larger or
+ # The first form will select all polygons or edge pairs with an area larger or
# equal to min and less (but not equal to) max. The second form
- # will select the polygons with exactly the given area.
+ # will select the polygons or edge pairs with exactly the given area.
# The third form basically is equivalent to the first form, but
# allows specification of nil for min or max indicating no lower or
# upper limit.
+ #
+ # This method is available for polygon or edge pair layers.
# %DRC%
# @name without_area
- # @brief Selects polygons by area
+ # @brief Selects polygons or edge pairs by area
# @synopsis layer.without_area(min .. max)
# @synopsis layer.without_area(value)
# @synopsis layer.without_area(min, max)
# This method is the inverse of "with_area". It will select
- # polygons without an area equal to the given one or outside
+ # polygons or edge pairs without an area equal to the given one or outside
# the given interval.
#
- # This method is available for polygon layers only.
+ # This method is available for polygon or edge pair layers.
%w(area).each do |f|
[true, false].each do |inv|
@@ -361,7 +363,8 @@ module DRC
@engine._context("#{mn}") do
- requires_region
+ self.data.is_a?(RBA::Region) || self.data.is_a?(RBA::EdgePairs) || raise("Requires an edge pair or polygon layer")
+
if args.size == 1
a = args[0]
if a.is_a?(Range)
@@ -857,7 +860,7 @@ CODE
# @synopsis layer.with_angle(min .. max)
# @synopsis layer.with_angle(value)
# @synopsis layer.with_angle(min, max)
- # @synopsis edge_pairlayer.with_angle(min, max [, both])
+ # @synopsis edge_pair_layer.with_angle(min, max [, both])
#
# When called on an edge layer, the method selects edges by their angle,
# measured against the horizontal axis in the mathematical sense.
@@ -871,10 +874,6 @@ CODE
# The second version selects edges with exactly the given angle. The third
# version is identical to the first one.
#
- # When called on a polygon layer, this method selects corners which match the
- # given angle or is within the given angle interval. The angle is measured between the edges forming the corner.
- # For each corner, an edge pair containing the edges forming in the angle is returned.
- #
# When called on an edge pair layer, this method selects edge pairs with one or both edges
# meeting the angle criterion. In this case an additional argument is accepted which can be
# either "both" (plain word) to indicate that both edges have to be within the given interval.
@@ -903,6 +902,9 @@ CODE
# @td @img(/images/drc_with_angle4.png) @/td
# @/tr
# @/table
+ #
+ # Note that in former versions, with_angle could be used on polygon layers selecting corners with specific angles.
+ # This feature has been deprecated. Use \corners instead.
# %DRC%
# @name without_angle
@@ -910,11 +912,12 @@ CODE
# @synopsis layer.without_angle(min .. max)
# @synopsis layer.without_angle(value)
# @synopsis layer.without_angle(min, max)
- # @synopsis edge_pairlayer.without_angle(min, max [, both])
+ # @synopsis edge_pair_layer.without_angle(min, max [, both])
#
# The method basically is the inverse of \with_angle. It selects all edges
# of the edge layer or corners of the polygons which do not have the given angle (second form) or whose angle
- # is not inside the given interval (first and third form).
+ # is not inside the given interval (first and third form). When called on edge pairs, it selects
+ # edge pairs by the angles of their edges.
#
# A note on the "both" modifier (without_angle called on edge pairs): "both" means that
# both edges need to be "without_angle". For example
@@ -925,8 +928,41 @@ CODE
# ep = edge_pairs.without_angle(0, both)
# @/code
#
+ # See \with_internal_angle and \without_internal_angle to select edge pairs by the
+ # angle between the edges.
- %w(angle).each do |f|
+ # %DRC%
+ # @name with_internal_angle
+ # @brief Selects edge pairs by their internal angle
+ # @synopsis edge_pair_layer.with_internal_angle(min .. max)
+ # @synopsis edge_pair_layer.with_internal_angle(value)
+ # @synopsis edge_pair_layer.with_internal_angle(min, max)
+ #
+ # This method selects edge pairs by the angle enclosed by their edges.
+ # The angle is between 0 (parallel or anti-parallel edges) and 90 degree (perpendicular edges).
+ # If an interval or two values are given, the angle is checked to be within the given
+ # range.
+ #
+ # Here are examples for "with_internal_angle" on edge pair layers:
+ #
+ # @code
+ # # selects edge pairs with parallel edges
+ # ep1 = edge_pairs.with_internal_angle(0)
+ # # selects edge pairs with perpendicular edges
+ # ep2 = edge_pairs.with_internal_angle(90)
+ # @/code
+
+ # %DRC%
+ # @name without_internal_angle
+ # @brief Selects edge pairs by their internal angle
+ # @synopsis edge_pair_layer.without_internal_angle(min .. max)
+ # @synopsis edge_pair_layer.without_internal_angle(value)
+ # @synopsis edge_pair_layer.without_internal_angle(min, max)
+ #
+ # The method basically is the inverse of \with_internal_angle. It selects all
+ # edge pairs by the angle enclosed by their edges, applying the opposite criterion than \with_internal_angle.
+
+ %w(angle internal_angle).each do |f|
[true, false].each do |inv|
mn = (inv ? "without" : "with") + "_" + f
eval <<"CODE"
@@ -935,16 +971,22 @@ CODE
@engine._context("#{mn}") do
f = :with_#{f}
- args = args.select do |a|
- if a.is_a?(DRCBothEdges)
- if !self.data.is_a?(RBA::EdgePairs)
- raise("'both' keyword only available for edge pair layers")
+
+ if "#{f}" == "angle"
+ self.data.is_a?(RBA::Region) || self.data.is_a?(RBA::Edges) || self.data.is_a?(RBA::EdgePairs) || raise("Requires an edge, edge pair or polygon layer")
+ args = args.select do |a|
+ if a.is_a?(DRCBothEdges)
+ if !self.data.is_a?(RBA::EdgePairs)
+ raise("'both' keyword only available for edge pair layers")
+ end
+ f = :with_#{f}_both
+ false
+ else
+ true
end
- f = :with_#{f}_both
- false
- else
- true
end
+ else
+ requires_edge_pairs
end
result_class = self.data.is_a?(RBA::Edges) ? RBA::Edges : RBA::EdgePairs
diff --git a/src/drc/unit_tests/drcSimpleTests.cc b/src/drc/unit_tests/drcSimpleTests.cc
index 6b19de6d3..ad98a0644 100644
--- a/src/drc/unit_tests/drcSimpleTests.cc
+++ b/src/drc/unit_tests/drcSimpleTests.cc
@@ -1283,12 +1283,12 @@ TEST(48d_drcWithFragments)
run_test (_this, "48", true);
}
-TEST(49_drcWithFragments)
+TEST(49_epAngle)
{
run_test (_this, "49", false);
}
-TEST(49d_drcWithFragments)
+TEST(49d_epAngle)
{
run_test (_this, "49", true);
}
@@ -1298,3 +1298,8 @@ TEST(50_issue826)
run_test (_this, "50", false);
}
+TEST(51_epInternalAngle)
+{
+ run_test (_this, "51", false);
+}
+
diff --git a/src/lay/lay/doc/about/drc_ref_layer.xml b/src/lay/lay/doc/about/drc_ref_layer.xml
index 9c2e565dc..b13360a9a 100644
--- a/src/lay/lay/doc/about/drc_ref_layer.xml
+++ b/src/lay/lay/doc/about/drc_ref_layer.xml
@@ -3157,7 +3157,7 @@ Shielding is enabled by default, but can be switched off with the "transparent"
layer.with_angle(min .. max)
layer.with_angle(value)
layer.with_angle(min, max)
-edge_pairlayer.with_angle(min, max [, both])
+edge_pair_layer.with_angle(min, max [, both])
When called on an edge layer, the method selects edges by their angle,
@@ -3172,10 +3172,6 @@ edges with a angle larger or equal to min and less than max (but not equal).
The second version selects edges with exactly the given angle. The third
version is identical to the first one.
-When called on a polygon layer, this method selects corners which match the
-given angle or is within the given angle interval. The angle is measured between the edges forming the corner.
-For each corner, an edge pair containing the edges forming in the angle is returned.
-
When called on an edge pair layer, this method selects edge pairs with one or both edges
meeting the angle criterion. In this case an additional argument is accepted which can be
either "both" (plain word) to indicate that both edges have to be within the given interval.
@@ -3204,8 +3200,11 @@ The following images demonstrate some use cases of with_an
 |
+
+Note that in former versions, with_angle could be used on polygon layers selecting corners with specific angles.
+This feature has been deprecated. Use corners instead.
-"with_area" - Selects polygons by area
+"with_area" - Selects polygons or edge pairs by area
Usage:
-The first form will select all polygons with an area larger or
+The first form will select all polygons or edge pairs with an area larger or
equal to min and less (but not equal to) max. The second form
-will select the polygons with exactly the given area.
+will select the polygons or edge pairs with exactly the given area.
The third form basically is equivalent to the first form, but
allows specification of nil for min or max indicating no lower or
upper limit.
+
+This method is available for polygon or edge pair layers.
"with_area_ratio" - Selects polygons by the ratio of the bounding box area vs. polygon area
@@ -3334,7 +3335,7 @@ The tile size must be specified with the "tile_size" option:
# reports areas where layer 1/0 density is below 10% on 20x20 um tiles
-low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um))
+low_density = input(1, 0).with_density(0.0 .. 0.1, tile_size(20.um))
Anisotropic tiles can be specified by giving two values, like "tile_size(10.um, 20.um)".
@@ -3348,7 +3349,7 @@ in increments of the tile step:
# reports areas where layer 1/0 density is below 10% on 30x30 um tiles
# with a tile step of 20x20 um:
-low_density = input(1, 0).density(0.0 .. 0.1, tile_size(30.um), tile_step(20.um))
+low_density = input(1, 0).with_density(0.0 .. 0.1, tile_size(30.um), tile_step(20.um))
For "tile_step", anisotropic values can be given as well by using two values: the first for the
@@ -3366,7 +3367,7 @@ drawn boundary layer. To specify a separate, additional layer included in the bo
# reports density of layer 1/0 below 10% on 20x20 um tiles. The layout's boundary is taken from
# layer 0/0:
cell_frame = input(0, 0)
-low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um), tile_boundary(cell_frame))
+low_density = input(1, 0).with_density(0.0 .. 0.1, tile_size(20.um), tile_boundary(cell_frame))
Note that the layer given in "tile_boundary" adds to the input layer for computing the bounding box.
@@ -3378,7 +3379,7 @@ direction. With the "tile_origin" option this allows full control over the area
# reports density of layer 1/0 below 10% on 20x20 um tiles in the region 0,0 .. 2000,3000
# (100 and 150 tiles of 20 um each are used in horizontal and vertical direction):
-low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um), tile_origin(0.0, 0.0), tile_count(100, 150))
+low_density = input(1, 0).with_density(0.0 .. 0.1, tile_size(20.um), tile_origin(0.0, 0.0), tile_count(100, 150))
The "padding mode" indicates how the area outside the layout's bounding box is considered.
@@ -3392,7 +3393,7 @@ There are two modes:
Example:
-low_density = input(1, 0).density(0.0 .. 0.1, tile_size(20.um), padding_ignore)
+low_density = input(1, 0).with_density(0.0 .. 0.1, tile_size(20.um), padding_ignore)
The complementary version of "with_density" is without_density.
@@ -3430,6 +3431,29 @@ This method is available for edge pair layers only.
This method is available for polygon layers. It will select all polygons from the input layer
which have the specified number of holes.
+"with_internal_angle" - Selects edge pairs by their internal angle
+
+Usage:
+
+- edge_pair_layer.with_internal_angle(min .. max)
+- edge_pair_layer.with_internal_angle(value)
+- edge_pair_layer.with_internal_angle(min, max)
+
+
+This method selects edge pairs by the angle enclosed by their edges.
+The angle is between 0 (parallel or anti-parallel edges) and 90 degree (perpendicular edges).
+If an interval or two values are given, the angle is checked to be within the given
+range.
+
+Here are examples for "with_internal_angle" on edge pair layers:
+
+
+# selects edge pairs with parallel edges
+ep1 = edge_pairs.with_internal_angle(0)
+# selects edge pairs with perpendicular edges
+ep2 = edge_pairs.with_internal_angle(90)
+
+
"with_length" - Selects edges by their length
Usage:
@@ -3505,12 +3529,13 @@ This method is available for polygon layers only.
layer.without_angle(min .. max)
layer.without_angle(value)
layer.without_angle(min, max)
-edge_pairlayer.without_angle(min, max [, both])
+edge_pair_layer.without_angle(min, max [, both])
The method basically is the inverse of with_angle. It selects all edges
of the edge layer or corners of the polygons which do not have the given angle (second form) or whose angle
-is not inside the given interval (first and third form).
+is not inside the given interval (first and third form). When called on edge pairs, it selects
+edge pairs by the angles of their edges.
A note on the "both" modifier (without_angle called on edge pairs): "both" means that
both edges need to be "without_angle". For example
@@ -3520,8 +3545,11 @@ both edges need to be "without_angle". For example
# the edge pair is skipped if one edge is horizontal
ep = edge_pairs.without_angle(0, both)
+
+See with_internal_angle and without_internal_angle to select edge pairs by the
+angle between the edges.
-"without_area" - Selects polygons by area
+"without_area" - Selects polygons or edge pairs by area
Usage:
@@ -3531,10 +3559,10 @@ ep = edge_pairs.without_angle(0, both)
This method is the inverse of "with_area". It will select
-polygons without an area equal to the given one or outside
+polygons or edge pairs without an area equal to the given one or outside
the given interval.
-This method is available for polygon layers only.
+This method is available for polygon or edge pair layers.
"without_area_ratio" - Selects polygons by the aspect ratio of their bounding box
@@ -3647,6 +3675,18 @@ This method is available for edge pair layers only.
This method is available for polygon layers. It will select all polygons from the input layer
which do not have the specified number of holes.
+"without_internal_angle" - Selects edge pairs by their internal angle
+
+Usage:
+
+- edge_pair_layer.without_internal_angle(min .. max)
+- edge_pair_layer.without_internal_angle(value)
+- edge_pair_layer.without_internal_angle(min, max)
+
+
+The method basically is the inverse of with_internal_angle. It selects all
+edge pairs by the angle enclosed by their edges, applying the opposite criterion than with_internal_angle.
+
"without_length" - Selects edges by the their length
Usage:
diff --git a/testdata/drc/drcSimpleTests_51.drc b/testdata/drc/drcSimpleTests_51.drc
new file mode 100644
index 000000000..ee43169dc
--- /dev/null
+++ b/testdata/drc/drcSimpleTests_51.drc
@@ -0,0 +1,26 @@
+
+source $drc_test_source
+target $drc_test_target
+
+if $drc_test_deep
+ deep
+end
+
+ep = input(1, 0).drc(sep(input(2, 0), angle_limit(91)) < 0.5)
+
+input(1, 0).output(1, 0)
+input(2, 0).output(2, 0)
+
+ep.polygons(0).output(100, 0)
+
+ep.with_internal_angle(45.0).polygons(0).output(200, 0)
+ep.with_internal_angle(0.0).polygons(0).output(201, 0)
+ep.with_internal_angle(45.0..91.0).polygons(0).output(202, 0)
+
+ep.without_internal_angle(45.0).polygons(0).output(220, 0)
+ep.without_internal_angle(0.0).polygons(0).output(221, 0)
+ep.without_internal_angle(45.0..91.0).polygons(0).output(222, 0)
+
+ep.with_area(0 .. 0.1).polygons(0).output(300, 0)
+ep.without_area(0 .. 0.1).polygons(0).output(301, 0)
+
diff --git a/testdata/drc/drcSimpleTests_51.gds b/testdata/drc/drcSimpleTests_51.gds
new file mode 100644
index 000000000..ec9722ff6
Binary files /dev/null and b/testdata/drc/drcSimpleTests_51.gds differ
diff --git a/testdata/drc/drcSimpleTests_au51.gds b/testdata/drc/drcSimpleTests_au51.gds
new file mode 100644
index 000000000..2025e5c0d
Binary files /dev/null and b/testdata/drc/drcSimpleTests_au51.gds differ
diff --git a/testdata/ruby/dbEdgePairsTest.rb b/testdata/ruby/dbEdgePairsTest.rb
index 95ef504b5..27cb55035 100644
--- a/testdata/ruby/dbEdgePairsTest.rb
+++ b/testdata/ruby/dbEdgePairsTest.rb
@@ -268,13 +268,9 @@ class DBEdgePairs_TestClass < TestBase
assert_equal(r1.with_area(150, 150, false).to_s, "")
assert_equal(r1.with_area(150, 151, true).to_s, "(0,0;0,10)/(10,0;10,20);(0,0;0,20)/(10,20;10,0);(0,0;0,10)/(10,0;10,10)")
- assert_equal(r1.with_internal_angle(0, false).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,20)/(10,20;10,0)")
+ assert_equal(r1.with_internal_angle(0, false).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,10)/(10,0;10,20);(0,0;0,20)/(10,20;10,0);(0,0;0,10)/(10,0;10,10)")
assert_equal(r1.with_internal_angle(0, 0, false).to_s, "")
- assert_equal(r1.with_internal_angle(0, 180, false).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,20)/(10,20;10,0)")
- assert_equal(r1.with_internal_angle(0, 180, false, true, true).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,10)/(10,0;10,20);(0,0;0,20)/(10,20;10,0);(0,0;0,10)/(10,0;10,10)")
- assert_equal(r1.with_internal_angle(180, false).to_s, "(0,0;0,10)/(10,0;10,20);(0,0;0,10)/(10,0;10,10)")
- assert_equal(r1.with_internal_angle(-180, false).to_s, "(0,0;0,10)/(10,0;10,20);(0,0;0,10)/(10,0;10,10)")
- assert_equal(r1.with_internal_angle(0, true).to_s, "(0,0;0,10)/(10,0;10,20);(0,0;0,10)/(10,0;10,10)")
+ assert_equal(r1.with_internal_angle(0, true).to_s, "")
ep1 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(10, 20, 10, 0))
ep2 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(20, 0, 30, 0))
@@ -286,8 +282,8 @@ class DBEdgePairs_TestClass < TestBase
assert_equal(r1.with_distance(20, true).to_s, "(0,0;0,10)/(10,20;10,0)")
assert_equal(r1.with_internal_angle(0, false).to_s, "(0,0;0,10)/(10,20;10,0)")
- assert_equal(r1.with_internal_angle(90, false).to_s, "(0,0;0,10)/(20,0;30,0)")
- assert_equal(r1.with_internal_angle(-90, false).to_s, "(0,0;0,10)/(-20,0;-30,0)")
+ assert_equal(r1.with_internal_angle(90, false).to_s, "(0,0;0,10)/(20,0;30,0);(0,0;0,10)/(-20,0;-30,0)")
+ assert_equal(r1.with_internal_angle(-90, false).to_s, "(0,0;0,10)/(20,0;30,0);(0,0;0,10)/(-20,0;-30,0)")
assert_equal(r1.with_angle(90, false).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,10)/(20,0;30,0);(0,0;0,10)/(-20,0;-30,0)")
assert_equal(r1.with_angle(0, false).to_s, "(0,0;0,10)/(20,0;30,0);(0,0;0,10)/(-20,0;-30,0)")
@@ -295,6 +291,18 @@ class DBEdgePairs_TestClass < TestBase
assert_equal(r1.with_angle_both(90, false).to_s, "(0,0;0,10)/(10,20;10,0)")
assert_equal(r1.with_angle_both(0, false).to_s, "")
+ ep1 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(10, 20, 10, 0))
+ ep2 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(20, 10, 30, 0))
+
+ r1 = RBA::EdgePairs::new([ ep1, ep2 ])
+
+ assert_equal(r1.with_internal_angle(0, false).to_s, "(0,0;0,10)/(10,20;10,0)")
+ assert_equal(r1.with_internal_angle(90, false).to_s, "")
+ assert_equal(r1.with_internal_angle(90, true).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,10)/(20,10;30,0)")
+ assert_equal(r1.with_internal_angle(45, false).to_s, "(0,0;0,10)/(20,10;30,0)")
+ assert_equal(r1.with_internal_angle(0, 45, false, true, true).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,10)/(20,10;30,0)")
+ assert_equal(r1.with_internal_angle(0, 45, true, true, true).to_s, "")
+
end
end