@pascal-app/core 1.0.0-beta.2 → 1.0.0-beta.4
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/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/lib/terrain-codec.d.ts +6 -1
- package/dist/lib/terrain-codec.d.ts.map +1 -1
- package/dist/lib/terrain-codec.js +50 -16
- package/dist/lib/terrain-source.d.ts +1 -0
- package/dist/lib/terrain-source.d.ts.map +1 -1
- package/dist/lib/terrain-source.js +4 -1
- package/dist/store/use-live-terrain.d.ts +10 -0
- package/dist/store/use-live-terrain.d.ts.map +1 -1
- package/dist/store/use-live-terrain.js +26 -2
- package/dist/store/use-scene.d.ts.map +1 -1
- package/dist/store/use-scene.js +13 -31
- package/dist/utils/heal-scene-graph.d.ts +5 -0
- package/dist/utils/heal-scene-graph.d.ts.map +1 -1
- package/dist/utils/heal-scene-graph.js +46 -1
- package/dist/utils/retired-scene-nodes.d.ts +6 -0
- package/dist/utils/retired-scene-nodes.d.ts.map +1 -0
- package/dist/utils/retired-scene-nodes.js +30 -0
- package/dist/utils/scene-migrations.d.ts +3 -0
- package/dist/utils/scene-migrations.d.ts.map +1 -0
- package/dist/utils/scene-migrations.js +6 -0
- package/package.json +6 -1
package/dist/index.d.ts
CHANGED
|
@@ -17,10 +17,10 @@ export { getRenderableSlabPolygon, type SlabEdgeWallBandSnap, type SlabPolygonCo
|
|
|
17
17
|
export { deriveSlotId, isSlotMaterialName, SLOT_MATERIAL_PREFIX, slotLabelFromId, } from './lib/slots';
|
|
18
18
|
export { type AutoCeilingPlanningContext, type AutoCeilingSyncPlan, type AutoSlabPlanningContext, type AutoSlabSyncPlan, type AutoZoneSyncPlan, detectSpacesForLevel, initSpaceDetectionSync, isSpaceDetectionPaused, pauseSpaceDetection, planAutoCeilingsForLevel, planAutoSlabsForLevel, planAutoZonesForLevel, resolveAutoZonePolygon, resumeSpaceDetection, type Space, type SpaceBoundaryFace, wallClosesRoom, wallTouchesOthers, } from './lib/space-detection';
|
|
19
19
|
export { advanceStroke, type BrushSettings, type BrushShape, beginStroke, brushHeightAt, DEFAULT_BRUSH_SETTINGS, detachStrokeAnchor, highestOver, MIN_BRUSH_RADIUS_IN_SPACINGS, maxCoverage, minBrushRadius, RAISE_METRES_PER_STROKE, sampleTarget, type TerrainStroke, type TerrainVerb, weightAt, } from './lib/terrain-brush';
|
|
20
|
-
export { decodeTerrainField, encodeTerrainField, isDatumField } from './lib/terrain-codec';
|
|
20
|
+
export { decodeHeightPatch, decodeTerrainField, type EncodedHeightPatch, encodeHeightPatch, encodeTerrainField, isDatumField, } from './lib/terrain-codec';
|
|
21
21
|
export { applyHeightPatch, createTerrainField, DEFAULT_TERRAIN_SPACING, DEFAULT_TERRAIN_STEP, diffToPatches, flattenPatch, type HeightPatch, heightAt, heightAtSample, isFlatOver, normalAt, quantize, sampleRangeOver, slopeAt, surfaceHeightAt, type TerrainField, } from './lib/terrain-field';
|
|
22
22
|
export { raycastTerrain, type TerrainHit } from './lib/terrain-raycast';
|
|
23
|
-
export { commitTerrainField, terrainFieldForEdit, terrainFieldOf } from './lib/terrain-source';
|
|
23
|
+
export { commitTerrainField, persistedTerrainFieldOf, terrainFieldForEdit, terrainFieldOf, } from './lib/terrain-source';
|
|
24
24
|
export { isLevelBaseConsumer, isSiteDatum, levelBaseElevationAt, noteLevelBaseConsumer, SITE_DATUM_EPSILON, SITE_DATUM_Y, terrainSupportLift, } from './lib/terrain-support';
|
|
25
25
|
export { closestOnSegment, collectLevelWallSegments, nearestWallSegment, WALL_SNAP_DISTANCE_M, type WallSegment, type WallSegmentClosest, } from './lib/wall-distance';
|
|
26
26
|
export { deriveZoneQuantityReport, type ZoneQuantityReport, type ZoneQuantityValue, } from './lib/zone-quantities';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -16,10 +16,10 @@ export { getRenderableSlabPolygon, slabPolygonContextFromGeometry, snapSlabEdgeT
|
|
|
16
16
|
export { deriveSlotId, isSlotMaterialName, SLOT_MATERIAL_PREFIX, slotLabelFromId, } from './lib/slots';
|
|
17
17
|
export { detectSpacesForLevel, initSpaceDetectionSync, isSpaceDetectionPaused, pauseSpaceDetection, planAutoCeilingsForLevel, planAutoSlabsForLevel, planAutoZonesForLevel, resolveAutoZonePolygon, resumeSpaceDetection, wallClosesRoom, wallTouchesOthers, } from './lib/space-detection';
|
|
18
18
|
export { advanceStroke, beginStroke, brushHeightAt, DEFAULT_BRUSH_SETTINGS, detachStrokeAnchor, highestOver, MIN_BRUSH_RADIUS_IN_SPACINGS, maxCoverage, minBrushRadius, RAISE_METRES_PER_STROKE, sampleTarget, weightAt, } from './lib/terrain-brush';
|
|
19
|
-
export { decodeTerrainField, encodeTerrainField, isDatumField } from './lib/terrain-codec';
|
|
19
|
+
export { decodeHeightPatch, decodeTerrainField, encodeHeightPatch, encodeTerrainField, isDatumField, } from './lib/terrain-codec';
|
|
20
20
|
export { applyHeightPatch, createTerrainField, DEFAULT_TERRAIN_SPACING, DEFAULT_TERRAIN_STEP, diffToPatches, flattenPatch, heightAt, heightAtSample, isFlatOver, normalAt, quantize, sampleRangeOver, slopeAt, surfaceHeightAt, } from './lib/terrain-field';
|
|
21
21
|
export { raycastTerrain } from './lib/terrain-raycast';
|
|
22
|
-
export { commitTerrainField, terrainFieldForEdit, terrainFieldOf } from './lib/terrain-source';
|
|
22
|
+
export { commitTerrainField, persistedTerrainFieldOf, terrainFieldForEdit, terrainFieldOf, } from './lib/terrain-source';
|
|
23
23
|
export { isLevelBaseConsumer, isSiteDatum, levelBaseElevationAt, noteLevelBaseConsumer, SITE_DATUM_EPSILON, SITE_DATUM_Y, terrainSupportLift, } from './lib/terrain-support';
|
|
24
24
|
export { closestOnSegment, collectLevelWallSegments, nearestWallSegment, WALL_SNAP_DISTANCE_M, } from './lib/wall-distance';
|
|
25
25
|
export { deriveZoneQuantityReport, } from './lib/zone-quantities';
|
|
@@ -25,7 +25,12 @@
|
|
|
25
25
|
* the scene.
|
|
26
26
|
*/
|
|
27
27
|
import { type TerrainData } from '../schema/terrain';
|
|
28
|
-
import type { TerrainField } from './terrain-field';
|
|
28
|
+
import type { HeightPatch, TerrainField } from './terrain-field';
|
|
29
|
+
export type EncodedHeightPatch = Omit<HeightPatch, 'heights'> & {
|
|
30
|
+
heights: string;
|
|
31
|
+
};
|
|
32
|
+
export declare function encodeHeightPatch(patch: HeightPatch): EncodedHeightPatch;
|
|
33
|
+
export declare function decodeHeightPatch(value: unknown): HeightPatch | null;
|
|
29
34
|
export declare function encodeTerrainField(field: TerrainField): TerrainData;
|
|
30
35
|
/**
|
|
31
36
|
* Rebuild a field from persisted data, or `null` if the data is unusable.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terrain-codec.d.ts","sourceRoot":"","sources":["../../src/lib/terrain-codec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"terrain-codec.d.ts","sourceRoot":"","sources":["../../src/lib/terrain-codec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAyEhE,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEnF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,kBAAkB,CAExE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CA4BpE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,WAAW,CAUnE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,GAAG,IAAI,CAgCrE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAKzD"}
|
|
@@ -76,12 +76,55 @@ function decodeBase64(text) {
|
|
|
76
76
|
}
|
|
77
77
|
return bytes;
|
|
78
78
|
}
|
|
79
|
-
|
|
80
|
-
const bytes = new Uint8Array(
|
|
79
|
+
function encodeInt16Samples(samples) {
|
|
80
|
+
const bytes = new Uint8Array(samples.length * 2);
|
|
81
81
|
const view = new DataView(bytes.buffer);
|
|
82
|
-
for (let i = 0; i <
|
|
83
|
-
view.setInt16(i * 2,
|
|
82
|
+
for (let i = 0; i < samples.length; i++) {
|
|
83
|
+
view.setInt16(i * 2, samples[i] ?? 0, true);
|
|
84
|
+
}
|
|
85
|
+
return encodeBase64(bytes);
|
|
86
|
+
}
|
|
87
|
+
function decodeInt16Samples(text, sampleCount) {
|
|
88
|
+
const bytes = decodeBase64(text);
|
|
89
|
+
if (!bytes || encodeBase64(bytes) !== text || bytes.byteLength !== sampleCount * 2)
|
|
90
|
+
return null;
|
|
91
|
+
const samples = new Int16Array(sampleCount);
|
|
92
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
93
|
+
for (let i = 0; i < samples.length; i++) {
|
|
94
|
+
samples[i] = view.getInt16(i * 2, true);
|
|
84
95
|
}
|
|
96
|
+
return samples;
|
|
97
|
+
}
|
|
98
|
+
export function encodeHeightPatch(patch) {
|
|
99
|
+
return { ...patch, heights: encodeInt16Samples(patch.heights) };
|
|
100
|
+
}
|
|
101
|
+
export function decodeHeightPatch(value) {
|
|
102
|
+
if (!value || typeof value !== 'object')
|
|
103
|
+
return null;
|
|
104
|
+
const patch = value;
|
|
105
|
+
if (!Number.isInteger(patch.col0) ||
|
|
106
|
+
!Number.isInteger(patch.row0) ||
|
|
107
|
+
!Number.isInteger(patch.cols) ||
|
|
108
|
+
!Number.isInteger(patch.rows)) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
const col0 = patch.col0;
|
|
112
|
+
const row0 = patch.row0;
|
|
113
|
+
const cols = patch.cols;
|
|
114
|
+
const rows = patch.rows;
|
|
115
|
+
if (col0 < 0 ||
|
|
116
|
+
row0 < 0 ||
|
|
117
|
+
cols < 1 ||
|
|
118
|
+
rows < 1 ||
|
|
119
|
+
col0 + cols > MAX_TERRAIN_SIDE ||
|
|
120
|
+
row0 + rows > MAX_TERRAIN_SIDE ||
|
|
121
|
+
typeof patch.heights !== 'string') {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
const heights = decodeInt16Samples(patch.heights, cols * rows);
|
|
125
|
+
return heights ? { col0, row0, cols, rows, heights } : null;
|
|
126
|
+
}
|
|
127
|
+
export function encodeTerrainField(field) {
|
|
85
128
|
return {
|
|
86
129
|
type: 'heightfield',
|
|
87
130
|
origin: [field.origin[0], field.origin[1]],
|
|
@@ -89,7 +132,7 @@ export function encodeTerrainField(field) {
|
|
|
89
132
|
cols: field.cols,
|
|
90
133
|
rows: field.rows,
|
|
91
134
|
step: field.step,
|
|
92
|
-
heights:
|
|
135
|
+
heights: encodeInt16Samples(field.heights),
|
|
93
136
|
};
|
|
94
137
|
}
|
|
95
138
|
/**
|
|
@@ -130,18 +173,9 @@ export function decodeTerrainField(data) {
|
|
|
130
173
|
!Number.isFinite(d.origin[1])) {
|
|
131
174
|
return null;
|
|
132
175
|
}
|
|
133
|
-
const
|
|
134
|
-
if (!
|
|
176
|
+
const heights = decodeInt16Samples(d.heights, cols * rows);
|
|
177
|
+
if (!heights)
|
|
135
178
|
return null;
|
|
136
|
-
if (encodeBase64(bytes) !== d.heights)
|
|
137
|
-
return null;
|
|
138
|
-
if (bytes.byteLength !== cols * rows * 2)
|
|
139
|
-
return null;
|
|
140
|
-
const heights = new Int16Array(cols * rows);
|
|
141
|
-
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
142
|
-
for (let i = 0; i < heights.length; i++) {
|
|
143
|
-
heights[i] = view.getInt16(i * 2, true);
|
|
144
|
-
}
|
|
145
179
|
return {
|
|
146
180
|
origin: [d.origin[0], d.origin[1]],
|
|
147
181
|
spacing: d.spacing,
|
|
@@ -39,6 +39,7 @@ import { createTerrainField, type TerrainField } from './terrain-field';
|
|
|
39
39
|
export declare function terrainFieldOf(site: (Pick<SiteNode, 'terrain'> & {
|
|
40
40
|
id?: string;
|
|
41
41
|
}) | null | undefined): TerrainField | null;
|
|
42
|
+
export declare function persistedTerrainFieldOf(site: Pick<SiteNode, 'terrain'> | null | undefined): TerrainField | null;
|
|
42
43
|
/**
|
|
43
44
|
* The field a site *would* sculpt into: its existing terrain, or a fresh flat
|
|
44
45
|
* field sized to `options`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terrain-source.d.ts","sourceRoot":"","sources":["../../src/lib/terrain-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAGpD,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAUvE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,GAAG,SAAS,GACrE,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"terrain-source.d.ts","sourceRoot":"","sources":["../../src/lib/terrain-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAGpD,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAUvE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,GAAG,SAAS,GACrE,YAAY,GAAG,IAAI,CAMrB;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,GACjD,YAAY,GAAG,IAAI,CAcrB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,EAClD,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC,GACjD,YAAY,CAEd;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,WAAW,CAInE"}
|
|
@@ -48,6 +48,9 @@ export function terrainFieldOf(site) {
|
|
|
48
48
|
if (live)
|
|
49
49
|
return live;
|
|
50
50
|
}
|
|
51
|
+
return persistedTerrainFieldOf(site);
|
|
52
|
+
}
|
|
53
|
+
export function persistedTerrainFieldOf(site) {
|
|
51
54
|
const data = site?.terrain;
|
|
52
55
|
if (!data)
|
|
53
56
|
return null;
|
|
@@ -73,7 +76,7 @@ export function terrainFieldOf(site) {
|
|
|
73
76
|
* would force every reader to allocate a field it does not need.
|
|
74
77
|
*/
|
|
75
78
|
export function terrainFieldForEdit(site, options) {
|
|
76
|
-
return
|
|
79
|
+
return persistedTerrainFieldOf(site) ?? createTerrainField(options);
|
|
77
80
|
}
|
|
78
81
|
/**
|
|
79
82
|
* Encode a field for persistence and prime the read cache with it.
|
|
@@ -31,9 +31,15 @@ export type LiveTerrainStroke = {
|
|
|
31
31
|
*/
|
|
32
32
|
readonly lastPatch: HeightPatch | null;
|
|
33
33
|
};
|
|
34
|
+
export type RemoteLiveTerrainStroke = {
|
|
35
|
+
readonly sourceId: string;
|
|
36
|
+
readonly field: TerrainField;
|
|
37
|
+
readonly lastPatch: HeightPatch;
|
|
38
|
+
};
|
|
34
39
|
type LiveTerrainState = {
|
|
35
40
|
/** Keyed by site node id — a scene can hold more than one site. */
|
|
36
41
|
strokes: Map<string, LiveTerrainStroke>;
|
|
42
|
+
remoteStrokes: Map<string, RemoteLiveTerrainStroke>;
|
|
37
43
|
/**
|
|
38
44
|
* Start a stroke from `field`.
|
|
39
45
|
*
|
|
@@ -56,6 +62,10 @@ type LiveTerrainState = {
|
|
|
56
62
|
/** The live field for a site, or undefined when no stroke is in flight. */
|
|
57
63
|
fieldOf(siteId: string): TerrainField | undefined;
|
|
58
64
|
strokeOf(siteId: string): LiveTerrainStroke | undefined;
|
|
65
|
+
remoteStrokeOf(siteId: string): RemoteLiveTerrainStroke | undefined;
|
|
66
|
+
previewRemote(siteId: string, sourceId: string, field: TerrainField, patch: HeightPatch): void;
|
|
67
|
+
endRemote(siteId: string, sourceId: string): void;
|
|
68
|
+
endRemoteSource(sourceId: string): void;
|
|
59
69
|
/** End the stroke. The caller persists the field first if it wants to keep it. */
|
|
60
70
|
end(siteId: string): void;
|
|
61
71
|
endAll(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-live-terrain.d.ts","sourceRoot":"","sources":["../../src/store/use-live-terrain.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAErE;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;IAC5B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI,CAAA;CACvC,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB,mEAAmE;IACnE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;IACvC;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAAA;IAChD,oEAAoE;IACpE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IACtE,2EAA2E;IAC3E,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAA;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAAA;IACvD,kFAAkF;IAClF,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,MAAM,IAAI,IAAI,CAAA;CACf,CAAA;AAED,QAAA,MAAM,cAAc,+
|
|
1
|
+
{"version":3,"file":"use-live-terrain.d.ts","sourceRoot":"","sources":["../../src/store/use-live-terrain.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAErE;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;IAC5B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI,CAAA;CACvC,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAA;CAChC,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB,mEAAmE;IACnE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;IACvC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAA;IACnD;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAAA;IAChD,oEAAoE;IACpE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IACtE,2EAA2E;IAC3E,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAA;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAAA;IACvD,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS,CAAA;IACnE,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IAC9F,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACjD,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC,kFAAkF;IAClF,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,MAAM,IAAI,IAAI,CAAA;CACf,CAAA;AAED,QAAA,MAAM,cAAc,+EAiEjB,CAAA;AAEH,eAAe,cAAc,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { create } from 'zustand';
|
|
2
2
|
const useLiveTerrain = create((set, get) => ({
|
|
3
3
|
strokes: new Map(),
|
|
4
|
+
remoteStrokes: new Map(),
|
|
4
5
|
begin: (siteId, field) => set((state) => {
|
|
5
6
|
const next = new Map(state.strokes);
|
|
6
7
|
next.set(siteId, { snapshot: field, field, lastPatch: null });
|
|
@@ -17,8 +18,29 @@ const useLiveTerrain = create((set, get) => ({
|
|
|
17
18
|
next.set(siteId, { snapshot: current.snapshot, field, lastPatch: patch });
|
|
18
19
|
return { strokes: next };
|
|
19
20
|
}),
|
|
20
|
-
fieldOf: (siteId) => get().strokes.get(siteId)?.field,
|
|
21
|
+
fieldOf: (siteId) => get().strokes.get(siteId)?.field ?? get().remoteStrokes.get(siteId)?.field,
|
|
21
22
|
strokeOf: (siteId) => get().strokes.get(siteId),
|
|
23
|
+
remoteStrokeOf: (siteId) => get().remoteStrokes.get(siteId),
|
|
24
|
+
previewRemote: (siteId, sourceId, field, patch) => set((state) => {
|
|
25
|
+
const next = new Map(state.remoteStrokes);
|
|
26
|
+
next.set(siteId, { sourceId, field, lastPatch: patch });
|
|
27
|
+
return { remoteStrokes: next };
|
|
28
|
+
}),
|
|
29
|
+
endRemote: (siteId, sourceId) => set((state) => {
|
|
30
|
+
if (state.remoteStrokes.get(siteId)?.sourceId !== sourceId)
|
|
31
|
+
return state;
|
|
32
|
+
const next = new Map(state.remoteStrokes);
|
|
33
|
+
next.delete(siteId);
|
|
34
|
+
return { remoteStrokes: next };
|
|
35
|
+
}),
|
|
36
|
+
endRemoteSource: (sourceId) => set((state) => {
|
|
37
|
+
const next = new Map(state.remoteStrokes);
|
|
38
|
+
for (const [siteId, stroke] of next) {
|
|
39
|
+
if (stroke.sourceId === sourceId)
|
|
40
|
+
next.delete(siteId);
|
|
41
|
+
}
|
|
42
|
+
return next.size === state.remoteStrokes.size ? state : { remoteStrokes: next };
|
|
43
|
+
}),
|
|
22
44
|
end: (siteId) => set((state) => {
|
|
23
45
|
if (!state.strokes.has(siteId))
|
|
24
46
|
return state;
|
|
@@ -26,6 +48,8 @@ const useLiveTerrain = create((set, get) => ({
|
|
|
26
48
|
next.delete(siteId);
|
|
27
49
|
return { strokes: next };
|
|
28
50
|
}),
|
|
29
|
-
endAll: () => set((state) =>
|
|
51
|
+
endAll: () => set((state) => state.strokes.size === 0 && state.remoteStrokes.size === 0
|
|
52
|
+
? state
|
|
53
|
+
: { remoteStrokes: new Map(), strokes: new Map() }),
|
|
30
54
|
}));
|
|
31
55
|
export default useLiveTerrain;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-scene.d.ts","sourceRoot":"","sources":["../../src/store/use-scene.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE1C,OAAO,EAAU,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAA;AAInE,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAoBrE,OAAO,EAEL,aAAa,EACb,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,SAAS,EAA4B,MAAM,iBAAiB,CAAA;
|
|
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
|
@@ -23,6 +23,7 @@ import { getCeilingClampBound } from '../services/storey';
|
|
|
23
23
|
import { computeWallSlabSupport } from '../systems/slab/slab-support';
|
|
24
24
|
import { DEFAULT_WALL_HEIGHT } from '../systems/wall/wall-footprint';
|
|
25
25
|
import { healSceneNodes } from '../utils/heal-scene-graph';
|
|
26
|
+
import { removeRetiredDrawingSheetNodes } from '../utils/retired-scene-nodes';
|
|
26
27
|
import * as nodeActions from './actions/node-actions';
|
|
27
28
|
import { areSceneSnapshotsEqual, getSceneHistoryPauseDepth, notifySceneCommit, pauseSceneHistory, resetSceneHistoryPauseDepth, resumeSceneHistory, } from './history-control';
|
|
28
29
|
import useLiveNodeOverrides from './use-live-node-overrides';
|
|
@@ -468,26 +469,6 @@ function migrateConstructionDimension(node) {
|
|
|
468
469
|
}),
|
|
469
470
|
};
|
|
470
471
|
}
|
|
471
|
-
function removeRetiredDrawingSheets(nodes) {
|
|
472
|
-
const retiredIds = new Set(Object.entries(nodes)
|
|
473
|
-
.filter(([, node]) => node?.type === 'drawing-sheet')
|
|
474
|
-
.map(([id]) => id));
|
|
475
|
-
if (retiredIds.size === 0)
|
|
476
|
-
return;
|
|
477
|
-
for (const id of retiredIds)
|
|
478
|
-
delete nodes[id];
|
|
479
|
-
for (const [id, node] of Object.entries(nodes)) {
|
|
480
|
-
if (!Array.isArray(node?.children))
|
|
481
|
-
continue;
|
|
482
|
-
const children = getStringArray(node.children);
|
|
483
|
-
if (!children.some((childId) => retiredIds.has(childId)))
|
|
484
|
-
continue;
|
|
485
|
-
nodes[id] = {
|
|
486
|
-
...node,
|
|
487
|
-
children: children.filter((childId) => !retiredIds.has(childId)),
|
|
488
|
-
};
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
472
|
function migrateWallAssembly(node) {
|
|
492
473
|
if (!Object.hasOwn(node, 'assemblyLayers'))
|
|
493
474
|
return node;
|
|
@@ -516,8 +497,7 @@ function migrateNodes(nodes) {
|
|
|
516
497
|
// Repair pre-existing corruption (null children, zero-length walls) before
|
|
517
498
|
// any per-type migration runs, so already-saved scenes load cleanly.
|
|
518
499
|
const { nodes: healed } = healSceneNodes(nodes);
|
|
519
|
-
const patchedNodes =
|
|
520
|
-
removeRetiredDrawingSheets(patchedNodes);
|
|
500
|
+
const { nodes: patchedNodes } = removeRetiredDrawingSheetNodes(healed);
|
|
521
501
|
// Scene materials minted while moving legacy wall fields onto `node.slots`;
|
|
522
502
|
// merged into the scene material map by the caller (`setScene`).
|
|
523
503
|
const mintedMaterials = {};
|
|
@@ -1100,22 +1080,24 @@ const useScene = create()(temporal((set, get) => ({
|
|
|
1100
1080
|
});
|
|
1101
1081
|
return; // Scene already loaded
|
|
1102
1082
|
}
|
|
1103
|
-
// Create hierarchy: Site → Building → Level
|
|
1083
|
+
// Create hierarchy: Site → Building → Level. Parent links must be
|
|
1084
|
+
// written explicitly — the schema defaults `parentId` to null, and the
|
|
1085
|
+
// scene authority rejects parent/child asymmetry that the renderer
|
|
1086
|
+
// happily traverses through `children`.
|
|
1087
|
+
const site = SiteNode.parse({});
|
|
1088
|
+
const building = BuildingNode.parse({
|
|
1089
|
+
parentId: site.id,
|
|
1090
|
+
});
|
|
1104
1091
|
const level0 = LevelNode.parse({
|
|
1092
|
+
parentId: building.id,
|
|
1105
1093
|
level: 0,
|
|
1106
1094
|
children: [],
|
|
1107
1095
|
height: 2.5,
|
|
1108
1096
|
});
|
|
1109
|
-
const building = BuildingNode.parse({
|
|
1110
|
-
children: [level0.id],
|
|
1111
|
-
});
|
|
1112
|
-
const site = SiteNode.parse({
|
|
1113
|
-
children: [building.id],
|
|
1114
|
-
});
|
|
1115
1097
|
// Define all nodes flat
|
|
1116
1098
|
const nodes = {
|
|
1117
|
-
[site.id]: site,
|
|
1118
|
-
[building.id]: building,
|
|
1099
|
+
[site.id]: { ...site, children: [building.id] },
|
|
1100
|
+
[building.id]: { ...building, children: [level0.id] },
|
|
1119
1101
|
[level0.id]: level0,
|
|
1120
1102
|
};
|
|
1121
1103
|
// Site is the root
|
|
@@ -9,6 +9,11 @@ export interface HealSceneResult {
|
|
|
9
9
|
* a different node (stale reparent leftovers), plus same-array duplicates.
|
|
10
10
|
*/
|
|
11
11
|
strippedStaleChildRefs: number;
|
|
12
|
+
/**
|
|
13
|
+
* Ids of nodes whose null `parentId` was repaired to the one parent that
|
|
14
|
+
* still claims them via `children`.
|
|
15
|
+
*/
|
|
16
|
+
repairedParentLinkNodeIds: string[];
|
|
12
17
|
}
|
|
13
18
|
/**
|
|
14
19
|
* Returns a healed copy of a `nodes` map. Pure — does not mutate `input`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heal-scene-graph.d.ts","sourceRoot":"","sources":["../../src/utils/heal-scene-graph.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"heal-scene-graph.d.ts","sourceRoot":"","sources":["../../src/utils/heal-scene-graph.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,kDAAkD;IAClD,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,sFAAsF;IACtF,iBAAiB,EAAE,MAAM,CAAA;IACzB;;;OAGG;IACH,sBAAsB,EAAE,MAAM,CAAA;IAC9B;;;OAGG;IACH,yBAAyB,EAAE,MAAM,EAAE,CAAA;CACpC;AAgBD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CAiH9E"}
|
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
// duplicate reference renders the child twice (duplicate React keys in the
|
|
14
14
|
// 2D plan, doubled hosted geometry in 3D). Same-array duplicates are
|
|
15
15
|
// collapsed too.
|
|
16
|
+
// 4. A node with a null `parentId` that exactly one parent still claims via
|
|
17
|
+
// `children` (the legacy site-child flatten and the old default-scene
|
|
18
|
+
// assembler both linked children without writing `parentId`). The editor
|
|
19
|
+
// renders the chain through `children`, but the hosted scene authority
|
|
20
|
+
// validates parent/child symmetry and rejects the whole scene.
|
|
16
21
|
//
|
|
17
22
|
// All are also prevented at the source now; this is the load-time safety net
|
|
18
23
|
// for already-saved scenes.
|
|
@@ -102,5 +107,45 @@ export function healSceneNodes(input) {
|
|
|
102
107
|
}
|
|
103
108
|
nodes[id] = node;
|
|
104
109
|
}
|
|
105
|
-
|
|
110
|
+
// Pass 3: repair null parent links. A node claimed as a child by exactly one
|
|
111
|
+
// parent must point back at it; legacy writers linked `children` without
|
|
112
|
+
// writing `parentId`. Embedded legacy site children claim by their `id` so
|
|
113
|
+
// the flattened flat-map node is repaired too.
|
|
114
|
+
const claimantsByChildId = new Map();
|
|
115
|
+
for (const [id, node] of Object.entries(nodes)) {
|
|
116
|
+
const children = node?.children;
|
|
117
|
+
if (!Array.isArray(children))
|
|
118
|
+
continue;
|
|
119
|
+
for (const child of children) {
|
|
120
|
+
const childId = typeof child === 'string'
|
|
121
|
+
? child
|
|
122
|
+
: child && typeof child === 'object' && typeof child.id === 'string'
|
|
123
|
+
? child.id
|
|
124
|
+
: null;
|
|
125
|
+
if (!childId || !(childId in nodes))
|
|
126
|
+
continue;
|
|
127
|
+
const claimants = claimantsByChildId.get(childId) ?? [];
|
|
128
|
+
claimants.push(id);
|
|
129
|
+
claimantsByChildId.set(childId, claimants);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const repairedParentLinkNodeIds = [];
|
|
133
|
+
for (const [id, node] of Object.entries(nodes)) {
|
|
134
|
+
if (!node || typeof node !== 'object')
|
|
135
|
+
continue;
|
|
136
|
+
if (node.parentId != null)
|
|
137
|
+
continue;
|
|
138
|
+
const claimants = claimantsByChildId.get(id);
|
|
139
|
+
if (claimants?.length !== 1 || claimants[0] === id)
|
|
140
|
+
continue;
|
|
141
|
+
nodes[id] = { ...node, parentId: claimants[0] };
|
|
142
|
+
repairedParentLinkNodeIds.push(id);
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
nodes,
|
|
146
|
+
droppedWallIds,
|
|
147
|
+
strippedChildRefs,
|
|
148
|
+
strippedStaleChildRefs,
|
|
149
|
+
repairedParentLinkNodeIds,
|
|
150
|
+
};
|
|
106
151
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type RetiredSceneNodeMigration<TNode> = {
|
|
2
|
+
nodes: Record<string, TNode>;
|
|
3
|
+
removedNodeIds: ReadonlySet<string>;
|
|
4
|
+
};
|
|
5
|
+
export declare function removeRetiredDrawingSheetNodes<TNode>(nodes: Record<string, TNode>): RetiredSceneNodeMigration<TNode>;
|
|
6
|
+
//# sourceMappingURL=retired-scene-nodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retired-scene-nodes.d.ts","sourceRoot":"","sources":["../../src/utils/retired-scene-nodes.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,yBAAyB,CAAC,KAAK,IAAI;IAC7C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IAC5B,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CACpC,CAAA;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAClD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAC3B,yBAAyB,CAAC,KAAK,CAAC,CAkClC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export function removeRetiredDrawingSheetNodes(nodes) {
|
|
2
|
+
const removedNodeIds = new Set(Object.entries(nodes)
|
|
3
|
+
.filter(([, node]) => {
|
|
4
|
+
return (node !== null &&
|
|
5
|
+
typeof node === 'object' &&
|
|
6
|
+
!Array.isArray(node) &&
|
|
7
|
+
node.type === 'drawing-sheet');
|
|
8
|
+
})
|
|
9
|
+
.map(([id]) => id));
|
|
10
|
+
if (removedNodeIds.size === 0)
|
|
11
|
+
return { nodes, removedNodeIds };
|
|
12
|
+
const migratedNodes = { ...nodes };
|
|
13
|
+
for (const id of removedNodeIds)
|
|
14
|
+
delete migratedNodes[id];
|
|
15
|
+
for (const [id, node] of Object.entries(migratedNodes)) {
|
|
16
|
+
if (!(node !== null && typeof node === 'object' && !Array.isArray(node)))
|
|
17
|
+
continue;
|
|
18
|
+
const children = node.children;
|
|
19
|
+
if (!Array.isArray(children))
|
|
20
|
+
continue;
|
|
21
|
+
if (!children.some((childId) => typeof childId === 'string' && removedNodeIds.has(childId))) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
migratedNodes[id] = {
|
|
25
|
+
...node,
|
|
26
|
+
children: children.filter((childId) => !(typeof childId === 'string' && removedNodeIds.has(childId))),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return { nodes: migratedNodes, removedNodeIds };
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-migrations.d.ts","sourceRoot":"","sources":["../../src/utils/scene-migrations.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,eAAe,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACzE,OAAO,EACL,KAAK,yBAAyB,EAC9B,8BAA8B,GAC/B,MAAM,uBAAuB,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Server-safe scene migrations shared by the client loader and the hosted
|
|
2
|
+
// scene authority. Everything exported here must stay pure data logic with no
|
|
3
|
+
// store, React, or Three.js imports so it can run in Server Components and
|
|
4
|
+
// API routes.
|
|
5
|
+
export { healSceneNodes } from './heal-scene-graph';
|
|
6
|
+
export { removeRetiredDrawingSheetNodes, } from './retired-scene-nodes';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pascal-app/core",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.4",
|
|
4
4
|
"description": "Core library for Pascal 3D building editor",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -16,6 +16,11 @@
|
|
|
16
16
|
"import": "./dist/utils/clone-scene-graph.js",
|
|
17
17
|
"default": "./dist/utils/clone-scene-graph.js"
|
|
18
18
|
},
|
|
19
|
+
"./scene-migrations": {
|
|
20
|
+
"types": "./dist/utils/scene-migrations.d.ts",
|
|
21
|
+
"import": "./dist/utils/scene-migrations.js",
|
|
22
|
+
"default": "./dist/utils/scene-migrations.js"
|
|
23
|
+
},
|
|
19
24
|
"./registry": {
|
|
20
25
|
"types": "./dist/registry/index.d.ts",
|
|
21
26
|
"import": "./dist/registry/index.js",
|