From 525152087686189b31fc89c504b31aa04e6f4ffb Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Mon, 21 Jun 2021 23:44:48 +0200
Subject: [PATCH 1/3] Added more filters for edge pairs: with_area,
with_internal_angle. Added tests
---
src/db/db/dbEdgePairFilters.cc | 37 ++++++++++++++++
src/db/db/dbEdgePairFilters.h | 50 +++++++++++++++++++++-
src/db/db/dbEdgesUtils.h | 1 -
src/db/db/gsiDeclDbEdgePairs.cc | 71 ++++++++++++++++++++++++++++++-
testdata/ruby/dbEdgePairsTest.rb | 72 ++++++++++++++++++++++++++++++++
5 files changed, 227 insertions(+), 4 deletions(-)
diff --git a/src/db/db/dbEdgePairFilters.cc b/src/db/db/dbEdgePairFilters.cc
index 541f33731..9b8d6ff9f 100644
--- a/src/db/db/dbEdgePairFilters.cc
+++ b/src/db/db/dbEdgePairFilters.cc
@@ -78,4 +78,41 @@ bool EdgePairFilterByDistance::selected (const db::EdgePair &edge_pair) const
return m_inverted ? !sel : sel;
}
+// ---------------------------------------------------------------------------------------------------
+// EdgePairFilterByArea implementation
+
+EdgePairFilterByArea::EdgePairFilterByArea (area_type min_area, area_type max_area, bool inverted)
+ : m_min_area (min_area), m_max_area (max_area), m_inverted (inverted)
+{
+ // .. nothing yet ..
+}
+
+bool EdgePairFilterByArea::selected (const db::EdgePair &edge_pair) const
+{
+ area_type dist = edge_pair.to_simple_polygon (0).area ();
+ bool sel = (dist >= m_min_area && dist < m_max_area);
+ return m_inverted ? !sel : sel;
+}
+
+// ---------------------------------------------------------------------------------------------------
+// EdgePairFilterByArea implementation
+
+InternalAngleEdgePairFilter::InternalAngleEdgePairFilter (double a, bool inverted)
+ : m_inverted (inverted), m_checker (a, true, a, true)
+{
+ // .. nothing yet ..
+}
+
+InternalAngleEdgePairFilter::InternalAngleEdgePairFilter (double amin, bool include_amin, double amax, bool include_amax, bool inverted)
+ : m_inverted (inverted), m_checker (amin, include_amin, amax, include_amax)
+{
+ // .. nothing yet ..
+}
+
+bool
+InternalAngleEdgePairFilter::selected (const db::EdgePair &edge_pair) const
+{
+ return m_checker (edge_pair.first ().d (), -edge_pair.second ().d ()) != m_inverted;
+}
+
}
diff --git a/src/db/db/dbEdgePairFilters.h b/src/db/db/dbEdgePairFilters.h
index 9f25858e8..4b961a281 100644
--- a/src/db/db/dbEdgePairFilters.h
+++ b/src/db/db/dbEdgePairFilters.h
@@ -25,6 +25,7 @@
#define HDR_dbEdgePairFilters
#include "dbEdgePairs.h"
+#include "dbEdgesUtils.h"
namespace db
{
@@ -69,12 +70,57 @@ public:
EdgePairFilterByDistance (distance_type min_distance, distance_type max_distance, bool inverted);
virtual bool selected (const db::EdgePair &edge_pair) const;
- virtual const TransformationReducer *vars () const { return 0; }
- virtual bool wants_variants () const { return false; }
+ virtual const TransformationReducer *vars () const { return &m_vars; }
+ virtual bool wants_variants () const { return true; }
private:
distance_type m_min_distance, m_max_distance;
bool m_inverted;
+ db::MagnificationReducer m_vars;
+};
+
+/**
+ * @brief Filters edge pairs based on the distance of the edges.
+ *
+ * The distance is measured as the smallest distance between each of the points of the two edges.
+ */
+class DB_PUBLIC EdgePairFilterByArea
+ : public EdgePairFilterBase
+{
+public:
+ typedef db::coord_traits::area_type area_type;
+
+ EdgePairFilterByArea (area_type min_area, area_type max_area, bool inverted);
+
+ virtual bool selected (const db::EdgePair &edge_pair) const;
+ virtual const TransformationReducer *vars () const { return &m_vars; }
+ virtual bool wants_variants () const { return true; }
+
+private:
+ area_type m_min_area, m_max_area;
+ bool m_inverted;
+ db::MagnificationReducer m_vars;
+};
+
+/**
+ * @brief Filters edge pairs based on the distance of the edges.
+ *
+ * The distance is measured as the smallest distance between each of the points of the two edges.
+ */
+class DB_PUBLIC InternalAngleEdgePairFilter
+ : public EdgePairFilterBase
+{
+public:
+ InternalAngleEdgePairFilter (double a, bool inverted);
+ InternalAngleEdgePairFilter (double amin, bool include_amin, double amax, bool include_amax, bool inverted);
+
+ virtual bool selected (const db::EdgePair &edge_pair) const;
+ virtual const TransformationReducer *vars () const { return 0; }
+ virtual bool wants_variants () const { return false; }
+
+private:
+ bool m_inverted;
+ db::EdgeAngleChecker m_checker;
};
}
diff --git a/src/db/db/dbEdgesUtils.h b/src/db/db/dbEdgesUtils.h
index 0fd02770a..7f221025e 100644
--- a/src/db/db/dbEdgesUtils.h
+++ b/src/db/db/dbEdgesUtils.h
@@ -236,7 +236,6 @@ struct DB_PUBLIC EdgeOrientationFilter
}
private:
- db::DVector m_emin, m_emax;
bool m_inverse;
db::MagnificationAndOrientationReducer m_vars;
EdgeAngleChecker m_checker;
diff --git a/src/db/db/gsiDeclDbEdgePairs.cc b/src/db/db/gsiDeclDbEdgePairs.cc
index 0b220e499..f7d3073a0 100644
--- a/src/db/db/gsiDeclDbEdgePairs.cc
+++ b/src/db/db/gsiDeclDbEdgePairs.cc
@@ -246,6 +246,30 @@ static db::EdgePairs with_angle_both2 (const db::EdgePairs *r, double amin, doub
return r->filtered (ef);
}
+static db::EdgePairs with_internal_angle1 (const db::EdgePairs *r, double a, bool inverse)
+{
+ db::InternalAngleEdgePairFilter f (a, inverse);
+ return r->filtered (f);
+}
+
+static db::EdgePairs with_internal_angle2 (const db::EdgePairs *r, double amin, double amax, bool inverse, bool include_amin, bool include_amax)
+{
+ db::InternalAngleEdgePairFilter f (amin, include_amin, amax, include_amax, inverse);
+ return r->filtered (f);
+}
+
+static db::EdgePairs with_area1 (const db::EdgePairs *r, db::EdgePair::area_type a, bool inverse)
+{
+ db::EdgePairFilterByArea f (a, a + 1, inverse);
+ return r->filtered (f);
+}
+
+static db::EdgePairs with_area2 (const db::EdgePairs *r, db::EdgePair::area_type amin, db::EdgePair::area_type amax, bool inverse)
+{
+ db::EdgePairFilterByArea f (amin, amax, inverse);
+ return r->filtered (f);
+}
+
extern Class decl_dbShapeCollection;
Class decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
@@ -621,7 +645,7 @@ Class decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
method_ext ("with_distance", with_distance2, gsi::arg ("min_distance"), gsi::arg ("max_distance"), gsi::arg ("inverse"),
"@brief Filters the edge pairs by the distance of the edges\n"
"Filters the edge pairs in the edge pair collection by distance of the edges. If \"inverse\" is false, only "
- "edge pairs where both edges have a distance between min_distance and max_distance (max_distance itself is excluded). If \"inverse\" is true, "
+ "edge pairs where both edges have a distance between min_distance and max_distance (max_distance itself is excluded) are returned. If \"inverse\" is true, "
"edge pairs not fulfilling this criterion are returned.\n"
"\n"
"Distance is measured as the shortest distance between any of the points on the edges.\n"
@@ -678,6 +702,51 @@ Class decl_EdgePairs (decl_dbShapeCollection, "db", "EdgePairs",
"\n"
"This method has been added in version 0.27.1.\n"
) +
+ method_ext ("with_area", with_area1, gsi::arg ("area"), gsi::arg ("inverse"),
+ "@brief Filters the edge pairs by the enclosed area\n"
+ "Filters the edge pairs in the edge pair collection by enclosed area. If \"inverse\" is false, only "
+ "edge pairs with the given area are returned. If \"inverse\" is true, "
+ "edge pairs not with the given area are returned.\n"
+ "\n"
+ "This method has been added in version 0.27.2.\n"
+ ) +
+ method_ext ("with_area", with_area2, gsi::arg ("min_area"), gsi::arg ("max_area"), gsi::arg ("inverse"),
+ "@brief Filters the edge pairs by the enclosed area\n"
+ "Filters the edge pairs in the edge pair collection by enclosed area. If \"inverse\" is false, only "
+ "edge pairs with an area between min_area and max_area (max_area itself is excluded) are returned. If \"inverse\" is true, "
+ "edge pairs not fulfilling this criterion are returned.\n"
+ "\n"
+ "This method has been added in version 0.27.2.\n"
+ ) +
+ method_ext ("with_internal_angle", with_internal_angle1, gsi::arg ("angle"), gsi::arg ("inverse"),
+ "@brief Filters the edge pairs by the angle between their edges\n"
+ "Filters the edge pairs in the edge pair collection by the angle between their edges. If \"inverse\" is false, only "
+ "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"
+ "\n"
+ "This method has been added in version 0.27.2.\n"
+ ) +
+ method_ext ("with_internal_angle", with_internal_angle2, gsi::arg ("min_angle"), gsi::arg ("max_angle"), gsi::arg ("inverse"), gsi::arg ("include_min_angle", true), gsi::arg ("include_max_angle", false),
+ "@brief Filters the edge pairs by the angle between their edges\n"
+ "Filters the edge pairs in the edge pair collection by the angle between their edges. If \"inverse\" is false, only "
+ "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"
+ "\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"
+ "\n"
+ "This method has been added in version 0.27.2.\n"
+ ) +
method_ext ("polygons", &polygons1,
"@brief Converts the edge pairs to polygons\n"
"This method creates polygons from the edge pairs. Each polygon will be a triangle or quadrangle "
diff --git a/testdata/ruby/dbEdgePairsTest.rb b/testdata/ruby/dbEdgePairsTest.rb
index 5a27c58fa..95ef504b5 100644
--- a/testdata/ruby/dbEdgePairsTest.rb
+++ b/testdata/ruby/dbEdgePairsTest.rb
@@ -225,6 +225,78 @@ class DBEdgePairs_TestClass < TestBase
end
+ def test_5
+
+ # filters
+
+ 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(10, 0, 10, 20))
+ ep3 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 20), RBA::Edge::new(10, 20, 10, 0))
+ ep4 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(10, 0, 10, 10))
+
+ r1 = RBA::EdgePairs::new([ ep1, ep2, ep3, ep4 ])
+
+ assert_equal(r1.with_distance(10, 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_distance(5, 20, 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_distance(15, 20, false).to_s, "")
+ assert_equal(r1.with_distance(15, 20, 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_length(10, false).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,10)/(10,0;10,20);(0,0;0,10)/(10,0;10,10)")
+ assert_equal(r1.with_length(10, 20, false).to_s, "(0,0;0,10)/(10,20;10,0);(0,0;0,10)/(10,0;10,20);(0,0;0,10)/(10,0;10,10)")
+ assert_equal(r1.with_length(10, 21, 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_length(10, 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)")
+ assert_equal(r1.with_length_both(10, false).to_s, "(0,0;0,10)/(10,0;10,10)")
+ assert_equal(r1.with_length_both(10, 20, false).to_s, "(0,0;0,10)/(10,0;10,10)")
+ assert_equal(r1.with_length_both(10, 21, 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_length_both(10, true).to_s, "(0,0;0,20)/(10,20;10,0)")
+
+ assert_equal(r1.with_angle(0, false).to_s, "")
+ assert_equal(r1.with_angle(0, 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_angle(90, 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_angle(0, 90, false).to_s, "")
+ assert_equal(r1.with_angle(0, 90, 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_angle_both(0, false).to_s, "")
+ assert_equal(r1.with_angle_both(0, 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_angle_both(90, 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_angle_both(0, 90, false).to_s, "")
+ assert_equal(r1.with_angle_both(0, 90, 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_area(0, false).to_s, "(0,0;0,10)/(10,0;10,10)")
+ assert_equal(r1.with_area(150, false).to_s, "(0,0;0,10)/(10,20;10,0)")
+ assert_equal(r1.with_area(0, 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)")
+ assert_equal(r1.with_area(150, 151, false).to_s, "(0,0;0,10)/(10,20;10,0)")
+ 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, 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)")
+
+ 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))
+ ep3 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(-20, 0, -30, 0))
+
+ r1 = RBA::EdgePairs::new([ ep1, ep2, ep3 ])
+
+ assert_equal(r1.with_distance(20, false).to_s, "(0,0;0,10)/(20,0;30,0);(0,0;0,10)/(-20,0;-30,0)")
+ 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_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)")
+ assert_equal(r1.with_angle(0, 90, false, true, true).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_both(90, false).to_s, "(0,0;0,10)/(10,20;10,0)")
+ assert_equal(r1.with_angle_both(0, false).to_s, "")
+
+ end
+
end
From 881e0010d565490aa782e0f73c85101534b02102 Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Sun, 27 Jun 2021 14:18:04 +0200
Subject: [PATCH 2/3] Implemented with(out)_angle, with(out)_area on edge pairs
(DRC, GSI). Deprecated 'with(out)_angle' on polygon layers (DRC) as this is
now redundant with 'corners'
---
src/db/db/dbEdgePairFilters.cc | 12 ++-
src/db/db/gsiDeclDbEdgePairs.cc | 10 +--
src/db/unit_tests/dbEdgePairsTests.cc | 40 ++++++++++
src/drc/drc/built-in-macros/_drc_layer.rb | 88 ++++++++++++++++------
src/drc/unit_tests/drcSimpleTests.cc | 9 ++-
src/lay/lay/doc/about/drc_ref_layer.xml | 76 ++++++++++++++-----
testdata/drc/drcSimpleTests_51.drc | 26 +++++++
testdata/drc/drcSimpleTests_51.gds | Bin 0 -> 552 bytes
testdata/drc/drcSimpleTests_au51.gds | Bin 0 -> 7514 bytes
testdata/ruby/dbEdgePairsTest.rb | 24 ++++--
10 files changed, 225 insertions(+), 60 deletions(-)
create mode 100644 testdata/drc/drcSimpleTests_51.drc
create mode 100644 testdata/drc/drcSimpleTests_51.gds
create mode 100644 testdata/drc/drcSimpleTests_au51.gds
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 0000000000000000000000000000000000000000..ec9722ff6db87717b29b840cbc6c4c6e297a53cc
GIT binary patch
literal 552
zcmZQzV_;&6V31*CVt>lO#vskW%V5fY!e-!LV)OBIVqg$qX0>zdH1|HX{DY;-4*dnQ
zqe2*DSW(m>o58@w#^%hxz{0`6z{bnOz{tSH$Hc(Epd!EwBzFSwSD>U65Qjl%5FaYe
zB8aI^M}YbN|9|%w7?{N%G%FVa1LF<`1{e(!XBK0?ssDEcL_dgTH3FI=hM+F=~$l%Jpcgy_Iy8{|!WgJN(CQh(;@7F|Ov9_P25&{PP~surYs
zTV4}htLlSL&WJDKjdlM0PHY_8cpFa73H~m>FMi|PWWL)^>}&V~ufewbls9eVJtLp6uG)^c*tl{&$LHC`yoBEuV0B8aB-cAmwZxxTKTw7=mm5lTF!&Ob&PzF
z`EKsjS@AE{&t0h>_%HL_9P|y(!A_YAzcu5IeMUc3=U#px{>3r-Df6xC#rPOMxz6Ld
z(2Hu_dH%lnRs4%O1Akd>;J?hbt{eLo`T*(~c6wLxUdMg=)N}ir>tuSF^WaBWPv%?K
zi~BTw&Z>3Uik{5#x9Xd`FZ55G%Zo#@ZtSP+`4{(z&mX^2tyA?+^v!C%EpO|*i*e-q
zgI*%JENooZ}y@{ebH@Q@3{UPCYRE
z0`+3}1@drX!E;JDS3fhHqn{<5E73^?y!3NH~{{7*2FM
zOV1Oo)@|t<{d%5oa$i8c;QZ(4x#1jo{;<&rSG^m~QSX-HI?AkD8zxIMh+5o+}^w
zq@(T)=cs$j<=4G(^*)__NBR0bka-U^oI^JZ=g4`;hyFZj^he*X`QAGJy*uGtx@94xLCimrf*{OD7EH(22+Y
z^L=g?@9e9FH~E_P{fFUA9%X&6Fqkzu>CrpOvLuOpT-=imFjlX4y%NjZ;>q?|_&QqH3Xmdn?J!3Rw}cUz?v;Y7A
literal 0
HcmV?d00001
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
From 1d42711b6566fc4cd8184f3ae3d6968f495b47f5 Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Sun, 27 Jun 2021 16:07:10 +0200
Subject: [PATCH 3/3] Updated test data
---
testdata/ruby/dbEdgePairsTest.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testdata/ruby/dbEdgePairsTest.rb b/testdata/ruby/dbEdgePairsTest.rb
index 27cb55035..e56de3be6 100644
--- a/testdata/ruby/dbEdgePairsTest.rb
+++ b/testdata/ruby/dbEdgePairsTest.rb
@@ -283,7 +283,7 @@ class DBEdgePairs_TestClass < TestBase
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);(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, "")
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)")