Fix organic tree smoothing drift and layer mapping (#14069)

This commit is contained in:
Kiss Lorand
2026-06-07 13:28:58 +08:00
committed by GitHub
parent d92bf80269
commit 4d86f5c250
2 changed files with 78 additions and 11 deletions
+23 -6
View File
@@ -13,6 +13,7 @@
#include "../Polygon.hpp"
#include "SupportCommon.hpp"
#include <algorithm>
#include <string_view>
namespace Slic3r
@@ -614,19 +615,35 @@ inline double layer_z(const SlicingParameters &slicing_params, const TreeSupport
slicing_params.object_print_z_min + slicing_params.first_object_layer_height + (layer_idx - config.raft_layers.size()) * slicing_params.layer_height :
config.raft_layers[layer_idx];
}
inline double first_object_support_layer_z(const SlicingParameters &slicing_params)
{
return slicing_params.object_print_z_min + slicing_params.first_object_layer_height;
}
// Orca: Reverse layer_z() for support layers below the first object layer.
// config.raft_layers may include raft/contact/intermediate support Zs, so do not collapse them to the first object support layer.
// Lowest collision layer
inline LayerIndex layer_idx_ceil(const SlicingParameters &slicing_params, const TreeSupportSettings &config, const double z)
{
return
LayerIndex(config.raft_layers.size()) +
std::max<LayerIndex>(0, ceil((z - slicing_params.object_print_z_min - slicing_params.first_object_layer_height) / slicing_params.layer_height));
const double first_object_z = first_object_support_layer_z(slicing_params);
if (!config.raft_layers.empty() && z < first_object_z - EPSILON) {
auto it = std::lower_bound(config.raft_layers.begin(), config.raft_layers.end(), z - EPSILON);
return LayerIndex(it == config.raft_layers.end() ? config.raft_layers.size() : std::distance(config.raft_layers.begin(), it));
}
return LayerIndex(config.raft_layers.size()) +
std::max<LayerIndex>(0, LayerIndex(std::ceil((z - first_object_z) / slicing_params.layer_height)));
}
// Highest collision layer
inline LayerIndex layer_idx_floor(const SlicingParameters &slicing_params, const TreeSupportSettings &config, const double z)
{
return
LayerIndex(config.raft_layers.size()) +
std::max<LayerIndex>(0, floor((z - slicing_params.object_print_z_min - slicing_params.first_object_layer_height) / slicing_params.layer_height));
const double first_object_z = first_object_support_layer_z(slicing_params);
if (!config.raft_layers.empty() && z < first_object_z - EPSILON) {
auto it = std::upper_bound(config.raft_layers.begin(), config.raft_layers.end(), z + EPSILON);
return LayerIndex(it == config.raft_layers.begin() ? 0 : std::distance(config.raft_layers.begin(), it) - 1);
}
return LayerIndex(config.raft_layers.size()) +
std::max<LayerIndex>(0, LayerIndex(std::floor((z - first_object_z) / slicing_params.layer_height)));
}
inline SupportGeneratorLayer& layer_initialize(