Share and Clamp the Build Plate Tilt Shift in Support Generators

The three support generators each computed lh * tan(tilt), which overflows
coord_t at 90 degrees and flips sign beyond it (belt sync can write up to
180). One helper now returns the tilt slope with the tilt capped at 89 degrees.
This commit is contained in:
Hanif Koh
2026-09-14 01:32:07 +08:00
parent d0c068a230
commit 8ceb187feb
5 changed files with 20 additions and 22 deletions
+6
View File
@@ -2067,4 +2067,10 @@ sub clip_with_shape {
}
*/
Vec2d build_plate_tilt_slope(const PrintConfig &print_config)
{
auto slope = [](double tilt_deg) { return std::tan(Geometry::deg2rad(std::clamp(tilt_deg, -89., 89.))); };
return { slope(print_config.build_plate_tilt_y.value), slope(print_config.build_plate_tilt_x.value) };
}
} // namespace Slic3r
+4
View File
@@ -150,6 +150,10 @@ Polygons belt_floor_surface_polygon(
const SlicingParameters &slicing_params, const PrintConfig &print_config,
const PrintObject &object, coordf_t print_z);
// Build plate tilt: XY drift of gravity per unit of layer height, zero on a level plate.
// The tilt is capped below 90 degrees to keep the drift finite.
Vec2d build_plate_tilt_slope(const PrintConfig &print_config);
} // namespace Slic3r
#endif /* slic3r_SupportCommon_hpp_ */
+3 -7
View File
@@ -1439,9 +1439,8 @@ static inline ExPolygons detect_overhangs(
const bool bridge_no_support = object_config.bridge_no_support.value;
const coordf_t xy_expansion = scale_(object_config.support_expansion.value);
// Build plate tilt: compute per-layer XY shift for tilted gravity direction
const double tilt_x_rad = Geometry::deg2rad(print_config.build_plate_tilt_x.value);
const double tilt_y_rad = Geometry::deg2rad(print_config.build_plate_tilt_y.value);
const bool has_tilt = std::abs(tilt_x_rad) > EPSILON || std::abs(tilt_y_rad) > EPSILON;
const Vec2d tilt_slope = build_plate_tilt_slope(print_config);
const bool has_tilt = tilt_slope.cwiseAbs().maxCoeff() > EPSILON;
float lower_layer_offset = 0;
if (layer_id == 0)
@@ -1481,10 +1480,7 @@ static inline ExPolygons detect_overhangs(
Polygons tilted_lower;
if (has_tilt) {
tilted_lower = lower_layer_polygons;
const double lh = lower_layer.height;
Point tilt_shift(coord_t(scale_(lh * tan(tilt_y_rad))),
coord_t(scale_(lh * tan(tilt_x_rad))));
translate(tilted_lower, tilt_shift);
translate(tilted_lower, Point::new_scale(tilt_slope * lower_layer.height));
effective_lower = &tilted_lower;
}
+3 -7
View File
@@ -709,9 +709,8 @@ void TreeSupport::detect_overhangs(bool check_support_necessity/* = false*/)
const double threshold_rad = Geometry::deg2rad(thresh_angle);
// Build plate tilt: compute per-layer XY shift for tilted gravity direction
const PrintConfig& print_cfg = m_object->print()->config();
const double tilt_x_rad = Geometry::deg2rad(print_cfg.build_plate_tilt_x.value);
const double tilt_y_rad = Geometry::deg2rad(print_cfg.build_plate_tilt_y.value);
const bool has_tilt = std::abs(tilt_x_rad) > EPSILON || std::abs(tilt_y_rad) > EPSILON;
const Vec2d tilt_slope = build_plate_tilt_slope(print_cfg);
const bool has_tilt = tilt_slope.cwiseAbs().maxCoeff() > EPSILON;
// FIXME this is a fudge constant!
double support_tree_tip_diameter = 0.8;
auto enforcer_overhang_offset = scaled<double>(support_tree_tip_diameter);
@@ -858,10 +857,7 @@ void TreeSupport::detect_overhangs(bool check_support_necessity/* = false*/)
ExPolygons shifted_lower;
if (has_tilt) {
shifted_lower = lower_polys; // copy
const double lh = lower_layer->height;
Point tilt_shift(coord_t(scale_(lh * tan(tilt_y_rad))),
coord_t(scale_(lh * tan(tilt_x_rad))));
translate(shifted_lower, tilt_shift);
translate(shifted_lower, Point::new_scale(tilt_slope * lower_layer->height));
}
const ExPolygons &effective_lower = has_tilt ? shifted_lower : lower_polys;
+4 -8
View File
@@ -211,9 +211,8 @@ static std::vector<std::pair<TreeSupportSettings, std::vector<size_t>>> group_me
// +1 makes the threshold inclusive
double tan_threshold = support_threshold_auto ? 0. : tan(M_PI * double(support_threshold + 1) / 180.);
// Build plate tilt: compute per-layer XY shift for tilted gravity direction
const double tilt_x_rad = Geometry::deg2rad(print_config.build_plate_tilt_x.value);
const double tilt_y_rad = Geometry::deg2rad(print_config.build_plate_tilt_y.value);
const bool has_tilt = std::abs(tilt_x_rad) > EPSILON || std::abs(tilt_y_rad) > EPSILON;
const Vec2d tilt_slope = build_plate_tilt_slope(print_config);
const bool has_tilt = tilt_slope.cwiseAbs().maxCoeff() > EPSILON;
//FIXME this is a fudge constant!
auto enforcer_overhang_offset = scaled<double>(config.tree_support_tip_diameter.value);
const coordf_t radius_sample_resolution = g_config_tree_support_collision_resolution;
@@ -235,7 +234,7 @@ static std::vector<std::pair<TreeSupportSettings, std::vector<size_t>>> group_me
size_t num_overhang_layers = support_auto ? num_object_layers : std::min(num_object_layers, std::max(size_t(support_enforce_layers), enforcers_layers.size()));
tbb::parallel_for(tbb::blocked_range<LayerIndex>(1, num_overhang_layers),
[&print_object, &config, &print_config, &enforcers_layers, &blockers_layers,
support_auto, support_enforce_layers, support_threshold_auto, tan_threshold, enforcer_overhang_offset, num_raft_layers, radius_sample_resolution, has_tilt, tilt_x_rad, tilt_y_rad, &throw_on_cancel, &out]
support_auto, support_enforce_layers, support_threshold_auto, tan_threshold, enforcer_overhang_offset, num_raft_layers, radius_sample_resolution, has_tilt, tilt_slope, &throw_on_cancel, &out]
(const tbb::blocked_range<LayerIndex> &range) {
for (LayerIndex layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
const Layer &current_layer = *print_object.get_layer(layer_id);
@@ -263,10 +262,7 @@ static std::vector<std::pair<TreeSupportSettings, std::vector<size_t>>> group_me
Polygons lower_layer_offseted;
if (has_tilt) {
Polygons lower_src = to_polygons(lower_layer.lslices_extrudable);
const double lh = lower_layer.height;
Point tilt_shift(coord_t(scale_(lh * tan(tilt_y_rad))),
coord_t(scale_(lh * tan(tilt_x_rad))));
translate(lower_src, tilt_shift);
translate(lower_src, Point::new_scale(tilt_slope * lower_layer.height));
lower_layer_offseted = offset(lower_src, lower_layer_offset);
} else {
lower_layer_offseted = offset(lower_layer.lslices_extrudable, lower_layer_offset);