Parametric dimensions#8083
Open
theoryshaw wants to merge 38 commits into
Open
Conversation
…BBIM_Dimension.SuppressZeroInches Generated with the assistance of an AI coding tool.
Generated with the assistance of an AI coding tool.
…eometry New modal operator (bim.set_dimension_anchor) anchors dimension vertices to IFC element faces. Anchors are stored as JSON in a BBIM_DimensionTarget pset on the IfcAnnotation and resolved via tessellation at regeneration time. - resolve_anchor.py / regenerate_dimension.py: new ifcopenshell API modules - bim.set_dimension_anchor: 2-phase Object Mode modal (pick vertex → pick face) - bim.regenerate_dimensions: recomputes all parametric dimensions - Auto-regeneration via depsgraph_update_post when referenced elements move - placement_override reads Blender matrix_world for G-moved elements - Plan-view annotations flattened to annotation plane (Z=0 in local space) - IfcIndexedPolyCurve.Segments rebuilt to handle n-point chains correctly
…imensions Extends parametric dimension support with a modal polyline operator that uses Bonsai's existing snap infrastructure (same as walls/slabs) for placing anchor points. Shift+A in the Annotation tool now routes dimension types through this operator instead of the generic add_annotation path. - DrawParametricDimension: PolylineOperator subclass; each confirmed snap point is converted to a BBIM_DimensionTarget anchor via _snap_to_anchor, which reads face_index from the snap dict for face hits and falls back to closest_point_on_mesh for vertex/edge hits - handle_inserting_polyline override tracks anchor list in sync with polyline points (insert on count increase, pop on BACKSPACE) - hotkey_S_A dispatches to bim.draw_parametric_dimension for DIMENSION/RADIUS/ DIAMETER/ANGLE/PLAN_LEVEL/SECTION_LEVEL types; all other types keep existing path - depsgraph_update_post_handler extended to also watch is_updated_geometry so dimensions auto-regenerate when a referenced mesh is edited in Edit Mode; the affected element's tessellation is evicted from _dim_shape_cache so resolve_anchor re-tessellates from the updated IFC representation on the next pass Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SetDimensionAnchor — hover-select-then-confirm: - Cursor highlights candidate IFC elements (orange Blender selection outline) before committing; Tab cycles through overlapping/coplanar candidates - _compute_candidates: ray-cast all IFC mesh objects; falls back to 2D bounding-box proximity (5 cm tolerance) for plan-view picks where the ray misses the mesh by sub-mm amounts - _write_anchor: after anchoring a face, immediately calls regenerate_dimension with placement_override (Blender matrix_world) and _update_blender_curve so the curve vertex moves to the resolved point DrawParametricDimension — ForcePerpendicularToFace live snap constraint: - Reads force_perpendicular_to_face toggle from annotation props on invoke - After anchor[0] is placed on a FACE, _update_perp_constraint extracts the face normal and stores it as the constraint axis - _apply_perp_constraint runs every modal tick after handle_snap_selection, projecting the current snap point onto pt[0] + t*normal - On finalize, _create_dimension_from_polyline writes ForcePerpendicularToFace to the BBIM_Dimension pset and calls regenerate_dimension to snap the stored curve to the constraint before the operator exits regenerate_dimension.py: - ForcePerpendicularToFace block: after resolving all anchors, projects vertices 1…n onto the line through pt[0] along anchor[0]'s face normal - _get_anchor_face_normal_world: reads normal_local from anchor fingerprint, calls _rotate_local_to_world with placement_override; falls back to stored world-space normal resolve_anchor.py: - _rotate_local_to_world: transforms an element-local direction vector to world space using the element's placement or placement_override matrix pset/operator.py: - EditPset._execute: after editing a BBIM_Dimension pset on an IfcAnnotation, auto-calls regenerate_dimension + _update_blender_curve so changes to anchors/ForcePerpendicularToFace are reflected immediately in the viewport prop.py / workspace.py: - Added force_perpendicular_to_face BoolProperty to BIMAnnotationProperties - UI toggle shown in annotation tool header for DIMENSION/RADIUS/DIAMETER/ ANGLE/PLAN_LEVEL/SECTION_LEVEL types Psets_BBIM_Annotation.ifc: - Added ForcePerpendicularToFace property template (#39) to BBIM_Dimension - Extended BBIM_Dimension applicability to ANGLE, PLAN_LEVEL, SECTION_LEVEL Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cularToFace toggle updates selection workspace.py: - Move "Set Dimension Anchor" and "Regenerate" buttons from the properties panel (ui.py) into draw_edit_object_interface in the annotation tool, visible whenever a selected object is a dimension-type IfcAnnotation - Change force_perpendicular_to_face from a push-button (toggle=True) to a standard checkbox for clearer on/off state ui.py: - Remove the "Parametric Dimension" section (now lives in the tool header) prop.py: - Add _update_force_perpendicular update callback: when the checkbox is toggled, iterates all selected dimension annotations, writes the new ForcePerpendicularToFace value to each BBIM_Dimension pset, and calls regenerate_dimension so the constraint is applied immediately Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pendicularToFace - BBIM_Dimension.LinePosition (IfcLengthMeasure): holds the dimension line at a fixed global coordinate along cross(world_Z, dim_direction), independent of geometry movement - regenerate_dimension applies LinePosition only when ForcePerpendicularToFace is also set (the two are semantically coupled); anchor["pt"] always stores the true surface hit so the measured length is unaffected - BIMAnnotationProperties.line_position uses get/set callbacks instead of an update callback to avoid the 'Writing to ID classes in this context is not allowed' error that fires when Blender draws the tool header - DimensionLinePositionWidget (BIM_GGT_dimension_line_position): gizmo group with two opposing GizmoCone handles at the curve midpoint; poll requires ForcePerpendicularToFace so the handles only appear when the feature is active - UI: line_position field and gizmo are hidden when ForcePerpendicularToFace is off - Psets_BBIM_Annotation.ifc: #40 LinePosition template added to BBIM_Dimension Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tric dimensions - GizmoAnchorHandle + DimensionAnchorWidget: colored dot gizmos at each dimension curve vertex (green=anchored, orange=free); color changes to blue while SetDimensionAnchor is in PICK_FACE mode for that vertex - ClickNearestDimensionAnchor (LMB keymap): Python proximity operator that fires SetDimensionAnchor pre-targeted at the nearest anchor dot within 120px, returning PASS_THROUGH for misses so normal viewport clicks are unaffected - SetDimensionAnchor: added anchor_index prop to enter PICK_FACE directly; set_active_anchor called at all phase transitions (invoke, vertex-pick, face-pick, alt-click free, ESC/RMB) so gizmo color tracks state correctly - handler._sync_dimension_anchors_to_curve: proximity-based anchor sync when curve vertex count changes in Edit Mode (subdivide / delete) - depsgraph_update_post_handler: regenerates dimensions when referenced elements move; also handles annotation curve edits directly - Remove standalone Set Anchor button from annotation tool UI (replaced by clicking a gizmo dot) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… layer anchors - ClickNearestDimensionAnchor: scan all selected objects instead of active object so clicking a green dot doesn't lose to the underlying IFC geometry - GizmoAnchorHandle: remove draw_select entirely (any entry in the select buffer causes Blender's gizmo system to consume clicks); keep purely visual - Scale anchor dots to scale_basis = 0.2 - Fix ReferenceError in decoration.py draw loop after undo by catching ReferenceError and resetting DecoratorData.is_loaded - SetDimensionAnchor: inherit tool.Ifc.Operator so IFC pset writes are tracked for undo; finish the modal after each face write so each anchor gets its own undo step - Fix ReferenceError in _modal after undo when annotation RNA is freed - handler.py: add regenerate_dims_for_layer; call it from EditMaterialSetItem._execute so dimensions update when layer thickness changes - regenerate_dimension.py: fix ForcePerpendicularToFace for LAYER_BOUNDARY anchors by deriving the thickness-axis normal from LayerSetDirection (AXIS2→Y, AXIS1→X, AXIS3→Z) instead of requiring a stored normal_local Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…for DrawParametricDimension - DrawParametricDimension: TAB cycles snap mode FACE→LAYER→EDGE→VERTEX during placement; consumes both PRESS and RELEASE when not in input mode to avoid conflict with polyline Cycle Input - DrawParametricDimension: IFC-native snap candidate overrides polyline cursor position in LAYER/EDGE/VERTEX modes; FACE mode shows polygon outline; reuses _snap_draw_data / _draw_snap_indicator_global infrastructure from SetDimensionAnchor - DrawParametricDimension: LAYER_BOUNDARY support in _update_perp_constraint, deriving normal from LayerSetDirection (AXIS1/2/3) - ClickNearestDimensionAnchor: scan all visible annotations instead of only selected ones — view3d.select deselects the dimension before this operator runs, so pre-selection check caused dots to never activate - AnnotationTool keymap: bim.click_nearest_dimension_anchor placed before view3d.select so it fires first when the annotation tool is active Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove clear_snap_objs() from PolylineOperator.invoke — BVH cache now persists across invocations; per-entry staleness is checked in create_snap_obj via matrix_world equality + vertex count, eliminating the ~11 s full rebuild on every Shift+A press. - Add _init_snapping_points() hook to PolylineOperator; DrawParametricDimension overrides it with a cheap plane-intersection placeholder, deferring full BVH detection to the first MOUSEMOVE. - Cache matrix_world in SnapObj and replace O(N_vertices) validation loop with O(1) matrix equality + single sample vertex check, cutting per-call create_snap_obj cost from 22-600 ms to <0.2 ms on cache hits. - Use scene-level BVH pierce-through in SetDimensionAnchor._compute_candidates instead of per-object ray_cast loop (O(log N) vs O(N_objects)). - Guard PolylineDecorator snap_mouse_point access against empty collection to prevent IndexError before first MOUSEMOVE populates the property. - Wrap closest_point_on_mesh in try/except RuntimeError in _update_snap_draw_data for annotation objects with no internal mesh data. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nsion Vertical faces perpendicular to the camera cannot be hit by raycast, so the dimension snap tool missed them entirely. Fix by checking nearby objects whose 3D bbox contains the floor hit point and running mode-appropriate candidate lookup on each: - FACE mode: _snap_on_coplanar_faces finds vertical mesh faces with a bottom edge at the hovered Z, projects the cursor onto the face plane, and returns a FACE candidate (blue outline + face snap point). - LAYER mode: get_layer_snap_candidates now runs on nearby bbox objects the same way VERTEX/EDGE mode already did, using the shared _snap_cand_multi_cache (cleared on TAB mode switch).
theoryshaw
added a commit
that referenced
this pull request
May 21, 2026
Both PR #7798 (ManualDrawingReference) and PR #8083 (parametric_dimensions) independently added properties after entry #33 in Psets_BBIM_Annotation.ifc and new BoolProperty declarations after `type_name` in prop.py and workspace.py UI rows at the same locations. Resolution: keep #8083's IDs (#34-#40) unchanged, renumber #7798's IsManualDrawingReference and IsDocumentReference entries to #41 and #42, update EPset_Annotation reference list accordingly, keep both UI rows, and combine hotkey_S_A to use #8083's parametric-dimension routing with #7798's "INVOKE_DEFAULT" argument for add_annotation.
theoryshaw
added a commit
that referenced
this pull request
May 22, 2026
Both PR #7965 (inset_section_endpoints) and PR #8083 (parametric_dimensions) independently added properties after entry #33 in Psets_BBIM_Annotation.ifc and new BoolProperty declarations after `type_name` in prop.py and workspace.py UI rows at the same locations. Resolution: keep #8083's IDs (#34-#40) unchanged, renumber #7965's IsManualDrawingReference and IsDocumentReference entries to #41 and #42, update EPset_Annotation reference list accordingly, keep both UI rows, and combine hotkey_S_A to use #8083's parametric-dimension routing with #7965's "INVOKE_DEFAULT" argument for add_annotation.
…BBIM_Dimension.SuppressZeroInches Generated with the assistance of an AI coding tool.
Generated with the assistance of an AI coding tool.
…eometry New modal operator (bim.set_dimension_anchor) anchors dimension vertices to IFC element faces. Anchors are stored as JSON in a BBIM_DimensionTarget pset on the IfcAnnotation and resolved via tessellation at regeneration time. - resolve_anchor.py / regenerate_dimension.py: new ifcopenshell API modules - bim.set_dimension_anchor: 2-phase Object Mode modal (pick vertex → pick face) - bim.regenerate_dimensions: recomputes all parametric dimensions - Auto-regeneration via depsgraph_update_post when referenced elements move - placement_override reads Blender matrix_world for G-moved elements - Plan-view annotations flattened to annotation plane (Z=0 in local space) - IfcIndexedPolyCurve.Segments rebuilt to handle n-point chains correctly
…imensions Extends parametric dimension support with a modal polyline operator that uses Bonsai's existing snap infrastructure (same as walls/slabs) for placing anchor points. Shift+A in the Annotation tool now routes dimension types through this operator instead of the generic add_annotation path. - DrawParametricDimension: PolylineOperator subclass; each confirmed snap point is converted to a BBIM_DimensionTarget anchor via _snap_to_anchor, which reads face_index from the snap dict for face hits and falls back to closest_point_on_mesh for vertex/edge hits - handle_inserting_polyline override tracks anchor list in sync with polyline points (insert on count increase, pop on BACKSPACE) - hotkey_S_A dispatches to bim.draw_parametric_dimension for DIMENSION/RADIUS/ DIAMETER/ANGLE/PLAN_LEVEL/SECTION_LEVEL types; all other types keep existing path - depsgraph_update_post_handler extended to also watch is_updated_geometry so dimensions auto-regenerate when a referenced mesh is edited in Edit Mode; the affected element's tessellation is evicted from _dim_shape_cache so resolve_anchor re-tessellates from the updated IFC representation on the next pass Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SetDimensionAnchor — hover-select-then-confirm: - Cursor highlights candidate IFC elements (orange Blender selection outline) before committing; Tab cycles through overlapping/coplanar candidates - _compute_candidates: ray-cast all IFC mesh objects; falls back to 2D bounding-box proximity (5 cm tolerance) for plan-view picks where the ray misses the mesh by sub-mm amounts - _write_anchor: after anchoring a face, immediately calls regenerate_dimension with placement_override (Blender matrix_world) and _update_blender_curve so the curve vertex moves to the resolved point DrawParametricDimension — ForcePerpendicularToFace live snap constraint: - Reads force_perpendicular_to_face toggle from annotation props on invoke - After anchor[0] is placed on a FACE, _update_perp_constraint extracts the face normal and stores it as the constraint axis - _apply_perp_constraint runs every modal tick after handle_snap_selection, projecting the current snap point onto pt[0] + t*normal - On finalize, _create_dimension_from_polyline writes ForcePerpendicularToFace to the BBIM_Dimension pset and calls regenerate_dimension to snap the stored curve to the constraint before the operator exits regenerate_dimension.py: - ForcePerpendicularToFace block: after resolving all anchors, projects vertices 1…n onto the line through pt[0] along anchor[0]'s face normal - _get_anchor_face_normal_world: reads normal_local from anchor fingerprint, calls _rotate_local_to_world with placement_override; falls back to stored world-space normal resolve_anchor.py: - _rotate_local_to_world: transforms an element-local direction vector to world space using the element's placement or placement_override matrix pset/operator.py: - EditPset._execute: after editing a BBIM_Dimension pset on an IfcAnnotation, auto-calls regenerate_dimension + _update_blender_curve so changes to anchors/ForcePerpendicularToFace are reflected immediately in the viewport prop.py / workspace.py: - Added force_perpendicular_to_face BoolProperty to BIMAnnotationProperties - UI toggle shown in annotation tool header for DIMENSION/RADIUS/DIAMETER/ ANGLE/PLAN_LEVEL/SECTION_LEVEL types Psets_BBIM_Annotation.ifc: - Added ForcePerpendicularToFace property template (#39) to BBIM_Dimension - Extended BBIM_Dimension applicability to ANGLE, PLAN_LEVEL, SECTION_LEVEL Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cularToFace toggle updates selection workspace.py: - Move "Set Dimension Anchor" and "Regenerate" buttons from the properties panel (ui.py) into draw_edit_object_interface in the annotation tool, visible whenever a selected object is a dimension-type IfcAnnotation - Change force_perpendicular_to_face from a push-button (toggle=True) to a standard checkbox for clearer on/off state ui.py: - Remove the "Parametric Dimension" section (now lives in the tool header) prop.py: - Add _update_force_perpendicular update callback: when the checkbox is toggled, iterates all selected dimension annotations, writes the new ForcePerpendicularToFace value to each BBIM_Dimension pset, and calls regenerate_dimension so the constraint is applied immediately Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pendicularToFace - BBIM_Dimension.LinePosition (IfcLengthMeasure): holds the dimension line at a fixed global coordinate along cross(world_Z, dim_direction), independent of geometry movement - regenerate_dimension applies LinePosition only when ForcePerpendicularToFace is also set (the two are semantically coupled); anchor["pt"] always stores the true surface hit so the measured length is unaffected - BIMAnnotationProperties.line_position uses get/set callbacks instead of an update callback to avoid the 'Writing to ID classes in this context is not allowed' error that fires when Blender draws the tool header - DimensionLinePositionWidget (BIM_GGT_dimension_line_position): gizmo group with two opposing GizmoCone handles at the curve midpoint; poll requires ForcePerpendicularToFace so the handles only appear when the feature is active - UI: line_position field and gizmo are hidden when ForcePerpendicularToFace is off - Psets_BBIM_Annotation.ifc: #40 LinePosition template added to BBIM_Dimension Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tric dimensions - GizmoAnchorHandle + DimensionAnchorWidget: colored dot gizmos at each dimension curve vertex (green=anchored, orange=free); color changes to blue while SetDimensionAnchor is in PICK_FACE mode for that vertex - ClickNearestDimensionAnchor (LMB keymap): Python proximity operator that fires SetDimensionAnchor pre-targeted at the nearest anchor dot within 120px, returning PASS_THROUGH for misses so normal viewport clicks are unaffected - SetDimensionAnchor: added anchor_index prop to enter PICK_FACE directly; set_active_anchor called at all phase transitions (invoke, vertex-pick, face-pick, alt-click free, ESC/RMB) so gizmo color tracks state correctly - handler._sync_dimension_anchors_to_curve: proximity-based anchor sync when curve vertex count changes in Edit Mode (subdivide / delete) - depsgraph_update_post_handler: regenerates dimensions when referenced elements move; also handles annotation curve edits directly - Remove standalone Set Anchor button from annotation tool UI (replaced by clicking a gizmo dot) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… layer anchors - ClickNearestDimensionAnchor: scan all selected objects instead of active object so clicking a green dot doesn't lose to the underlying IFC geometry - GizmoAnchorHandle: remove draw_select entirely (any entry in the select buffer causes Blender's gizmo system to consume clicks); keep purely visual - Scale anchor dots to scale_basis = 0.2 - Fix ReferenceError in decoration.py draw loop after undo by catching ReferenceError and resetting DecoratorData.is_loaded - SetDimensionAnchor: inherit tool.Ifc.Operator so IFC pset writes are tracked for undo; finish the modal after each face write so each anchor gets its own undo step - Fix ReferenceError in _modal after undo when annotation RNA is freed - handler.py: add regenerate_dims_for_layer; call it from EditMaterialSetItem._execute so dimensions update when layer thickness changes - regenerate_dimension.py: fix ForcePerpendicularToFace for LAYER_BOUNDARY anchors by deriving the thickness-axis normal from LayerSetDirection (AXIS2→Y, AXIS1→X, AXIS3→Z) instead of requiring a stored normal_local Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…for DrawParametricDimension - DrawParametricDimension: TAB cycles snap mode FACE→LAYER→EDGE→VERTEX during placement; consumes both PRESS and RELEASE when not in input mode to avoid conflict with polyline Cycle Input - DrawParametricDimension: IFC-native snap candidate overrides polyline cursor position in LAYER/EDGE/VERTEX modes; FACE mode shows polygon outline; reuses _snap_draw_data / _draw_snap_indicator_global infrastructure from SetDimensionAnchor - DrawParametricDimension: LAYER_BOUNDARY support in _update_perp_constraint, deriving normal from LayerSetDirection (AXIS1/2/3) - ClickNearestDimensionAnchor: scan all visible annotations instead of only selected ones — view3d.select deselects the dimension before this operator runs, so pre-selection check caused dots to never activate - AnnotationTool keymap: bim.click_nearest_dimension_anchor placed before view3d.select so it fires first when the annotation tool is active Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove clear_snap_objs() from PolylineOperator.invoke — BVH cache now persists across invocations; per-entry staleness is checked in create_snap_obj via matrix_world equality + vertex count, eliminating the ~11 s full rebuild on every Shift+A press. - Add _init_snapping_points() hook to PolylineOperator; DrawParametricDimension overrides it with a cheap plane-intersection placeholder, deferring full BVH detection to the first MOUSEMOVE. - Cache matrix_world in SnapObj and replace O(N_vertices) validation loop with O(1) matrix equality + single sample vertex check, cutting per-call create_snap_obj cost from 22-600 ms to <0.2 ms on cache hits. - Use scene-level BVH pierce-through in SetDimensionAnchor._compute_candidates instead of per-object ray_cast loop (O(log N) vs O(N_objects)). - Guard PolylineDecorator snap_mouse_point access against empty collection to prevent IndexError before first MOUSEMOVE populates the property. - Wrap closest_point_on_mesh in try/except RuntimeError in _update_snap_draw_data for annotation objects with no internal mesh data. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nsion Vertical faces perpendicular to the camera cannot be hit by raycast, so the dimension snap tool missed them entirely. Fix by checking nearby objects whose 3D bbox contains the floor hit point and running mode-appropriate candidate lookup on each: - FACE mode: _snap_on_coplanar_faces finds vertical mesh faces with a bottom edge at the hovered Z, projects the cursor onto the face plane, and returns a FACE candidate (blue outline + face snap point). - LAYER mode: get_layer_snap_candidates now runs on nearby bbox objects the same way VERTEX/EDGE mode already did, using the shared _snap_cand_multi_cache (cleared on TAB mode switch).
…rcePerpendicularToFace - Switch FACE/LAYER mode nearby-object filtering from 3D bbox to 2D screen-space bbox (30px tolerance), fixing walls whose local Y extent doesn't contain the floor hit point (e.g. wall at Z=0 with mesh not quite reaching the floor level). - Also run _snap_on_coplanar_faces on hit_obj itself so the blue outline and IFC snap fire even when the cursor lands exactly on the wall/floor boundary (hit_obj IS the wall, previously skipped). - Store face_normal_world in coplanar face candidates and call build_anchor_from_hit in _build_ifc_anchor for snap=="FACE", so the anchor gets a proper FACE type with normal_local in addr. This enables ForcePerpendicularToFace and LinePosition to work for coplanar edge-on face snaps the same as directly-hit faces. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tline - Add dedicated POST_PIXEL GPU callback (_draw_anchor_hover_global) using pre-converted 2D screen coords, replacing the shared POST_VIEW callback that caused GPU state issues and Blender freezes - Add LAYER snap mode hover indicator showing full seam-corner outline - Remove select_set calls from hover highlight to prevent green object outline - Add _is_hidden() using hide_get/hide_viewport/visible_get so only scene- visible objects are snap candidates - Add _face_perp_ok() filter (camera-based) to prefer wall faces over floor/ceiling faces in FACE mode; non-perp hits tracked in ray_hit_objs so directly-hit elements always rank above proximity-found neighbours - Add _get_current_anchor_guid() to promote the currently-bound element to the front of the candidate list when re-picking an anchor vertex - Add _coplanar_face_outline() to merge tessellated triangles (including walls with window/door voids) into the correct outer face boundary; walks all disconnected loops and returns the largest (outer perimeter), skips meshes > 500 polygons to avoid freezing on terrain objects - Skip _prefer_perp_face_index in FACE mode so the exact hit face is used rather than the face most perpendicular to the camera - Sort proximity candidates so ray-hit objects rank before bbox-only matches Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
0eee689 to
76e390f
Compare
Member
Author
The build (BonsaiPR v0.8.6-alpha260608-c65433c) already contains old parametric_dimensions commits (pre-rebase, different hashes) followed by PR #7798 (ManualDrawingReference) and other PRs merged on top. After the rebase of parametric_dimensions onto v0.8.0, git's LCA between the build state and this branch reverted to v0.8.0. This caused false conflicts in DrawParametricDimension (operator.py) where both sides "added" it from empty, and real conflicts in prop.py/workspace.py/pset from PR #7798 additions that now appeared as build-only changes. Fix: merge old-pd tip 913c9c4 with -s ours (no content change) to make it a git ancestor of this branch. This shifts the LCA to 913c9c4, so: - operator.py: only new pd changed DrawParametricDimension from that LCA -> clean - prop.py / workspace.py / pset: new pd = LCA; build added #7798 content -> clean Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Member
Author
…ension Walls viewed edge-on in plan (2-7 px screen bbox) were never hit by Blender's raycast, so all three snap modes silently returned nothing. - FACE: remove has_coplanar_edge Z-gate; vertical faces are now snappable regardless of what elevation the native snap lands on (sub-floor surfaces at Z~-7.5m were blocking all candidates) - All modes: replace hardcoded 30 px _FACE_THRESH_D2 with a per-candidate max_tol that matches the adaptive _SCREEN_TOL used for bbox inclusion (~98 px for 2 px-wide walls) - VERTEX/EDGE/LAYER: remove early `if not hit_obj: return None`; all modes now search objs_2d_bbox with adaptive tolerance when the primary raycast misses - Add _get_mesh_snap_candidates fallback for tessellated elements (IfcFacetedBrep etc.) where get_profile_snap_candidates returns [] - Add LOCAL_POINT anchor method (build_anchor_from_local_point + resolve_anchor handler) so mesh-derived anchors store element-local coords and follow the element through moves/rotations rather than becoming free-floating WORLD anchors Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…stale active-obj guard ClickNearestDimensionAnchor was firing SetDimensionAnchor immediately on LMB PRESS and returning FINISHED, which caused Blender to re-deliver the RELEASE to view3d.select — deselecting the annotation mid-flight. Rewrite as a two-event modal: PRESS starts the modal, RELEASE fires SetDimensionAnchor and exits. SetDimensionAnchor also swallows any LMB RELEASE it receives to prevent view3d.select from stealing the active object after hand-off. The pre-click active-object guard (skip if dimension not active_object) caused dots to never turn blue: view3d.select was silently replacing the dimension with the plane underneath on every line-body click, so the dimension was never the active object at the time of the dot click. Removed — the operator now selects the dimension itself before going modal, making each dot click self-contained. RADIUS_PX reduced from 60 to 15 to match the gizmo disc visual size and prevent false triggers on line-body clicks near endpoints.
regenerate_dimension was only called when ForcePerpendicularToFace was set, so normal two-anchor dimensions were left at raw polyline cursor positions after placement. The depsgraph handler would later correct them when the user happened to select a referenced IFC element, making accurate placement appear to require a manual selection step. Remove the _force_perpendicular guard so the anchor-based regeneration always runs at the end of _create_dimension_from_polyline.
…cularToFace DimensionLinePositionWidget was gated behind ForcePerpendicularToFace in both the gizmo poll and the regenerate_dimension LinePosition application. The coupling was unnecessary: _get_line_offset_direction already derives the offset axis from cross(world_Z, dim_direction) as its primary path, requiring the face normal only as a vertical-dimension fallback. Remove the ForcePerpendicularToFace guard from both sites so any anchor-based dimension shows the drag arrows and responds to LinePosition.
…X/EDGE snaps When SetDimensionAnchor's tessellation fallback ran (element has no IfcExtrudedAreaSolid, so get_profile_snap_candidates returns empty), VERTEX and EDGE snaps created a static world anchor (free end) instead of a parametric one. The anchor had a position but no guid, so it never moved with the element. _compute_snap_geom now includes local_m (element-local Blender coordinates, metres) in the tessellation fallback return dict for both VERTEX and EDGE modes. _handle_face_pick uses build_anchor_from_local_point when local_m is present, storing a LOCAL_POINT anchor that resolves back to world space via the element placement — so the endpoint follows the element through moves and rotations.
…h UI BakeParametricDimension (bim.bake_parametric_dimension): removes the BBIM_Dimension pset from the active annotation, leaving the curve geometry in place as a static dimension that no longer regenerates when referenced elements move. MakeDimensionParametric (bim.make_dimension_parametric): adds a BBIM_Dimension pset to a static dimension annotation, creating one free world-point anchor per spline vertex at the current positions. The endpoints can then be re-anchored to IFC faces via SetDimensionAnchor.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
addresses #1320
Still some things to iron out, but putting this out there to test on BonsaiPR.
20260519_0944.mp4