diff --git a/src/db/db/dbTriangle.cc b/src/db/db/dbTriangle.cc index 867187295..e9289a324 100644 --- a/src/db/db/dbTriangle.cc +++ b/src/db/db/dbTriangle.cc @@ -32,19 +32,19 @@ namespace db // Vertex implementation Vertex::Vertex () - : DPoint (), m_level (0) + : DPoint (), m_is_precious (false) { // .. nothing yet .. } Vertex::Vertex (const db::DPoint &p) - : DPoint (p), m_level (0) + : DPoint (p), m_is_precious (false) { // .. nothing yet .. } Vertex::Vertex (const Vertex &v) - : DPoint (), m_level (0) + : DPoint (), m_is_precious (false) { operator= (v); } @@ -54,13 +54,13 @@ Vertex &Vertex::operator= (const Vertex &v) if (this != &v) { // NOTE: edges are not copied! db::DPoint::operator= (v); - m_level = v.m_level; + m_is_precious = v.m_is_precious; } return *this; } Vertex::Vertex (db::DCoord x, db::DCoord y) - : DPoint (x, y), m_level (0) + : DPoint (x, y), m_is_precious (false) { // .. nothing yet .. } diff --git a/src/db/db/dbTriangle.h b/src/db/db/dbTriangle.h index 29ff09abb..332d1c695 100644 --- a/src/db/db/dbTriangle.h +++ b/src/db/db/dbTriangle.h @@ -74,8 +74,8 @@ public: bool has_edge (const TriangleEdge *edge) const; - size_t level () const { return m_level; } - void set_level (size_t l) { m_level = l; } + void set_is_precious (bool f) { m_is_precious = f; } + bool is_precious () const { return m_is_precious; } std::string to_string (bool with_id = false) const; @@ -102,7 +102,7 @@ private: } edges_type mp_edges; - size_t m_level; + bool m_is_precious; }; /** diff --git a/src/db/db/dbTriangles.cc b/src/db/db/dbTriangles.cc index 23710b681..e712abaa2 100644 --- a/src/db/db/dbTriangles.cc +++ b/src/db/db/dbTriangles.cc @@ -1484,7 +1484,7 @@ Triangles::create_constrained_delaunay (const db::Polygon &p, const std::vector< clear (); for (auto v = vertexes.begin (); v != vertexes.end (); ++v) { - insert_point (trans * *v); + insert_point (trans * *v)->set_is_precious (true); } std::vector > edge_contours; @@ -1499,7 +1499,7 @@ Triangles::create_constrained_delaunay (const db::DPolygon &p, const std::vector clear (); for (auto v = vertexes.begin (); v != vertexes.end (); ++v) { - insert_point (trans * *v); + insert_point (trans * *v)->set_is_precious (true); } std::vector > edge_contours; @@ -1724,7 +1724,7 @@ Triangles::refine (const TriangulateParameters ¶meters) for (auto e = (*v)->begin_edges (); e != (*v)->end_edges () && ! has_segment; ++e) { has_segment = (*e)->is_segment (); } - if (! has_segment) { + if (! has_segment && ! (*v)->is_precious ()) { to_delete.push_back (*v); } } diff --git a/src/db/unit_tests/dbTriangleTests.cc b/src/db/unit_tests/dbTriangleTests.cc index 439eb1c65..4d0eb9e78 100644 --- a/src/db/unit_tests/dbTriangleTests.cc +++ b/src/db/unit_tests/dbTriangleTests.cc @@ -54,9 +54,6 @@ TEST(Vertex_basic) v = db::Vertex (db::DPoint (2, 3)); EXPECT_EQ (v.to_string (), "(2, 3)"); - - v.set_level (42); - EXPECT_EQ (v.level (), size_t (42)); } static std::string edges_from_vertex (const db::Vertex &v) diff --git a/src/db/unit_tests/dbTrianglesTests.cc b/src/db/unit_tests/dbTrianglesTests.cc index c3855ce29..df7c5e357 100644 --- a/src/db/unit_tests/dbTrianglesTests.cc +++ b/src/db/unit_tests/dbTrianglesTests.cc @@ -1000,3 +1000,79 @@ TEST(triangulate_issue1996) EXPECT_GT (tri.num_triangles (), size_t (128000)); EXPECT_LT (tri.num_triangles (), size_t (132000)); } + +TEST(triangulate_with_vertexes) +{ + db::Point contour[] = { + db::Point (0, 0), + db::Point (0, 100), + db::Point (1000, 100), + db::Point (1000, 0) + }; + + db::Polygon poly; + poly.assign_hull (contour + 0, contour + sizeof (contour) / sizeof (contour[0])); + + double dbu = 0.001; + + db::Triangles::TriangulateParameters param; + param.min_b = 0.0; + param.max_area = 0.0; + + std::vector vertexes; + + TestableTriangles tri; + db::CplxTrans trans = db::DCplxTrans (dbu) * db::CplxTrans (db::Trans (db::Point () - poly.box ().center ())); + tri.triangulate (poly, param, trans); + + EXPECT_EQ (tri.to_string (), "((-0.5, -0.05), (-0.5, 0.05), (0.5, 0.05)), ((0.5, -0.05), (-0.5, -0.05), (0.5, 0.05))"); + + vertexes.clear (); + + // outside vertexes are ignored, but lead to a different triangulation + vertexes.push_back (db::Point (50, 150)); + tri.triangulate (poly, vertexes, param, trans); + + EXPECT_EQ (tri.to_string (), "((-0.5, -0.05), (-0.133333333333, 0.05), (0.5, -0.05)), ((0.5, 0.05), (0.5, -0.05), (-0.133333333333, 0.05)), ((-0.133333333333, 0.05), (-0.5, -0.05), (-0.5, 0.05))"); + + for (auto v = vertexes.begin (); v != vertexes.end (); ++v) { + auto *vp = tri.find_vertex_for_point (trans * *v); + EXPECT_EQ (vp, 0); + } + + vertexes.clear (); + vertexes.push_back (db::Point (50, 50)); + tri.triangulate (poly, vertexes, param, trans); + + EXPECT_EQ (tri.to_string (), "((-0.45, 0), (-0.5, -0.05), (-0.5, 0.05)), ((0.5, 0.05), (-0.45, 0), (-0.5, 0.05)), ((-0.45, 0), (0.5, -0.05), (-0.5, -0.05)), ((-0.45, 0), (0.5, 0.05), (0.5, -0.05))"); + + for (auto v = vertexes.begin (); v != vertexes.end (); ++v) { + auto *vp = tri.find_vertex_for_point (trans * *v); + if (! vp) { + tl::warn << "Vertex not present in output: " << v->to_string (); + EXPECT_EQ (1, 0); + } + } + + // aggressive triangulation + param.min_b = 1.0; + param.max_area = 20 * 20 * dbu * dbu; + + tri.triangulate (poly, vertexes, param, trans); + + EXPECT_GT (tri.num_triangles (), size_t (380)); + EXPECT_LT (tri.num_triangles (), size_t (400)); + + for (auto t = tri.begin (); t != tri.end (); ++t) { + EXPECT_LE (t->area (), param.max_area); + EXPECT_GE (t->b (), param.min_b); + } + + for (auto v = vertexes.begin (); v != vertexes.end (); ++v) { + auto *vp = tri.find_vertex_for_point (trans * *v); + if (! vp) { + tl::warn << "Vertex not present in output: " << v->to_string (); + EXPECT_EQ (1, 0); + } + } +}