diff --git a/src/db/db/dbRegion.h b/src/db/db/dbRegion.h index 6a2617f1d..521d2fb58 100644 --- a/src/db/db/dbRegion.h +++ b/src/db/db/dbRegion.h @@ -267,6 +267,16 @@ public: return mp_delegate; } + /** + * @brief Takes the underlying delegate object + */ + RegionDelegate *take_delegate () + { + RegionDelegate *delegate = mp_delegate; + mp_delegate = 0; + return delegate; + } + /** * @brief Sets the base verbosity * diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index 3f30aa7cb..9c3e9cd2f 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -610,15 +610,53 @@ static db::EdgePairs separation2 (const db::Region *r, const db::Region &other, ); } +static inline std::vector as_2region_vector (const std::pair &rp) +{ + std::vector res; + res.reserve (2); + res.push_back (db::Region (const_cast (rp.first).take_delegate ())); + res.push_back (db::Region (const_cast (rp.second).take_delegate ())); + return res; +} + static std::vector andnot (const db::Region *r, const db::Region &other) { - std::pair rp = r->andnot (other); + return as_2region_vector (r->andnot (other)); +} - std::vector res; - res.resize (2, db::Region ()); - res [0] = rp.first; - res [1] = rp.second; - return res; +static std::vector split_inside (const db::Region *r, const db::Region &other) +{ + return as_2region_vector (r->selected_inside_differential (other)); +} + +static std::vector split_outside (const db::Region *r, const db::Region &other) +{ + return as_2region_vector (r->selected_outside_differential (other)); +} + +static std::vector split_overlapping (const db::Region *r, const db::Region &other, size_t min_count, size_t max_count) +{ + return as_2region_vector (r->selected_overlapping_differential (other, min_count, max_count)); +} + +static std::vector split_covering (const db::Region *r, const db::Region &other, size_t min_count, size_t max_count) +{ + return as_2region_vector (r->selected_enclosing_differential (other, min_count, max_count)); +} + +static std::vector split_interacting_with_region (const db::Region *r, const db::Region &other, size_t min_count, size_t max_count) +{ + return as_2region_vector (r->selected_interacting_differential (other, min_count, max_count)); +} + +static std::vector split_interacting_with_edges (const db::Region *r, const db::Edges &other, size_t min_count, size_t max_count) +{ + return as_2region_vector (r->selected_interacting_differential (other, min_count, max_count)); +} + +static std::vector split_interacting_with_texts (const db::Region *r, const db::Texts &other, size_t min_count, size_t max_count) +{ + return as_2region_vector (r->selected_interacting_differential (other, min_count, max_count)); } template @@ -681,6 +719,7 @@ int po_any (); extern Class decl_dbShapeCollection; + Class decl_Region (decl_dbShapeCollection, "db", "Region", constructor ("new", &new_v, "@brief Default constructor\n" @@ -1616,7 +1655,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\n" "This method has been introduced in version 0.27." ) + - method ("split_covering", &db::Region::selected_enclosing_differential, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits::max ()), "unlimited"), + method_ext ("split_covering", &split_covering, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits::max ()), "unlimited"), "@brief Returns the polygons of this region which are completely covering polygons from the other region and the ones which are not at the same time\n" "\n" "@return Two new regions: the first containing the result of \\covering, the second the result of \\not_covering\n" @@ -1662,7 +1701,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\n" "Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n" ) + - method ("split_inside", &db::Region::selected_inside_differential, gsi::arg ("other"), + method_ext ("split_inside", &split_inside, gsi::arg ("other"), "@brief Returns the polygons of this region which are completely inside polygons from the other region and the ones which are not at the same time\n" "\n" "@return Two new regions: the first containing the result of \\inside, the second the result of \\not_inside\n" @@ -1700,7 +1739,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\n" "Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n" ) + - method ("split_outside", &db::Region::selected_outside_differential, gsi::arg ("other"), + method_ext ("split_outside", &split_outside, gsi::arg ("other"), "@brief Returns the polygons of this region which are completely outside polygons from the other region and the ones which are not at the same time\n" "\n" "@return Two new regions: the first containing the result of \\outside, the second the result of \\not_outside\n" @@ -1752,7 +1791,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\n" "The min_count and max_count arguments have been added in version 0.27.\n" ) + - method ("split_interacting", (std::pair (db::Region::*) (const db::Region &, size_t, size_t) const) &db::Region::selected_interacting_differential, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits::max ()), "unlimited"), + method_ext ("split_interacting", &split_interacting_with_region, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits::max ()), "unlimited"), "@brief Returns the polygons of this region which are interacting with polygons from the other region and the ones which are not at the same time\n" "\n" "@return Two new regions: the first containing the result of \\interacting, the second the result of \\not_interacting\n" @@ -1820,7 +1859,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "This method has been introduced in version 0.25\n" "The min_count and max_count arguments have been added in version 0.27.\n" ) + - method ("split_interacting", (std::pair (db::Region::*) (const db::Edges &, size_t, size_t) const) &db::Region::selected_interacting_differential, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits::max ()), "unlimited"), + method_ext ("split_interacting", &split_interacting_with_edges, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits::max ()), "unlimited"), "@brief Returns the polygons of this region which are interacting with edges from the other edge collection and the ones which are not at the same time\n" "\n" "@return Two new regions: the first containing the result of \\interacting, the second the result of \\not_interacting\n" @@ -1888,7 +1927,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\n" "This method has been introduced in version 0.27\n" ) + - method ("split_interacting", (std::pair (db::Region::*) (const db::Texts &, size_t, size_t) const) &db::Region::selected_interacting_differential, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits::max ()), "unlimited"), + method_ext ("split_interacting", &split_interacting_with_texts, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits::max ()), "unlimited"), "@brief Returns the polygons of this region which are interacting with texts from the other text collection and the ones which are not at the same time\n" "\n" "@return Two new regions: the first containing the result of \\interacting, the second the result of \\not_interacting\n" @@ -1944,7 +1983,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\n" "The count options have been introduced in version 0.27." ) + - method ("split_overlapping", &db::Region::selected_overlapping_differential, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits::max ()), "unlimited"), + method_ext ("split_overlapping", &split_overlapping, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits::max ()), "unlimited"), "@brief Returns the polygons of this region which are overlapping with polygons from the other region and the ones which are not at the same time\n" "\n" "@return Two new regions: the first containing the result of \\overlapping, the second the result of \\not_overlapping\n" diff --git a/src/db/unit_tests/dbRegionTests.cc b/src/db/unit_tests/dbRegionTests.cc index c8b2334fa..b1a6c41a0 100644 --- a/src/db/unit_tests/dbRegionTests.cc +++ b/src/db/unit_tests/dbRegionTests.cc @@ -354,6 +354,8 @@ TEST(10a) r.set_merged_semantics (false); EXPECT_EQ (r.selected_interacting (db::Region (db::Box (db::Point (20, 20), db::Point (30, 30)))).to_string (), "(0,0;0,200;100,200;100,0)"); EXPECT_EQ (r.selected_not_interacting (db::Region (db::Box (db::Point (20, 20), db::Point (30, 30)))).to_string (), "(-100,-100;-100,0;0,0;0,-100)"); + EXPECT_EQ (r.selected_interacting_differential (db::Region (db::Box (db::Point (20, 20), db::Point (30, 30)))).first.to_string (), "(0,0;0,200;100,200;100,0)"); + EXPECT_EQ (r.selected_interacting_differential (db::Region (db::Box (db::Point (20, 20), db::Point (30, 30)))).second.to_string (), "(-100,-100;-100,0;0,0;0,-100)"); EXPECT_EQ (db::compare (r.selected_interacting (db::Region (db::Box (db::Point (-20, -20), db::Point (30, 30)))), "(0,0;0,200;100,200;100,0);(-100,-100;-100,0;0,0;0,-100)"), true); EXPECT_EQ (r.selected_interacting (db::Region (db::Box (db::Point (-200, -200), db::Point (-190, -190)))).to_string (), ""); db::Region rr = r; @@ -836,6 +838,8 @@ TEST(18a) EXPECT_EQ (db::compare (o, "(50,10;50,30;70,30;70,10);(70,60;70,80;90,80;90,60)"), true); o = r; EXPECT_EQ (db::compare (o.selected_not_outside (rr), "(0,0;0,20;20,20;20,0);(20,30;20,50;40,50;40,30);(0,60;0,80;60,80;60,60);(0,100;0,130;30,130;30,100)"), true); + EXPECT_EQ (db::compare (o.selected_outside_differential (rr).first, "(50,10;50,30;70,30;70,10);(70,60;70,80;90,80;90,60)"), true); + EXPECT_EQ (db::compare (o.selected_outside_differential (rr).second, "(0,0;0,20;20,20;20,0);(20,30;20,50;40,50;40,30);(0,60;0,80;60,80;60,60);(0,100;0,130;30,130;30,100)"), true); EXPECT_EQ (o.selected_outside (rr).count () + o.selected_not_outside (rr).count (), size_t (6)); EXPECT_EQ (o.selected_outside (rr).hier_count () + o.selected_not_outside (rr).hier_count (), size_t (6)); o.select_not_outside (rr); @@ -848,6 +852,8 @@ TEST(18a) EXPECT_EQ (o.to_string (), "(20,30;20,50;40,50;40,30)"); o = r; EXPECT_EQ (db::compare (o.selected_not_inside (rr), "(0,0;0,20;20,20;20,0);(50,10;50,30;70,30;70,10);(70,60;70,80;90,80;90,60);(0,60;0,80;60,80;60,60);(0,100;0,130;30,130;30,100)"), true); + EXPECT_EQ (db::compare (o.selected_inside_differential (rr).first, "(20,30;20,50;40,50;40,30)"), true); + EXPECT_EQ (db::compare (o.selected_inside_differential (rr).second, "(0,0;0,20;20,20;20,0);(50,10;50,30;70,30;70,10);(70,60;70,80;90,80;90,60);(0,60;0,80;60,80;60,60);(0,100;0,130;30,130;30,100)"), true); EXPECT_EQ (o.selected_inside (rr).count () + o.selected_not_inside (rr).count (), size_t (6)); EXPECT_EQ (o.selected_inside (rr).hier_count () + o.selected_not_inside (rr).hier_count (), size_t (6)); o.select_not_inside (rr); @@ -860,6 +866,8 @@ TEST(18a) EXPECT_EQ (db::compare (o, "(0,0;0,20;20,20;20,0);(50,10;50,30;70,30;70,10);(20,30;20,50;40,50;40,30);(0,60;0,80;60,80;60,60);(0,100;0,130;30,130;30,100)"), true); o = r; EXPECT_EQ (o.selected_not_interacting (rr).to_string (), "(70,60;70,80;90,80;90,60)"); + EXPECT_EQ (db::compare (o.selected_interacting_differential (rr).first, "(0,0;0,20;20,20;20,0);(50,10;50,30;70,30;70,10);(20,30;20,50;40,50;40,30);(0,60;0,80;60,80;60,60);(0,100;0,130;30,130;30,100)"), true); + EXPECT_EQ (db::compare (o.selected_interacting_differential (rr).second, "(70,60;70,80;90,80;90,60)"), true); EXPECT_EQ (o.selected_interacting (rr).count () + o.selected_not_interacting (rr).count (), size_t (6)); EXPECT_EQ (o.selected_interacting (rr).hier_count () + o.selected_not_interacting (rr).hier_count (), size_t (6)); o.select_not_interacting (rr); @@ -872,6 +880,8 @@ TEST(18a) EXPECT_EQ (db::compare (o, "(0,0;0,20;20,20;20,0);(20,30;20,50;40,50;40,30);(0,60;0,80;60,80;60,60);(0,100;0,130;30,130;30,100)"), true); o = r; EXPECT_EQ (db::compare (o.selected_not_overlapping (rr), "(50,10;50,30;70,30;70,10);(70,60;70,80;90,80;90,60)"), true); + EXPECT_EQ (db::compare (o.selected_overlapping_differential (rr).first, "(0,0;0,20;20,20;20,0);(20,30;20,50;40,50;40,30);(0,60;0,80;60,80;60,60);(0,100;0,130;30,130;30,100)"), true); + EXPECT_EQ (db::compare (o.selected_overlapping_differential (rr).second, "(50,10;50,30;70,30;70,10);(70,60;70,80;90,80;90,60)"), true); EXPECT_EQ (o.selected_overlapping (rr).count () + o.selected_not_overlapping (rr).count (), size_t (6)); EXPECT_EQ (o.selected_overlapping (rr).hier_count () + o.selected_not_overlapping (rr).hier_count (), size_t (6)); o.select_not_overlapping (rr); @@ -884,6 +894,8 @@ TEST(18a) EXPECT_EQ (o.to_string (), "(0,100;0,130;30,130;30,100)"); o = r; EXPECT_EQ (db::compare (o.selected_not_enclosing (rr), "(0,0;0,20;20,20;20,0);(50,10;50,30;70,30;70,10);(70,60;70,80;90,80;90,60);(20,30;20,50;40,50;40,30);(0,60;0,80;60,80;60,60)"), true); + EXPECT_EQ (db::compare (o.selected_enclosing_differential (rr).first, "(0,100;0,130;30,130;30,100)"), true); + EXPECT_EQ (db::compare (o.selected_enclosing_differential (rr).second, "(0,0;0,20;20,20;20,0);(50,10;50,30;70,30;70,10);(70,60;70,80;90,80;90,60);(20,30;20,50;40,50;40,30);(0,60;0,80;60,80;60,60)"), true); EXPECT_EQ (o.selected_enclosing (rr).count () + o.selected_not_enclosing (rr).count (), size_t (6)); EXPECT_EQ (o.selected_enclosing (rr).hier_count () + o.selected_not_enclosing (rr).hier_count (), size_t (6)); o.select_not_enclosing (rr); @@ -1506,6 +1518,8 @@ TEST(30a) r.set_merged_semantics (false); EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (20, 20), db::Point (30, 30)))).to_string (), "(0,0;0,200;100,200;100,0)"); EXPECT_EQ (r.selected_not_interacting (db::Edges (db::Edge (db::Point (20, 20), db::Point (30, 30)))).to_string (), "(-100,-100;-100,0;0,0;0,-100)"); + EXPECT_EQ (r.selected_interacting_differential (db::Edges (db::Edge (db::Point (20, 20), db::Point (30, 30)))).first.to_string (), "(0,0;0,200;100,200;100,0)"); + EXPECT_EQ (r.selected_interacting_differential (db::Edges (db::Edge (db::Point (20, 20), db::Point (30, 30)))).second.to_string (), "(-100,-100;-100,0;0,0;0,-100)"); EXPECT_EQ (db::compare (r.selected_interacting (db::Edges (db::Edge (db::Point (-20, -20), db::Point (30, 30)))), "(-100,-100;-100,0;0,0;0,-100);(0,0;0,200;100,200;100,0)"), true); EXPECT_EQ (r.selected_interacting (db::Edges (db::Edge (db::Point (-200, -200), db::Point (-190, -190)))).to_string (), ""); db::Region rr = r; @@ -1689,6 +1703,8 @@ TEST(34a) r.set_merged_semantics (false); EXPECT_EQ (r.selected_interacting (db::Texts (db::Text ("abc", db::Trans (db::Vector (30, 30))))).to_string (), "(0,0;0,200;100,200;100,0)"); EXPECT_EQ (r.selected_not_interacting (db::Texts (db::Text ("abc", db::Trans (db::Vector (30, 30))))).to_string (), "(-100,-100;-100,0;0,0;0,-100)"); + EXPECT_EQ (r.selected_interacting_differential (db::Texts (db::Text ("abc", db::Trans (db::Vector (30, 30))))).first.to_string (), "(0,0;0,200;100,200;100,0)"); + EXPECT_EQ (r.selected_interacting_differential (db::Texts (db::Text ("abc", db::Trans (db::Vector (30, 30))))).second.to_string (), "(-100,-100;-100,0;0,0;0,-100)"); db::Texts tt; tt.insert (db::Text ("abc", db::Trans (db::Vector (30, 30)))); tt.insert (db::Text ("xyz", db::Trans (db::Vector (-100, 0)))); @@ -1782,6 +1798,7 @@ TEST(35a_interact_with_count_region) EXPECT_EQ (r.selected_interacting (rr, 0, 2).to_string (), ""); EXPECT_EQ (r.selected_interacting (rr, 1, 2).to_string (), ""); EXPECT_EQ (r.selected_interacting (rr, 1, 4).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); + EXPECT_EQ (r.selected_interacting_differential (rr, 1, 4).first.to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_interacting (rr, 2, 4).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_interacting (rr, 2, 1).to_string (), ""); EXPECT_EQ (r.selected_interacting (rr, 3, 4).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); @@ -1797,6 +1814,7 @@ TEST(35a_interact_with_count_region) EXPECT_EQ (r.selected_not_interacting (rr).to_string (), ""); EXPECT_EQ (r.selected_not_interacting (rr, 0, 2).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_not_interacting (rr, 1, 2).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); + EXPECT_EQ (r.selected_interacting_differential (rr, 1, 2).second.to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_not_interacting (rr, 1, 4).to_string (), ""); EXPECT_EQ (r.selected_not_interacting (rr, 2, 4).to_string (), ""); EXPECT_EQ (db::compare (r.selected_not_interacting (rr, 2, 1), "(0,0;0,200;100,200;100,0);(-100,-100;-100,0;0,0;0,-100)"), true); @@ -1855,6 +1873,7 @@ TEST(35b_interact_with_count_edge) EXPECT_EQ (r.selected_interacting (rr, 1, 2).to_string (), ""); EXPECT_EQ (r.selected_interacting (rr, 1, 4).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_interacting (rr, 2, 4).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); + EXPECT_EQ (r.selected_interacting_differential (rr, 2, 4).first.to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_interacting (rr, 2, 1).to_string (), ""); EXPECT_EQ (r.selected_interacting (rr, 3, 4).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_interacting (rr, 4, 5).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); @@ -1869,6 +1888,7 @@ TEST(35b_interact_with_count_edge) EXPECT_EQ (r.selected_not_interacting (rr).to_string (), ""); EXPECT_EQ (r.selected_not_interacting (rr, 0, 2).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_not_interacting (rr, 1, 2).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); + EXPECT_EQ (r.selected_interacting_differential (rr, 1, 2).second.to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_not_interacting (rr, 1, 4).to_string (), ""); EXPECT_EQ (r.selected_not_interacting (rr, 2, 4).to_string (), ""); EXPECT_EQ (db::compare (r.selected_not_interacting (rr, 2, 1), "(0,0;0,200;100,200;100,0);(-100,-100;-100,0;0,0;0,-100)"), true); @@ -1926,6 +1946,7 @@ TEST(35c_interact_with_count_text) EXPECT_EQ (r.selected_interacting (rr, 1, 2).to_string (), ""); EXPECT_EQ (r.selected_interacting (rr, 1, 4).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_interacting (rr, 2, 4).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); + EXPECT_EQ (r.selected_interacting_differential (rr, 2, 4).first.to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_interacting (rr, 2, 1).to_string (), ""); EXPECT_EQ (r.selected_interacting (rr, 3, 4).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_interacting (rr, 4, 5).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); @@ -1940,6 +1961,7 @@ TEST(35c_interact_with_count_text) EXPECT_EQ (r.selected_not_interacting (rr).to_string (), ""); EXPECT_EQ (r.selected_not_interacting (rr, 0, 2).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_not_interacting (rr, 1, 2).to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); + EXPECT_EQ (r.selected_interacting_differential (rr, 1, 2).second.to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.selected_not_interacting (rr, 1, 4).to_string (), ""); EXPECT_EQ (r.selected_not_interacting (rr, 2, 4).to_string (), ""); EXPECT_EQ (db::compare (r.selected_not_interacting (rr, 2, 1), "(0,0;0,200;100,200;100,0);(-100,-100;-100,0;0,0;0,-100)"), true); diff --git a/src/drc/drc/built-in-macros/_drc_layer.rb b/src/drc/drc/built-in-macros/_drc_layer.rb index 4af73ed55..9ebc03775 100644 --- a/src/drc/drc/built-in-macros/_drc_layer.rb +++ b/src/drc/drc/built-in-macros/_drc_layer.rb @@ -1660,6 +1660,7 @@ CODE @engine._context("andnot") do + check_is_layer(other) requires_region other.requires_region @@ -1776,14 +1777,17 @@ CODE # %DRC% # @name split_covering # @brief Returns the results of \covering and \not_covering at the same time + # @synopsis (a, b) = layer.split_covering(other [, options ]) # # This method returns the polygons covering polygons from the other layer in # one layer and all others in a second layer. This method is equivalent to calling - # \covering and \not_covering, but is faster than doing this is separate steps: + # \covering and \not_covering, but is faster than doing this in separate steps: # # @code # (covering, not_covering) = l1.split_covering(l2) # @/code + # + # The options of this method are the same than \covering. # %DRC% # @name select_covering @@ -1864,14 +1868,17 @@ CODE # %DRC% # @name split_overlapping # @brief Returns the results of \overlapping and \not_overlapping at the same time + # @synopsis (a, b) = layer.split_overlapping(other [, options ]) # # This method returns the polygons overlapping polygons from the other layer in # one layer and all others in a second layer. This method is equivalent to calling - # \overlapping and \not_overlapping, but is faster than doing this is separate steps: + # \overlapping and \not_overlapping, but is faster than doing this in separate steps: # # @code # (overlapping, not_overlapping) = l1.split_overlapping(l2) # @/code + # + # The options of this method are the same than \overlapping. # %DRC% # @name select_overlapping @@ -1950,10 +1957,11 @@ CODE # %DRC% # @name split_inside # @brief Returns the results of \inside and \not_inside at the same time + # @synopsis (a, b) = layer.split_inside(other) # # This method returns the polygons inside of polygons from the other layer in # one layer and all others in a second layer. This method is equivalent to calling - # \inside and \not_inside, but is faster than doing this is separate steps: + # \inside and \not_inside, but is faster than doing this in separate steps: # # @code # (inside, not_inside) = l1.split_inside(l2) @@ -2034,10 +2042,11 @@ CODE # %DRC% # @name split_outside # @brief Returns the results of \outside and \not_outside at the same time + # @synopsis (a, b) = layer.split_outside(other) # # This method returns the polygons outside of polygons from the other layer in # one layer and all others in a second layer. This method is equivalent to calling - # \outside and \not_outside, but is faster than doing this is separate steps: + # \outside and \not_outside, but is faster than doing this in separate steps: # # @code # (outside, not_outside) = l1.split_outside(l2) @@ -2200,14 +2209,17 @@ CODE # %DRC% # @name split_interacting # @brief Returns the results of \interacting and \not_interacting at the same time + # @synopsis (a, b) = layer.split_interacting(other [, options ]) # # This method returns the polygons interacting with objects from the other container in # one layer and all others in a second layer. This method is equivalent to calling - # \interacting and \not_interacting, but is faster than doing this is separate steps: + # \interacting and \not_interacting, but is faster than doing this in separate steps: # # @code # (interacting, not_interacting) = l1.split_interacting(l2) # @/code + # + # The options of this method are the same than \interacting. # %DRC% # @name select_interacting @@ -2345,6 +2357,7 @@ CODE @engine._context("#{f}") do + check_is_layer(other) if :#{f} != :pull_interacting requires_region other.requires_region @@ -2390,6 +2403,7 @@ CODE @engine._context("#{f}") do + check_is_layer(other) other.requires_edges_texts_or_region if self.data.is_a?(RBA::Texts) other.requires_region @@ -2426,6 +2440,7 @@ CODE @engine._context("#{f}") do + check_is_layer(other) if self.data.is_a?(RBA::Text) other.requires_region elsif self.data.is_a?(RBA::Region) @@ -2450,6 +2465,7 @@ CODE @engine._context("#{f}") do + check_is_layer(other) requires_edges_texts_or_region if self.data.is_a?(RBA::Text) other.requires_region @@ -2478,6 +2494,7 @@ CODE @engine._context("#{f}") do + check_is_layer(other) requires_region other.requires_edges_texts_or_region @@ -2580,6 +2597,7 @@ CODE @engine._context("#{f}") do + check_is_layer(other) requires_region other.requires_region @@ -2598,6 +2616,7 @@ CODE @engine._context("#{f}") do + check_is_layer(other) other.requires_region requires_edges @@ -2615,6 +2634,7 @@ CODE @engine._context("#{f}") do + check_is_layer(other) other.requires_edges requires_edges @@ -4230,6 +4250,10 @@ CODE @data = d end + def check_is_layer(other) + other.is_a?(DRCLayer) || raise("Argument needs to be a DRC layer") + end + def requires_region self.data.is_a?(RBA::Region) || raise("Requires a polygon layer") end diff --git a/src/lay/lay/doc/about/drc_ref_layer.xml b/src/lay/lay/doc/about/drc_ref_layer.xml index 702ec3f82..b0bfbca96 100644 --- a/src/lay/lay/doc/about/drc_ref_layer.xml +++ b/src/lay/lay/doc/about/drc_ref_layer.xml @@ -2659,6 +2659,87 @@ The following image shows the effect of the space check:

+

"split_covering" - Returns the results of covering and not_covering at the same time

+ +

Usage:

+
    +
  • (a, b) = layer.split_covering(other [, options ])
  • +
+

+This method returns the polygons covering polygons from the other layer in +one layer and all others in a second layer. This method is equivalent to calling +covering and not_covering, but is faster than doing this in separate steps: +

+

+(covering, not_covering) = l1.split_covering(l2)
+
+

+The options of this method are the same than covering. +

+

"split_inside" - Returns the results of inside and not_inside at the same time

+ +

Usage:

+
    +
  • (a, b) = layer.split_inside(other)
  • +
+

+This method returns the polygons inside of polygons from the other layer in +one layer and all others in a second layer. This method is equivalent to calling +inside and not_inside, but is faster than doing this in separate steps: +

+

+(inside, not_inside) = l1.split_inside(l2)
+
+

+

"split_interacting" - Returns the results of interacting and not_interacting at the same time

+ +

Usage:

+
    +
  • (a, b) = layer.split_interacting(other [, options ])
  • +
+

+This method returns the polygons interacting with objects from the other container in +one layer and all others in a second layer. This method is equivalent to calling +interacting and not_interacting, but is faster than doing this in separate steps: +

+

+(interacting, not_interacting) = l1.split_interacting(l2)
+
+

+The options of this method are the same than interacting. +

+

"split_outside" - Returns the results of outside and not_outside at the same time

+ +

Usage:

+
    +
  • (a, b) = layer.split_outside(other)
  • +
+

+This method returns the polygons outside of polygons from the other layer in +one layer and all others in a second layer. This method is equivalent to calling +outside and not_outside, but is faster than doing this in separate steps: +

+

+(outside, not_outside) = l1.split_outside(l2)
+
+

+

"split_overlapping" - Returns the results of overlapping and not_overlapping at the same time

+ +

Usage:

+
    +
  • (a, b) = layer.split_overlapping(other [, options ])
  • +
+

+This method returns the polygons overlapping polygons from the other layer in +one layer and all others in a second layer. This method is equivalent to calling +overlapping and not_overlapping, but is faster than doing this in separate steps: +

+

+(overlapping, not_overlapping) = l1.split_overlapping(l2)
+
+

+The options of this method are the same than overlapping. +

"squares" - Selects all squares from the input

Usage:

diff --git a/testdata/drc/drcSimpleTests_20.drc b/testdata/drc/drcSimpleTests_20.drc index 5468d4f58..36eb31718 100644 --- a/testdata/drc/drcSimpleTests_20.drc +++ b/testdata/drc/drcSimpleTests_20.drc @@ -12,6 +12,18 @@ l2 = input(2, 0) l1.output(1, 0) l2.output(2, 0) +def split_vs_normal(r, f1, f2, *args) + d1 = r.send(f1, *args)[0].data + d2 = r.send(f2, *args).data + d1.to_s == d2.to_s || raise("#{f1.to_s} vs. #{f2.to_s} check failed: #{d1.to_s} != #{d2.to_s}") +end + +def splitn_vs_normal(r, f1, f2, *args) + d1 = r.send(f1, *args)[1].data + d2 = r.send(f2, *args).data + d1.to_s == d2.to_s || raise("#{f1.to_s} vs. #{f2.to_s} check failed: #{d1.to_s} != #{d2.to_s}") +end + l1.interacting(l2, 1).output(100, 0) l1.interacting(l2, 2).output(101, 0) l1.interacting(l2, 1..2).output(102, 0) @@ -22,6 +34,11 @@ else end l1.interacting(l2, 1, 2).output(104, 0) +split_vs_normal(l1, :split_interacting, :interacting, l2, 1) +split_vs_normal(l1, :split_interacting, :interacting, l2, 2) +split_vs_normal(l1, :split_interacting, :interacting, l2, 1..2) +split_vs_normal(l1, :split_interacting, :interacting, l2, 1, 2) + l1.overlapping(l2, 1).output(110, 0) l1.overlapping(l2, 2).output(111, 0) l1.overlapping(l2, 1..2).output(112, 0) @@ -32,6 +49,11 @@ else end l1.overlapping(l2, 1, 2).output(114, 0) +split_vs_normal(l1, :split_overlapping, :overlapping, l2, 1) +split_vs_normal(l1, :split_overlapping, :overlapping, l2, 2) +split_vs_normal(l1, :split_overlapping, :overlapping, l2, 1..2) +split_vs_normal(l1, :split_overlapping, :overlapping, l2, 1, 2) + l = l1.dup l.select_interacting(l2, 1) l.output(200, 0) @@ -82,6 +104,11 @@ else end l1.not_interacting(l2, 1, 2).output(304, 0) +splitn_vs_normal(l1, :split_interacting, :not_interacting, l2, 1) +splitn_vs_normal(l1, :split_interacting, :not_interacting, l2, 2) +splitn_vs_normal(l1, :split_interacting, :not_interacting, l2, 1..2) +splitn_vs_normal(l1, :split_interacting, :not_interacting, l2, 1, 2) + l1.not_overlapping(l2, 1).output(310, 0) l1.not_overlapping(l2, 2).output(311, 0) l1.not_overlapping(l2, 1..2).output(312, 0) @@ -92,6 +119,11 @@ else end l1.not_overlapping(l2, 1, 2).output(314, 0) +splitn_vs_normal(l1, :split_overlapping, :not_overlapping, l2, 1) +splitn_vs_normal(l1, :split_overlapping, :not_overlapping, l2, 2) +splitn_vs_normal(l1, :split_overlapping, :not_overlapping, l2, 1..2) +splitn_vs_normal(l1, :split_overlapping, :not_overlapping, l2, 1, 2) + l = l1.dup l.select_not_interacting(l2, 1) l.output(400, 0) diff --git a/testdata/drc/drcSimpleTests_24.drc b/testdata/drc/drcSimpleTests_24.drc index 3b594e534..3c69ec3bc 100644 --- a/testdata/drc/drcSimpleTests_24.drc +++ b/testdata/drc/drcSimpleTests_24.drc @@ -10,11 +10,33 @@ b = input(2, 0) a.output(1, 0) b.output(2, 0) +def split_vs_normal(r, f1, f2, *args) + d1 = r.send(f1, *args)[0].data + d2 = r.send(f2, *args).data + d1.to_s == d2.to_s || raise("#{f1.to_s} vs. #{f2.to_s} check failed: #{d1.to_s} != #{d2.to_s}") +end + +def splitn_vs_normal(r, f1, f2, *args) + d1 = r.send(f1, *args)[1].data + d2 = r.send(f2, *args).data + d1.to_s == d2.to_s || raise("#{f1.to_s} vs. #{f2.to_s} check failed: #{d1.to_s} != #{d2.to_s}") +end + a.covering(b).output(100, 0) a.covering(b, 1..1).output(101, 0) a.covering(b, 2..2).output(102, 0) a.covering(b, 3..3).output(103, 0) b.inside(a).output(110, 0) +a.not_covering(b).output(120, 0) +b.not_inside(a).output(130, 0) + +split_vs_normal(a, :split_covering, :covering, b) +split_vs_normal(a, :split_covering, :covering, b, 1..1) +split_vs_normal(a, :split_covering, :covering, b, 2..2) +split_vs_normal(a, :split_covering, :covering, b, 3..3) +split_vs_normal(b, :split_inside, :inside, a) +splitn_vs_normal(a, :split_covering, :not_covering, b) +splitn_vs_normal(b, :split_inside, :not_inside, a) deep @@ -26,4 +48,14 @@ a.covering(b, 1..1).output(201, 0) a.covering(b, 2..2).output(202, 0) a.covering(b, 3..3).output(203, 0) b.inside(a).output(210, 0) +a.not_covering(b).output(220, 0) +b.not_inside(a).output(230, 0) + +split_vs_normal(a, :split_covering, :covering, b) +split_vs_normal(a, :split_covering, :covering, b, 1..1) +split_vs_normal(a, :split_covering, :covering, b, 2..2) +split_vs_normal(a, :split_covering, :covering, b, 3..3) +split_vs_normal(b, :split_inside, :inside, a) +splitn_vs_normal(a, :split_covering, :not_covering, b) +splitn_vs_normal(b, :split_inside, :not_inside, a) diff --git a/testdata/drc/drcSimpleTests_au24.gds b/testdata/drc/drcSimpleTests_au24.gds index 8ca7815d2..e650d083b 100644 Binary files a/testdata/drc/drcSimpleTests_au24.gds and b/testdata/drc/drcSimpleTests_au24.gds differ diff --git a/testdata/drc/drcSuiteTests.drc b/testdata/drc/drcSuiteTests.drc index 9574e8e96..35615d564 100644 --- a/testdata/drc/drcSuiteTests.drc +++ b/testdata/drc/drcSuiteTests.drc @@ -148,6 +148,7 @@ def run_testsuite(dm, ic, tiled = false, hier = false) b.not_interacting(a).output(lb, dm + 1) b.interacting(empty).output(lb, dm + 2) b.not_interacting(empty).output(lb, dm + 3) + b.interacting(a).in(b).output(lb + 1, dm) (b|a).not_in(b).output(lb + 2, dm) x.in(b).output(lb + 3, dm) @@ -160,18 +161,42 @@ def run_testsuite(dm, ic, tiled = false, hier = false) b.not_inside(c).output(lb, dm + 1) b.inside(empty).output(lb, dm + 2) b.not_inside(empty).output(lb, dm + 3) + (p, m) = b.split_inside(c) + p.output(lb, dm + 10) + m.output(lb, dm + 11) + + b.covering(c).output(lb, dm + 100) + b.not_covering(c).output(lb, dm + 101) + b.covering(empty).output(lb, dm + 102) + b.not_covering(empty).output(lb, dm + 103) + (p, m) = b.split_covering(c) + p.output(lb, dm + 110) + m.output(lb, dm + 111) + b.outside(c).output(lb + 1, dm) b.not_outside(c).output(lb + 1, dm + 1) b.outside(empty).output(lb + 1, dm + 2) b.not_outside(empty).output(lb + 1, dm + 3) + (p, m) = b.split_outside(c) + p.output(lb + 1, dm + 10) + m.output(lb + 1, dm + 11) + b.overlapping(c).output(lb + 2, dm) b.not_overlapping(c).output(lb + 2, dm + 1) b.overlapping(empty).output(lb + 2, dm + 2) b.not_overlapping(empty).output(lb + 2, dm + 3) + (p, m) = b.split_overlapping(c) + p.output(lb + 2, dm + 10) + m.output(lb + 2, dm + 11) + b.interacting(c).output(lb + 3, dm) b.not_interacting(c).output(lb + 3, dm + 1) b.interacting(empty).output(lb + 3, dm + 2) b.not_interacting(empty).output(lb + 3, dm + 3) + (p, m) = b.split_interacting(c) + p.output(lb + 3, dm + 10) + m.output(lb + 3, dm + 11) + bdup = b.dup bdup.select_inside(c) bdup.xor(b.inside(c)).output(lb + 4, dm) diff --git a/testdata/drc/drcSuiteTests_au1.oas b/testdata/drc/drcSuiteTests_au1.oas index ef395210f..0dd5c6851 100644 Binary files a/testdata/drc/drcSuiteTests_au1.oas and b/testdata/drc/drcSuiteTests_au1.oas differ diff --git a/testdata/drc/drcSuiteTests_au2.oas b/testdata/drc/drcSuiteTests_au2.oas index 8a5528975..6ccbca614 100644 Binary files a/testdata/drc/drcSuiteTests_au2.oas and b/testdata/drc/drcSuiteTests_au2.oas differ diff --git a/testdata/drc/drcSuiteTests_au3.oas b/testdata/drc/drcSuiteTests_au3.oas index 4f5221a28..c42f0b098 100644 Binary files a/testdata/drc/drcSuiteTests_au3.oas and b/testdata/drc/drcSuiteTests_au3.oas differ diff --git a/testdata/drc/drcSuiteTests_au4.oas b/testdata/drc/drcSuiteTests_au4.oas index bff2c5694..1b2dc47b6 100644 Binary files a/testdata/drc/drcSuiteTests_au4.oas and b/testdata/drc/drcSuiteTests_au4.oas differ diff --git a/testdata/drc/drcSuiteTests_au5.oas b/testdata/drc/drcSuiteTests_au5.oas index c5ea03d11..ccb803594 100644 Binary files a/testdata/drc/drcSuiteTests_au5.oas and b/testdata/drc/drcSuiteTests_au5.oas differ diff --git a/testdata/drc/drcSuiteTests_au6.oas b/testdata/drc/drcSuiteTests_au6.oas index e1017d058..e9a693a4d 100644 Binary files a/testdata/drc/drcSuiteTests_au6.oas and b/testdata/drc/drcSuiteTests_au6.oas differ diff --git a/testdata/ruby/dbRegionTest.rb b/testdata/ruby/dbRegionTest.rb index 27cd9b257..79985b676 100644 --- a/testdata/ruby/dbRegionTest.rb +++ b/testdata/ruby/dbRegionTest.rb @@ -525,34 +525,49 @@ class DBRegion_TestClass < TestBase r1 = RBA::Region::new r1.insert(RBA::Box::new(10, 20, 100, 200)) + r11 = r1.dup r1.insert(RBA::Box::new(50, 70, 150, 270)) r1.insert(RBA::Box::new(100, 70, 250, 270)) r2 = RBA::Region::new(RBA::Box::new(-10, -20, 100, 200)) r3 = RBA::Region::new(RBA::Box::new(150, 270, 160, 280)) r3 += r2 + r21 = r2.dup + r21 += RBA::Region::new(RBA::Box::new(110, -20, 200, 200)) assert_equal(r1.merged_semantics?, true) r1.merged_semantics = false assert_equal(r1.merged_semantics?, false) assert_equal(r1.inside(r2).to_s, "(10,20;10,200;100,200;100,20)") + assert_equal(r1.split_inside(r2)[0].to_s, "(10,20;10,200;100,200;100,20)") assert_equal(csort(r1.not_inside(r2).to_s), csort("(50,70;50,270;150,270;150,70);(100,70;100,270;250,270;250,70)")) + assert_equal(csort(r1.split_inside(r2)[1].to_s), csort("(50,70;50,270;150,270;150,70);(100,70;100,270;250,270;250,70)")) + assert_equal(r21.covering(r11).to_s, "(-10,-20;-10,200;100,200;100,-20)") + assert_equal(r21.split_covering(r11)[0].to_s, "(-10,-20;-10,200;100,200;100,-20)") + assert_equal(csort(r21.not_covering(r11).to_s), csort("(110,-20;110,200;200,200;200,-20)")) + assert_equal(csort(r21.split_covering(r11)[1].to_s), csort("(110,-20;110,200;200,200;200,-20)")) assert_equal(csort(r1.interacting(r2).to_s), csort("(10,20;10,200;100,200;100,20);(50,70;50,270;150,270;150,70);(100,70;100,270;250,270;250,70)")) assert_equal(csort(r1.interacting(r3, 1).to_s), csort("(10,20;10,200;100,200;100,20);(50,70;50,270;150,270;150,70);(100,70;100,270;250,270;250,70)")) assert_equal(csort(r1.interacting(r3, 2).to_s), csort("(50,70;50,270;150,270;150,70);(100,70;100,270;250,270;250,70)")) + assert_equal(csort(r1.split_interacting(r3, 2)[0].to_s), csort("(50,70;50,270;150,270;150,70);(100,70;100,270;250,270;250,70)")) assert_equal(r1.interacting(r3, 3).to_s, "") assert_equal(r1.interacting(r3, 1, 1).to_s, "(10,20;10,200;100,200;100,20)") assert_equal(csort(r1.interacting(r3, 2, 2).to_s), csort("(50,70;50,270;150,270;150,70);(100,70;100,270;250,270;250,70)")) assert_equal(r1.not_interacting(r2).to_s, "") assert_equal(r1.not_interacting(r3, 1).to_s, "") assert_equal(r1.not_interacting(r3, 2).to_s, "(10,20;10,200;100,200;100,20)") + assert_equal(r1.split_interacting(r3, 2)[1].to_s, "(10,20;10,200;100,200;100,20)") assert_equal(csort(r1.not_interacting(r3, 3).to_s), csort("(10,20;10,200;100,200;100,20);(50,70;50,270;150,270;150,70);(100,70;100,270;250,270;250,70)")) assert_equal(csort(r1.not_interacting(r3, 1, 1).to_s), csort("(50,70;50,270;150,270;150,70);(100,70;100,270;250,270;250,70)")) assert_equal(r1.not_interacting(r3, 2, 2).to_s, "(10,20;10,200;100,200;100,20)") assert_equal(csort(r1.overlapping(r2).to_s), csort("(10,20;10,200;100,200;100,20);(50,70;50,270;150,270;150,70)")) + assert_equal(csort(r1.split_overlapping(r2)[0].to_s), csort("(10,20;10,200;100,200;100,20);(50,70;50,270;150,270;150,70)")) assert_equal(r1.not_overlapping(r2).to_s, "(100,70;100,270;250,270;250,70)") + assert_equal(r1.split_overlapping(r2)[1].to_s, "(100,70;100,270;250,270;250,70)") assert_equal(r1.outside(r2).to_s, "(100,70;100,270;250,270;250,70)") + assert_equal(r1.split_outside(r2)[0].to_s, "(100,70;100,270;250,270;250,70)") assert_equal(csort(r1.not_outside(r2).to_s), csort("(10,20;10,200;100,200;100,20);(50,70;50,270;150,270;150,70)")) + assert_equal(csort(r1.split_outside(r2)[1].to_s), csort("(10,20;10,200;100,200;100,20);(50,70;50,270;150,270;150,70)")) e2 = RBA::Edges::new(RBA::Edge::new(-10, -20, 100, 200)) e3 = RBA::Edges::new(RBA::Edge::new(150, 270, 160, 280)) @@ -561,12 +576,14 @@ class DBRegion_TestClass < TestBase assert_equal(csort(r1.interacting(e2).to_s), csort("(100,70;100,270;250,270;250,70);(50,70;50,270;150,270;150,70);(10,20;10,200;100,200;100,20)")) assert_equal(csort(r1.interacting(e3, 1).to_s), csort("(100,70;100,270;250,270;250,70);(50,70;50,270;150,270;150,70);(10,20;10,200;100,200;100,20)")) assert_equal(csort(r1.interacting(e3, 2).to_s), csort("(100,70;100,270;250,270;250,70);(50,70;50,270;150,270;150,70)")) + assert_equal(csort(r1.split_interacting(e3, 2)[0].to_s), csort("(100,70;100,270;250,270;250,70);(50,70;50,270;150,270;150,70)")) assert_equal(r1.interacting(e3, 3).to_s, "") assert_equal(r1.interacting(e3, 1, 1).to_s, "(10,20;10,200;100,200;100,20)") assert_equal(csort(r1.interacting(e3, 2, 2).to_s), csort("(100,70;100,270;250,270;250,70);(50,70;50,270;150,270;150,70)")) assert_equal(r1.not_interacting(e2).to_s, "") assert_equal(r1.not_interacting(e3, 1).to_s, "") assert_equal(r1.not_interacting(e3, 2).to_s, "(10,20;10,200;100,200;100,20)") + assert_equal(r1.split_interacting(e3, 2)[1].to_s, "(10,20;10,200;100,200;100,20)") assert_equal(csort(r1.not_interacting(e3, 3).to_s), csort("(100,70;100,270;250,270;250,70);(50,70;50,270;150,270;150,70);(10,20;10,200;100,200;100,20)")) assert_equal(csort(r1.not_interacting(e3, 1, 1).to_s), csort("(100,70;100,270;250,270;250,70);(50,70;50,270;150,270;150,70)")) assert_equal(r1.not_interacting(e3, 2, 2).to_s, "(10,20;10,200;100,200;100,20)") @@ -577,6 +594,7 @@ class DBRegion_TestClass < TestBase assert_equal(csort(r1.interacting(t2).to_s), csort("(50,70;50,270;150,270;150,70);(10,20;10,200;100,200;100,20)")) assert_equal(csort(r1.interacting(t3, 1).to_s), csort("(100,70;100,270;250,270;250,70);(50,70;50,270;150,270;150,70);(10,20;10,200;100,200;100,20)")) + assert_equal(csort(r1.split_interacting(t3, 1)[0].to_s), csort("(100,70;100,270;250,270;250,70);(50,70;50,270;150,270;150,70);(10,20;10,200;100,200;100,20)")) assert_equal(r1.interacting(t3, 2).to_s, "(50,70;50,270;150,270;150,70)") assert_equal(r1.interacting(t3, 3).to_s, "") assert_equal(csort(r1.interacting(t3, 1, 1).to_s), csort("(100,70;100,270;250,270;250,70);(10,20;10,200;100,200;100,20)")) @@ -584,6 +602,7 @@ class DBRegion_TestClass < TestBase assert_equal(r1.not_interacting(t2).to_s, "(100,70;100,270;250,270;250,70)") assert_equal(r1.not_interacting(t3, 1).to_s, "") assert_equal(csort(r1.not_interacting(t3, 2).to_s), csort("(100,70;100,270;250,270;250,70);(10,20;10,200;100,200;100,20)")) + assert_equal(csort(r1.split_interacting(t3, 2)[1].to_s), csort("(100,70;100,270;250,270;250,70);(10,20;10,200;100,200;100,20)")) assert_equal(csort(r1.not_interacting(t3, 3).to_s), csort("(100,70;100,270;250,270;250,70);(50,70;50,270;150,270;150,70);(10,20;10,200;100,200;100,20)")) assert_equal(r1.not_interacting(t3, 1, 1).to_s, "(50,70;50,270;150,270;150,70)") assert_equal(csort(r1.not_interacting(t3, 2, 2).to_s), csort("(100,70;100,270;250,270;250,70);(10,20;10,200;100,200;100,20)"))