From bb48983e91e90ecafd6a0f30abbff58b198130b3 Mon Sep 17 00:00:00 2001 From: Arthur Date: Sat, 24 Dec 2022 19:16:53 +0800 Subject: [PATCH] ENH: improve generate_contact_points tree support 1. Previously we used integer Point type to detect corner, which was wrong. 2. Delete duplicate points more aggressively to prevent too many points around curved overhangs. 3. Do not generate roof_1st_layers if there is no interface at all. Change-Id: I1167ac04c533ec8f29dc9e656ba7072d1b54197f (cherry picked from commit 1329347c4bf9c8207cf21e591a6ad113bb565673) --- src/libslic3r/TreeSupport.cpp | 43 +++++++++++++++++++++-------------- src/libslic3r/TreeSupport.hpp | 3 ++- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/libslic3r/TreeSupport.cpp b/src/libslic3r/TreeSupport.cpp index a9b06ac67..7c51520cf 100644 --- a/src/libslic3r/TreeSupport.cpp +++ b/src/libslic3r/TreeSupport.cpp @@ -1597,8 +1597,11 @@ void TreeSupport::generate_toolpaths() filler_support->spacing = support_flow.spacing(); Flow flow = (layer_id == 0 && m_raft_layers == 0) ? m_object->print()->brim_flow() : support_flow; if (area_group.dist_to_top < 10 && !with_infill && m_object_config->support_style!=smsTreeHybrid) { - // at least 2 walls for the top tips - make_perimeter_and_inner_brim(ts_layer->support_fills.entities, poly, std::max(wall_count, size_t(2)), flow, erSupportMaterial); + if (area_group.dist_to_top < 5) // 1 wall at the top <5mm + make_perimeter_and_inner_brim(ts_layer->support_fills.entities, poly, 1, flow, erSupportMaterial); + else // at least 2 walls for range [5,10) + make_perimeter_and_inner_brim(ts_layer->support_fills.entities, poly, std::max(wall_count, size_t(2)), flow, erSupportMaterial); + } else { if (with_infill && layer_id > 0 && m_support_params.base_fill_pattern != ipLightning) { filler_support->angle = Geometry::deg2rad(object_config.support_angle.value); @@ -3327,7 +3330,9 @@ void TreeSupport::generate_contact_points(std::vector 0) + support_roof_layers += 1; // BBS: add a normal support layer below interface (if we have interface) coordf_t thresh_angle = config.support_threshold_angle.value < EPSILON ? 30.f : config.support_threshold_angle.value; coordf_t half_overhang_distance = scale_(tan(thresh_angle * M_PI / 180.0) * layer_height / 2); @@ -3419,32 +3424,36 @@ void TreeSupport::generate_contact_points(std::vectoroverhang_types[&overhang_part] == TreeSupportLayer::Detected) { // add points at corners auto &points = overhang_part.contour.points; - for (int i = 0; i < points.size(); i++) { + int nSize = points.size(); + for (int i = 0; i < nSize; i++) { auto pt = points[i]; - auto v1 = (pt - points[(i - 1 + points.size()) % points.size()]).normalized(); - auto v2 = (pt - points[(i + 1) % points.size()]).normalized(); - if (v1.dot(v2) > -0.7) { + auto v1 = (pt - points[(i - 1 + nSize) % nSize]).cast().normalized(); + auto v2 = (pt - points[(i + 1) % nSize]).cast().normalized(); + if (v1.dot(v2) > -0.7) { // angle smaller than 135 degrees Node *contact_node = new Node(pt, -z_distance_top_layers, layer_nr % 2, support_roof_layers + z_distance_top_layers, true, Node::NO_PARENT, print_z, height, z_distance_top); contact_node->overhang = &overhang_part; + contact_node->is_corner = true; curr_nodes.emplace_back(contact_node); } } } if(ts_layer->overhang_types[&overhang_part] == TreeSupportLayer::Enforced || is_slim){ // remove close points in Enforcers - auto above_nodes = contact_nodes[layer_nr - 1]; - if (!curr_nodes.empty() && !above_nodes.empty()) { + // auto above_nodes = contact_nodes[layer_nr - 1]; + if (!curr_nodes.empty() /*&& !above_nodes.empty()*/) { for (auto it = curr_nodes.begin(); it != curr_nodes.end();) { bool is_duplicate = false; - Slic3r::Vec3f curr_pt((*it)->position(0), (*it)->position(1), scale_((*it)->print_z)); - for (auto &pt : all_nodes) { - auto dif = curr_pt - pt; - if (dif.norm() < scale_(2)) { - delete (*it); - it = curr_nodes.erase(it); - is_duplicate = true; - break; + if (!(*it)->is_corner) { + Slic3r::Vec3f curr_pt((*it)->position(0), (*it)->position(1), scale_((*it)->print_z)); + for (auto &pt : all_nodes) { + auto dif = curr_pt - pt; + if (dif.norm() < point_spread / 2) { + delete (*it); + it = curr_nodes.erase(it); + is_duplicate = true; + break; + } } } if (!is_duplicate) it++; diff --git a/src/libslic3r/TreeSupport.hpp b/src/libslic3r/TreeSupport.hpp index cbaa0bcf3..b725b8422 100644 --- a/src/libslic3r/TreeSupport.hpp +++ b/src/libslic3r/TreeSupport.hpp @@ -270,7 +270,8 @@ public: mutable double radius = 0.0; mutable double max_move_dist = 0.0; NodeType type = eCircle; - bool is_merged = false; // this node is generated by merging upper nodes + bool is_merged = false; // this node is generated by merging upper nodes + bool is_corner = false; const ExPolygon* overhang = nullptr; // when type==ePolygon, set this value to get original overhang area /*!