OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::MMU_Graph Struct Reference
Collaboration diagram for Slic3r::MMU_Graph:

Classes

struct  Arc
struct  Node

Public Types

enum class  ARC_TYPE { BORDER , NON_BORDER }

Public Member Functions

void remove_edge (const size_t from_idx, const size_t to_idx)
size_t get_global_index (const size_t poly_idx, const size_t point_idx) const
void append_edge (const size_t &from_idx, const size_t &to_idx, int color=-1, ARC_TYPE type=ARC_TYPE::NON_BORDER)
MMU_Graph::Arc get_border_arc (size_t idx) const
size_t nodes_count () const
void remove_nodes_with_one_arc ()
void add_contours (const std::vector< std::vector< ColoredLine > > &color_poly)
bool is_vertex_on_contour (const Voronoi::VD::vertex_type *vertex) const
bool is_edge_attach_to_contour (const voronoi_diagram< double >::const_edge_iterator &edge_iterator) const
bool is_edge_connecting_two_contour_vertices (const voronoi_diagram< double >::const_edge_iterator &edge_iterator) const
void append_voronoi_vertices (const Geometry::VoronoiDiagram &vd, const Polygons &color_poly_tmp, BoundingBox bbox)
void garbage_collect ()

Public Attributes

std::vector< MMU_Graph::Node > nodes
std::vector< MMU_Graph::Arc > arcs
size_t all_border_points {}
std::vector< size_t > polygon_idx_offset
std::vector< size_t > polygon_sizes

Detailed Description

Member Enumeration Documentation

◆ ARC_TYPE

enum class Slic3r::MMU_Graph::ARC_TYPE
strong
Enumerator
BORDER 
NON_BORDER 
94{ BORDER, NON_BORDER };
#define BORDER(a, b)
Definition OptionsGroup.hpp:32

Member Function Documentation

◆ add_contours()

void Slic3r::MMU_Graph::add_contours ( const std::vector< std::vector< ColoredLine > > & color_poly)
inline
193 {
194 this->all_border_points = nodes.size();
195 this->polygon_sizes = std::vector<size_t>(color_poly.size());
196 for (size_t polygon_idx = 0; polygon_idx < color_poly.size(); ++polygon_idx) this->polygon_sizes[polygon_idx] = color_poly[polygon_idx].size();
197 this->polygon_idx_offset = std::vector<size_t>(color_poly.size());
198 this->polygon_idx_offset[0] = 0;
199 for (size_t polygon_idx = 1; polygon_idx < color_poly.size(); ++polygon_idx) {
200 this->polygon_idx_offset[polygon_idx] = this->polygon_idx_offset[polygon_idx - 1] + color_poly[polygon_idx - 1].size();
201 }
202
203 size_t poly_idx = 0;
204 for (const std::vector<ColoredLine> &color_lines : color_poly) {
205 size_t line_idx = 0;
206 for (const ColoredLine &color_line : color_lines) {
207 size_t from_idx = this->get_global_index(poly_idx, line_idx);
208 size_t to_idx = this->get_global_index(poly_idx, (line_idx + 1) % color_lines.size());
209 this->append_edge(from_idx, to_idx, color_line.color, ARC_TYPE::BORDER);
210 ++line_idx;
211 }
212 ++poly_idx;
213 }
214 }
size_t get_global_index(const size_t poly_idx, const size_t point_idx) const
Definition MultiMaterialSegmentation.cpp:138
std::vector< MMU_Graph::Node > nodes
Definition MultiMaterialSegmentation.cpp:125
void append_edge(const size_t &from_idx, const size_t &to_idx, int color=-1, ARC_TYPE type=ARC_TYPE::NON_BORDER)
Definition MultiMaterialSegmentation.cpp:140
std::vector< size_t > polygon_sizes
Definition MultiMaterialSegmentation.cpp:130
std::vector< size_t > polygon_idx_offset
Definition MultiMaterialSegmentation.cpp:129
size_t all_border_points
Definition MultiMaterialSegmentation.cpp:127
@ BORDER
Definition MultiMaterialSegmentation.cpp:94

References append_edge(), BORDER, get_global_index(), and nodes.

Referenced by Slic3r::build_graph().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ append_edge()

void Slic3r::MMU_Graph::append_edge ( const size_t & from_idx,
const size_t & to_idx,
int color = -1,
ARC_TYPE type = ARC_TYPE::NON_BORDER )
inline
141 {
142 // Don't append duplicate edges between the same nodes.
143 for (const size_t &arc_idx : this->nodes[from_idx].arc_idxs)
144 if (arcs[arc_idx].to_idx == to_idx) return;
145 for (const size_t &arc_idx : this->nodes[to_idx].arc_idxs)
146 if (arcs[arc_idx].to_idx == from_idx) return;
147
148 this->nodes[from_idx].arc_idxs.push_back(this->arcs.size());
149 this->arcs.push_back({from_idx, to_idx, color, type});
150
151 // Always insert only one directed arc for the input polygons.
152 // Two directed arcs in both directions are inserted if arcs aren't between points of the input polygons.
153 if (type == ARC_TYPE::NON_BORDER) {
154 this->nodes[to_idx].arc_idxs.push_back(this->arcs.size());
155 this->arcs.push_back({to_idx, from_idx, color, type});
156 }
157 }
std::vector< MMU_Graph::Arc > arcs
Definition MultiMaterialSegmentation.cpp:126
@ NON_BORDER
Definition MultiMaterialSegmentation.cpp:94

References arcs, and NON_BORDER.

Referenced by add_contours(), and Slic3r::build_graph().

Here is the caller graph for this function:

◆ append_voronoi_vertices()

void Slic3r::MMU_Graph::append_voronoi_vertices ( const Geometry::VoronoiDiagram & vd,
const Polygons & color_poly_tmp,
BoundingBox bbox )
inline
236 {
237 bbox.offset(SCALED_EPSILON);
238
239 struct CPoint
240 {
241 CPoint() = delete;
242 CPoint(const Vec2d &point, size_t contour_idx, size_t point_idx) : m_point_double(point), m_point(mk_point(point)), m_point_idx(point_idx), m_contour_idx(contour_idx)
243 {}
244 CPoint(const Vec2d &point, size_t point_idx) : m_point_double(point), m_point(mk_point(point)), m_point_idx(point_idx), m_contour_idx(0) {}
245 const Vec2d m_point_double;
246 const Point m_point;
247 size_t m_point_idx;
248 size_t m_contour_idx;
249
250 [[nodiscard]] const Vec2d &point_double() const { return m_point_double; }
251 [[nodiscard]] const Point &point() const { return m_point; }
252 bool operator==(const CPoint &rhs) const
253 {
254 return this->m_point_double == rhs.m_point_double && this->m_contour_idx == rhs.m_contour_idx && this->m_point_idx == rhs.m_point_idx;
255 }
256 };
257 struct CPointAccessor
258 {
259 const Point *operator()(const CPoint &pt) const { return &pt.point(); }
260 };
261 typedef ClosestPointInRadiusLookup<CPoint, CPointAccessor> CPointLookupType;
262
263 CPointLookupType closest_voronoi_point(coord_t(SCALED_EPSILON));
264 CPointLookupType closest_contour_point(3 * coord_t(SCALED_EPSILON));
265 for (const Polygon &polygon : color_poly_tmp)
266 for (const Point &pt : polygon.points) closest_contour_point.insert(CPoint(Vec2d(pt.x(), pt.y()), &polygon - &color_poly_tmp.front(), &pt - &polygon.points.front()));
267
268 for (const voronoi_diagram<double>::vertex_type &vertex : vd.vertices()) {
269 vertex.color(-1);
270 Vec2d vertex_point_double = Vec2d(vertex.x(), vertex.y());
271 Point vertex_point = mk_point(vertex);
272
273 const Vec2d &first_point_double = this->nodes[this->get_border_arc(vertex.incident_edge()->cell()->source_index()).from_idx].point;
274 const Vec2d &second_point_double = this->nodes[this->get_border_arc(vertex.incident_edge()->twin()->cell()->source_index()).from_idx].point;
275
276 if (vertex_equal_to_point(&vertex, first_point_double)) {
277 assert(vertex.color() != vertex.incident_edge()->cell()->source_index());
278 assert(vertex.color() != vertex.incident_edge()->twin()->cell()->source_index());
279 vertex.color(this->get_border_arc(vertex.incident_edge()->cell()->source_index()).from_idx);
280 } else if (vertex_equal_to_point(&vertex, second_point_double)) {
281 assert(vertex.color() != vertex.incident_edge()->cell()->source_index());
282 assert(vertex.color() != vertex.incident_edge()->twin()->cell()->source_index());
283 vertex.color(this->get_border_arc(vertex.incident_edge()->twin()->cell()->source_index()).from_idx);
284 } else if (bbox.contains(vertex_point)) {
285 if (auto [contour_pt, c_dist_sqr] = closest_contour_point.find(vertex_point); contour_pt != nullptr && c_dist_sqr < Slic3r::sqr(3 * SCALED_EPSILON)) {
286 vertex.color(this->get_global_index(contour_pt->m_contour_idx, contour_pt->m_point_idx));
287 } else if (auto [voronoi_pt, v_dist_sqr] = closest_voronoi_point.find(vertex_point); voronoi_pt == nullptr || v_dist_sqr >= Slic3r::sqr(SCALED_EPSILON / 10.0)) {
288 closest_voronoi_point.insert(CPoint(vertex_point_double, this->nodes_count()));
289 vertex.color(this->nodes_count());
290 this->nodes.push_back({vertex_point_double});
291 } else {
292 // Boost Voronoi diagram generator sometimes creates two very closed points instead of one point.
293 // For the example points (146872.99999999997, -146872.99999999997) and (146873, -146873), this example also included in Voronoi generator test cases.
294 std::vector<std::pair<const CPoint *, double>> all_closes_c_points = closest_voronoi_point.find_all(vertex_point);
295 int merge_to_point = -1;
296 for (const std::pair<const CPoint *, double> &c_point : all_closes_c_points)
297 if ((vertex_point_double - c_point.first->point_double()).squaredNorm() <= Slic3r::sqr(EPSILON)) {
298 merge_to_point = int(c_point.first->m_point_idx);
299 break;
300 }
301
302 if (merge_to_point != -1) {
303 vertex.color(merge_to_point);
304 } else {
305 closest_voronoi_point.insert(CPoint(vertex_point_double, this->nodes_count()));
306 vertex.color(this->nodes_count());
307 this->nodes.push_back({vertex_point_double});
308 }
309 }
310 }
311 }
312 }
#define EPSILON
Definition ColorUtils.cpp:64
#define SCALED_EPSILON
Definition libslic3r.h:109
int64_t coord_t
Definition libslic3r.h:48
Vec2d vertex_point(const VD::vertex_type &v)
Definition VoronoiOffset.hpp:31
Kernel::Point_3 Point
Definition MeshRepair.cpp:81
static bool vertex_equal_to_point(const Voronoi::VD::vertex_type &vertex, const Vec2d &ipt)
Definition MultiMaterialSegmentation.cpp:79
bool operator==(const clonable_ptr< T > &l, const clonable_ptr< U > &r) noexcept
Definition clonable_ptr.hpp:145
constexpr T sqr(T x)
Definition libslic3r.h:301
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > Vec2d
Definition Point.hpp:67
static Point mk_point(const Voronoi::VD::vertex_type *point)
Definition MultiMaterialSegmentation.cpp:69
size_t from_idx
Definition MultiMaterialSegmentation.cpp:98
size_t nodes_count() const
Definition MultiMaterialSegmentation.cpp:167
MMU_Graph::Arc get_border_arc(size_t idx) const
Definition MultiMaterialSegmentation.cpp:161

References Slic3r::BoundingBoxBase< PointType, APointsType >::contains(), EPSILON, Slic3r::MMU_Graph::Arc::from_idx, get_border_arc(), get_global_index(), Slic3r::mk_point(), nodes_count(), Slic3r::BoundingBoxBase< PointType, APointsType >::offset(), Slic3r::operator==(), SCALED_EPSILON, Slic3r::sqr(), Slic3r::vertex_equal_to_point(), and Slic3r::Geometry::VoronoiDiagram::vertices().

Referenced by Slic3r::build_graph().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ garbage_collect()

void Slic3r::MMU_Graph::garbage_collect ( )
inline
315 {
316 std::vector<int> nodes_map(this->nodes.size(), -1);
317 int nodes_count = 0;
318 size_t arcs_count = 0;
319 for (const MMU_Graph::Node &node : this->nodes)
320 if (size_t node_idx = &node - &this->nodes.front(); !node.arc_idxs.empty()) {
321 nodes_map[node_idx] = nodes_count++;
322 arcs_count += node.arc_idxs.size();
323 }
324
325 std::vector<MMU_Graph::Node> new_nodes;
326 std::vector<MMU_Graph::Arc> new_arcs;
327 new_nodes.reserve(nodes_count);
328 new_arcs.reserve(arcs_count);
329 for (const MMU_Graph::Node &node : this->nodes)
330 if (size_t node_idx = &node - &this->nodes.front(); nodes_map[node_idx] >= 0) {
331 new_nodes.push_back({node.point});
332 for (const size_t &arc_idx : node.arc_idxs) {
333 const Arc &arc = this->arcs[arc_idx];
334 new_nodes.back().arc_idxs.emplace_back(new_arcs.size());
335 new_arcs.push_back({size_t(nodes_map[arc.from_idx]), size_t(nodes_map[arc.to_idx]), arc.color, arc.type});
336 }
337 }
338
339 this->nodes = std::move(new_nodes);
340 this->arcs = std::move(new_arcs);
341 }
void arc(std::vector< std::pair< Vec2d, Vec2d > > &out, double cx, double cy, double rx, double ry, double a0, double a1, int n=14)
Definition DesignSketchTool.cpp:7759
Definition MultiMaterialSegmentation.cpp:97

References nodes_count().

Here is the call graph for this function:

◆ get_border_arc()

MMU_Graph::Arc Slic3r::MMU_Graph::get_border_arc ( size_t idx) const
inlinenodiscard
162 {
163 assert(idx < this->all_border_points);
164 return this->arcs[idx];
165 }

References all_border_points.

Referenced by append_voronoi_vertices(), and Slic3r::build_graph().

Here is the caller graph for this function:

◆ get_global_index()

size_t Slic3r::MMU_Graph::get_global_index ( const size_t poly_idx,
const size_t point_idx ) const
inlinenodiscard
138{ return polygon_idx_offset[poly_idx] + point_idx; }

References polygon_idx_offset.

Referenced by add_contours(), append_voronoi_vertices(), Slic3r::build_graph(), Slic3r::init_polygon_indices(), and Slic3r::remove_multiple_edges_in_vertices().

Here is the caller graph for this function:

◆ is_edge_attach_to_contour()

bool Slic3r::MMU_Graph::is_edge_attach_to_contour ( const voronoi_diagram< double >::const_edge_iterator & edge_iterator) const
inlinenodiscard
224 {
225 return this->is_vertex_on_contour(edge_iterator->vertex0()) || this->is_vertex_on_contour(edge_iterator->vertex1());
226 }
bool is_vertex_on_contour(const Voronoi::VD::vertex_type *vertex) const
Definition MultiMaterialSegmentation.cpp:217

References is_vertex_on_contour().

Referenced by Slic3r::build_graph().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_edge_connecting_two_contour_vertices()

bool Slic3r::MMU_Graph::is_edge_connecting_two_contour_vertices ( const voronoi_diagram< double >::const_edge_iterator & edge_iterator) const
inlinenodiscard
229 {
230 return this->is_vertex_on_contour(edge_iterator->vertex0()) && this->is_vertex_on_contour(edge_iterator->vertex1());
231 }

References is_vertex_on_contour().

Referenced by Slic3r::build_graph().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_vertex_on_contour()

bool Slic3r::MMU_Graph::is_vertex_on_contour ( const Voronoi::VD::vertex_type * vertex) const
inline
218 {
219 assert(vertex != nullptr);
220 return vertex->color() < this->all_border_points;
221 }

Referenced by Slic3r::build_graph(), is_edge_attach_to_contour(), and is_edge_connecting_two_contour_vertices().

Here is the caller graph for this function:

◆ nodes_count()

size_t Slic3r::MMU_Graph::nodes_count ( ) const
inlinenodiscard
167{ return this->nodes.size(); }

Referenced by append_voronoi_vertices(), Slic3r::build_graph(), and garbage_collect().

Here is the caller graph for this function:

◆ remove_edge()

void Slic3r::MMU_Graph::remove_edge ( const size_t from_idx,
const size_t to_idx )
inline
133 {
134 nodes[from_idx].remove_edge(to_idx, *this);
135 nodes[to_idx].remove_edge(from_idx, *this);
136 }

References nodes.

Referenced by Slic3r::remove_multiple_edges_in_vertices(), and remove_nodes_with_one_arc().

Here is the caller graph for this function:

◆ remove_nodes_with_one_arc()

void Slic3r::MMU_Graph::remove_nodes_with_one_arc ( )
inline
170 {
171 std::queue<size_t> update_queue;
172 for (const MMU_Graph::Node &node : this->nodes) {
173 size_t node_idx = &node - &this->nodes.front();
174 // Skip nodes that represent points of input polygons.
175 if (node.arc_idxs.size() == 1 && node_idx >= this->all_border_points) update_queue.emplace(&node - &this->nodes.front());
176 }
177
178 while (!update_queue.empty()) {
179 size_t node_from_idx = update_queue.front();
180 MMU_Graph::Node &node_from = this->nodes[update_queue.front()];
181 update_queue.pop();
182 if (node_from.arc_idxs.empty()) continue;
183
184 assert(node_from.arc_idxs.size() == 1);
185 size_t node_to_idx = arcs[node_from.arc_idxs.front()].to_idx;
186 MMU_Graph::Node &node_to = this->nodes[node_to_idx];
187 this->remove_edge(node_from_idx, node_to_idx);
188 if (node_to.arc_idxs.size() == 1 && node_to_idx >= this->all_border_points) update_queue.emplace(node_to_idx);
189 }
190 }
void remove_edge(const size_t from_idx, const size_t to_idx)
Definition MultiMaterialSegmentation.cpp:132

References Slic3r::MMU_Graph::Node::arc_idxs, arcs, and remove_edge().

Referenced by Slic3r::build_graph().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ all_border_points

size_t Slic3r::MMU_Graph::all_border_points {}

◆ arcs

◆ nodes

◆ polygon_idx_offset

std::vector<size_t> Slic3r::MMU_Graph::polygon_idx_offset

Referenced by get_global_index().

◆ polygon_sizes

std::vector<size_t> Slic3r::MMU_Graph::polygon_sizes

The documentation for this struct was generated from the following file: