Fixed crash when cutting meshes with very very tiny triangles. #3953

This commit is contained in:
Alessandro Ranellucci 2017-05-26 20:57:50 +02:00
parent 5f038e85ef
commit 3469800223
2 changed files with 24 additions and 14 deletions

View File

@ -18,6 +18,8 @@ class ExPolygon
public: public:
Polygon contour; Polygon contour;
Polygons holes; Polygons holes;
ExPolygon() {};
explicit ExPolygon(const Polygon &_contour) : contour(_contour) {};
operator Points() const; operator Points() const;
operator Polygons() const; operator Polygons() const;
void scale(double factor); void scale(double factor);

View File

@ -1128,31 +1128,39 @@ TriangleMeshSlicer<A>::make_expolygons_simple(std::vector<IntersectionLine> &lin
Polygons loops; Polygons loops;
this->make_loops(lines, &loops); this->make_loops(lines, &loops);
// cache slice contour area
std::vector<double> area;
area.resize(slices->size(), -1);
Polygons cw; Polygons cw;
for (Polygons::const_iterator loop = loops.begin(); loop != loops.end(); ++loop) { for (const Polygon &loop : loops) {
if (loop->area() >= 0) { const double a = loop.area();
ExPolygon ex; if (a >= 0) {
ex.contour = *loop; slices->push_back(ExPolygon(loop));
slices->push_back(ex); area.push_back(a);
} else { } else {
cw.push_back(*loop); cw.push_back(loop);
} }
} }
// assign holes to contours // assign holes to contours
for (Polygons::const_iterator loop = cw.begin(); loop != cw.end(); ++loop) { for (const Polygon &loop : cw) {
int slice_idx = -1; int slice_idx = -1;
double current_contour_area = -1; double current_contour_area = -1;
for (ExPolygons::iterator slice = slices->begin(); slice != slices->end(); ++slice) { for (size_t i = 0; i < slices->size(); ++i) {
if (slice->contour.contains(loop->points.front())) { if ((*slices)[i].contour.contains(loop.points.front())) {
double area = slice->contour.area(); if (area[i] == -1) area[i] = (*slices)[i].contour.area();
if (area < current_contour_area || current_contour_area == -1) { if (area[i] < current_contour_area || current_contour_area == -1) {
slice_idx = slice - slices->begin(); slice_idx = i;
current_contour_area = area; current_contour_area = area[i];
} }
} }
} }
(*slices)[slice_idx].holes.push_back(*loop);
// discard holes which couldn't fit inside a contour as they are probably
// invalid polygons (self-intersecting)
if (slice_idx > -1)
(*slices)[slice_idx].holes.push_back(loop);
} }
} }