Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::Triangulation Class Reference

#include <src/libslic3r/Triangulation.hpp>

Public Types

using HalfEdge = std::pair< uint32_t, uint32_t >
 
using HalfEdges = std::vector< HalfEdge >
 
using Indices = std::vector< Vec3i >
 
using Changes = std::vector< uint32_t >
 

Public Member Functions

 Triangulation ()=delete
 

Static Public Member Functions

static Indices triangulate (const Points &points, const HalfEdges &half_edges)
 Connect points by triangulation to create filled surface by triangles Input points have to be unique Inspiration for make unique points is Emboss::dilate_to_unique_points.
 
static Indices triangulate (const Polygon &polygon)
 
static Indices triangulate (const Polygons &polygons)
 
static Indices triangulate (const ExPolygon &expolygon)
 
static Indices triangulate (const ExPolygons &expolygons)
 
static Changes create_changes (const Points &points, const Points &duplicits)
 Create conversion map from original index into new with respect of duplicit point.
 
static Indices triangulate (const ExPolygons &expolygons, const Points &points)
 Triangulation for expolygons, speed up when points are already collected NOTE: Not working properly for ExPolygons with multiple point on same coordinate You should check it by "collect_changes".
 
static Indices triangulate (const ExPolygons &expolygons, const Points &points, const Changes &changes)
 Triangulation for expolygons containing multiple points with same coordinate.
 

Detailed Description

Member Typedef Documentation

◆ Changes

◆ HalfEdge

◆ HalfEdges

◆ Indices

using Slic3r::Triangulation::Indices = std::vector<Vec3i>

Constructor & Destructor Documentation

◆ Triangulation()

Slic3r::Triangulation::Triangulation ( )
delete

Member Function Documentation

◆ create_changes()

Triangulation::Changes Triangulation::create_changes ( const Points points,
const Points duplicits 
)
static

Create conversion map from original index into new with respect of duplicit point.

Parameters
pointsinput set of points
duplicitsduplicit points collected from points
Returns
Conversion map for point index
304{
305 assert(!duplicits.empty());
306 assert(duplicits.size() < points.size()/2);
307 std::vector<uint32_t> duplicit_indices(duplicits.size(), std::numeric_limits<uint32_t>::max());
308 Changes changes;
309 changes.reserve(points.size());
310 uint32_t index = 0;
311 for (const Point &p: points) {
312 auto it = std::lower_bound(duplicits.begin(), duplicits.end(), p);
313 if (it == duplicits.end() || *it != p) {
314 changes.push_back(index);
315 ++index;
316 continue;
317 }
318 uint32_t &d_index = duplicit_indices[it - duplicits.begin()];
319 if (d_index == std::numeric_limits<uint32_t>::max()) {
320 d_index = index;
321 changes.push_back(index);
322 ++index;
323 } else {
324 changes.push_back(d_index);
325 }
326 }
327 return changes;
328}
Definition Point.hpp:158
std::vector< uint32_t > Changes
Definition Triangulation.hpp:40
unsigned __int32 uint32_t
Definition unistd.h:79

Referenced by priv::polygons2model_duplicit(), and triangulate().

+ Here is the caller graph for this function:

◆ triangulate() [1/7]

Triangulation::Indices Triangulation::triangulate ( const ExPolygon expolygon)
static
237 {
238 ExPolygons expolys({expolygon});
239 return triangulate(expolys);
240}
static Indices triangulate(const Points &points, const HalfEdges &half_edges)
Connect points by triangulation to create filled surface by triangles Input points have to be unique ...
Definition Triangulation.cpp:85
std::vector< ExPolygon > ExPolygons
Definition ExPolygon.hpp:13

References triangulate().

+ Here is the call graph for this function:

◆ triangulate() [2/7]

Triangulation::Indices Triangulation::triangulate ( const ExPolygons expolygons)
static
242 {
243 Points pts = to_points(expolygons);
244 Points d_pts = collect_duplicates(pts);
245 if (d_pts.empty()) return triangulate(expolygons, pts);
246
247 Changes changes = create_changes(pts, d_pts);
248 Indices indices = triangulate(expolygons, pts, changes);
249 // reverse map for changes
250 Changes changes2(changes.size(), std::numeric_limits<uint32_t>::max());
251 for (size_t i = 0; i < changes.size(); ++i)
252 changes2[changes[i]] = i;
253
254 // convert indices into expolygons indicies
255 for (Vec3i &t : indices)
256 for (size_t ti = 0; ti < 3; ti++) t[ti] = changes2[t[ti]];
257
258 return indices;
259}
std::vector< Vec3i > Indices
Definition Triangulation.hpp:20
static Changes create_changes(const Points &points, const Points &duplicits)
Create conversion map from original index into new with respect of duplicit point.
Definition Triangulation.cpp:303
Points collect_duplicates(Points pts)
Definition Point.cpp:69
Points to_points(const ExPolygons &src)
Definition ExPolygon.hpp:196
std::vector< Point, PointsAllocator< Point > > Points
Definition Point.hpp:58

References Slic3r::collect_duplicates(), create_changes(), Slic3r::to_points(), and triangulate().

+ Here is the call graph for this function:

◆ triangulate() [3/7]

Triangulation::Indices Triangulation::triangulate ( const ExPolygons expolygons,
const Points points 
)
static

Triangulation for expolygons, speed up when points are already collected NOTE: Not working properly for ExPolygons with multiple point on same coordinate You should check it by "collect_changes".

Parameters
expolygonsInput shape to triangulation - define edges
pointsPoints from expolygons
Returns
Triangle indices
262{
263 assert(count_points(expolygons) == points.size());
264 // when contain duplicit coordinate in points will not work properly
265 assert(collect_duplicates(points).empty());
266
268 edges.reserve(points.size());
269 uint32_t offset = 0;
270 for (const ExPolygon &expolygon : expolygons) {
271 priv::insert_edges(edges, offset, expolygon.contour);
272 for (const Polygon &hole : expolygon.holes)
274 }
275 std::sort(edges.begin(), edges.end());
276 return triangulate(points, edges);
277}
Definition ExPolygon.hpp:16
Definition Polygon.hpp:24
std::vector< HalfEdge > HalfEdges
Definition Triangulation.hpp:19
Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, ClipperLib::JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:416
bool empty(const BoundingBoxBase< PointType, PointsType > &bb)
Definition BoundingBox.hpp:229
size_t count_points(const ExPolygons &expolys)
Definition ExPolygon.hpp:88
const Polygons & holes(const ExPolygon &p)
Definition AGGRaster.hpp:22
IGL_INLINE void edges(const Eigen::MatrixBase< DerivedF > &F, Eigen::PlainObjectBase< DerivedE > &E)
Definition edges.cpp:13
Slic3r::Polygon & hole(Slic3r::ExPolygon &sh, unsigned long idx)
Definition geometries.hpp:200
Definition CutSurface.cpp:39
void insert_edges(Triangulation::HalfEdges &edges, uint32_t &offset, const Polygon &polygon, const Triangulation::Changes &changes)
Definition Triangulation.cpp:10

References Slic3r::collect_duplicates(), Slic3r::count_points(), Slic3r::empty(), priv::insert_edges(), Slic3r::offset(), and triangulate().

+ Here is the call graph for this function:

◆ triangulate() [4/7]

Triangulation::Indices Triangulation::triangulate ( const ExPolygons expolygons,
const Points points,
const Changes changes 
)
static

Triangulation for expolygons containing multiple points with same coordinate.

Parameters
expolygonsInput shape to triangulation - define edge
pointsPoints from expolygons
changesChanges swap for indicies into points
Returns
Triangle indices
280{
281 assert(!points.empty());
282 assert(count_points(expolygons) == points.size());
283 assert(changes.size() == points.size());
284 // IMPROVE: search from end and somehow distiquish that value is not a change
285 uint32_t count_points = *std::max_element(changes.begin(), changes.end())+1;
286 Points pts(count_points);
287 for (size_t i = 0; i < changes.size(); i++)
288 pts[changes[i]] = points[i];
289
291 edges.reserve(points.size());
292 uint32_t offset = 0;
293 for (const ExPolygon &expolygon : expolygons) {
294 priv::insert_edges(edges, offset, expolygon.contour, changes);
295 for (const Polygon &hole : expolygon.holes)
296 priv::insert_edges(edges, offset, hole, changes);
297 }
298
299 std::sort(edges.begin(), edges.end());
300 return triangulate(pts, edges);
301}

References Slic3r::count_points(), priv::insert_edges(), Slic3r::offset(), and triangulate().

+ Here is the call graph for this function:

◆ triangulate() [5/7]

Triangulation::Indices Triangulation::triangulate ( const Points points,
const HalfEdges half_edges 
)
static

Connect points by triangulation to create filled surface by triangles Input points have to be unique Inspiration for make unique points is Emboss::dilate_to_unique_points.

Parameters
pointsPoints to connect
edgesConstraint for edges, pair is from point(first) to point(second), sorted lexicographically
Returns
Triangles
87{
88 assert(!points.empty());
89 assert(!constrained_half_edges.empty());
90 // constrained must be sorted
91 assert(std::is_sorted(constrained_half_edges.begin(),
92 constrained_half_edges.end()));
93 // check that there is no duplicit constrained edge
94 assert(std::adjacent_find(constrained_half_edges.begin(), constrained_half_edges.end()) == constrained_half_edges.end());
95 // edges can NOT contain bidirectional constrained
96 assert(!priv::has_bidirectional_constrained(constrained_half_edges));
97 // check that there is only unique poistion of points
98 assert(priv::is_unique(points));
99 assert(!priv::has_self_intersection(points, constrained_half_edges));
100 // use cgal triangulation
101 using K = CGAL::Exact_predicates_inexact_constructions_kernel;
102 using Vb = CGAL::Triangulation_vertex_base_with_info_2<uint32_t, K>;
103 using Fb = CGAL::Constrained_triangulation_face_base_2<K>;
104 using Tds = CGAL::Triangulation_data_structure_2<Vb, Fb>;
105 using CDT = CGAL::Constrained_Delaunay_triangulation_2<K, Tds, CGAL::Exact_predicates_tag>;
106
107 // construct a constrained triangulation
108 CDT cdt;
109 {
110 std::vector<CDT::Vertex_handle> vertices_handle(points.size()); // for constriants
111 using Point_with_ord = std::pair<CDT::Point, size_t>;
112 using SearchTrait = CGAL::Spatial_sort_traits_adapter_2
113 <K, CGAL::First_of_pair_property_map<Point_with_ord> >;
114
115 std::vector<Point_with_ord> cdt_points;
116 cdt_points.reserve(points.size());
117 size_t ord = 0;
118 for (const auto &p : points)
119 cdt_points.emplace_back(std::make_pair(CDT::Point{p.x(), p.y()}, ord++));
120
121 SearchTrait st;
122 CGAL::spatial_sort(cdt_points.begin(), cdt_points.end(), st);
123 CDT::Face_handle f;
124 for (const auto& p : cdt_points) {
125 auto handle = cdt.insert(p.first, f);
126 handle->info() = p.second;
127 vertices_handle[p.second] = handle;
128 f = handle->face();
129 }
130
131 // Constrain the triangulation.
132 for (const HalfEdge &edge : constrained_half_edges)
133 cdt.insert_constraint(vertices_handle[edge.first], vertices_handle[edge.second]);
134 }
135
136 auto faces = cdt.finite_face_handles();
137
138 // Unmark constrained edges of outside faces.
139 size_t num_faces = 0;
140 for (CDT::Face_handle fh : faces) {
141 for (int i = 0; i < 3; ++i) {
142 if (!fh->is_constrained(i)) continue;
143 auto key = std::make_pair(fh->vertex((i + 2) % 3)->info(), fh->vertex((i + 1) % 3)->info());
144 auto it = std::lower_bound(constrained_half_edges.begin(), constrained_half_edges.end(), key);
145 if (it == constrained_half_edges.end() || *it != key) continue;
146 // This face contains a constrained edge and it is outside.
147 for (int j = 0; j < 3; ++ j)
148 fh->set_constraint(j, false);
149 --num_faces;
150 break;
151 }
152 ++num_faces;
153 }
154
155 auto inside = [](CDT::Face_handle &fh) {
156 return fh->neighbor(0) != fh &&
157 (fh->is_constrained(0) ||
158 fh->is_constrained(1) ||
159 fh->is_constrained(2));
160 };
161
162#ifdef VISUALIZE_TRIANGULATION
163 std::vector<Vec3i> indices2;
164 indices2.reserve(num_faces);
165 for (CDT::Face_handle fh : faces)
166 if (inside(fh)) indices2.emplace_back(fh->vertex(0)->info(), fh->vertex(1)->info(), fh->vertex(2)->info());
167 visualize(points, indices2, "C:/data/temp/triangulation_without_floodfill.obj");
168#endif // VISUALIZE_TRIANGULATION
169
170 // Propagate inside the constrained regions.
171 std::vector<CDT::Face_handle> queue;
172 queue.reserve(num_faces);
173 for (CDT::Face_handle seed : faces){
174 if (!inside(seed)) continue;
175 // Seed fill to neighbor faces.
176 queue.emplace_back(seed);
177 while (! queue.empty()) {
178 CDT::Face_handle fh = queue.back();
179 queue.pop_back();
180 for (int i = 0; i < 3; ++i) {
181 if (fh->is_constrained(i)) continue;
182 // Propagate along this edge.
183 fh->set_constraint(i, true);
184 CDT::Face_handle nh = fh->neighbor(i);
185 bool was_inside = inside(nh);
186 // Mark the other side of this edge.
187 nh->set_constraint(nh->index(fh), true);
188 if (! was_inside)
189 queue.push_back(nh);
190 }
191 }
192 }
193
194 std::vector<Vec3i> indices;
195 indices.reserve(num_faces);
196 for (CDT::Face_handle fh : faces)
197 if (inside(fh))
198 indices.emplace_back(fh->vertex(0)->info(), fh->vertex(1)->info(), fh->vertex(2)->info());
199
200#ifdef VISUALIZE_TRIANGULATION
201 visualize(points, indices, "C:/data/temp/triangulation.obj");
202#endif // VISUALIZE_TRIANGULATION
203
204 return indices;
205}
std::pair< uint32_t, uint32_t > HalfEdge
Definition Triangulation.hpp:18
if(!(yy_init))
Definition lexer.c:1190
const Scalar & y
Definition MathFunctions.h:552
bool inside(const Polygons &polygons, const Point &p)
CGAL::Simple_cartesian< double > K
Definition VoronoiUtilsCgal.cpp:19
static double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
Definition FillGyroid.cpp:12
IGL_INLINE bool cdt(const Eigen::PlainObjectBase< DerivedV > &V, const Eigen::PlainObjectBase< DerivedF > &F, const CDTParam &param, Eigen::PlainObjectBase< DerivedTV > &TV, Eigen::PlainObjectBase< DerivedTT > &TT, Eigen::PlainObjectBase< DerivedTF > &TF)
Definition cdt.cpp:18
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
bool has_bidirectional_constrained(const Triangulation::HalfEdges &constrained)
Definition Triangulation.cpp:37
bool has_self_intersection(const Points &points, const Triangulation::HalfEdges &constrained_half_edges)
Definition Triangulation.cpp:56
bool is_unique(const Points &points)
Definition Triangulation.cpp:49
STL namespace.
CGAL::Triangulation_vertex_base_with_info_2< unsigned int, Kernel > Vb
Definition point_areas.cpp:17
CGAL::Triangulation_data_structure_2< Vb > Tds
Definition point_areas.cpp:18

References Slic3r::f(), priv::has_bidirectional_constrained(), priv::has_self_intersection(), and priv::is_unique().

Referenced by priv::polygons2model_duplicit(), priv::polygons2model_unique(), triangulate(), triangulate(), triangulate(), triangulate(), triangulate(), and triangulate().

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

◆ triangulate() [6/7]

Triangulation::Indices Triangulation::triangulate ( const Polygon polygon)
static
208{
209 const Points &pts = polygon.points;
211 edges.reserve(pts.size());
212 uint32_t offset = 0;
213 priv::insert_edges(edges, offset, polygon);
214 std::sort(edges.begin(), edges.end());
215 return triangulate(pts, edges);
216}
Points points
Definition MultiPoint.hpp:18

References priv::insert_edges(), Slic3r::offset(), Slic3r::MultiPoint::points, and triangulate().

+ Here is the call graph for this function:

◆ triangulate() [7/7]

Triangulation::Indices Triangulation::triangulate ( const Polygons polygons)
static
219{
220 size_t count = count_points(polygons);
221 Points points;
222 points.reserve(count);
223
225 edges.reserve(count);
226 uint32_t offset = 0;
227
228 for (const Polygon &polygon : polygons) {
229 Slic3r::append(points, polygon.points);
230 priv::insert_edges(edges, offset, polygon);
231 }
232
233 std::sort(edges.begin(), edges.end());
234 return triangulate(points, edges);
235}
void append(std::vector< T, Alloc > &dest, const std::vector< T, Alloc2 > &src)
Definition libslic3r.h:110
IGL_INLINE void count(const Eigen::SparseMatrix< XType > &X, const int dim, Eigen::SparseVector< SType > &S)
Definition count.cpp:12

References Slic3r::append(), Slic3r::count_points(), priv::insert_edges(), Slic3r::offset(), and triangulate().

+ Here is the call graph for this function:

The documentation for this class was generated from the following files: