diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp index fd23142e0d..5bce5d18dd 100644 --- a/src/libslic3r/ClipperUtils.cpp +++ b/src/libslic3r/ClipperUtils.cpp @@ -780,6 +780,8 @@ Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polyg { return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::ExPolygonProvider(subject), ClipperUtils::SinglePathProvider(clip.points), do_safety_offset); } Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset) { return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::ExPolygonProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); } +Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygon &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset) + { return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::ExPolygonProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); } Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset) { return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); } Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset) diff --git a/src/libslic3r/ClipperUtils.hpp b/src/libslic3r/ClipperUtils.hpp index 70dec5dd99..1f22d943d0 100644 --- a/src/libslic3r/ClipperUtils.hpp +++ b/src/libslic3r/ClipperUtils.hpp @@ -454,6 +454,7 @@ Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Surfac Slic3r::ExPolygons diff_ex(const Slic3r::Polygon &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygon &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); +Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygon &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); diff --git a/src/libslic3r/SLA/SupportPointGenerator.cpp b/src/libslic3r/SLA/SupportPointGenerator.cpp index ae138210f5..3dea8993c9 100644 --- a/src/libslic3r/SLA/SupportPointGenerator.cpp +++ b/src/libslic3r/SLA/SupportPointGenerator.cpp @@ -333,22 +333,15 @@ void support_peninsulas(const Peninsulas& peninsulas, NearPoints& near_points, f } /// -/// Copy parts from link to output +/// Copy parts shapes from link to output /// /// Links between part of mesh -/// Collected polygons from links -Polygons get_polygons(const PartLinks& part_links) { - size_t cnt = 0; +/// Collected expolygons from links +ExPolygons get_shapes(const PartLinks& part_links) { + ExPolygons out; + out.reserve(part_links.size()); for (const PartLink &part_link : part_links) - cnt += 1 + part_link->shape->holes.size(); - - Polygons out; - out.reserve(cnt); - for (const PartLink &part_link : part_links) { - const ExPolygon &shape = *part_link->shape; - out.emplace_back(shape.contour); - append(out, shape.holes); - } + out.push_back(*part_link->shape); // copy return out; } @@ -413,13 +406,13 @@ Points sample_overhangs(const LayerPart& part, double dist2) { const ExPolygon &shape = *part.shape; // Collect previous expolygons by links collected in loop before - Polygons prev_polygons = get_polygons(part.prev_parts); - assert(!prev_polygons.empty()); - ExPolygons overhangs = diff_ex(shape, prev_polygons); + ExPolygons prev_shapes = get_shapes(part.prev_parts); + assert(!prev_shapes.empty()); + ExPolygons overhangs = diff_ex(shape, prev_shapes); if (overhangs.empty()) // above part is smaller in whole contour return {}; - Points prev_points = to_points(prev_polygons); + Points prev_points = to_points(prev_shapes); std::sort(prev_points.begin(), prev_points.end()); // TODO: solve case when shape and prev points has same point @@ -569,14 +562,17 @@ void remove_supports_out_of_part(NearPoints &near_points, const LayerPart &part, /// supported distance from mainland void create_peninsulas(LayerPart &part, const PrepareSupportConfig &config) { assert(config.peninsula_min_width > config.peninsula_self_supported_width); - const Polygons below_polygons = get_polygons(part.prev_parts); - const Polygons below_expanded = expand(below_polygons, config.peninsula_min_width, ClipperLib::jtSquare); + const ExPolygons below_shapes = get_shapes(part.prev_parts); + const ExPolygons below_expanded = offset_ex(below_shapes, config.peninsula_min_width, ClipperLib::jtSquare); const ExPolygon &part_shape = *part.shape; ExPolygons over_peninsula = diff_ex(part_shape, below_expanded); if (over_peninsula.empty()) return; // only tiny overhangs - Polygons below_self_supported = expand(below_polygons, config.peninsula_self_supported_width, ClipperLib::jtSquare); + ExPolygons below_self_supported = offset_ex(below_shapes, config.peninsula_self_supported_width, ClipperLib::jtSquare); + // exist weird edge case, where expand function return empty result + assert(below_self_supported.empty()); + // exist layer part over peninsula limit ExPolygons peninsulas_shape = diff_ex(part_shape, below_self_supported); @@ -603,6 +599,9 @@ void create_peninsulas(LayerPart &part, const PrepareSupportConfig &config) { // False .. line is made by border of current layer part(peninsula coast) auto exist_belowe = [&get_angle, &idx, &is_lower, &below_lines, &belowe_line_angle] (const Line &l) { + // It is edge case of expand + if (below_lines.empty()) + return false; // allowed angle epsilon const double angle_epsilon = 1e-3; // < 0.06 DEG const double paralel_epsilon = scale_(1e-2); // 10 um @@ -871,8 +870,8 @@ size_t get_index_of_closest_part(const Point &coor, const LayerParts &parts, dou // check point lais inside prev or next part shape // When assert appear check that part index is really the correct one assert(union_ex( - get_polygons(parts[part_index].prev_parts), - get_polygons(parts[part_index].next_parts))[0].contains(coor)); + get_shapes(parts[part_index].prev_parts), + get_shapes(parts[part_index].next_parts))[0].contains(coor)); return part_index; } @@ -958,8 +957,8 @@ LayerParts::const_iterator get_closest_part(const PartLinks &links, Vec2d &coor) // check point lais inside prev or next part shape // When assert appear check that part index is really the correct one assert(union_ex( - get_polygons(links[part_index]->prev_parts), - get_polygons(links[part_index]->next_parts))[0].contains(coor.cast())); + get_shapes(links[part_index]->prev_parts), + get_shapes(links[part_index]->next_parts))[0].contains(coor.cast())); coor = hit_point; // update closest point return links[part_index]; }