mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-06 07:51:47 +00:00
Disable snap on schematic gizmos
Schematic dimensions float in billboarded viewport space; their labels carry the value, not the bar length. Snapping the dragged tip to scene vertices produces nonsensical value jumps when the mouse crosses unrelated meshes. Add an opt-out flag on the parametric gizmo group base and override it on the schematic base — every schematic subclass inherits no-snap behaviour, and in-place parametric gizmos (door, window, wall, stair, roof, mep) keep the existing Ctrl-toggleable snap because the default stays True. GizmoDimension.invoke also forces tool_settings.use_snap = False for schematic gizmos so the header magnet visibly switches off for the drag's duration. The existing exit path restores the user's previous setting on release. Generated with the assistance of an AI coding tool.
This commit is contained in:
@@ -4877,7 +4877,14 @@ class GizmoDimension(GizmoMovable):
|
||||
|
||||
self.init_value = click_distance
|
||||
|
||||
if self.initial_snap_state and self.active_obj:
|
||||
# Schematic gizmos opt out of dimension snap. Force the header
|
||||
# indicator to ``off`` for the drag's duration so the user sees the
|
||||
# state matches behaviour; ``exit`` restores ``initial_snap_state``.
|
||||
# Skipping the snap cache here also avoids the per-drag mesh probe.
|
||||
snap_supported = getattr(self.gizmo_group, "snap_enabled_on_dimensions", True)
|
||||
if not snap_supported:
|
||||
context.scene.tool_settings.use_snap = False
|
||||
elif self.initial_snap_state and self.active_obj:
|
||||
build_snap_cache(context, self.active_obj)
|
||||
self._snap_cache_built = True
|
||||
|
||||
@@ -4919,11 +4926,18 @@ class GizmoDimension(GizmoMovable):
|
||||
if not region or not rv3d:
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
tool_settings.use_snap = not self.initial_snap_state if event.ctrl else self.initial_snap_state
|
||||
# Group-level opt-out: schematic gizmos float in viewport space, so
|
||||
# global-snap-to-scene-vertices would produce spurious value jumps.
|
||||
# The fallback (``True``) covers any gizmo whose group is not a
|
||||
# ``BaseParametricGizmoGroup``.
|
||||
snap_supported = getattr(self.gizmo_group, "snap_enabled_on_dimensions", True)
|
||||
|
||||
if tool_settings.use_snap and not self._snap_cache_built and self.active_obj:
|
||||
build_snap_cache(context, self.active_obj)
|
||||
self._snap_cache_built = True
|
||||
if snap_supported:
|
||||
tool_settings.use_snap = not self.initial_snap_state if event.ctrl else self.initial_snap_state
|
||||
|
||||
if tool_settings.use_snap and not self._snap_cache_built and self.active_obj:
|
||||
build_snap_cache(context, self.active_obj)
|
||||
self._snap_cache_built = True
|
||||
|
||||
current_coord = (event.mouse_region_x, event.mouse_region_y)
|
||||
|
||||
@@ -4947,7 +4961,7 @@ class GizmoDimension(GizmoMovable):
|
||||
|
||||
delta = (current_3d - self.start_location).dot(axis_direction)
|
||||
|
||||
if tool_settings.use_snap and self.active_obj:
|
||||
if snap_supported and tool_settings.use_snap and self.active_obj:
|
||||
# Snap the dimension tip (not mouse position) to target
|
||||
# Calculate where the dimension tip would be with current delta
|
||||
# The tip is at: gizmo_origin + axis * (init_value + delta)
|
||||
@@ -5320,6 +5334,13 @@ class BaseParametricGizmoGroup:
|
||||
# Pre-computed flip matrix for negative value handling (180° rotation around Z)
|
||||
FLIP_MATRIX = Matrix.Rotation(math.pi, 4, "Z")
|
||||
|
||||
# Default: dimension drags respect Blender's global snap (Ctrl-toggleable
|
||||
# during drag). Subclasses whose dimensions float in viewport space rather
|
||||
# than aligning to real-world geometry should override to ``False`` —
|
||||
# snapping to scene vertices in that case produces spurious value jumps
|
||||
# as the mouse crosses unrelated meshes.
|
||||
snap_enabled_on_dimensions: bool = True
|
||||
|
||||
# === Icon Gizmo Layout (meters) ===
|
||||
# Icons are positioned in a horizontal row above the element:
|
||||
# [Validate] [Cancel] [Cycle]
|
||||
@@ -6580,6 +6601,11 @@ class BaseSchematicGizmoGroup(BaseParametricGizmoGroup):
|
||||
# list and become no-ops. The schematic equivalents below take their place.
|
||||
dimension_gizmo_props: list[DimensionGizmoConfig] = []
|
||||
|
||||
# Schematic dimensions float in billboarded viewport space, not aligned to
|
||||
# real-world geometry. Snapping the dragged tip to scene vertices would
|
||||
# produce nonsensical value jumps as the mouse crosses unrelated meshes.
|
||||
snap_enabled_on_dimensions: bool = False
|
||||
|
||||
# Declarative dimension configuration consumed by ``setup_schematic_dimensions``
|
||||
# and ``update_schematic_dimensions``. Each config produces one
|
||||
# ``BIM_GT_gizmo_dimension`` instance positioned at a schematic-local
|
||||
|
||||
@@ -24,7 +24,11 @@ from types import SimpleNamespace
|
||||
import bpy
|
||||
import pytest
|
||||
|
||||
from bonsai.bim.module.drawing.gizmos import DimensionGizmoConfig
|
||||
from bonsai.bim.module.drawing.gizmos import (
|
||||
BaseParametricGizmoGroup,
|
||||
BaseSchematicGizmoGroup,
|
||||
DimensionGizmoConfig,
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.drawing
|
||||
|
||||
@@ -52,3 +56,19 @@ def test_text_formatter_receives_props_and_value():
|
||||
config = DimensionGizmoConfig(attr_name="length", axis=(1, 0, 0), text_formatter=formatter)
|
||||
props = SimpleNamespace(label="L")
|
||||
assert config.text_formatter(props, 3.14) == "L=3.14"
|
||||
|
||||
|
||||
def test_parametric_base_enables_dimension_snap_by_default():
|
||||
"""In-place parametric gizmos align to real-world geometry, so dragging
|
||||
must respect the global snap toggle (Ctrl-flip during drag) — same
|
||||
contract every door / window / wall / stair / roof / mep dimension
|
||||
has shipped with."""
|
||||
assert BaseParametricGizmoGroup.snap_enabled_on_dimensions is True
|
||||
|
||||
|
||||
def test_schematic_base_disables_dimension_snap():
|
||||
"""Schematic dimensions float in viewport space; snapping the dragged
|
||||
tip to scene vertices would produce spurious value jumps as the
|
||||
mouse crosses unrelated geometry. The opt-out lives on the base so
|
||||
every schematic subclass inherits it without per-class wiring."""
|
||||
assert BaseSchematicGizmoGroup.snap_enabled_on_dimensions is False
|
||||
|
||||
Reference in New Issue
Block a user