@ifc-lite/viewer 1.19.0 → 1.21.0
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/.turbo/turbo-build.log +59 -43
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +496 -0
- package/dist/assets/basketViewActivator-Bzw51jhm.js +71 -0
- package/dist/assets/{bcf-DOG9_WPX.js → bcf-4K724hw0.js} +18 -18
- package/dist/assets/decode-worker-t2EGKAxO.js +1708 -0
- package/dist/assets/drawing-2d-Bjy8YPrg.js +257 -0
- package/dist/assets/exporters-u0sz2Upj.js +259119 -0
- package/dist/assets/geometry-controller.worker-NH8pZmrU.js +7 -0
- package/dist/assets/geometry.worker-Bp4rW_R1.js +1 -0
- package/dist/assets/ids-B7AXEv7h.js +4067 -0
- package/dist/assets/ifc-lite-DfZHk36-.js +7 -0
- package/dist/assets/ifc-lite_bg-DlKs5-yM.wasm +0 -0
- package/dist/assets/ifc-lite_bg-PqmRe3Ph.wasm +0 -0
- package/dist/assets/index-CSWgTe1s.css +1 -0
- package/dist/assets/{index-BOi3BuUI.js → index-DVNSvEMh.js} +49877 -28410
- package/dist/assets/laz-perf-Cvr_Lepg.js +1 -0
- package/dist/assets/laz-perf-DnSyzVYH.wasm +0 -0
- package/dist/assets/{native-bridge-CpBeOPQa.js → native-bridge-BiD01jI9.js} +2 -2
- package/dist/assets/parser.worker-Bnbrl6gy.js +182 -0
- package/dist/assets/{sandbox-Baez7n-t.js → sandbox-DPD1ROr0.js} +548 -530
- package/dist/assets/{server-client-BB6cMAXE.js → server-client-DP8fMPY9.js} +1 -1
- package/dist/assets/three-CDRZThFA.js +4057 -0
- package/dist/assets/{wasm-bridge-CAYCUHbE.js → wasm-bridge-CErti6zX.js} +1 -1
- package/dist/assets/workerHelpers-CBbWSJmd.js +36 -0
- package/dist/index.html +10 -9
- package/dist/samples/building-architecture.ifc +453 -0
- package/dist/samples/hello-wall.ifc +1054 -0
- package/dist/samples/infra-bridge.ifc +962 -0
- package/index.html +1 -1
- package/package.json +15 -10
- package/public/samples/building-architecture.ifc +453 -0
- package/public/samples/hello-wall.ifc +1054 -0
- package/public/samples/infra-bridge.ifc +962 -0
- package/src/App.tsx +37 -3
- package/src/components/mcp/HeroScene.tsx +876 -0
- package/src/components/mcp/McpLanding.tsx +1318 -0
- package/src/components/mcp/McpPlayground.tsx +524 -0
- package/src/components/mcp/PlaygroundChat.tsx +1097 -0
- package/src/components/mcp/PlaygroundViewer.tsx +815 -0
- package/src/components/mcp/README.md +171 -0
- package/src/components/mcp/data.ts +659 -0
- package/src/components/mcp/playground-dispatcher.ts +1649 -0
- package/src/components/mcp/playground-files.ts +107 -0
- package/src/components/mcp/playground-uploads.ts +122 -0
- package/src/components/mcp/types.ts +65 -0
- package/src/components/mcp/use-mcp-page.ts +109 -0
- package/src/components/viewer/BasketPresentationDock.tsx +3 -0
- package/src/components/viewer/CesiumOverlay.tsx +165 -120
- package/src/components/viewer/DeviationPanel.tsx +172 -0
- package/src/components/viewer/HierarchyPanel.tsx +29 -3
- package/src/components/viewer/HoverTooltip.tsx +5 -0
- package/src/components/viewer/IDSAuditSummary.tsx +389 -0
- package/src/components/viewer/IDSPanel.tsx +80 -26
- package/src/components/viewer/MainToolbar.tsx +79 -7
- package/src/components/viewer/MergeLayersBanner.tsx +108 -0
- package/src/components/viewer/MobileToolbar.tsx +326 -0
- package/src/components/viewer/PointCloudClasses.tsx +111 -0
- package/src/components/viewer/PointCloudLegend.tsx +119 -0
- package/src/components/viewer/PointCloudPanel.tsx +52 -1
- package/src/components/viewer/PropertiesPanel.tsx +37 -6
- package/src/components/viewer/RectSelectionOverlay.tsx +48 -0
- package/src/components/viewer/StatusBar.tsx +14 -0
- package/src/components/viewer/ViewerLayout.tsx +288 -95
- package/src/components/viewer/Viewport.tsx +86 -18
- package/src/components/viewer/ViewportContainer.tsx +60 -15
- package/src/components/viewer/ViewportOverlays.tsx +41 -26
- package/src/components/viewer/mouseHandlerTypes.ts +22 -0
- package/src/components/viewer/properties/GeoreferencingPanel.tsx +77 -8
- package/src/components/viewer/properties/MaterialCard.tsx +2 -2
- package/src/components/viewer/selectionHandlers.ts +41 -0
- package/src/components/viewer/tools/SectionPanel.tsx +181 -24
- package/src/components/viewer/tools/SectionVisualization.tsx +384 -3
- package/src/components/viewer/useAnimationLoop.ts +22 -0
- package/src/components/viewer/useMouseControls.ts +296 -3
- package/src/components/viewer/usePointCloudSync.ts +8 -1
- package/src/components/viewer/useRenderUpdates.ts +21 -1
- package/src/components/viewer/useTouchControls.ts +100 -41
- package/src/generated/mcp-catalog.json +82 -0
- package/src/hooks/federationLoadGate.test.ts +90 -0
- package/src/hooks/federationLoadGate.ts +127 -0
- package/src/hooks/ids/idsDataAccessor.ts +11 -259
- package/src/hooks/ingest/pointCloudIngest.ts +127 -16
- package/src/hooks/useDrawingGeneration.ts +81 -8
- package/src/hooks/useIDS.ts +90 -10
- package/src/hooks/useIfcFederation.ts +94 -16
- package/src/hooks/useIfcLoader.ts +289 -64
- package/src/hooks/useViewerSelectors.ts +10 -0
- package/src/lib/geo/cesium-bridge.ts +84 -67
- package/src/lib/geo/clamp-anchor.test.ts +80 -0
- package/src/lib/geo/clamp-anchor.ts +57 -0
- package/src/lib/geo/effective-georef.test.ts +79 -1
- package/src/lib/geo/effective-georef.ts +83 -0
- package/src/lib/geo/reproject.ts +26 -13
- package/src/lib/geo/terrain-elevation.ts +166 -0
- package/src/lib/lens/adapter.ts +1 -1
- package/src/lib/llm/context-builder.ts +1 -1
- package/src/lib/perf/memoryAccounting.test.ts +92 -0
- package/src/lib/perf/memoryAccounting.ts +235 -0
- package/src/sdk/adapters/mutation-view.ts +1 -1
- package/src/store/constants.ts +39 -2
- package/src/store/index.ts +6 -1
- package/src/store/slices/cesiumSlice.ts +1 -1
- package/src/store/slices/idsSlice.ts +24 -0
- package/src/store/slices/loadingSlice.ts +12 -0
- package/src/store/slices/pointCloudSlice.ts +72 -1
- package/src/store/slices/sectionSlice.test.ts +590 -1
- package/src/store/slices/sectionSlice.ts +344 -17
- package/src/store/slices/uiSlice.merge-layers.test.ts +217 -0
- package/src/store/slices/uiSlice.ts +60 -2
- package/src/store/types.ts +42 -0
- package/src/store.ts +13 -0
- package/src/utils/acquireFileBuffer.test.ts +231 -0
- package/src/utils/acquireFileBuffer.ts +128 -0
- package/src/utils/ifcConfig.ts +24 -0
- package/src/utils/nativeSpatialDataStore.ts +20 -2
- package/src/utils/spatialHierarchy.test.ts +116 -0
- package/src/utils/spatialHierarchy.ts +23 -0
- package/tailwind.config.js +5 -0
- package/tsconfig.json +1 -0
- package/vite.config.ts +12 -0
- package/dist/assets/basketViewActivator-RZy5c3Td.js +0 -1
- package/dist/assets/decode-worker-Collf_X_.js +0 -1320
- package/dist/assets/drawing-2d-DoxKMqbO.js +0 -257
- package/dist/assets/exporters-BraHBeoi.js +0 -81583
- package/dist/assets/geometry.worker-DQEZB2rB.js +0 -1
- package/dist/assets/ids-DQ5jY0E8.js +0 -1
- package/dist/assets/ifc-lite_bg-4yUkDRD8.wasm +0 -0
- package/dist/assets/index-0XpVr_S5.css +0 -1
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import type { StateCreator } from 'zustand';
|
|
12
12
|
import type {
|
|
13
|
+
IDSAuditReport,
|
|
13
14
|
IDSDocument,
|
|
14
15
|
IDSValidationReport,
|
|
15
16
|
IDSSpecificationResult,
|
|
@@ -40,6 +41,15 @@ export type IDSFilterMode = 'all' | 'failed' | 'passed';
|
|
|
40
41
|
export interface IDSSliceState {
|
|
41
42
|
/** Loaded IDS document */
|
|
42
43
|
idsDocument: IDSDocument | null;
|
|
44
|
+
/**
|
|
45
|
+
* Audit report for the loaded IDS document itself — flags authoring
|
|
46
|
+
* issues (missing attributes, invalid IFC entity references, regex
|
|
47
|
+
* errors, etc.). Distinct from `idsValidationReport`, which describes
|
|
48
|
+
* how an IFC model conforms to the IDS.
|
|
49
|
+
*/
|
|
50
|
+
idsAuditReport: IDSAuditReport | null;
|
|
51
|
+
/** Whether the audit pipeline is currently running. */
|
|
52
|
+
idsAuditing: boolean;
|
|
43
53
|
/** Validation report after running validation */
|
|
44
54
|
idsValidationReport: IDSValidationReport | null;
|
|
45
55
|
/** Currently active specification (for filtering results) */
|
|
@@ -71,6 +81,10 @@ export interface IDSSlice extends IDSSliceState {
|
|
|
71
81
|
setIdsDocument: (document: IDSDocument | null) => void;
|
|
72
82
|
clearIdsDocument: () => void;
|
|
73
83
|
|
|
84
|
+
// Audit actions
|
|
85
|
+
setIdsAuditReport: (report: IDSAuditReport | null) => void;
|
|
86
|
+
setIdsAuditing: (auditing: boolean) => void;
|
|
87
|
+
|
|
74
88
|
// Validation actions
|
|
75
89
|
setIdsValidationReport: (report: IDSValidationReport | null) => void;
|
|
76
90
|
clearIdsValidationReport: () => void;
|
|
@@ -158,6 +172,8 @@ function buildEntityIdSets(
|
|
|
158
172
|
export const createIdsSlice: StateCreator<IDSSlice, [], [], IDSSlice> = (set, get) => ({
|
|
159
173
|
// Initial state
|
|
160
174
|
idsDocument: null,
|
|
175
|
+
idsAuditReport: null,
|
|
176
|
+
idsAuditing: false,
|
|
161
177
|
idsValidationReport: null,
|
|
162
178
|
idsActiveSpecificationId: null,
|
|
163
179
|
idsActiveEntityId: null,
|
|
@@ -175,6 +191,9 @@ export const createIdsSlice: StateCreator<IDSSlice, [], [], IDSSlice> = (set, ge
|
|
|
175
191
|
setIdsDocument: (idsDocument) =>
|
|
176
192
|
set({
|
|
177
193
|
idsDocument,
|
|
194
|
+
// Loading a new document invalidates any previous audit/validation
|
|
195
|
+
// results — they were tied to a specific document instance.
|
|
196
|
+
idsAuditReport: null,
|
|
178
197
|
idsValidationReport: null,
|
|
179
198
|
idsActiveSpecificationId: null,
|
|
180
199
|
idsActiveEntityId: null,
|
|
@@ -186,6 +205,7 @@ export const createIdsSlice: StateCreator<IDSSlice, [], [], IDSSlice> = (set, ge
|
|
|
186
205
|
clearIdsDocument: () =>
|
|
187
206
|
set({
|
|
188
207
|
idsDocument: null,
|
|
208
|
+
idsAuditReport: null,
|
|
189
209
|
idsValidationReport: null,
|
|
190
210
|
idsActiveSpecificationId: null,
|
|
191
211
|
idsActiveEntityId: null,
|
|
@@ -194,6 +214,10 @@ export const createIdsSlice: StateCreator<IDSSlice, [], [], IDSSlice> = (set, ge
|
|
|
194
214
|
idsPassedEntityIds: new Set(),
|
|
195
215
|
}),
|
|
196
216
|
|
|
217
|
+
// Audit actions
|
|
218
|
+
setIdsAuditReport: (idsAuditReport) => set({ idsAuditReport }),
|
|
219
|
+
setIdsAuditing: (idsAuditing) => set({ idsAuditing }),
|
|
220
|
+
|
|
197
221
|
// Validation actions
|
|
198
222
|
setIdsValidationReport: (report) => {
|
|
199
223
|
const { failed, passed } = buildEntityIdSets(report);
|
|
@@ -16,6 +16,15 @@ export interface LoadingSlice {
|
|
|
16
16
|
geometryProgress: { phase: string; percent: number; indeterminate?: boolean } | null;
|
|
17
17
|
metadataProgress: { phase: string; percent: number; indeterminate?: boolean } | null;
|
|
18
18
|
error: string | null;
|
|
19
|
+
/**
|
|
20
|
+
* Cancellation hook for an in-flight long-running operation (e.g.
|
|
21
|
+
* streaming a 100M-point scan). UI components can show a Cancel
|
|
22
|
+
* button while this is non-null. The loader hooks register the
|
|
23
|
+
* canceller after starting the stream and clear it on success /
|
|
24
|
+
* error. Kept on the loading slice (not its own slice) since it
|
|
25
|
+
* tracks lifecycle alongside `progress`.
|
|
26
|
+
*/
|
|
27
|
+
activeStreamCanceller: (() => void) | null;
|
|
19
28
|
|
|
20
29
|
// Actions
|
|
21
30
|
setLoading: (loading: boolean) => void;
|
|
@@ -24,6 +33,7 @@ export interface LoadingSlice {
|
|
|
24
33
|
setGeometryProgress: (progress: { phase: string; percent: number; indeterminate?: boolean } | null) => void;
|
|
25
34
|
setMetadataProgress: (progress: { phase: string; percent: number; indeterminate?: boolean } | null) => void;
|
|
26
35
|
setError: (error: string | null) => void;
|
|
36
|
+
setActiveStreamCanceller: (cancel: (() => void) | null) => void;
|
|
27
37
|
}
|
|
28
38
|
|
|
29
39
|
export const createLoadingSlice: StateCreator<LoadingSlice, [], [], LoadingSlice> = (set) => ({
|
|
@@ -34,6 +44,7 @@ export const createLoadingSlice: StateCreator<LoadingSlice, [], [], LoadingSlice
|
|
|
34
44
|
geometryProgress: null,
|
|
35
45
|
metadataProgress: null,
|
|
36
46
|
error: null,
|
|
47
|
+
activeStreamCanceller: null,
|
|
37
48
|
|
|
38
49
|
// Actions
|
|
39
50
|
setLoading: (loading) => set({ loading }),
|
|
@@ -42,4 +53,5 @@ export const createLoadingSlice: StateCreator<LoadingSlice, [], [], LoadingSlice
|
|
|
42
53
|
setGeometryProgress: (geometryProgress) => set({ geometryProgress }),
|
|
43
54
|
setMetadataProgress: (metadataProgress) => set({ metadataProgress }),
|
|
44
55
|
setError: (error) => set({ error }),
|
|
56
|
+
setActiveStreamCanceller: (activeStreamCanceller) => set({ activeStreamCanceller }),
|
|
45
57
|
});
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import type { StateCreator } from 'zustand';
|
|
14
14
|
|
|
15
|
-
export type PointColorModeUi = 'rgb' | 'classification' | 'intensity' | 'height' | 'fixed';
|
|
15
|
+
export type PointColorModeUi = 'rgb' | 'classification' | 'intensity' | 'height' | 'fixed' | 'deviation';
|
|
16
16
|
export type PointSizeModeUi = 'fixed-px' | 'adaptive-world' | 'attenuated';
|
|
17
17
|
|
|
18
18
|
export interface PointCloudSlice {
|
|
@@ -31,6 +31,35 @@ export interface PointCloudSlice {
|
|
|
31
31
|
pointCloudEdlEnabled: boolean;
|
|
32
32
|
/** EDL strength multiplier. 0..3, default 1. */
|
|
33
33
|
pointCloudEdlStrength: number;
|
|
34
|
+
/**
|
|
35
|
+
* Per-ASPRS-class visibility bitmask (32 bits = covers classes
|
|
36
|
+
* 0..31, the LAS 1.4 standard range). Bit `i` set → class `i`
|
|
37
|
+
* visible. Default `0xFFFFFFFF` (all visible). Only point clouds
|
|
38
|
+
* carry classifications; meshes ignore this.
|
|
39
|
+
*/
|
|
40
|
+
pointCloudClassMask: number;
|
|
41
|
+
/**
|
|
42
|
+
* Stride-cull factor for the splat shader. 1 = render every point,
|
|
43
|
+
* N>1 = render every Nth point. Used by the section-plane slider's
|
|
44
|
+
* drag-preview path so dragging over a 100M-point scan stays
|
|
45
|
+
* responsive. Defaults to 1 (full density).
|
|
46
|
+
*/
|
|
47
|
+
pointCloudPreviewStride: number;
|
|
48
|
+
/**
|
|
49
|
+
* BIM↔scan deviation heatmap range. `centerOffset` shifts the
|
|
50
|
+
* "white" point off zero (handy when a scan has a global offset
|
|
51
|
+
* from the model); `halfRange` is the metres mapped to ±1 on the
|
|
52
|
+
* blue-white-red ramp. Defaults to (0, 0.05) — ±5cm.
|
|
53
|
+
*/
|
|
54
|
+
pointCloudDeviationCenterOffset: number;
|
|
55
|
+
pointCloudDeviationHalfRange: number;
|
|
56
|
+
/**
|
|
57
|
+
* True once `Renderer.computeDeviations` has populated the deviation
|
|
58
|
+
* buffers for the current point cloud + mesh set. UI gates the
|
|
59
|
+
* "Deviation" colour-mode option on this flag so users don't get a
|
|
60
|
+
* confusing all-blue rendering when nothing has been computed.
|
|
61
|
+
*/
|
|
62
|
+
pointCloudDeviationComputed: boolean;
|
|
34
63
|
/**
|
|
35
64
|
* Best-effort count of point cloud assets currently uploaded to the
|
|
36
65
|
* renderer. Updated by ingest paths; UI uses it to show/hide the
|
|
@@ -45,6 +74,14 @@ export interface PointCloudSlice {
|
|
|
45
74
|
setPointCloudRoundShape: (enabled: boolean) => void;
|
|
46
75
|
setPointCloudEdlEnabled: (enabled: boolean) => void;
|
|
47
76
|
setPointCloudEdlStrength: (strength: number) => void;
|
|
77
|
+
setPointCloudClassMask: (mask: number) => void;
|
|
78
|
+
/** Toggle a single ASPRS class. `classId` is clamped to 0..31. */
|
|
79
|
+
togglePointCloudClass: (classId: number) => void;
|
|
80
|
+
/** Set the stride-cull factor (1 = full density). */
|
|
81
|
+
setPointCloudPreviewStride: (stride: number) => void;
|
|
82
|
+
setPointCloudDeviationCenterOffset: (m: number) => void;
|
|
83
|
+
setPointCloudDeviationHalfRange: (m: number) => void;
|
|
84
|
+
setPointCloudDeviationComputed: (computed: boolean) => void;
|
|
48
85
|
setPointCloudAssetCount: (count: number) => void;
|
|
49
86
|
incrementPointCloudAssetCount: (n?: number) => void;
|
|
50
87
|
}
|
|
@@ -67,6 +104,14 @@ export const POINT_CLOUD_DEFAULTS = {
|
|
|
67
104
|
pointCloudRoundShape: true,
|
|
68
105
|
pointCloudEdlEnabled: true,
|
|
69
106
|
pointCloudEdlStrength: 1,
|
|
107
|
+
// 0xFFFFFFFF — all 32 classes visible. Stored as `-1 >>> 0` to
|
|
108
|
+
// keep the value as an unsigned 32-bit integer; JS doesn't have
|
|
109
|
+
// a u32 literal type so we round-trip through `>>> 0`.
|
|
110
|
+
pointCloudClassMask: 0xFFFFFFFF,
|
|
111
|
+
pointCloudPreviewStride: 1,
|
|
112
|
+
pointCloudDeviationCenterOffset: 0,
|
|
113
|
+
pointCloudDeviationHalfRange: 0.05,
|
|
114
|
+
pointCloudDeviationComputed: false,
|
|
70
115
|
pointCloudAssetCount: 0,
|
|
71
116
|
} as const;
|
|
72
117
|
|
|
@@ -91,6 +136,32 @@ export const createPointCloudSlice: StateCreator<PointCloudSlice, [], [], PointC
|
|
|
91
136
|
setPointCloudEdlStrength: (strength) => set({
|
|
92
137
|
pointCloudEdlStrength: Number.isFinite(strength) ? Math.max(0, Math.min(3, strength)) : 1,
|
|
93
138
|
}),
|
|
139
|
+
setPointCloudClassMask: (mask) => set({
|
|
140
|
+
// Coerce through `>>> 0` to keep the stored value as an unsigned
|
|
141
|
+
// 32-bit integer; non-finite / negative inputs reset to "all on".
|
|
142
|
+
pointCloudClassMask: Number.isFinite(mask) ? (mask >>> 0) : 0xFFFFFFFF,
|
|
143
|
+
}),
|
|
144
|
+
togglePointCloudClass: (classId) => set((s) => {
|
|
145
|
+
const c = Math.max(0, Math.min(31, classId | 0));
|
|
146
|
+
const bit = 1 << c;
|
|
147
|
+
// XOR flips the bit; coerce through `>>> 0` so the stored value
|
|
148
|
+
// stays in the unsigned 32-bit range.
|
|
149
|
+
return { pointCloudClassMask: (s.pointCloudClassMask ^ bit) >>> 0 };
|
|
150
|
+
}),
|
|
151
|
+
setPointCloudPreviewStride: (stride) => set({
|
|
152
|
+
pointCloudPreviewStride: Number.isFinite(stride)
|
|
153
|
+
? Math.max(1, Math.min(256, Math.floor(stride) || 1))
|
|
154
|
+
: 1,
|
|
155
|
+
}),
|
|
156
|
+
setPointCloudDeviationCenterOffset: (m) => set({
|
|
157
|
+
pointCloudDeviationCenterOffset: Number.isFinite(m) ? m : 0,
|
|
158
|
+
}),
|
|
159
|
+
setPointCloudDeviationHalfRange: (m) => set({
|
|
160
|
+
// halfRange must stay strictly positive — a zero or negative value
|
|
161
|
+
// would NaN the GPU ramp's division. Clamp to 0.1 mm minimum.
|
|
162
|
+
pointCloudDeviationHalfRange: Number.isFinite(m) ? Math.max(1e-4, m) : 0.05,
|
|
163
|
+
}),
|
|
164
|
+
setPointCloudDeviationComputed: (computed) => set({ pointCloudDeviationComputed: computed }),
|
|
94
165
|
setPointCloudAssetCount: (count) => set({
|
|
95
166
|
pointCloudAssetCount: Number.isFinite(count) ? Math.max(0, count) : 0,
|
|
96
167
|
}),
|