mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-26 10:04:28 +08:00
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:
parent
9328681428
commit
e53f60dc1a
@ -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 {
|
//class ExtrusionTreeVisitor : ExtrusionVisitor {
|
||||||
//public:
|
//public:
|
||||||
// //virtual void use(ExtrusionEntity &entity) { assert(false); };
|
// //virtual void use(ExtrusionEntity &entity) { assert(false); };
|
||||||
|
@ -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
|
#endif
|
||||||
|
@ -1852,6 +1852,8 @@ PerimeterGenerator::_extrude_and_cut_loop(const PerimeterGeneratorLoop &loop, co
|
|||||||
for (ExtrusionPath &path : paths) {
|
for (ExtrusionPath &path : paths) {
|
||||||
direction_polyline.points.insert(direction_polyline.points.end(), path.polyline.points.begin(), path.polyline.points.end());
|
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_start(SCALED_RESOLUTION);
|
||||||
direction_polyline.clip_end(SCALED_RESOLUTION);
|
direction_polyline.clip_end(SCALED_RESOLUTION);
|
||||||
coord_t dot = direction.dot(Line(direction_polyline.points.back(), direction_polyline.points.front()));
|
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
|
//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]);
|
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_start = &my_loop.paths[nearest.idx_polyline_outter];
|
||||||
ExtrusionPath *outer_end = &my_loop.paths[nearest.idx_polyline_outter + 1];
|
ExtrusionPath *outer_end = &my_loop.paths[nearest.idx_polyline_outter + 1];
|
||||||
Line deletedSection;
|
Line deletedSection;
|
||||||
|
|
||||||
//cut our polyline
|
//cut our polyline, so outer_start has no common point with outer_end
|
||||||
//separate them
|
//separate them
|
||||||
size_t nearest_idx_outter = outer_start->polyline.closest_point_index(nearest.outter_best);
|
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)) {
|
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]);
|
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
|
//update for next loop
|
||||||
childs.erase(childs.begin() + nearest.idx_children);
|
childs.erase(childs.begin() + nearest.idx_children);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user