mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Bonsai: orient new fillings by the wall's direction sense
Fixes #6588 FilledOpeningGenerator.generate decided a new door/window's facing purely from which wall axis (base or side) the insertion point snapped to: base kept the wall's orientation, side rotated the filling 180 degrees. That convention encodes the wall body lying on the +Y side of the base axis, which is only true for DirectionSense POSITIVE. On a flipped wall (NEGATIVE), the body lies on -Y, so every inserted filling faced out of the wall instead of into it, with the lining protruding outside the body, and the user had to run Flip Fill manually after every insertion. Fold the direction sense into the decision: the filling faces the wall body from whichever face was clicked, so NEGATIVE inverts which snap target needs the 180 degree turn. The ProductPreviewDecorator ghost preview uses the same base/side test, and is updated identically so what the user sees while hovering matches what gets placed. POSITIVE walls are byte-for-byte unchanged, and the opening void extrusion is centered on the filling plane, so the cut is unaffected by the turn. Verified live headless (Blender 5.2): doors and windows on a NEGATIVE wall now face into the body from either clicked face, mirroring the POSITIVE result; opening still cuts the wall in all four direction-sense x clicked-face combinations. Generated with the assistance of an AI coding tool.
This commit is contained in:
@@ -1554,16 +1554,26 @@ class ProductDecorator(tool.Blender.ViewportDecorator):
|
||||
axis_side = axes["side"]
|
||||
point_on_base_axis = tool.Cad.point_on_edge(mouse_point, axis_base)
|
||||
point_on_side_axis = tool.Cad.point_on_edge(mouse_point, axis_side)
|
||||
# Match FilledOpeningGenerator.generate: the filling faces the
|
||||
# wall body from whichever face is snapped, so a NEGATIVE
|
||||
# direction sense inverts which face needs the 180 degree turn.
|
||||
flipped_wall = layers["direction_sense"] == "NEGATIVE"
|
||||
if (point_on_base_axis - mouse_point).length_squared <= (point_on_side_axis - mouse_point).length_squared:
|
||||
# mouse is snapped to the base axis, the preview looks exactly like the placed door / window
|
||||
rot_mat = snap_obj.matrix_world
|
||||
# mouse is snapped to the base axis
|
||||
rotate_filling = flipped_wall
|
||||
else:
|
||||
# mouse is snapped to the side axis, the preview is inverted, rotate it now and correct x position later
|
||||
# mouse is snapped to the side axis
|
||||
rotate_filling = not flipped_wall
|
||||
if rotate_filling:
|
||||
# the preview is inverted, rotate it now and correct x position later
|
||||
rot_mat = (
|
||||
(snap_obj.matrix_world.to_quaternion() @ Quaternion(Vector((0, 0, 1)), radians(180)))
|
||||
.to_matrix()
|
||||
.to_4x4()
|
||||
)
|
||||
else:
|
||||
# the preview looks exactly like the placed door / window
|
||||
rot_mat = snap_obj.matrix_world
|
||||
|
||||
mouse_point.z = snap_obj.matrix_world.translation.z
|
||||
|
||||
|
||||
@@ -303,12 +303,19 @@ class FilledOpeningGenerator:
|
||||
new_matrix = voided_obj.matrix_world.copy()
|
||||
point_on_base_axis = tool.Cad.point_on_edge(target, axis_base)
|
||||
point_on_side_axis = tool.Cad.point_on_edge(target, axis_side)
|
||||
# The filling faces the wall body from whichever face was
|
||||
# clicked, so a NEGATIVE direction sense (body on the wall's
|
||||
# local -Y) inverts which face needs the 180 degree turn.
|
||||
flipped_wall = layers["direction_sense"] == "NEGATIVE"
|
||||
if (point_on_base_axis - target).length <= (point_on_side_axis - target).length:
|
||||
new_matrix.translation.x = point_on_base_axis.x
|
||||
new_matrix.translation.y = point_on_base_axis.y
|
||||
rotate_filling = flipped_wall
|
||||
else:
|
||||
new_matrix.translation.x = point_on_side_axis.x
|
||||
new_matrix.translation.y = point_on_side_axis.y
|
||||
rotate_filling = not flipped_wall
|
||||
if rotate_filling:
|
||||
new_matrix = new_matrix @ Matrix.Rotation(radians(180.0), 4, "Z")
|
||||
|
||||
if should_set_z_level:
|
||||
|
||||
Reference in New Issue
Block a user