diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index 05542694b8..da76ea2f43 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -1634,25 +1634,28 @@ static inline ExPolygons detect_overhangs( //FIXME add user defined filtering here based on minimal area or minimum radius or whatever. // BBS - for (ExPolygon& expoly : layerm->raw_slices) { - bool is_sharp_tail = false; - float accum_height = layer.height; + if (g_config_support_sharp_tails) { + for (ExPolygon& expoly : layerm->raw_slices) { + if (offset_ex(expoly, -0.5 * fw).empty()) continue; + bool is_sharp_tail = false; + float accum_height = layer.height; - // 1. nothing below - // Check whether this is a sharp tail region. - // Should use lower_layer_expolys without any offset. Otherwise, it may missing sharp tails near the main body. - if (g_config_support_sharp_tails && !overlaps(offset_ex(expoly, 0.5 * fw), lower_layer_expolys)) { - is_sharp_tail = expoly.area() < area_thresh_well_supported && !offset_ex(expoly,-0.1*fw).empty(); - } + // 1. nothing below + // Check whether this is a sharp tail region. + // Should use lower_layer_expolys without any offset. Otherwise, it may missing sharp tails near the main body. + if (!overlaps(offset_ex(expoly, 0.5 * fw), lower_layer_expolys)) { + is_sharp_tail = expoly.area() < area_thresh_well_supported && !offset_ex(expoly, -0.1 * fw).empty(); + } - if (is_sharp_tail) { - ExPolygons overhang = diff_ex({ expoly }, lower_layer_polygons); - layer.sharp_tails.push_back(expoly); - layer.sharp_tails_height.insert({ &expoly, accum_height }); - overhang = offset_ex(overhang, 0.05 * fw); - polygons_append(diff_polygons, to_polygons(overhang)); + if (is_sharp_tail) { + ExPolygons overhang = diff_ex({ expoly }, lower_layer_expolys); + layer.sharp_tails.push_back(expoly); + layer.sharp_tails_height.insert({ &expoly, accum_height }); + overhang = offset_ex(overhang, 0.05 * fw); + polygons_append(diff_polygons, to_polygons(overhang)); + } } - } + } } if (diff_polygons.empty()) @@ -2269,15 +2272,12 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ const Layer* layer = object.get_layer(layer_nr); const Layer* lower_layer = layer->lower_layer; - // skip if: - // 1) if the current layer is already detected as sharp tails - // 2) lower layer has no sharp tails - if (!lower_layer || layer->sharp_tails.empty() == false || lower_layer->sharp_tails.empty() == true) + if (!lower_layer) continue; // BBS detect sharp tail const ExPolygons& lower_layer_sharptails = lower_layer->sharp_tails; - auto& lower_layer_sharptails_height = lower_layer->sharp_tails_height; + const auto& lower_layer_sharptails_height = lower_layer->sharp_tails_height; for (const ExPolygon& expoly : layer->lslices) { bool is_sharp_tail = false; float accum_height = layer->height; @@ -2308,13 +2308,13 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ } // 2.3 check whether sharp tail exceed the max height - for (auto& lower_sharp_tail_height : lower_layer_sharptails_height) { + for (const auto& lower_sharp_tail_height : lower_layer_sharptails_height) { if (lower_sharp_tail_height.first->overlaps(expoly)) { accum_height += lower_sharp_tail_height.second; break; } } - if (accum_height >= sharp_tail_max_support_height) { + if (accum_height > sharp_tail_max_support_height) { is_sharp_tail = false; break; } diff --git a/src/libslic3r/TreeSupport.cpp b/src/libslic3r/TreeSupport.cpp index 78c5012b5a..5c680ba721 100644 --- a/src/libslic3r/TreeSupport.cpp +++ b/src/libslic3r/TreeSupport.cpp @@ -864,9 +864,11 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only) } } ExPolygons curr_polys; + std::vector curr_poly_ptrs; for (const ExPolygon& expoly : layer->lslices) { if (!offset_ex(expoly, -extrusion_width_scaled / 2).empty()) { curr_polys.emplace_back(expoly); + curr_poly_ptrs.emplace_back(&expoly); } } @@ -879,28 +881,30 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only) overhang_areas.end()); - ExPolygons overhangs_sharp_tail; if (is_auto(stype) && g_config_support_sharp_tails) { // BBS detect sharp tail - const ExPolygons& lower_layer_sharptails = lower_layer->sharp_tails; - auto& lower_layer_sharptails_height = lower_layer->sharp_tails_height; - for (ExPolygon& expoly : layer->lslices) { + for (const ExPolygon* expoly : curr_poly_ptrs) { bool is_sharp_tail = false; // 1. nothing below // this is a sharp tail region if it's small but non-ignorable - if (!overlaps(offset_ex(expoly, 0.5 * extrusion_width_scaled), lower_polys)) { - is_sharp_tail = expoly.area() < area_thresh_well_supported && !offset_ex(expoly, -0.1 * extrusion_width_scaled).empty(); + if (!overlaps(offset_ex(*expoly, 0.5 * extrusion_width_scaled), lower_polys)) { + is_sharp_tail = expoly->area() < area_thresh_well_supported && !offset_ex(*expoly, -0.1 * extrusion_width_scaled).empty(); } if (is_sharp_tail) { - ExPolygons overhang = diff_ex({ expoly }, lower_layer->lslices); - layer->sharp_tails.push_back(expoly); - layer->sharp_tails_height.insert({ &expoly, layer->height }); + ExPolygons overhang = diff_ex({ *expoly }, lower_polys); + layer->sharp_tails.push_back(*expoly); + layer->sharp_tails_height.insert({ expoly, layer->height }); append(overhang_areas, overhang); - if (!overhang.empty()) + if (!overhang.empty()) { has_sharp_tails = true; +#ifdef SUPPORT_TREE_DEBUG_TO_SVG + SVG svg(format("SVG/sharp_tail_orig_%.02f.svg", layer->print_z), m_object->bounding_box()); + if (svg.is_opened()) svg.draw(overhang, "red"); +#endif + } } } } @@ -947,15 +951,12 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only) Layer* layer = m_object->get_layer(layer_nr); SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers); Layer* lower_layer = layer->lower_layer; - // skip if: - // 1) if the current layer is already detected as sharp tails - // 2) lower layer has no sharp tails - if (!lower_layer || layer->sharp_tails.empty() == false || lower_layer->sharp_tails.empty() == true) + if (!lower_layer) continue; // BBS detect sharp tail const ExPolygons& lower_layer_sharptails = lower_layer->sharp_tails; - auto& lower_layer_sharptails_height = lower_layer->sharp_tails_height; + const auto& lower_layer_sharptails_height = lower_layer->sharp_tails_height; for (ExPolygon& expoly : layer->lslices) { bool is_sharp_tail = false; float accum_height = layer->height; @@ -986,13 +987,13 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only) } // 2.3 check whether sharp tail exceed the max height - for (auto& lower_sharp_tail_height : lower_layer_sharptails_height) { + for (const auto& lower_sharp_tail_height : lower_layer_sharptails_height) { if (lower_sharp_tail_height.first->overlaps(expoly)) { accum_height += lower_sharp_tail_height.second; break; } } - if (accum_height >= sharp_tail_max_support_height) { + if (accum_height > sharp_tail_max_support_height) { is_sharp_tail = false; break; } @@ -1018,8 +1019,8 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only) if (!overhang.empty()) has_sharp_tails = true; #ifdef SUPPORT_TREE_DEBUG_TO_SVG - SVG svg(get_svg_filename(std::to_string(layer->print_z), "sharp_tail"), m_object->bounding_box()); - if (svg.is_opened()) svg.draw(overhang, "yellow"); + SVG svg(format("SVG/sharp_tail_%.02f.svg",layer->print_z), m_object->bounding_box()); + if (svg.is_opened()) svg.draw(overhang, "red"); #endif } @@ -1068,10 +1069,14 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only) const Layer* layer1 = m_object->get_layer(cluster.min_layer); BoundingBox bbox = cluster.merged_bbox; bbox.merge(get_extents(layer1->lslices)); - SVG svg(format("SVG/overhangCluster_%s_%s_tail=%s_cantilever=%s_small=%s.svg", cluster.min_layer, layer1->print_z, cluster.is_sharp_tail, cluster.is_cantilever, cluster.is_small_overhang), bbox); + SVG svg(format("SVG/overhangCluster_%s-%s_%s-%s_tail=%s_cantilever=%s_small=%s.svg", + cluster.min_layer, cluster.max_layer, layer1->print_z, m_object->get_layer(cluster.max_layer)->print_z, + cluster.is_sharp_tail, cluster.is_cantilever, cluster.is_small_overhang), bbox); if (svg.is_opened()) { svg.draw(layer1->lslices, "red"); svg.draw(cluster.merged_poly, "blue"); + svg.draw_text(bbox.min + Point(scale_(0), scale_(2)), "lslices", "red", 2); + svg.draw_text(bbox.min + Point(scale_(0), scale_(2)), "overhang", "blue", 2); } #endif