From fb84f3113af146b8fe64bea2b5ab695682d81671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Wed, 31 Jan 2024 17:40:57 +0100 Subject: [PATCH] Introduce wrapper class around boost::polygon::voronoi_diagram. --- .../Arachne/SkeletalTrapezoidation.cpp | 54 +++++------ .../Arachne/SkeletalTrapezoidation.hpp | 23 +++-- .../Arachne/utils/PolygonsPointIndex.hpp | 2 - src/libslic3r/Geometry/MedialAxis.cpp | 2 +- src/libslic3r/Geometry/Voronoi.hpp | 89 ++++++++++++++++--- src/libslic3r/Geometry/VoronoiUtilsCgal.cpp | 8 +- src/libslic3r/MultiMaterialSegmentation.cpp | 6 +- tests/libslic3r/test_voronoi.cpp | 38 ++++---- 8 files changed, 142 insertions(+), 80 deletions(-) diff --git a/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp b/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp index 2be3ef1949..644c7f2269 100644 --- a/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp +++ b/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp @@ -89,7 +89,7 @@ static void export_graph_to_svg(const std::string } #endif -SkeletalTrapezoidation::node_t& SkeletalTrapezoidation::makeNode(vd_t::vertex_type& vd_node, Point p) +SkeletalTrapezoidation::node_t& SkeletalTrapezoidation::makeNode(VD::vertex_type& vd_node, Point p) { auto he_node_it = vd_node_to_he_node.find(&vd_node); if (he_node_it == vd_node_to_he_node.end()) @@ -105,7 +105,7 @@ SkeletalTrapezoidation::node_t& SkeletalTrapezoidation::makeNode(vd_t::vertex_ty } } -void SkeletalTrapezoidation::transferEdge(Point from, Point to, vd_t::edge_type& vd_edge, edge_t*& prev_edge, Point& start_source_point, Point& end_source_point, const std::vector& segments) +void SkeletalTrapezoidation::transferEdge(Point from, Point to, VD::edge_type& vd_edge, edge_t*& prev_edge, Point& start_source_point, Point& end_source_point, const std::vector& segments) { auto he_edge_it = vd_edge_to_he_edge.find(vd_edge.twin()); if (he_edge_it != vd_edge_to_he_edge.end()) @@ -216,14 +216,14 @@ void SkeletalTrapezoidation::transferEdge(Point from, Point to, vd_t::edge_type& } } -Points SkeletalTrapezoidation::discretize(const vd_t::edge_type& vd_edge, const std::vector& segments) +Points SkeletalTrapezoidation::discretize(const VD::edge_type& vd_edge, const std::vector& segments) { /*Terminology in this function assumes that the edge moves horizontally from left to right. This is not necessarily the case; the edge can go in any direction, but it helps to picture it in a certain direction in your head.*/ - const vd_t::cell_type* left_cell = vd_edge.cell(); - const vd_t::cell_type* right_cell = vd_edge.twin()->cell(); + const VD::cell_type* left_cell = vd_edge.cell(); + const VD::cell_type* right_cell = vd_edge.twin()->cell(); assert(VoronoiUtils::p(vd_edge.vertex0()).x() <= std::numeric_limits::max() && VoronoiUtils::p(vd_edge.vertex0()).x() >= std::numeric_limits::lowest()); assert(VoronoiUtils::p(vd_edge.vertex0()).y() <= std::numeric_limits::max() && VoronoiUtils::p(vd_edge.vertex0()).y() >= std::numeric_limits::lowest()); @@ -331,7 +331,7 @@ Points SkeletalTrapezoidation::discretize(const vd_t::edge_type& vd_edge, const } } -bool SkeletalTrapezoidation::computePointCellRange(vd_t::cell_type& cell, Point& start_source_point, Point& end_source_point, vd_t::edge_type*& starting_vd_edge, vd_t::edge_type*& ending_vd_edge, const std::vector& segments) +bool SkeletalTrapezoidation::computePointCellRange(VD::cell_type& cell, Point& start_source_point, Point& end_source_point, VD::edge_type*& starting_vd_edge, VD::edge_type*& ending_vd_edge, const std::vector& segments) { if (cell.incident_edge()->is_infinite()) return false; //Infinite edges only occur outside of the polygon. Don't copy any part of this cell. @@ -340,7 +340,7 @@ bool SkeletalTrapezoidation::computePointCellRange(vd_t::cell_type& cell, Point& // Copy whole cell into graph or not at all // If the cell.incident_edge()->vertex0() is far away so much that it doesn't even fit into Vec2i64, then there is no way that it will be inside the input polygon. - if (const vd_t::vertex_type &vert = *cell.incident_edge()->vertex0(); + if (const VD::vertex_type &vert = *cell.incident_edge()->vertex0(); vert.x() >= double(std::numeric_limits::max()) || vert.x() <= double(std::numeric_limits::lowest()) || vert.y() >= double(std::numeric_limits::max()) || vert.y() <= double(std::numeric_limits::lowest())) return false; // Don't copy any part of this cell @@ -358,7 +358,7 @@ bool SkeletalTrapezoidation::computePointCellRange(vd_t::cell_type& cell, Point& if (!LinearAlg2D::isInsideCorner(source_point_index.prev().p(), source_point_index.p(), source_point_index.next().p(), some_point)) return false; // Don't copy any part of this cell - vd_t::edge_type* vd_edge = cell.incident_edge(); + VD::edge_type* vd_edge = cell.incident_edge(); do { assert(vd_edge->is_finite()); if (Vec2i64 p1 = VoronoiUtils::p(vd_edge->vertex1()); p1 == source_point.cast()) { @@ -376,7 +376,7 @@ bool SkeletalTrapezoidation::computePointCellRange(vd_t::cell_type& cell, Point& return true; } -void SkeletalTrapezoidation::computeSegmentCellRange(vd_t::cell_type& cell, Point& start_source_point, Point& end_source_point, vd_t::edge_type*& starting_vd_edge, vd_t::edge_type*& ending_vd_edge, const std::vector& segments) +void SkeletalTrapezoidation::computeSegmentCellRange(VD::cell_type& cell, Point& start_source_point, Point& end_source_point, VD::edge_type*& starting_vd_edge, VD::edge_type*& ending_vd_edge, const std::vector& segments) { const Segment &source_segment = VoronoiUtils::getSourceSegment(cell, segments); const Point from = source_segment.from(); @@ -387,7 +387,7 @@ void SkeletalTrapezoidation::computeSegmentCellRange(vd_t::cell_type& cell, Poin bool seen_possible_start = false; bool after_start = false; bool ending_edge_is_set_before_start = false; - vd_t::edge_type* edge = cell.incident_edge(); + VD::edge_type* edge = cell.incident_edge(); do { if (edge->is_infinite()) continue; @@ -431,7 +431,7 @@ SkeletalTrapezoidation::SkeletalTrapezoidation(const Polygons& polys, const Bead constructFromPolygons(polys); } -static bool has_finite_edge_with_non_finite_vertex(const Geometry::VoronoiDiagram &voronoi_diagram) +static bool has_finite_edge_with_non_finite_vertex(const VD &voronoi_diagram) { for (const VoronoiUtils::vd_t::edge_type &edge : voronoi_diagram.edges()) { if (edge.is_finite()) { @@ -444,11 +444,11 @@ static bool has_finite_edge_with_non_finite_vertex(const Geometry::VoronoiDiagra return false; } -static bool detect_missing_voronoi_vertex(const Geometry::VoronoiDiagram &voronoi_diagram, const std::vector &segments) { +static bool detect_missing_voronoi_vertex(const VD &voronoi_diagram, const std::vector &segments) { if (has_finite_edge_with_non_finite_vertex(voronoi_diagram)) return true; - for (VoronoiUtils::vd_t::cell_type cell : voronoi_diagram.cells()) { + for (VD::cell_type cell : voronoi_diagram.cells()) { if (!cell.incident_edge()) continue; // There is no spoon @@ -517,9 +517,9 @@ inline static void rotate_back_skeletal_trapezoidation_graph_after_fix(SkeletalT } } -bool detect_voronoi_edge_intersecting_input_segment(const Geometry::VoronoiDiagram &voronoi_diagram, const std::vector &segments) +bool detect_voronoi_edge_intersecting_input_segment(const VD &voronoi_diagram, const std::vector &segments) { - for (VoronoiUtils::vd_t::cell_type cell : voronoi_diagram.cells()) { + for (VD::cell_type cell : voronoi_diagram.cells()) { if (!cell.incident_edge()) continue; // Degenerated cell, there is no spoon @@ -530,14 +530,14 @@ bool detect_voronoi_edge_intersecting_input_segment(const Geometry::VoronoiDiagr const Vec2d source_segment_from = source_segment.from().cast(); const Vec2d source_segment_vec = source_segment.to().cast() - source_segment_from; - Point start_source_point, end_source_point; - VoronoiUtils::vd_t::edge_type *begin_voronoi_edge = nullptr, *end_voronoi_edge = nullptr; + Point start_source_point, end_source_point; + VD::edge_type *begin_voronoi_edge = nullptr, *end_voronoi_edge = nullptr; SkeletalTrapezoidation::computeSegmentCellRange(cell, start_source_point, end_source_point, begin_voronoi_edge, end_voronoi_edge, segments); // All Voronoi vertices must be on left side of the source segment, otherwise Voronoi diagram is invalid. // FIXME Lukas H.: Be aware that begin_voronoi_edge and end_voronoi_edge could be nullptr in some specific cases. // It mostly happens when there is some missing Voronoi, for example, in GH issue #8846 (IssuesWithMysteriousPerimeters.3mf). if (begin_voronoi_edge != nullptr && end_voronoi_edge != nullptr) - for (VoronoiUtils::vd_t::edge_type *edge = begin_voronoi_edge; edge != end_voronoi_edge; edge = edge->next()) + for (VD::edge_type *edge = begin_voronoi_edge; edge != end_voronoi_edge; edge = edge->next()) if (const Vec2d edge_v1(edge->vertex1()->x(), edge->vertex1()->y()); Slic3r::cross2(source_segment_vec, edge_v1 - source_segment_from) < 0) return true; } @@ -555,7 +555,7 @@ enum class VoronoiDiagramStatus { // Try to detect cases when some Voronoi vertex is missing, when the Voronoi diagram // is not planar or some Voronoi edge is intersecting input segment. -VoronoiDiagramStatus detect_voronoi_diagram_known_issues(const Geometry::VoronoiDiagram &voronoi_diagram, +VoronoiDiagramStatus detect_voronoi_diagram_known_issues(const VD &voronoi_diagram, const std::vector &segments) { if (const bool has_missing_voronoi_vertex = detect_missing_voronoi_vertex(voronoi_diagram, segments); has_missing_voronoi_vertex) { @@ -571,7 +571,7 @@ VoronoiDiagramStatus detect_voronoi_diagram_known_issues(const Geometry::Voronoi } inline static std::pair try_to_fix_degenerated_voronoi_diagram_by_rotation( - Geometry::VoronoiDiagram &voronoi_diagram, + VD &voronoi_diagram, const Polygons &polys, Polygons &polys_rotated, std::vector &segments, @@ -602,7 +602,7 @@ inline static std::pair try_to_fix_degenerated_voronoi_diagram segments.emplace_back(&polys_rotated, poly_idx, point_idx); voronoi_diagram.clear(); - construct_voronoi(segments.begin(), segments.end(), &voronoi_diagram); + voronoi_diagram.construct_voronoi(segments.cbegin(), segments.cend()); #ifdef ARACHNE_DEBUG_VORONOI { @@ -651,8 +651,8 @@ void SkeletalTrapezoidation::constructFromPolygons(const Polygons& polys) } #endif - Geometry::VoronoiDiagram voronoi_diagram; - construct_voronoi(segments.begin(), segments.end(), &voronoi_diagram); + VD voronoi_diagram; + voronoi_diagram.construct_voronoi(segments.begin(), segments.end()); #ifdef ARACHNE_DEBUG_VORONOI { @@ -692,14 +692,14 @@ void SkeletalTrapezoidation::constructFromPolygons(const Polygons& polys) process_voronoi_diagram: assert(this->graph.edges.empty() && this->graph.nodes.empty() && this->vd_edge_to_he_edge.empty() && this->vd_node_to_he_node.empty()); - for (vd_t::cell_type cell : voronoi_diagram.cells()) { + for (VD::cell_type cell : voronoi_diagram.cells()) { if (!cell.incident_edge()) continue; // There is no spoon Point start_source_point; Point end_source_point; - vd_t::edge_type* starting_voronoi_edge = nullptr; - vd_t::edge_type* ending_voronoi_edge = nullptr; + VD::edge_type* starting_voronoi_edge = nullptr; + VD::edge_type* ending_voronoi_edge = nullptr; // Compute and store result in above variables if (cell.contains_point()) { @@ -726,7 +726,7 @@ process_voronoi_diagram: constexpr bool is_next_to_start_or_end = true; graph.makeRib(prev_edge, start_source_point, end_source_point, is_next_to_start_or_end); - for (vd_t::edge_type* vd_edge = starting_voronoi_edge->next(); vd_edge != ending_voronoi_edge; vd_edge = vd_edge->next()) { + for (VD::edge_type* vd_edge = starting_voronoi_edge->next(); vd_edge != ending_voronoi_edge; vd_edge = vd_edge->next()) { assert(vd_edge->is_finite()); assert(VoronoiUtils::p(vd_edge->vertex0()).x() <= std::numeric_limits::max() && VoronoiUtils::p(vd_edge->vertex0()).x() >= std::numeric_limits::lowest()); diff --git a/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp b/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp index e2a013b154..dfb40ceb11 100644 --- a/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp +++ b/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp @@ -26,8 +26,9 @@ //#define ARACHNE_DEBUG //#define ARACHNE_DEBUG_VORONOI -namespace Slic3r::Arachne -{ +namespace Slic3r::Arachne { + +using VD = Slic3r::Geometry::VoronoiDiagram; /*! * Main class of the dynamic beading strategies. @@ -50,8 +51,6 @@ deposition modeling" by Kuipers et al. */ class SkeletalTrapezoidation { - using pos_t = double; - using vd_t = boost::polygon::voronoi_diagram; using graph_t = SkeletalTrapezoidationGraph; using edge_t = STHalfEdge; using node_t = STHalfEdgeNode; @@ -168,9 +167,9 @@ protected: * mapping each voronoi VD edge to the corresponding halfedge HE edge * In case the result segment is discretized, we map the VD edge to the *last* HE edge */ - ankerl::unordered_dense::map vd_edge_to_he_edge; - ankerl::unordered_dense::map vd_node_to_he_node; - node_t& makeNode(vd_t::vertex_type& vd_node, Point p); //!< Get the node which the VD node maps to, or create a new mapping if there wasn't any yet. + ankerl::unordered_dense::map vd_edge_to_he_edge; + ankerl::unordered_dense::map vd_node_to_he_node; + node_t& makeNode(VD::vertex_type& vd_node, Point p); //!< Get the node which the VD node maps to, or create a new mapping if there wasn't any yet. /*! * (Eventual) returned 'polylines per index' result (from generateToolpaths): @@ -181,7 +180,7 @@ protected: * Transfer an edge from the VD to the HE and perform discretization of parabolic edges (and vertex-vertex edges) * \p prev_edge serves as input and output. May be null as input. */ - void transferEdge(Point from, Point to, vd_t::edge_type& vd_edge, edge_t*& prev_edge, Point& start_source_point, Point& end_source_point, const std::vector& segments); + void transferEdge(Point from, Point to, VD::edge_type& vd_edge, edge_t*& prev_edge, Point& start_source_point, Point& end_source_point, const std::vector& segments); /*! * Discretize a Voronoi edge that represents the medial axis of a vertex- @@ -208,7 +207,7 @@ protected: * \return A number of coordinates along the edge where the edge is broken * up into discrete pieces. */ - Points discretize(const vd_t::edge_type& segment, const std::vector& segments); + Points discretize(const VD::edge_type& segment, const std::vector& segments); /*! * Compute the range of line segments that surround a cell of the skeletal @@ -234,7 +233,7 @@ protected: * /return Whether the cell is inside of the polygon. If it's outside of the * polygon we should skip processing it altogether. */ - static bool computePointCellRange(vd_t::cell_type& cell, Point& start_source_point, Point& end_source_point, vd_t::edge_type*& starting_vd_edge, vd_t::edge_type*& ending_vd_edge, const std::vector& segments); + static bool computePointCellRange(VD::cell_type& cell, Point& start_source_point, Point& end_source_point, VD::edge_type*& starting_vd_edge, VD::edge_type*& ending_vd_edge, const std::vector& segments); /*! * Compute the range of line segments that surround a cell of the skeletal @@ -260,7 +259,7 @@ protected: * /return Whether the cell is inside of the polygon. If it's outside of the * polygon we should skip processing it altogether. */ - static void computeSegmentCellRange(vd_t::cell_type& cell, Point& start_source_point, Point& end_source_point, vd_t::edge_type*& starting_vd_edge, vd_t::edge_type*& ending_vd_edge, const std::vector& segments); + static void computeSegmentCellRange(VD::cell_type& cell, Point& start_source_point, Point& end_source_point, VD::edge_type*& starting_vd_edge, VD::edge_type*& ending_vd_edge, const std::vector& segments); /*! * For VD cells associated with an input polygon vertex, we need to separate the node at the end and start of the cell into two @@ -603,7 +602,7 @@ protected: */ void generateLocalMaximaSingleBeads(); - friend bool detect_voronoi_edge_intersecting_input_segment(const Geometry::VoronoiDiagram &voronoi_diagram, const std::vector &segments); + friend bool detect_voronoi_edge_intersecting_input_segment(const VD &voronoi_diagram, const std::vector &segments); }; } // namespace Slic3r::Arachne diff --git a/src/libslic3r/Arachne/utils/PolygonsPointIndex.hpp b/src/libslic3r/Arachne/utils/PolygonsPointIndex.hpp index 125b3ef926..04f017f86a 100644 --- a/src/libslic3r/Arachne/utils/PolygonsPointIndex.hpp +++ b/src/libslic3r/Arachne/utils/PolygonsPointIndex.hpp @@ -156,8 +156,6 @@ struct PathsPointIndexLocator } }; -using PolygonsPointIndexLocator = PathsPointIndexLocator; - }//namespace Slic3r::Arachne namespace std diff --git a/src/libslic3r/Geometry/MedialAxis.cpp b/src/libslic3r/Geometry/MedialAxis.cpp index aaaa970f32..3854dcee48 100644 --- a/src/libslic3r/Geometry/MedialAxis.cpp +++ b/src/libslic3r/Geometry/MedialAxis.cpp @@ -467,7 +467,7 @@ void MedialAxis::build(ThickPolylines* polylines) test(l.b.y()); } #endif // NDEBUG - construct_voronoi(m_lines.begin(), m_lines.end(), &m_vd); + m_vd.construct_voronoi(m_lines.begin(), m_lines.end()); Slic3r::Voronoi::annotate_inside_outside(m_vd, m_lines); // static constexpr double threshold_alpha = M_PI / 12.; // 30 degrees // std::vector skeleton_edges = Slic3r::Voronoi::skeleton_edges_rough(vd, lines, threshold_alpha); diff --git a/src/libslic3r/Geometry/Voronoi.hpp b/src/libslic3r/Geometry/Voronoi.hpp index 88b487c761..bfd6d17643 100644 --- a/src/libslic3r/Geometry/Voronoi.hpp +++ b/src/libslic3r/Geometry/Voronoi.hpp @@ -8,10 +8,8 @@ #include "../Line.hpp" #include "../Polyline.hpp" -#define BOOST_VORONOI_USE_GMP 1 - #ifdef _MSC_VER -// Suppress warning C4146 in OpenVDB: unary minus operator applied to unsigned type, result still unsigned +// Suppress warning C4146 in OpenVDB: unary minus operator applied to unsigned type, result still unsigned #pragma warning(push) #pragma warning(disable : 4146) #endif // _MSC_VER @@ -20,18 +18,85 @@ #pragma warning(pop) #endif // _MSC_VER -namespace Slic3r { +namespace Slic3r::Geometry { -namespace Geometry { - -class VoronoiDiagram : public boost::polygon::voronoi_diagram { +class VoronoiDiagram +{ public: - typedef double coord_type; - typedef boost::polygon::point_data point_type; - typedef boost::polygon::segment_data segment_type; - typedef boost::polygon::rectangle_data rect_type; + using coord_type = double; + using voronoi_diagram_type = boost::polygon::voronoi_diagram; + using point_type = boost::polygon::point_data; + using segment_type = boost::polygon::segment_data; + using rect_type = boost::polygon::rectangle_data; + + using coordinate_type = voronoi_diagram_type::coordinate_type; + using vertex_type = voronoi_diagram_type::vertex_type; + using edge_type = voronoi_diagram_type::edge_type; + using cell_type = voronoi_diagram_type::cell_type; + + using const_vertex_iterator = voronoi_diagram_type::const_vertex_iterator; + using const_edge_iterator = voronoi_diagram_type::const_edge_iterator; + using const_cell_iterator = voronoi_diagram_type::const_cell_iterator; + + using vertex_container_type = voronoi_diagram_type::vertex_container_type; + using edge_container_type = voronoi_diagram_type::edge_container_type; + using cell_container_type = voronoi_diagram_type::cell_container_type; + + VoronoiDiagram() = default; + + virtual ~VoronoiDiagram() = default; + + void clear() { m_voronoi_diagram.clear(); } + + const cell_container_type &cells() const { return m_voronoi_diagram.cells(); } + + const vertex_container_type &vertices() const { return m_voronoi_diagram.vertices(); } + + const edge_container_type &edges() const { return m_voronoi_diagram.edges(); } + + std::size_t num_cells() const { return m_voronoi_diagram.num_cells(); } + + std::size_t num_edges() const { return m_voronoi_diagram.num_edges(); } + + std::size_t num_vertices() const { return m_voronoi_diagram.num_vertices(); } + + template + typename boost::polygon::enable_if< + typename boost::polygon::gtl_if::value_type>::type>::type>::type, + void>::type + construct_voronoi(const SegmentIterator first, const SegmentIterator last) + { + boost::polygon::construct_voronoi(first, last, &m_voronoi_diagram); + } + + template + typename boost::polygon::enable_if< + typename boost::polygon::gtl_if::value_type>::type>::type>::type, + void>::type + construct_voronoi(const PointIterator first, const PointIterator last) + { + boost::polygon::construct_voronoi(first, last, &m_voronoi_diagram); + } + + template + typename boost::polygon::enable_if< + typename boost::polygon::gtl_and< + typename boost::polygon::gtl_if::value_type>::type>::type>::type, + typename boost::polygon::gtl_if::value_type>::type>::type>::type>::type, + void>::type + construct_voronoi(const PointIterator p_first, const PointIterator p_last, const SegmentIterator s_first, const SegmentIterator s_last) + { + boost::polygon::construct_voronoi(p_first, p_last, s_first, s_last, &m_voronoi_diagram); + } + +private: + voronoi_diagram_type m_voronoi_diagram; }; -} } // namespace Slicer::Geometry +} // namespace Slic3r::Geometry #endif // slic3r_Geometry_Voronoi_hpp_ diff --git a/src/libslic3r/Geometry/VoronoiUtilsCgal.cpp b/src/libslic3r/Geometry/VoronoiUtilsCgal.cpp index 965cece814..ce97acf02a 100644 --- a/src/libslic3r/Geometry/VoronoiUtilsCgal.cpp +++ b/src/libslic3r/Geometry/VoronoiUtilsCgal.cpp @@ -254,7 +254,7 @@ static bool check_if_three_edges_are_ccw(const VD::edge_type &first, const VD::e } } -bool VoronoiUtilsCgal::is_voronoi_diagram_planar_angle(const VoronoiDiagram &voronoi_diagram, const std::vector &segments) +bool VoronoiUtilsCgal::is_voronoi_diagram_planar_angle(const VD &voronoi_diagram, const std::vector &segments) { for (const VD::vertex_type &vertex : voronoi_diagram.vertices()) { std::vector edges; @@ -271,9 +271,9 @@ bool VoronoiUtilsCgal::is_voronoi_diagram_planar_angle(const VoronoiDiagram &vor // Checking for CCW make sense for three and more edges. if (edges.size() > 2) { for (auto edge_it = edges.begin() ; edge_it != edges.end(); ++edge_it) { - const Geometry::VoronoiDiagram::edge_type *prev_edge = edge_it == edges.begin() ? edges.back() : *std::prev(edge_it); - const Geometry::VoronoiDiagram::edge_type *curr_edge = *edge_it; - const Geometry::VoronoiDiagram::edge_type *next_edge = std::next(edge_it) == edges.end() ? edges.front() : *std::next(edge_it); + const VD::edge_type *prev_edge = edge_it == edges.begin() ? edges.back() : *std::prev(edge_it); + const VD::edge_type *curr_edge = *edge_it; + const VD::edge_type *next_edge = std::next(edge_it) == edges.end() ? edges.front() : *std::next(edge_it); if (!check_if_three_edges_are_ccw(*prev_edge, *curr_edge, *next_edge, segments)) return false; diff --git a/src/libslic3r/MultiMaterialSegmentation.cpp b/src/libslic3r/MultiMaterialSegmentation.cpp index 334a33c389..23f593c0eb 100644 --- a/src/libslic3r/MultiMaterialSegmentation.cpp +++ b/src/libslic3r/MultiMaterialSegmentation.cpp @@ -702,7 +702,7 @@ struct MMU_Graph // All Voronoi vertices are post-processes to merge very close vertices to single. Witch eliminates issues with intersection edges. // Also, Voronoi vertices outside of the bounding of input polygons are throw away by marking them. - void append_voronoi_vertices(const Geometry::VoronoiDiagram &vd, const Polygons &color_poly_tmp, BoundingBox bbox) { + void append_voronoi_vertices(const Voronoi::VD &vd, const Polygons &color_poly_tmp, BoundingBox bbox) { bbox.offset(SCALED_EPSILON); struct CPoint @@ -884,7 +884,7 @@ static inline Line clip_finite_voronoi_edge(const Voronoi::VD::edge_type &edge, static MMU_Graph build_graph(size_t layer_idx, const std::vector> &color_poly) { - Geometry::VoronoiDiagram vd; + Voronoi::VD vd; std::vector lines_colored = to_lines(color_poly); const Polygons color_poly_tmp = colored_points_to_polygon(color_poly); const Points points = to_points(color_poly_tmp); @@ -908,7 +908,7 @@ static MMU_Graph build_graph(size_t layer_idx, const std::vector skeleton_edges = Slic3r::Voronoi::skeleton_edges_rough(vd, lines, threshold_alpha); @@ -1966,7 +1966,7 @@ TEST_CASE("Voronoi missing vertex 1", "[VoronoiMissingVertex1]") VD vd; Lines lines = to_lines(poly); - construct_voronoi(lines.begin(), lines.end(), &vd); + vd.construct_voronoi(lines.begin(), lines.end()); #ifdef VORONOI_DEBUG_OUT dump_voronoi_to_svg(debug_out_path("voronoi-missing-vertex1-out.svg").c_str(), vd, Points(), lines); #endif @@ -2006,7 +2006,7 @@ TEST_CASE("Voronoi missing vertex 2", "[VoronoiMissingVertex2]") VD vd; Lines lines = to_lines(poly); - construct_voronoi(lines.begin(), lines.end(), &vd); + vd.construct_voronoi(lines.begin(), lines.end()); #ifdef VORONOI_DEBUG_OUT dump_voronoi_to_svg(debug_out_path("voronoi-missing-vertex2-out.svg").c_str(), vd, Points(), lines); #endif @@ -2047,7 +2047,7 @@ TEST_CASE("Voronoi missing vertex 3", "[VoronoiMissingVertex3]") VD vd; Lines lines = to_lines(poly); - construct_voronoi(lines.begin(), lines.end(), &vd); + vd.construct_voronoi(lines.begin(), lines.end()); #ifdef VORONOI_DEBUG_OUT dump_voronoi_to_svg(debug_out_path("voronoi-missing-vertex3-out.svg").c_str(), vd, Points(), lines); #endif @@ -2091,8 +2091,8 @@ TEST_CASE("Voronoi missing vertex 4", "[VoronoiMissingVertex4]") Geometry::VoronoiDiagram vd_2; Lines lines_1 = to_lines(polygon_1); Lines lines_2 = to_lines(polygon_2); - construct_voronoi(lines_1.begin(), lines_1.end(), &vd_1); - construct_voronoi(lines_2.begin(), lines_2.end(), &vd_2); + vd_1.construct_voronoi(lines_1.begin(), lines_1.end()); + vd_2.construct_voronoi(lines_2.begin(), lines_2.end()); #ifdef VORONOI_DEBUG_OUT dump_voronoi_to_svg(debug_out_path("voronoi-missing-vertex4-1-out.svg").c_str(), vd_1, Points(), lines_1); dump_voronoi_to_svg(debug_out_path("voronoi-missing-vertex4-2-out.svg").c_str(), vd_2, Points(), lines_2); @@ -2124,7 +2124,7 @@ TEST_CASE("Duplicate Voronoi vertices", "[Voronoi]") VD vd; Lines lines = to_lines(poly); - construct_voronoi(lines.begin(), lines.end(), &vd); + vd.construct_voronoi(lines.begin(), lines.end()); #ifdef VORONOI_DEBUG_OUT dump_voronoi_to_svg(debug_out_path("voronoi-duplicate-vertices-out.svg").c_str(), vd, Points(), lines); #endif @@ -2164,7 +2164,7 @@ TEST_CASE("Intersecting Voronoi edges", "[Voronoi]") VD vd; Lines lines = to_lines(poly); - construct_voronoi(lines.begin(), lines.end(), &vd); + vd.construct_voronoi(lines.begin(), lines.end()); #ifdef VORONOI_DEBUG_OUT dump_voronoi_to_svg(debug_out_path("voronoi-intersecting-edges-out.svg").c_str(), vd, Points(), lines); #endif @@ -2226,7 +2226,7 @@ TEST_CASE("Non-planar voronoi diagram", "[VoronoiNonPlanar]") VD vd; Lines lines = to_lines(poly); - construct_voronoi(lines.begin(), lines.end(), &vd); + vd.construct_voronoi(lines.begin(), lines.end()); #ifdef VORONOI_DEBUG_OUT dump_voronoi_to_svg(debug_out_path("voronoi-non-planar-out.svg").c_str(), vd, Points(), lines); #endif