Prusa Slicer 2.6.0
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::Nodenodes
 
std::vector< MMU_Graph::Arcarcs
 
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 

Member Function Documentation

◆ add_contours()

void Slic3r::MMU_Graph::add_contours ( const std::vector< std::vector< ColoredLine > > &  color_poly)
inline
658 {
659 this->all_border_points = nodes.size();
660 this->polygon_sizes = std::vector<size_t>(color_poly.size());
661 for (size_t polygon_idx = 0; polygon_idx < color_poly.size(); ++polygon_idx)
662 this->polygon_sizes[polygon_idx] = color_poly[polygon_idx].size();
663 this->polygon_idx_offset = std::vector<size_t>(color_poly.size());
664 this->polygon_idx_offset[0] = 0;
665 for (size_t polygon_idx = 1; polygon_idx < color_poly.size(); ++polygon_idx) {
666 this->polygon_idx_offset[polygon_idx] = this->polygon_idx_offset[polygon_idx - 1] + color_poly[polygon_idx - 1].size();
667 }
668
669 size_t poly_idx = 0;
670 for (const std::vector<ColoredLine> &color_lines : color_poly) {
671 size_t line_idx = 0;
672 for (const ColoredLine &color_line : color_lines) {
673 size_t from_idx = this->get_global_index(poly_idx, line_idx);
674 size_t to_idx = this->get_global_index(poly_idx, (line_idx + 1) % color_lines.size());
675 this->append_edge(from_idx, to_idx, color_line.color, ARC_TYPE::BORDER);
676 ++line_idx;
677 }
678 ++poly_idx;
679 }
680 }
constexpr auto size(const C &c) -> decltype(c.size())
Definition span.hpp:183
size_t get_global_index(const size_t poly_idx, const size_t point_idx) const
Definition MultiMaterialSegmentation.cpp:599
std::vector< MMU_Graph::Node > nodes
Definition MultiMaterialSegmentation.cpp:586
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:601
std::vector< size_t > polygon_sizes
Definition MultiMaterialSegmentation.cpp:591
std::vector< size_t > polygon_idx_offset
Definition MultiMaterialSegmentation.cpp:590
size_t all_border_points
Definition MultiMaterialSegmentation.cpp:588

◆ 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
602 {
603 // Don't append duplicate edges between the same nodes.
604 for (const size_t &arc_idx : this->nodes[from_idx].arc_idxs)
605 if (arcs[arc_idx].to_idx == to_idx)
606 return;
607 for (const size_t &arc_idx : this->nodes[to_idx].arc_idxs)
608 if (arcs[arc_idx].to_idx == from_idx)
609 return;
610
611 this->nodes[from_idx].arc_idxs.push_back(this->arcs.size());
612 this->arcs.push_back({from_idx, to_idx, color, type});
613
614 // Always insert only one directed arc for the input polygons.
615 // Two directed arcs in both directions are inserted if arcs aren't between points of the input polygons.
616 if (type == ARC_TYPE::NON_BORDER) {
617 this->nodes[to_idx].arc_idxs.push_back(this->arcs.size());
618 this->arcs.push_back({to_idx, from_idx, color, type});
619 }
620 }
if(!(yy_init))
Definition lexer.c:1190
std::vector< MMU_Graph::Arc > arcs
Definition MultiMaterialSegmentation.cpp:587

◆ append_voronoi_vertices()

void Slic3r::MMU_Graph::append_voronoi_vertices ( const Geometry::VoronoiDiagram vd,
const Polygons color_poly_tmp,
BoundingBox  bbox 
)
inline
701 {
702 bbox.offset(SCALED_EPSILON);
703
704 struct CPoint
705 {
706 CPoint() = delete;
707 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) {}
708 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) {}
709 const Vec2d m_point_double;
710 const Point m_point;
711 size_t m_point_idx;
712 size_t m_contour_idx;
713
714 [[nodiscard]] const Vec2d &point_double() const { return m_point_double; }
715 [[nodiscard]] const Point &point() const { return m_point; }
716 bool operator==(const CPoint &rhs) const { return m_point_double == rhs.m_point_double && m_contour_idx == rhs.m_contour_idx && m_point_idx == rhs.m_point_idx; }
717 };
718 struct CPointAccessor { const Point* operator()(const CPoint &pt) const { return &pt.point(); }};
719 typedef ClosestPointInRadiusLookup<CPoint, CPointAccessor> CPointLookupType;
720
721 CPointLookupType closest_voronoi_point(coord_t(SCALED_EPSILON));
722 CPointLookupType closest_contour_point(3 * coord_t(SCALED_EPSILON));
723 for (const Polygon &polygon : color_poly_tmp)
724 for (const Point &pt : polygon.points)
725 closest_contour_point.insert(CPoint(Vec2d(pt.x(), pt.y()), &polygon - &color_poly_tmp.front(), &pt - &polygon.points.front()));
726
727 for (const voronoi_diagram<double>::vertex_type &vertex : vd.vertices()) {
728 vertex.color(-1);
729 Vec2d vertex_point_double = Vec2d(vertex.x(), vertex.y());
730 Point vertex_point = mk_point(vertex);
731
732 const Vec2d &first_point_double = this->nodes[this->get_border_arc(vertex.incident_edge()->cell()->source_index()).from_idx].point;
733 const Vec2d &second_point_double = this->nodes[this->get_border_arc(vertex.incident_edge()->twin()->cell()->source_index()).from_idx].point;
734
735 if (vertex_equal_to_point(&vertex, first_point_double)) {
736 assert(vertex.color() != vertex.incident_edge()->cell()->source_index());
737 assert(vertex.color() != vertex.incident_edge()->twin()->cell()->source_index());
738 vertex.color(this->get_border_arc(vertex.incident_edge()->cell()->source_index()).from_idx);
739 } else if (vertex_equal_to_point(&vertex, second_point_double)) {
740 assert(vertex.color() != vertex.incident_edge()->cell()->source_index());
741 assert(vertex.color() != vertex.incident_edge()->twin()->cell()->source_index());
742 vertex.color(this->get_border_arc(vertex.incident_edge()->twin()->cell()->source_index()).from_idx);
743 } else if (bbox.contains(vertex_point)) {
744 if (auto [contour_pt, c_dist_sqr] = closest_contour_point.find(vertex_point); contour_pt != nullptr && c_dist_sqr < Slic3r::sqr(3 * SCALED_EPSILON)) {
745 vertex.color(this->get_global_index(contour_pt->m_contour_idx, contour_pt->m_point_idx));
746 } 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)) {
747 closest_voronoi_point.insert(CPoint(vertex_point_double, this->nodes_count()));
748 vertex.color(this->nodes_count());
749 this->nodes.push_back({vertex_point_double});
750 } else {
751 // Boost Voronoi diagram generator sometimes creates two very closed points instead of one point.
752 // For the example points (146872.99999999997, -146872.99999999997) and (146873, -146873), this example also included in Voronoi generator test cases.
753 std::vector<std::pair<const CPoint *, double>> all_closes_c_points = closest_voronoi_point.find_all(vertex_point);
754 int merge_to_point = -1;
755 for (const std::pair<const CPoint *, double> &c_point : all_closes_c_points)
756 if ((vertex_point_double - c_point.first->point_double()).squaredNorm() <= Slic3r::sqr(EPSILON)) {
757 merge_to_point = int(c_point.first->m_point_idx);
758 break;
759 }
760
761 if (merge_to_point != -1) {
762 vertex.color(merge_to_point);
763 } else {
764 closest_voronoi_point.insert(CPoint(vertex_point_double, this->nodes_count()));
765 vertex.color(this->nodes_count());
766 this->nodes.push_back({vertex_point_double});
767 }
768 }
769 }
770 }
771 }
#define const
Definition getopt.c:38
#define SCALED_EPSILON
Definition libslic3r.h:71
static constexpr double EPSILON
Definition libslic3r.h:51
int32_t coord_t
Definition libslic3r.h:39
bool operator==(const IntPoint &l, const IntPoint &r)
Definition clipper.cpp:93
const Scalar & y
Definition MathFunctions.h:552
Vec2d vertex_point(const VD::vertex_type &v)
Definition VoronoiOffset.hpp:26
Definition avrdude-slic3r.cpp:16
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > Vec2d
Definition Point.hpp:51
static bool vertex_equal_to_point(const Voronoi::VD::vertex_type &vertex, const Vec2d &ipt)
Definition MultiMaterialSegmentation.cpp:183
constexpr T sqr(T x)
Definition libslic3r.h:258
static Point mk_point(const Voronoi::VD::vertex_type *point)
Definition MultiMaterialSegmentation.cpp:543
TCoord< P > x(const P &p)
Definition geometry_traits.hpp:297
TPoint< S > & vertex(S &sh, unsigned long idx, const PolygonTag &)
Definition geometry_traits.hpp:1180
TPoint< P > front(const P &p)
Definition geometry_traits.hpp:872
Kernel::Point_2 Point
Definition point_areas.cpp:20
size_t from_idx
Definition MultiMaterialSegmentation.cpp:559
size_t nodes_count() const
Definition MultiMaterialSegmentation.cpp:629
MMU_Graph::Arc get_border_arc(size_t idx) const
Definition MultiMaterialSegmentation.cpp:624

References Slic3r::BoundingBoxBase< PointType, APointsType >::contains(), EPSILON, Slic3r::mk_point(), Slic3r::BoundingBoxBase< PointType, APointsType >::offset(), SCALED_EPSILON, and Slic3r::sqr().

+ Here is the call graph for this function:

◆ garbage_collect()

void Slic3r::MMU_Graph::garbage_collect ( )
inline
774 {
775 std::vector<int> nodes_map(this->nodes.size(), -1);
776 int nodes_count = 0;
777 size_t arcs_count = 0;
778 for (const MMU_Graph::Node &node : this->nodes)
779 if (size_t node_idx = &node - &this->nodes.front(); !node.arc_idxs.empty()) {
780 nodes_map[node_idx] = nodes_count++;
781 arcs_count += node.arc_idxs.size();
782 }
783
784 std::vector<MMU_Graph::Node> new_nodes;
785 std::vector<MMU_Graph::Arc> new_arcs;
786 new_nodes.reserve(nodes_count);
787 new_arcs.reserve(arcs_count);
788 for (const MMU_Graph::Node &node : this->nodes)
789 if (size_t node_idx = &node - &this->nodes.front(); nodes_map[node_idx] >= 0) {
790 new_nodes.push_back({node.point});
791 for (const size_t &arc_idx : node.arc_idxs) {
792 const Arc &arc = this->arcs[arc_idx];
793 new_nodes.back().arc_idxs.emplace_back(new_arcs.size());
794 new_arcs.push_back({size_t(nodes_map[arc.from_idx]), size_t(nodes_map[arc.to_idx]), arc.color, arc.type});
795 }
796 }
797
798 this->nodes = std::move(new_nodes);
799 this->arcs = std::move(new_arcs);
800 }

References Slic3r::MMU_Graph::Arc::color, Slic3r::MMU_Graph::Arc::from_idx, Slic3r::MMU_Graph::Arc::to_idx, and Slic3r::MMU_Graph::Arc::type.

◆ get_border_arc()

MMU_Graph::Arc Slic3r::MMU_Graph::get_border_arc ( size_t  idx) const
inline
624 {
625 assert(idx < this->all_border_points);
626 return this->arcs[idx];
627 }

◆ get_global_index()

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

Referenced by 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
inline
690 {
691 return this->is_vertex_on_contour(edge_iterator->vertex0()) || this->is_vertex_on_contour(edge_iterator->vertex1());
692 }
bool is_vertex_on_contour(const Voronoi::VD::vertex_type *vertex) const
Definition MultiMaterialSegmentation.cpp:683

◆ 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
inline
695 {
696 return this->is_vertex_on_contour(edge_iterator->vertex0()) && this->is_vertex_on_contour(edge_iterator->vertex1());
697 }

◆ is_vertex_on_contour()

bool Slic3r::MMU_Graph::is_vertex_on_contour ( const Voronoi::VD::vertex_type *  vertex) const
inline
684 {
685 assert(vertex != nullptr);
686 return vertex->color() < this->all_border_points;
687 }

◆ nodes_count()

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

◆ remove_edge()

void Slic3r::MMU_Graph::remove_edge ( const size_t  from_idx,
const size_t  to_idx 
)
inline
594 {
595 nodes[from_idx].remove_edge(to_idx, *this);
596 nodes[to_idx].remove_edge(from_idx, *this);
597 }

Referenced by Slic3r::remove_multiple_edges_in_vertices().

+ Here is the caller graph for this function:

◆ remove_nodes_with_one_arc()

void Slic3r::MMU_Graph::remove_nodes_with_one_arc ( )
inline
632 {
633 std::queue<size_t> update_queue;
634 for (const MMU_Graph::Node &node : this->nodes) {
635 size_t node_idx = &node - &this->nodes.front();
636 // Skip nodes that represent points of input polygons.
637 if (node.arc_idxs.size() == 1 && node_idx >= this->all_border_points)
638 update_queue.emplace(&node - &this->nodes.front());
639 }
640
641 while (!update_queue.empty()) {
642 size_t node_from_idx = update_queue.front();
643 MMU_Graph::Node &node_from = this->nodes[update_queue.front()];
644 update_queue.pop();
645 if (node_from.arc_idxs.empty())
646 continue;
647
648 assert(node_from.arc_idxs.size() == 1);
649 size_t node_to_idx = arcs[node_from.arc_idxs.front()].to_idx;
650 MMU_Graph::Node &node_to = this->nodes[node_to_idx];
651 this->remove_edge(node_from_idx, node_to_idx);
652 if (node_to.arc_idxs.size() == 1 && node_to_idx >= this->all_border_points)
653 update_queue.emplace(node_to_idx);
654 }
655 }
void remove_edge(const size_t from_idx, const size_t to_idx)
Definition MultiMaterialSegmentation.cpp:593

References Slic3r::MMU_Graph::Node::arc_idxs.

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

◆ polygon_sizes

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

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