diff --git a/src/db/db/dbTriangle.cc b/src/db/db/dbTriangle.cc index 9f4f49fa3..284b4b6cf 100644 --- a/src/db/db/dbTriangle.cc +++ b/src/db/db/dbTriangle.cc @@ -102,6 +102,21 @@ Vertex::has_edge (const TriangleEdge *edge) const return false; } +size_t +Vertex::num_edges (int max_count) const +{ + if (max_count < 0) { + // NOTE: this can be slow for a std::list, so we have max_count to limit this effort + return mp_edges.size (); + } else { + size_t n = 0; + for (auto i = mp_edges.begin (); i != mp_edges.end () && --max_count >= 0; ++i) { + ++n; + } + return n; + } +} + std::string Vertex::to_string (bool with_id) const { @@ -112,18 +127,6 @@ Vertex::to_string (bool with_id) const return res; } -void -Vertex::remove_edge (db::TriangleEdge *edge) -{ - for (auto e = mp_edges.begin (); e != mp_edges.end (); ++e) { - if (*e == edge) { - mp_edges.erase (e); - return; - } - } - tl_assert (false); -} - int Vertex::in_circle (const DPoint &point, const DPoint ¢er, double radius) { @@ -172,17 +175,20 @@ void TriangleEdge::link () { mp_v1->mp_edges.push_back (this); + m_ec_v1 = --mp_v1->mp_edges.end (); + mp_v2->mp_edges.push_back (this); + m_ec_v2 = --mp_v2->mp_edges.end (); } void TriangleEdge::unlink () { if (mp_v1) { - mp_v1->remove_edge (this); + mp_v1->remove_edge (m_ec_v1); } if (mp_v2) { - mp_v2->remove_edge (this); + mp_v2->remove_edge (m_ec_v2); } mp_v1 = mp_v2 = 0; } diff --git a/src/db/db/dbTriangle.h b/src/db/db/dbTriangle.h index 4d5bc4931..d2966509d 100644 --- a/src/db/db/dbTriangle.h +++ b/src/db/db/dbTriangle.h @@ -48,8 +48,9 @@ class DB_PUBLIC Vertex : public db::DPoint { public: - typedef std::vector edges_type; + typedef std::list edges_type; typedef edges_type::const_iterator edges_iterator; + typedef edges_type::iterator edges_iterator_non_const; Vertex (); Vertex (const DPoint &p); @@ -63,7 +64,7 @@ public: edges_iterator begin_edges () const { return mp_edges.begin (); } edges_iterator end_edges () const { return mp_edges.end (); } - size_t num_edges () const { return mp_edges.size (); } + size_t num_edges (int max_count = -1) const; bool has_edge (const TriangleEdge *edge) const; @@ -88,7 +89,11 @@ public: private: friend class TriangleEdge; - void remove_edge (db::TriangleEdge *edge); + + void remove_edge (const edges_iterator_non_const &ec) + { + mp_edges.erase (ec); + } edges_type mp_edges; size_t m_level; @@ -397,6 +402,7 @@ private: Vertex *mp_v1, *mp_v2; Triangle *mp_left, *mp_right; + Vertex::edges_iterator_non_const m_ec_v1, m_ec_v2; size_t m_level; size_t m_id; bool m_is_segment; diff --git a/src/db/db/dbTriangles.cc b/src/db/db/dbTriangles.cc index 6a6c9c373..11f713abf 100644 --- a/src/db/db/dbTriangles.cc +++ b/src/db/db/dbTriangles.cc @@ -724,7 +724,7 @@ Triangles::remove_inside_vertex (db::Vertex *vertex, std::listnum_edges () > 3) { + while (vertex->num_edges (4) > 3) { db::TriangleEdge *to_flip = 0; for (auto e = vertex->begin_edges (); e != vertex->end_edges () && to_flip == 0; ++e) { @@ -746,9 +746,9 @@ Triangles::remove_inside_vertex (db::Vertex *vertex, std::listnum_edges () > 3) { + if (vertex->num_edges (4) > 3) { - tl_assert (vertex->num_edges () == 4); + tl_assert (vertex->num_edges (5) == 4); // This case can happen if two edges attached to the vertex are collinear // in this case choose the "join" strategy