@ifc-lite/viewer 1.17.6 → 1.19.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 +20 -15
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +949 -0
- package/dist/assets/{basketViewActivator-86rgogji.js → basketViewActivator-RZy5c3Td.js} +1 -1
- package/dist/assets/decode-worker-Collf_X_.js +1320 -0
- package/dist/assets/{exporters-CcPS9MK5.js → exporters-BraHBeoi.js} +4194 -3025
- package/dist/assets/{geometry.worker-BFUYA08u.js → geometry.worker-DQEZB2rB.js} +1 -1
- package/dist/assets/ifc-lite_bg-4yUkDRD8.wasm +0 -0
- package/dist/assets/index-0XpVr_S5.css +1 -0
- package/dist/assets/{index-Bfms9I4A.js → index-BOi3BuUI.js} +46423 -31181
- package/dist/assets/index-XwKzDuw6.js +22 -0
- package/dist/assets/{native-bridge-DUyLCMZS.js → native-bridge-CpBeOPQa.js} +1 -1
- package/dist/assets/sandbox-Baez7n-t.js +9682 -0
- package/dist/assets/{server-client-BuZK7OST.js → server-client-BB6cMAXE.js} +1 -1
- package/dist/assets/{wasm-bridge-JsqEGDV8.js → wasm-bridge-CAYCUHbE.js} +1 -1
- package/dist/index.html +6 -6
- package/package.json +11 -10
- package/src/apache-arrow.d.ts +30 -0
- package/src/components/viewer/AddElementPanel.tsx +758 -0
- package/src/components/viewer/BulkPropertyEditor.tsx +7 -0
- package/src/components/viewer/ChatPanel.tsx +64 -2
- package/src/components/viewer/CommandPalette.tsx +56 -7
- package/src/components/viewer/EntityContextMenu.tsx +168 -4
- package/src/components/viewer/ExportChangesButton.tsx +25 -5
- package/src/components/viewer/ExportDialog.tsx +19 -1
- package/src/components/viewer/MainToolbar.tsx +73 -12
- package/src/components/viewer/PointCloudPanel.tsx +174 -0
- package/src/components/viewer/PropertiesPanel.tsx +222 -22
- package/src/components/viewer/SearchInline.tsx +669 -0
- package/src/components/viewer/SearchModal.filter.builder.tsx +766 -0
- package/src/components/viewer/SearchModal.filter.tsx +514 -0
- package/src/components/viewer/SearchModal.text.tsx +388 -0
- package/src/components/viewer/SearchModal.tsx +235 -0
- package/src/components/viewer/ToolOverlays.tsx +5 -0
- package/src/components/viewer/ViewerLayout.tsx +24 -4
- package/src/components/viewer/Viewport.tsx +29 -2
- package/src/components/viewer/ViewportContainer.tsx +45 -5
- package/src/components/viewer/ViewportOverlays.tsx +13 -2
- package/src/components/viewer/annotations/AnnotationDropInput.tsx +203 -0
- package/src/components/viewer/annotations/AnnotationLayer.tsx +287 -0
- package/src/components/viewer/annotations/AnnotationPin.tsx +90 -0
- package/src/components/viewer/annotations/AnnotationPopover.tsx +296 -0
- package/src/components/viewer/bcf/BCFTopicDetail.tsx +1 -1
- package/src/components/viewer/lists/ListPanel.tsx +14 -21
- package/src/components/viewer/properties/RawStepCard.tsx +332 -0
- package/src/components/viewer/properties/RawStepRow.tsx +261 -0
- package/src/components/viewer/properties/ScheduleCard.tsx +224 -0
- package/src/components/viewer/properties/TaskEditCard.tsx +510 -0
- package/src/components/viewer/properties/raw-step-format.ts +193 -0
- package/src/components/viewer/schedule/AnimationSettingsPopover.tsx +542 -0
- package/src/components/viewer/schedule/GanttDependencyArrows.tsx +89 -0
- package/src/components/viewer/schedule/GanttDragTooltip.tsx +48 -0
- package/src/components/viewer/schedule/GanttEmptyState.tsx +97 -0
- package/src/components/viewer/schedule/GanttPanel.tsx +295 -0
- package/src/components/viewer/schedule/GanttTaskBar.tsx +199 -0
- package/src/components/viewer/schedule/GanttTaskTree.tsx +250 -0
- package/src/components/viewer/schedule/GanttTimeline.tsx +305 -0
- package/src/components/viewer/schedule/GanttToolbar.tsx +406 -0
- package/src/components/viewer/schedule/GenerateAdvancedPanel.tsx +147 -0
- package/src/components/viewer/schedule/GenerateScheduleDialog.tsx +392 -0
- package/src/components/viewer/schedule/HeightStrategyPanel.tsx +120 -0
- package/src/components/viewer/schedule/generate-schedule.test.ts +439 -0
- package/src/components/viewer/schedule/generate-schedule.ts +648 -0
- package/src/components/viewer/schedule/schedule-animator.test.ts +452 -0
- package/src/components/viewer/schedule/schedule-animator.ts +488 -0
- package/src/components/viewer/schedule/schedule-selection.test.ts +148 -0
- package/src/components/viewer/schedule/schedule-selection.ts +163 -0
- package/src/components/viewer/schedule/schedule-utils.ts +223 -0
- package/src/components/viewer/schedule/useConstructionSequence.ts +156 -0
- package/src/components/viewer/schedule/useGanttBarDrag.test.ts +90 -0
- package/src/components/viewer/schedule/useGanttBarDrag.ts +305 -0
- package/src/components/viewer/schedule/useGanttSelection3DHighlight.ts +152 -0
- package/src/components/viewer/schedule/useOverlayCompositor.ts +108 -0
- package/src/components/viewer/selectionHandlers.ts +446 -0
- package/src/components/viewer/tools/AddElementOverlay.tsx +581 -0
- package/src/components/viewer/useDuplicateShortcut.ts +77 -0
- package/src/components/viewer/useMouseControls.ts +9 -1
- package/src/components/viewer/usePointCloudLifecycle.ts +64 -0
- package/src/components/viewer/usePointCloudSync.ts +98 -0
- package/src/hooks/ingest/pointCloudIngest.ts +391 -0
- package/src/hooks/ingest/viewerModelIngest.ts +32 -3
- package/src/hooks/useIfcFederation.ts +72 -3
- package/src/hooks/useIfcLoader.ts +89 -13
- package/src/hooks/useKeyboardShortcuts.ts +25 -0
- package/src/hooks/useSandbox.ts +1 -1
- package/src/hooks/useSearchIndex.ts +125 -0
- package/src/index.css +66 -0
- package/src/lib/llm/system-prompt.test.ts +14 -0
- package/src/lib/llm/system-prompt.ts +102 -1
- package/src/lib/llm/types.ts +6 -0
- package/src/lib/recent-files.ts +38 -4
- package/src/lib/scripts/templates/bim-globals.d.ts +136 -114
- package/src/lib/scripts/templates/construction-schedule.ts +223 -0
- package/src/lib/scripts/templates.ts +7 -0
- package/src/lib/search/common-ifc-types.ts +36 -0
- package/src/lib/search/filter-evaluate.test.ts +537 -0
- package/src/lib/search/filter-evaluate.ts +610 -0
- package/src/lib/search/filter-rules.test.ts +119 -0
- package/src/lib/search/filter-rules.ts +198 -0
- package/src/lib/search/filter-schema.test.ts +233 -0
- package/src/lib/search/filter-schema.ts +146 -0
- package/src/lib/search/recent-searches.test.ts +116 -0
- package/src/lib/search/recent-searches.ts +93 -0
- package/src/lib/search/result-export.test.ts +101 -0
- package/src/lib/search/result-export.ts +104 -0
- package/src/lib/search/saved-filters.test.ts +118 -0
- package/src/lib/search/saved-filters.ts +154 -0
- package/src/lib/search/tier0-scan.test.ts +196 -0
- package/src/lib/search/tier0-scan.ts +237 -0
- package/src/lib/search/tier1-index.test.ts +242 -0
- package/src/lib/search/tier1-index.ts +448 -0
- package/src/sdk/adapters/export-adapter.test.ts +434 -1
- package/src/sdk/adapters/export-adapter.ts +404 -1
- package/src/sdk/adapters/export-schedule-splice.test.ts +127 -0
- package/src/sdk/adapters/export-schedule-splice.ts +87 -0
- package/src/sdk/adapters/model-compat.ts +8 -2
- package/src/sdk/adapters/schedule-adapter.ts +73 -0
- package/src/sdk/adapters/store-adapter.ts +201 -0
- package/src/sdk/adapters/visibility-adapter.ts +3 -0
- package/src/sdk/local-backend.ts +16 -8
- package/src/services/desktop-export.ts +3 -1
- package/src/services/desktop-native-metadata.ts +41 -18
- package/src/services/file-dialog.ts +8 -3
- package/src/services/tauri-modules.d.ts +25 -0
- package/src/store/basketVisibleSet.ts +3 -0
- package/src/store/globalId.ts +4 -1
- package/src/store/index.ts +79 -1
- package/src/store/slices/addElementMeshes.ts +365 -0
- package/src/store/slices/addElementSlice.ts +275 -0
- package/src/store/slices/annotationsSlice.test.ts +133 -0
- package/src/store/slices/annotationsSlice.ts +251 -0
- package/src/store/slices/dataSlice.test.ts +23 -4
- package/src/store/slices/dataSlice.ts +1 -1
- package/src/store/slices/modelSlice.test.ts +67 -9
- package/src/store/slices/modelSlice.ts +39 -7
- package/src/store/slices/mutationSlice.ts +964 -3
- package/src/store/slices/overlayCompositor.test.ts +164 -0
- package/src/store/slices/overlaySlice.test.ts +93 -0
- package/src/store/slices/overlaySlice.ts +151 -0
- package/src/store/slices/pinboardSlice.test.ts +6 -1
- package/src/store/slices/playbackSlice.ts +128 -0
- package/src/store/slices/pointCloudSlice.ts +102 -0
- package/src/store/slices/schedule-edit-helpers.test.ts +97 -0
- package/src/store/slices/schedule-edit-helpers.ts +179 -0
- package/src/store/slices/scheduleSlice.test.ts +694 -0
- package/src/store/slices/scheduleSlice.ts +1330 -0
- package/src/store/slices/searchSlice.test.ts +342 -0
- package/src/store/slices/searchSlice.ts +341 -0
- package/src/store/slices/selectionSlice.test.ts +46 -0
- package/src/store/slices/selectionSlice.ts +20 -0
- package/src/store/types.ts +7 -0
- package/src/store.ts +14 -0
- package/vite.config.ts +1 -0
- package/dist/assets/ifc-lite_bg-BINvzoCP.wasm +0 -0
- package/dist/assets/index-_bfZsDCC.css +0 -1
- package/dist/assets/sandbox-C8575tul.js +0 -5951
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Display + parse helpers for the Raw STEP tab.
|
|
7
|
+
*
|
|
8
|
+
* The serialization layer in `@ifc-lite/export` (`serializeStepValue`)
|
|
9
|
+
* is the source of truth for what gets written to disk. The helpers here
|
|
10
|
+
* mirror it on the read side (display) and inverse it on the write side
|
|
11
|
+
* (parse user input) so the round-trip stays predictable for anyone who
|
|
12
|
+
* has seen STEP literals before.
|
|
13
|
+
*
|
|
14
|
+
* Conventions (mirrors the SDK / `StoreEditor` doc-comments):
|
|
15
|
+
* $ / null / empty → JS `null`
|
|
16
|
+
* .T. / .F. → JS `true` / `false`
|
|
17
|
+
* 123 / 1.5 / 1e3 → JS `number`
|
|
18
|
+
* #42 → JS string `"#42"` (STEP exporter writes as-is)
|
|
19
|
+
* .AREA. → JS string `".AREA."`
|
|
20
|
+
* 'foo' → JS string `'foo'` (quotes added by the serializer)
|
|
21
|
+
* (a,b,c) → JS array, recursively
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import type { IfcAttributeValue } from '@ifc-lite/mutations';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Tokenize the inside of a STEP entity body (`,`-separated arguments)
|
|
28
|
+
* with awareness of nested parens and quoted strings. Same semantics
|
|
29
|
+
* as `splitTopLevelArgs` in `@ifc-lite/export` (kept inline here to
|
|
30
|
+
* avoid leaking a private util across the package boundary).
|
|
31
|
+
*/
|
|
32
|
+
function splitTopLevelArgs(text: string): string[] {
|
|
33
|
+
const parts: string[] = [];
|
|
34
|
+
let current = '';
|
|
35
|
+
let depth = 0;
|
|
36
|
+
let inString = false;
|
|
37
|
+
|
|
38
|
+
for (let i = 0; i < text.length; i++) {
|
|
39
|
+
const ch = text[i];
|
|
40
|
+
if (inString) {
|
|
41
|
+
current += ch;
|
|
42
|
+
if (ch === "'") {
|
|
43
|
+
// STEP escapes a single quote by doubling it (`''`).
|
|
44
|
+
if (text[i + 1] === "'") {
|
|
45
|
+
current += text[i + 1];
|
|
46
|
+
i++;
|
|
47
|
+
} else {
|
|
48
|
+
inString = false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
} else if (ch === "'") {
|
|
52
|
+
inString = true;
|
|
53
|
+
current += ch;
|
|
54
|
+
} else if (ch === '(') {
|
|
55
|
+
depth++;
|
|
56
|
+
current += ch;
|
|
57
|
+
} else if (ch === ')') {
|
|
58
|
+
depth--;
|
|
59
|
+
current += ch;
|
|
60
|
+
} else if (ch === ',' && depth === 0) {
|
|
61
|
+
parts.push(current.trim());
|
|
62
|
+
current = '';
|
|
63
|
+
} else {
|
|
64
|
+
current += ch;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (current.trim() || parts.length > 0) parts.push(current.trim());
|
|
68
|
+
return parts;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Read raw positional argument tokens directly from the STEP source
|
|
73
|
+
* buffer for an entity. Returns `null` if the entity body can't be
|
|
74
|
+
* parsed (mismatched parens, no source bytes, …).
|
|
75
|
+
*
|
|
76
|
+
* Each token is the verbatim on-disk literal — `#42` for refs,
|
|
77
|
+
* `.AREA.` for enums, `'My Column'` for strings, `1.5` for numbers.
|
|
78
|
+
* This is the most faithful representation for the "Raw STEP" view
|
|
79
|
+
* and it side-steps the need to round-trip references through the
|
|
80
|
+
* EntityExtractor (which strips the `#` prefix when it parses them
|
|
81
|
+
* into JS numbers).
|
|
82
|
+
*/
|
|
83
|
+
export function extractRawStepTokens(
|
|
84
|
+
buffer: Uint8Array,
|
|
85
|
+
byteOffset: number,
|
|
86
|
+
byteLength: number,
|
|
87
|
+
): string[] | null {
|
|
88
|
+
if (byteLength <= 0) return null;
|
|
89
|
+
const text = new TextDecoder().decode(
|
|
90
|
+
buffer.subarray(byteOffset, byteOffset + byteLength),
|
|
91
|
+
);
|
|
92
|
+
// Match #N=TYPE( ... ) — the trailing `;` is optional in case the
|
|
93
|
+
// ref slice doesn't include it.
|
|
94
|
+
const match = text.match(/^#\d+\s*=\s*[A-Z0-9_]+\(([\s\S]*)\)\s*;?\s*$/i);
|
|
95
|
+
if (!match) return null;
|
|
96
|
+
return splitTopLevelArgs(match[1]);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Serialize an overlay attribute value to the canonical STEP token
|
|
101
|
+
* form. Mirrors `serializeStepValue` in `@ifc-lite/export` for the
|
|
102
|
+
* conventions the StoreEditor / setPositionalAttribute API document.
|
|
103
|
+
*
|
|
104
|
+
* Used to render the displayed value when a positional override
|
|
105
|
+
* exists — the override is held as a JS value (number / string /
|
|
106
|
+
* null / array), but the row UI needs a STEP literal to look right
|
|
107
|
+
* next to the unmodified base tokens.
|
|
108
|
+
*/
|
|
109
|
+
export function serializeStepToken(value: IfcAttributeValue): string {
|
|
110
|
+
if (value === null || value === undefined) return '$';
|
|
111
|
+
if (typeof value === 'boolean') return value ? '.T.' : '.F.';
|
|
112
|
+
if (typeof value === 'number') {
|
|
113
|
+
if (!Number.isFinite(value)) return '$';
|
|
114
|
+
return String(value);
|
|
115
|
+
}
|
|
116
|
+
if (typeof value === 'string') {
|
|
117
|
+
const trimmed = value.trim();
|
|
118
|
+
// Strings tagged as references / enums / wildcards pass through
|
|
119
|
+
// unchanged — the StoreEditor's input convention already keeps
|
|
120
|
+
// them in canonical form.
|
|
121
|
+
if (trimmed === '$' || trimmed === '*') return trimmed;
|
|
122
|
+
if (/^#\d+$/.test(trimmed)) return trimmed;
|
|
123
|
+
if (/^\.[A-Z0-9_]+\.$/i.test(trimmed)) return trimmed.toUpperCase();
|
|
124
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
125
|
+
}
|
|
126
|
+
if (Array.isArray(value)) {
|
|
127
|
+
return `(${value.map(serializeStepToken).join(',')})`;
|
|
128
|
+
}
|
|
129
|
+
return String(value);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Coarse classifier for "is this token safe to inline-edit?" Lists
|
|
134
|
+
* (`(...)`) and typed values (`IFCLABEL(...)`) are display-only —
|
|
135
|
+
* the row UI hides the pen icon for them and tells the user to
|
|
136
|
+
* reach for the script panel.
|
|
137
|
+
*/
|
|
138
|
+
export function isInlineEditableToken(token: string): boolean {
|
|
139
|
+
const t = token.trim();
|
|
140
|
+
if (!t) return true;
|
|
141
|
+
if (t.startsWith('(')) return false;
|
|
142
|
+
if (/^[A-Z][A-Z0-9_]*\(/i.test(t)) return false;
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Parse a user-typed value from the inline editor into the shape
|
|
148
|
+
* expected by `StoreEditor.setPositionalAttribute()`. Mirrors the
|
|
149
|
+
* conventions documented at the top of this file.
|
|
150
|
+
*
|
|
151
|
+
* Returns either `{ value: ... }` on success or `{ error: '...' }` on
|
|
152
|
+
* a clearly-invalid input. Most strings are accepted — this keeps the
|
|
153
|
+
* editor permissive (so e.g. an arbitrary identifier still lands as a
|
|
154
|
+
* quoted STEP string).
|
|
155
|
+
*/
|
|
156
|
+
export function parseRawStepInput(input: string): { value: IfcAttributeValue } | { error: string } {
|
|
157
|
+
const trimmed = input.trim();
|
|
158
|
+
|
|
159
|
+
if (trimmed === '' || trimmed === '$' || trimmed.toLowerCase() === 'null') {
|
|
160
|
+
return { value: null };
|
|
161
|
+
}
|
|
162
|
+
if (trimmed === '.T.' || trimmed === '.t.') return { value: true };
|
|
163
|
+
if (trimmed === '.F.' || trimmed === '.f.') return { value: false };
|
|
164
|
+
|
|
165
|
+
// Reference: keep as-is, the serializer recognises the `#N` prefix.
|
|
166
|
+
if (/^#\d+$/.test(trimmed)) return { value: trimmed };
|
|
167
|
+
|
|
168
|
+
// Enum: normalise to upper-case dot-form.
|
|
169
|
+
if (/^\.[A-Za-z0-9_]+\.$/.test(trimmed)) return { value: trimmed.toUpperCase() };
|
|
170
|
+
|
|
171
|
+
// Number — accept both integer and real notation, including scientific.
|
|
172
|
+
if (/^-?\d+$/.test(trimmed)) return { value: Number.parseInt(trimmed, 10) };
|
|
173
|
+
if (/^-?\d*\.\d+([eE][+-]?\d+)?$/.test(trimmed) || /^-?\d+\.\d*([eE][+-]?\d+)?$/.test(trimmed) || /^-?\d+[eE][+-]?\d+$/.test(trimmed)) {
|
|
174
|
+
const n = Number.parseFloat(trimmed);
|
|
175
|
+
if (Number.isFinite(n)) return { value: n };
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Quoted string: strip the wrapping quotes — `serializeStepValue`
|
|
179
|
+
// re-adds them on export.
|
|
180
|
+
if (trimmed.startsWith("'") && trimmed.endsWith("'") && trimmed.length >= 2) {
|
|
181
|
+
return { value: trimmed.slice(1, -1).replace(/''/g, "'") };
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Lists / typed values: refuse for now. The pen icon is hidden for
|
|
185
|
+
// these anyway, but if a power user pastes a list literal we should
|
|
186
|
+
// flag rather than silently corrupt.
|
|
187
|
+
if (trimmed.startsWith('(') || /^[A-Z][A-Z0-9_]*\(/i.test(trimmed)) {
|
|
188
|
+
return { error: 'Lists and typed values must be edited from the script panel' };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Fallback: treat as a plain string. The serializer will quote it.
|
|
192
|
+
return { value: trimmed };
|
|
193
|
+
}
|