feat(wall): add endHeightOffset for sloped top edge - #640
Conversation
Fixes a bug where negative offset values caused wall geometry to self-intersect and drop below the base. The value is now strictly clamped to 0 at the Zod schema, UI, and geometry generation layers.
# Conflicts: # packages/nodes/src/wall/panel.tsx
curved wall sloped geometry - **Geometry Generation**: - `applyWallEndHeightSlope`: Replaced naive X-axis interpolation with exact radial angle-based parameterization (`t`) when the wall footprint is curved. Implemented robust `getSignedAngleDiff` and angle-unwrapping based on expected linear distance to prevent severe Y-axis warping on the wall end caps when `Math.atan2` boundaries are crossed on steep semicircular curves. - `generateExtrudedWall`: Added `getWallArcData` injection, mapping the arc center into wall-local coordinate space, and passing `localArc` down into the height slope generator. - **Height Resolution Core**: - `resolveWallTop`: Added an optional `t?: number` (parametric position along the chord) to correctly account for the sloped top. It injects `endHeightOffset * t` directly into the final top boundary calculation. - `resolveWallEffectiveHeight`: Cascaded the optional `t` parameter from the caller down into `resolveWallTop` and adjusted elevation offsets. - **Spatial Grid Placement**: - `getWallHeight`: Now accepts an optional parametric position and passes it directly to `resolveWallTop`. - `canPlaceOnWall`: Computes the exact parametric `tCenter` for wall-hosted items based on the projection of the item's position onto the wall chord. This allows the placement bounding box constraints to accurately read the sloped height of the wall at the item's insertion point, fixing the bug where placement validators treated the entire wall as completely flat. - **UI and Constraints**: - `panel.tsx`: Refactored the `SliderControl` minimum constraint for the `endHeightOffset` input to explicitly prevent the wall top from dropping below a safe minimum height threshold (`0.01m`).
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 83d0854. Configure here.
| } | ||
| const wallHeight = wallNode.height ?? 2.5 | ||
| const minEndHeight = 0.01 | ||
| const endHeightOffset = Math.max(rawOffset, -(wallHeight - minEndHeight)) |
There was a problem hiding this comment.
Plane-bound slope clamp uses wrong height
Medium Severity
applyWallEndHeightSlope clamps negative endHeightOffset against wallNode.height ?? 2.5. Plane-bound walls have no stored height, so the clamp ignores the real extruded body height (topY / storey minus base). On taller storeys the UI can request a lower end than geometry applies; on shorter bodies a large negative offset can pull the end below the wall base.
Reviewed by Cursor Bugbot for commit 83d0854. Configure here.
| ): number { | ||
| const levelId = resolveNodeLevelId(wall, nodes) | ||
| const baseElevation = getWallBaseElevationForNodes(wall, nodes) | ||
| return resolveWallEffectiveHeight(wall, getWallPlaneTop(wall, levelId, nodes), baseElevation) |
There was a problem hiding this comment.
Openings ignore sloped wall top
Medium Severity
getWallEffectiveHeightForNodes still resolves a single flat height and never passes parametric t, so resolveWallOpeningCeiling caps doors and windows at the start-side top. With a negative endHeightOffset, openings near the end can be taller than the rendered wall there and cut through the sloped crest.
Reviewed by Cursor Bugbot for commit 83d0854. Configure here.


What does this PR do?
Adds an
endHeightOffsetproperty to theWallNodeschema to allow wall extremities to have different heights (e.g., for creating a knee wall following a single-pitch roof slope). This adds an "End height offset" slider to the wall properties panel and updates the geometry generation to apply the slope along the top edge of the wall.How to test
End height offsetslider.Screenshots / screen recording
Checklist
bun devbun checkto verify)mainbranchNote
Medium Risk
Changes wall height resolution, 3D mesh generation, and wall-item placement together; additive optional field but mismatches could affect doors/windows on sloped walls.
Overview
Walls can now have a sloped top edge via a new optional
endHeightOffsetonWallNode(extra height at theendpoint only;startunchanged).The wall properties panel adds an End height offset slider (bounded so the end cannot drop below a minimal top height).
resolveWallTop/resolveWallEffectiveHeighttake an optional parametrictalong the wall and addendHeightOffset * tto the resolved top.SpatialGridManageruses that local height when validating wall-mounted placement (canPlaceOnWallpassestfrom position along the wall). The viewer runsapplyWallEndHeightSlopeafter extrusion to lift top vertices from start→end, including curved walls (arc-basedtinstead of chord X).Reviewed by Cursor Bugbot for commit 83d0854. Bugbot is set up for automated code reviews on this repo. Configure here.