feat(ifc): preserve unsupported IFC geometry - #553
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 5 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 3449f30. Configure here.
| if (parentNodeId && nodes[parentNodeId]) { | ||
| ;(nodes[parentNodeId] as { children?: string[] }).children?.push(nodeId) | ||
| } | ||
| importedMeshCount++ |
There was a problem hiding this comment.
Stair flights duplicate stair geometry
Medium Severity
When converting IFCSTAIR elements, their child IFCSTAIRFLIGHT express IDs are not registered as processed. This causes the fallback mesh pass to create duplicate imported-mesh nodes for stair flights, leading to double-rendered stair geometry.
Reviewed by Cursor Bugbot for commit 3449f30. Configure here.
| for (let i = 0; i + 2 < primitive.positions.length; i += 3) { | ||
| const point: [number, number] = [primitive.positions[i]!, primitive.positions[i + 2]!] | ||
| unique.set(`${point[0].toFixed(5)}:${point[1].toFixed(5)}`, point) | ||
| } |
There was a problem hiding this comment.
Space hull wrong plan axes
Medium Severity
When an IFCSPACE has no swept profile, meshFootprint builds the zone polygon from GetFlatMesh vertex positions[0] and positions[2]. With default swapYZ, that extraction maps the second plan axis from IFC world Z, while native walls and profile-based zones use scene X/Y from worldToScene. Room zones from the mesh hull can sit rotated or offset from walls.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 3449f30. Configure here.
| deletable: true, | ||
| presettable: false, | ||
| }, | ||
| geometry: buildImportedMeshGeometry, |
There was a problem hiding this comment.
Moving imported mesh double-transforms
Medium Severity
IFC import bakes level-local world coordinates into primitives while leaving position at [0,0,0], but the node definition marks imported-mesh as movable. ParametricNodeRenderer applies node.position on the outer group, so dragging an imported mesh shifts it twice relative to its baked vertices.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 3449f30. Configure here.
| const materialA = (a.wall.metadata as { material?: unknown } | undefined)?.material | ||
| const materialB = (b.wall.metadata as { material?: unknown } | undefined)?.material | ||
| if (typeof materialA !== 'string' || typeof materialB !== 'string') return true | ||
| return materialA === materialB |
There was a problem hiding this comment.
Missing material allows wall merge
Medium Severity
wallMaterialCompatible treats a missing metadata.material on either wall as compatible and allows merge. Collinear exterior and interior fragments can combine when only one side received an IFC material association, undoing the intent of the new material guard.
Reviewed by Cursor Bugbot for commit 3449f30. Configure here.
| upper.pop() | ||
| const hull = [...lower, ...upper] | ||
| return hull.length >= 3 ? hull : null | ||
| } |
There was a problem hiding this comment.
Space footprint uses convex hull
Medium Severity
When an IFCSPACE has no swept profile, meshFootprint builds a convex hull from mesh vertices and that polygon becomes the room ZoneNode. Concave or L-shaped spaces are inflated to their hull, so room zones and anything derived from the boundary can be wrong while the commit still counts the space as successfully imported.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 3449f30. Configure here.


Summary
imported-meshbuilt-in node with registry-driven 3D and floorplan geometryIfcDoor.OperationTypeand glazing fromPset_DoorCommon.GlazingAreaFractionArchitecture
@pascal-app/ifc-converterpackages/nodes/src/imported-meshVerification
npm run build --workspace=@pascal-app/corenpm run build --workspace=@pascal-app/ifc-converterbun test packages/core/srcbun test packages/nodes/src— 877 passed, 1 skippedbun test packages/ifc-converter/tests— 9 passed01-duplex.ifc— 245 nodes, including 100 exact-geometry fallbacksNote
Medium Risk
Large changes to IFC→scene-graph mapping and spatial math can shift imported model layout and wall/opening behavior; mitigated by new unit tests for cleanup and door semantics.
Overview
Adds a first-class
imported-meshscene node (indexed triangle primitives with IFC colors) and wires it through core schema, editor events, and a hidden@pascal-app/nodesdefinition so import-only geometry is selectable and renderable without palette clutter.The IFC converter stops dropping unsupported or failed-native elements: beams, furnishings, railings, and similar types—and walls/slabs/doors/windows that could not be parameterized—are emitted as
imported-meshviaGetFlatMesh, with axis handling that avoids doubleswapYZon mesh vertices.IfcSpacemaps tozone(room) nodes; doors pick families fromOperationTypeand glazing fromPset_DoorCommon.GlazingAreaFraction. Placement and stacking improve through inferred storeys for building-aggregated roofs, level heights from IFC elevations, level-local coordinates, stricter wall centerlines, and skipping roof/landing slabs and unhosted wall-hosted openings (skylights fall through to mesh). Post-import wall simplification is tightened so parallel offset walls and different materials are not merged.wasmPathis configurable for Node callers.Reviewed by Cursor Bugbot for commit 3449f30. Bugbot is set up for automated code reviews on this repo. Configure here.