mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 12:39:04 +08:00
Exist weird edge case, where expand function return empty result even when input is not empty.
Fix crash for files: SPE-2518_SLA-Crash-3DBenchy.3mf SPE-2518_SLA-Crash-RAB_2_pose_3.3mf + use expolygons as input for expanding layer part instead of polygons
This commit is contained in:
parent
5dec0ea57a
commit
8f9bc6ddbe
@ -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); }
|
{ 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)
|
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); }
|
{ 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)
|
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); }
|
{ 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)
|
Slic3r::ExPolygons diff_ex(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset)
|
||||||
|
@ -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::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::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::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::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::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);
|
Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
|
||||||
|
@ -333,22 +333,15 @@ void support_peninsulas(const Peninsulas& peninsulas, NearPoints& near_points, f
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Copy parts from link to output
|
/// Copy parts shapes from link to output
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="part_links">Links between part of mesh</param>
|
/// <param name="part_links">Links between part of mesh</param>
|
||||||
/// <returns>Collected polygons from links</returns>
|
/// <returns>Collected expolygons from links</returns>
|
||||||
Polygons get_polygons(const PartLinks& part_links) {
|
ExPolygons get_shapes(const PartLinks& part_links) {
|
||||||
size_t cnt = 0;
|
ExPolygons out;
|
||||||
|
out.reserve(part_links.size());
|
||||||
for (const PartLink &part_link : part_links)
|
for (const PartLink &part_link : part_links)
|
||||||
cnt += 1 + part_link->shape->holes.size();
|
out.push_back(*part_link->shape); // copy
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,13 +406,13 @@ Points sample_overhangs(const LayerPart& part, double dist2) {
|
|||||||
const ExPolygon &shape = *part.shape;
|
const ExPolygon &shape = *part.shape;
|
||||||
|
|
||||||
// Collect previous expolygons by links collected in loop before
|
// Collect previous expolygons by links collected in loop before
|
||||||
Polygons prev_polygons = get_polygons(part.prev_parts);
|
ExPolygons prev_shapes = get_shapes(part.prev_parts);
|
||||||
assert(!prev_polygons.empty());
|
assert(!prev_shapes.empty());
|
||||||
ExPolygons overhangs = diff_ex(shape, prev_polygons);
|
ExPolygons overhangs = diff_ex(shape, prev_shapes);
|
||||||
if (overhangs.empty()) // above part is smaller in whole contour
|
if (overhangs.empty()) // above part is smaller in whole contour
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
Points prev_points = to_points(prev_polygons);
|
Points prev_points = to_points(prev_shapes);
|
||||||
std::sort(prev_points.begin(), prev_points.end());
|
std::sort(prev_points.begin(), prev_points.end());
|
||||||
|
|
||||||
// TODO: solve case when shape and prev points has same point
|
// 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,
|
|||||||
/// <param name="self_supported_width">supported distance from mainland</param>
|
/// <param name="self_supported_width">supported distance from mainland</param>
|
||||||
void create_peninsulas(LayerPart &part, const PrepareSupportConfig &config) {
|
void create_peninsulas(LayerPart &part, const PrepareSupportConfig &config) {
|
||||||
assert(config.peninsula_min_width > config.peninsula_self_supported_width);
|
assert(config.peninsula_min_width > config.peninsula_self_supported_width);
|
||||||
const Polygons below_polygons = get_polygons(part.prev_parts);
|
const ExPolygons below_shapes = get_shapes(part.prev_parts);
|
||||||
const Polygons below_expanded = expand(below_polygons, config.peninsula_min_width, ClipperLib::jtSquare);
|
const ExPolygons below_expanded = offset_ex(below_shapes, config.peninsula_min_width, ClipperLib::jtSquare);
|
||||||
const ExPolygon &part_shape = *part.shape;
|
const ExPolygon &part_shape = *part.shape;
|
||||||
ExPolygons over_peninsula = diff_ex(part_shape, below_expanded);
|
ExPolygons over_peninsula = diff_ex(part_shape, below_expanded);
|
||||||
if (over_peninsula.empty())
|
if (over_peninsula.empty())
|
||||||
return; // only tiny overhangs
|
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
|
// exist layer part over peninsula limit
|
||||||
ExPolygons peninsulas_shape = diff_ex(part_shape, below_self_supported);
|
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)
|
// 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]
|
auto exist_belowe = [&get_angle, &idx, &is_lower, &below_lines, &belowe_line_angle]
|
||||||
(const Line &l) {
|
(const Line &l) {
|
||||||
|
// It is edge case of expand
|
||||||
|
if (below_lines.empty())
|
||||||
|
return false;
|
||||||
// allowed angle epsilon
|
// allowed angle epsilon
|
||||||
const double angle_epsilon = 1e-3; // < 0.06 DEG
|
const double angle_epsilon = 1e-3; // < 0.06 DEG
|
||||||
const double paralel_epsilon = scale_(1e-2); // 10 um
|
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
|
// check point lais inside prev or next part shape
|
||||||
// When assert appear check that part index is really the correct one
|
// When assert appear check that part index is really the correct one
|
||||||
assert(union_ex(
|
assert(union_ex(
|
||||||
get_polygons(parts[part_index].prev_parts),
|
get_shapes(parts[part_index].prev_parts),
|
||||||
get_polygons(parts[part_index].next_parts))[0].contains(coor));
|
get_shapes(parts[part_index].next_parts))[0].contains(coor));
|
||||||
return part_index;
|
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
|
// check point lais inside prev or next part shape
|
||||||
// When assert appear check that part index is really the correct one
|
// When assert appear check that part index is really the correct one
|
||||||
assert(union_ex(
|
assert(union_ex(
|
||||||
get_polygons(links[part_index]->prev_parts),
|
get_shapes(links[part_index]->prev_parts),
|
||||||
get_polygons(links[part_index]->next_parts))[0].contains(coor.cast<coord_t>()));
|
get_shapes(links[part_index]->next_parts))[0].contains(coor.cast<coord_t>()));
|
||||||
coor = hit_point; // update closest point
|
coor = hit_point; // update closest point
|
||||||
return links[part_index];
|
return links[part_index];
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user