Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fb4ac2b
fix(capture): round armed FOV, add Alt slow modifier for the drone ca…
wass08 Sep 9, 2026
66ca853
fix(roof): keep the gable shell base on the wall top
wass08 Sep 9, 2026
bd7aa72
feat(editor): Cmd/Ctrl+S saves instead of opening the browser dialog
wass08 Sep 9, 2026
d9c709e
fix(tools): anchor composite presets at their footprint centre, lift …
wass08 Sep 9, 2026
c4a1535
fix(stair): follow the storey height from the elected base
wass08 Sep 9, 2026
9035df7
fix(item): drop un-hosted items to the floor, draw the placement box …
wass08 Sep 9, 2026
6cd7f33
fix(selection): keep member rotation when pressing R/T mid-drag
wass08 Sep 9, 2026
6aadbb3
chore(deps): three 0.186.0
wass08 Sep 9, 2026
85cdc90
test: pre-evaluate three in the bun test preload
wass08 Sep 9, 2026
61f2faf
fix(roof): lift the inner cutter and deck with the shell eave
wass08 Sep 9, 2026
9d79be1
fix(editor): fall back to the autosave flush when the host does not h…
wass08 Sep 9, 2026
1651ac0
fix(roof): floor every prism at 5 cm instead of lifting by the shell'…
wass08 Sep 9, 2026
f7f60e4
fix(stair): drop the duplicate geometry Rise control
wass08 Sep 9, 2026
91d01e7
test: import resolveSync explicitly in the three preload
wass08 Sep 9, 2026
9dfd816
test: skip the three preload where the cwd has no three dependency
wass08 Sep 9, 2026
c50f549
fix(editor): seed placed stairs from the elected base; keep the gestu…
wass08 Sep 9, 2026
5526120
fix(stair): cap the placed rise by the pointed support surface
wass08 Sep 9, 2026
71122f6
fix: scale the stair ghost to the placed rise; await renderer.dispose…
wass08 Sep 9, 2026
7aac601
fix(stair): read the placed rise from the preview scene
wass08 Sep 9, 2026
40eba21
fix(selection): re-fit alignment bounds from the start footprint afte…
wass08 Sep 9, 2026
4c7439f
fix(stair): switching to straight materializes a flight; level labels…
wass08 Sep 10, 2026
558882a
feat(roof): wall-footprint roofs follow their source walls' tops
wass08 Sep 10, 2026
55bf556
fix(stair): a flight height edit pins the parent stair to the new tot…
wass08 Sep 10, 2026
0af754d
fix(roof): follow wall tops below the storey plane
wass08 Sep 10, 2026
947c439
feat(roof): follow walls by intent, resolved from the footprint
wass08 Sep 10, 2026
f38c105
fix(roof): pick supporting walls by footprint overlap, not closed-roo…
wass08 Sep 10, 2026
fb945b1
fix(roof): parent room roofs to the storey above their walls; follow …
wass08 Sep 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/editor/bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
preload = ["../../scripts/bun-preload-three.ts"]

[test]
preload = ["../../scripts/bun-preload-three.ts"]
2 changes: 1 addition & 1 deletion apps/editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"react-dom": "^19.2.4",
"tailwind-merge": "^3.5.0",
"tailwindcss": "^4.2.1",
"three": "^0.185.0",
"three": "^0.186.0",
"zod": ">=4.5.4 <4.6"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion apps/ifc-converter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"react-dom": "^19.2.4",
"tailwind-merge": "^3.5.0",
"tailwindcss": "^4.2.1",
"three": "^0.185.0",
"three": "^0.186.0",
"web-ifc": "^0.0.77"
},
"devDependencies": {
Expand Down
20 changes: 10 additions & 10 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
preload = ["./scripts/bun-preload-three.ts"]

[test]
preload = ["./scripts/bun-preload-three.ts"]
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"@types/three": "0.184.1",
"next": "16.3.0",
"react-grab": "0.1.50",
"three": "0.185.1"
"three": "0.186.0"
},
"optionalDependencies": {
"@tailwindcss/oxide-darwin-arm64": "4.3.0",
Expand Down
4 changes: 4 additions & 0 deletions packages/capture-viewer/bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
preload = ["../../scripts/bun-preload-three.ts"]

[test]
preload = ["../../scripts/bun-preload-three.ts"]
4 changes: 2 additions & 2 deletions packages/capture-viewer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"@react-three/drei": "^10",
"@react-three/fiber": "^9",
"react": "^18 || ^19",
"three": "^0.185"
"three": "^0.186"
},
"devDependencies": {
"@pascal-app/capture-protocol": "^1.0.0-beta.4",
Expand All @@ -50,7 +50,7 @@
"@types/react": "^19.2.2",
"@types/three": "^0.184.0",
"react": "^19.2.4",
"three": "^0.185.0",
"three": "^0.186.0",
"typescript": "6.0.3"
},
"keywords": [
Expand Down
4 changes: 4 additions & 0 deletions packages/core/bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
preload = ["../../scripts/bun-preload-three.ts"]

[test]
preload = ["../../scripts/bun-preload-three.ts"]
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"@react-three/drei": "^10",
"@react-three/fiber": "^9",
"react": "^18 || ^19",
"three": "^0.185"
"three": "^0.186"
},
"dependencies": {
"@pascal-app/capture-protocol": "^1.0.0-beta.4",
Expand Down
13 changes: 13 additions & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,12 +395,25 @@ export {
isSplineFence,
sampleFenceSpline,
} from './systems/fence/fence-spline'
export { resolveRoofElevation, resolveRoofWallTopElevation } from './systems/roof/roof-elevation'
export { RoofElevationSystem } from './systems/roof/roof-elevation-system'
export {
fitRoofFootprint,
type RoofFootprintTarget,
resolveRoomRoofFootprint,
resolveRoomRoofFootprintOnLevel,
} from './systems/roof/roof-footprint'
export { resolveSlabPlacementElevation } from './systems/slab/slab-placement'
export {
clampSlabElevationForWalls,
getSlabElevationUpperBound,
type SlabElevationClamp,
} from './systems/slab/slab-support'
export {
createDefaultStairSegment,
createStairFlightFromStair,
type StairFlightOverrides,
} from './systems/stair/stair-flight'
export { type StairFootprintAABB, stairFootprintAABB } from './systems/stair/stair-footprint'
export { createSurfaceOpeningPreviewController } from './systems/stair/stair-opening-preview'
export { syncAutoStairOpenings } from './systems/stair/stair-opening-sync'
Expand Down
11 changes: 11 additions & 0 deletions packages/core/src/schema/nodes/roof-elevation.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { expect, test } from 'bun:test'
import { RoofNode } from './roof'

test('roofs default to custom level support', () => {
expect(RoofNode.parse({}).support).toEqual({ kind: 'level' })
})

test('wall-follow support survives JSON parsing without host references', () => {
const roof = RoofNode.parse({ support: { kind: 'walls' }, position: [2, -0.5, 1] })
expect(RoofNode.parse(JSON.parse(JSON.stringify(roof)))).toEqual(roof)
})
9 changes: 9 additions & 0 deletions packages/core/src/schema/nodes/roof-segment-walls.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ function segment(overrides: Partial<RoofSegmentNode> = {}): RoofSegmentNode {
}

describe('roof wall face frames', () => {
test('zero-height gable profiles keep their base at zero and raise the eave to five centimeters', () => {
const face = getRoofSegmentWallFace(segment({ wallHeight: 0 }), 'right')

expect(Math.min(...face.profile.map(([, v]) => v))).toBe(0)
expect(face.profile[2]?.[1]).toBe(0.05)
expect(face.profile[4]?.[1]).toBe(0.05)
expect(face.profile[3]?.[1]).toBeCloseTo(0.05 + 3.05 * Math.tan((40 * Math.PI) / 180))
})

test('frame z = 0 lands on the nominal footprint (wall mid-plane)', () => {
const seg = segment()
// front face, u at the face middle, v = 1, mid-plane.
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/schema/nodes/roof-segment-walls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import { getDutchRoofMetrics, getSegmentSlopeFrame } from './roof-segment'
* (`getVol(wallThickness / 2, 0, 0, …)`): the volume is the segment
* footprint extended outward by `wallThickness / 2`, which drops the eave
* line by `(wallThickness / 2) · tanθ` and raises the ridge by the same
* amount so the apex stays at `wallHeight + activeRh`.
* amount so the apex stays at `wallHeight + activeRh` unless the eave
* hits the CSG minimum. The base stays at 0; the eave is raised to at
* least 0.05 above it to avoid sinking the shell into the supporting wall.
*/

export type RoofWallFaceId = 'front' | 'back' | 'right' | 'left'
Expand Down Expand Up @@ -76,7 +78,7 @@ function getWallVolumeFrame(node: SegmentWallInputs): WallVolumeFrame {
const autoDrop = (wallThickness / 2) * tanTheta
const wV = Math.max(0.01, node.width + wallThickness)
const dV = Math.max(0.01, node.depth + wallThickness)
const eaveY = Math.max(0.01, node.wallHeight - autoDrop)
const eaveY = Math.max(0.05, node.wallHeight - autoDrop)
let rh = activeRh
if (activeRh > 0) {
rh = activeRh + autoDrop
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/schema/nodes/roof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type RoofSurfaceMaterialSpec = {
export const RoofSupport = z
.discriminatedUnion('kind', [
z.object({ kind: z.literal('level') }),
z.object({ kind: z.literal('walls') }),
z.object({
kind: z.literal('roof'),
roofSegmentId: RoofSegmentNode.shape.id,
Expand Down Expand Up @@ -49,7 +50,7 @@ export const RoofNode = BaseNode.extend({
When not being edited, segments are visually combined into a single solid.
- position: center position of the roof group
- rotation: rotation around Y axis
- support: level placement or an explicit roof-surface attachment
- support: custom level placement, spatial wall-top following, or a roof-surface attachment
- children: array of RoofSegmentNode IDs
`,
)
Expand Down
Loading
Loading