diff --git a/src/libslic3r/Support/SupportMaterial.cpp b/src/libslic3r/Support/SupportMaterial.cpp index d1fa5d8627..48e3f4caf2 100644 --- a/src/libslic3r/Support/SupportMaterial.cpp +++ b/src/libslic3r/Support/SupportMaterial.cpp @@ -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. diff --git a/src/libslic3r/Support/TreeSupport.cpp b/src/libslic3r/Support/TreeSupport.cpp index fcd29e4dcd..e6ed4acc96 100644 --- a/src/libslic3r/Support/TreeSupport.cpp +++ b/src/libslic3r/Support/TreeSupport.cpp @@ -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; } diff --git a/src/libslic3r/Support/TreeSupportCommon.hpp b/src/libslic3r/Support/TreeSupportCommon.hpp index 31e410838d..39e07cfaf4 100644 --- a/src/libslic3r/Support/TreeSupportCommon.hpp +++ b/src/libslic3r/Support/TreeSupportCommon.hpp @@ -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 \ No newline at end of file +#endif // slic3r_TreeSupportCommon_hpp