diff --git a/src/db/db/dbAsIfFlatEdges.cc b/src/db/db/dbAsIfFlatEdges.cc index bee4e3709..da124613c 100644 --- a/src/db/db/dbAsIfFlatEdges.cc +++ b/src/db/db/dbAsIfFlatEdges.cc @@ -221,9 +221,9 @@ AsIfFlatEdges::selected_interacting_pair_generic (const Region ®ion, EdgeInte for (EdgesIterator o (begin_merged ()); ! o.at_end (); ++o) { if (result.find (*o) == result.end ()) { - output->insert (*o); - } else { output2->insert (*o); + } else { + output->insert (*o); } } @@ -265,9 +265,9 @@ AsIfFlatEdges::selected_interacting_pair_generic (const Edges &other, EdgeIntera for (EdgesIterator o (begin_merged ()); ! o.at_end (); ++o) { if (results.find (*o) == results.end ()) { - output->insert (*o); - } else { output2->insert (*o); + } else { + output->insert (*o); } } diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index f5855af70..3239cb778 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -914,6 +914,32 @@ EdgesDelegate *DeepEdges::and_with (const Region &other) const } } +std::pair DeepEdges::andnot_with (const Region &other) const +{ + const DeepRegion *other_deep = dynamic_cast (other.delegate ()); + + if (empty ()) { + + // Nothing to do + return std::make_pair (new EmptyEdges (), new EmptyEdges ()); + + } else if (other.empty ()) { + + // Nothing to do + return std::make_pair (new EmptyEdges (), clone ()); + + } else if (! other_deep) { + + return AsIfFlatEdges::andnot_with (other); + + } else { + + auto res = edge_region_op (other_deep, EdgePolygonOp::Both, true /*include borders*/); + return std::make_pair (new DeepEdges (res.first), new DeepEdges (res.second)); + + } +} + EdgesDelegate *DeepEdges::not_with (const Region &other) const { const DeepRegion *other_deep = dynamic_cast (other.delegate ()); diff --git a/src/db/db/dbEdgesUtils.h b/src/db/db/dbEdgesUtils.h index 84d073f94..055d78eae 100644 --- a/src/db/db/dbEdgesUtils.h +++ b/src/db/db/dbEdgesUtils.h @@ -275,19 +275,35 @@ public: // .. nothing yet .. } + void finish (const db::Edge *o, size_t p) + { + if (p == 0 && m_mode == EdgesOutside && m_seen.find (o) == m_seen.end ()) { + mp_output->insert (*o); + } + } + void add (const db::Edge *o1, size_t p1, const db::Edge *o2, size_t p2) { // Select the edges which intersect if (p1 != p2) { + const db::Edge *o = p1 > p2 ? o2 : o1; const db::Edge *oo = p1 > p2 ? o1 : o2; + if ((m_mode == EdgesInteract && db::edge_interacts (*o, *oo)) || - (m_mode == EdgesInside && db::edge_is_inside (*o, *oo)) || - (m_mode == EdgesOutside && db::edge_is_outside (*o, *oo))) { + (m_mode == EdgesInside && db::edge_is_inside (*o, *oo))) { + if (m_seen.insert (o).second) { mp_output->insert (*o); } + + } else if (m_mode == EdgesOutside && ! db::edge_is_outside (*o, *oo)) { + + // In this case we need to collect edges which are outside always - we report those on "finished". + m_seen.insert (o); + } + } } @@ -332,18 +348,51 @@ public: // .. nothing yet .. } + void finish (const OutputType *o) + { + if (m_mode == EdgesOutside && m_seen.find (o) == m_seen.end ()) { + mp_output->insert (*o); + } + } + + void finish1 (const db::Edge *o, size_t /*p*/) + { + const OutputType *ep = 0; + tl::select (ep, o, (const db::Polygon *) 0); + if (ep) { + finish (ep); + } + } + + void finish2 (const db::Polygon *o, size_t /*p*/) + { + const OutputType *ep = 0; + tl::select (ep, (const db::Edge *) 0, o); + if (ep) { + finish (ep); + } + } + void add (const db::Edge *e, size_t, const db::Polygon *p, size_t) { const OutputType *ep = 0; tl::select (ep, e, p); if (m_seen.find (ep) == m_seen.end ()) { + if ((m_mode == EdgesInteract && db::edge_interacts (*e, *p)) || - (m_mode == EdgesInside && db::edge_is_inside (*e, *p)) || - (m_mode == EdgesOutside && db::edge_is_outside (*e, *p))) { + (m_mode == EdgesInside && db::edge_is_inside (*e, *p))) { + m_seen.insert (ep); mp_output->insert (*ep); + + } else if (m_mode == EdgesOutside && ! db::edge_is_outside (*e, *p)) { + + // In this case we need to collect edges which are outside always - we report those on "finished". + m_seen.insert (ep); + } + } } diff --git a/src/db/unit_tests/dbEdgesTests.cc b/src/db/unit_tests/dbEdgesTests.cc index 4cede8b4a..52fe0cacc 100644 --- a/src/db/unit_tests/dbEdgesTests.cc +++ b/src/db/unit_tests/dbEdgesTests.cc @@ -939,6 +939,154 @@ TEST(23) EXPECT_EQ (e2.pull_interacting (e).to_string (), "(0,0;0,200)"); } +// Edges::selected_inside(region) +TEST(24) +{ + db::Edges e; + e.insert (db::Edge (0, 0, 0, 1000)); + e.insert (db::Edge (100, 0, 100, 3000)); + e.insert (db::Edge (1100, -1000, 1100, 2000)); + e.insert (db::Edge (1200, -1000, 1200, 0)); + e.insert (db::Edge (1300, -800, 1300, -200)); + e.insert (db::Edge (1400, 1000, 1400, 1100)); + e.insert (db::Edge (1500, 1000, 1500, 2100)); + e.insert (db::Edge (1600, -800, 1600, -400)); + e.insert (db::Edge (1600, -400, 1600, -200)); + e.insert (db::Edge (1700, 1500, 1600, 2500)); + e.insert (db::Edge (1800, 2500, 1800, 3500)); + e.insert (db::Edge (-1500, 0, -1500, 1000)); + + db::Region r; + r.insert (db::Box (0, -1000, 2000, 0)); + r.insert (db::Box (1000, 1000, 2000, 2000)); + + EXPECT_EQ (db::compare (e.selected_inside (db::Region ()), ""), true); + EXPECT_EQ (db::compare (e.selected_not_inside (db::Region ()), "(0,0;0,1000);(100,0;100,3000);(1100,-1000;1100,2000);(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1500,1000;1500,2100);(1600,-800;1600,-400);(1600,-400;1600,-200);(1700,1500;1600,2500);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (e.selected_inside_differential (db::Region ()).first, ""), true); + EXPECT_EQ (db::compare (e.selected_inside_differential (db::Region ()).second, "(0,0;0,1000);(100,0;100,3000);(1100,-1000;1100,2000);(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1500,1000;1500,2100);(1600,-800;1600,-400);(1600,-400;1600,-200);(1700,1500;1600,2500);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (db::Edges ().selected_inside (r), ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_not_inside (r), ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_inside_differential (r).first, ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_inside_differential (r).second, ""), true); + EXPECT_EQ (db::compare (e.selected_inside (r), "(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1600,-800;1600,-200)"), true); + EXPECT_EQ (db::compare (e.selected_not_inside (r), "(0,0;0,1000);(100,0;100,3000);(1100,-1000;1100,2000);(1500,1000;1500,2100);(1700,1500;1600,2500);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (e.selected_inside_differential (r).first, "(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1600,-800;1600,-200)"), true); + EXPECT_EQ (db::compare (e.selected_inside_differential (r).second, "(0,0;0,1000);(100,0;100,3000);(1100,-1000;1100,2000);(1500,1000;1500,2100);(1700,1500;1600,2500);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); +} + +// Edges::selected_inside(edges) +TEST(25) +{ + db::Edges e; + e.insert (db::Edge (0, 0, 0, 1000)); + e.insert (db::Edge (100, 0, 100, 3000)); + e.insert (db::Edge (1100, -1000, 1100, 2000)); + e.insert (db::Edge (1200, -1000, 1200, 0)); + e.insert (db::Edge (1300, -800, 1300, -200)); + e.insert (db::Edge (1400, 1000, 1400, 1100)); + e.insert (db::Edge (1500, 1000, 1500, 2100)); + e.insert (db::Edge (1600, -800, 1600, -400)); + e.insert (db::Edge (1600, -400, 1600, -200)); + e.insert (db::Edge (1700, 1500, 1600, 2500)); + e.insert (db::Edge (1800, 2500, 1800, 3500)); + e.insert (db::Edge (-1500, 0, -1500, 1000)); + + db::Edges ee; + for (int i = 0; i <= 2000; i += 100) { + ee.insert (db::Edge (i, -1000, i, 0)); + } + for (int i = 1000; i <= 2000; i += 100) { + ee.insert (db::Edge (i, 1000, i, 2000)); + } + + EXPECT_EQ (db::compare (e.selected_inside (db::Edges ()), ""), true); + EXPECT_EQ (db::compare (e.selected_not_inside (db::Edges ()), "(0,0;0,1000);(100,0;100,3000);(1100,-1000;1100,2000);(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1500,1000;1500,2100);(1600,-800;1600,-400);(1600,-400;1600,-200);(1700,1500;1600,2500);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (e.selected_inside_differential (db::Edges ()).first, ""), true); + EXPECT_EQ (db::compare (e.selected_inside_differential (db::Edges ()).second, "(0,0;0,1000);(100,0;100,3000);(1100,-1000;1100,2000);(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1500,1000;1500,2100);(1600,-800;1600,-400);(1600,-400;1600,-200);(1700,1500;1600,2500);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (db::Edges ().selected_inside (ee), ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_not_inside (ee), ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_inside_differential (ee).first, ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_inside_differential (ee).second, ""), true); + EXPECT_EQ (db::compare (e.selected_inside (ee), "(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1600,-800;1600,-200)"), true); + EXPECT_EQ (db::compare (e.selected_not_inside (ee), "(0,0;0,1000);(100,0;100,3000);(1100,-1000;1100,2000);(1500,1000;1500,2100);(1700,1500;1600,2500);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (e.selected_inside_differential (ee).first, "(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1600,-800;1600,-200)"), true); + EXPECT_EQ (db::compare (e.selected_inside_differential (ee).second, "(0,0;0,1000);(100,0;100,3000);(1100,-1000;1100,2000);(1500,1000;1500,2100);(1700,1500;1600,2500);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); +} + +// Edges::selected_outside(region) +TEST(26) +{ + db::Edges e; + e.insert (db::Edge (0, 0, 0, 1000)); + e.insert (db::Edge (100, 0, 100, 3000)); + e.insert (db::Edge (1100, -1000, 1100, 2000)); + e.insert (db::Edge (1200, -1000, 1200, 0)); + e.insert (db::Edge (1300, -800, 1300, -200)); + e.insert (db::Edge (1400, 1000, 1400, 1100)); + e.insert (db::Edge (1500, 1000, 1500, 2100)); + e.insert (db::Edge (1600, -800, 1600, -400)); + e.insert (db::Edge (1600, -400, 1600, -200)); + e.insert (db::Edge (1700, 1500, 1600, 2500)); + e.insert (db::Edge (1800, 2500, 1800, 3500)); + e.insert (db::Edge (-1500, 0, -1500, 1000)); + + db::Region r; + r.insert (db::Box (0, -1000, 2000, 0)); + r.insert (db::Box (1000, 1000, 2000, 2000)); + + EXPECT_EQ (db::compare (e.selected_outside (db::Region ()), "(0,0;0,1000);(100,0;100,3000);(1100,-1000;1100,2000);(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1500,1000;1500,2100);(1600,-800;1600,-400);(1600,-400;1600,-200);(1700,1500;1600,2500);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (e.selected_not_outside (db::Region ()), ""), true); + EXPECT_EQ (db::compare (e.selected_outside_differential (db::Region ()).first, "(0,0;0,1000);(100,0;100,3000);(1100,-1000;1100,2000);(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1500,1000;1500,2100);(1600,-800;1600,-400);(1600,-400;1600,-200);(1700,1500;1600,2500);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (e.selected_outside_differential (db::Region ()).second, ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_outside (r), ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_not_outside (r), ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_outside_differential (r).first, ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_outside_differential (r).second, ""), true); + EXPECT_EQ (db::compare (e.selected_outside (r), "(0,0;0,1000);(100,0;100,3000);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (e.selected_not_outside (r), "(1100,-1000;1100,2000);(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1500,1000;1500,2100);(1600,-800;1600,-200);(1700,1500;1600,2500)"), true); + EXPECT_EQ (db::compare (e.selected_outside_differential (r).first, "(0,0;0,1000);(100,0;100,3000);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (e.selected_outside_differential (r).second, "(1100,-1000;1100,2000);(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1500,1000;1500,2100);(1600,-800;1600,-200);(1700,1500;1600,2500)"), true); +} + +// Edges::selected_outside(edges) +TEST(27) +{ + db::Edges e; + e.insert (db::Edge (0, 0, 0, 1000)); + e.insert (db::Edge (100, 0, 100, 3000)); + e.insert (db::Edge (1100, -1000, 1100, 2000)); + e.insert (db::Edge (1200, -1000, 1200, 0)); + e.insert (db::Edge (1300, -800, 1300, -200)); + e.insert (db::Edge (1400, 1000, 1400, 1100)); + e.insert (db::Edge (1500, 1000, 1500, 2100)); + e.insert (db::Edge (1600, -800, 1600, -400)); + e.insert (db::Edge (1600, -400, 1600, -200)); + e.insert (db::Edge (1700, 1500, 1600, 2500)); + e.insert (db::Edge (1800, 2500, 1800, 3500)); + e.insert (db::Edge (-1500, 0, -1500, 1000)); + + db::Edges ee; + for (int i = 0; i <= 2000; i += 100) { + ee.insert (db::Edge (i, -1000, i, 0)); + } + for (int i = 1000; i <= 2000; i += 100) { + ee.insert (db::Edge (i, 1000, i, 2000)); + } + + EXPECT_EQ (db::compare (e.selected_outside (db::Edges ()), "(0,0;0,1000);(100,0;100,3000);(1100,-1000;1100,2000);(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1500,1000;1500,2100);(1600,-800;1600,-400);(1600,-400;1600,-200);(1700,1500;1600,2500);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (e.selected_not_outside (db::Edges ()), ""), true); + EXPECT_EQ (db::compare (e.selected_outside_differential (db::Edges ()).first, "(0,0;0,1000);(100,0;100,3000);(1100,-1000;1100,2000);(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1500,1000;1500,2100);(1600,-800;1600,-400);(1600,-400;1600,-200);(1700,1500;1600,2500);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (e.selected_outside_differential (db::Edges ()).second, ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_outside (ee), ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_not_outside (ee), ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_outside_differential (ee).first, ""), true); + EXPECT_EQ (db::compare (db::Edges ().selected_outside_differential (ee).second, ""), true); + EXPECT_EQ (db::compare (e.selected_outside (ee), "(0,0;0,1000);(100,0;100,3000);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (e.selected_not_outside (ee), "(1100,-1000;1100,2000);(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1500,1000;1500,2100);(1600,-800;1600,-200);(1700,1500;1600,2500)"), true); + EXPECT_EQ (db::compare (e.selected_outside_differential (ee).first, "(0,0;0,1000);(100,0;100,3000);(1800,2500;1800,3500);(-1500,0;-1500,1000)"), true); + EXPECT_EQ (db::compare (e.selected_outside_differential (ee).second, "(1100,-1000;1100,2000);(1200,-1000;1200,0);(1300,-800;1300,-200);(1400,1000;1400,1100);(1500,1000;1500,2100);(1600,-800;1600,-200);(1700,1500;1600,2500)"), true); +} + // GitHub issue #72 (Edges/Region NOT issue) TEST(100) {