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

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/ExtrusionEntity.hpp>

Inheritance diagram for Slic3r::ExtrusionLoopSloped:
Collaboration diagram for Slic3r::ExtrusionLoopSloped:

Public Member Functions

 ExtrusionLoopSloped (ExtrusionPaths &original_paths, double seam_gap, double slope_min_length, double slope_max_segment_length, double start_slope_ratio, ExtrusionLoopRole role=elrDefault)
std::vector< const ExtrusionPath * > get_all_paths () const
void clip_slope (double distance, bool inter_perimeter=false)
void clip_end (const double distance)
void clip_front (const double distance)
double slope_path_length ()
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
Polygons polygons_covered_by_width (const float scaled_epsilon=0.f) const
void polygons_covered_by_spacing (Polygons &out, const float scaled_epsilon) const override
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

std::vector< ExtrusionPathSloped > starts
std::vector< ExtrusionPathSloped > ends
ExtrusionPaths paths
bool print_after_infill = false
int inset_idx = -1

Private Attributes

ExtrusionLoopRole m_loop_role

Detailed Description

Constructor & Destructor Documentation

◆ ExtrusionLoopSloped()

Slic3r::ExtrusionLoopSloped::ExtrusionLoopSloped ( ExtrusionPaths & original_paths,
double seam_gap,
double slope_min_length,
double slope_max_segment_length,
double start_slope_ratio,
ExtrusionLoopRole role = elrDefault )
514{
515 // An eighth of a common line width: the path moves by less than that at the seam.
516 trim_seam_ends(original_paths, scale_(0.05));
517 // The caller measured the loop before the trim; a scarf that covers the whole loop must still end at 1.
518 double trimmed_length = 0.;
519 for (const ExtrusionPath &path : original_paths)
520 trimmed_length += unscale_(path.length());
521 slope_min_length = std::min(slope_min_length, trimmed_length);
522
523 // create slopes
524 const auto add_slop = [this, slope_max_segment_length, seam_gap](const ExtrusionPath &path, const Polyline3 &poly, double ratio_begin, double ratio_end) {
525 if (poly.empty()) { return; }
526
527 // Ensure `slope_max_segment_length`
528 Polyline3 detailed_poly;
529 {
530 detailed_poly.append(poly.first_point());
531
532 // Recursively split the line into half until no longer than `slope_max_segment_length`
533 const std::function<void(const Line3 &)> handle_line = [slope_max_segment_length, &detailed_poly, &handle_line](const Line3 &line) {
534 if (line.length() <= slope_max_segment_length) {
535 detailed_poly.append(line.b);
536 } else {
537 // Then process left half
538 handle_line({line.a, line.midpoint()});
539 // Then process right half
540 handle_line({line.midpoint(), line.b});
541 }
542 };
543
544 for (const auto &l : poly.lines()) { handle_line(l); }
545 }
546
547 starts.emplace_back(detailed_poly, path, ExtrusionPathSloped::Slope{ratio_begin, ratio_begin}, ExtrusionPathSloped::Slope{ratio_end, ratio_end});
548
549 if (is_approx(ratio_end, 1.) && seam_gap > 0) {
550 // Remove the segments that has no extrusion
551 const auto seg_length = detailed_poly.length();
552 if (seg_length > seam_gap) {
553 // Split the segment and remove the last `seam_gap` bit
554 const Polyline3 orig = detailed_poly;
555 Polyline3 tmp;
556 orig.split_at_length(seg_length - seam_gap, &detailed_poly, &tmp);
557
558 ratio_end = lerp(ratio_begin, ratio_end, (seg_length - seam_gap) / seg_length);
559 assert(1. - ratio_end > EPSILON);
560 } else {
561 // Remove the entire segment
562 detailed_poly.clear();
563 }
564 }
565 if (!detailed_poly.empty()) { ends.emplace_back(detailed_poly, path, ExtrusionPathSloped::Slope{1., 1. - ratio_begin}, ExtrusionPathSloped::Slope{1., 1. - ratio_end}); }
566
567 };
568
569 double remaining_length = slope_min_length;
570
571 ExtrusionPaths::iterator path = original_paths.begin();
572 double start_ratio = start_slope_ratio;
573 for (; path != original_paths.end() && remaining_length > 0; ++path) {
574 const double path_len = unscale_(path->length());
575 if (path_len > remaining_length) {
576 // Split current path into slope and non-slope part
577 Polyline3 slope_path;
578 Polyline3 flat_path;
579 split_at_slope_end(path->polyline, scale_(remaining_length), slope_max_segment_length, slope_path, flat_path);
580
581 add_slop(*path, slope_path, start_ratio, 1);
582 start_ratio = 1;
583
584 if (flat_path.size() > 1)
585 paths.emplace_back(std::move(flat_path), *path);
586 remaining_length = 0;
587 } else {
588 remaining_length -= path_len;
589 const double end_ratio = lerp(1.0, start_slope_ratio, remaining_length / slope_min_length);
590 add_slop(*path, path->polyline, start_ratio, end_ratio);
591 start_ratio = end_ratio;
592 }
593 }
594 assert(remaining_length <= 0);
595 assert(start_ratio == 1.);
596
597 // Put remaining flat paths
598 paths.insert(paths.end(), path, original_paths.end());
599}
#define EPSILON
Definition ColorUtils.cpp:64
virtual ExtrusionRole role() const =0
std::vector< ExtrusionPathSloped > ends
Definition ExtrusionEntity.hpp:562
std::vector< ExtrusionPathSloped > starts
Definition ExtrusionEntity.hpp:561
ExtrusionPaths paths
Definition ExtrusionEntity.hpp:470
ExtrusionLoop(ExtrusionLoopRole role=elrDefault)
Definition ExtrusionEntity.hpp:476
#define unscale_(val)
Definition libslic3r.h:107
#define scale_(val)
Definition libslic3r.h:106
void poly(std::vector< std::pair< Vec2d, Vec2d > > &out, std::initializer_list< Vec2d > p)
Definition DesignSketchTool.cpp:7751
static void split_at_slope_end(const Polyline3 &polyline, double length, double slope_max_segment_length, Polyline3 &slope, Polyline3 &flat)
Definition ExtrusionEntity.cpp:487
ColorRGB lerp(const ColorRGB &a, const ColorRGB &b, float t)
Definition Color.cpp:244
static void trim_seam_ends(ExtrusionPaths &paths, double tolerance)
Definition ExtrusionEntity.cpp:444
constexpr bool is_approx(Number value, Number test_value, Number precision=EPSILON)
Definition libslic3r.h:320

References Slic3r::ExtrusionLoop::ExtrusionLoop(), Slic3r::Polyline3::append(), Slic3r::MultiPoint3::clear(), Slic3r::MultiPoint3::empty(), ends, EPSILON, Slic3r::is_approx(), Slic3r::MultiPoint3::length(), Slic3r::lerp(), Slic3r::ExtrusionLoop::paths, Slic3r::ExtrusionLoop::role(), scale_, Slic3r::MultiPoint3::size(), Slic3r::Polyline3::split_at_length(), Slic3r::split_at_slope_end(), starts, Slic3r::trim_seam_ends(), and unscale_.

Here is the call graph for this function:

Member Function Documentation

◆ as_polyline()

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

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
inlineoverridevirtualinherited

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() [1/2]

void Slic3r::ExtrusionLoop::clip_end ( double distance,
ExtrusionPaths * paths ) const
inherited
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:

◆ clip_end() [2/2]

void Slic3r::ExtrusionLoopSloped::clip_end ( const double distance)
625{
626 double clip_dist = distance;
627 std::vector<ExtrusionPathSloped> &ends_slope = this->ends;
628 while (clip_dist > 0 && !ends_slope.empty()) {
629 ExtrusionPathSloped &last_path = ends_slope.back();
630 double len = last_path.length();
631 if (len <= clip_dist) {
632 ends_slope.pop_back();
633 clip_dist -= len;
634 } else {
635 last_path.polyline.clip_end(clip_dist);
636 break;
637 }
638 }
639}

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

Referenced by clip_slope().

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

◆ clip_front()

void Slic3r::ExtrusionLoopSloped::clip_front ( const double distance)
642{
643 double clip_dist = distance;
644 if (this->role() == erPerimeter)
646
647 std::vector<ExtrusionPathSloped> &start_slope = this->starts;
648
649 Polyline front_inward;
650 while (distance > 0 && !start_slope.empty()) {
651 ExtrusionPathSloped &first_path = start_slope.front();
652 double len = first_path.length();
653 if (len <= clip_dist) {
654 start_slope.erase(start_slope.begin());
655 clip_dist -= len;
656 } else {
657 first_path.polyline.reverse();
658 first_path.polyline.clip_end(clip_dist);
659 first_path.polyline.reverse();
660 break;
661 }
662 }
663}
double slope_path_length()
Definition ExtrusionEntity.cpp:665
ExtrusionRole role() const override
Definition ExtrusionEntity.hpp:512
@ erPerimeter
Definition ExtrusionEntity.hpp:28
static const double slope_inner_outer_wall_gap
Definition ExtrusionEntity.cpp:29

References Slic3r::Polyline3::clip_end(), Slic3r::erPerimeter, Slic3r::ExtrusionPath::length(), Slic3r::ExtrusionPath::polyline, Slic3r::Polyline3::reverse(), Slic3r::ExtrusionLoop::role(), scale_, slope_path_length(), and starts.

Referenced by clip_slope().

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

◆ clip_slope()

void Slic3r::ExtrusionLoopSloped::clip_slope ( double distance,
bool inter_perimeter = false )
618{
619
620 this->clip_end(distance);
621 this->clip_front(distance*2);
622}
void clip_front(const double distance)
Definition ExtrusionEntity.cpp:641
void clip_end(const double distance)
Definition ExtrusionEntity.cpp:624

References clip_end(), and clip_front().

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
inlineoverridevirtualinherited

Implements Slic3r::ExtrusionEntity.

485{ return new ExtrusionLoop (*this); }

References ExtrusionLoop().

Here is the call graph for this function:

◆ clone_move()

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

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
inlineoverridevirtualinherited

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
inlineoverridevirtualinherited

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
inlineoverridevirtualinherited

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
inlineoverridevirtualinherited

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_all_paths()

std::vector< const ExtrusionPath * > Slic3r::ExtrusionLoopSloped::get_all_paths ( ) const
nodiscard
601 {
602 std::vector<const ExtrusionPath*> r;
603 r.reserve(starts.size() + paths.size() + ends.size());
604 for (const auto& p : starts) {
605 r.push_back(&p);
606 }
607 for (const auto& p : paths) {
608 r.push_back(&p);
609 }
610 for (const auto& p : ends) {
611 r.push_back(&p);
612 }
613
614 return r;
615}

References ends, Slic3r::ExtrusionLoop::paths, and starts.

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

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
inherited
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
inherited
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 ( )
inlineinherited
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 ( )
inlineinherited
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
inlineoverridevirtualinherited

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
inherited
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
inlineoverridevirtualinherited

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
inlineoverridevirtualinherited

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
overridevirtualinherited

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
inlineinherited
513{ return m_loop_role; }
ExtrusionLoopRole m_loop_role
Definition ExtrusionEntity.hpp:555

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 ( )
inherited
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 ( )
inherited
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
overridevirtualinherited

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
inherited
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
inlineinherited
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
overridevirtualinherited

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
inlineinherited
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
overridevirtualinherited

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 ( )
overridevirtualinherited

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
inlineoverridevirtualinherited

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
@ 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
@ 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)
inlineinherited
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

◆ slope_path_length()

double Slic3r::ExtrusionLoopSloped::slope_path_length ( )
665 {
666 double total_length = 0.0;
667 for (ExtrusionPathSloped start_ep : this->starts) {
668 total_length += unscale_(start_ep.length());
669 }
670 return total_length;
671}
double total_length(const Polygons &polylines)
Definition Polygon.hpp:127

References starts, Slic3r::total_length(), and unscale_.

Referenced by clip_front().

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

◆ split_at()

void Slic3r::ExtrusionLoop::split_at ( const Point & point,
bool prefer_non_overhang,
const double scaled_epsilon = scaled<double>(0.001) )
inherited
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) )
inherited
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
inlineoverridevirtualinherited

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
inlineinherited
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

◆ ends

std::vector<ExtrusionPathSloped> Slic3r::ExtrusionLoopSloped::ends

◆ inset_idx

◆ m_loop_role

ExtrusionLoopRole Slic3r::ExtrusionLoop::m_loop_role
privateinherited

◆ paths

◆ print_after_infill

bool Slic3r::ExtrusionLoop::print_after_infill = false
inherited

◆ starts

std::vector<ExtrusionPathSloped> Slic3r::ExtrusionLoopSloped::starts

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