ENH: improve is_support_necessary

Use tree support to detect if there are sharp tails and so on.

Jira: STUDIO-1898

Change-Id: I148e14ca4024849875133a646a8fdd36c265b2fb
(cherry picked from commit bc74015d45e96e409d34d611876e3a24e289e029)
This commit is contained in:
Arthur 2023-01-04 17:58:18 +08:00 committed by Lane.Wei
parent 43ba4b0712
commit 81ee7bb99b
3 changed files with 29 additions and 11 deletions

View file

@ -2388,7 +2388,7 @@ void PrintObject::_generate_support_material()
support_material.generate(*this); support_material.generate(*this);
TreeSupport tree_support(*this, m_slicing_params); TreeSupport tree_support(*this, m_slicing_params);
tree_support.generate_support_areas(); tree_support.generate();
} }
// BBS // BBS
@ -2544,6 +2544,7 @@ template void PrintObject::remove_bridges_from_contacts<Polygons>(
SupportNecessaryType PrintObject::is_support_necessary() SupportNecessaryType PrintObject::is_support_necessary()
{ {
#if 0
static const double super_overhang_area_threshold = SQ(scale_(5.0)); static const double super_overhang_area_threshold = SQ(scale_(5.0));
double threshold_rad = (m_config.support_threshold_angle.value < EPSILON ? 30 : m_config.support_threshold_angle.value + 1) * M_PI / 180.; double threshold_rad = (m_config.support_threshold_angle.value < EPSILON ? 30 : m_config.support_threshold_angle.value + 1) * M_PI / 180.;
@ -2626,7 +2627,14 @@ SupportNecessaryType PrintObject::is_support_necessary()
if (!exceed_overhang.empty()) if (!exceed_overhang.empty())
return LargeOverhang; return LargeOverhang;
} }
#else
TreeSupport tree_support(*this, m_slicing_params);
tree_support.detect_overhangs();
if (tree_support.has_sharp_tails)
return SharpTail;
else if (tree_support.has_cantilever)
return LargeOverhang;
#endif
return NoNeedSupp; return NoNeedSupp;
} }

View file

@ -708,7 +708,7 @@ TreeSupport::TreeSupport(PrintObject& object, const SlicingParameters &slicing_p
#define SUPPORT_SURFACES_OFFSET_PARAMETERS ClipperLib::jtSquare, 0. #define SUPPORT_SURFACES_OFFSET_PARAMETERS ClipperLib::jtSquare, 0.
void TreeSupport::detect_object_overhangs() void TreeSupport::detect_overhangs()
{ {
// overhangs are already detected // overhangs are already detected
if (m_object->support_layer_count() >= m_object->layer_count()) if (m_object->support_layer_count() >= m_object->layer_count())
@ -719,12 +719,11 @@ void TreeSupport::detect_object_overhangs()
m_object->clear_tree_support_preview_cache(); m_object->clear_tree_support_preview_cache();
create_tree_support_layers(); create_tree_support_layers();
m_ts_data = m_object->alloc_tree_support_preview_cache();
m_ts_data->is_slim = is_slim;
const PrintObjectConfig& config = m_object->config(); const PrintObjectConfig& config = m_object->config();
SupportType stype = config.support_type.value; SupportType stype = config.support_type.value;
const coordf_t radius_sample_resolution = m_ts_data->m_radius_sample_resolution; const coordf_t radius_sample_resolution = g_config_tree_support_collision_resolution;
const coordf_t extrusion_width = config.line_width.value; const coordf_t extrusion_width = config.line_width.value;
const coordf_t extrusion_width_scaled = scale_(extrusion_width); const coordf_t extrusion_width_scaled = scale_(extrusion_width);
const coordf_t max_bridge_length = scale_(config.max_bridge_length.value); const coordf_t max_bridge_length = scale_(config.max_bridge_length.value);
@ -983,6 +982,9 @@ void TreeSupport::detect_object_overhangs()
layer->sharp_tails.push_back(expoly); layer->sharp_tails.push_back(expoly);
layer->sharp_tails_height.insert({ &expoly, accum_height }); layer->sharp_tails_height.insert({ &expoly, accum_height });
append(overhang_areas, overhang); append(overhang_areas, overhang);
if (!overhang.empty())
has_sharp_tails = true;
#ifdef SUPPORT_TREE_DEBUG_TO_SVG #ifdef SUPPORT_TREE_DEBUG_TO_SVG
SVG svg(get_svg_filename(std::to_string(layer->print_z), "sharp_tail"), m_object->bounding_box()); 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");
@ -1148,8 +1150,8 @@ void TreeSupport::detect_object_overhangs()
break; break;
SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers); SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers);
auto layer = m_object->get_layer(layer_nr);
if (support_critical_regions_only) { if (support_critical_regions_only) {
auto layer = m_object->get_layer(layer_nr);
auto lower_layer = layer->lower_layer; auto lower_layer = layer->lower_layer;
if (lower_layer == nullptr) if (lower_layer == nullptr)
ts_layer->overhang_areas = layer->sharp_tails; ts_layer->overhang_areas = layer->sharp_tails;
@ -1181,6 +1183,7 @@ void TreeSupport::detect_object_overhangs()
} }
if (!ts_layer->overhang_areas.empty()) has_overhangs = true; if (!ts_layer->overhang_areas.empty()) has_overhangs = true;
if (!layer->cantilevers.empty()) has_cantilever = true;
} }
#ifdef SUPPORT_TREE_DEBUG_TO_SVG #ifdef SUPPORT_TREE_DEBUG_TO_SVG
@ -1887,7 +1890,7 @@ Polygons TreeSupport::contact_nodes_to_polygon(const std::vector<Node*>& contact
} }
void TreeSupport::generate_support_areas() void TreeSupport::generate()
{ {
bool tree_support_enable = m_object_config->enable_support.value && is_tree(m_object_config->support_type.value); bool tree_support_enable = m_object_config->enable_support.value && is_tree(m_object_config->support_type.value);
if (!tree_support_enable) if (!tree_support_enable)
@ -1900,9 +1903,14 @@ void TreeSupport::generate_support_areas()
// Generate overhang areas // Generate overhang areas
profiler.stage_start(STAGE_DETECT_OVERHANGS); profiler.stage_start(STAGE_DETECT_OVERHANGS);
m_object->print()->set_status(55, _L("Support: detect overhangs")); m_object->print()->set_status(55, _L("Support: detect overhangs"));
detect_object_overhangs(); detect_overhangs();
profiler.stage_finish(STAGE_DETECT_OVERHANGS); profiler.stage_finish(STAGE_DETECT_OVERHANGS);
if (!has_overhangs) return;
m_ts_data = m_object->alloc_tree_support_preview_cache();
m_ts_data->is_slim = is_slim;
// Generate contact points of tree support // Generate contact points of tree support
profiler.stage_start(STAGE_GENERATE_CONTACT_NODES); profiler.stage_start(STAGE_GENERATE_CONTACT_NODES);
m_object->print()->set_status(56, _L("Support: generate contact points")); m_object->print()->set_status(56, _L("Support: generate contact points"));

View file

@ -206,9 +206,9 @@ public:
* \param storage The data storage where the mesh data is gotten from and * \param storage The data storage where the mesh data is gotten from and
* where the resulting support areas are stored. * where the resulting support areas are stored.
*/ */
void generate_support_areas(); void generate();
void detect_object_overhangs(); void detect_overhangs();
enum NodeType { enum NodeType {
eCircle, eCircle,
@ -372,6 +372,8 @@ public:
int avg_node_per_layer = 0; int avg_node_per_layer = 0;
float nodes_angle = 0; float nodes_angle = 0;
bool has_overhangs = false; bool has_overhangs = false;
bool has_sharp_tails = false;
bool has_cantilever = false;
std::unique_ptr<FillLightning::Generator> generator; std::unique_ptr<FillLightning::Generator> generator;
std::unordered_map<double, size_t> printZ_to_lightninglayer; std::unordered_map<double, size_t> printZ_to_lightninglayer;