From 49fe0756fa4571bdaff5eb428cf5914e448e70eb Mon Sep 17 00:00:00 2001 From: Gorgious56 Date: Mon, 1 Jun 2026 14:49:33 +0200 Subject: [PATCH] Fix spurious X/Y rotation on fillet corner wall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/bonsai/bonsai/bim/module/model/wall.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/bonsai/bonsai/bim/module/model/wall.py b/src/bonsai/bonsai/bim/module/model/wall.py index 4101672baa..93b832d3ae 100644 --- a/src/bonsai/bonsai/bim/module/model/wall.py +++ b/src/bonsai/bonsai/bim/module/model/wall.py @@ -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(