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)
This commit is contained in:
Arthur 2022-12-24 19:16:53 +08:00 committed by Lane.Wei
parent 4385a8b33e
commit bb48983e91
2 changed files with 28 additions and 18 deletions

View File

@ -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<std::vector<TreeSupport::N
}
const int z_distance_top_layers = round_up_divide(scale_(z_distance_top), scale_(layer_height)) + 1; //Support must always be 1 layer below overhang.
const size_t support_roof_layers = config.support_interface_top_layers.value + 1; // BBS: add a normal support layer below interface
size_t support_roof_layers = config.support_interface_top_layers.value;
if (support_roof_layers > 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::vector<std::vector<TreeSupport::N
if (ts_layer->overhang_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<double>().normalized();
auto v2 = (pt - points[(i + 1) % nSize]).cast<double>().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++;

View File

@ -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
/*!