ENH: improve tree supports

1. speedup organic tree support by using parallel for intersection of bed area
jira: STUDIO-8451
2. add extra wall for hybrid tree support's tall branches
3. disable circle fitting for tree support. This feature produces inconsistent
   circles for tree supports.
4. expose the option tree_support_branch_diameter_angle. Tree supports'
   strength can be improved by increasing this value.

Change-Id: If3688ca895df98a77f6ca538077daf8fe94e53f1
(cherry picked from commit 7697eb3dc8f87204d28e6be9adaf55dfcdadbc74)
This commit is contained in:
Arthur
2024-10-15 14:48:31 +08:00
committed by Noisyfox
parent 07c7e2f910
commit 1c686b3c04
9 changed files with 49 additions and 108 deletions

View File

@@ -1417,6 +1417,10 @@ SupportGeneratorLayersPtr generate_support_layers(
append(layers_sorted, intermediate_layers);
append(layers_sorted, interface_layers);
append(layers_sorted, base_interface_layers);
// remove dupliated layers
std::sort(layers_sorted.begin(), layers_sorted.end());
layers_sorted.erase(std::unique(layers_sorted.begin(), layers_sorted.end()), layers_sorted.end());
// Sort the layers lexicographically by a raising print_z and a decreasing height.
std::sort(layers_sorted.begin(), layers_sorted.end(), [](auto *l1, auto *l2) { return *l1 < *l2; });
int layer_id = 0;
@@ -1648,7 +1652,7 @@ void generate_support_toolpaths(
{
SupportLayer &support_layer = *support_layers[support_layer_id];
LayerCache &layer_cache = layer_caches[support_layer_id];
const float support_interface_angle = support_params.support_style == smsGrid ?
const float support_interface_angle = (support_params.support_style == smsGrid || config.support_interface_pattern == smipRectilinear) ?
support_params.interface_angle : support_params.raft_interface_angle(support_layer.interface_id());
// Find polygons with the same print_z.
@@ -1785,7 +1789,7 @@ void generate_support_toolpaths(
// Base support or flange.
if (! base_layer.empty() && ! base_layer.polygons_to_extrude().empty()) {
Fill *filler = filler_support.get();
Fill *filler = filler_support.get();
filler->angle = angles[support_layer_id % angles.size()];
// We don't use $base_flow->spacing because we need a constant spacing
// value that guarantees that all layers are correctly aligned.
@@ -1811,7 +1815,11 @@ void generate_support_toolpaths(
sheath = true;
no_sort = true;
} else if (support_params.support_style == SupportMaterialStyle::smsTreeOrganic) {
tree_supports_generate_paths(base_layer.extrusions, base_layer.polygons_to_extrude(), flow, support_params);
// if the tree supports are too tall, use double wall to make it stronger
SupportParameters support_params2 = support_params;
if (support_layer.print_z > 100.0)
support_params2.tree_branch_diameter_double_wall_area_scaled = 0.1;
tree_supports_generate_paths(base_layer.extrusions, base_layer.polygons_to_extrude(), flow, support_params2);
done = true;
}
if (! done)

View File

@@ -1540,7 +1540,10 @@ void TreeSupport::generate_toolpaths()
erSupportMaterial, filler_support.get(), support_density);
}
else {
tree_supports_generate_paths(ts_layer->support_fills.entities, loops, flow, m_support_params);
SupportParameters support_params = m_support_params;
if (area_group.need_extra_wall && object_config.tree_support_wall_count.value == 0)
support_params.tree_branch_diameter_double_wall_area_scaled = 0.1;
tree_supports_generate_paths(ts_layer->support_fills.entities, loops, flow, support_params);
}
}
}
@@ -2917,6 +2920,10 @@ void TreeSupport::smooth_nodes()
}
float max_move = scale_(m_object_config->support_line_width / 2);
// if the branch is very tall, the tip also needs extra wall
float thresh_tall_branch = 100;
float thresh_dist_to_top = 30;
for (int layer_nr = 0; layer_nr< contact_nodes.size(); layer_nr++) {
std::vector<SupportNode *> &curr_layer_nodes = contact_nodes[layer_nr];
if (curr_layer_nodes.empty()) continue;
@@ -2926,17 +2933,20 @@ void TreeSupport::smooth_nodes()
std::vector<double> radii;
std::vector<SupportNode *> branch;
SupportNode * p_node = node;
float total_height = 0;
// add a fixed head if it's not a polygon node, see STUDIO-4403
// Polygon node can't be added because the move distance might be huge, making the nodes in between jump and dangling
if (node->child && node->child->type!=ePolygon) {
pts.push_back(p_node->child->position);
radii.push_back(p_node->child->radius);
branch.push_back(p_node->child);
total_height += p_node->child->height;
}
do {
pts.push_back(p_node->position);
radii.push_back(p_node->radius);
branch.push_back(p_node);
total_height += p_node->height;
p_node = p_node->parent;
} while (p_node && !p_node->is_processed);
if (pts.size() < 3) continue;
@@ -2955,7 +2965,8 @@ void TreeSupport::smooth_nodes()
branch[i]->radius = radii1[i];
branch[i]->movement = (pts[i + 1] - pts[i - 1]) / 2;
branch[i]->is_processed = true;
if (branch[i]->parents.size()>1 || (branch[i]->movement.x() > max_move || branch[i]->movement.y() > max_move))
if (branch[i]->parents.size() > 1 || (branch[i]->movement.x() > max_move || branch[i]->movement.y() > max_move) ||
(total_height > thresh_tall_branch && branch[i]->dist_mm_to_top < thresh_dist_to_top))
branch[i]->need_extra_wall = true;
BOOST_LOG_TRIVIAL(info) << "smooth_nodes: layer_nr=" << layer_nr << ", i=" << i << ", pt=" << pt << ", movement=" << branch[i]->movement << ", radius=" << branch[i]->radius;
}

View File

@@ -36,6 +36,7 @@
#include <tbb/parallel_for.h>
#include <tbb/parallel_for_each.h>
#include <tbb/spin_mutex.h>
#if defined(TREE_SUPPORT_SHOW_ERRORS) && defined(_WIN32)
#define TREE_SUPPORT_SHOW_ERRORS_WIN32
@@ -3551,7 +3552,9 @@ static void generate_support_areas(Print &print, TreeSupport* tree_support, cons
print.set_status(69, _L("Generating support"));
generate_support_toolpaths(print_object.support_layers(), print_object.config(), support_params, print_object.slicing_parameters(),
raft_layers, bottom_contacts, top_contacts, intermediate_layers, interface_layers, base_interface_layers);
auto t_end = std::chrono::high_resolution_clock::now();
BOOST_LOG_TRIVIAL(info) << "Total time of organic tree support: " << 0.001 * std::chrono::duration_cast<std::chrono::microseconds>(t_end - t_start).count() << " ms";
#if 0
//#ifdef SLIC3R_DEBUG
{

View File

@@ -87,7 +87,7 @@ struct TreeSupportMeshGroupSettings {
this->support_tree_angle = std::clamp<double>(config.tree_support_branch_angle_organic * M_PI / 180., 0., 0.5 * M_PI - EPSILON);
this->support_tree_angle_slow = std::clamp<double>(config.tree_support_angle_slow * M_PI / 180., 0., this->support_tree_angle - EPSILON);
this->support_tree_branch_diameter = scaled<coord_t>(config.tree_support_branch_diameter_organic.value);
this->support_tree_branch_diameter_angle = std::clamp<double>(config.tree_support_branch_diameter_angle * M_PI / 180., 0., 0.5 * M_PI - EPSILON);
this->support_tree_branch_diameter_angle = std::clamp<double>(config.tree_support_branch_diameter_angle * M_PI / 180., 0., 0.5 * M_PI - EPSILON);
this->support_tree_top_rate = config.tree_support_top_rate.value; // percent
// this->support_tree_tip_diameter = this->support_line_width;
this->support_tree_tip_diameter = std::clamp(scaled<coord_t>(config.tree_support_tip_diameter.value), (coord_t)0, this->support_tree_branch_diameter);