OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::ExtrusionLoop Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/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 (const ExtrusionPath &&path, ExtrusionLoopRole role=elrDefault)
bool is_loop () const override
bool can_reverse () const override
ExtrusionEntity * clone () const override
ExtrusionEntity * clone_move () override
bool make_clockwise ()
bool make_counter_clockwise ()
bool is_clockwise ()
bool is_counter_clockwise ()
void reverse () override
Point first_point () const override
const Point3 & first_point3 () const override
Point last_point () const override
const Point3 & last_point3 () 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 set_loop_role (ExtrusionLoopRole role)
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 is_smooth (double angle_threshold=0.174, double min_arm_length=0.025) const
bool validate () const
virtual bool is_collection () const
virtual bool can_sort () const
virtual void set_reverse ()
virtual Polylines as_polylines () const

Static Public Member Functions

static std::string role_to_string (ExtrusionRole role)
static ExtrusionRole string_to_role (const std::string_view role)

Public Attributes

ExtrusionPaths paths
bool print_after_infill = false
int inset_idx = -1

Private Attributes

ExtrusionLoopRole m_loop_role

Detailed Description


Class Documentation

◆ Slic3r::ExtrusionLoop::ClosestPathPoint

struct Slic3r::ExtrusionLoop::ClosestPathPoint
Collaboration diagram for 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
476: m_loop_role(role) {}
ExtrusionRole role() const override
Definition ExtrusionEntity.hpp:512
ExtrusionLoopRole m_loop_role
Definition ExtrusionEntity.hpp:555

References Slic3r::elrDefault, m_loop_role, and role().

Referenced by Slic3r::ExtrusionLoopSloped::ExtrusionLoopSloped(), clone(), and clone_move().

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

◆ ExtrusionLoop() [2/5]

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

References Slic3r::elrDefault, m_loop_role, paths, and role().

Here is the call graph for this function:

◆ ExtrusionLoop() [3/5]

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

References Slic3r::elrDefault, m_loop_role, paths, and role().

Here is the call graph for this function:

◆ ExtrusionLoop() [4/5]

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

References Slic3r::elrDefault, m_loop_role, and role().

Here is the call graph for this function:

◆ ExtrusionLoop() [5/5]

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

References Slic3r::elrDefault, m_loop_role, and role().

Here is the call graph for this function:

Member Function Documentation

◆ as_polyline()

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

Implements Slic3r::ExtrusionEntity.

528 {
529 if (this->paths.empty() || this->length() <= 0.)
530 return Polyline();
531 return this->polygon().split_at_first_point();
532 }
Polygon polygon() const
Definition ExtrusionEntity.cpp:175
Polyline split_at_first_point() const
Definition Polygon.hpp:60

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
155{ Polylines dst; this->collect_polylines(dst); return dst; }
virtual void collect_polylines(Polylines &dst) const =0
std::vector< Polyline > Polylines
Definition Polyline.hpp:22

References collect_polylines().

Referenced by Slic3r::SupportMaterialInternal::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.

484{ return false; }

◆ can_sort()

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

Reimplemented in Slic3r::ExtrusionEntityCollection.

127{ return true; }//BBS: only used in ExtrusionEntityCollection

◆ clip_end()

void Slic3r::ExtrusionLoop::clip_end ( double distance,
ExtrusionPaths * paths ) const
331{
332 *paths = this->paths;
333
334 while (distance > 0 && !paths->empty()) {
335 ExtrusionPath &last = paths->back();
336 double len = last.length();
337 if (len <= distance) {
338 paths->pop_back();
339 distance -= len;
340 } else {
341 last.polyline.clip_end(distance);
342 break;
343 }
344 }
345}
float distance(SpiralVase::SpiralPoint a, SpiralVase::SpiralPoint b)
Definition SpiralVase.cpp:19

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

Referenced by Slic3r::GCode::extrude_loop().

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

◆ clone()

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

Implements Slic3r::ExtrusionEntity.

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

References ExtrusionLoop().

Here is the call graph for this function:

◆ clone_move()

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

Implements Slic3r::ExtrusionEntity.

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

References ExtrusionLoop().

Here is the call graph for this function:

◆ collect_points()

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

Implements Slic3r::ExtrusionEntity.

534 {
535 size_t n = std::accumulate(paths.begin(), paths.end(), 0, [](const size_t n, const ExtrusionPath &p){ return n + p.polyline.size(); });
536 dst.reserve(dst.size() + n);
537 for (const ExtrusionPath &p : this->paths)
538 append(dst, to_points(p.polyline.points));
539 }
Points to_points(const ExPolygons &src)
Definition ExPolygon.hpp:222
void append(std::vector< T, Alloc > &dest, const std::vector< T, Alloc2 > &src)
Definition libslic3r.h:157

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

Referenced by Slic3r::Skirt::find_start_point().

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

◆ collect_polylines()

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

Implements Slic3r::ExtrusionEntity.

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

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

Here is the call graph for this function:

◆ first_point()

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

Implements Slic3r::ExtrusionEntity.

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

Referenced by last_point().

Here is the caller graph for this function:

◆ first_point3()

const Point3 & Slic3r::ExtrusionLoop::first_point3 ( ) const
inlineoverridevirtual

Implements Slic3r::ExtrusionEntity.

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

Referenced by last_point3(), 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
244{
245 // Find the closest path and closest point belonging to that path. Avoid overhangs, if asked for.
246 ClosestPathPoint out{0, 0};
247 double min2 = std::numeric_limits<double>::max();
248 ClosestPathPoint best_non_overhang{0, 0};
249 double min2_non_overhang = std::numeric_limits<double>::max();
250 for (const ExtrusionPath &path : this->paths) {
251 std::pair<int, Point3> foot_pt_ = foot_pt(path.polyline.points, Point3(point));
252 Point foot_pt_2d = Point(foot_pt_.second.x(), foot_pt_.second.y());
253 double d2 = (foot_pt_2d - point).cast<double>().squaredNorm();
254 if (d2 < min2) {
255 out.foot_pt = foot_pt_2d;
256 out.path_idx = &path - &this->paths.front();
257 out.segment_idx = foot_pt_.first;
258 min2 = d2;
259 }
260 if (prefer_non_overhang && !is_bridge(path.role()) && d2 < min2_non_overhang) {
261 best_non_overhang.foot_pt = foot_pt_2d;
262 best_non_overhang.path_idx = &path - &this->paths.front();
263 best_non_overhang.segment_idx = foot_pt_.first;
264 min2_non_overhang = d2;
265 }
266 }
267 if (prefer_non_overhang && min2_non_overhang != std::numeric_limits<double>::max())
268 // Only apply the non-overhang point if there is one.
269 out = best_non_overhang;
270 return out;
271}
Definition ExtrusionEntity.hpp:502
T foot_pt(const T &line_pt, const T &line_dir, const T &pt)
Definition Geometry.hpp:186
Kernel::Point_3 Point
Definition MeshRepair.cpp:81
bool is_bridge(ExtrusionRole role)
Definition ExtrusionEntity.hpp:105
auto cast(const BoundingBoxBase< Tin > &b)
Definition BoundingBox.hpp:299

References Slic3r::cast(), Slic3r::ExtrusionLoop::ClosestPathPoint::foot_pt, Slic3r::Geometry::foot_pt(), Slic3r::is_bridge(), Slic3r::ExtrusionLoop::ClosestPathPoint::path_idx, paths, and Slic3r::ExtrusionLoop::ClosestPathPoint::segment_idx.

Referenced by Slic3r::SeamPlacer::place_seam(), and 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
348{
349 for (const ExtrusionPath &path : this->paths) {
350 int pos = path.polyline.find_point(point);
351 if (pos != -1) {
352 // point belongs to this path
353 // we consider it overhang only if it's not an endpoint
354 return (is_bridge(path.role()) && pos > 0 && pos != (int)(path.polyline.points.size())-1);
355 }
356 }
357 return false;
358}
Vec3d pos(const Pt &p)
Definition ReprojectPointsOnMesh.hpp:16

References Slic3r::is_bridge(), and paths.

Here is the call graph for this function:

◆ is_clockwise()

bool Slic3r::ExtrusionLoop::is_clockwise ( )
inline
490{ return this->polygon().is_clockwise(); }
bool is_clockwise() const
Definition Polygon.cpp:89

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

Here is the call graph for this function:

◆ is_collection()

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

◆ is_counter_clockwise()

bool Slic3r::ExtrusionLoop::is_counter_clockwise ( )
inline
491{ return this->polygon().is_counter_clockwise(); }
bool is_counter_clockwise() const
Definition Polygon.cpp:84

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

Referenced by Slic3r::GCode::extrude_loop().

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

◆ is_loop()

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

Reimplemented from Slic3r::ExtrusionEntity.

483{ return true; }

◆ is_smooth()

bool Slic3r::ExtrusionLoop::is_smooth ( double angle_threshold = 0.174,
double min_arm_length = 0.025 ) const
383{
384 // go through all the points in the loop and check if the angle between two segments(AB and BC) is less than the threshold
385 size_t idx_prev = 0;
386 size_t idx_curr = 0;
387 size_t idx_next = 0;
388
389 float distance_to_prev = 0;
390 float distance_to_next = 0;
391
392 const auto _polygon = polygon();
393 const Points& points = _polygon.points;
394
395 std::vector<float> lengths{};
396 for (size_t point_idx = 0; point_idx < points.size() - 1; ++point_idx) {
397 lengths.push_back((unscale(points[point_idx]) - unscale(points[point_idx + 1])).norm());
398 }
399 lengths.push_back(std::max((unscale(points[0]) - unscale(points[points.size() - 1])).norm(), 0.1));
400
401 // push idx_prev far enough back as initialization
402 while (distance_to_prev < min_arm_length) {
403 idx_prev = Slic3r::prev_idx_modulo(idx_prev, points.size());
404 distance_to_prev += lengths[idx_prev];
405 }
406
407 for (size_t _i = 0; _i < points.size(); ++_i) {
408 // pull idx_prev to current as much as possible, while respecting the min_arm_length
409 while (distance_to_prev - lengths[idx_prev] > min_arm_length) {
410 distance_to_prev -= lengths[idx_prev];
411 idx_prev = Slic3r::next_idx_modulo(idx_prev, points.size());
412 }
413
414 // push idx_next forward as far as needed
415 while (distance_to_next < min_arm_length) {
416 distance_to_next += lengths[idx_next];
417 idx_next = Slic3r::next_idx_modulo(idx_next, points.size());
418 }
419
420 // Calculate angle between idx_prev, idx_curr, idx_next.
421 const Point& p0 = points[idx_prev];
422 const Point& p1 = points[idx_curr];
423 const Point& p2 = points[idx_next];
424 const auto a = angle(p0 - p1, p2 - p1);
425 if (a > 0 ? a < angle_threshold : a > -angle_threshold) {
426 return false;
427 }
428
429 // increase idx_curr by one
430 float curr_distance = lengths[idx_curr];
431 idx_curr++;
432 distance_to_prev += curr_distance;
433 distance_to_next -= curr_distance;
434 }
435
436 return true;
437}
double angle(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:138
INDEX_TYPE prev_idx_modulo(INDEX_TYPE idx, const INDEX_TYPE count)
Definition Utils.hpp:445
INDEX_TYPE next_idx_modulo(INDEX_TYPE idx, const INDEX_TYPE count)
Definition Utils.hpp:453
std::vector< Point, PointsAllocator< Point > > Points
Definition Point.hpp:73
T unscale(Q v)
Definition libslic3r.h:138

References Slic3r::angle(), Slic3r::next_idx_modulo(), polygon(), Slic3r::prev_idx_modulo(), and Slic3r::unscale().

Referenced by Slic3r::GCode::extrude_loop().

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

◆ last_point()

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

Implements Slic3r::ExtrusionEntity.

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

References first_point().

Here is the call graph for this function:

◆ last_point3()

const Point3 & Slic3r::ExtrusionLoop::last_point3 ( ) const
inlineoverridevirtual

Implements Slic3r::ExtrusionEntity.

496{ assert(this->first_point3() == this->paths.back().polyline.points.back()); return this->first_point3(); }
const Point3 & first_point3() const override
Definition ExtrusionEntity.hpp:494

References first_point3().

Here is the call graph for this function:

◆ length()

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

Implements Slic3r::ExtrusionEntity.

188{
189 double len = 0;
190 for (const ExtrusionPath &path : this->paths)
191 len += path.polyline.length();
192 return len;
193}

References paths.

Referenced by Slic3r::GCode::extrude_loop(), Slic3r::GCode::extrude_support(), and Slic3r::SeamPlacer::place_seam().

Here is the caller graph for this function:

◆ loop_role()

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

References m_loop_role.

Referenced by Slic3r::convert_extrusion_to_json(), Slic3r::GCode::extrude_loop(), and Slic3r::reorient_perimeters().

Here is the caller graph for this function:

◆ make_clockwise()

bool Slic3r::ExtrusionLoop::make_clockwise ( )
155{
156 bool was_ccw = this->polygon().is_counter_clockwise();
157 if (was_ccw) this->reverse();
158 return was_ccw;
159}
void reverse() override
Definition ExtrusionEntity.cpp:168

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

Referenced by Slic3r::GCode::extrude_loop(), Slic3r::traverse_extrusions(), and Slic3r::traverse_loops().

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 ( )
162{
163 bool was_cw = this->polygon().is_clockwise();
164 if (was_cw) this->reverse();
165 return was_cw;
166}

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

Referenced by Slic3r::GCode::extrude_loop(), Slic3r::traverse_extrusions(), and Slic3r::traverse_loops().

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

◆ min_mm3_per_mm()

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

Implements Slic3r::ExtrusionEntity.

373{
374 double min_mm3_per_mm = std::numeric_limits<double>::max();
375 for (const ExtrusionPath &path : this->paths)
376 min_mm3_per_mm = std::min(min_mm3_per_mm, path.mm3_per_mm);
377 return min_mm3_per_mm;
378}
double min_mm3_per_mm() const override
Definition ExtrusionEntity.cpp:372

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
176{
178 for (const ExtrusionPath &path : this->paths) {
179 // for each polyline, append all points except the last one (because it coincides with the first one of the next polyline)
180 for (auto it = path.polyline.points.begin(); it != path.polyline.points.end() - 1; ++it) {
181 polygon.points.push_back(it->to_point());
182 }
183 }
184 return polygon;
185}
Slic3r::Polygon Polygon
Definition Emboss.cpp:101

References paths, and polygon().

Referenced by as_polyline(), Slic3r::GCode::extrude_loop(), is_clockwise(), is_counter_clockwise(), is_smooth(), 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
525 { 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:366
std::vector< Polygon, PointsAllocator< Polygon > > Polygons
Definition Polygon.hpp:22

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.

367{
368 for (const ExtrusionPath &path : this->paths)
369 path.polygons_covered_by_spacing(out, scaled_epsilon);
370}

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
523 { 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:360

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.

361{
362 for (const ExtrusionPath &path : this->paths)
363 path.polygons_covered_by_width(out, scaled_epsilon);
364}

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.

169{
170 for (ExtrusionPath &path : this->paths)
171 path.reverse();
172 std::reverse(this->paths.begin(), this->paths.end());
173}

References paths.

Referenced by make_clockwise(), make_counter_clockwise(), and Slic3r::reorient_perimeters().

Here is the caller graph for this function:

◆ role()

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

Implements Slic3r::ExtrusionEntity.

512{ return this->paths.empty() ? erNone : this->paths.front().role(); }
@ erNone
Definition ExtrusionEntity.hpp:27

References Slic3r::erNone.

Referenced by ExtrusionLoop(), ExtrusionLoop(), ExtrusionLoop(), ExtrusionLoop(), ExtrusionLoop(), Slic3r::ExtrusionLoopSloped::ExtrusionLoopSloped(), Slic3r::ExtrusionLoopSloped::clip_front(), Slic3r::GCode::extrude_loop(), Slic3r::SeamPlacer::place_seam(), and set_loop_role().

Here is the caller graph for this function:

◆ role_to_string()

std::string Slic3r::ExtrusionEntity::role_to_string ( ExtrusionRole role)
staticinherited
674{
675 switch (role) {
676 case erNone : return L("Undefined");
677 case erPerimeter : return L("Inner wall");
678 case erExternalPerimeter : return L("Outer wall");
679 case erOverhangPerimeter : return L("Overhang wall");
680 case erInternalInfill : return L("Sparse infill");
681 case erSolidInfill : return L("Internal solid infill");
682 case erTopSolidInfill : return L("Top surface");
683 case erBottomSurface : return L("Bottom surface");
684 case erIroning : return L("Ironing");
685 case erBridgeInfill : return L("Bridge");
686 case erInternalBridgeInfill : return L("Internal Bridge");
687 case erGapFill : return L("Gap infill");
688 case erSkirt : return L("Skirt");
689 case erBrim : return L("Brim");
690 case erSupportMaterial : return L("Support");
691 case erSupportMaterialInterface : return L("Support interface");
692 case erSupportTransition : return L("Support transition");
693 case erWipeTower : return L("Prime tower");
694 case erCustom : return L("Custom");
695 case erMixed : return L("Multiple");
696 default : assert(false);
697 }
698 return "";
699}
#define L(s)
Definition ExtrusionEntity.cpp:25
virtual ExtrusionRole role() const =0
@ erMixed
Definition ExtrusionEntity.hpp:47
@ erBottomSurface
Definition ExtrusionEntity.hpp:34
@ erExternalPerimeter
Definition ExtrusionEntity.hpp:29
@ erGapFill
Definition ExtrusionEntity.hpp:38
@ erCustom
Definition ExtrusionEntity.hpp:45
@ erSupportMaterialInterface
Definition ExtrusionEntity.hpp:42
@ erSupportMaterial
Definition ExtrusionEntity.hpp:41
@ erWipeTower
Definition ExtrusionEntity.hpp:44
@ erBrim
Definition ExtrusionEntity.hpp:40
@ erSolidInfill
Definition ExtrusionEntity.hpp:32
@ erBridgeInfill
Definition ExtrusionEntity.hpp:36
@ erInternalBridgeInfill
Definition ExtrusionEntity.hpp:37
@ erTopSolidInfill
Definition ExtrusionEntity.hpp:33
@ erSkirt
Definition ExtrusionEntity.hpp:39
@ erSupportTransition
Definition ExtrusionEntity.hpp:43
@ erOverhangPerimeter
Definition ExtrusionEntity.hpp:30
@ erIroning
Definition ExtrusionEntity.hpp:35
@ erPerimeter
Definition ExtrusionEntity.hpp:28
@ erInternalInfill
Definition ExtrusionEntity.hpp:31

References Slic3r::erBottomSurface, Slic3r::erBridgeInfill, Slic3r::erBrim, Slic3r::erCustom, Slic3r::erExternalPerimeter, Slic3r::erGapFill, Slic3r::erInternalBridgeInfill, Slic3r::erInternalInfill, Slic3r::erIroning, Slic3r::erMixed, Slic3r::erNone, Slic3r::erOverhangPerimeter, Slic3r::erPerimeter, Slic3r::erSkirt, Slic3r::erSolidInfill, Slic3r::erSupportMaterial, Slic3r::erSupportMaterialInterface, Slic3r::erSupportTransition, Slic3r::erTopSolidInfill, Slic3r::erWipeTower, L, and role().

Referenced by Slic3r::WipeTowerWriter::WipeTowerWriter(), Slic3r::WipeTowerWriter2::WipeTowerWriter2(), Slic3r::GCode::_do_export(), Slic3r::GCode::_extrude(), and Slic3r::anonymous_namespace{GCodeStatistics.cpp}::features_json().

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

◆ set_loop_role()

void Slic3r::ExtrusionLoop::set_loop_role ( ExtrusionLoopRole role)
inline
514{ m_loop_role = role; }

References m_loop_role, and role().

Referenced by Slic3r::convert_extrusion_from_json().

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

◆ set_reverse()

virtual void Slic3r::ExtrusionEntity::set_reverse ( )
inlinevirtualinherited

◆ split_at()

void Slic3r::ExtrusionLoop::split_at ( const Point & point,
bool prefer_non_overhang,
const double scaled_epsilon = scaled<double>(0.001) )
275{
276 if (this->paths.empty())
277 return;
278
279 auto [path_idx, segment_idx, p] = get_closest_path_and_point(point, prefer_non_overhang);
280
281 // Snap p to start or end of segment_idx if closer than scaled_epsilon.
282 {
283 const Point3 *p1 = this->paths[path_idx].polyline.points.data() + segment_idx;
284 const Point3 *p2 = p1;
285 ++p2;
286 Point p1_2d = Point(p1->x(), p1->y());
287 Point p2_2d = Point(p2->x(), p2->y());
288 double d2_1 = (point - p1_2d).cast<double>().squaredNorm();
289 double d2_2 = (point - p2_2d).cast<double>().squaredNorm();
290 const double thr2 = scaled_epsilon * scaled_epsilon;
291 if (d2_1 < d2_2) {
292 if (d2_1 < thr2) p = p1_2d;
293 } else {
294 if (d2_2 < thr2) p = p2_2d;
295 }
296 }
297
298 // now split path_idx in two parts
299 const ExtrusionPath &path = this->paths[path_idx];
300 ExtrusionPath p1(path.role(), path.mm3_per_mm, path.width, path.height);
301 ExtrusionPath p2(path.role(), path.mm3_per_mm, path.width, path.height);
302 p1.z_contoured = p2.z_contoured = path.z_contoured;
303 path.polyline.split_at(p, &p1.polyline, &p2.polyline);
304
305 if (this->paths.size() == 1) {
306 if (!p1.polyline.is_valid()) {
307 std::swap(this->paths.front().polyline.points, p2.polyline.points);
308 std::swap(this->paths.front().polyline.fitting_result, p2.polyline.fitting_result);
309 }
310 else if (!p2.polyline.is_valid()) {
311 std::swap(this->paths.front().polyline.points, p1.polyline.points);
312 std::swap(this->paths.front().polyline.fitting_result, p1.polyline.fitting_result);
313 }
314 else {
315 p2.polyline.append(std::move(p1.polyline));
316 std::swap(this->paths.front().polyline.points, p2.polyline.points);
317 std::swap(this->paths.front().polyline.fitting_result, p2.polyline.fitting_result);
318 }
319 } else {
320 // install the two paths
321 this->paths.erase(this->paths.begin() + path_idx);
322 if (p2.polyline.is_valid()) this->paths.insert(this->paths.begin() + path_idx, p2);
323 if (p1.polyline.is_valid()) this->paths.insert(this->paths.begin() + path_idx, p1);
324 }
325
326 // split at the new vertex
327 this->split_at_vertex(p);
328}
bool split_at_vertex(const Point &point, const double scaled_epsilon=scaled< double >(0.001))
Definition ExtrusionEntity.cpp:195
ClosestPathPoint get_closest_path_and_point(const Point &point, bool prefer_non_overhang) const
Definition ExtrusionEntity.cpp:243

References Slic3r::Polyline3::append(), Slic3r::cast(), Slic3r::Polyline3::fitting_result, get_closest_path_and_point(), Slic3r::ExtrusionPath::height, Slic3r::MultiPoint3::is_valid(), Slic3r::ExtrusionPath::mm3_per_mm, paths, Slic3r::MultiPoint3::points, Slic3r::ExtrusionPath::polyline, Slic3r::ExtrusionPath::role(), Slic3r::Polyline3::split_at(), split_at_vertex(), Slic3r::ExtrusionPath::width, and Slic3r::ExtrusionPath::z_contoured.

Referenced by Slic3r::GCode::extrude_loop(), and Slic3r::SeamPlacer::place_seam().

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

◆ split_at_vertex()

bool Slic3r::ExtrusionLoop::split_at_vertex ( const Point & point,
const double scaled_epsilon = scaled<double>(0.001) )
196{
197 for (ExtrusionPaths::iterator path = this->paths.begin(); path != this->paths.end(); ++path) {
198 if (int idx = path->polyline.find_point(point, scaled_epsilon); idx != -1) {
199 if (this->paths.size() == 1) {
200 // just change the order of points
201 Polyline3 p1, p2;
202 path->polyline.split_at_index(idx, &p1, &p2);
203 if (p1.is_valid() && p2.is_valid()) {
204 p2.append(std::move(p1));
205 std::swap(path->polyline.points, p2.points);
206 std::swap(path->polyline.fitting_result, p2.fitting_result);
207 }
208 } else {
209 // new paths list starts with the second half of current path
210 ExtrusionPaths new_paths;
211 Polyline3 p1, p2;
212 path->polyline.split_at_index(idx, &p1, &p2);
213 new_paths.reserve(this->paths.size() + 1);
214 {
215 ExtrusionPath p = *path;
216 std::swap(p.polyline.points, p2.points);
217 std::swap(p.polyline.fitting_result, p2.fitting_result);
218 if (p.polyline.is_valid()) new_paths.push_back(p);
219 }
220
221 // then we add all paths until the end of current path list
222 new_paths.insert(new_paths.end(), path+1, this->paths.end()); // not including this path
223
224 // then we add all paths since the beginning of current list up to the previous one
225 new_paths.insert(new_paths.end(), this->paths.begin(), path); // not including this path
226
227 // finally we add the first half of current path
228 {
229 ExtrusionPath p = *path;
230 std::swap(p.polyline.points, p1.points);
231 std::swap(p.polyline.fitting_result, p1.fitting_result);
232 if (p.polyline.is_valid()) new_paths.push_back(p);
233 }
234 // we can now override the old path list with the new one and stop looping
235 std::swap(this->paths, new_paths);
236 }
237 return true;
238 }
239 }
240 return false;
241}
std::vector< ExtrusionPath > ExtrusionPaths
Definition ExtrusionEntity.hpp:395

References Slic3r::Polyline3::append(), Slic3r::Polyline3::fitting_result, Slic3r::MultiPoint3::is_valid(), paths, Slic3r::MultiPoint3::points, Slic3r::ExtrusionPath::polyline, and Slic3r::Polyline3::split_at_index().

Referenced by Slic3r::SeamPlacer::place_seam(), and split_at().

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

◆ string_to_role()

ExtrusionRole Slic3r::ExtrusionEntity::string_to_role ( const std::string_view role)
staticinherited
702{
703 if (role == L("Inner wall"))
704 return erPerimeter;
705 else if (role == L("Outer wall"))
706 return erExternalPerimeter;
707 else if (role == L("Overhang wall"))
708 return erOverhangPerimeter;
709 else if (role == L("Sparse infill"))
710 return erInternalInfill;
711 else if (role == L("Internal solid infill"))
712 return erSolidInfill;
713 else if (role == L("Top surface"))
714 return erTopSolidInfill;
715 else if (role == L("Bottom surface"))
716 return erBottomSurface;
717 else if (role == L("Ironing"))
718 return erIroning;
719 else if (role == L("Bridge"))
720 return erBridgeInfill;
721 else if (role == L("Internal Bridge"))
723 else if (role == L("Gap infill"))
724 return erGapFill;
725 else if (role == ("Skirt"))
726 return erSkirt;
727 else if (role == ("Brim"))
728 return erBrim;
729 else if (role == L("Support"))
730 return erSupportMaterial;
731 else if (role == L("Support interface"))
733 else if (role == L("Support transition"))
734 return erSupportTransition;
735 else if (role == L("Prime tower"))
736 return erWipeTower;
737 else if (role == L("Custom"))
738 return erCustom;
739 else if (role == L("Multiple"))
740 return erMixed;
741 else
742 return erNone;
743}

References Slic3r::erBottomSurface, Slic3r::erBridgeInfill, Slic3r::erBrim, Slic3r::erCustom, Slic3r::erExternalPerimeter, Slic3r::erGapFill, Slic3r::erInternalBridgeInfill, Slic3r::erInternalInfill, Slic3r::erIroning, Slic3r::erMixed, Slic3r::erNone, Slic3r::erOverhangPerimeter, Slic3r::erPerimeter, Slic3r::erSkirt, Slic3r::erSolidInfill, Slic3r::erSupportMaterial, Slic3r::erSupportMaterialInterface, Slic3r::erSupportTransition, Slic3r::erTopSolidInfill, Slic3r::erWipeTower, L, and role().

Referenced by Slic3r::FanMover::_process_gcode_line(), and Slic3r::GCodeProcessor::process_tags().

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.

540{ double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }

References paths.

◆ validate()

bool Slic3r::ExtrusionLoop::validate ( ) const
inline
546 {
547 assert(this->first_point3() == this->paths.back().polyline.points.back());
548 for (size_t i = 1; i < paths.size(); ++ i)
549 assert(this->paths[i - 1].polyline.points.back() == this->paths[i].polyline.points.front());
550 return true;
551 }

References first_point3(), and paths.

Here is the call graph for this function:

Member Data Documentation

◆ inset_idx

◆ m_loop_role

◆ paths

◆ print_after_infill

bool Slic3r::ExtrusionLoop::print_after_infill = false

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