mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-16 09:35:54 +08:00
Fix: Windows and Linux has different order of polygons after Clipper simplify
To unify behavior between platforms: Polygons are sorted on the end of function. + Remove Slic3r::ExPolygons simplify_polygons_ex(const Slic3r::Polygons &subject); // different definition and declaration, unused function
This commit is contained in:
parent
c16ae5bf1f
commit
ac2f6304a0
@ -1041,8 +1041,7 @@ Polygons union_parallel_reduce(const Polygons &subject)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygons simplify_polygons(const Polygons &subject)
|
Polygons simplify_polygons(const Polygons &subject) {
|
||||||
{
|
|
||||||
CLIPPER_UTILS_TIME_LIMIT_MILLIS(CLIPPER_UTILS_TIME_LIMIT_DEFAULT);
|
CLIPPER_UTILS_TIME_LIMIT_MILLIS(CLIPPER_UTILS_TIME_LIMIT_DEFAULT);
|
||||||
|
|
||||||
ClipperLib::Paths output;
|
ClipperLib::Paths output;
|
||||||
@ -1052,27 +1051,9 @@ Polygons simplify_polygons(const Polygons &subject)
|
|||||||
c.StrictlySimple(true);
|
c.StrictlySimple(true);
|
||||||
c.AddPaths(ClipperUtils::PolygonsProvider(subject), ClipperLib::ptSubject, true);
|
c.AddPaths(ClipperUtils::PolygonsProvider(subject), ClipperLib::ptSubject, true);
|
||||||
c.Execute(ClipperLib::ctUnion, output, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
|
c.Execute(ClipperLib::ctUnion, output, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
|
||||||
|
|
||||||
// convert into Slic3r polygons
|
|
||||||
return to_polygons(std::move(output));
|
return to_polygons(std::move(output));
|
||||||
}
|
}
|
||||||
|
|
||||||
ExPolygons simplify_polygons_ex(const Polygons &subject, bool preserve_collinear)
|
|
||||||
{
|
|
||||||
CLIPPER_UTILS_TIME_LIMIT_MILLIS(CLIPPER_UTILS_TIME_LIMIT_DEFAULT);
|
|
||||||
|
|
||||||
ClipperLib::PolyTree polytree;
|
|
||||||
ClipperLib::Clipper c;
|
|
||||||
// c.PreserveCollinear(true);
|
|
||||||
//FIXME StrictlySimple is very expensive! Is it needed?
|
|
||||||
c.StrictlySimple(true);
|
|
||||||
c.AddPaths(ClipperUtils::PolygonsProvider(subject), ClipperLib::ptSubject, true);
|
|
||||||
c.Execute(ClipperLib::ctUnion, polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
|
|
||||||
|
|
||||||
// convert into ExPolygons
|
|
||||||
return PolyTreeToExPolygons(std::move(polytree));
|
|
||||||
}
|
|
||||||
|
|
||||||
Polygons top_level_islands(const Slic3r::Polygons &polygons)
|
Polygons top_level_islands(const Slic3r::Polygons &polygons)
|
||||||
{
|
{
|
||||||
CLIPPER_UTILS_TIME_LIMIT_MILLIS(CLIPPER_UTILS_TIME_LIMIT_DEFAULT);
|
CLIPPER_UTILS_TIME_LIMIT_MILLIS(CLIPPER_UTILS_TIME_LIMIT_DEFAULT);
|
||||||
|
@ -641,7 +641,6 @@ void traverse_pt(const ClipperLib::PolyNodes &nodes, ExOrJustPolygons *retval)
|
|||||||
|
|
||||||
/* OTHER */
|
/* OTHER */
|
||||||
Slic3r::Polygons simplify_polygons(const Slic3r::Polygons &subject);
|
Slic3r::Polygons simplify_polygons(const Slic3r::Polygons &subject);
|
||||||
Slic3r::ExPolygons simplify_polygons_ex(const Slic3r::Polygons &subject);
|
|
||||||
|
|
||||||
Polygons top_level_islands(const Slic3r::Polygons &polygons);
|
Polygons top_level_islands(const Slic3r::Polygons &polygons);
|
||||||
|
|
||||||
|
@ -135,8 +135,39 @@ ExPolygon get_simplified(const ExPolygon &island, const SampleConfig &config) {
|
|||||||
//// "Close" operation still create neighbor pixel for sharp triangle tip - cause VD issues
|
//// "Close" operation still create neighbor pixel for sharp triangle tip - cause VD issues
|
||||||
|
|
||||||
ExPolygons simplified_expolygons = island.simplify(config.simplification_tolerance);
|
ExPolygons simplified_expolygons = island.simplify(config.simplification_tolerance);
|
||||||
return simplified_expolygons.empty() ?
|
if (simplified_expolygons.empty())
|
||||||
island : get_expolygon_with_biggest_contour(simplified_expolygons);
|
return island;
|
||||||
|
|
||||||
|
ExPolygon biggest = get_expolygon_with_biggest_contour(simplified_expolygons);
|
||||||
|
|
||||||
|
// NOTE: Order of polygon is different for Windows and Linux
|
||||||
|
// to unify behavior one have to sort holes
|
||||||
|
std::sort(biggest.holes.begin(), biggest.holes.end(),
|
||||||
|
// first sort by size of polygons than by coordinates of points
|
||||||
|
[](const Polygon &polygon1, const Polygon &polygon2) {
|
||||||
|
if (polygon1.size() > polygon2.size())
|
||||||
|
return true;
|
||||||
|
if (polygon1.size() < polygon2.size())
|
||||||
|
return false;
|
||||||
|
// NOTE: polygon1.size() == polygon2.size()
|
||||||
|
for (size_t point_index = 0; point_index < polygon1.size(); ++point_index) {
|
||||||
|
const Point &p1 = polygon1[point_index];
|
||||||
|
const Point &p2 = polygon2[point_index];
|
||||||
|
if (p1.x() > p2.x())
|
||||||
|
return true;
|
||||||
|
if (p1.x() < p2.x())
|
||||||
|
return false;
|
||||||
|
// NOTE: p1.x() == p2.x()
|
||||||
|
if (p1.y() > p2.y())
|
||||||
|
return true;
|
||||||
|
if (p1.y() < p2.y())
|
||||||
|
return false;
|
||||||
|
// NOTE: p1 == p2 check next point
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return biggest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user