Open
Fix wall generation from multi-loop composite slab profiles, including arcs/fillets and circles#8239
Conversation
Copilot created this pull request from a session on behalf of
sboddy
July 2, 2026 21:51
View session
Copilot
AI
changed the title
Interpret
Handle IfcCircle slabs in wall-from-slab generation
Jul 2, 2026
IfcArcIndex slab perimeters for wall generationWhen a slab consists of multiple separate closed loops, the swept area is IfcCompositeProfileDef which has a Profiles attribute rather than OuterCurve. Iterate over each profile and generate walls for all loops. Generated with the assistance of an AI coding tool.
Copilot
AI
changed the title
Handle IfcCircle slabs in wall-from-slab generation
bonsai: handle IfcCompositeProfileDef in derive_from_slab
Jul 2, 2026
When a slab has two separate closed loops (IfcCompositeProfileDef), the flat walls list was passed to DumbWallJoiner in a circular ring, cross-connecting the last wall of loop 1 to the first wall of loop 2. The joiner then computed an intersection between non-intersecting walls, producing endpoints far outside the slab's bounding box. Group walls by loop in derive_from_slab and join only within each group. Generated with the assistance of an AI coding tool.
Copilot
AI
changed the title
bonsai: handle IfcCompositeProfileDef in derive_from_slab
Fix wall generation from multi-loop composite slab profiles
Jul 2, 2026
Copilot stopped work on behalf of
sboddy due to an error
July 3, 2026 00:14
Copilot stopped work on behalf of
sboddy due to an error
July 3, 2026 00:15
Contributor
|
I've tested this locally, and it fixes the wall from slab generation where arcs, fillets, and circles are used. Furthermore, a slab can define multiple independent loops, and the wall generation still works. Setting this to ready so that it gets pulled into BonsaiPR where it can get a bit of exposure. Don't merge to main yet. |
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.
This PR is to fix #6896 but during testing copilots solution a second issue was discovered and fixed. Namely that multiple loops in the slab would cause an exception.
Shift+A → Add From Perimetergenerated walls from slab perimeter vertices only, soIfcIndexedPolyCurvearcs were treated like straight chords. This change makes slab-to-wall generation interpret arc segments and circles and emit contiguous wall segments along sampled arc geometry.Changes
Arc-aware perimeter extraction
DumbWallGenerator.derive_from_slab()now branches on curve content: existing polyline path for non-arc curves; arc-aware path forIfcIndexedPolyCurvewith arc segments._curve_has_arc_segments()to detect arc-bearing segment payloads across wrapper representations.Arc segment sampling to wall segments
_derive_points_from_arc_segments()to convertIfcArcIndextriplets into sampled points viatool.Cad.create_arc_segments(...).Perimeter robustness
_world_xy_point()for consistent IFC→world conversion.Creating walls from a slab failed when the slab outer curve was
IfcCircle, because the wall generator only handled polyline-like curves and raisedUnsupported polyline type: IfcCircle. This change adds a dedicated circle path so circular slabs can produce wall segments viaShift+Awithout throwing.Changes
Wall generation: curve-type coverage
IfcCirclehandling inDumbWallGenerator.derive_from_slab().Circle perimeter extraction
_derive_points_from_circle(...)to sample circular perimeters usingSLAB_ARC_RESOLUTION.IfcAxis2Placement2D) before wall segment creation.AI-generated contribution
When a slab has multiple separate closed loops, its swept area is
IfcCompositeProfileDef(which hasProfiles, notOuterCurve). CallingShift+Ato draw walls from such a slab raisedAttributeError: entity instance of type 'IFC4.IfcCompositeProfileDef' has no attribute 'OuterCurve'.derive_from_slab(wall.py): detectIfcCompositeProfileDefand iterate over each of itsProfilesrather than assuming a singleOuterCurve. Each closed loop is processed independently and walls are generated for all of them. Single-profile slabs are unaffected.Two bugs when generating walls from a slab whose swept area is
IfcCompositeProfileDef(multiple separate closed loops):extrusion.SweptArea.OuterCurveraisesAttributeErrorbecauseIfcCompositeProfileDefhasProfiles, notOuterCurve.DumbWallJoinerloop treated all walls as a single circular ring, cross-connecting the last wall of loop N to the first wall of loop N+1. Since those walls never intersect, the computed join point lands far from the slab.Changes
derive_from_slab: detectsIfcCompositeProfileDefand iterates over each constituent profile, building walls per loop independently; returns alist[list[wall]](one inner list per closed loop) instead of a flat list.DrawWallsFromSlab._execute: updated to iterate over wall groups, running theDumbWallJoinerring-connect only within each loop's own walls.Single-profile slabs are unaffected —
wall_groupshas one element and the behaviour is identical to before.