FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Saikei alignment editing capabilities by Moult · Pull Request #7589 · IfcOpenShell/IfcOpenShell · GitHub

Saikei alignment editing capabilities - #7589

Draft
Moult wants to merge 53 commits into
v0.8.0from
saikei
Draft

Saikei alignment editing capabilities#7589
Moult wants to merge 53 commits into
v0.8.0from
saikei

Conversation

Moult commented Jan 21, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Do not merge yet, slowly working through the code from Saikei

Saikei has implemented a bunch of alignment authoring in Blender. This code represents the ability to create an alignment, create a horizontal alignment (no vertical or cant yet), and tabular editing of the PI points of alignment segments. There is more functionality in Saikei but not yet available in this PR.

Some TODO items

  • Redo copyright headers to have consistent formatting
  • Refactor core into tool
  • Remove code that could be done using tool.Ifc
  • Detailed line by line review
  • Review "debug" API operators
  • Move UI into Bonsai tabs instead of viewport tab
  • Triple check all coordinate conversions. Sampling should be done in Blender coords. UI should be done in global coords. IFC should be in local coords. 2D layouts should be in Blender z=0.
  • Replace Saikei prefixes with Bonsai for consistency
  • Replace polyline tool with existing tool.Polyline modals
  • Make loading and creation consistent in terms of displaying alignment and toggling edit of layouts / segments

Moult requested a review from RickBrice January 21, 2026 01:49

Copy link
Copy Markdown
Contributor

Happy to review. What is the timeframe? I’m pretty swamped until after 2nd week of February.

Recommend @civilx64 is added as a reviewer as well

Moult commented Jan 21, 2026

Copy link
Copy Markdown
Contributor Author

No particular timeframe, this is just an incremental integration of features from Saikei. It might be good to have a video call with @DesertSpringsCivil (MYoder89)

Copy link
Copy Markdown
Contributor

Hey all! Happy to jump on a video call any time, and feel free to pull in anyone else who you think might be interested.

I started building Saikei on my own, but am working to merge it in with Bonsai now. You can see the pre-merged version on the project page here (https://saikeicivil.org/). The ultimate goal right now would be to merge everything up through corridor creation with parametric controls.

Copy link
Copy Markdown
Contributor

I have availability for a video call next week.
Tuesday 7a-1pm
Wednesday 1-3p
Thursday 10am-3pm
Friday 7-9am 1-2pm
All Pacific Time.

Copy link
Copy Markdown
Contributor

@Moult I need some help. I checked out this PR. When I fire up blender, I get the following error

Exception in module register(): C:\Users\bricer\AppData\Roaming\Blender Foundation\Blender\5.0\extensions\raw_githubusercontent_com\bonsai\__init__.py
Traceback (most recent call last):
  File "C:\Program Files\Blender Foundation\Blender 5.0\5.0\scripts\modules\addon_utils.py", line 515, in enable
    mod.register()
  File "C:\Users\bricer\AppData\Roaming\Blender Foundation\Blender\5.0\extensions\raw_githubusercontent_com\bonsai\__init__.py", line 289, in register
    import bonsai.bim
  File "C:\Users\bricer\AppData\Roaming\Blender Foundation\Blender\5.0\extensions\.local\lib\python3.11\site-packages\bonsai\bim\__init__.py", line 24, in <module>
    from . import handler, ui, prop, operator
  File "C:\Users\bricer\AppData\Roaming\Blender Foundation\Blender\5.0\extensions\.local\lib\python3.11\site-packages\bonsai\bim\handler.py", line 26, in <module>
    import bonsai.tool as tool
  File "C:\Users\bricer\AppData\Roaming\Blender Foundation\Blender\5.0\extensions\.local\lib\python3.11\site-packages\bonsai\tool\__init__.py", line 20, in <module>
    from bonsai.tool.alignment import Alignment
ModuleNotFoundError: No module named 'bonsai.tool.alignment'

I ran the script for the live development environment and have confirmed that the bonsai folder listed in the error message maps to my development environment where the PR was checkout to.

I think there are issues related to intermediate code changes, but I'm not sure what to do about that. Does this PR work for you? Please advise.

Moult commented Jan 22, 2026

Copy link
Copy Markdown
Contributor Author

Whoops :)

Copy link
Copy Markdown
Contributor

... and magically it all works now. Thanks

Copy link
Copy Markdown
Contributor

I have availability for a video call next week. Tuesday 7a-1pm Wednesday 1-3p Thursday 10am-3pm Friday 7-9am 1-2pm All Pacific Time.

How does next Wednesday 2 pm PST/3 pm MST sound? I can do Jitsi, Teams, Matrix- whatever works for everyone.

Copy link
Copy Markdown
Contributor

Wednesday 1/28 at 2/3pm is perfect. I PMd you on linked in with contact info. I can set up a teams meeting with your email

DesertSpringsCivil and others added 3 commits January 28, 2026 11:18
- Move math/calculation functions from core to tool layer
  (calculate_pi_geometry, calculate_deflection_angle, etc.)
- Remove duplicate get_ifc_file() wrappers, use tool.Ifc.get() directly
- Remove redundant ifc_definition_id manual settings (tool.Ifc.link handles this)
- Remove fallback object lookup methods (_find_object_by_ifc_id, _find_object_by_name_pattern)
- Simplify remove methods to use tool.Ifc.get_object() directly
- Clean up defensive try/except ImportError blocks
- Update is_ifc4x3() to use tool.Ifc.get_schema()
- Update license headers to Bonsai standard

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Operators removed (not called in any UI):
- SAIKEI_OT_create_alignment_polyline
- SAIKEI_OT_create_alignment_offset
- SAIKEI_OT_add_vertical_layout
- SAIKEI_OT_add_layout_segment
- SAIKEI_OT_layout_horizontal_by_pi
- SAIKEI_OT_layout_vertical_by_pi
- SAIKEI_OT_create_representation
- SAIKEI_OT_create_segment_representations
- SAIKEI_OT_update_fallback_position
- SAIKEI_OT_validate_segments
- SAIKEI_OT_refresh_alignment_data

Also fixed poll_ifc4x3() and replaced all tool.Alignment.get_ifc_file()
calls with tool.Ifc.get() after previous refactoring removed that method.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Removed leftover imports from sequence module template:
- isodate, dateutil, calendar, datetime
- bonsai.bim.module.sequence.helper
- ifcopenshell.util.sequence, ifcopenshell.geom, ifcopenshell.util.selector
- Duplicate imports (os, json, ImportHelper, ifcopenshell.api.alignment)

These unused imports were causing silent module registration failures.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

RickBrice left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Excellent start. I couldn't get this far.

Consider using the IfcOpenShell geometry capabilities.

If you create and save and alignment model, you don't get it back when you re-open it. This is because the code that loads the model looks at the alignment and a single entity while the editing UI is expecting segments.

I'll probably have more comments, but will wait until after we have a meetup.

Comment thread src/bonsai/bonsai/tool/alignment.py Outdated
name = f"Segment {index + 1} ({seg_type})"

# Create curve geometry based on segment type
if seg_type == "LINE":

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Consider using the IfcOpenShell implementation for geometry mapping. It already supports all the curve and spiral types.

DesertSpringsCivil and others added 10 commits January 31, 2026 13:35
Replace manual per-segment geometry creation with IfcOpenShell's
built-in generate_vertices() utility. This provides automatic support
for all curve types (CLOTHOID, spirals, etc.) and removes ~75 lines
of manual geometry code.

Changes:
- Add create_curve_from_representation() using IfcOpenShell geometry engine
- Add _create_segment_empty() for segment selection without geometry
- Update create_objects_for_layout_segments() to use new methods
- Delete manual geometry methods: create_object_for_segment(),
  _create_line_segment(), _create_arc_segment()

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Git checkout with glob patterns (*.ifc) doesn't work on Windows.
This change:
- Expands glob via git ls-files and checks out files individually
- Skips symlink recreation if they already exist and are valid
- Refreshes git index before checkout to recognize deleted files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add new CIVIL tab (4th position) with CURVE_DATA icon
- Create BIM_PT_tab_horizontal_alignment panel container
- Move alignment UI from N-panel to Properties sidebar
- Remove old "Saikei Civil" N-panel tab

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
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>
…pport

- 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>
…ment warnings

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>
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>
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>
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>
DesertSpringsCivil and others added 2 commits February 18, 2026 19:40
…ecture

- Fix 4 runtime bugs: seg/s variable mismatch, missing float() wrappers,
  PI dict key mismatches ("x"/"y" -> "e"/"n"), float-to-StringProperty
- Remove ~470 lines of dead code across prop.py, core/alignment.py,
  tool/alignment.py, and operator.py
- Consolidate duplicate math functions from operator.py into tool layer
  (arc_length_at_pi, tangent_length_at_pi, tangent_segment_length)
- Move PI extraction logic from operator.py to tool/alignment.py
- Add IfcStore undo pattern to 7 IFC-modifying operators
- Core layer no longer calls IFC API directly (delegates via tool wrappers)
- Remove unused imports (math, IntProperty, Vector)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

civilx64 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

General comments for understanding segment_vertices in alignment API

Copy link
Copy Markdown
Contributor

Regarding segment_vertices function - would it make sense to have the curve_segment parameter be an IfcAlignmentSegment instead of an IfcCurveSegment?

My thinking is that for Helmert curves, the business logic segment maps into two geometric segments. This could be cleanly handled with IfcAlignmentSegment without any extra coding by the caller.

With IfcCurveSegment being the function parameter, the caller needs to know if a Helmert curve is being evaluated and get the vertices for both halves and then do some extra math to get the TI and NI points.

Some other options are:

  1. curve_segment could be either IfcAlignmentSegment or IfcCurveSegment, but problem remains the same if IfcCurveSegment is used with a Helmert curve
  2. The function could take two curve segment parameters. The second parameter would always be provided if a Helmert curve or otherwise None. Though this would not be enforceable, Callers could pass in whatever curve segments they like at their own peril.

What do you guys think?

DesertSpringsCivil commented Feb 23, 2026 via email

Copy link
Copy Markdown
Contributor

Renamed PI and CC to TI and NI
Fixes handling of units (now works correctly with US and SI units)
Changed tests to use US feet units
Fixed documentation

Copy link
Copy Markdown
Contributor

IfcAlignmentSegment makes perfect sense for the reasons you mentioned. It also makes sense for a consumer of the API to think primarily in terms of business logic and let the implementation abstract away the nuances of the corresponding shape representation(s).

Copy link
Copy Markdown
Contributor

I made a couple tweaks to the alignment API. segment_vertices can now accept an IfcAlignmentSegment or IfcCurveSegment. I still need to improve the unit tests.

Also, when creating an alignment that has a geometric representation, the representation of each IfcAlignmentSegment is automatically created and attached to the segment. So now we can get the representation from IfcAlignment as a composite curve and from IfcAlignmentSegment as a IfcCurveSegment.

Copy link
Copy Markdown
Contributor

@DesertSpringsCivil and example script for segment_vertices
plot_segment_vertices.py

Copy link
Copy Markdown
Contributor

Nice, thanks Rick! I'm working on incorporating these API functions into the Saikei code right now.

RickBrice and others added 14 commits February 24, 2026 12:44
updates some documentation
removes some dead code
Uses Rick Brice's new ifcopenshell.api.alignment.segment_vertices()
to extract PI positions from alignment segments via the C++ geometry
engine, replacing ~300 lines of hand-coded trig that only handled
LINE and CIRCULARARC. Now supports all segment types (CLOTHOID,
Helmert curves, etc.). Includes backward-compatible fallback for
IFC files without Axis/Segment representations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wrap SAIKEI_OT_enter_pi_edit_mode with Bonsai's IfcStore transaction
system so IFC segment changes from applying PI edits are tracked and
undoable via Ctrl+Z.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
get_mapped_segments now looks for representations attached to alignment segments before using the more complex method of computing the index of segments in the composite curve.
updates segment_vertices to use get_mapped_segments
Ignore CLAUDE.md, CLAUDE.local.md, and .mcp.json so personal
Claude Code configuration (managed via private dotfiles repo)
doesn't pollute the shared repository.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename all saikei.* operator idnames to civil.* per Bonsai convention
- Rename SAIKEI_OT_*, SAIKEI_PT_*, SAIKEI_UL_* classes to CIVIL_* prefix
- Rename SaikeiAlignmentProperties -> CivilAlignmentProperties
- Rename saikei_* Blender object custom property keys to civil_*
- Remove IOS-version-compat try/except fallback in _get_segment_vertices_in_model_units()
  now that Rick's segment_vertices() API accepts IfcAlignmentSegment directly
- Remove try/except wrapper around get_alignment() - call directly
- Add Michael Yoder copyright to __init__.py and operator.py
- Fix misleading coordinate comment (IFC -> global easting/northing)
- Document props.pis coordinate system (global E/N) in AlignmentPI and operator comments

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

4 participants


Back | FazBrowse Home | New Git URL