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

#include <src/libslic3r/ExtrusionEntity.hpp>

+ Inheritance diagram for Slic3r::ExtrusionLoop:
+ Collaboration diagram for Slic3r::ExtrusionLoop:

Classes

struct  ClosestPathPoint
 

Public Member Functions

 ExtrusionLoop (ExtrusionLoopRole role=elrDefault)
 
 ExtrusionLoop (const ExtrusionPaths &paths, ExtrusionLoopRole role=elrDefault)
 
 ExtrusionLoop (ExtrusionPaths &&paths, ExtrusionLoopRole role=elrDefault)
 
 ExtrusionLoop (const ExtrusionPath &path, ExtrusionLoopRole role=elrDefault)
 
 ExtrusionLoop (ExtrusionPath &&path, ExtrusionLoopRole role=elrDefault)
 
bool is_loop () const override
 
bool can_reverse () const override
 
ExtrusionEntityclone () const override
 
ExtrusionEntityclone_move () override
 
bool make_clockwise ()
 
bool make_counter_clockwise ()
 
void reverse () override
 
const Pointfirst_point () const override
 
const Pointlast_point () const override
 
const Pointmiddle_point () const override
 
Polygon polygon () const
 
double length () const override
 
bool split_at_vertex (const Point &point, const double scaled_epsilon=scaled< double >(0.001))
 
void split_at (const Point &point, bool prefer_non_overhang, const double scaled_epsilon=scaled< double >(0.001))
 
ClosestPathPoint get_closest_path_and_point (const Point &point, bool prefer_non_overhang) const
 
void clip_end (double distance, ExtrusionPaths *paths) const
 
bool has_overhang_point (const Point &point) const
 
ExtrusionRole role () const override
 
ExtrusionLoopRole loop_role () const
 
void polygons_covered_by_width (Polygons &out, const float scaled_epsilon) const override
 
void polygons_covered_by_spacing (Polygons &out, const float scaled_epsilon) const override
 
Polygons polygons_covered_by_width (const float scaled_epsilon=0.f) const
 
Polygons polygons_covered_by_spacing (const float scaled_epsilon=0.f) const
 
double min_mm3_per_mm () const override
 
Polyline as_polyline () const override
 
void collect_polylines (Polylines &dst) const override
 
void collect_points (Points &dst) const override
 
double total_volume () const override
 
bool validate () const
 
virtual bool is_collection () const
 
virtual Polylines as_polylines () const
 

Public Attributes

ExtrusionPaths paths
 

Private Attributes

ExtrusionLoopRole m_loop_role
 

Detailed Description


Class Documentation

◆ Slic3r::ExtrusionLoop::ClosestPathPoint

struct Slic3r::ExtrusionLoop::ClosestPathPoint
Class Members
Point foot_pt
size_t path_idx
size_t segment_idx

Constructor & Destructor Documentation

◆ ExtrusionLoop() [1/5]

Slic3r::ExtrusionLoop::ExtrusionLoop ( ExtrusionLoopRole  role = elrDefault)
inline
195: m_loop_role(role) {}
ExtrusionRole role() const override
Definition ExtrusionEntity.hpp:227
ExtrusionLoopRole m_loop_role
Definition ExtrusionEntity.hpp:262

◆ ExtrusionLoop() [2/5]

Slic3r::ExtrusionLoop::ExtrusionLoop ( const ExtrusionPaths paths,
ExtrusionLoopRole  role = elrDefault 
)
inline
ExtrusionPaths paths
Definition ExtrusionEntity.hpp:193

◆ ExtrusionLoop() [3/5]

Slic3r::ExtrusionLoop::ExtrusionLoop ( ExtrusionPaths &&  paths,
ExtrusionLoopRole  role = elrDefault 
)
inline
197: paths(std::move(paths)), m_loop_role(role) {}

◆ ExtrusionLoop() [4/5]

Slic3r::ExtrusionLoop::ExtrusionLoop ( const ExtrusionPath path,
ExtrusionLoopRole  role = elrDefault 
)
inline
198 : m_loop_role(role)
199 { this->paths.push_back(path); }

◆ ExtrusionLoop() [5/5]

Slic3r::ExtrusionLoop::ExtrusionLoop ( ExtrusionPath &&  path,
ExtrusionLoopRole  role = elrDefault 
)
inline
201 { this->paths.emplace_back(std::move(path)); }

Member Function Documentation

◆ as_polyline()

Polyline Slic3r::ExtrusionLoop::as_polyline ( ) const
inlineoverridevirtual

Implements Slic3r::ExtrusionEntity.

242{ return this->polygon().split_at_first_point(); }
Polygon polygon() const
Definition ExtrusionEntity.cpp:136
Polyline split_at_first_point() const
Definition Polygon.hpp:53

References polygon(), and Slic3r::Polygon::split_at_first_point().

Referenced by collect_polylines().

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

◆ as_polylines()

virtual Polylines Slic3r::ExtrusionEntity::as_polylines ( ) const
inlinevirtualinherited
53{ Polylines dst; this->collect_polylines(dst); return dst; }
virtual void collect_polylines(Polylines &dst) const =0
std::vector< Polyline > Polylines
Definition Polyline.hpp:14

References Slic3r::ExtrusionEntity::collect_polylines().

Referenced by Slic3r::FFFSupport::remove_bridges_from_contacts().

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

◆ can_reverse()

bool Slic3r::ExtrusionLoop::can_reverse ( ) const
inlineoverridevirtual

Reimplemented from Slic3r::ExtrusionEntity.

203{ return false; }

◆ clip_end()

void Slic3r::ExtrusionLoop::clip_end ( double  distance,
ExtrusionPaths paths 
) const
274{
275 *paths = this->paths;
276
277 while (distance > 0 && !paths->empty()) {
278 ExtrusionPath &last = paths->back();
279 double len = last.length();
280 if (len <= distance) {
281 paths->pop_back();
282 distance -= len;
283 } else {
284 last.polyline.clip_end(distance);
285 break;
286 }
287 }
288}
double distance(const P &p1, const P &p2)
Definition geometry_traits.hpp:329

References Slic3r::Polyline::clip_end(), Slic3r::ExtrusionPath::length(), paths, and Slic3r::ExtrusionPath::polyline.

+ Here is the call graph for this function:

◆ clone()

ExtrusionEntity * Slic3r::ExtrusionLoop::clone ( ) const
inlineoverridevirtual

Implements Slic3r::ExtrusionEntity.

204{ return new ExtrusionLoop (*this); }
ExtrusionLoop(ExtrusionLoopRole role=elrDefault)
Definition ExtrusionEntity.hpp:195

◆ clone_move()

ExtrusionEntity * Slic3r::ExtrusionLoop::clone_move ( )
inlineoverridevirtual

Implements Slic3r::ExtrusionEntity.

206{ return new ExtrusionLoop(std::move(*this)); }

◆ collect_points()

void Slic3r::ExtrusionLoop::collect_points ( Points dst) const
inlineoverridevirtual

Implements Slic3r::ExtrusionEntity.

244 {
245 size_t n = std::accumulate(paths.begin(), paths.end(), 0, [](const size_t n, const ExtrusionPath &p){ return n + p.polyline.size(); });
246 dst.reserve(dst.size() + n);
247 for (const ExtrusionPath &p : this->paths)
248 append(dst, p.polyline.points);
249 }
void append(std::vector< T, Alloc > &dest, const std::vector< T, Alloc2 > &src)
Definition libslic3r.h:110

References Slic3r::append(), paths, Slic3r::MultiPoint::points, and Slic3r::ExtrusionPath::polyline.

+ Here is the call graph for this function:

◆ collect_polylines()

void Slic3r::ExtrusionLoop::collect_polylines ( Polylines dst) const
inlineoverridevirtual

Implements Slic3r::ExtrusionEntity.

243{ Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); }
Polyline as_polyline() const override
Definition ExtrusionEntity.hpp:242

References as_polyline(), and Slic3r::MultiPoint::empty().

+ Here is the call graph for this function:

◆ first_point()

const Point & Slic3r::ExtrusionLoop::first_point ( ) const
inlineoverridevirtual

Implements Slic3r::ExtrusionEntity.

210{ return this->paths.front().polyline.points.front(); }

Referenced by last_point(), and validate().

+ Here is the caller graph for this function:

◆ get_closest_path_and_point()

ExtrusionLoop::ClosestPathPoint Slic3r::ExtrusionLoop::get_closest_path_and_point ( const Point point,
bool  prefer_non_overhang 
) const
196{
197 // Find the closest path and closest point belonging to that path. Avoid overhangs, if asked for.
198 ClosestPathPoint out { 0, 0 };
199 double min2 = std::numeric_limits<double>::max();
200 ClosestPathPoint best_non_overhang { 0, 0 };
201 double min2_non_overhang = std::numeric_limits<double>::max();
202 for (const ExtrusionPath &path : this->paths) {
203 std::pair<int, Point> foot_pt_ = foot_pt(path.polyline.points, point);
204 double d2 = (foot_pt_.second - point).cast<double>().squaredNorm();
205 if (d2 < min2) {
206 out.foot_pt = foot_pt_.second;
207 out.path_idx = &path - &this->paths.front();
208 out.segment_idx = foot_pt_.first;
209 min2 = d2;
210 }
211 if (prefer_non_overhang && ! path.role().is_bridge() && d2 < min2_non_overhang) {
212 best_non_overhang.foot_pt = foot_pt_.second;
213 best_non_overhang.path_idx = &path - &this->paths.front();
214 best_non_overhang.segment_idx = foot_pt_.first;
215 min2_non_overhang = d2;
216 }
217 }
218 if (prefer_non_overhang && min2_non_overhang != std::numeric_limits<double>::max())
219 // Only apply the non-overhang point if there is one.
220 out = best_non_overhang;
221 return out;
222}
std::pair< int, Point > foot_pt(const Points &polyline, const Point &pt)
Definition Polyline.cpp:234

References Slic3r::foot_pt(), and paths.

Referenced by split_at().

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

◆ has_overhang_point()

bool Slic3r::ExtrusionLoop::has_overhang_point ( const Point point) const
291{
292 for (const ExtrusionPath &path : this->paths) {
293 int pos = path.polyline.find_point(point);
294 if (pos != -1) {
295 // point belongs to this path
296 // we consider it overhang only if it's not an endpoint
297 return (path.role().is_bridge() && pos > 0 && pos != int(path.polyline.points.size())-1);
298 }
299 }
300 return false;
301}
Vec3d pos(const Pt &p)
Definition ReprojectPointsOnMesh.hpp:14

References paths.

◆ is_collection()

virtual bool Slic3r::ExtrusionEntity::is_collection ( ) const
inlinevirtualinherited

Reimplemented in Slic3r::ExtrusionEntityCollection.

24{ return false; }

Referenced by Slic3r::SupportSpotsGenerator::check_extrusion_entity_stability(), Slic3r::SupportSpotsGenerator::check_stability(), Slic3r::Layer::sort_perimeters_into_islands(), and Slic3r::SupportSpotsGenerator::to_short_lines().

+ Here is the caller graph for this function:

◆ is_loop()

bool Slic3r::ExtrusionLoop::is_loop ( ) const
inlineoverridevirtual

Reimplemented from Slic3r::ExtrusionEntity.

202{ return true; }

◆ last_point()

const Point & Slic3r::ExtrusionLoop::last_point ( ) const
inlineoverridevirtual

Implements Slic3r::ExtrusionEntity.

211{ assert(this->first_point() == this->paths.back().polyline.points.back()); return this->first_point(); }
const Point & first_point() const override
Definition ExtrusionEntity.hpp:210

References first_point().

+ Here is the call graph for this function:

◆ length()

double Slic3r::ExtrusionLoop::length ( ) const
overridevirtual

Implements Slic3r::ExtrusionEntity.

147{
148 double len = 0;
149 for (const ExtrusionPath &path : this->paths)
150 len += path.polyline.length();
151 return len;
152}
double length() const override
Definition ExtrusionEntity.cpp:146

References paths.

◆ loop_role()

ExtrusionLoopRole Slic3r::ExtrusionLoop::loop_role ( ) const
inline
228{ return m_loop_role; }

References m_loop_role.

◆ make_clockwise()

bool Slic3r::ExtrusionLoop::make_clockwise ( )
116{
117 bool was_ccw = this->polygon().is_counter_clockwise();
118 if (was_ccw) this->reverse();
119 return was_ccw;
120}
void reverse() override
Definition ExtrusionEntity.cpp:129
bool is_counter_clockwise() const
Definition Polygon.cpp:68

References Slic3r::Polygon::is_counter_clockwise(), polygon(), and reverse().

Referenced by Slic3r::traverse_extrusions(), and Slic3r::traverse_loops_classic().

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

◆ make_counter_clockwise()

bool Slic3r::ExtrusionLoop::make_counter_clockwise ( )
123{
124 bool was_cw = this->polygon().is_clockwise();
125 if (was_cw) this->reverse();
126 return was_cw;
127}
bool is_clockwise() const
Definition Polygon.cpp:73

References Slic3r::Polygon::is_clockwise(), polygon(), and reverse().

Referenced by Slic3r::traverse_extrusions(), and Slic3r::traverse_loops_classic().

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

◆ middle_point()

const Point & Slic3r::ExtrusionLoop::middle_point ( ) const
inlineoverridevirtual

Implements Slic3r::ExtrusionEntity.

212{ auto& path = this->paths[this->paths.size() / 2]; return path.polyline.points[path.polyline.size() / 2]; }

◆ min_mm3_per_mm()

double Slic3r::ExtrusionLoop::min_mm3_per_mm ( ) const
overridevirtual

Implements Slic3r::ExtrusionEntity.

316{
317 double min_mm3_per_mm = std::numeric_limits<double>::max();
318 for (const ExtrusionPath &path : this->paths)
319 min_mm3_per_mm = std::min(min_mm3_per_mm, path.mm3_per_mm);
320 return min_mm3_per_mm;
321}
double min_mm3_per_mm() const override
Definition ExtrusionEntity.cpp:315
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half() min(const half &a, const half &b)
Definition Half.h:507
STL namespace.

References min_mm3_per_mm(), and paths.

Referenced by min_mm3_per_mm().

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

◆ polygon()

Polygon Slic3r::ExtrusionLoop::polygon ( ) const
137{
139 for (const ExtrusionPath &path : this->paths) {
140 // for each polyline, append all points except the last one (because it coincides with the first one of the next polyline)
141 polygon.points.insert(polygon.points.end(), path.polyline.points.begin(), path.polyline.points.end()-1);
142 }
143 return polygon;
144}
Points points
Definition MultiPoint.hpp:18
Slic3r::Polygon Polygon
Definition Emboss.cpp:34

References paths, Slic3r::MultiPoint::points, and polygon().

Referenced by as_polyline(), make_clockwise(), make_counter_clockwise(), and polygon().

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

◆ polygons_covered_by_spacing() [1/2]

Polygons Slic3r::ExtrusionLoop::polygons_covered_by_spacing ( const float  scaled_epsilon = 0.f) const
inline
239 { Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
void polygons_covered_by_spacing(Polygons &out, const float scaled_epsilon) const override
Definition ExtrusionEntity.cpp:309
std::vector< Polygon, PointsAllocator< Polygon > > Polygons
Definition Polygon.hpp:15

References polygons_covered_by_spacing().

+ Here is the call graph for this function:

◆ polygons_covered_by_spacing() [2/2]

void Slic3r::ExtrusionLoop::polygons_covered_by_spacing ( Polygons out,
const float  scaled_epsilon 
) const
overridevirtual

Implements Slic3r::ExtrusionEntity.

310{
311 for (const ExtrusionPath &path : this->paths)
312 path.polygons_covered_by_spacing(out, scaled_epsilon);
313}

References paths.

Referenced by polygons_covered_by_spacing().

+ Here is the caller graph for this function:

◆ polygons_covered_by_width() [1/2]

Polygons Slic3r::ExtrusionLoop::polygons_covered_by_width ( const float  scaled_epsilon = 0.f) const
inline
237 { Polygons out; this->polygons_covered_by_width(out, scaled_epsilon); return out; }
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const override
Definition ExtrusionEntity.cpp:303

References polygons_covered_by_width().

+ Here is the call graph for this function:

◆ polygons_covered_by_width() [2/2]

void Slic3r::ExtrusionLoop::polygons_covered_by_width ( Polygons out,
const float  scaled_epsilon 
) const
overridevirtual

Implements Slic3r::ExtrusionEntity.

304{
305 for (const ExtrusionPath &path : this->paths)
306 path.polygons_covered_by_width(out, scaled_epsilon);
307}

References paths.

Referenced by polygons_covered_by_width().

+ Here is the caller graph for this function:

◆ reverse()

void Slic3r::ExtrusionLoop::reverse ( )
overridevirtual

Implements Slic3r::ExtrusionEntity.

130{
131 for (ExtrusionPath &path : this->paths)
132 path.reverse();
133 std::reverse(this->paths.begin(), this->paths.end());
134}

References paths.

Referenced by make_clockwise(), and make_counter_clockwise().

+ Here is the caller graph for this function:

◆ role()

ExtrusionRole Slic3r::ExtrusionLoop::role ( ) const
inlineoverridevirtual

Implements Slic3r::ExtrusionEntity.

227{ return this->paths.empty() ? ExtrusionRole::None : this->paths.front().role(); }
static constexpr const ExtrusionRoleModifiers None
Definition ExtrusionRole.hpp:47

References Slic3r::ExtrusionRole::None.

◆ split_at()

void Slic3r::ExtrusionLoop::split_at ( const Point point,
bool  prefer_non_overhang,
const double  scaled_epsilon = scaled<double>(0.001) 
)
226{
227 if (this->paths.empty())
228 return;
229
230 auto [path_idx, segment_idx, p] = get_closest_path_and_point(point, prefer_non_overhang);
231
232 // Snap p to start or end of segment_idx if closer than scaled_epsilon.
233 {
234 const Point *p1 = this->paths[path_idx].polyline.points.data() + segment_idx;
235 const Point *p2 = p1;
236 ++ p2;
237 double d2_1 = (point - *p1).cast<double>().squaredNorm();
238 double d2_2 = (point - *p2).cast<double>().squaredNorm();
239 const double thr2 = scaled_epsilon * scaled_epsilon;
240 if (d2_1 < d2_2) {
241 if (d2_1 < thr2)
242 p = *p1;
243 } else {
244 if (d2_2 < thr2)
245 p = *p2;
246 }
247 }
248
249 // now split path_idx in two parts
250 const ExtrusionPath &path = this->paths[path_idx];
251 ExtrusionPath p1(path.role(), path.mm3_per_mm, path.width, path.height);
252 ExtrusionPath p2(path.role(), path.mm3_per_mm, path.width, path.height);
253 path.polyline.split_at(p, &p1.polyline, &p2.polyline);
254
255 if (this->paths.size() == 1) {
256 if (p2.polyline.is_valid()) {
257 if (p1.polyline.is_valid())
258 p2.polyline.points.insert(p2.polyline.points.end(), p1.polyline.points.begin() + 1, p1.polyline.points.end());
259 this->paths.front().polyline.points = std::move(p2.polyline.points);
260 } else
261 this->paths.front().polyline.points = std::move(p1.polyline.points);
262 } else {
263 // install the two paths
264 this->paths.erase(this->paths.begin() + path_idx);
265 if (p2.polyline.is_valid()) this->paths.insert(this->paths.begin() + path_idx, p2);
266 if (p1.polyline.is_valid()) this->paths.insert(this->paths.begin() + path_idx, p1);
267 }
268
269 // split at the new vertex
270 this->split_at_vertex(p, 0.);
271}
bool split_at_vertex(const Point &point, const double scaled_epsilon=scaled< double >(0.001))
Definition ExtrusionEntity.cpp:154
ClosestPathPoint get_closest_path_and_point(const Point &point, bool prefer_non_overhang) const
Definition ExtrusionEntity.cpp:195
Kernel::Point_2 Point
Definition point_areas.cpp:20

References get_closest_path_and_point(), Slic3r::ExtrusionPath::height, Slic3r::MultiPoint::is_valid(), Slic3r::ExtrusionPath::mm3_per_mm, paths, Slic3r::MultiPoint::points, Slic3r::ExtrusionPath::polyline, Slic3r::ExtrusionPath::role(), Slic3r::Polyline::split_at(), split_at_vertex(), and Slic3r::ExtrusionPath::width.

+ Here is the call graph for this function:

◆ split_at_vertex()

bool Slic3r::ExtrusionLoop::split_at_vertex ( const Point point,
const double  scaled_epsilon = scaled<double>(0.001) 
)
155{
156 for (ExtrusionPaths::iterator path = this->paths.begin(); path != this->paths.end(); ++path)
157 if (int idx = path->polyline.find_point(point, scaled_epsilon); idx != -1) {
158 if (this->paths.size() == 1) {
159 // just change the order of points
160 path->polyline.points.insert(path->polyline.points.end(), path->polyline.points.begin() + 1, path->polyline.points.begin() + idx + 1);
161 path->polyline.points.erase(path->polyline.points.begin(), path->polyline.points.begin() + idx);
162 } else {
163 // new paths list starts with the second half of current path
164 ExtrusionPaths new_paths;
165 new_paths.reserve(this->paths.size() + 1);
166 {
167 ExtrusionPath p = *path;
168 p.polyline.points.erase(p.polyline.points.begin(), p.polyline.points.begin() + idx);
169 if (p.polyline.is_valid())
170 new_paths.emplace_back(std::move(p));
171 }
172
173 // then we add all paths until the end of current path list
174 std::move(path + 1, this->paths.end(), std::back_inserter(new_paths)); // not including this path
175
176 // then we add all paths since the beginning of current list up to the previous one
177 std::move(this->paths.begin(), path, std::back_inserter(new_paths)); // not including this path
178
179 // finally we add the first half of current path
180 {
181 ExtrusionPath &p = *path;
182 p.polyline.points.erase(p.polyline.points.begin() + idx + 1, p.polyline.points.end());
183 if (p.polyline.is_valid())
184 new_paths.emplace_back(std::move(p));
185 }
186 // we can now override the old path list with the new one and stop looping
187 this->paths = std::move(new_paths);
188 }
189 return true;
190 }
191 // The point was not found.
192 return false;
193}
std::vector< ExtrusionPath > ExtrusionPaths
Definition ExtrusionEntity.hpp:135

References Slic3r::MultiPoint::is_valid(), paths, Slic3r::MultiPoint::points, and Slic3r::ExtrusionPath::polyline.

Referenced by split_at().

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

◆ total_volume()

double Slic3r::ExtrusionLoop::total_volume ( ) const
inlineoverridevirtual

Implements Slic3r::ExtrusionEntity.

250{ double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
double total_volume() const override
Definition ExtrusionEntity.hpp:250
IGL_INLINE void volume(const Eigen::MatrixBase< DerivedV > &V, const Eigen::MatrixBase< DerivedT > &T, Eigen::PlainObjectBase< Derivedvol > &vol)
Definition volume.cpp:15

References paths.

◆ validate()

bool Slic3r::ExtrusionLoop::validate ( ) const
inline
253 {
254 assert(this->first_point() == this->paths.back().polyline.points.back());
255 for (size_t i = 1; i < paths.size(); ++ i)
256 assert(this->paths[i - 1].polyline.points.back() == this->paths[i].polyline.points.front());
257 return true;
258 }

References first_point(), and paths.

+ Here is the call graph for this function:

Member Data Documentation

◆ m_loop_role

ExtrusionLoopRole Slic3r::ExtrusionLoop::m_loop_role
private

Referenced by loop_role().

◆ paths


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