FIX: wrong cantilever check of circular ring overhangs

jira: STUDIO-10240
Change-Id: Ic4ff176a017e0aa7333404e1f5eec6cac6700484
This commit is contained in:
jiaxi.chen 2025-02-10 17:58:07 +08:00 committed by lane.wei
parent f2cb4f747c
commit 05365a7a3f
1 changed files with 38 additions and 12 deletions

View File

@ -927,22 +927,48 @@ void TreeSupport::detect_overhangs(bool check_support_necessity/* = false*/)
// check cantilever
auto lower_layer_support_thresh = offset_ex(lower_polys, extrusion_width_scaled, SUPPORT_SURFACES_OFFSET_PARAMETERS);
// lower_layer_offset may be very small, so we need to do max and then add 0.1
lower_layer_offseted = offset_ex(lower_layer_offseted, scale_(std::max(extrusion_width - lower_layer_offset, 0.) + 0.1));
for (ExPolygon& poly : overhangs_all_layers[layer_nr]) {
for (ExPolygon &poly : overhangs_all_layers[layer_nr]) {
// check if there is some contour that is totally floating
bool is_cantilever = false;
double dist_max = 0;
for (size_t i = 0; i < poly.num_contours(); i++) {
Polygon contour = poly.contour_or_hole(i);
bool is_floating = true;
double tmp_dist_max = 0;
for (const auto &pt : contour.points) {
if (is_inside_ex(lower_layer_support_thresh, pt)) {
is_floating = false;
break;
} else
tmp_dist_max = std::max(tmp_dist_max, (projection_onto(lower_layer_support_thresh, pt) - pt).cast<double>().norm());
}
if (is_floating) {
is_cantilever = true;
dist_max = tmp_dist_max;
break;
}
}
if (!is_cantilever) {
dist_max = 0;
auto cluster_boundary_ex = intersection_ex(poly, lower_layer_offseted);
Polygons cluster_boundary = to_polygons(cluster_boundary_ex);
if (cluster_boundary.empty()) continue;
double dist_max = 0;
for (auto& pt : poly.contour.points) {
for (auto &pt : poly.contour.points) {
double dist_pt = std::numeric_limits<double>::max();
for (auto& ply : cluster_boundary) {
for (auto &ply : cluster_boundary) {
double d = ply.distance_to(pt);
dist_pt = std::min(dist_pt, d);
}
dist_max = std::max(dist_max, dist_pt);
}
if (dist_max > scale_(3)) { // is cantilever if the farmost point is larger than 3mm away from base
is_cantilever = dist_max > scale_(3);
}
// is cantilever if the farmost point is larger than 3mm away from base or some contour is totally floating
if (is_cantilever) {
max_cantilever_dist = std::max(max_cantilever_dist, dist_max);
layer->cantilevers.emplace_back(poly);
BOOST_LOG_TRIVIAL(debug) << "found a cantilever cluster. layer_nr=" << layer_nr << dist_max;