Replace hardcoded 5-degree angle snapping with Blender's
snap_angle_increment setting in create_wall_from_2_points()
and create_profile_from_2_points().
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace hardcoded 5-degree angle snapping with Blender's
snap_angle_increment setting in handle_lock_axis() for:
- Initial angle rounding when locking axis (A key)
- Angle rounding and increments on Shift+Wheel scroll
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace hardcoded 5-degree angle snapping with Blender's
snap_angle_increment setting in calculate_distance_and_angle().
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This function retrieves the angle snap increment from Blender's
tool_settings.snap_angle_increment property, which was added in
Blender 4.2. This allows users to configure the angle snap value
through Blender's native UI instead of using hardcoded values.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add clear_layout_segments API to remove segments while preserving alignment ID
- Modify exit_pi_edit_mode to edit segments in-place instead of delete+recreate
- Fix curve visualization by using create_shape for segment vertices
- Fix evaluate_segment validation to handle negative-length curve segments
This prevents "Active alignment no longer exists" errors when editing PIs
and properly renders circular arcs regardless of turn direction.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, sort, reverse list, and join functionality was implemented
as special cases in Bonsai itself. Given that it has usecases
(especially in material lists, but any sort of list applies) I've moved
this function into the IOS formatting language.
The IOS formatting language previously wasn't capable of this, but the
awesome addition by @falken10vdl made the formatting language accept
queries inline, so that means it can handle lists. I also added tests
for all the new functions and expression syntax (+-*/ operators).
I simplified the code that gets the evaluated text literal - previously
it seems to call format() multiple times.
Previously, copy attribution was coupled with text editing. This meant
that you couldn't just do something like change the font or alignment
without also affecting literals. Now like most apps you can just select
bunch of text and change font size etc, using the same UI look and feel
that copying attribute has when editing attributes.
This refactor also removes the need for explicit props tracking each
possible attribute to copy, and the settings collection group. Bulk
applying is now done in core with no calls to UI.
Turned out `aud` module we had in our makefile had nothing to do with Blender built-in `uad` module 🫣
So no need to install anything from PyPI since this module is generally available in Blender
This isn't complete yet, but it hopefully demonstrates a preferred
implementation:
* Logic in core, not operator
* Loop done in core, without needing to call other core functions, so
the overhead of enabling and disabling editing per object is removed. No
more Blender logic, just straight editing in IFC.
* Reuse existing function to grab text attributes instead of
reimplementing it twice.
* Remove dead code, there seems to be a function
apply_to_selected_objects which was completely unused and duplicated
code twice.
When using G key to move PIs, Blender's transform modal consumes
the Enter key. Adding Space as an alternative lets users apply
changes more easily. Also adds Numpad Enter support.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements the ability to edit alignment PI (Point of Intersection)
positions after creation using Blender's standard transform tools:
- Back-calculate PI positions from existing IFC alignment segments
- Create temporary EMPTY objects at PI locations for editing
- Visual feedback via PIEditDecorator (yellow tangent lines, HUD)
- Modal operator handles G key movement, Enter to apply, Escape to cancel
- Regenerates alignment with new PI positions on apply
- Handles edge cases: single-segment, tangent-only, undo during edit
Architecture follows Bonsai patterns:
- Core layer: Business logic orchestration (enter/exit_pi_edit_mode)
- Tool layer: Math, IFC, and Blender implementations
- UI layer: Modal operator with PASS_THROUGH for standard transforms
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This file contains project-specific context for Claude Code sessions.
It should NOT be pushed to origin (protected by pre-push hook).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add visual feedback during PI placement with PIPickerDecorator:
- Yellow tangent lines connecting placed PIs
- Rubber band line from last PI to cursor position
- Green circle markers at each PI location
- HUD text showing instructions and PI count
Follows Bonsai's established decorator pattern with GPU draw handlers.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace segment empty objects with actual curve geometry so that selecting
a segment in the Outliner highlights the corresponding line/curve in the
viewport.
Changes:
- Add get_segment_vertices() using IfcOpenShell's evaluate_segment() to
sample points along individual segments via the geometry engine
- Replace _create_segment_empty with _create_segment_curve that creates
Blender CURVE objects with actual geometry
- Remove single HorizontalCurve in favor of per-segment curves
- Supports all segment types (LINE, CIRCULARARC, CLOTHOID, spirals, etc.)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Zero-length segments are required by IFC to mark alignment ends but should
be invisible to users. This change:
- Adds helper methods to detect zero-length and empty layouts
- Silently skips geometry generation for empty alignments (no error messages)
- Excludes zero-length segments from Outliner display
- Uses separate visible segment counter for consistent naming
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix modal operator to use absolute mouse coordinates converted to 3D
viewport region space, instead of event.mouse_region_x/y which are
relative to whichever region received the event
- Store 3D viewport area, region, and region_data references in invoke()
for consistent raycasting throughout modal operation
- Add coordinate transformation methods (blender_to_ifc_coordinates and
ifc_to_blender_coordinates) for projects with geospatial Blender offsets
- Transform alignment curve vertices from IFC global to Blender local
coordinates when has_blender_offset is enabled
- Add try/except for piecewise-step-size geometry setting in util.py
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Simplifies the Horizontal Alignment panel by removing the Import
Alignment CSV button and the PI Details submenu that displayed
when selecting rows in the PI Editor list.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix issue where selected text annotations remained in editing mode after
applying changes. Now properly restores original editing state for each
selected object.
Add RuntimeError handling for IfcOpenShell versions that don't support
the piecewise-step-type setting in geometry generation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>