FIX: bugs fix

1. The logic of Normal Tree transition layers is not suitable for Organic Trees — they should be handled separately
2. 0 raft when using soluble materials

jira: STUDIO-12169
Change-Id: I433be3a9d7afed5594785d080b9b0bfe78ca82c8
This commit is contained in:
jiaxi.chen 2025-05-13 17:55:22 +08:00 committed by lane.wei
parent 573db9bf60
commit 729c4041f7
3 changed files with 81 additions and 33 deletions

View File

@ -118,9 +118,10 @@ std::pair<SupportGeneratorLayersPtr, SupportGeneratorLayersPtr> generate_interfa
}
return nullptr;
};
const bool istree = is_tree(config.support_type);
tbb::parallel_for(tbb::blocked_range<int>(0, int(intermediate_layers.size())),
[&bottom_contacts, &top_contacts, &top_interface_layers, &top_base_interface_layers, &intermediate_layers, &insert_layer, &support_params,
snug_supports, &interface_layers, &base_interface_layers](const tbb::blocked_range<int>& range) {
snug_supports, &interface_layers, &base_interface_layers, &istree](const tbb::blocked_range<int>& range) {
// Gather the top / bottom contact layers intersecting with num_interface_layers resp. num_interface_layers_only intermediate layers above / below
// this intermediate layer.
// Index of the first top contact layer intersecting the current intermediate layer.
@ -139,24 +140,54 @@ std::pair<SupportGeneratorLayersPtr, SupportGeneratorLayersPtr> generate_interfa
Polygons polygons_bottom_contact_projected_interface;
Polygons polygons_bottom_contact_projected_base;
if (support_params.num_top_interface_layers > 0) {
// Move idx_top_contact_first up until above the current print_z.
idx_top_contact_first = idx_higher_or_equal(top_contacts, idx_top_contact_first, [&intermediate_layer](const SupportGeneratorLayer *layer){ return layer->print_z >= intermediate_layer.print_z; }); // - EPSILON
// Collect the top contact areas above this intermediate layer, below top_z.
for (int idx_top_contact = idx_top_contact_first; idx_top_contact < int(top_contacts.size()); ++ idx_top_contact) {
const SupportGeneratorLayer &top_contact_layer = *top_contacts[idx_top_contact];
const bool is_top_contact = is_approx(top_contact_layer.bottom_z, intermediate_layers[num_intermediate - 1]->print_z);
if (is_top_contact) {
if (idx_intermediate_layer > num_intermediate - support_params.num_top_interface_layers)
polygons_append(polygons_top_contact_projected_interface, snug_supports ? *top_contact_layer.overhang_polygons : top_contact_layer.polygons);
else if (idx_intermediate_layer > num_intermediate - support_params.num_top_interface_layers - support_params.num_top_base_interface_layers)
polygons_append(polygons_top_contact_projected_base, snug_supports ? *top_contact_layer.overhang_polygons : top_contact_layer.polygons);
} else {
if (top_contact_layer.print_z - EPSILON <
intermediate_layers[std::min(int(idx_intermediate_layer + support_params.num_top_interface_layers - 1), num_intermediate - 1)]->print_z)
polygons_append(polygons_top_contact_projected_interface, snug_supports ? *top_contact_layer.overhang_polygons : top_contact_layer.polygons);
else if (top_contact_layer.print_z - EPSILON < intermediate_layers[std::min(int(idx_intermediate_layer + support_params.num_top_interface_layers -
1 + support_params.num_top_base_interface_layers),num_intermediate - 1)]->print_z)
polygons_append(polygons_top_contact_projected_base, snug_supports ? *top_contact_layer.overhang_polygons : top_contact_layer.polygons);
if (istree) {
// Top Z coordinate of a slab, over which we are collecting the top / bottom contact surfaces
coordf_t top_z = intermediate_layers[std::min(num_intermediate - 1, idx_intermediate_layer + int(support_params.num_top_interface_layers) - 1)]
->print_z;
coordf_t top_inteface_z = std::numeric_limits<coordf_t>::max();
if (support_params.num_top_base_interface_layers > 0)
// Some top base interface layers will be generated.
top_inteface_z =
support_params.num_top_interface_layers_only() == 0 ?
// Only base interface layers to generate.
-std::numeric_limits<coordf_t>::max() :
intermediate_layers[std::min(num_intermediate - 1, idx_intermediate_layer + int(support_params.num_top_interface_layers_only()) - 1)]
->print_z;
// Move idx_top_contact_first up until above the current print_z.
idx_top_contact_first = idx_higher_or_equal(top_contacts, idx_top_contact_first, [&intermediate_layer](const SupportGeneratorLayer *layer) {
return layer->print_z >= intermediate_layer.print_z;
}); // - EPSILON
// Collect the top contact areas above this intermediate layer, below top_z.
for (int idx_top_contact = idx_top_contact_first; idx_top_contact < int(top_contacts.size()); ++idx_top_contact) {
const SupportGeneratorLayer &top_contact_layer = *top_contacts[idx_top_contact];
// FIXME maybe this adds one interface layer in excess?
if (top_contact_layer.bottom_z - EPSILON > top_z) break;
polygons_append(top_contact_layer.bottom_z - EPSILON > top_inteface_z ? polygons_top_contact_projected_base :
polygons_top_contact_projected_interface,
// For snug supports, project the overhang polygons covering the whole overhang, so that they will merge without a gap with support
// polygons of the other layers. For grid supports, merging of support regions will be performed by the projection into grid.
snug_supports ? *top_contact_layer.overhang_polygons : top_contact_layer.polygons);
}
} else {
// Move idx_top_contact_first up until above the current print_z.
idx_top_contact_first = idx_higher_or_equal(top_contacts, idx_top_contact_first, [&intermediate_layer](const SupportGeneratorLayer *layer){ return layer->print_z >= intermediate_layer.print_z; }); // - EPSILON
// Collect the top contact areas above this intermediate layer, below top_z.
for (int idx_top_contact = idx_top_contact_first; idx_top_contact < int(top_contacts.size()); ++ idx_top_contact) {
const SupportGeneratorLayer &top_contact_layer = *top_contacts[idx_top_contact];
const bool is_top_contact = is_approx(top_contact_layer.bottom_z, intermediate_layers[num_intermediate - 1]->print_z);
if (is_top_contact) {
if (idx_intermediate_layer > num_intermediate - support_params.num_top_interface_layers)
polygons_append(polygons_top_contact_projected_interface, snug_supports ? *top_contact_layer.overhang_polygons : top_contact_layer.polygons);
else if (idx_intermediate_layer > num_intermediate - support_params.num_top_interface_layers - support_params.num_top_base_interface_layers)
polygons_append(polygons_top_contact_projected_base, snug_supports ? *top_contact_layer.overhang_polygons : top_contact_layer.polygons);
} else {
if (top_contact_layer.print_z - EPSILON <
intermediate_layers[std::min(int(idx_intermediate_layer + support_params.num_top_interface_layers - 1), num_intermediate - 1)]->print_z)
polygons_append(polygons_top_contact_projected_interface, snug_supports ? *top_contact_layer.overhang_polygons : top_contact_layer.polygons);
else if (top_contact_layer.print_z - EPSILON < intermediate_layers[std::min(int(idx_intermediate_layer + support_params.num_top_interface_layers -
1 + support_params.num_top_base_interface_layers),num_intermediate - 1)]->print_z)
polygons_append(polygons_top_contact_projected_base, snug_supports ? *top_contact_layer.overhang_polygons : top_contact_layer.polygons);
}
}
}
}
@ -206,7 +237,7 @@ std::pair<SupportGeneratorLayersPtr, SupportGeneratorLayersPtr> generate_interfa
}
});
if (support_params.num_top_base_interface_layers > 1)
if (support_params.num_top_base_interface_layers > 1 && !istree)
tbb::parallel_for(tbb::blocked_range<int>(1, int(base_interface_layers.size())),
[&base_interface_layers, &top_contacts, &support_params, &intermediate_layers](const tbb::blocked_range<int> &range) {
for (int layer_id = range.begin(); layer_id < range.end(); ++layer_id) {

View File

@ -33,19 +33,35 @@ struct SupportParameters {
num_top_interface_layers : object_config.support_interface_bottom_layers;
this->has_top_contacts = num_top_interface_layers > 0;
this->has_bottom_contacts = num_bottom_interface_layers > 0;
if (this->soluble_interface_non_soluble_base) {
// Try to support soluble dense interfaces with non-soluble dense interfaces.
this->num_top_base_interface_layers = num_top_interface_layers > 0 ? 2 : 0;
this->num_bottom_base_interface_layers = size_t(std::min(int(num_bottom_interface_layers) / 2, 2));
} else {
// BBS: if support interface and support base do not use the same filament, add a base layer to improve their adhesion
// Note: support materials (such as Supp.W) can't be used as support base now, so support interface and base are still using different filaments even if
// support_filament==0
bool differnt_support_interface_filament = object_config.support_interface_filament != 0 &&
object_config.support_interface_filament != object_config.support_filament;
this->num_top_base_interface_layers = num_top_interface_layers > 0 ? differnt_support_interface_filament ? 2 : 1 : 0;
this->num_bottom_base_interface_layers = differnt_support_interface_filament ? 1 : 0;
}
if (is_tree(object_config.support_type)) {
if (this->soluble_interface_non_soluble_base) {
// Try to support soluble dense interfaces with non-soluble dense interfaces.
this->num_top_base_interface_layers = size_t(std::min(int(num_top_interface_layers) / 2, 2));
this->num_bottom_base_interface_layers = size_t(std::min(int(num_bottom_interface_layers) / 2, 2));
} else {
// BBS: if support interface and support base do not use the same filament, add a base layer to improve their adhesion
// Note: support materials (such as Supp.W) can't be used as support base now, so support interface and base are still using different filaments even if
// support_filament==0
bool differnt_support_interface_filament = object_config.support_interface_filament != 0 &&
object_config.support_interface_filament != object_config.support_filament;
this->num_top_base_interface_layers = differnt_support_interface_filament ? 1 : 0;
this->num_bottom_base_interface_layers = differnt_support_interface_filament ? 1 : 0;
}
} else {
if (this->soluble_interface_non_soluble_base) {
// Try to support soluble dense interfaces with non-soluble dense interfaces.
this->num_top_base_interface_layers = num_top_interface_layers > 0 ? 2 : 0;
this->num_bottom_base_interface_layers = size_t(std::min(int(num_bottom_interface_layers) / 2, 2));
} else {
// BBS: if support interface and support base do not use the same filament, add a base layer to improve their adhesion
// Note: support materials (such as Supp.W) can't be used as support base now, so support interface and base are still using different filaments even if
// support_filament==0
bool differnt_support_interface_filament = object_config.support_interface_filament != 0 &&
object_config.support_interface_filament != object_config.support_filament;
this->num_top_base_interface_layers = num_top_interface_layers > 0 ? differnt_support_interface_filament ? 2 : 1 : 0;
this->num_bottom_base_interface_layers = differnt_support_interface_filament ? 1 : 0;
}
}
}
this->first_layer_flow = Slic3r::support_material_1st_layer_flow(&object, float(slicing_params.first_print_layer_height));
this->support_material_flow = Slic3r::support_material_flow(&object, float(slicing_params.layer_height));

View File

@ -676,6 +676,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in
toggle_field("support_filament", have_support_material || have_skirt);
toggle_line("raft_contact_distance", have_raft && !have_support_soluble);
if (!have_raft || have_support_soluble) config->opt_float("raft_contact_distance") = config->opt_float("support_top_z_distance");
bool has_ironing = (config->opt_enum<IroningType>("ironing_type") != IroningType::NoIroning);
for (auto el : {