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

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

Static Public Member Functions

static void do_arc_fitting (const Points &points, std::vector< PathFittingData > &result, double tolerance)
static void do_arc_fitting_and_simplify (Points &points, std::vector< PathFittingData > &result, double tolerance)

Detailed Description

Member Function Documentation

◆ do_arc_fitting()

void Slic3r::ArcFitter::do_arc_fitting ( const Points & points,
std::vector< PathFittingData > & result,
double tolerance )
static
16{
17#ifdef DEBUG_ARC_FITTING
18 static int irun = 0;
19 BoundingBox bbox_svg;
20 bbox_svg.merge(get_extents(points));
21 Polyline temp = Polyline(points);
22 {
23 std::stringstream stri;
24 stri << "debug_arc_fitting_" << irun << ".svg";
25 SVG svg(stri.str(), bbox_svg);
26 svg.draw(points, "blue", 50000);
27 svg.draw(temp, "red", 1);
28 svg.Close();
29 }
30 ++ irun;
31#endif
32
33 result.clear();
34 result.reserve(points.size() / 2); //worst case size
35 if (points.size() < 3) {
36 PathFittingData data;
37 data.start_point_index = 0;
38 data.end_point_index = points.size() - 1;
39 data.path_type = EMovePathType::Linear_move;
40 result.push_back(data);
41 return;
42 }
43
44 size_t front_index = 0;
45 size_t back_index = 0;
46 ArcSegment last_arc;
47 bool can_fit = false;
48 Points current_segment;
49 current_segment.reserve(points.size());
50 ArcSegment target_arc;
51 for (size_t i = 0; i < points.size(); i++) {
52 //BBS: point in stack is not enough, build stack first
53 back_index = i;
54 current_segment.push_back(points[i]);
55 if (back_index - front_index < 2)
56 continue;
57
58 can_fit = ArcSegment::try_create_arc(current_segment, target_arc, Polyline(current_segment).length(),
60 tolerance,
62 if (can_fit) {
63 //BBS: can be fit as arc, then save arc data temperarily
64 last_arc = target_arc;
65 if (back_index == points.size() - 1) {
66 result.emplace_back(PathFittingData{ front_index,
67 back_index,
69 last_arc });
70 front_index = back_index;
71 }
72 } else {
73 if (back_index - front_index > 2) {
74 //BBS: althought current point_stack can't be fit as arc,
75 //but previous must can be fit if removing the top in stack, so save last arc
76 result.emplace_back(PathFittingData{ front_index,
77 back_index - 1,
79 last_arc });
80 } else {
81 //BBS: save the first segment as line move when 3 point-line can't be fit as arc move
82 if (result.empty() || result.back().path_type != EMovePathType::Linear_move)
83 result.emplace_back(PathFittingData{front_index, front_index + 1, EMovePathType::Linear_move, ArcSegment()});
84 else if(result.back().path_type == EMovePathType::Linear_move)
85 result.back().end_point_index = front_index + 1;
86 }
87 front_index = back_index - 1;
88 current_segment.clear();
89 current_segment.push_back(points[front_index]);
90 current_segment.push_back(points[front_index + 1]);
91 }
92 }
93 //BBS: handle the remain data
94 if (front_index != back_index) {
95 if (result.empty() || result.back().path_type != EMovePathType::Linear_move)
96 result.emplace_back(PathFittingData{front_index, back_index, EMovePathType::Linear_move, ArcSegment()});
97 else if (result.back().path_type == EMovePathType::Linear_move)
98 result.back().end_point_index = back_index;
99 }
100 result.shrink_to_fit();
101}
#define DEFAULT_SCALED_MAX_RADIUS
Definition Circle.hpp:68
#define DEFAULT_ARC_LENGTH_PERCENT_TOLERANCE
Definition Circle.hpp:70
static bool try_create_arc(const Points &points, ArcSegment &target_arc, double approximate_length, double max_radius=DEFAULT_SCALED_MAX_RADIUS, double tolerance=DEFAULT_SCALED_RESOLUTION, double path_tolerance_percent=DEFAULT_ARC_LENGTH_PERCENT_TOLERANCE)
Definition Circle.cpp:280
double length(const Points &pts)
Definition MultiPoint.hpp:181
BoundingBox get_extents(const ExPolygonsWithIds &e)
Definition Emboss.cpp:1374
std::vector< Point, PointsAllocator< Point > > Points
Definition Point.hpp:73
@ Arc_move_cw
Definition ArcFitter.hpp:16
@ Arc_move_ccw
Definition ArcFitter.hpp:17
@ Linear_move
Definition ArcFitter.hpp:15
@ Arc_Dir_CCW
Definition Circle.hpp:63

References Slic3r::Arc_Dir_CCW, Slic3r::Arc_move_ccw, Slic3r::Arc_move_cw, Slic3r::SVG::Close(), DEFAULT_ARC_LENGTH_PERCENT_TOLERANCE, DEFAULT_SCALED_MAX_RADIUS, Slic3r::ArcSegment::direction, Slic3r::SVG::draw(), Slic3r::PathFittingData::end_point_index, Slic3r::get_extents(), Slic3r::length(), Slic3r::Linear_move, Slic3r::BoundingBoxBase< PointType, APointsType >::merge(), Slic3r::PathFittingData::path_type, Slic3r::PathFittingData::start_point_index, and Slic3r::ArcSegment::try_create_arc().

Referenced by do_arc_fitting_and_simplify().

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

◆ do_arc_fitting_and_simplify()

void Slic3r::ArcFitter::do_arc_fitting_and_simplify ( Points & points,
std::vector< PathFittingData > & result,
double tolerance )
static
104{
105 //BBS: 1 do arc fit first
106 if (abs(tolerance) > SCALED_EPSILON)
107 ArcFitter::do_arc_fitting(points, result, tolerance);
108 else
109 result.push_back(PathFittingData{ 0, points.size() - 1, EMovePathType::Linear_move, ArcSegment() });
110
111 //BBS: 2 for straight part which can't fit arc, use DP simplify
112 //for arc part, only need to keep start and end point
113 if (result.size() == 1 && result[0].path_type == EMovePathType::Linear_move) {
114 //BBS: all are straight segment, directly use DP simplify
115 points = MultiPoint::_douglas_peucker(points, tolerance);
116 result[0].end_point_index = points.size() - 1;
117 return;
118 } else {
119 //BBS: has both arc part and straight part, we should spilit the straight part out and do DP simplify
120 Points simplified_points;
121 simplified_points.reserve(points.size());
122 simplified_points.push_back(points[0]);
123 std::vector<size_t> reduce_count(result.size(), 0);
124 for (size_t i = 0; i < result.size(); i++)
125 {
126 size_t start_index = result[i].start_point_index;
127 size_t end_index = result[i].end_point_index;
128 //BBS: get the straight and arc part, and do simplifing independently.
129 //Why: It's obvious that we need to use DP to simplify straight part to reduce point.
130 //For arc part, theoretically, we only need to keep the start and end point, and
131 //delete all other point. But when considering wipe operation, we must keep the original
132 //point data and shouldn't reduce too much by only saving start and end point.
133 Points straight_or_arc_part;
134 straight_or_arc_part.reserve(end_index - start_index + 1);
135 for (size_t j = start_index; j <= end_index; j++)
136 straight_or_arc_part.push_back(points[j]);
137 straight_or_arc_part = MultiPoint::_douglas_peucker(straight_or_arc_part, tolerance);
138 //BBS: how many point has been reduced
139 reduce_count[i] = end_index - start_index + 1 - straight_or_arc_part.size();
140 //BBS: save the simplified result
141 for (size_t j = 1; j < straight_or_arc_part.size(); j++) {
142 simplified_points.push_back(straight_or_arc_part[j]);
143 }
144 }
145 //BBS: save and will return the simplified_points
146 points = simplified_points;
147 //BBS: modify the index in result because the point index must be changed to match the simplified points
148 for (size_t j = 1; j < reduce_count.size(); j++)
149 reduce_count[j] += reduce_count[j - 1];
150 for (size_t j = 0; j < result.size(); j++)
151 {
152 result[j].end_point_index -= reduce_count[j];
153 if (j != result.size() - 1)
154 result[j + 1].start_point_index = result[j].end_point_index;
155 }
156 }
157}
static void do_arc_fitting(const Points &points, std::vector< PathFittingData > &result, double tolerance)
Definition ArcFitter.cpp:15
static Points _douglas_peucker(const Points &points, const double tolerance)
Definition MultiPoint.cpp:175
#define SCALED_EPSILON
Definition libslic3r.h:109

References Slic3r::MultiPoint::_douglas_peucker(), do_arc_fitting(), Slic3r::Linear_move, and SCALED_EPSILON.

Referenced by Slic3r::Polyline3::simplify_by_fitting_arc(), and Slic3r::Polyline::simplify_by_fitting_arc().

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

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