mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-29 16:22:53 +00:00
Align extend gizmo arrow with segment axis
The extend icon used a pure screen-space billboard that always pointed +X across the screen — the arrow ran horizontally regardless of the pipe / duct's orientation. The new billboarded_along_axis helper rotates the gizmo about the camera- forward axis so its local +X aligns with the segment's local +Z projected onto the screen, keeping the icon camera-facing but visually following the extrusion direction. The flip-mirror branch now reads from cursor-vs-current-end along the segment axis (not screen-X), so the arrow points away from the current endpoint regardless of viewport orientation. The split icon stacks perpendicular to the rotated extend arrow in screen space so the two don't overlap. The decorator's green preview line no longer clamps the cursor projection to min_projected_length — it follows the raw projection so the line stays visible when the cursor crosses behind the segment origin (the user still sees where they're pointing even though the operator floors the actual commit). Generated with the assistance of an AI coding tool.
This commit is contained in:
@@ -332,7 +332,6 @@ def test_extend_preview_line_returns_none_for_degenerate_segment():
|
||||
matrix_world=Matrix.Identity(4),
|
||||
cursor_world=Vector((0.0, 0.0, 1.0)),
|
||||
current_length=0.0,
|
||||
min_projected_length=0.01,
|
||||
)
|
||||
assert result is None
|
||||
|
||||
@@ -346,7 +345,6 @@ def test_extend_preview_line_returns_none_when_cursor_at_current_end():
|
||||
matrix_world=Matrix.Identity(4),
|
||||
cursor_world=Vector((0.0, 0.0, 1.5)),
|
||||
current_length=1.5,
|
||||
min_projected_length=0.01,
|
||||
)
|
||||
assert result is None
|
||||
|
||||
@@ -361,7 +359,6 @@ def test_extend_preview_line_renders_extension_when_cursor_past_end():
|
||||
matrix_world=Matrix.Identity(4),
|
||||
cursor_world=Vector((0.0, 0.0, 3.0)),
|
||||
current_length=1.0,
|
||||
min_projected_length=0.01,
|
||||
)
|
||||
assert result is not None
|
||||
start, end = result
|
||||
@@ -378,7 +375,6 @@ def test_extend_preview_line_renders_trim_when_cursor_inside_segment():
|
||||
matrix_world=Matrix.Identity(4),
|
||||
cursor_world=Vector((0.0, 0.0, 0.4)),
|
||||
current_length=1.0,
|
||||
min_projected_length=0.01,
|
||||
)
|
||||
assert result is not None
|
||||
start, end = result
|
||||
@@ -386,23 +382,23 @@ def test_extend_preview_line_renders_trim_when_cursor_inside_segment():
|
||||
assert tuple(end) == pytest.approx((0.0, 0.0, 0.4))
|
||||
|
||||
|
||||
def test_extend_preview_line_clamps_cursor_projection_to_minimum():
|
||||
"""When the cursor's projected Z is negative (behind segment origin) or
|
||||
near zero, the extend operator clamps to ``min_projected_length``. The
|
||||
preview must match the same clamp so the line lands where the operator
|
||||
would actually commit, not at the raw cursor position."""
|
||||
def test_extend_preview_line_follows_raw_projection_behind_segment_origin():
|
||||
"""When the cursor's projected Z is negative (behind segment origin),
|
||||
the preview line must follow the raw cursor projection — the user is
|
||||
pointing somewhere and expects to see where, even though the operator
|
||||
would floor the actual commit. Matching the operator's clamp would
|
||||
hide the line whenever the cursor crossed the segment origin."""
|
||||
from bonsai.bim.module.model.decorator import MEPSegmentExtendPreviewDecorator
|
||||
|
||||
result = MEPSegmentExtendPreviewDecorator._compute_extend_preview_line(
|
||||
matrix_world=Matrix.Identity(4),
|
||||
cursor_world=Vector((0.0, 0.0, -2.0)),
|
||||
current_length=1.0,
|
||||
min_projected_length=0.01,
|
||||
)
|
||||
assert result is not None
|
||||
start, end = result
|
||||
assert tuple(start) == pytest.approx((0.0, 0.0, 1.0))
|
||||
assert tuple(end) == pytest.approx((0.0, 0.0, 0.01))
|
||||
assert tuple(end) == pytest.approx((0.0, 0.0, -2.0))
|
||||
|
||||
|
||||
def test_extend_preview_line_respects_object_rotation():
|
||||
@@ -418,7 +414,6 @@ def test_extend_preview_line_respects_object_rotation():
|
||||
matrix_world=rotation,
|
||||
cursor_world=Vector((3.0, 0.0, 0.0)),
|
||||
current_length=1.0,
|
||||
min_projected_length=0.01,
|
||||
)
|
||||
assert result is not None
|
||||
start, end = result
|
||||
|
||||
Reference in New Issue
Block a user