@pascal-app/core 1.0.1 → 1.0.3
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/hooks/spatial-grid/spatial-grid-sync.d.ts +42 -8
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/lib/node-visibility.d.ts +12 -0
- package/dist/lib/node-visibility.d.ts.map +1 -0
- package/dist/lib/node-visibility.js +12 -0
- package/dist/procedural-items/query.d.ts +1 -0
- package/dist/procedural-items/query.d.ts.map +1 -1
- package/dist/procedural-items/query.js +67 -23
- package/dist/registry/handles.d.ts +28 -1
- package/dist/registry/handles.d.ts.map +1 -1
- package/dist/registry/index.d.ts +1 -1
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/subtree.d.ts.map +1 -1
- package/dist/registry/subtree.js +6 -0
- package/dist/registry/types.d.ts +12 -2
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +1 -0
- package/dist/schema/nodes/block.d.ts +2 -2
- package/dist/schema/nodes/block.d.ts.map +1 -1
- package/dist/schema/nodes/block.js +21 -8
- package/dist/schema/nodes/cabinet.d.ts +2 -2
- package/dist/schema/nodes/curtain-wall.d.ts +129 -0
- package/dist/schema/nodes/curtain-wall.d.ts.map +1 -0
- package/dist/schema/nodes/curtain-wall.js +49 -0
- package/dist/schema/nodes/door.d.ts +2 -2
- package/dist/schema/nodes/wall.d.ts +73 -0
- package/dist/schema/nodes/wall.d.ts.map +1 -1
- package/dist/schema/nodes/wall.js +3 -0
- package/dist/schema/types.d.ts +76 -3
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/services/__fixtures__/hosting.d.ts +3 -0
- package/dist/services/__fixtures__/hosting.d.ts.map +1 -0
- package/dist/services/__fixtures__/hosting.js +9 -0
- package/dist/services/__fixtures__/shelf-surface-rows.d.ts +4 -0
- package/dist/services/__fixtures__/shelf-surface-rows.d.ts.map +1 -0
- package/dist/services/__fixtures__/shelf-surface-rows.js +18 -0
- package/dist/services/hosting.d.ts +3 -0
- package/dist/services/hosting.d.ts.map +1 -1
- package/dist/services/hosting.js +24 -7
- package/dist/services/index.d.ts +3 -3
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +3 -3
- package/dist/services/snap.d.ts +3 -0
- package/dist/services/snap.d.ts.map +1 -1
- package/dist/services/snap.js +11 -0
- package/dist/services/surface-hosting.d.ts +6 -2
- package/dist/services/surface-hosting.d.ts.map +1 -1
- package/dist/services/surface-hosting.js +47 -10
- package/dist/store/actions/node-actions.d.ts.map +1 -1
- package/dist/store/actions/node-actions.js +3 -96
- package/dist/store/use-scene.d.ts.map +1 -1
- package/dist/store/use-scene.js +13 -1
- package/dist/systems/stair/stair-opening-preview.d.ts +42 -8
- package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -1
- package/dist/systems/wall/wall-merge.d.ts +38 -0
- package/dist/systems/wall/wall-merge.d.ts.map +1 -0
- package/dist/systems/wall/wall-merge.js +240 -0
- package/dist/systems/wall/wall-operations.d.ts +28 -0
- package/dist/systems/wall/wall-operations.d.ts.map +1 -0
- package/dist/systems/wall/wall-operations.js +145 -0
- package/dist/systems/wall/wall-topology.d.ts +7 -0
- package/dist/systems/wall/wall-topology.d.ts.map +1 -1
- package/dist/systems/wall/wall-topology.js +53 -5
- package/dist/validation/validate-build-json.d.ts.map +1 -1
- package/dist/validation/validate-build-json.js +12 -0
- package/package.json +2 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { isProceduralItem } from '../procedural-items/query.js';
|
|
1
|
+
import { attachmentBounds, attachmentRegionsOverlap, isProceduralItem, } from '../procedural-items/query.js';
|
|
2
2
|
import { evaluateRecipe } from '../procedural-items/recipe.js';
|
|
3
|
-
import { boxCorners, frame, transformPoint } from '../procedural-items/spatial.js';
|
|
3
|
+
import { boundsOf, boxCorners, frame, transformPoint } from '../procedural-items/spatial.js';
|
|
4
4
|
import { nodeRegistry } from '../registry/registry.js';
|
|
5
5
|
import { getScaledDimensions, isLowProfileItemSurface } from '../schema/nodes/item.js';
|
|
6
|
-
import { canHostOnTop } from './hosting.js';
|
|
6
|
+
import { canHostOnTop, wouldCreateHostingCycle } from './hosting.js';
|
|
7
7
|
import { shelfRowBoardDimensions } from './shelf-board.js';
|
|
8
8
|
import { surfaceRegionContainsFootprint, surfaceRegionContainsPoint } from './surface-region.js';
|
|
9
9
|
export const NON_PHYSICAL_HOST_KINDS = [
|
|
@@ -132,7 +132,29 @@ const adapters = new Map([
|
|
|
132
132
|
]);
|
|
133
133
|
export function getSurfaceProvider(host) {
|
|
134
134
|
const declaration = nodeRegistry.get(host.type)?.capabilities.surfaces;
|
|
135
|
-
return declaration?.hosting
|
|
135
|
+
return declaration?.hosting || adapters.get(host.type) || hitDerivedSurfaceProvider;
|
|
136
|
+
}
|
|
137
|
+
export function rendersHostedChildren(def) {
|
|
138
|
+
return def.renderer
|
|
139
|
+
? def.renderer.kind === 'parametric' && def.rendersChildren !== false
|
|
140
|
+
: !!def.geometry;
|
|
141
|
+
}
|
|
142
|
+
export function canHostSurfaceChild(host, childKind, childId) {
|
|
143
|
+
const def = nodeRegistry.get(host.type);
|
|
144
|
+
if (!def ||
|
|
145
|
+
NON_PHYSICAL_HOST_KINDS.includes(host.type) ||
|
|
146
|
+
def.capabilities.surfaces?.hosting === false ||
|
|
147
|
+
nodeRegistry.get(childKind)?.capabilities.surfacePlacement === 'floor-only' ||
|
|
148
|
+
!rendersHostedChildren(def))
|
|
149
|
+
return false;
|
|
150
|
+
const generated = childId
|
|
151
|
+
? undefined
|
|
152
|
+
: nodeRegistry.get(childKind)?.schema.shape.id?.safeParse(undefined);
|
|
153
|
+
const id = childId ?? (generated?.success ? generated.data : undefined);
|
|
154
|
+
if (typeof id !== 'string')
|
|
155
|
+
return false;
|
|
156
|
+
const parsed = def.schema.shape.children?.safeParse([id]);
|
|
157
|
+
return parsed?.success === true && Array.isArray(parsed.data) && parsed.data.includes(id);
|
|
136
158
|
}
|
|
137
159
|
function hostRegion(host, ctx) {
|
|
138
160
|
const capabilities = nodeRegistry.get(host.type)?.capabilities;
|
|
@@ -159,9 +181,10 @@ function hostRegion(host, ctx) {
|
|
|
159
181
|
/** Hit and child rotation are host-local; bounds and dimensions are scaled child-local values. */
|
|
160
182
|
export function resolveSurfacePlacement(args) {
|
|
161
183
|
const { host, hit, childKind, childFootprint } = args;
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
184
|
+
if (args.childId && wouldCreateHostingCycle(args.childId, host, args.scene))
|
|
185
|
+
return null;
|
|
186
|
+
// Defer without a refusal so the paired grid event can place on floor support.
|
|
187
|
+
if (!canHostOnTop(host) || !canHostSurfaceChild(host, childKind, args.childId))
|
|
165
188
|
return null;
|
|
166
189
|
const reject = (reason) => {
|
|
167
190
|
args.onReject?.(reason);
|
|
@@ -169,8 +192,6 @@ export function resolveSurfacePlacement(args) {
|
|
|
169
192
|
};
|
|
170
193
|
if (!hit.point.every(Number.isFinite))
|
|
171
194
|
return reject('invalid-hit');
|
|
172
|
-
if (NON_PHYSICAL_HOST_KINDS.includes(host.type) || !canHostOnTop(host))
|
|
173
|
-
return reject('host-not-eligible');
|
|
174
195
|
const ctx = { scene: args.scene };
|
|
175
196
|
const provider = getSurfaceProvider(host);
|
|
176
197
|
const poseFor = (surface) => {
|
|
@@ -219,7 +240,7 @@ export function resolveSurfacePlacement(args) {
|
|
|
219
240
|
surfaceLocal: surface.id === null ? null : { position: localPosition, rotationY: rotation[1], rotation },
|
|
220
241
|
};
|
|
221
242
|
};
|
|
222
|
-
let surface = provider.resolveHit(host, hit, ctx);
|
|
243
|
+
let surface = args.surface ?? provider.resolveHit(host, hit, ctx);
|
|
223
244
|
if (!surface && hit.normalWorldY >= UPWARD_SURFACE_NORMAL_MIN_Y) {
|
|
224
245
|
// Grab offsets and snapping can leave the pointer over a hole while the child's centre is supported.
|
|
225
246
|
surface = nearestSurface((provider.surfaces?.(host, ctx) ?? []).filter((candidate) => {
|
|
@@ -264,5 +285,21 @@ export function resolveSurfacePlacement(args) {
|
|
|
264
285
|
if (!surfaceRegionContainsFootprint(hostRegion(host, ctx), pose.position, childFootprint.size, childFootprint.rotation ?? childFootprint.rotationY, childFootprint.localBounds))
|
|
265
286
|
return reject('footprint-exceeds-host');
|
|
266
287
|
}
|
|
288
|
+
if (isProceduralItem(host) && pose.surfaceId !== null && pose.surfaceLocal) {
|
|
289
|
+
const bounds = childFootprint.localBounds ?? {
|
|
290
|
+
min: [-childFootprint.size[0] / 2, 0, -childFootprint.size[2] / 2],
|
|
291
|
+
max: [childFootprint.size[0] / 2, childFootprint.size[1], childFootprint.size[2] / 2],
|
|
292
|
+
};
|
|
293
|
+
const proposal = boundsOf(boxCorners([...bounds.min], [...bounds.max]).map((point) => transformPoint(frame([...pose.surfaceLocal.position], [...pose.surfaceLocal.rotation]), point)));
|
|
294
|
+
for (const id of host.children) {
|
|
295
|
+
if (id === args.childId || host.attachments[id] !== pose.surfaceId)
|
|
296
|
+
continue;
|
|
297
|
+
const child = args.scene.get(id);
|
|
298
|
+
if (child &&
|
|
299
|
+
(isProceduralItem(child) || child.type === 'item') &&
|
|
300
|
+
attachmentRegionsOverlap(attachmentBounds(child), proposal))
|
|
301
|
+
return reject('surface-occupied');
|
|
302
|
+
}
|
|
303
|
+
}
|
|
267
304
|
return pose;
|
|
268
305
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-actions.d.ts","sourceRoot":"","sources":["../../../src/store/actions/node-actions.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"node-actions.d.ts","sourceRoot":"","sources":["../../../src/store/actions/node-actions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { nodeRegistry } from '../../registry/registry.js';
|
|
2
2
|
import { validateNodeRelations } from '../../registry/validate-relations.js';
|
|
3
|
-
import { AnyNode as AnyNodeSchema, createDefaultGuttersForSegment, createDefaultRidgeVentsForSegment, DownspoutNode as DownspoutNodeSchema, defaultDownspoutMetadata, generateId, getDefaultGutterSide,
|
|
3
|
+
import { AnyNode as AnyNodeSchema, createDefaultGuttersForSegment, createDefaultRidgeVentsForSegment, DownspoutNode as DownspoutNodeSchema, defaultDownspoutMetadata, generateId, getDefaultGutterSide, isAutoGutterEnabled, isAutoRidgeVentEnabled, isDefaultDownspoutNode, isDefaultGutterNode, isDefaultRidgeVentNode, parseNode, planAutomaticDownspouts, resolveAutomaticDownspoutLength, } from '../../schema/index.js';
|
|
4
4
|
import { constrainWallCurveOffsetToAvoidIntersections } from '../../systems/wall/wall-curve.js';
|
|
5
|
+
import { areWallStylesCompatible, areWallsCollinearAcrossPoint, buildMergedWallAttachmentUpdates, getWallEndpointAtPoint, resolveMergedWallEndpoints, } from '../../systems/wall/wall-merge.js';
|
|
5
6
|
import { activeSceneCommitNodeIds, addActiveSceneCommitNodeIds, runWithSceneCommitNodeIds, } from '../history-control.js';
|
|
6
7
|
const DEFAULT_RIDGE_VENT_REFRESH_FIELDS = new Set([
|
|
7
8
|
'roofType',
|
|
@@ -750,100 +751,6 @@ function refreshDefaultGuttersForRoofIds(nextNodes, roofIds, dirtyIds, deletedId
|
|
|
750
751
|
// Track pending RAF for updateNodesAction to prevent multiple queued callbacks
|
|
751
752
|
let pendingRafId = null;
|
|
752
753
|
let pendingUpdates = new Set();
|
|
753
|
-
function pointsEqual(a, b, tolerance = 1e-6) {
|
|
754
|
-
const dx = a[0] - b[0];
|
|
755
|
-
const dz = a[1] - b[1];
|
|
756
|
-
return dx * dx + dz * dz <= tolerance * tolerance;
|
|
757
|
-
}
|
|
758
|
-
function wallLength(wall) {
|
|
759
|
-
return Math.hypot(wall.end[0] - wall.start[0], wall.end[1] - wall.start[1]);
|
|
760
|
-
}
|
|
761
|
-
function getWallEndpointAtPoint(wall, point) {
|
|
762
|
-
if (pointsEqual(wall.start, point))
|
|
763
|
-
return 'start';
|
|
764
|
-
if (pointsEqual(wall.end, point))
|
|
765
|
-
return 'end';
|
|
766
|
-
return null;
|
|
767
|
-
}
|
|
768
|
-
function getWallFreeEndpoint(wall, sharedPoint) {
|
|
769
|
-
return pointsEqual(wall.start, sharedPoint) ? wall.end : wall.start;
|
|
770
|
-
}
|
|
771
|
-
function areWallStylesCompatible(a, b) {
|
|
772
|
-
const aInterior = getWallSurfaceMaterialSignature(getEffectiveWallSurfaceMaterial(a, 'interior'));
|
|
773
|
-
const bInterior = getWallSurfaceMaterialSignature(getEffectiveWallSurfaceMaterial(b, 'interior'));
|
|
774
|
-
const aExterior = getWallSurfaceMaterialSignature(getEffectiveWallSurfaceMaterial(a, 'exterior'));
|
|
775
|
-
const bExterior = getWallSurfaceMaterialSignature(getEffectiveWallSurfaceMaterial(b, 'exterior'));
|
|
776
|
-
return ((a.parentId ?? null) === (b.parentId ?? null) &&
|
|
777
|
-
Math.abs((a.curveOffset ?? 0) - (b.curveOffset ?? 0)) <= 1e-6 &&
|
|
778
|
-
Math.abs((a.thickness ?? 0.2) - (b.thickness ?? 0.2)) <= 1e-6 &&
|
|
779
|
-
// Absent height means plane-bound (follows the storey), which must never
|
|
780
|
-
// merge with an explicit height — even one that currently matches the plane.
|
|
781
|
-
(a.height == null) === (b.height == null) &&
|
|
782
|
-
Math.abs((a.height ?? 0) - (b.height ?? 0)) <= 1e-6 &&
|
|
783
|
-
aInterior === bInterior &&
|
|
784
|
-
aExterior === bExterior &&
|
|
785
|
-
a.frontSide === b.frontSide &&
|
|
786
|
-
a.backSide === b.backSide &&
|
|
787
|
-
a.visible === b.visible);
|
|
788
|
-
}
|
|
789
|
-
function areWallsCollinearAcrossPoint(a, b, sharedPoint) {
|
|
790
|
-
const freeA = getWallFreeEndpoint(a, sharedPoint);
|
|
791
|
-
const freeB = getWallFreeEndpoint(b, sharedPoint);
|
|
792
|
-
const ax = freeA[0] - sharedPoint[0];
|
|
793
|
-
const az = freeA[1] - sharedPoint[1];
|
|
794
|
-
const bx = freeB[0] - sharedPoint[0];
|
|
795
|
-
const bz = freeB[1] - sharedPoint[1];
|
|
796
|
-
const lenA = Math.hypot(ax, az);
|
|
797
|
-
const lenB = Math.hypot(bx, bz);
|
|
798
|
-
if (lenA < 1e-6 || lenB < 1e-6)
|
|
799
|
-
return false;
|
|
800
|
-
const cross = (ax * bz - az * bx) / (lenA * lenB);
|
|
801
|
-
const dot = (ax * bx + az * bz) / (lenA * lenB);
|
|
802
|
-
return Math.abs(cross) <= 1e-4 && dot < -0.999;
|
|
803
|
-
}
|
|
804
|
-
function resolveMergedWallEndpoints(primary, secondary, sharedPoint) {
|
|
805
|
-
const primaryEndpoint = getWallEndpointAtPoint(primary, sharedPoint);
|
|
806
|
-
const secondaryEndpoint = getWallEndpointAtPoint(secondary, sharedPoint);
|
|
807
|
-
if (primaryEndpoint === 'end' && secondaryEndpoint === 'start') {
|
|
808
|
-
return { start: primary.start, end: secondary.end };
|
|
809
|
-
}
|
|
810
|
-
if (primaryEndpoint === 'start' && secondaryEndpoint === 'end') {
|
|
811
|
-
return { start: secondary.start, end: primary.end };
|
|
812
|
-
}
|
|
813
|
-
if (primaryEndpoint === 'start' && secondaryEndpoint === 'start') {
|
|
814
|
-
return { start: primary.end, end: secondary.end };
|
|
815
|
-
}
|
|
816
|
-
return { start: primary.start, end: secondary.start };
|
|
817
|
-
}
|
|
818
|
-
function buildMergedWallAttachmentUpdates(primary, secondary, mergedWallId, mergedStart, mergedEnd, nodes) {
|
|
819
|
-
const mergedLength = Math.max(Math.hypot(mergedEnd[0] - mergedStart[0], mergedEnd[1] - mergedStart[1]), 1e-6);
|
|
820
|
-
const tangentX = (mergedEnd[0] - mergedStart[0]) / mergedLength;
|
|
821
|
-
const tangentZ = (mergedEnd[1] - mergedStart[1]) / mergedLength;
|
|
822
|
-
const updates = [];
|
|
823
|
-
const wallChildren = [...(primary.children ?? []), ...(secondary.children ?? [])];
|
|
824
|
-
for (const childId of wallChildren) {
|
|
825
|
-
const child = nodes[childId];
|
|
826
|
-
if (!(child && 'position' in child && Array.isArray(child.position))) {
|
|
827
|
-
continue;
|
|
828
|
-
}
|
|
829
|
-
const sourceWall = child.parentId === secondary.id ? secondary : primary;
|
|
830
|
-
const sourceLength = Math.max(wallLength(sourceWall), 1e-6);
|
|
831
|
-
const localX = typeof child.position[0] === 'number' ? child.position[0] : 0;
|
|
832
|
-
const worldX = sourceWall.start[0] + ((sourceWall.end[0] - sourceWall.start[0]) * localX) / sourceLength;
|
|
833
|
-
const worldZ = sourceWall.start[1] + ((sourceWall.end[1] - sourceWall.start[1]) * localX) / sourceLength;
|
|
834
|
-
const nextLocalX = Math.max(0, Math.min(mergedLength, (worldX - mergedStart[0]) * tangentX + (worldZ - mergedStart[1]) * tangentZ));
|
|
835
|
-
updates.push({
|
|
836
|
-
id: childId,
|
|
837
|
-
data: {
|
|
838
|
-
parentId: mergedWallId,
|
|
839
|
-
wallId: mergedWallId,
|
|
840
|
-
position: [nextLocalX, child.position[1], child.position[2]],
|
|
841
|
-
...('wallT' in child ? { wallT: nextLocalX / mergedLength } : {}),
|
|
842
|
-
},
|
|
843
|
-
});
|
|
844
|
-
}
|
|
845
|
-
return updates;
|
|
846
|
-
}
|
|
847
754
|
function buildWallMergePlans(nodes, idsToDelete) {
|
|
848
755
|
const deletedWalls = idsToDelete
|
|
849
756
|
.map((id) => nodes[id])
|
|
@@ -861,7 +768,7 @@ function buildWallMergePlans(nodes, idsToDelete) {
|
|
|
861
768
|
return false;
|
|
862
769
|
if ((node.parentId ?? null) !== (deletedWall.parentId ?? null))
|
|
863
770
|
return false;
|
|
864
|
-
return
|
|
771
|
+
return getWallEndpointAtPoint(node, junction) !== null;
|
|
865
772
|
});
|
|
866
773
|
if (candidates.length !== 2) {
|
|
867
774
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-scene.d.ts","sourceRoot":"","sources":["../../src/store/use-scene.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"use-scene.d.ts","sourceRoot":"","sources":["../../src/store/use-scene.ts"],"names":[],"mappings":"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"}
|
package/dist/store/use-scene.js
CHANGED
|
@@ -991,9 +991,21 @@ function sceneHistorySnapshotFromState(state) {
|
|
|
991
991
|
}
|
|
992
992
|
}
|
|
993
993
|
const historyNodes = {};
|
|
994
|
-
for (const [id,
|
|
994
|
+
for (const [id, sourceNode] of Object.entries(nodes)) {
|
|
995
995
|
if (transientNodeIds.has(id))
|
|
996
996
|
continue;
|
|
997
|
+
let node = sourceNode;
|
|
998
|
+
if (node.type === 'procedural-item') {
|
|
999
|
+
let attachments;
|
|
1000
|
+
for (const childId of transientNodeIds) {
|
|
1001
|
+
if (!Object.hasOwn(node.attachments, childId))
|
|
1002
|
+
continue;
|
|
1003
|
+
attachments ??= { ...node.attachments };
|
|
1004
|
+
delete attachments[childId];
|
|
1005
|
+
}
|
|
1006
|
+
if (attachments)
|
|
1007
|
+
node = { ...node, attachments };
|
|
1008
|
+
}
|
|
997
1009
|
if (!('children' in node && Array.isArray(node.children))) {
|
|
998
1010
|
historyNodes[id] = node;
|
|
999
1011
|
continue;
|
|
@@ -490,6 +490,40 @@ export declare function getNodesWithLiveStairOpeningInputs(nodes: Record<string,
|
|
|
490
490
|
} | undefined;
|
|
491
491
|
materialPreset?: string | undefined;
|
|
492
492
|
height?: number | undefined;
|
|
493
|
+
wallType?: "standard" | "curtain" | undefined;
|
|
494
|
+
curtainWall?: {
|
|
495
|
+
construction: "stick" | "unitized";
|
|
496
|
+
framing: "capped" | "vertical-caps" | "horizontal-caps" | "structural-glazing";
|
|
497
|
+
columns: {
|
|
498
|
+
layout: "count" | "maximum-spacing" | "fixed-spacing";
|
|
499
|
+
count: number;
|
|
500
|
+
spacing: number;
|
|
501
|
+
alignment: "start" | "center" | "end";
|
|
502
|
+
};
|
|
503
|
+
rows: {
|
|
504
|
+
layout: "count" | "maximum-spacing" | "fixed-spacing";
|
|
505
|
+
count: number;
|
|
506
|
+
spacing: number;
|
|
507
|
+
alignment: "start" | "center" | "end";
|
|
508
|
+
};
|
|
509
|
+
mullionWidth: number;
|
|
510
|
+
transomWidth: number;
|
|
511
|
+
perimeterWidth: number;
|
|
512
|
+
jointWidth: number;
|
|
513
|
+
glassThickness: number;
|
|
514
|
+
panelType: "glass" | "solid" | "empty";
|
|
515
|
+
spandrel: "top" | "none" | "bottom";
|
|
516
|
+
frameColor: string;
|
|
517
|
+
glassColor: string;
|
|
518
|
+
solidColor: string;
|
|
519
|
+
glassOpacity: number;
|
|
520
|
+
glassRoughness: number;
|
|
521
|
+
panels: {
|
|
522
|
+
column: number;
|
|
523
|
+
row: number;
|
|
524
|
+
type: "glass" | "solid" | "empty";
|
|
525
|
+
}[];
|
|
526
|
+
} | undefined;
|
|
493
527
|
thickness?: number | undefined;
|
|
494
528
|
fillToTerrain?: boolean | undefined;
|
|
495
529
|
interiorMaterial?: {
|
|
@@ -572,10 +606,10 @@ export declare function getNodesWithLiveStairOpeningInputs(nodes: Record<string,
|
|
|
572
606
|
baseHeight: number;
|
|
573
607
|
style: "slat" | "rail" | "privacy" | "horizontal";
|
|
574
608
|
baseStyle: "floating" | "grounded";
|
|
575
|
-
thickness: number;
|
|
576
|
-
postSpacing: number;
|
|
577
609
|
start: [number, number];
|
|
578
610
|
end: [number, number];
|
|
611
|
+
thickness: number;
|
|
612
|
+
postSpacing: number;
|
|
579
613
|
postSize: number;
|
|
580
614
|
topRailHeight: number;
|
|
581
615
|
groundClearance: number;
|
|
@@ -644,7 +678,7 @@ export declare function getNodesWithLiveStairOpeningInputs(nodes: Record<string,
|
|
|
644
678
|
frontStyle: "slab" | "shaker" | "raised-arch";
|
|
645
679
|
panelReady: boolean;
|
|
646
680
|
handleStyle: "none" | "bar" | "cutout" | "hole" | "knob";
|
|
647
|
-
handlePosition: "top" | "
|
|
681
|
+
handlePosition: "top" | "center" | "auto";
|
|
648
682
|
frontOverlay: "full" | "inset";
|
|
649
683
|
withBottomPanel: boolean;
|
|
650
684
|
showPlinth: boolean;
|
|
@@ -790,7 +824,7 @@ export declare function getNodesWithLiveStairOpeningInputs(nodes: Record<string,
|
|
|
790
824
|
frontStyle: "slab" | "shaker" | "raised-arch";
|
|
791
825
|
panelReady: boolean;
|
|
792
826
|
handleStyle: "none" | "bar" | "cutout" | "hole" | "knob";
|
|
793
|
-
handlePosition: "top" | "
|
|
827
|
+
handlePosition: "top" | "center" | "auto";
|
|
794
828
|
frontOverlay: "full" | "inset";
|
|
795
829
|
withBottomPanel: boolean;
|
|
796
830
|
showPlinth: boolean;
|
|
@@ -1489,8 +1523,8 @@ export declare function getNodesWithLiveStairOpeningInputs(nodes: Record<string,
|
|
|
1489
1523
|
height: number;
|
|
1490
1524
|
style: "wall-shelf" | "bookshelf" | "open-rack" | "cubby";
|
|
1491
1525
|
rows: number;
|
|
1492
|
-
thickness: number;
|
|
1493
1526
|
columns: number;
|
|
1527
|
+
thickness: number;
|
|
1494
1528
|
withBack: boolean;
|
|
1495
1529
|
withSides: boolean;
|
|
1496
1530
|
withBottom: boolean;
|
|
@@ -1954,7 +1988,7 @@ export declare function getNodesWithLiveStairOpeningInputs(nodes: Record<string,
|
|
|
1954
1988
|
swingDirection: "inward" | "outward";
|
|
1955
1989
|
swingAngle: number;
|
|
1956
1990
|
segments: {
|
|
1957
|
-
type: "glass" | "
|
|
1991
|
+
type: "glass" | "empty" | "panel";
|
|
1958
1992
|
heightRatio: number;
|
|
1959
1993
|
columnRatios: number[];
|
|
1960
1994
|
dividerThickness: number;
|
|
@@ -2378,9 +2412,9 @@ export declare function getNodesWithLiveStairOpeningInputs(nodes: Record<string,
|
|
|
2378
2412
|
metadata: Record<string, unknown>;
|
|
2379
2413
|
rotation: number;
|
|
2380
2414
|
rows: number;
|
|
2415
|
+
columns: number;
|
|
2381
2416
|
frameThickness: number;
|
|
2382
2417
|
frameDepth: number;
|
|
2383
|
-
columns: number;
|
|
2384
2418
|
panelWidth: number;
|
|
2385
2419
|
panelHeight: number;
|
|
2386
2420
|
gapX: number;
|
|
@@ -2446,6 +2480,7 @@ export declare function getNodesWithLiveStairOpeningInputs(nodes: Record<string,
|
|
|
2446
2480
|
rotation: number;
|
|
2447
2481
|
width: number;
|
|
2448
2482
|
height: number;
|
|
2483
|
+
glassThickness: number;
|
|
2449
2484
|
operationState: number;
|
|
2450
2485
|
slideDirection: "x" | "z";
|
|
2451
2486
|
frameThickness: number;
|
|
@@ -2453,7 +2488,6 @@ export declare function getNodesWithLiveStairOpeningInputs(nodes: Record<string,
|
|
|
2453
2488
|
curbHeight: number;
|
|
2454
2489
|
cutoutOffset: number;
|
|
2455
2490
|
skylightType: "flat" | "sliding" | "opening" | "walk-on" | "lantern";
|
|
2456
|
-
glassThickness: number;
|
|
2457
2491
|
lanternHeight: number;
|
|
2458
2492
|
lanternTopScale: number;
|
|
2459
2493
|
openingAngle: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stair-opening-preview.d.ts","sourceRoot":"","sources":["../../../src/systems/stair/stair-opening-preview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC7E,OAA6B,EAAE,KAAK,iBAAiB,EAAE,MAAM,qCAAqC,CAAA;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAGpE,KAAK,oBAAoB,GAAG;IAC1B,EAAE,EAAE,SAAS,CAAA;IACb,IAAI,EAAE,OAAO,CAAC,QAAQ,GAAG,WAAW,CAAC,CAAA;CACtC,CAAA;AAoBD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,EAClD,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACrD,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,WAYvC;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,EAClD,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACrD,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC
|
|
1
|
+
{"version":3,"file":"stair-opening-preview.d.ts","sourceRoot":"","sources":["../../../src/systems/stair/stair-opening-preview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC7E,OAA6B,EAAE,KAAK,iBAAiB,EAAE,MAAM,qCAAqC,CAAA;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAGpE,KAAK,oBAAoB,GAAG;IAC1B,EAAE,EAAE,SAAS,CAAA;IACb,IAAI,EAAE,OAAO,CAAC,QAAQ,GAAG,WAAW,CAAC,CAAA;CACtC,CAAA;AAoBD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,EAClD,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACrD,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,WAYvC;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,EAClD,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACrD,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwBvC;AAED,wBAAgB,qCAAqC;;mBAUlC,oBAAoB,EAAE;;EAiCxC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type AnyNode, type AnyNodeId, type WallNode } from '../../schema/index.js';
|
|
2
|
+
import type { WallTopologyChanges } from './wall-topology.js';
|
|
3
|
+
export type WallAttachmentUpdate = {
|
|
4
|
+
id: AnyNodeId;
|
|
5
|
+
data: Partial<AnyNode>;
|
|
6
|
+
};
|
|
7
|
+
export declare function getWallEndpointAtPoint(wall: Pick<WallNode, 'start' | 'end'>, point: [number, number]): 'start' | 'end' | null;
|
|
8
|
+
/**
|
|
9
|
+
* The first thing two walls disagree on (for the merge's explanation), or null.
|
|
10
|
+
* The delete heal is strict: room sides must match, and a wall following the
|
|
11
|
+
* storey never joins one with an explicit height. An explicit merge compares
|
|
12
|
+
* what is visible instead — `heightOf` resolves each wall's actual height — and
|
|
13
|
+
* leaves the sides to room detection, which reclassifies the merged wall.
|
|
14
|
+
*/
|
|
15
|
+
export declare function wallStyleMismatch(a: WallNode, b: WallNode, options: {
|
|
16
|
+
sides: boolean;
|
|
17
|
+
heightOf?: (wall: WallNode) => number;
|
|
18
|
+
}): string | null;
|
|
19
|
+
export declare function areWallStylesCompatible(a: WallNode, b: WallNode): boolean;
|
|
20
|
+
export declare function areWallsCollinearAcrossPoint(a: WallNode, b: WallNode, sharedPoint: [number, number]): boolean;
|
|
21
|
+
export declare function resolveMergedWallEndpoints(primary: WallNode, secondary: WallNode, sharedPoint: [number, number]): {
|
|
22
|
+
start: [number, number];
|
|
23
|
+
end: [number, number];
|
|
24
|
+
};
|
|
25
|
+
export declare function buildMergedWallAttachmentUpdates(primary: WallNode, secondary: WallNode, mergedWallId: AnyNodeId, mergedStart: [number, number], mergedEnd: [number, number], nodes: Record<AnyNodeId, AnyNode>): WallAttachmentUpdate[];
|
|
26
|
+
/**
|
|
27
|
+
* Merges a straight run of adjoining walls into one — the inverse of a split.
|
|
28
|
+
* Every joint must hold exactly these walls (a T or a cross stays split), and
|
|
29
|
+
* neighbours must continue in line and look alike (`wallStyleMismatch`: same
|
|
30
|
+
* thickness, visible height and finish). The wall with the most attachments
|
|
31
|
+
* keeps its id and height mode; openings and wall items keep their world
|
|
32
|
+
* position on it.
|
|
33
|
+
*/
|
|
34
|
+
export declare function planWallMerge(nodes: Record<AnyNodeId, AnyNode>, wallIds: readonly AnyNodeId[]): {
|
|
35
|
+
changes: WallTopologyChanges;
|
|
36
|
+
wallId: WallNode['id'];
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=wall-merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wall-merge.d.ts","sourceRoot":"","sources":["../../../src/systems/wall/wall-merge.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EAGd,KAAK,QAAQ,EACd,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAK1D,MAAM,MAAM,oBAAoB,GAAG;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAA;AAY5E,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,KAAK,CAAC,EACrC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GACtB,OAAO,GAAG,KAAK,GAAG,IAAI,CAIxB;AAMD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,QAAQ,EACX,CAAC,EAAE,QAAQ,EACX,OAAO,EAAE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,CAAA;CAAE,GACjE,MAAM,GAAG,IAAI,CAuBf;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,WAE/D;AAED,wBAAgB,4BAA4B,CAC1C,CAAC,EAAE,QAAQ,EACX,CAAC,EAAE,QAAQ,EACX,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,WAgB9B;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,QAAQ,EACjB,SAAS,EAAE,QAAQ,EACnB,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B;IAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAkBpD;AAyBD,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,QAAQ,EACjB,SAAS,EAAE,QAAQ,EACnB,YAAY,EAAE,SAAS,EACvB,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,GAChC,oBAAoB,EAAE,CAyDxB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EACjC,OAAO,EAAE,SAAS,SAAS,EAAE,GAC5B;IAAE,OAAO,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;CAAE,CA4F1D"}
|