Bonsai: don't blow up a vertical AXIS3 element when its layers change

DumbSlabPlaner.change_thickness rewrote the body extrusion assuming the
extrusion axis is the layer axis, scaling the depth by an unbounded
1 / cos(x_angle). For an AXIS3 element that stands vertically, whose
extrusion runs perpendicular (or nearly so) to the profile plane normal,
that factor diverges: editing the layer set turned a 2" shelving panel
into a 670 m slab. A purely local-X extrusion was worse still, raising
ValueError from get_existing_x_angle on a zero length vector.

Derive the scale from the normalised extrusion direction's z component
instead. It is identical to 1 / cos(x_angle) for every direction the
parametric slab tool produces, but it stays correct when the direction
carries an x component and it makes the degenerate case explicit: when
the component vanishes no depth can realise the requested thickness, so
the representation is left untouched rather than rewritten to garbage.

Generated with the assistance of an AI coding tool.
This commit is contained in:
Petru Conduraru
2026-07-20 13:03:17 +03:00
parent 55a2430d71
commit bd3a727f4f
+10 -3
View File
@@ -271,14 +271,21 @@ class DumbSlabPlaner:
# For instances, a 30 degrees angled extrusion with positive direction has the same extrusion direction as a
# -150 degrees angled extrusion with negative direction. The difference lies in the object's rotation.
# This means that things can get messy if the user changes the object x angle somehow. We have to figure out an alternative approach.
direction_ratios = Vector(extrusion.ExtrudedDirection.DirectionRatios)
# No depth can realise the requested thickness once the extrusion runs
# perpendicular to the layer axis, so leave the representation alone.
layer_axis_ratio = direction_ratios.normalized().z
if tool.Cad.is_x(abs(layer_axis_ratio), 0, tolerance=0.001):
return
existing_x_angle = tool.Model.get_existing_x_angle(extrusion)
existing_x_angle = 0 if tool.Cad.is_x(existing_x_angle, 0, tolerance=0.001) else existing_x_angle
existing_x_angle = 0 if tool.Cad.is_x(existing_x_angle, pi, tolerance=0.001) else existing_x_angle
existing_x_angle = 0 if tool.Cad.is_x(existing_x_angle, 2 * pi, tolerance=0.001) else existing_x_angle
direction_ratios = Vector(extrusion.ExtrudedDirection.DirectionRatios)
offset_direction = direction_ratios.copy()
perpendicular_depth = thickness * abs(1 / cos(existing_x_angle))
perpendicular_offset = layer_offset * abs(1 / cos(existing_x_angle)) / self.unit_scale
perpendicular_depth = thickness / abs(layer_axis_ratio)
perpendicular_offset = layer_offset / abs(layer_axis_ratio) / self.unit_scale
# Check angle and z direction to determine whether the extrusion direction is positive or negative
if (abs(existing_x_angle) < (pi / 2) and direction_ratios.z > 0) or (