Fix looping_perimeter bug

This commit is contained in:
supermerill 2022-02-12 17:15:22 +01:00
parent c50f76ec14
commit 650c13e900
2 changed files with 73 additions and 19 deletions

View File

@ -1233,20 +1233,45 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const Polyline& loop_polygon
bool no_small_flow = _lower_slices_bridge_speed_big == _lower_slices_bridge_flow_small;
Polylines small_flow;
Polylines big_flow;
#ifdef _DEBUG
for (Polyline& poly : ok_polylines)
for (int i = 0; i < poly.points.size() - 1; i++)
assert(poly.points[i] != poly.points[i + 1]);
#endif
Polylines* previous = &ok_polylines;
if (this->config->overhangs_width_speed.value > 0 && (this->config->overhangs_width_speed.value < this->config->overhangs_width.value || this->config->overhangs_width.value == 0)) {
if (!this->_lower_slices_bridge_speed_small.empty()) {
small_speed = diff_pl(*previous, this->_lower_slices_bridge_speed_small);
#ifdef _DEBUG
for (Polyline& poly : small_speed) // assert small_speed
for (int i = 0; i < poly.points.size() - 1; i++) // assert small_speed
assert(poly.points[i] != poly.points[i + 1]); // assert small_speed
#endif
if (!small_speed.empty()) {
*previous = intersection_pl(*previous, this->_lower_slices_bridge_speed_small);
#ifdef _DEBUG
for (Polyline& poly : *previous) // assert previous
for (int i = 0; i < poly.points.size() - 1; i++) // assert previous
assert(poly.points[i] != poly.points[i + 1]); // assert previous
#endif
previous = &small_speed;
}
}
if (!this->_lower_slices_bridge_speed_big.empty()) {
big_speed = diff_pl(*previous, this->_lower_slices_bridge_speed_big);
#ifdef _DEBUG
for (Polyline& poly : big_speed) // assert big_speed
for (int i = 0; i < poly.points.size() - 1; i++) // assert big_speed
assert(poly.points[i] != poly.points[i + 1]); // assert big_speed
#endif
if (!big_speed.empty()) {
*previous = intersection_pl(*previous, this->_lower_slices_bridge_speed_big);
#ifdef _DEBUG
for (Polyline& poly : *previous) // assert previous
for (int i = 0; i < poly.points.size() - 1; i++) // assert previous
assert(poly.points[i] != poly.points[i + 1]); // assert previous
#endif
previous = &big_speed;
}
}
@ -1254,15 +1279,35 @@ ExtrusionPaths PerimeterGenerator::create_overhangs(const Polyline& loop_polygon
if (this->config->overhangs_width.value > 0) {
if (!this->_lower_slices_bridge_flow_small.empty()) {
small_flow = diff_pl(*previous, this->_lower_slices_bridge_flow_small);
#ifdef _DEBUG
for (Polyline& poly : small_flow) // assert small_flow
for (int i = 0; i < poly.points.size() - 1; i++) // assert small_flow
assert(poly.points[i] != poly.points[i + 1]); // assert small_flow
#endif
if (!small_flow.empty()) {
*previous = intersection_pl(*previous, this->_lower_slices_bridge_flow_small);
#ifdef _DEBUG
for (Polyline& poly : *previous) // assert previous
for (int i = 0; i < poly.points.size() - 1; i++) // assert previous
assert(poly.points[i] != poly.points[i + 1]); // assert previous
#endif
previous = &small_flow;
}
}
if (!this->_lower_slices_bridge_flow_big.empty()) {
big_flow = diff_pl(*previous, this->_lower_slices_bridge_flow_big);
#ifdef _DEBUG
for (Polyline& poly : big_flow) // assert big_flow
for (int i = 0; i < poly.points.size() - 1; i++) // assert big_flow
assert(poly.points[i] != poly.points[i + 1]); // assert big_flow
#endif
if (!big_flow.empty()) {
*previous = intersection_pl(*previous, this->_lower_slices_bridge_flow_big);
#ifdef _DEBUG
for (Polyline& poly : *previous) // assert previous
for (int i = 0; i < poly.points.size() - 1; i++) // assert previous
assert(poly.points[i] != poly.points[i + 1]); // assert previous
#endif
previous = &big_flow;
}
}
@ -1844,16 +1889,21 @@ PerimeterGenerator::_get_nearest_point(const PerimeterGeneratorLoops &children,
ExtrusionLoop
PerimeterGenerator::_extrude_and_cut_loop(const PerimeterGeneratorLoop &loop, const Point entry_point, const Line &direction) const
PerimeterGenerator::_extrude_and_cut_loop(const PerimeterGeneratorLoop &loop, const Point entry_point, const Line &direction, bool enforce_loop) const
{
bool need_to_reverse = false;
Polyline initial_polyline;
const coord_t dist_cut = (coord_t)scale_(this->print_config->nozzle_diameter.get_at(this->config->perimeter_extruder - 1));
coord_t dist_cut = (coord_t)scale_(this->print_config->nozzle_diameter.get_at(this->config->perimeter_extruder - 1));
if (loop.polygon.points.size() < 3) return ExtrusionLoop(elrDefault);
if (loop.polygon.length() < dist_cut * 2) {
if (enforce_loop) {
//do something to still use it
dist_cut = loop.polygon.length() / 4;
} else {
//reduce it ot a single-point loop that will eb emrged inside the complex path
ExtrusionLoop single_point(elrDefault);
Polyline poly_point;
poly_point.append(loop.polygon.centroid());
@ -1865,6 +1915,7 @@ PerimeterGenerator::_extrude_and_cut_loop(const PerimeterGeneratorLoop &loop, co
single_point.paths.back().polyline = poly_point;
return single_point;
}
}
const size_t idx_closest_from_entry_point = loop.polygon.closest_point_index(entry_point);
if (loop.polygon.points[idx_closest_from_entry_point].distance_to(entry_point) > SCALED_EPSILON) {
//create new Point
@ -1916,12 +1967,15 @@ PerimeterGenerator::_extrude_and_cut_loop(const PerimeterGeneratorLoop &loop, co
if (direction.length() > 0) {
Polyline direction_polyline;
for (ExtrusionPath &path : paths) {
if(direction_polyline.size() == 0 || direction_polyline.points.back() != path.first_point())
direction_polyline.points.insert(direction_polyline.points.end(), path.polyline.points.begin(), path.polyline.points.end());
}
for (int i = 0; i < direction_polyline.points.size() - 1; i++)
assert(direction_polyline.points[i] != direction_polyline.points[i + 1]);
direction_polyline.clip_start(SCALED_RESOLUTION);
direction_polyline.clip_end(SCALED_RESOLUTION);
if (direction_polyline.length() > perimeter_flow.scaled_width() / 8) {
direction_polyline.clip_start(perimeter_flow.scaled_width() / 20);
direction_polyline.clip_end(perimeter_flow.scaled_width() / 20);
}
coord_t dot = direction.dot(Line(direction_polyline.points.back(), direction_polyline.points.front()));
need_to_reverse = dot>0;
}
@ -1996,7 +2050,7 @@ PerimeterGenerator::_traverse_and_join_loops(const PerimeterGeneratorLoop &loop,
//const coord_t dist_cut = (coord_t)scale_(this->print_config->nozzle_diameter.get_at(this->config->perimeter_extruder - 1));
//TODO change this->external_perimeter_flow.scaled_width() if it's the first one!
const coord_t max_width_extrusion = this->perimeter_flow.scaled_width();
ExtrusionLoop my_loop = _extrude_and_cut_loop(loop, entry_point);
ExtrusionLoop my_loop = _extrude_and_cut_loop(loop, entry_point, Line{ {0,0},{0,0} }, true);
int child_idx = 0;
//Polylines myPolylines = { myPolyline };
@ -2059,10 +2113,10 @@ PerimeterGenerator::_traverse_and_join_loops(const PerimeterGeneratorLoop &loop,
outer_end->polyline.points.insert(outer_end->polyline.points.begin(), nearest.outter_best);
}
Polyline to_reduce = outer_start->polyline;
if (to_reduce.points.size()>1) to_reduce.clip_end(SCALED_RESOLUTION);
if (to_reduce.points.size()>1 && to_reduce.length() > (perimeter_flow.scaled_width() / 10)) to_reduce.clip_end(perimeter_flow.scaled_width() / 20);
deletedSection.a = to_reduce.points.back();
to_reduce = outer_end->polyline;
if (to_reduce.points.size()>1) to_reduce.clip_start(SCALED_RESOLUTION);
if (to_reduce.points.size()>1 && to_reduce.length() > (perimeter_flow.scaled_width() / 10)) to_reduce.clip_start(perimeter_flow.scaled_width() / 20);
deletedSection.b = to_reduce.points.front();
//get the inner loop to connect to us.

View File

@ -113,7 +113,7 @@ private:
// like _traverse_loops but with merging all periemter into one continuous loop
ExtrusionLoop _traverse_and_join_loops(const PerimeterGeneratorLoop &loop, const PerimeterGeneratorLoops &childs, const Point entryPoint) const;
// sub-function of _traverse_and_join_loops, transform a single loop as a cut extrusion to be merged with an other one.
ExtrusionLoop _extrude_and_cut_loop(const PerimeterGeneratorLoop &loop, const Point entryPoint, const Line &direction = Line(Point(0,0),Point(0,0))) const;
ExtrusionLoop _extrude_and_cut_loop(const PerimeterGeneratorLoop& loop, const Point entryPoint, const Line& direction = Line(Point(0, 0), Point(0, 0)), bool enforce_loop = false) const;
// sub-function of _traverse_and_join_loops, find the good splot to cut a loop to be able to join it with an other one
PerimeterIntersectionPoint _get_nearest_point(const PerimeterGeneratorLoops &children, ExtrusionLoop &myPolylines, const coord_t dist_cut, const coord_t max_dist) const;
};