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

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

Inheritance diagram for Slic3r::Polyline3:
Collaboration diagram for Slic3r::Polyline3:

Public Member Functions

 Polyline3 ()
 Polyline3 (const Points3 &points)
 Polyline3 (const Polyline &poly, coord_t z=0)
virtual Lines3 lines () const
Polyline to_polyline () const
void clip_end (double distance)
void simplify (double tolerance)
void simplify_by_fitting_arc (double tolerance)
void reverse ()
bool split_at_index (const size_t index, Polyline3 *p1, Polyline3 *p2) const
void split_at (Point &point, Polyline3 *p1, Polyline3 *p2) const
void split_at (Point3 &point, Polyline3 *p1, Polyline3 *p2) const
bool split_at_length (const double length, Polyline3 *p1, Polyline3 *p2) const
void append (const Point3 &point)
void append (const Polyline3 &src)
void append_before (const Point3 &point)
void append (const Vec3crd &point)
void append (const Points3::const_iterator &begin, const Points3::const_iterator &end)
void translate (double x, double y, double z=0)
void translate (const Point3 &vector)
void rotate (double angle)
void rotate (double cos_angle, double sin_angle)
void rotate (double angle, const Point3 &center)
Point3 & first_point ()
const Point3 & first_point () const
Point3 & last_point ()
const Point3 & last_point () const
size_t size () const
bool empty () const
void clear ()
auto begin ()
auto begin () const
auto end ()
auto end () const
double length () const
bool is_valid () const
BoundingBox3 bounding_box () const
int find_point (const Point &point) const
int find_point (const Point &point, const double scaled_epsilon) const
int find_point (const Point3 &point) const
int find_point (const Point3 &point, const double scaled_epsilon) const
bool remove_duplicate_points ()

Static Public Member Functions

static Points3 _douglas_peucker (const Points3 &points, double tolerance)

Public Attributes

std::vector< PathFittingData > fitting_result
Points3 points

Private Member Functions

void append_fitting_result_after_append_points ()
void append_fitting_result_after_append_polyline (const Polyline3 &src)
bool split_fitting_result_before_index (size_t index, Point3 &new_endpoint, std::vector< PathFittingData > &result) const
bool split_fitting_result_after_index (size_t index, Point3 &new_startpoint, std::vector< PathFittingData > &result) const

Detailed Description

Constructor & Destructor Documentation

◆ Polyline3() [1/3]

Slic3r::Polyline3::Polyline3 ( )
inline
300{}

Referenced by append(), append_fitting_result_after_append_polyline(), split_at(), split_at(), split_at_index(), and split_at_length().

Here is the caller graph for this function:

◆ Polyline3() [2/3]

Slic3r::Polyline3::Polyline3 ( const Points3 & points)
inlineexplicit
301{ this->points = points; }
Points3 points
Definition MultiPoint.hpp:129

References Slic3r::MultiPoint3::points.

◆ Polyline3() [3/3]

Slic3r::Polyline3::Polyline3 ( const Polyline & poly,
coord_t z = 0 )
inlineexplicit
302 {
303 this->points.reserve(poly.points.size());
304 for (const Point &pt : poly.points) {
305 this->points.emplace_back(pt.x(), pt.y(), z);
306 }
307 }
void poly(std::vector< std::pair< Vec2d, Vec2d > > &out, std::initializer_list< Vec2d > p)
Definition DesignSketchTool.cpp:7751

References Slic3r::MultiPoint3::points.

Member Function Documentation

◆ _douglas_peucker()

Points3 Slic3r::MultiPoint3::_douglas_peucker ( const Points3 & points,
double tolerance )
staticinherited
478{
479 Points3 result_pts;
480 double tolerance_sq = tolerance * tolerance;
481 if (!pts.empty()) {
482 const Point3* anchor = &pts.front();
483 size_t anchor_idx = 0;
484 const Point3* floater = &pts.back();
485 size_t floater_idx = pts.size() - 1;
486 result_pts.reserve(pts.size());
487 result_pts.emplace_back(*anchor);
488 if (anchor_idx != floater_idx) {
489 assert(pts.size() > 1);
490 std::vector<size_t> dpStack;
491 dpStack.reserve(pts.size());
492 dpStack.emplace_back(floater_idx);
493 for (;;) {
494 double max_dist_sq = 0.0;
495 size_t furthest_idx = anchor_idx;
496 // find point furthest from line seg created by (anchor, floater) and note it
497 for (size_t i = anchor_idx + 1; i < floater_idx; ++i) {
498 double dist_sq = Line3::distance_to_squared(pts[i], *anchor, *floater);
499 if (dist_sq > max_dist_sq) {
500 max_dist_sq = dist_sq;
501 furthest_idx = i;
502 }
503 }
504 // remove point if less than tolerance
505 if (max_dist_sq <= tolerance_sq) {
506 result_pts.emplace_back(*floater);
507 anchor_idx = floater_idx;
508 anchor = floater;
509 assert(dpStack.back() == floater_idx);
510 dpStack.pop_back();
511 if (dpStack.empty())
512 break;
513 floater_idx = dpStack.back();
514 } else {
515 floater_idx = furthest_idx;
516 dpStack.emplace_back(floater_idx);
517 }
518 floater = &pts[floater_idx];
519 }
520 }
521 assert(result_pts.front() == pts.front());
522 assert(result_pts.back() == pts.back());
523
524#if 0
525 {
526 static int iRun = 0;
527 BoundingBox bbox(pts);
528 BoundingBox bbox2(result_pts);
529 bbox.merge(bbox2);
530 SVG svg(debug_out_path("douglas_peucker_%d.svg", iRun ++).c_str(), bbox);
531 if (pts.front() == pts.back())
532 svg.draw(Polygon(pts), "black");
533 else
534 svg.draw(Polyline(pts), "black");
535 if (result_pts.front() == result_pts.back())
536 svg.draw(Polygon(result_pts), "green", scale_(0.1));
537 else
538 svg.draw(Polyline(result_pts), "green", scale_(0.1));
539 }
540#endif
541 }
542 return result_pts;
543}
static double distance_to_squared(const Point3 &point, const Point3 &a, const Point3 &b)
Definition Line.hpp:242
#define scale_(val)
Definition libslic3r.h:106
std::string debug_out_path(const char *name,...)
Definition utils.cpp:382
std::vector< Point3, PointsAllocator< Point3 > > Points3
Definition Point.hpp:76
Slic3r::Polygon Polygon
Definition Emboss.cpp:101

References Slic3r::debug_out_path(), Slic3r::Line3::distance_to_squared(), Slic3r::SVG::draw(), Slic3r::BoundingBoxBase< PointType, APointsType >::merge(), and scale_.

Referenced by Slic3r::Polyline3::simplify().

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

◆ append() [1/4]

void Slic3r::MultiPoint3::append ( const Points3::const_iterator & begin,
const Points3::const_iterator & end )
inlineinherited
134 {
135 this->points.insert(this->points.end(), begin, end);
136 }
auto begin()
Definition MultiPoint.hpp:153
auto end()
Definition MultiPoint.hpp:154

References begin(), and end().

Here is the call graph for this function:

◆ append() [2/4]

void Slic3r::MultiPoint3::append ( const Vec3crd & point)
inlineinherited
132{ this->points.push_back(Point3(point)); }

◆ append() [3/4]

void Slic3r::Polyline3::append ( const Point3 & point)
799{
800 // // Don't append if same as last point
801 // if (!this->empty() && this->last_point() == point)
802 // return;
803
804 // this->points.push_back(point);
805 // append_fitting_result_after_append_points();
806
807 // BBS: don't need to append same point
808 if (!this->empty() && this->last_point() == point)
809 return;
810 MultiPoint3::append(point);
812}
bool empty() const
Definition MultiPoint.hpp:150
void append(const Point3 &point)
Definition MultiPoint.hpp:131
Point3 & last_point()
Definition MultiPoint.hpp:146
void append_fitting_result_after_append_points()
Definition Polyline.cpp:1017

References Slic3r::MultiPoint3::append(), append_fitting_result_after_append_points(), Slic3r::MultiPoint3::empty(), and Slic3r::MultiPoint3::last_point().

Referenced by Slic3r::ExtrusionLoopSloped::ExtrusionLoopSloped(), append(), append_before(), Slic3r::contour_extrusion_path(), Slic3r::modulate_extrusion_by_overlapping_layers(), Slic3r::ExtrusionLoop::split_at(), split_at(), split_at_index(), split_at_length(), Slic3r::ExtrusionLoop::split_at_vertex(), Slic3r::thick_polyline_to_extrusion_paths_2(), and Slic3r::thick_polyline_to_multi_path().

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

◆ append() [4/4]

void Slic3r::Polyline3::append ( const Polyline3 & src)
815{
816 if (!src.is_valid()) return;
817
818 if (this->points.empty()) {
819 this->points = src.points;
820 this->fitting_result = src.fitting_result;
821 } else {
822 // BBS: append the first point to create connection first, update the fitting date as well
823 this->append(src.points[0]);
824 // BBS: append a polyline which has fitting data to a polyline without fitting data.
825 // Then create a fake fitting data first, so that we can keep the fitting data in last polyline
826 if (this->fitting_result.empty() && !src.fitting_result.empty()) {
827 this->fitting_result.emplace_back(PathFittingData{0, this->points.size() - 1, EMovePathType::Linear_move, ArcSegment()});
828 }
829 // BBS: then append the remain points
830 MultiPoint3::append(src.points.begin() + 1, src.points.end());
831 // BBS: finally append the fitting data
833 }
834}
void append_fitting_result_after_append_polyline(const Polyline3 &src)
Definition Polyline.cpp:1031
std::vector< PathFittingData > fitting_result
Definition Polyline.hpp:350
void append(const Point3 &point)
Definition Polyline.cpp:798
@ Linear_move
Definition ArcFitter.hpp:15

References Polyline3(), Slic3r::MultiPoint3::append(), append(), append_fitting_result_after_append_polyline(), fitting_result, Slic3r::MultiPoint3::is_valid(), Slic3r::Linear_move, and Slic3r::MultiPoint3::points.

Here is the call graph for this function:

◆ append_before()

void Slic3r::Polyline3::append_before ( const Point3 & point)
837{
838 // BBS: don't need to append same point
839 if (!this->empty() && this->first_point() == point)
840 return;
841 if (this->size() == 1) {
842 this->fitting_result.clear();
843 MultiPoint3::append(point);
845 } else {
846 this->reverse();
847 this->append(point);
848 this->reverse();
849 }
850}
size_t size() const
Definition MultiPoint.hpp:149
void reverse()
Definition MultiPoint.hpp:140
Point3 & first_point()
Definition MultiPoint.hpp:145
void reverse()
Definition Polyline.cpp:749

References Slic3r::MultiPoint3::append(), append(), Slic3r::MultiPoint3::empty(), Slic3r::MultiPoint3::first_point(), fitting_result, Slic3r::MultiPoint3::reverse(), reverse(), and Slic3r::MultiPoint3::size().

Referenced by split_at(), and split_at_length().

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

◆ append_fitting_result_after_append_points()

void Slic3r::Polyline3::append_fitting_result_after_append_points ( )
private
1018{
1019 if (!fitting_result.empty()) {
1020 if (fitting_result.back().is_linear_move()) {
1021 fitting_result.back().end_point_index = this->points.size() - 1;
1022 } else {
1023 size_t new_start = fitting_result.back().end_point_index;
1024 size_t new_end = this->points.size() - 1;
1025 if (new_start != new_end)
1026 fitting_result.emplace_back(PathFittingData{new_start, new_end, EMovePathType::Linear_move, ArcSegment()});
1027 }
1028 }
1029}

References fitting_result, Slic3r::Linear_move, and Slic3r::MultiPoint3::points.

Referenced by append().

Here is the caller graph for this function:

◆ append_fitting_result_after_append_polyline()

void Slic3r::Polyline3::append_fitting_result_after_append_polyline ( const Polyline3 & src)
private
1032{
1033 if (!this->fitting_result.empty()) {
1034 // BBS: offset and save the fitting_result from src polyline
1035 if (!src.fitting_result.empty()) {
1036 size_t old_size = this->fitting_result.size();
1037 size_t index_offset = this->fitting_result.back().end_point_index;
1038 this->fitting_result.insert(this->fitting_result.end(), src.fitting_result.begin(), src.fitting_result.end());
1039 for (size_t i = old_size; i < this->fitting_result.size(); i++) {
1040 this->fitting_result[i].start_point_index += index_offset;
1041 this->fitting_result[i].end_point_index += index_offset;
1042 }
1043 } else {
1044 // BBS: the append polyline has no fitting data, then append as linear move directly
1045 size_t new_start = this->fitting_result.back().end_point_index;
1046 size_t new_end = this->size() - 1;
1047 if (new_start != new_end)
1048 this->fitting_result.emplace_back(PathFittingData{new_start, new_end, EMovePathType::Linear_move, ArcSegment()});
1049 }
1050 }
1051}

References Polyline3(), fitting_result, Slic3r::Linear_move, and Slic3r::MultiPoint3::size().

Referenced by append().

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

◆ begin() [1/2]

auto Slic3r::MultiPoint3::begin ( )
inlineinherited
153{ return this->points.begin(); }

Referenced by append(), and Slic3r::Polyline3::split_at_index().

Here is the caller graph for this function:

◆ begin() [2/2]

auto Slic3r::MultiPoint3::begin ( ) const
inlineinherited
155{ return this->points.begin(); }

◆ bounding_box()

BoundingBox3 Slic3r::MultiPoint3::bounding_box ( ) const
inherited
452{ return BoundingBox3(this->points); }

References points.

◆ clear()

void Slic3r::MultiPoint3::clear ( )
inlineinherited
151{ this->points.clear(); }

Referenced by Slic3r::ExtrusionLoopSloped::ExtrusionLoopSloped(), Slic3r::FakeWipeTower::getFakeExtrusionPathsFromWipeTower2(), Slic3r::Polyline3::split_at_index(), and Slic3r::Polyline3::split_at_length().

Here is the caller graph for this function:

◆ clip_end()

void Slic3r::Polyline3::clip_end ( double distance)
693{
694 bool last_point_inserted = false;
695 size_t remove_after_index = MultiPoint3::size();
696 while (distance > 0) {
697 Vec3d last_point = this->last_point().cast<double>();
698 this->points.pop_back();
699 remove_after_index--;
700 if (this->points.empty()) {
701 this->fitting_result.clear();
702 return;
703 }
704 Vec3d v = this->last_point().cast<double>() - last_point;
705 double lsqr = v.squaredNorm();
706 if (lsqr > distance * distance) {
707 this->points.emplace_back((last_point + v * (distance / sqrt(lsqr))).cast<coord_t>());
708 last_point_inserted = true;
709 break;
710 }
711 distance -= sqrt(lsqr);
712 }
713
714 // BBS: don't need to clip fitting result if it's empty
715 if (fitting_result.empty())
716 return;
717 while (!fitting_result.empty() && fitting_result.back().start_point_index >= remove_after_index)
718 fitting_result.pop_back();
719 if (!fitting_result.empty()) {
720 // BBS: last remaining segment is arc move, then clip the arc at last point
721 if (fitting_result.back().path_type == EMovePathType::Arc_move_ccw ||
722 fitting_result.back().path_type == EMovePathType::Arc_move_cw) {
723 if (fitting_result.back().arc_data.clip_end(this->last_point().to_point()))
724 // BBS: succeed to clip arc, then update the last point
725 // TODO: fix z parameter
726 this->points.back() = Point3(fitting_result.back().arc_data.end_point, this->points.back().z());
727 else
728 // BBS: Failed to clip arc, then back to linear move
730 }
731 fitting_result.back().end_point_index = this->points.size() - 1;
732 }
733}
float distance(SpiralVase::SpiralPoint a, SpiralVase::SpiralPoint b)
Definition SpiralVase.cpp:19
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68
@ Arc_move_cw
Definition ArcFitter.hpp:16
@ Arc_move_ccw
Definition ArcFitter.hpp:17
auto cast(const BoundingBoxBase< Tin > &b)
Definition BoundingBox.hpp:299

References Slic3r::Arc_move_ccw, Slic3r::Arc_move_cw, Slic3r::cast(), fitting_result, Slic3r::MultiPoint3::last_point(), Slic3r::Linear_move, Slic3r::MultiPoint3::points, and Slic3r::MultiPoint3::size().

Referenced by Slic3r::ExtrusionLoop::clip_end(), Slic3r::ExtrusionLoopSloped::clip_end(), and Slic3r::ExtrusionLoopSloped::clip_front().

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

◆ empty()

bool Slic3r::MultiPoint3::empty ( ) const
inlineinherited

◆ end() [1/2]

auto Slic3r::MultiPoint3::end ( )
inlineinherited
154{ return this->points.end(); }

Referenced by append().

Here is the caller graph for this function:

◆ end() [2/2]

auto Slic3r::MultiPoint3::end ( ) const
inlineinherited
156{ return this->points.end(); }

◆ find_point() [1/4]

int Slic3r::MultiPoint3::find_point ( const Point & point) const
inherited
613{
614 for (const Point3 &pt : this->points)
615 if (pt.to_point() == point)
616 return int(&pt - &this->points.front());
617 return -1; // not found
618}

References points.

Referenced by find_point(), find_point(), Slic3r::Polyline3::split_at(), and Slic3r::Polyline3::split_at_length().

Here is the caller graph for this function:

◆ find_point() [2/4]

int Slic3r::MultiPoint3::find_point ( const Point & point,
const double scaled_epsilon ) const
inherited
621{
622 if (scaled_epsilon == 0) return this->find_point(point);
623
624 auto dist2_min = std::numeric_limits<double>::max();
625 auto eps2 = scaled_epsilon * scaled_epsilon;
626 int idx_min = -1;
627 for (const Point3 &pt : this->points) {
628 double d2 = (pt.to_point() - point).cast<double>().squaredNorm();
629 if (d2 < dist2_min) {
630 idx_min = int(&pt - &this->points.front());
631 dist2_min = d2;
632 }
633 }
634 return (dist2_min < eps2) ? idx_min : -1;
635}
int find_point(const Point &point) const
Definition MultiPoint.cpp:612

References find_point(), and points.

Here is the call graph for this function:

◆ find_point() [3/4]

int Slic3r::MultiPoint3::find_point ( const Point3 & point) const
inherited
638{
639 for (const Point3 &pt : this->points)
640 if (pt == point)
641 return int(&pt - &this->points.front());
642 return -1; // not found
643}

References points.

◆ find_point() [4/4]

int Slic3r::MultiPoint3::find_point ( const Point3 & point,
const double scaled_epsilon ) const
inherited
646{
647 if (scaled_epsilon == 0) return this->find_point(point);
648
649 auto dist2_min = std::numeric_limits<double>::max();
650 auto eps2 = scaled_epsilon * scaled_epsilon;
651 int idx_min = -1;
652 for (const Point3 &pt : this->points) {
653 double d2 = (pt - point).cast<double>().squaredNorm();
654 if (d2 < dist2_min) {
655 idx_min = int(&pt - &this->points.front());
656 dist2_min = d2;
657 }
658 }
659 return (dist2_min < eps2) ? idx_min : -1;
660}

References Slic3r::cast(), find_point(), and points.

Here is the call graph for this function:

◆ first_point() [1/2]

Point3 & Slic3r::MultiPoint3::first_point ( )
inlineinherited
145{ return this->points.front(); }

Referenced by Slic3r::Polyline3::append_before(), Slic3r::Polyline3::split_at(), Slic3r::Polyline3::split_at_index(), and Slic3r::Polyline3::split_at_length().

Here is the caller graph for this function:

◆ first_point() [2/2]

const Point3 & Slic3r::MultiPoint3::first_point ( ) const
inlineinherited
147{ return this->points.front(); }

◆ is_valid()

bool Slic3r::MultiPoint3::is_valid ( ) const
inlineinherited
160{ return this->points.size() >= 2; }

Referenced by Slic3r::Polyline3::append(), Slic3r::ExtrusionLoop::split_at(), Slic3r::Polyline3::split_at(), Slic3r::ExtrusionLoop::split_at_vertex(), and Slic3r::thick_polyline_to_multi_path().

Here is the caller graph for this function:

◆ last_point() [1/2]

Point3 & Slic3r::MultiPoint3::last_point ( )
inlineinherited
146{ return this->points.back(); }

Referenced by Slic3r::Polyline3::append(), Slic3r::Polyline3::clip_end(), Slic3r::Polyline3::split_at(), Slic3r::Polyline3::split_at_index(), and Slic3r::Polyline3::split_at_length().

Here is the caller graph for this function:

◆ last_point() [2/2]

const Point3 & Slic3r::MultiPoint3::last_point ( ) const
inlineinherited
148{ return this->points.back(); }

◆ length()

double Slic3r::MultiPoint3::length ( ) const
inherited
443{
444 const Lines3& lines = this->lines();
445 double len = 0;
446 for (auto it = lines.cbegin(); it != lines.cend(); ++it) {
447 len += it->length();
448 }
449 return len;
450}
virtual Lines3 lines() const =0
std::vector< Line3 > Lines3
Definition Line.hpp:21

References lines().

Referenced by Slic3r::ExtrusionLoopSloped::ExtrusionLoopSloped(), Slic3r::GCode::_extrude(), and Slic3r::Polyline3::split_at_length().

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

◆ lines()

Lines3 Slic3r::Polyline3::lines ( ) const
virtual

Implements Slic3r::MultiPoint3.

671{
673 if (this->points.size() >= 2) {
674 lines.reserve(this->points.size() - 1);
675 for (Points3::const_iterator it = this->points.begin(); it != this->points.end() - 1; ++it) {
676 lines.emplace_back(*it, *(it + 1));
677 }
678 }
679 return lines;
680}
virtual Lines3 lines() const
Definition Polyline.cpp:670

References lines(), and Slic3r::MultiPoint3::points.

Referenced by Slic3r::GCode::_extrude(), lines(), split_at(), split_at_length(), and Slic3r::split_at_slope_end().

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

◆ remove_duplicate_points()

bool Slic3r::MultiPoint3::remove_duplicate_points ( )
inherited
455{
456 size_t j = 0;
457 for (size_t i = 1; i < points.size(); ++i) {
458 if (points[j] == points[i]) {
459 // Just increase index i.
460 } else {
461 ++ j;
462 if (j < i)
463 points[j] = points[i];
464 }
465 }
466
467 if (++j < points.size())
468 {
469 points.erase(points.begin() + j, points.end());
470 return true;
471 }
472
473 return false;
474}

References points.

◆ reverse()

void Slic3r::Polyline3::reverse ( )
750{
751 // BBS: reverse points
753 // BBS: reverse the fitting_result
754 if (!this->fitting_result.empty()) {
755 for (size_t i = 0; i < this->fitting_result.size(); i++) {
756 std::swap(fitting_result[i].start_point_index, fitting_result[i].end_point_index);
757 fitting_result[i].start_point_index = MultiPoint3::size() - 1 - fitting_result[i].start_point_index;
758 fitting_result[i].end_point_index = MultiPoint3::size() - 1 - fitting_result[i].end_point_index;
759 if (fitting_result[i].is_arc_move())
760 fitting_result[i].reverse_arc_path();
761 }
762 std::reverse(this->fitting_result.begin(), this->fitting_result.end());
763 }
764}

References fitting_result, Slic3r::MultiPoint3::reverse(), and Slic3r::MultiPoint3::size().

Referenced by append_before(), Slic3r::ExtrusionLoopSloped::clip_front(), and Slic3r::ExtrusionPath::reverse().

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

◆ rotate() [1/3]

void Slic3r::MultiPoint3::rotate ( double angle)
inlineinherited
141{ this->rotate(cos(angle), sin(angle)); }
void rotate(double angle)
Definition MultiPoint.hpp:141
double angle(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:138

References Slic3r::angle(), and rotate().

Referenced by rotate().

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

◆ rotate() [2/3]

void Slic3r::MultiPoint3::rotate ( double angle,
const Point3 & center )
inherited
601{
602 double s = sin(angle);
603 double c = cos(angle);
604 for (Point3 &pt : points) {
605 Vec3crd v(pt - center);
606 pt(0) = (coord_t)round(double(center(0)) + c * v[0] - s * v[1]);
607 pt(1) = (coord_t)round(double(center(1)) + c * v[1] + s * v[0]);
608 // Keep Z unchanged from original point
609 }
610}
int64_t coord_t
Definition libslic3r.h:48
void center(ExPolygonsWithIds &e)
Definition Emboss.cpp:1382
Eigen::Matrix< coord_t, 3, 1, Eigen::DontAlign > Vec3crd
Definition Point.hpp:53

References Slic3r::angle(), Slic3r::center(), and points.

Here is the call graph for this function:

◆ rotate() [3/3]

void Slic3r::MultiPoint3::rotate ( double cos_angle,
double sin_angle )
inherited
590{
591 for (Point3 &pt : this->points) {
592 double cur_x = double(pt(0));
593 double cur_y = double(pt(1));
594 pt(0) = coord_t(round(cos_angle * cur_x - sin_angle * cur_y));
595 pt(1) = coord_t(round(cos_angle * cur_y + sin_angle * cur_x));
596 // Keep Z unchanged
597 }
598}

References points.

◆ simplify()

void Slic3r::Polyline3::simplify ( double tolerance)
736{
737 this->points = MultiPoint3::_douglas_peucker(this->points, tolerance);
738 this->fitting_result.clear();
739}
static Points3 _douglas_peucker(const Points3 &points, double tolerance)
Definition MultiPoint.cpp:477

References Slic3r::MultiPoint3::_douglas_peucker(), fitting_result, and Slic3r::MultiPoint3::points.

Here is the call graph for this function:

◆ simplify_by_fitting_arc()

void Slic3r::Polyline3::simplify_by_fitting_arc ( double tolerance)
742{
743 // BBS: do arc fit first, then use DP simplify to handle the straight part to reduce point.
744 Points points_2d = to_points(this->points);
745 ArcFitter::do_arc_fitting_and_simplify(points_2d, this->fitting_result, tolerance);
746 this->points = to_points3(points_2d);
747}
static void do_arc_fitting_and_simplify(Points &points, std::vector< PathFittingData > &result, double tolerance)
Definition ArcFitter.cpp:103
std::vector< Point, PointsAllocator< Point > > Points
Definition Point.hpp:73
Points to_points(const ExPolygons &src)
Definition ExPolygon.hpp:222
Points3 to_points3(const Points &points)
Definition Point.cpp:282

References Slic3r::ArcFitter::do_arc_fitting_and_simplify(), fitting_result, Slic3r::MultiPoint3::points, Slic3r::to_points(), and Slic3r::to_points3().

Here is the call graph for this function:

◆ size()

size_t Slic3r::MultiPoint3::size ( ) const
inlineinherited
149{ return this->points.size(); }

Referenced by Slic3r::ExtrusionLoopSloped::ExtrusionLoopSloped(), Slic3r::Polyline3::append_before(), Slic3r::Polyline3::append_fitting_result_after_append_polyline(), Slic3r::Polyline3::clip_end(), Slic3r::paths_touch(), Slic3r::Polyline3::reverse(), Slic3r::ExtrusionPath::size(), and Slic3r::Polyline3::split_at_index().

Here is the caller graph for this function:

◆ split_at() [1/2]

void Slic3r::Polyline3::split_at ( Point & point,
Polyline3 * p1,
Polyline3 * p2 ) const
853{
854 if (this->points.empty()) return;
855
856 // 0 judge whether the point is on the polyline
857 int index = this->find_point(point);
858 if (index != -1) {
859 // BBS: the spilit point is on the polyline, then easy
860 split_at_index(index, p1, p2);
861 point = p1->is_valid() ? p1->last_point().to_point() : p2->first_point().to_point();
862 return;
863 }
864
865 // 1 find the line to split at
866 size_t line_idx = 0;
867 Point p = this->first_point().to_point();
868 double min = (p - point).cast<double>().norm();
869 Lines3 lines = this->lines();
870 for (Lines3::const_iterator line = lines.begin(); line != lines.end(); ++line) {
871 Point p_tmp = point.projection_onto(line->to_line());
872 if ((p_tmp - point).cast<double>().norm() < min) {
873 p = p_tmp;
874 min = (p - point).cast<double>().norm();
875 line_idx = line - lines.begin();
876 }
877 }
878
879 // 2 judge whether the cloest point is one vertex of polyline.
880 // and spilit the polyline at different index
881 index = this->find_point(p);
882 if (index != -1) {
883 this->split_at_index(index, p1, p2);
884 p1->append(Point3(point, p1->last_point().z()));
885 p2->append_before(Point3(point, p2->first_point().z()));
886 } else {
887 Polyline3 temp;
888 this->split_at_index(line_idx, p1, &temp);
889 p1->append(Point3(point, p1->last_point().z()));
890 this->split_at_index(line_idx + 1, &temp, p2);
891 p2->append_before(Point3(point, p2->first_point().z()));
892 }
893}
Point to_point() const
Definition Point.hpp:372
Polyline3()
Definition Polyline.hpp:300
bool split_at_index(const size_t index, Polyline3 *p1, Polyline3 *p2) const
Definition Polyline.cpp:766
Kernel::Point_3 Point
Definition MeshRepair.cpp:81

References Polyline3(), append(), append_before(), Slic3r::cast(), Slic3r::MultiPoint3::find_point(), Slic3r::MultiPoint3::first_point(), Slic3r::MultiPoint3::is_valid(), Slic3r::MultiPoint3::last_point(), lines(), Slic3r::MultiPoint3::points, Slic3r::Point::projection_onto(), split_at_index(), and Slic3r::Point3::to_point().

Referenced by Slic3r::ExtrusionLoop::split_at(), and split_at().

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

◆ split_at() [2/2]

void Slic3r::Polyline3::split_at ( Point3 & point,
Polyline3 * p1,
Polyline3 * p2 ) const
895 {
896 Point p = point.to_point();
897 this->split_at(p, p1, p2);
898 point = Point3(p, point.z());
899}
void split_at(Point &point, Polyline3 *p1, Polyline3 *p2) const
Definition Polyline.cpp:852

References Polyline3(), split_at(), and Slic3r::Point3::to_point().

Here is the call graph for this function:

◆ split_at_index()

bool Slic3r::Polyline3::split_at_index ( const size_t index,
Polyline3 * p1,
Polyline3 * p2 ) const
767{
768 if (index > this->size() - 1)
769 return false;
770
771 if (index == 0) {
772 p1->clear();
773 p1->append(this->first_point());
774 *p2 = *this;
775 } else if (index == this->size() - 1) {
776 p2->clear();
777 p2->append(this->last_point());
778 *p1 = *this;
779 } else {
780 // BBS: spilit first part
781 p1->clear();
782 p1->points.reserve(index + 1);
783 p1->points.insert(p1->begin(), this->begin(), this->begin() + index + 1);
784 Point3 new_endpoint;
785 if (this->split_fitting_result_before_index(index, new_endpoint, p1->fitting_result))
786 p1->points.back() = new_endpoint;
787
788 p2->clear();
789 p2->points.reserve(this->size() - index);
790 p2->points.insert(p2->begin(), this->begin() + index, this->end());
791 Point3 new_startpoint;
792 if (this->split_fitting_result_after_index(index, new_startpoint, p2->fitting_result))
793 p2->points.front() = new_startpoint;
794 }
795 return true;
796}
bool split_fitting_result_after_index(size_t index, Point3 &new_startpoint, std::vector< PathFittingData > &result) const
Definition Polyline.cpp:981
bool split_fitting_result_before_index(size_t index, Point3 &new_endpoint, std::vector< PathFittingData > &result) const
Definition Polyline.cpp:948

References Polyline3(), append(), Slic3r::MultiPoint3::begin(), Slic3r::MultiPoint3::clear(), Slic3r::MultiPoint3::first_point(), fitting_result, Slic3r::MultiPoint3::last_point(), Slic3r::MultiPoint3::points, Slic3r::MultiPoint3::size(), split_fitting_result_after_index(), and split_fitting_result_before_index().

Referenced by split_at(), split_at_length(), Slic3r::split_at_slope_end(), and Slic3r::ExtrusionLoop::split_at_vertex().

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

◆ split_at_length()

bool Slic3r::Polyline3::split_at_length ( const double length,
Polyline3 * p1,
Polyline3 * p2 ) const
901 {
902 if (this->points.empty()) return false;
903 if (length < 0 || length > this->length()) {
904 return false;
905 }
906
907 if (length < SCALED_EPSILON) {
908 p1->clear();
909 p1->append(this->first_point());
910 *p2 = *this;
911 } else if (is_approx(length, this->length(), SCALED_EPSILON)) {
912 p2->clear();
913 p2->append(this->last_point());
914 *p1 = *this;
915 } else {
916 // 1 find the line to split at
917 size_t line_idx = 0;
918 double acc_length = 0;
919 Point3 p = this->first_point();
920 for (const auto& l : this->lines()) {
921 p = l.b;
922
923 const double current_length = l.length();
924 if (acc_length + current_length >= length) {
925 p = lerp(l.a, l.b, (length - acc_length) / current_length);
926 break;
927 }
928 acc_length += current_length;
929 line_idx++;
930 }
931
932 // 2 judge whether the cloest point is one vertex of polyline.
933 // and spilit the polyline at different index
934 int index = this->find_point(p);
935 if (index != -1) {
936 this->split_at_index(index, p1, p2);
937 } else {
938 Polyline3 temp;
939 this->split_at_index(line_idx, p1, &temp);
940 p1->append(p);
941 this->split_at_index(line_idx + 1, &temp, p2);
942 p2->append_before(p);
943 }
944 }
945 return true;
946}
double length() const
Definition MultiPoint.cpp:442
#define SCALED_EPSILON
Definition libslic3r.h:109
ColorRGB lerp(const ColorRGB &a, const ColorRGB &b, float t)
Definition Color.cpp:244
constexpr bool is_approx(Number value, Number test_value, Number precision=EPSILON)
Definition libslic3r.h:320

References Polyline3(), append(), append_before(), Slic3r::MultiPoint3::clear(), Slic3r::MultiPoint3::find_point(), Slic3r::MultiPoint3::first_point(), Slic3r::is_approx(), Slic3r::MultiPoint3::last_point(), Slic3r::MultiPoint3::length(), Slic3r::lerp(), lines(), Slic3r::MultiPoint3::points, SCALED_EPSILON, and split_at_index().

Referenced by Slic3r::ExtrusionLoopSloped::ExtrusionLoopSloped(), and Slic3r::split_at_slope_end().

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

◆ split_fitting_result_after_index()

bool Slic3r::Polyline3::split_fitting_result_after_index ( size_t index,
Point3 & new_startpoint,
std::vector< PathFittingData > & result ) const
private
982{
983 data.clear();
984 new_startpoint = this->points[index];
985 if (!this->fitting_result.empty()) {
986 data.reserve(this->fitting_result.size());
987 for (size_t i = 0; i < this->fitting_result.size(); i++) {
988 if (this->fitting_result[i].end_point_index > index)
989 data.push_back(this->fitting_result[i]);
990 }
991 if (!data.empty()) {
992 for (size_t i = 0; i < data.size(); i++) {
993 if (i != 0) {
994 data[i].start_point_index -= index;
995 data[i].end_point_index -= index;
996 } else {
997 data[i].end_point_index -= index;
998 // BBS: need to clip the arc and generate new start point
999 if (data.front().is_arc_move() && data.front().start_point_index < index) {
1000 if (!data.front().arc_data.clip_start(this->points[index].to_point()))
1001 // BBS: failed to clip arc, then return to be linear move
1002 data.front().path_type = EMovePathType::Linear_move;
1003 else
1004 // BBS: succeed to clip arc, then update and return the new start point
1005 new_startpoint = Point3(data.front().arc_data.start_point, 0);
1006 }
1007 data[i].start_point_index = 0;
1008 }
1009 }
1010 }
1011 data.shrink_to_fit();
1012 return true;
1013 }
1014 return false;
1015}

References fitting_result, Slic3r::Linear_move, and Slic3r::MultiPoint3::points.

Referenced by split_at_index().

Here is the caller graph for this function:

◆ split_fitting_result_before_index()

bool Slic3r::Polyline3::split_fitting_result_before_index ( size_t index,
Point3 & new_endpoint,
std::vector< PathFittingData > & result ) const
private
949{
950 data.clear();
951 new_endpoint = this->points[index];
952 if (!this->fitting_result.empty()) {
953 // BBS: max size
954 data.reserve(this->fitting_result.size());
955 // BBS: save fitting result before index
956 for (size_t i = 0; i < this->fitting_result.size(); i++) {
957 if (this->fitting_result[i].start_point_index < index)
958 data.push_back(this->fitting_result[i]);
959 else
960 break;
961 }
962
963 if (!data.empty()) {
964 // BBS: need to clip the arc and generate new end point
965 if (data.back().is_arc_move() && data.back().end_point_index > index) {
966 if (!data.back().arc_data.clip_end(this->points[index].to_point()))
967 // BBS: failed to clip arc, then return to be linear move
968 data.back().path_type = EMovePathType::Linear_move;
969 else
970 // BBS: succeed to clip arc, then update and return the new end point
971 new_endpoint = Point3(data.back().arc_data.end_point, 0);
972 }
973 data.back().end_point_index = index;
974 }
975 data.shrink_to_fit();
976 return true;
977 }
978 return false;
979}

References fitting_result, Slic3r::Linear_move, and Slic3r::MultiPoint3::points.

Referenced by split_at_index().

Here is the caller graph for this function:

◆ to_polyline()

Polyline Slic3r::Polyline3::to_polyline ( ) const

◆ translate() [1/2]

void Slic3r::MultiPoint3::translate ( const Point3 & vector)
inherited
437{
438 for (Point3& pt : points)
439 pt += v;
440}

References points.

◆ translate() [2/2]

void Slic3r::MultiPoint3::translate ( double x,
double y,
double z = 0 )
inlineinherited
138{ this->translate(Point3(coord_t(x), coord_t(y), coord_t(z))); }
void translate(double x, double y, double z=0)
Definition MultiPoint.hpp:138

References translate().

Referenced by translate().

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

Member Data Documentation

◆ fitting_result

◆ points

Points3 Slic3r::MultiPoint3::points
inherited

Referenced by Slic3r::Polyline3::Polyline3(), Slic3r::Polyline3::Polyline3(), Slic3r::GCode::_extrude(), Slic3r::Polyline3::append(), Slic3r::Polyline3::append_fitting_result_after_append_points(), bounding_box(), Slic3r::Polyline3::clip_end(), Slic3r::SupportMaterialInternal::collect_bridging_perimeter_areas(), Slic3r::ExtrusionLoop::collect_points(), Slic3r::ExtrusionMultiPath::collect_points(), Slic3r::ExtrusionPath::collect_points3(), Slic3r::contour_extrusion_path(), Slic3r::GCode::extrude_path(), Slic3r::ExtrusionSimulator::extrude_to_accumulator(), Slic3r::extrusion_entities_append_loops(), find_point(), find_point(), find_point(), find_point(), Slic3r::ExtrusionPath::first_point(), Slic3r::ExtrusionPath::first_point3(), Slic3r::FakeWipeTower::getFakeExtrusionPathsFromWipeTower2(), Slic3r::FakeWipeTower::getTrueExtrusionLayersFromWipeTower(), Slic3r::ExtrusionPath::is_closed(), Slic3r::ExtrusionPath::last_point(), Slic3r::ExtrusionPath::last_point3(), Slic3r::Polyline3::lines(), Slic3r::modulate_extrusion_by_overlapping_layers(), Slic3r::paths_touch(), remove_duplicate_points(), rotate(), rotate(), Slic3r::Polyline3::simplify(), Slic3r::Polyline3::simplify_by_fitting_arc(), Slic3r::ExtrusionLoop::split_at(), Slic3r::Polyline3::split_at(), Slic3r::Polyline3::split_at_index(), Slic3r::Polyline3::split_at_length(), Slic3r::ExtrusionLoop::split_at_vertex(), Slic3r::Polyline3::split_fitting_result_after_index(), Slic3r::Polyline3::split_fitting_result_before_index(), Slic3r::thick_polyline_to_multi_path(), Slic3r::Polyline3::to_polyline(), and translate().


The documentation for this class was generated from the following files:
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Polyline.hpp
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Polyline.cpp