Skip to content

Commit

Permalink
ENH: improve generate_contact_points tree support
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
ArthurBambulab authored and lanewei120 committed Dec 26, 2022
1 parent 5998ab4 commit 7c7e113
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 18 deletions.
43 changes: 26 additions & 17 deletions src/libslic3r/TreeSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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++;
Expand Down
3 changes: 2 additions & 1 deletion src/libslic3r/TreeSupport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,8 @@ class TreeSupport
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

/*!
Expand Down

0 comments on commit 7c7e113

Please sign in to comment.