mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-14 00:52:04 +00:00
Fix support preview artifacts (missing layers) (#13310)
Fix support preview artifacts caused by incorrect gap subdivision Support generation could sometimes split a gap into too many steps, even when it should fit exactly into a single layer. This was most noticeable when max_suport_layer_height was equal to the print layer height (e.g. 0.2 mm). This resulted in incorrect support layering and visible artifacts in preview. The issue was caused by floating-point precision, where values that should be equal to the configured limit were treated as slightly larger. Fix by biasing the subdivision calculation with EPSILON so near-equal values are not split into extra steps. Applied consistently to: - SupportMaterial (normal supports) - TreeSupportCommon (tree stepping) - TreeSupport (layer creation)
This commit is contained in:
@@ -2882,8 +2882,9 @@ SupportGeneratorLayersPtr PrintObjectSupportMaterial::raft_and_intermediate_supp
|
||||
intermediate_layers.push_back(&layer_new);
|
||||
}
|
||||
} else {
|
||||
// Insert intermediate layers.
|
||||
size_t n_layers_extra = size_t(ceil(dist / m_slicing_params.max_suport_layer_height));
|
||||
// ORCA: Bias by EPSILON so a gap effectively equal to
|
||||
// max_suport_layer_height is not split by floating-point noise.
|
||||
size_t n_layers_extra = size_t(ceil((dist - EPSILON) / m_slicing_params.max_suport_layer_height));
|
||||
assert(n_layers_extra > 0);
|
||||
coordf_t step = dist / coordf_t(n_layers_extra);
|
||||
if (extr1 != nullptr && extr1->layer_type == SupporLayerType::TopContact &&
|
||||
@@ -2898,7 +2899,9 @@ SupportGeneratorLayersPtr PrintObjectSupportMaterial::raft_and_intermediate_supp
|
||||
layer_new.height = extr1->height;
|
||||
intermediate_layers.push_back(&layer_new);
|
||||
dist = extr2z - extr1z;
|
||||
n_layers_extra = size_t(ceil(dist / m_slicing_params.max_suport_layer_height));
|
||||
// ORCA: Recalculate with the same EPSILON bias after re-anchoring at the top
|
||||
// contact layer so near-equal gaps do not gain an extra split here either.
|
||||
n_layers_extra = size_t(ceil((dist - EPSILON) / m_slicing_params.max_suport_layer_height));
|
||||
if (n_layers_extra == 0)
|
||||
continue;
|
||||
// Continue printing the other layers up to extr2z.
|
||||
|
||||
@@ -1157,12 +1157,17 @@ void TreeSupport::create_tree_support_layers()
|
||||
|
||||
// Layers between the raft contacts and bottom of the object.
|
||||
double dist_to_go = m_slicing_params.object_print_z_min - raft_print_z;
|
||||
auto nsteps = int(ceil(dist_to_go / m_slicing_params.max_suport_layer_height));
|
||||
double height = dist_to_go / nsteps;
|
||||
for (int i = 0; i < nsteps; ++i) {
|
||||
raft_print_z += height;
|
||||
raft_slice_z = raft_print_z - height / 2;
|
||||
m_object->add_tree_support_layer(layer_id++, height, raft_print_z, raft_slice_z);
|
||||
// ORCA: Guard tiny residual raft-to-object gaps so the EPSILON-biased ceil()
|
||||
// below cannot turn them into zero steps after floating-point accumulation.
|
||||
if (dist_to_go > EPSILON) {
|
||||
// ORCA: Bias by EPSILON so near-equal gaps do not get an extra split from FP noise.
|
||||
auto nsteps = int(ceil((dist_to_go - EPSILON) / m_slicing_params.max_suport_layer_height));
|
||||
double height = dist_to_go / nsteps;
|
||||
for (int i = 0; i < nsteps; ++i) {
|
||||
raft_print_z += height;
|
||||
raft_slice_z = raft_print_z - height / 2;
|
||||
m_object->add_tree_support_layer(layer_id++, height, raft_print_z, raft_slice_z);
|
||||
}
|
||||
}
|
||||
m_raft_layers = layer_id;
|
||||
}
|
||||
|
||||
@@ -343,7 +343,8 @@ public:
|
||||
}
|
||||
if (double dist_to_go = slicing_params.object_print_z_min - z; dist_to_go > EPSILON) {
|
||||
// Layers between the raft contacts and bottom of the object.
|
||||
auto nsteps = int(ceil(dist_to_go / slicing_params.max_suport_layer_height));
|
||||
// ORCA: Bias by EPSILON so near-equal gaps do not get an extra split from FP noise.
|
||||
auto nsteps = int(ceil((dist_to_go - EPSILON) / slicing_params.max_suport_layer_height));
|
||||
double step = dist_to_go / nsteps;
|
||||
for (int i = 0; i < nsteps; ++ i) {
|
||||
z += step;
|
||||
@@ -754,4 +755,4 @@ enum class LineStatus
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif // slic3r_TreeSupportCommon_hpp
|
||||
#endif // slic3r_TreeSupportCommon_hpp
|
||||
|
||||
Reference in New Issue
Block a user