Fix crash from perimeter_loop one-point loop

supermerill/SuperSlicer#1623
Fixme: take the first object from this issue project
  and you can see some bad lines at layer 31.
This commit is contained in:
supermerill 2021-10-11 16:51:16 +02:00
parent 9328681428
commit e53f60dc1a
3 changed files with 44 additions and 1 deletions

View File

@ -388,6 +388,28 @@ void ExtrusionLength::use(const ExtrusionEntityCollection& collection) {
}
}
void ExtrusionVisitorRecursiveConst::use(const ExtrusionMultiPath& multipath) {
for (const ExtrusionPath& path: multipath.paths) {
path.visit(*this);
}
}
void ExtrusionVisitorRecursiveConst::use(const ExtrusionMultiPath3D& multipath3D) {
for (const ExtrusionPath3D& path3D : multipath3D.paths) {
path3D.visit(*this);
}
}
void ExtrusionVisitorRecursiveConst::use(const ExtrusionLoop& loop) {
for (const ExtrusionPath& path : loop.paths) {
path.visit(*this);
}
}
void ExtrusionVisitorRecursiveConst::use(const ExtrusionEntityCollection& collection) {
for (const ExtrusionEntity* entity : collection.entities) {
entity->visit(*this);
}
}
//class ExtrusionTreeVisitor : ExtrusionVisitor {
//public:
// //virtual void use(ExtrusionEntity &entity) { assert(false); };

View File

@ -606,6 +606,14 @@ public:
}
};
class ExtrusionVisitorRecursiveConst : public ExtrusionVisitorConst {
public:
virtual void use(const ExtrusionMultiPath& multipath) override;
virtual void use(const ExtrusionMultiPath3D& multipath) override;
virtual void use(const ExtrusionLoop& loop) override;
virtual void use(const ExtrusionEntityCollection& collection) override;
};
}
#endif

View File

@ -1852,6 +1852,8 @@ PerimeterGenerator::_extrude_and_cut_loop(const PerimeterGeneratorLoop &loop, co
for (ExtrusionPath &path : paths) {
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);
coord_t dot = direction.dot(Line(direction_polyline.points.back(), direction_polyline.points.front()));
@ -1950,11 +1952,12 @@ PerimeterGenerator::_traverse_and_join_loops(const PerimeterGeneratorLoop &loop,
//create new node with recursive ask for the inner perimeter & COPY of the points, ready to be cut
my_loop.paths.insert(my_loop.paths.begin() + nearest.idx_polyline_outter + 1, my_loop.paths[nearest.idx_polyline_outter]);
// outer_start == outer_end
ExtrusionPath *outer_start = &my_loop.paths[nearest.idx_polyline_outter];
ExtrusionPath *outer_end = &my_loop.paths[nearest.idx_polyline_outter + 1];
Line deletedSection;
//cut our polyline
//cut our polyline, so outer_start has no common point with outer_end
//separate them
size_t nearest_idx_outter = outer_start->polyline.closest_point_index(nearest.outter_best);
if (outer_start->polyline.points[nearest_idx_outter].coincides_with_epsilon(nearest.outter_best)) {
@ -2195,6 +2198,16 @@ PerimeterGenerator::_traverse_and_join_loops(const PerimeterGeneratorLoop &loop,
my_loop.paths.insert(my_loop.paths.begin() + nearest.idx_polyline_outter + 1, travel_path_begin[i]);
}
}
//remove one-point extrusion
//FIXME prevent this instead of patching here?
for (int i = 0; i < my_loop.paths.size(); i++) {
if (my_loop.paths[i].polyline.size() < 2) {
if (my_loop.paths[i].polyline.size() == 1)
std::cout << "erase one-point extrusion : layer " << this->layer->id() << " " << my_loop.paths[i].polyline.points.front().x() << ":" << my_loop.paths[i].polyline.points.front().y() << "\n";
my_loop.paths.erase(my_loop.paths.begin() + i);
i--;
}
}
//update for next loop
childs.erase(childs.begin() + nearest.idx_children);