mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
Fix spurious X/Y rotation on fillet corner wall
When the two source walls were placed at different elevations, the fillet corner wall ended up with sub-degree X and Y Euler rotations even though both source walls had only a Z rotation. Cause: _apply_fillet_corner_geometry derived the corner's local X axis from `chord = tangent_b - tangent_a` (a 3D vector). With walls at different Z, `chord.z` was non-zero, so `x_dir = chord.normalized()` inherited that Z component. The Z axis was already hardcoded to world Z, so x_dir and z_dir were no longer orthogonal — the resulting matrix_world was non-orthonormal, and Blender's Euler decomposition surfaced the skew as the visible X/Y rotation drift. Project the chord to the XY plane before normalising so x_dir is strictly XY-aligned and orthogonal to z_dir. The corner wall is now placed at wall A's elevation with a pure Z rotation, which matches the user's expectation when both inputs are Z-aligned regardless of their relative elevation. Generated with the assistance of an AI coding tool.
This commit is contained in:
committed by
Thomas Krijnen
parent
1534003e51
commit
49fe0756fa
@@ -2651,7 +2651,17 @@ def _apply_fillet_corner_geometry(
|
||||
if body_context is None:
|
||||
return None
|
||||
|
||||
x_dir = chord.normalized()
|
||||
# Project the chord to the XY plane for the local-frame X axis. The
|
||||
# corner wall's Z axis is hardcoded to world Z below, so an XY-aligned
|
||||
# X axis is required for an orthonormal rotation matrix. Without the
|
||||
# projection, any chord Z component (walls placed at different
|
||||
# elevations) leaves x_dir non-orthogonal to z_dir and Blender's
|
||||
# Euler decomposition surfaces the skew as spurious sub-degree X/Y
|
||||
# rotations on the corner.
|
||||
chord_xy = Vector((chord.x, chord.y, 0.0))
|
||||
if chord_xy.length < 1e-6:
|
||||
return None
|
||||
x_dir = chord_xy.normalized()
|
||||
z_dir = Vector((0.0, 0.0, 1.0))
|
||||
y_dir = z_dir.cross(x_dir).normalized()
|
||||
corner_obj.matrix_world = Matrix(
|
||||
|
||||
Reference in New Issue
Block a user