@pascal-app/viewer 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/capture/capture-runtime.js +1 -1
- package/dist/components/error-boundary.d.ts.map +1 -1
- package/dist/components/renderers/node-renderer.d.ts +1 -1
- package/dist/components/renderers/node-renderer.d.ts.map +1 -1
- package/dist/components/renderers/node-renderer.js +4 -1
- package/dist/components/renderers/parametric-node-renderer.d.ts.map +1 -1
- package/dist/components/viewer/bvh-ecctrl.d.ts.map +1 -1
- package/dist/components/viewer/frame-limiter.d.ts.map +1 -1
- package/dist/components/viewer/glb-interactive.js +1 -1
- package/dist/components/viewer/glb-reference-nodes.js +1 -1
- package/dist/components/viewer/glb-replace-instances.js +1 -1
- package/dist/components/viewer/glb-scene.d.ts.map +1 -1
- package/dist/components/viewer/glb-scene.js +2 -3
- package/dist/components/viewer/glb-walkthrough-controller.js +1 -1
- package/dist/components/viewer/index.d.ts +10 -1
- package/dist/components/viewer/index.d.ts.map +1 -1
- package/dist/components/viewer/index.js +28 -12
- package/dist/components/viewer/lights.d.ts.map +1 -1
- package/dist/components/viewer/lights.js +107 -21
- package/dist/components/viewer/perf-panel.d.ts.map +1 -1
- package/dist/components/viewer/perf-panel.js +1 -1
- package/dist/components/viewer/post-processing.d.ts.map +1 -1
- package/dist/components/viewer/post-processing.js +96 -33
- package/dist/components/viewer/registered-systems.js +1 -1
- package/dist/components/viewer/scene-bvh.d.ts.map +1 -1
- package/dist/components/viewer/scene-bvh.js +1 -1
- package/dist/components/viewer/scene-environment.d.ts.map +1 -1
- package/dist/components/viewer/scene-environment.js +31 -11
- package/dist/components/viewer/selection-manager.js +15 -7
- package/dist/components/viewer/underground-ambiance.d.ts +9 -0
- package/dist/components/viewer/underground-ambiance.d.ts.map +1 -0
- package/dist/components/viewer/underground-ambiance.js +105 -0
- package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
- package/dist/components/viewer/viewer-camera.js +1 -1
- package/dist/components/viewer/viewer-presentations.d.ts.map +1 -1
- package/dist/hooks/use-gltf-ktx2.d.ts.map +1 -1
- package/dist/hooks/use-gltf-ktx2.js +2 -0
- package/dist/hooks/use-node-events.d.ts.map +1 -1
- package/dist/index.d.ts +16 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -7
- package/dist/lib/backdrop.d.ts +17 -0
- package/dist/lib/backdrop.d.ts.map +1 -1
- package/dist/lib/backdrop.js +18 -1
- package/dist/lib/construction-dust.d.ts +57 -0
- package/dist/lib/construction-dust.d.ts.map +1 -0
- package/dist/lib/construction-dust.js +187 -0
- package/dist/lib/csg-utils.js +1 -1
- package/dist/lib/foundation-materials.d.ts +26 -0
- package/dist/lib/foundation-materials.d.ts.map +1 -0
- package/dist/lib/foundation-materials.js +65 -0
- package/dist/lib/gltf-unlit.d.ts +10 -0
- package/dist/lib/gltf-unlit.d.ts.map +1 -0
- package/dist/lib/gltf-unlit.js +23 -0
- package/dist/lib/ground-window.d.ts +33 -0
- package/dist/lib/ground-window.d.ts.map +1 -0
- package/dist/lib/ground-window.js +114 -0
- package/dist/lib/hero-pose.d.ts +1 -1
- package/dist/lib/hero-pose.d.ts.map +1 -1
- package/dist/lib/ink-edges.d.ts +2 -1
- package/dist/lib/ink-edges.d.ts.map +1 -1
- package/dist/lib/ktx2-loader.d.ts +7 -0
- package/dist/lib/ktx2-loader.d.ts.map +1 -1
- package/dist/lib/ktx2-loader.js +35 -0
- package/dist/lib/layer-pass.d.ts.map +1 -1
- package/dist/lib/layers.d.ts +11 -7
- package/dist/lib/layers.d.ts.map +1 -1
- package/dist/lib/layers.js +16 -6
- package/dist/lib/materials.d.ts +5 -0
- package/dist/lib/materials.d.ts.map +1 -1
- package/dist/lib/materials.js +34 -4
- package/dist/lib/merged-outline-node.d.ts +5 -0
- package/dist/lib/merged-outline-node.d.ts.map +1 -1
- package/dist/lib/merged-outline-node.js +80 -2
- package/dist/lib/pointer-events.d.ts +20 -4
- package/dist/lib/pointer-events.d.ts.map +1 -1
- package/dist/lib/pointer-events.js +78 -14
- package/dist/lib/post-processing-resources.d.ts.map +1 -1
- package/dist/lib/reveal-candidates.d.ts +80 -0
- package/dist/lib/reveal-candidates.d.ts.map +1 -0
- package/dist/lib/reveal-candidates.js +524 -0
- package/dist/lib/reveal-ghost.d.ts +9 -0
- package/dist/lib/reveal-ghost.d.ts.map +1 -0
- package/dist/lib/reveal-ghost.js +62 -0
- package/dist/lib/reveal-pending.d.ts +12 -0
- package/dist/lib/reveal-pending.d.ts.map +1 -0
- package/dist/lib/reveal-pending.js +12 -0
- package/dist/lib/reveal-pose.d.ts +70 -0
- package/dist/lib/reveal-pose.d.ts.map +1 -0
- package/dist/lib/reveal-pose.js +248 -0
- package/dist/lib/reveal-schedule.d.ts +208 -0
- package/dist/lib/reveal-schedule.d.ts.map +1 -0
- package/dist/lib/reveal-schedule.js +410 -0
- package/dist/lib/reveal-texture-scale.d.ts +5 -0
- package/dist/lib/reveal-texture-scale.d.ts.map +1 -0
- package/dist/lib/reveal-texture-scale.js +113 -0
- package/dist/lib/reveal-windows.d.ts +23 -0
- package/dist/lib/reveal-windows.d.ts.map +1 -0
- package/dist/lib/reveal-windows.js +31 -0
- package/dist/lib/reveal-wipe.d.ts +71 -0
- package/dist/lib/reveal-wipe.d.ts.map +1 -0
- package/dist/lib/reveal-wipe.js +105 -0
- package/dist/lib/scene-pass-mrt.d.ts +12 -0
- package/dist/lib/scene-pass-mrt.d.ts.map +1 -0
- package/dist/lib/scene-pass-mrt.js +23 -0
- package/dist/lib/scene-themes.d.ts +30 -8
- package/dist/lib/scene-themes.d.ts.map +1 -1
- package/dist/lib/scene-themes.js +36 -0
- package/dist/lib/scene-visibility.d.ts +11 -1
- package/dist/lib/scene-visibility.d.ts.map +1 -1
- package/dist/lib/scene-visibility.js +38 -0
- package/dist/lib/site-surfaces.d.ts +32 -0
- package/dist/lib/site-surfaces.d.ts.map +1 -0
- package/dist/lib/site-surfaces.js +70 -0
- package/dist/lib/snapshot-pipeline.d.ts +2 -1
- package/dist/lib/snapshot-pipeline.d.ts.map +1 -1
- package/dist/lib/snapshot-pipeline.js +35 -15
- package/dist/lib/tsl-compat.d.ts +2 -2
- package/dist/lib/tsl-compat.d.ts.map +1 -1
- package/dist/lib/underground-ambiance.d.ts +168 -0
- package/dist/lib/underground-ambiance.d.ts.map +1 -0
- package/dist/lib/underground-ambiance.js +334 -0
- package/dist/store/use-viewer.d.ts +184 -27
- package/dist/store/use-viewer.d.ts.map +1 -1
- package/dist/store/use-viewer.js +155 -19
- package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
- package/dist/systems/ceiling/ceiling-system.js +2 -0
- package/dist/systems/construction-reveal/construction-dust.d.ts +16 -0
- package/dist/systems/construction-reveal/construction-dust.d.ts.map +1 -0
- package/dist/systems/construction-reveal/construction-dust.js +92 -0
- package/dist/systems/construction-reveal/construction-reveal.d.ts +276 -0
- package/dist/systems/construction-reveal/construction-reveal.d.ts.map +1 -0
- package/dist/systems/construction-reveal/construction-reveal.js +2383 -0
- package/dist/systems/construction-reveal/dust-material.d.ts +10 -0
- package/dist/systems/construction-reveal/dust-material.d.ts.map +1 -0
- package/dist/systems/construction-reveal/dust-material.js +17 -0
- package/dist/systems/construction-reveal/ghost-dress.d.ts +10 -0
- package/dist/systems/construction-reveal/ghost-dress.d.ts.map +1 -0
- package/dist/systems/construction-reveal/ghost-dress.js +24 -0
- package/dist/systems/elevator/elevator-interaction-system.d.ts +7 -0
- package/dist/systems/elevator/elevator-interaction-system.d.ts.map +1 -1
- package/dist/systems/elevator/elevator-interaction-system.js +18 -1
- package/dist/systems/geometry/geometry-system.d.ts.map +1 -1
- package/dist/systems/interactive/control-widget.d.ts.map +1 -1
- package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
- package/dist/systems/interactive/interactive-system.js +16 -6
- package/dist/systems/interactive/scripted-clips.js +1 -1
- package/dist/systems/item-light/item-light-system.js +1 -1
- package/dist/systems/level/level-hold.d.ts +4 -0
- package/dist/systems/level/level-hold.d.ts.map +1 -0
- package/dist/systems/level/level-hold.js +14 -0
- package/dist/systems/level/level-system.d.ts.map +1 -1
- package/dist/systems/level/level-system.js +16 -1
- package/dist/systems/level/level-utils.d.ts +13 -3
- package/dist/systems/level/level-utils.d.ts.map +1 -1
- package/dist/systems/level/level-utils.js +56 -8
- package/dist/systems/roof/__fixtures__/roof-plane-cases.d.ts +103 -0
- package/dist/systems/roof/__fixtures__/roof-plane-cases.d.ts.map +1 -0
- package/dist/systems/roof/__fixtures__/roof-plane-cases.js +317 -0
- package/dist/systems/roof/roof-materials.d.ts +4 -2
- package/dist/systems/roof/roof-materials.d.ts.map +1 -1
- package/dist/systems/roof/roof-materials.js +18 -24
- package/dist/systems/roof/roof-system.d.ts +8 -1
- package/dist/systems/roof/roof-system.d.ts.map +1 -1
- package/dist/systems/roof/roof-system.js +195 -45
- package/dist/systems/wall/wall-cutout-cache.d.ts +32 -3
- package/dist/systems/wall/wall-cutout-cache.d.ts.map +1 -1
- package/dist/systems/wall/wall-cutout-cache.js +95 -2
- package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
- package/dist/systems/wall/wall-material-variant.d.ts.map +1 -1
- package/dist/systems/wall/wall-materials.d.ts.map +1 -1
- package/dist/systems/wall/wall-materials.js +39 -4
- package/dist/systems/wall/wall-placeholder-sweep.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.d.ts +5 -0
- package/dist/systems/wall/wall-system.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.js +42 -19
- package/dist/systems/window/corner-frame.d.ts +10 -0
- package/dist/systems/window/corner-frame.d.ts.map +1 -0
- package/dist/systems/window/corner-frame.js +17 -0
- package/dist/systems/window/window-system.d.ts +1 -1
- package/dist/systems/window/window-system.d.ts.map +1 -1
- package/dist/systems/window/window-system.js +31 -6
- package/package.json +8 -8
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every roof the hosted Architect plugin's `hip_roof_planes` and `gable_roof_planes` built, each
|
|
3
|
+
* beside the `roof_segment_add` call that covers it and the roof segment that call writes, so the
|
|
4
|
+
* two plane tools can retire into it (catalogue slice R). No stored thread called either tool, so
|
|
5
|
+
* the cases are what their contracts take (both ridge axes, a hip either way and square, the
|
|
6
|
+
* default, wide, flush and wider-than-the-eaves gable overhangs, a thickness, an eave on the plate,
|
|
7
|
+
* over it and on posts) and the plugin's own call (a hip at the walls' 2.6 m tops).
|
|
8
|
+
*
|
|
9
|
+
* The plane tools took the rectangle of the walls' outside faces, a rise per 12, the overhang past
|
|
10
|
+
* those faces in metres (a gable's ends their own), a thickness square to the slope (0.29 m by
|
|
11
|
+
* default) and an eave height that was the roof's SURFACE at the outside wall face. The segment
|
|
12
|
+
* takes the same rectangle (`rectAt: 'outside'`), the pitch, the overhangs and the thickness in
|
|
13
|
+
* any unit, and an eave that is the plate it bears on, its default the walls' tops; the walls'
|
|
14
|
+
* thickness, which it reads from the walls along those faces (6.5 in where none stand, a porch on
|
|
15
|
+
* posts), puts their centre lines inside the faces.
|
|
16
|
+
*
|
|
17
|
+
* A plane call whose roof stood on its walls, or over them, is the same roof as a segment: same
|
|
18
|
+
* outline, surface, ridge and thickness (`lift` 0).
|
|
19
|
+
*
|
|
20
|
+
* Not reproduced, on purpose (no stored call made either, so each is a call a model could make):
|
|
21
|
+
* - A plane call with its eave at the walls' tops, the plugin's own and the likeliest, sank its roof
|
|
22
|
+
* into them: its slab's underside stood `thickness / cos(pitch)` under the plate at the wall face.
|
|
23
|
+
* A segment is never sunk under the walls it sits on (`eave_under_walls`); the replacement leaves
|
|
24
|
+
* the eave out and the roof sits on them, the same outline, pitch and thickness, its surface
|
|
25
|
+
* `lift` higher. Those rows say so.
|
|
26
|
+
* - Planes over a storey with another over it stood inside that storey; a segment refuses that
|
|
27
|
+
* (`into_storey_above`). The hosted table checks the refusal.
|
|
28
|
+
* - The plane tools answered each plane's id, so one slope could be edited or painted on its own
|
|
29
|
+
* (`update_roof_plane`). A segment is one mass whose slopes change together; one slope on its own
|
|
30
|
+
* is `create_roof_plane`'s, which stays, and the retired tools' answer says so.
|
|
31
|
+
*
|
|
32
|
+
* The viewer runs the segments through the roof geometry against the planes' own geometry
|
|
33
|
+
* (`roof-plane-cases.test.ts`); the hosted plugin runs each replacement call through
|
|
34
|
+
* `roof_segment_add` and reads back the segment it wrote.
|
|
35
|
+
*/
|
|
36
|
+
const IN = 0.0254;
|
|
37
|
+
/** The walls' thickness, a 2x6 wall finished: what `roof_segment_add` reads from them. */
|
|
38
|
+
export const ROOF_PLANE_WALL_THICKNESS = 6.5 * IN;
|
|
39
|
+
/** The covering a segment lays over its deck, in the thickness the plane tools took whole. */
|
|
40
|
+
export const ROOF_PLANE_COVERING = 0.02;
|
|
41
|
+
/** The plane tools' defaults. */
|
|
42
|
+
const PLANE_OVERHANG = 0.457;
|
|
43
|
+
const PLANE_GABLE_OVERHANG = 0.305;
|
|
44
|
+
const PLANE_THICKNESS = 0.29;
|
|
45
|
+
const slopeOf = (pitch) => Math.atan(pitch / 12);
|
|
46
|
+
/** Where a plane call put the roof's surface at the wall face for a roof bearing on `plate`. */
|
|
47
|
+
function surfaceOnPlate(plate, pitch, thickness = PLANE_THICKNESS) {
|
|
48
|
+
const slope = slopeOf(pitch);
|
|
49
|
+
return plate - (ROOF_PLANE_WALL_THICKNESS / 2) * Math.tan(slope) + thickness / Math.cos(slope);
|
|
50
|
+
}
|
|
51
|
+
/** The plate under a plane call's surface: what `eaveHeight` is to a segment. */
|
|
52
|
+
function plateUnder(call) {
|
|
53
|
+
const slope = slopeOf(call.pitch);
|
|
54
|
+
return (call.eaveHeight +
|
|
55
|
+
(ROOF_PLANE_WALL_THICKNESS / 2) * Math.tan(slope) -
|
|
56
|
+
(call.thickness ?? PLANE_THICKNESS) / Math.cos(slope));
|
|
57
|
+
}
|
|
58
|
+
function roofPlaneCase(name, walls, call, replacement) {
|
|
59
|
+
const [ax, az, bx, bz] = call.rect;
|
|
60
|
+
const t = ROOF_PLANE_WALL_THICKNESS;
|
|
61
|
+
const w = Math.abs(bx - ax) - t;
|
|
62
|
+
const d = Math.abs(bz - az) - t;
|
|
63
|
+
const axis = replacement.ridgeAxis;
|
|
64
|
+
const slope = slopeOf(call.pitch);
|
|
65
|
+
const thickness = call.thickness ?? PLANE_THICKNESS;
|
|
66
|
+
const under = plateUnder(call);
|
|
67
|
+
// a segment bears on its walls' tops at the lowest; over them, where the planes put it
|
|
68
|
+
const eave = walls ? Math.max(under, walls.height) : under;
|
|
69
|
+
return {
|
|
70
|
+
name,
|
|
71
|
+
walls,
|
|
72
|
+
call,
|
|
73
|
+
replacement,
|
|
74
|
+
segment: {
|
|
75
|
+
roofType: replacement.roofType,
|
|
76
|
+
name: replacement.name,
|
|
77
|
+
centre: [(ax + bx) / 2, (az + bz) / 2],
|
|
78
|
+
width: axis === 'x' ? w : d,
|
|
79
|
+
depth: axis === 'x' ? d : w,
|
|
80
|
+
rotation: axis === 'x' ? 0 : -Math.PI / 2,
|
|
81
|
+
pitch: (slope * 180) / Math.PI,
|
|
82
|
+
overhang: (call.overhang ?? PLANE_OVERHANG) / Math.cos(slope),
|
|
83
|
+
...(call.tool === 'gable_roof_planes'
|
|
84
|
+
? { gableOverhang: call.gableOverhang ?? PLANE_GABLE_OVERHANG }
|
|
85
|
+
: {}),
|
|
86
|
+
wallThickness: t,
|
|
87
|
+
deckThickness: thickness - ROOF_PLANE_COVERING,
|
|
88
|
+
shingleThickness: ROOF_PLANE_COVERING,
|
|
89
|
+
eave,
|
|
90
|
+
},
|
|
91
|
+
lift: eave - under,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** The 12 × 8 m house, walls 2.6 m tall: its outside faces. */
|
|
95
|
+
const WIDE = [-0.08255, -0.08255, 12.08255, 8.08255];
|
|
96
|
+
/** The same house turned: 8 m wide, 12 m deep. */
|
|
97
|
+
const DEEP = [-0.08255, -0.08255, 8.08255, 12.08255];
|
|
98
|
+
/** A 10 m square house. */
|
|
99
|
+
const SQUARE = [-0.08255, -0.08255, 10.08255, 10.08255];
|
|
100
|
+
/** A porch roof on posts, clear of the house, their outside faces. */
|
|
101
|
+
const PORCH = [14, 2, 18, 6];
|
|
102
|
+
const PLATE = 2.6;
|
|
103
|
+
const house = (rect) => ({ rect, height: PLATE });
|
|
104
|
+
export const ROOF_PLANE_CASES = [
|
|
105
|
+
roofPlaneCase('hip_roof_planes defaults, its surface where a roof on the 2.6 m plate has it', house(WIDE), {
|
|
106
|
+
tool: 'hip_roof_planes',
|
|
107
|
+
rect: WIDE,
|
|
108
|
+
pitch: 6,
|
|
109
|
+
eaveHeight: surfaceOnPlate(PLATE, 6),
|
|
110
|
+
name: 'Hip',
|
|
111
|
+
}, {
|
|
112
|
+
roofType: 'hip',
|
|
113
|
+
name: 'Hip',
|
|
114
|
+
rect: WIDE,
|
|
115
|
+
rectAt: 'outside',
|
|
116
|
+
ridgeAxis: 'x',
|
|
117
|
+
pitchTwelfths: 6,
|
|
118
|
+
overhangIn: '0.457 m',
|
|
119
|
+
thicknessIn: '0.29 m',
|
|
120
|
+
}),
|
|
121
|
+
roofPlaneCase("hip_roof_planes at the walls' tops (the plugin's own call): the planes sank into the walls", house(WIDE), { tool: 'hip_roof_planes', rect: WIDE, pitch: 6, eaveHeight: PLATE }, {
|
|
122
|
+
roofType: 'hip',
|
|
123
|
+
name: 'Hip',
|
|
124
|
+
rect: WIDE,
|
|
125
|
+
rectAt: 'outside',
|
|
126
|
+
ridgeAxis: 'x',
|
|
127
|
+
pitchTwelfths: 6,
|
|
128
|
+
overhangIn: '0.457 m',
|
|
129
|
+
thicknessIn: '0.29 m',
|
|
130
|
+
}),
|
|
131
|
+
roofPlaneCase('hip_roof_planes deeper than wide (its ridge north-south), 5:12, 0.6 m eaves, 0.2 m thick', house(DEEP), {
|
|
132
|
+
tool: 'hip_roof_planes',
|
|
133
|
+
rect: DEEP,
|
|
134
|
+
pitch: 5,
|
|
135
|
+
eaveHeight: surfaceOnPlate(PLATE, 5, 0.2),
|
|
136
|
+
overhang: 0.6,
|
|
137
|
+
thickness: 0.2,
|
|
138
|
+
name: 'Main',
|
|
139
|
+
}, {
|
|
140
|
+
roofType: 'hip',
|
|
141
|
+
name: 'Main',
|
|
142
|
+
rect: DEEP,
|
|
143
|
+
rectAt: 'outside',
|
|
144
|
+
ridgeAxis: 'z',
|
|
145
|
+
pitchTwelfths: 5,
|
|
146
|
+
overhangIn: '0.6 m',
|
|
147
|
+
thicknessIn: '0.2 m',
|
|
148
|
+
}),
|
|
149
|
+
roofPlaneCase('hip_roof_planes over a square: a pyramid, 8:12, 0.3 m eaves', house(SQUARE), {
|
|
150
|
+
tool: 'hip_roof_planes',
|
|
151
|
+
rect: SQUARE,
|
|
152
|
+
pitch: 8,
|
|
153
|
+
eaveHeight: surfaceOnPlate(PLATE, 8),
|
|
154
|
+
overhang: 0.3,
|
|
155
|
+
}, {
|
|
156
|
+
roofType: 'hip',
|
|
157
|
+
name: 'Hip',
|
|
158
|
+
rect: SQUARE,
|
|
159
|
+
rectAt: 'outside',
|
|
160
|
+
ridgeAxis: 'x',
|
|
161
|
+
pitchTwelfths: 8,
|
|
162
|
+
overhangIn: '0.3 m',
|
|
163
|
+
thicknessIn: '0.29 m',
|
|
164
|
+
}),
|
|
165
|
+
roofPlaneCase('hip_roof_planes flush with the walls (no eaves), 4:12', house(WIDE), {
|
|
166
|
+
tool: 'hip_roof_planes',
|
|
167
|
+
rect: WIDE,
|
|
168
|
+
pitch: 4,
|
|
169
|
+
eaveHeight: surfaceOnPlate(PLATE, 4),
|
|
170
|
+
overhang: 0,
|
|
171
|
+
}, {
|
|
172
|
+
roofType: 'hip',
|
|
173
|
+
name: 'Hip',
|
|
174
|
+
rect: WIDE,
|
|
175
|
+
rectAt: 'outside',
|
|
176
|
+
ridgeAxis: 'x',
|
|
177
|
+
pitchTwelfths: 4,
|
|
178
|
+
overhangIn: '0 m',
|
|
179
|
+
thicknessIn: '0.29 m',
|
|
180
|
+
}),
|
|
181
|
+
roofPlaneCase('hip_roof_planes on a plate 0.3 m over the walls: the eave given (floating over them, it stays on their storey)', house(WIDE), {
|
|
182
|
+
tool: 'hip_roof_planes',
|
|
183
|
+
rect: WIDE,
|
|
184
|
+
pitch: 6,
|
|
185
|
+
eaveHeight: surfaceOnPlate(PLATE + 0.3, 6),
|
|
186
|
+
}, {
|
|
187
|
+
roofType: 'hip',
|
|
188
|
+
name: 'Hip',
|
|
189
|
+
rect: WIDE,
|
|
190
|
+
rectAt: 'outside',
|
|
191
|
+
ridgeAxis: 'x',
|
|
192
|
+
pitchTwelfths: 6,
|
|
193
|
+
overhangIn: '0.457 m',
|
|
194
|
+
thicknessIn: '0.29 m',
|
|
195
|
+
eaveHeight: PLATE + 0.3,
|
|
196
|
+
}),
|
|
197
|
+
roofPlaneCase('gable_roof_planes defaults, the ridge east-west: 18 in eaves, 12 in at the gable ends', house(WIDE), {
|
|
198
|
+
tool: 'gable_roof_planes',
|
|
199
|
+
rect: WIDE,
|
|
200
|
+
ridgeAxis: 'x',
|
|
201
|
+
pitch: 6,
|
|
202
|
+
eaveHeight: surfaceOnPlate(PLATE, 6),
|
|
203
|
+
name: 'Gable',
|
|
204
|
+
}, {
|
|
205
|
+
roofType: 'gable',
|
|
206
|
+
name: 'Gable',
|
|
207
|
+
rect: WIDE,
|
|
208
|
+
rectAt: 'outside',
|
|
209
|
+
ridgeAxis: 'x',
|
|
210
|
+
pitchTwelfths: 6,
|
|
211
|
+
overhangIn: '0.457 m',
|
|
212
|
+
gableOverhangIn: '0.305 m',
|
|
213
|
+
thicknessIn: '0.29 m',
|
|
214
|
+
}),
|
|
215
|
+
roofPlaneCase("gable_roof_planes at the walls' tops: the planes sank into the walls", house(WIDE), { tool: 'gable_roof_planes', rect: WIDE, ridgeAxis: 'x', pitch: 6, eaveHeight: PLATE }, {
|
|
216
|
+
roofType: 'gable',
|
|
217
|
+
name: 'Gable',
|
|
218
|
+
rect: WIDE,
|
|
219
|
+
rectAt: 'outside',
|
|
220
|
+
ridgeAxis: 'x',
|
|
221
|
+
pitchTwelfths: 6,
|
|
222
|
+
overhangIn: '0.457 m',
|
|
223
|
+
gableOverhangIn: '0.305 m',
|
|
224
|
+
thicknessIn: '0.29 m',
|
|
225
|
+
}),
|
|
226
|
+
roofPlaneCase('gable_roof_planes, the ridge north-south over the deep house, 8:12', house(DEEP), {
|
|
227
|
+
tool: 'gable_roof_planes',
|
|
228
|
+
rect: DEEP,
|
|
229
|
+
ridgeAxis: 'z',
|
|
230
|
+
pitch: 8,
|
|
231
|
+
eaveHeight: surfaceOnPlate(PLATE, 8),
|
|
232
|
+
}, {
|
|
233
|
+
roofType: 'gable',
|
|
234
|
+
name: 'Gable',
|
|
235
|
+
rect: DEEP,
|
|
236
|
+
rectAt: 'outside',
|
|
237
|
+
ridgeAxis: 'z',
|
|
238
|
+
pitchTwelfths: 8,
|
|
239
|
+
overhangIn: '0.457 m',
|
|
240
|
+
gableOverhangIn: '0.305 m',
|
|
241
|
+
thicknessIn: '0.29 m',
|
|
242
|
+
}),
|
|
243
|
+
roofPlaneCase('gable_roof_planes, the ridge north-south across the wide house, 4:12', house(WIDE), {
|
|
244
|
+
tool: 'gable_roof_planes',
|
|
245
|
+
rect: WIDE,
|
|
246
|
+
ridgeAxis: 'z',
|
|
247
|
+
pitch: 4,
|
|
248
|
+
eaveHeight: surfaceOnPlate(PLATE, 4),
|
|
249
|
+
}, {
|
|
250
|
+
roofType: 'gable',
|
|
251
|
+
name: 'Gable',
|
|
252
|
+
rect: WIDE,
|
|
253
|
+
rectAt: 'outside',
|
|
254
|
+
ridgeAxis: 'z',
|
|
255
|
+
pitchTwelfths: 4,
|
|
256
|
+
overhangIn: '0.457 m',
|
|
257
|
+
gableOverhangIn: '0.305 m',
|
|
258
|
+
thicknessIn: '0.29 m',
|
|
259
|
+
}),
|
|
260
|
+
roofPlaneCase('gable_roof_planes with gable ends reaching past the eaves: 0.9 m rakes, 0.3 m eaves, 3:12', house(WIDE), {
|
|
261
|
+
tool: 'gable_roof_planes',
|
|
262
|
+
rect: WIDE,
|
|
263
|
+
ridgeAxis: 'x',
|
|
264
|
+
pitch: 3,
|
|
265
|
+
eaveHeight: surfaceOnPlate(PLATE, 3, 0.25),
|
|
266
|
+
overhang: 0.3,
|
|
267
|
+
gableOverhang: 0.9,
|
|
268
|
+
thickness: 0.25,
|
|
269
|
+
}, {
|
|
270
|
+
roofType: 'gable',
|
|
271
|
+
name: 'Gable',
|
|
272
|
+
rect: WIDE,
|
|
273
|
+
rectAt: 'outside',
|
|
274
|
+
ridgeAxis: 'x',
|
|
275
|
+
pitchTwelfths: 3,
|
|
276
|
+
overhangIn: '0.3 m',
|
|
277
|
+
gableOverhangIn: '0.9 m',
|
|
278
|
+
thicknessIn: '0.25 m',
|
|
279
|
+
}),
|
|
280
|
+
roofPlaneCase('gable_roof_planes with flush gable ends', house(WIDE), {
|
|
281
|
+
tool: 'gable_roof_planes',
|
|
282
|
+
rect: WIDE,
|
|
283
|
+
ridgeAxis: 'x',
|
|
284
|
+
pitch: 6,
|
|
285
|
+
eaveHeight: surfaceOnPlate(PLATE, 6),
|
|
286
|
+
gableOverhang: 0,
|
|
287
|
+
}, {
|
|
288
|
+
roofType: 'gable',
|
|
289
|
+
name: 'Gable',
|
|
290
|
+
rect: WIDE,
|
|
291
|
+
rectAt: 'outside',
|
|
292
|
+
ridgeAxis: 'x',
|
|
293
|
+
pitchTwelfths: 6,
|
|
294
|
+
overhangIn: '0.457 m',
|
|
295
|
+
gableOverhangIn: '0 m',
|
|
296
|
+
thicknessIn: '0.29 m',
|
|
297
|
+
}),
|
|
298
|
+
roofPlaneCase('gable_roof_planes over a porch on posts: its eave on the beam, given', null, {
|
|
299
|
+
tool: 'gable_roof_planes',
|
|
300
|
+
rect: PORCH,
|
|
301
|
+
ridgeAxis: 'z',
|
|
302
|
+
pitch: 6,
|
|
303
|
+
eaveHeight: surfaceOnPlate(2.4, 6),
|
|
304
|
+
name: 'Porch',
|
|
305
|
+
}, {
|
|
306
|
+
roofType: 'gable',
|
|
307
|
+
name: 'Porch',
|
|
308
|
+
rect: PORCH,
|
|
309
|
+
rectAt: 'outside',
|
|
310
|
+
ridgeAxis: 'z',
|
|
311
|
+
pitchTwelfths: 6,
|
|
312
|
+
overhangIn: '0.457 m',
|
|
313
|
+
gableOverhangIn: '0.305 m',
|
|
314
|
+
thicknessIn: '0.29 m',
|
|
315
|
+
eaveHeight: 2.4,
|
|
316
|
+
}),
|
|
317
|
+
];
|
|
@@ -7,8 +7,10 @@ export type RoofMaterialArray = [THREE.Material, THREE.Material, THREE.Material,
|
|
|
7
7
|
* The cladding the walls under a roof declare through their ASSEMBLIES
|
|
8
8
|
* (`wall.assembly.exterior.finish` → catalog ref), so the roof's gable band —
|
|
9
9
|
* the triangle of wall above the plate that the roof kind builds — is skinned
|
|
10
|
-
* like the walls it sits on instead of the bare drywall default. The
|
|
11
|
-
*
|
|
10
|
+
* like the walls it sits on instead of the bare drywall default. The walls are
|
|
11
|
+
* the roof's level's, or for a roof on a level of its own (a building's roof
|
|
12
|
+
* level), the storey's directly below. The most common ref among them wins;
|
|
13
|
+
* null when none declares one.
|
|
12
14
|
*/
|
|
13
15
|
export declare function levelWallCladdingRef(nodes: Readonly<Record<string, AnyNode | undefined>>, roof: Pick<RoofNode, 'parentId'>): string | null;
|
|
14
16
|
export declare function getRoofMaterialArray(node: RoofNode, shading?: RenderShading, textures?: boolean, colorPreset?: ColorPreset, sceneTheme?: string,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roof-materials.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-materials.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"roof-materials.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-materials.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAMZ,KAAK,QAAQ,EAEb,KAAK,aAAa,EAClB,KAAK,eAAe,EAGrB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAA;AACnC,OAAO,EACL,KAAK,WAAW,EAGhB,KAAK,aAAa,EAGnB,MAAM,qBAAqB,CAAA;AAE5B,KAAK,cAAc,GAAG,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC,GAAG,SAAS,CAAA;AAaxE,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;AAqChG;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC,EACpD,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,GAC/B,MAAM,GAAG,IAAI,CAyBf;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,EACd,OAAO,GAAE,aAA0B,EACnC,QAAQ,UAAO,EACf,WAAW,GAAE,WAAoB,EACjC,UAAU,CAAC,EAAE,MAAM;AACnB,uFAAuF;AACvF,eAAe,GAAE,MAAM,GAAG,IAAW,EACrC,cAAc,CAAC,EAAE,cAAc,GAC9B,iBAAiB,GAAG,IAAI,CA4D1B"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getEffectiveRoofSurfaceMaterial, parseMaterialRef, wallAssemblyFinishRef, } from '@pascal-app/core';
|
|
1
|
+
import { findLevelBelowId, getEffectiveRoofSurfaceMaterial, getLevelElevations, parseMaterialRef, wallAssemblyFinishRef, } from '@pascal-app/core';
|
|
2
2
|
import { createMaterial, createSurfaceRoleMaterial, resolveMaterialRef, resolveSlotDefaultMaterial, } from '../../lib/materials';
|
|
3
3
|
// Declared catalog defaults for an unpainted roof, per the 4-slot layout
|
|
4
4
|
// (0 wall/trim · 1 deck · 2 interior soffit · 3 shingle top). The wall/trim
|
|
@@ -36,18 +36,23 @@ function createResolvedMaterial(material, materialPreset, sceneMaterials, shadin
|
|
|
36
36
|
* The cladding the walls under a roof declare through their ASSEMBLIES
|
|
37
37
|
* (`wall.assembly.exterior.finish` → catalog ref), so the roof's gable band —
|
|
38
38
|
* the triangle of wall above the plate that the roof kind builds — is skinned
|
|
39
|
-
* like the walls it sits on instead of the bare drywall default. The
|
|
40
|
-
*
|
|
39
|
+
* like the walls it sits on instead of the bare drywall default. The walls are
|
|
40
|
+
* the roof's level's, or for a roof on a level of its own (a building's roof
|
|
41
|
+
* level), the storey's directly below. The most common ref among them wins;
|
|
42
|
+
* null when none declares one.
|
|
41
43
|
*/
|
|
42
44
|
export function levelWallCladdingRef(nodes, roof) {
|
|
43
45
|
const levelId = roof.parentId;
|
|
44
46
|
if (!levelId)
|
|
45
47
|
return null;
|
|
48
|
+
const wallsOn = (id) => Object.values(nodes).filter((node) => node?.type === 'wall' && node.parentId === id);
|
|
49
|
+
const own = wallsOn(levelId);
|
|
50
|
+
const walls = own.length
|
|
51
|
+
? own
|
|
52
|
+
: wallsOn(findLevelBelowId(levelId, getLevelElevations(nodes)));
|
|
46
53
|
const counts = new Map();
|
|
47
|
-
for (const
|
|
48
|
-
|
|
49
|
-
continue;
|
|
50
|
-
const ref = wallAssemblyFinishRef(node);
|
|
54
|
+
for (const wall of walls) {
|
|
55
|
+
const ref = wallAssemblyFinishRef(wall);
|
|
51
56
|
if (ref)
|
|
52
57
|
counts.set(ref, (counts.get(ref) ?? 0) + 1);
|
|
53
58
|
}
|
|
@@ -97,33 +102,22 @@ wallCladdingRef = null, sceneMaterials) {
|
|
|
97
102
|
roofMaterialArrayCache.set(cacheKey, roleArray);
|
|
98
103
|
return roleArray;
|
|
99
104
|
}
|
|
100
|
-
// Textures-on default appearance: catalog finishes per slot (terracotta
|
|
101
|
-
// shingle, soft-white deck/soffit, wall-coloured trim). Used both when the
|
|
102
|
-
// roof is unpainted and to fill any individual unpainted slot below.
|
|
103
|
-
const defaultArray = [
|
|
104
|
-
resolveSlotDefaultMaterial(wallCladdingRef ?? ROOF_DEFAULT_REFS[0], shading),
|
|
105
|
-
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[1], shading),
|
|
106
|
-
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[2], shading),
|
|
107
|
-
resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[3], shading),
|
|
108
|
-
];
|
|
109
105
|
const resolve = (spec) => createResolvedMaterial(spec.material, spec.materialPreset, sceneMaterials, shading);
|
|
110
106
|
const topMaterial = resolve(top);
|
|
111
107
|
const edgeMaterial = resolve(edge);
|
|
112
108
|
const wallMaterial = resolve(wall);
|
|
113
|
-
if (!(topMaterial || edgeMaterial || wallMaterial)) {
|
|
114
|
-
roofMaterialArrayCache.set(cacheKey, defaultArray);
|
|
115
|
-
return defaultArray;
|
|
116
|
-
}
|
|
117
109
|
// Each slot resolves to its own role only, then the declared default — never
|
|
118
110
|
// another role. Cross-role fallback here used to splatter a single painted
|
|
119
111
|
// surface (e.g. the edge) across the shingle and soffit slots. The legacy
|
|
120
112
|
// catch-all still fills every role because `getEffectiveRoofSurfaceMaterial`
|
|
121
113
|
// returns it for top/edge/wall alike.
|
|
114
|
+
// Resolve an unpainted slot's catalog default lazily: painted roofs must
|
|
115
|
+
// not load unused finish assets (or make capture readiness depend on them).
|
|
122
116
|
const materialArray = [
|
|
123
|
-
edgeMaterial ??
|
|
124
|
-
wallMaterial ??
|
|
125
|
-
wallMaterial ??
|
|
126
|
-
topMaterial ??
|
|
117
|
+
edgeMaterial ?? resolveSlotDefaultMaterial(wallCladdingRef ?? ROOF_DEFAULT_REFS[0], shading),
|
|
118
|
+
wallMaterial ?? resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[1], shading),
|
|
119
|
+
wallMaterial ?? resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[2], shading),
|
|
120
|
+
topMaterial ?? resolveSlotDefaultMaterial(ROOF_DEFAULT_REFS[3], shading),
|
|
127
121
|
];
|
|
128
122
|
roofMaterialArrayCache.set(cacheKey, materialArray);
|
|
129
123
|
return materialArray;
|
|
@@ -9,7 +9,13 @@ import { Brush } from 'three-bvh-csg';
|
|
|
9
9
|
*/
|
|
10
10
|
export declare function getPendingRoofMergeCount(): number;
|
|
11
11
|
export declare function countPendingRoofShells(pending: Iterable<string>, mounted: (id: string) => THREE.Object3D | undefined): number;
|
|
12
|
-
|
|
12
|
+
/** What a plugin adds to a segment mesh after its geometry is rebuilt. */
|
|
13
|
+
export type RoofGeometryAdapter = {
|
|
14
|
+
syncGeometry: (node: RoofSegmentNode, mesh: THREE.Mesh) => void;
|
|
15
|
+
};
|
|
16
|
+
export declare const RoofSystem: ({ geometryAdapter }?: {
|
|
17
|
+
geometryAdapter?: RoofGeometryAdapter;
|
|
18
|
+
}) => null;
|
|
13
19
|
/**
|
|
14
20
|
* Four dummy materials used as identity placeholders during CSG. Shared
|
|
15
21
|
* across every input brush so three-bvh-csg can preserve reference
|
|
@@ -51,6 +57,7 @@ export declare function getRoofSegmentBrushes(node: RoofSegmentNode, options?: {
|
|
|
51
57
|
fascia?: boolean;
|
|
52
58
|
}): RoofSegmentBrushSet | null;
|
|
53
59
|
export declare function generateRoofSegmentGeometry(node: RoofSegmentNode, nodes?: Record<string, AnyNode>): THREE.BufferGeometry;
|
|
60
|
+
export declare function clipDirectRoofGeometryAgainstSiblings(geometry: THREE.BufferGeometry, node: RoofSegmentNode, nodes: Record<string, AnyNode>, space: 'roof' | 'segment'): THREE.BufferGeometry;
|
|
54
61
|
export declare function remapRoofShellFaces(geometry: THREE.BufferGeometry, node: RoofSegmentNode): void;
|
|
55
62
|
export type SurfaceFrame = {
|
|
56
63
|
point: THREE.Vector3;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roof-system.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-system.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"roof-system.d.ts","sourceRoot":"","sources":["../../../src/systems/roof/roof-system.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EA6BZ,KAAK,eAAe,EAQrB,MAAM,kBAAkB,CAAA;AAEzB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAY,KAAK,EAA0B,MAAM,eAAe,CAAA;AA4JvE;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAIjD;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,EACzB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,KAAK,CAAC,QAAQ,GAAG,SAAS,GAClD,MAAM,CAIR;AAiFD,0EAA0E;AAC1E,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,IAAI,CAAA;CAChE,CAAA;AAED,eAAO,MAAM,UAAU,yBAAyB;IAAE,eAAe,CAAC,EAAE,mBAAmB,CAAA;CAAE,SA0JxF,CAAA;AAqbD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE;IAC7B,KAAK,CAAC,iBAAiB;IACvB,KAAK,CAAC,iBAAiB;IACvB,KAAK,CAAC,iBAAiB;IACvB,KAAK,CAAC,iBAAiB;CAMxB,CAAA;AAID,eAAO,MAAM,wBAAwB,IAAI,CAAA;AAEzC,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,KAAK,CAAA;IACf,QAAQ,EAAE,KAAK,CAAA;IACf,SAAS,EAAE,KAAK,CAAA;IAChB,UAAU,EAAE,KAAK,CAAA;IACjB,UAAU,EAAE,KAAK,CAAC,cAAc,GAAG,IAAI,CAAA;CACxC,CAAA;AA4FD,wBAAgB,yBAAyB,CACvC,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,YAAY,EAAE,KAAK,CAAC,QAAQ,EAAE,EAC9B,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,GACtC,MAAM,CAuBR;AA4XD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,KAAK,CAAC,cAAc,GAAG,IAAI,EACrC,OAAO,EAAE,eAAe,GACvB,KAAK,CAAC,cAAc,GAAG,IAAI,CAgC7B;AAuHD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,eAAe,EACrB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,mBAAmB,GAAG,IAAI,CA4V5B;AAkFD,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,eAAe,EACrB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,KAAK,CAAC,cAAc,CA8GtB;AAED,wBAAgB,qCAAqC,CACnD,QAAQ,EAAE,KAAK,CAAC,cAAc,EAC9B,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,KAAK,CAAC,cAAc,CAiCtB;AA+vCD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,eAAe,QA0ExF;AAirBD,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAA;IACpB,MAAM,EAAE,KAAK,CAAC,OAAO,CAAA;CACtB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,eAAe,EACxB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT,YAAY,CA+Ld"}
|