From 0c2ba2b0a22610c411e411a0f78c1640df732894 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 24 Mar 2023 17:59:53 +0800 Subject: [PATCH] ENH: improve sharp detection for small regions 1. improve sharp detection for small regions. When the region is around 1 extrsion width, previous method may miss some sharp tails. Now we reduce the width threshold to 0.1*extrusion_width for sharp tails. When checking "nothing below", need to expand the poly a little. Example: benchy. 2. improve is_support_necessary. Only popup warning for sharp tail and large cantilever (longer than 6mm). Jira: STUDIO-2567 Change-Id: I5e977e7766b35409891d1b41e36278e3f07fa372 (cherry picked from commit c9d8a7c1c3bbd4367c7fc44408c67e5c534167f4) --- src/libslic3r/Print.hpp | 1 + src/libslic3r/PrintObject.cpp | 30 +++++++++++++----------------- src/libslic3r/SupportMaterial.cpp | 5 +++-- src/libslic3r/TreeSupport.cpp | 13 ++++++++++--- src/libslic3r/TreeSupport.hpp | 1 + 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index b68d0a95af..ef43affa10 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -51,6 +51,7 @@ struct groupedVolumeSlices enum SupportNecessaryType { NoNeedSupp=0, SharpTail, + Cantilever, LargeOverhang, }; diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 0988676e4d..3d6b0c3563 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -458,7 +458,7 @@ void PrintObject::generate_support_material() this->_generate_support_material(); m_print->throw_if_canceled(); - } else { + } else if(!m_print->get_no_check_flag()) { // BBS: pop a warning if objects have significant amount of overhangs but support material is not enabled m_print->set_status(50, L("Checking support necessity")); typedef std::chrono::high_resolution_clock clock_; @@ -468,20 +468,16 @@ void PrintObject::generate_support_material() SupportNecessaryType sntype = this->is_support_necessary(); double duration{ std::chrono::duration_cast(clock_::now() - t0).count() }; - BOOST_LOG_TRIVIAL(info) << std::fixed << std::setprecision(0) - << "is_support_necessary took " << (duration / 60) << " minutes and " - << std::setprecision(3) - << std::fmod(duration, 60.0) << " seconds." << std::endl; + BOOST_LOG_TRIVIAL(info) << std::fixed << std::setprecision(0) << "is_support_necessary takes " << duration << " secs."; if (sntype != NoNeedSupp) { - if (sntype == SharpTail) { - std::string warning_message = format(L("It seems object %s has completely floating regions. Please re-orient the object or enable support generation."), - this->model_object()->name); - this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, warning_message, PrintStateBase::SlicingNeedSupportOn); - } else { - std::string warning_message = format(L("It seems object %s has large overhangs. Please enable support generation."), this->model_object()->name); - this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, warning_message, PrintStateBase::SlicingNeedSupportOn); - } + std::map reasons = { + {SharpTail,L("floating regions")}, + {Cantilever,L("floating cantilever")}, + {LargeOverhang,L("large overhangs")} }; + std::string warning_message = format(L("It seems object %s has %s. Please re-orient the object or enable support generation."), + this->model_object()->name, reasons[sntype]); + this->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL, warning_message, PrintStateBase::SlicingNeedSupportOn); } #if 0 @@ -2580,9 +2576,9 @@ template void PrintObject::remove_bridges_from_contacts( SupportNecessaryType PrintObject::is_support_necessary() { -#if 0 static const double super_overhang_area_threshold = SQ(scale_(5.0)); - + const double cantilevel_dist_thresh = scale_(6); +#if 0 double threshold_rad = (m_config.support_threshold_angle.value < EPSILON ? 30 : m_config.support_threshold_angle.value + 1) * M_PI / 180.; int enforce_support_layers = m_config.enforce_support_layers; const coordf_t extrusion_width = m_config.line_width.value; @@ -2670,8 +2666,8 @@ SupportNecessaryType PrintObject::is_support_necessary() this->clear_support_layers(); if (tree_support.has_sharp_tails) return SharpTail; - else if (tree_support.has_cantilever) - return LargeOverhang; + else if (tree_support.has_cantilever && tree_support.max_cantilevel_dist > cantilevel_dist_thresh) + return Cantilever; #endif return NoNeedSupp; } diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index 71c35f2d6e..3c037ee8eb 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -1638,8 +1638,8 @@ static inline ExPolygons detect_overhangs( // 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({ expoly }, lower_layer_expolys)) { - is_sharp_tail = expoly.area() < area_thresh_well_supported && !offset_ex(expoly,-0.5*fw).empty(); + 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(); } if (is_sharp_tail) { @@ -2366,6 +2366,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_ if (layer->lower_layer == NULL) continue; Layer* lower_layer = layer->lower_layer; auto cluster_boundary = intersection(cluster.merged_overhangs_dilated, offset(lower_layer->lslices, scale_(0.5))); + if (cluster_boundary.empty()) continue; double dist_max = 0; Points cluster_pts; for (auto& poly : cluster.merged_overhangs_dilated) diff --git a/src/libslic3r/TreeSupport.cpp b/src/libslic3r/TreeSupport.cpp index 5c69ea1e56..4c37b2c3cd 100644 --- a/src/libslic3r/TreeSupport.cpp +++ b/src/libslic3r/TreeSupport.cpp @@ -898,8 +898,8 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only) bool is_sharp_tail = false; // 1. nothing below // this is a sharp tail region if it's small but non-ignorable - if (!overlaps({ expoly }, lower_polys)) { - is_sharp_tail = expoly.area() < area_thresh_well_supported && !offset_ex(expoly, -0.5 * 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) { @@ -912,7 +912,10 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only) 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"); + if (svg.is_opened()) { + svg.draw(overhang, "yellow"); + svg.draw(lower_layer->lslices, "red"); + } #endif } } @@ -1045,11 +1048,13 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only) m_object->project_and_append_custom_facets(false, EnforcerBlockerType::BLOCKER, blockers); // check whether the overhang cluster is cantilever (far awary from main body) + max_cantilevel_dist = 0; for (auto& cluster : overhangClusters) { Layer* layer = m_object->get_layer(cluster.min_layer); if (layer->lower_layer == NULL) continue; Layer* lower_layer = layer->lower_layer; auto cluster_boundary = intersection(cluster.merged_poly, offset(lower_layer->lslices, scale_(0.5))); + if (cluster_boundary.empty()) continue; double dist_max = 0; Points cluster_pts; for (auto& poly : cluster.merged_poly) @@ -1068,9 +1073,11 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only) auto p_overhang = it->second; m_object->get_layer(layer_nr)->cantilevers.emplace_back(*p_overhang); } + max_cantilevel_dist = std::max(max_cantilevel_dist, dist_max); cluster.is_cantilever = true; } } + BOOST_LOG_TRIVIAL(info) << "max_cantilevel_dist=" << max_cantilevel_dist; if (is_auto(stype) && g_config_remove_small_overhangs) { if (blockers.size() < m_object->layer_count()) diff --git a/src/libslic3r/TreeSupport.hpp b/src/libslic3r/TreeSupport.hpp index a114a45c5f..eb9c7f0c79 100644 --- a/src/libslic3r/TreeSupport.hpp +++ b/src/libslic3r/TreeSupport.hpp @@ -380,6 +380,7 @@ public: bool has_overhangs = false; bool has_sharp_tails = false; bool has_cantilever = false; + double max_cantilevel_dist = 0; SupportType support_type; SupportMaterialStyle support_style;