Skip to content

Fix wall generation from multi-loop composite slab profiles, including arcs/fillets and circles#8239

Open
sboddy with Copilot wants to merge 7 commits into
v0.8.0from
copilot/research-wall-generation-from-slabs
Open

Fix wall generation from multi-loop composite slab profiles, including arcs/fillets and circles#8239
sboddy with Copilot wants to merge 7 commits into
v0.8.0from
copilot/research-wall-generation-from-slabs

Conversation

Copilot AI commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

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 Perimeter generated walls from slab perimeter vertices only, so IfcIndexedPolyCurve arcs 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 for IfcIndexedPolyCurve with arc segments.
    • Added _curve_has_arc_segments() to detect arc-bearing segment payloads across wrapper representations.
  • Arc segment sampling to wall segments

    • Added _derive_points_from_arc_segments() to convert IfcArcIndex triplets into sampled points via tool.Cad.create_arc_segments(...).
    • Ensures start→end arc traversal consistency before wall creation, so segment ordering stays contiguous around the perimeter.
  • Perimeter robustness

    • Added _world_xy_point() for consistent IFC→world conversion.
    • Added point deduplication tolerance and explicit loop closure.
    • For non-arc indexed line segments, all referenced indices are now emitted (not only endpoints), preserving multi-index segment detail.

Creating walls from a slab failed when the slab outer curve was IfcCircle, because the wall generator only handled polyline-like curves and raised Unsupported polyline type: IfcCircle. This change adds a dedicated circle path so circular slabs can produce wall segments via Shift+A without throwing.

Changes

  • Wall generation: curve-type coverage

    • Added IfcCircle handling in DumbWallGenerator.derive_from_slab().
    • Kept existing behavior for indexed polycurves (including arc segments) and other supported polyline curves.
  • Circle perimeter extraction

    • Added _derive_points_from_circle(...) to sample circular perimeters using SLAB_ARC_RESOLUTION.
    • Applies slab object/world transform and circle local placement (IfcAxis2Placement2D) before wall segment creation.
    • Closes the sampled loop explicitly for consistent downstream segment iteration.
  • AI-generated contribution

    • This PR includes code generated/modified with the assistance of an AI coding tool.

When a slab has multiple separate closed loops, its swept area is IfcCompositeProfileDef (which has Profiles, not OuterCurve). Calling Shift+A to draw walls from such a slab raised AttributeError: entity instance of type 'IFC4.IfcCompositeProfileDef' has no attribute 'OuterCurve'.

  • derive_from_slab (wall.py): detect IfcCompositeProfileDef and iterate over each of its Profiles rather than assuming a single OuterCurve. 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):

  1. Crashextrusion.SweptArea.OuterCurve raises AttributeError because IfcCompositeProfileDef has Profiles, not OuterCurve.
  2. Phantom walls far outside the bounding box — the post-generation DumbWallJoiner loop 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: detects IfcCompositeProfileDef and iterates over each constituent profile, building walls per loop independently; returns a list[list[wall]] (one inner list per closed loop) instead of a flat list.
  • DrawWallsFromSlab._execute: updated to iterate over wall groups, running the DumbWallJoiner ring-connect only within each loop's own walls.

Single-profile slabs are unaffected — wall_groups has one element and the behaviour is identical to before.

Copilot AI changed the title Interpret IfcArcIndex slab perimeters for wall generation Handle IfcCircle slabs in wall-from-slab generation Jul 2, 2026
Copilot finished work on behalf of sboddy July 2, 2026 22:12
Copilot AI requested a review from sboddy July 2, 2026 22:12
When 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
Copilot finished work on behalf of sboddy July 2, 2026 23:22
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 finished work on behalf of sboddy July 2, 2026 23:54
Copilot finished work on behalf of sboddy July 3, 2026 00:06
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
@sboddy sboddy changed the title Fix wall generation from multi-loop composite slab profiles Fix wall generation from multi-loop composite slab profiles, including arcs/fillets and circles Jul 3, 2026
@sboddy

sboddy commented Jul 3, 2026

Copy link
Copy Markdown
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.

@sboddy sboddy marked this pull request as ready for review July 3, 2026 01:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Using a slab w/ 3-point-arc or fillet to add walls

2 participants