diff --git a/src/db/db/dbEdges.cc b/src/db/db/dbEdges.cc index 3890d4fbd..00f7b7542 100644 --- a/src/db/db/dbEdges.cc +++ b/src/db/db/dbEdges.cc @@ -883,20 +883,31 @@ struct JoinEdgesCluster void finish () { std::multimap objects_by_p1; - std::multiset p2; + std::multimap objects_by_p2; for (iterator o = begin (); o != end (); ++o) { if (o->first->p1 () != o->first->p2 ()) { objects_by_p1.insert (std::make_pair (o->first->p1 (), o)); - p2.insert (o->first->p2 ()); + objects_by_p2.insert (std::make_pair (o->first->p2 (), o)); } } - while (! p2.empty ()) { + while (! objects_by_p2.empty ()) { tl_assert (! objects_by_p1.empty ()); // Find the beginning of a new sequence - std::multimap::iterator j = objects_by_p1.begin (); + std::multimap::iterator j0 = objects_by_p1.begin (); + std::multimap::iterator j = j0; + do { + std::multimap::iterator jj = objects_by_p2.find (j->first); + if (jj == objects_by_p2.end ()) { + break; + } else { + j = objects_by_p1.find (jj->second->first->p1 ()); + tl_assert (j != objects_by_p1.end ()); + } + } while (j != j0); + iterator i = j->second; // determine a sequence @@ -906,12 +917,22 @@ struct JoinEdgesCluster do { + // record the next point pts.push_back (i->first->p2 ()); - std::multiset::iterator ip2 = p2.find (i->first->p2 ()); - tl_assert (ip2 != p2.end ()); - p2.erase (ip2); + + // remove the edge as it's taken + std::multimap::iterator jj; + for (jj = objects_by_p2.find (i->first->p2 ()); jj != objects_by_p2.end () && jj->first == i->first->p2 (); ++jj) { + if (jj->second == i) { + break; + } + } + tl_assert (jj != objects_by_p2.end () && jj->second == i); + objects_by_p2.erase (jj); objects_by_p1.erase (j); + // process along the edge to the next one + // TODO: this chooses any solution in case of forks. Choose a specific one? j = objects_by_p1.find (i->first->p2 ()); if (j != objects_by_p1.end ()) { i = j->second; diff --git a/src/db/unit_tests/dbEdges.cc b/src/db/unit_tests/dbEdges.cc index cf6d78a15..6a5a3c7b1 100644 --- a/src/db/unit_tests/dbEdges.cc +++ b/src/db/unit_tests/dbEdges.cc @@ -311,7 +311,40 @@ TEST(6) EXPECT_EQ (r.to_string (), "(-20,-20;-20,220;120,220;120,-20/-10,-10;110,-10;110,210;-10,210)"); } -TEST(7) +TEST(6b) +{ + // Ticket #90: order of edges as input to the edge collector should not matter + + db::Edges e; + e.insert (db::Edge (db::Point (0, -200), db::Point (100, -200))); + e.insert (db::Edge (db::Point (250, -200), db::Point (300, 0))); + e.insert (db::Edge (db::Point (0, 0), db::Point (0, -200))); + e.insert (db::Edge (db::Point (200, 0), db::Point (250, -200))); + + db::Region r; + e.extended (r, 0, 0, 20, 0, true); + EXPECT_EQ (r.to_string (), "(0,-200;0,0;20,0;20,-180;100,-180;100,-200);(250,-200;200,0;219,5;250,-118;281,5;300,0)"); +} + +TEST(6c) +{ + // A more complex scenario with forks + + db::Edges e; + e.insert (db::Edge (db::Point (0, -200), db::Point (100, -200))); + e.insert (db::Edge (db::Point (250, -200), db::Point (300, 0))); + e.insert (db::Edge (db::Point (0, 0), db::Point (0, -200))); + e.insert (db::Edge (db::Point (0, -100), db::Point (0, -200))); + e.insert (db::Edge (db::Point (200, 0), db::Point (250, -200))); + e.insert (db::Edge (db::Point (0, -200), db::Point (200, -200))); + e.insert (db::Edge (db::Point (250, -200), db::Point (350, 0))); + + db::Region r; + e.extended (r, 0, 0, 20, 0, true); + EXPECT_EQ (r.to_string (), "(0,-200;0,0;20,0;20,-180;100,-180;100,-200);(0,-200;0,-100;20,-100;20,-180;200,-180;200,-200);(250,-200;200,0;219,5;250,-118;281,5;300,0);(250,-200;232,-191;332,9;350,0)"); +} + +TEST(7) { db::Edges e; e.insert (db::Edge (db::Point (0, 0), db::Point (0, 200)));