From 0ec68eb35b0c863aece86fee98807cb299d69124 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 28 Feb 2018 11:41:04 +0100 Subject: [PATCH] Fix for issue #661 (ExPolygons generation) --- xs/src/libslic3r/TriangleMesh.cpp | 67 ++++++++++++++++++------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/xs/src/libslic3r/TriangleMesh.cpp b/xs/src/libslic3r/TriangleMesh.cpp index 1cdfb091d..ffbe507ef 100644 --- a/xs/src/libslic3r/TriangleMesh.cpp +++ b/xs/src/libslic3r/TriangleMesh.cpp @@ -1186,40 +1186,46 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slic loops correctly in some edge cases when original model had overlapping facets */ - std::vector area; - std::vector sorted_area; // vector of indices - for (Polygons::const_iterator loop = loops.begin(); loop != loops.end(); ++ loop) { - area.push_back(loop->area()); - sorted_area.push_back(loop - loops.begin()); - } - - // outer first - std::sort(sorted_area.begin(), sorted_area.end(), - [&area](size_t a, size_t b) { return std::abs(area[a]) > std::abs(area[b]); }); + /* The following lines are commented out because they can generate wrong polygons, + see for example issue #661 */ - // we don't perform a safety offset now because it might reverse cw loops - Polygons p_slices; - for (std::vector::const_iterator loop_idx = sorted_area.begin(); loop_idx != sorted_area.end(); ++ loop_idx) { - /* we rely on the already computed area to determine the winding order - of the loops, since the Orientation() function provided by Clipper - would do the same, thus repeating the calculation */ - Polygons::const_iterator loop = loops.begin() + *loop_idx; - if (area[*loop_idx] > +EPSILON) - p_slices.push_back(*loop); - else if (area[*loop_idx] < -EPSILON) - //FIXME This is arbitrary and possibly very slow. - // If the hole is inside a polygon, then there is no need to diff. - // If the hole intersects a polygon boundary, then diff it, but then - // there is no guarantee of an ordering of the loops. - // Maybe we can test for the intersection before running the expensive diff algorithm? - p_slices = diff(p_slices, *loop); - } + //std::vector area; + //std::vector sorted_area; // vector of indices + //for (Polygons::const_iterator loop = loops.begin(); loop != loops.end(); ++ loop) { + // area.push_back(loop->area()); + // sorted_area.push_back(loop - loops.begin()); + //} + // + //// outer first + //std::sort(sorted_area.begin(), sorted_area.end(), + // [&area](size_t a, size_t b) { return std::abs(area[a]) > std::abs(area[b]); }); + + //// we don't perform a safety offset now because it might reverse cw loops + //Polygons p_slices; + //for (std::vector::const_iterator loop_idx = sorted_area.begin(); loop_idx != sorted_area.end(); ++ loop_idx) { + // /* we rely on the already computed area to determine the winding order + // of the loops, since the Orientation() function provided by Clipper + // would do the same, thus repeating the calculation */ + // Polygons::const_iterator loop = loops.begin() + *loop_idx; + // if (area[*loop_idx] > +EPSILON) + // p_slices.push_back(*loop); + // else if (area[*loop_idx] < -EPSILON) + // //FIXME This is arbitrary and possibly very slow. + // // If the hole is inside a polygon, then there is no need to diff. + // // If the hole intersects a polygon boundary, then diff it, but then + // // there is no guarantee of an ordering of the loops. + // // Maybe we can test for the intersection before running the expensive diff algorithm? + // p_slices = diff(p_slices, *loop); + //} // perform a safety offset to merge very close facets (TODO: find test case for this) double safety_offset = scale_(0.0499); //FIXME see https://github.com/prusa3d/Slic3r/issues/520 // double safety_offset = scale_(0.0001); - ExPolygons ex_slices = offset2_ex(p_slices, +safety_offset, -safety_offset); + + /* The following line is commented out because it can generate wrong polygons, + see for example issue #661 */ + //ExPolygons ex_slices = offset2_ex(p_slices, +safety_offset, -safety_offset); #ifdef SLIC3R_TRIANGLEMESH_DEBUG size_t holes_count = 0; @@ -1230,7 +1236,10 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slic #endif // append to the supplied collection - expolygons_append(*slices, ex_slices); + /* Fix for issue #661 { */ + expolygons_append(*slices, offset2_ex(union_(loops, false), +safety_offset, -safety_offset)); + //expolygons_append(*slices, ex_slices); + /* } */ } void TriangleMeshSlicer::make_expolygons(std::vector &lines, ExPolygons* slices) const