236 {
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;
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; }
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
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());
272
275
277 assert(vertex.color() != vertex.incident_edge()->cell()->source_index());
278 assert(vertex.color() != vertex.incident_edge()->twin()->cell()->source_index());
281 assert(vertex.color() != vertex.incident_edge()->cell()->source_index());
282 assert(vertex.color() != vertex.incident_edge()->twin()->cell()->source_index());
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()));
290 this->
nodes.push_back({vertex_point_double});
291 } else {
292
293
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()));
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