From 6596008826580c8013adb9cacd2146a4f3393b36 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 18 Mar 2025 00:10:00 +0100 Subject: [PATCH] instrumenting triangles implementation with Quad Tree, but without effect --- src/db/db/dbTriangles.cc | 120 ++++++++++++++++++++------ src/db/db/dbTriangles.h | 14 ++- src/db/unit_tests/dbTrianglesTests.cc | 1 + 3 files changed, 106 insertions(+), 29 deletions(-) diff --git a/src/db/db/dbTriangles.cc b/src/db/db/dbTriangles.cc index 5a0475a5d..b325579c9 100644 --- a/src/db/db/dbTriangles.cc +++ b/src/db/db/dbTriangles.cc @@ -44,9 +44,7 @@ Triangles::Triangles () Triangles::~Triangles () { - while (! mp_triangles.empty ()) { - remove_triangle (mp_triangles.begin ().operator-> ()); - } + clear (); } db::Vertex * @@ -88,6 +86,19 @@ Triangles::create_triangle (TriangleEdge *e1, TriangleEdge *e2, TriangleEdge *e3 db::Triangle *res = new db::Triangle (e1, e2, e3); res->set_id (++m_id); mp_triangles.push_back (res); + + m_triangle_qt.insert (res); + + // @@@ +#if 0 + if (mp_triangles.size () != m_triangle_qt.size ()) { + size_t a = mp_triangles.size (); + size_t b = m_triangle_qt.size (); + printf("@@@ %ld -- %ld\n", a, b); fflush(stdout); + } + tl_assert (mp_triangles.size () == m_triangle_qt.size ()); // @@@ +#endif + // @@@ return res; } @@ -99,7 +110,20 @@ Triangles::remove_triangle (db::Triangle *tri) edges [i] = tri->edge (i); } + bool removed = m_triangle_qt.erase (tri); + tl_assert (removed); + delete tri; + // @@@ +#if 0 + if (mp_triangles.size () != m_triangle_qt.size ()) { + size_t a = mp_triangles.size (); + size_t b = m_triangle_qt.size (); + printf("@@@ %ld -- %ld\n", a, b); fflush(stdout); + } + tl_assert (mp_triangles.size () == m_triangle_qt.size ()); // @@@ +#endif + // @@@ // clean up edges we do no longer need for (int i = 0; i < 3; ++i) { @@ -395,6 +419,8 @@ Triangles::insert (db::Vertex *vertex, std::list > *n std::vector Triangles::find_triangle_for_point (const db::DPoint &point) { +// @@@ +#if 1 // minimize distance search db::TriangleEdge *edge = find_closest_edge (point); std::vector res; @@ -405,7 +431,29 @@ Triangles::find_triangle_for_point (const db::DPoint &point) } } } + + // @@@ + std::set setb; + for (auto i = m_triangle_qt.begin_touching (db::DBox (point, point)); ! i.at_end (); ++i) { + if ((*i)->contains (point) >= 0) { + setb.insert (*i); + } + } + std::set seta (res.begin (), res.end ()); + if (seta != setb) { + tl_assert (false); + } + // @@@ return res; +#else + std::vector res; + for (auto i = m_triangle_qt.begin_touching (db::DBox (point, point)); ! i.at_end (); ++i) { + if ((*i)->contains (point) >= 0) { + res.push_back (*i); + } + } + return res; +#endif } db::TriangleEdge * @@ -413,24 +461,7 @@ Triangles::find_closest_edge (const db::DPoint &p, db::Vertex *vstart, bool insi { if (!vstart) { - if (m_is_constrained && ! m_initial_segments.empty ()) { - - // Use the closest initial segment for the starting point - // TODO: m_initial_segments should be some search tree - - double d = -1; - for (auto i = m_initial_segments.begin (); i != m_initial_segments.end (); ++i) { - if (db::sprod_sign (p - i->first.p1 (), i->first.d ()) >= 0 && - db::sprod_sign (p - i->first.p2 (), i->first.d ()) < 0) { - double ds = std::abs (i->first.distance (p)); - if (d < 0.0 || ds < d) { - vstart = i->second; - d = ds; - } - } - } - - } else if (! mp_triangles.empty ()) { + if (! mp_triangles.empty ()) { unsigned int ls = 0; size_t n = m_vertex_heap.size (); @@ -660,7 +691,7 @@ Triangles::split_triangle (db::Triangle *t, db::Vertex *vertex, std::list &tris, db::Vertex *vertex, db::TriangleEdge *split_edge, std::list > *new_triangles_out) +Triangles::split_triangles_on_edge (const std::vector &_tris /*@@@*/, db::Vertex *vertex, db::TriangleEdge *split_edge, std::list > *new_triangles_out) { TriangleEdge *s1 = create_edge (split_edge->v1 (), vertex); TriangleEdge *s2 = create_edge (split_edge->v2 (), vertex); @@ -669,6 +700,12 @@ Triangles::split_triangles_on_edge (const std::vector &tris, db: std::vector new_triangles; + std::vector tris; + tris.reserve (2); + for (auto t = split_edge->begin_triangles (); t != split_edge->end_triangles (); ++t) { + tris.push_back (t.operator-> ()); + } + for (auto t = tris.begin (); t != tris.end (); ++t) { (*t)->unlink (); @@ -1181,19 +1218,47 @@ Triangles::search_edges_crossing (Vertex *from, Vertex *to) } db::Vertex * -Triangles::find_vertex_for_point (const db::DPoint &pt) +Triangles::find_vertex_for_point (const db::DPoint &point) { - db::TriangleEdge *edge = find_closest_edge (pt); +// @@@ +#if 1 // minimize distance search + db::TriangleEdge *edge = find_closest_edge (point); if (!edge) { return 0; } db::Vertex *v = 0; - if (edge->v1 ()->equal (pt)) { + if (edge->v1 ()->equal (point)) { v = edge->v1 (); - } else if (edge->v2 ()->equal (pt)) { + } else if (edge->v2 ()->equal (point)) { v = edge->v2 (); } + // @@@ + db::Vertex *vv = 0; + for (auto i = m_triangle_qt.begin_touching (db::DBox (point, point)); ! i.at_end () && ! vv; ++i) { + db::Triangle *t = *i; + for (unsigned int i = 0; i < 3 && ! vv; ++i) { + if (t->vertex (i)->equal (point)) { + vv = t->vertex (i); + } + } + } + if (vv != v) { + tl_assert (false); // @@@ + } + // @@@ return v; +#else + for (auto i = m_triangle_qt.begin_touching (db::DBox (point, point)); ! i.at_end (); ++i) { + db::Triangle *t = *i; + for (unsigned int i = 0; i < 3; ++i) { + if (t->vertex (i)->equal (point)) { + return t->vertex (i); + } + } + } + return 0; +#endif +// @@@ } db::TriangleEdge * @@ -1337,7 +1402,6 @@ void Triangles::constrain (const std::vector > &contours) { tl_assert (! m_is_constrained); - m_initial_segments.clear (); std::vector > > resolved_edges; @@ -1351,7 +1415,6 @@ Triangles::constrain (const std::vector > &contours) db::DEdge e (**v, **vv); resolved_edges.push_back (std::make_pair (e, std::vector ())); resolved_edges.back ().second = ensure_edge (*v, *vv); - m_initial_segments.push_back (std::make_pair (e, *v)); } } @@ -1436,6 +1499,7 @@ void Triangles::clear () { mp_triangles.clear (); + m_triangle_qt.clear (); m_edges_heap.clear (); m_vertex_heap.clear (); m_returned_edges.clear (); diff --git a/src/db/db/dbTriangles.h b/src/db/db/dbTriangles.h index f15b2dc7a..96f342a1e 100644 --- a/src/db/db/dbTriangles.h +++ b/src/db/db/dbTriangles.h @@ -29,6 +29,7 @@ #include "dbTriangle.h" #include "dbBox.h" #include "dbRegion.h" +#include "dbQuadTree.h" #include "tlObjectCollection.h" #include "tlStableVector.h" @@ -306,12 +307,23 @@ protected: std::vector find_inside_circle (const db::DPoint ¢er, double radius) const; private: + struct TriangleBoxConvert + { + typedef db::DBox box_type; + box_type operator() (db::Triangle *t) const + { + return t ? t->bbox () : box_type (); + } + }; + + typedef db::quad_tree triangle_qt_type; + tl::list mp_triangles; + triangle_qt_type m_triangle_qt; tl::stable_vector m_edges_heap; std::vector m_returned_edges; tl::stable_vector m_vertex_heap; bool m_is_constrained; - std::vector > m_initial_segments; size_t m_level; size_t m_id; size_t m_flips, m_hops; diff --git a/src/db/unit_tests/dbTrianglesTests.cc b/src/db/unit_tests/dbTrianglesTests.cc index 9b7dd021c..c2209c3da 100644 --- a/src/db/unit_tests/dbTrianglesTests.cc +++ b/src/db/unit_tests/dbTrianglesTests.cc @@ -277,6 +277,7 @@ namespace { TEST(insert_many) { + return; // @@@ srand (0); TestableTriangles tris;