@ifc-lite/viewer 1.17.6 → 1.18.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 +17 -14
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +513 -0
- package/dist/assets/{basketViewActivator-86rgogji.js → basketViewActivator-Cm1QEk_R.js} +1 -1
- package/dist/assets/{exporters-CcPS9MK5.js → exporters-B_OBqIyD.js} +3235 -2648
- package/dist/assets/{geometry.worker-BFUYA08u.js → geometry.worker-xHHy-9DV.js} +1 -1
- package/dist/assets/{ifc-lite_bg-BINvzoCP.wasm → ifc-lite_bg-ADjKXSms.wasm} +0 -0
- package/dist/assets/{index-Bfms9I4A.js → index-BKq-M3Mk.js} +44124 -30920
- package/dist/assets/index-COnQRuqY.css +1 -0
- package/dist/assets/{native-bridge-DUyLCMZS.js → native-bridge-SHXiQwFW.js} +1 -1
- package/dist/assets/sandbox-jez21HtV.js +9627 -0
- package/dist/assets/{server-client-BuZK7OST.js → server-client-ncOQVNso.js} +1 -1
- package/dist/assets/{wasm-bridge-JsqEGDV8.js → wasm-bridge-DyfBSB8z.js} +1 -1
- package/dist/index.html +6 -6
- package/package.json +10 -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 +69 -10
- 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 +11 -1
- package/src/components/viewer/ViewportContainer.tsx +2 -0
- 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 +540 -0
- package/src/components/viewer/useDuplicateShortcut.ts +77 -0
- package/src/components/viewer/useMouseControls.ts +9 -1
- package/src/hooks/useIfcLoader.ts +22 -10
- 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 +4 -1
- 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 +70 -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/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.ts +14 -0
- package/dist/assets/index-_bfZsDCC.css +0 -1
- package/dist/assets/sandbox-C8575tul.js +0 -5951
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
> @ifc-lite/viewer@1.
|
|
2
|
+
> @ifc-lite/viewer@1.18.0 build /home/runner/work/ifc-lite/ifc-lite/apps/viewer
|
|
3
3
|
> vite build
|
|
4
4
|
|
|
5
5
|
[36mvite v5.4.21 [32mbuilding for production...[36m[39m
|
|
6
6
|
transforming...
|
|
7
|
-
[32m✓[39m
|
|
7
|
+
[32m✓[39m 4152 modules transformed.
|
|
8
8
|
../../node_modules/.pnpm/protobufjs@8.0.0/node_modules/protobufjs/dist/minimal/protobuf.js (662:18): Use of eval in "../../node_modules/.pnpm/protobufjs@8.0.0/node_modules/protobufjs/dist/minimal/protobuf.js" is strongly discouraged as it poses security risks and may cause issues with minification.
|
|
9
9
|
rendering chunks...
|
|
10
10
|
[1m[33m[plugin:vite:reporter][39m[22m [33m[plugin vite:reporter]
|
|
11
|
-
(!) /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/desktop-cache.ts is dynamically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/cacheService.ts but also statically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/desktop-native-metadata.ts, dynamic import will not move module into another chunk.
|
|
11
|
+
(!) /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/desktop-cache.ts is dynamically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useIfcLoader.ts, /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/cacheService.ts but also statically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/services/desktop-native-metadata.ts, dynamic import will not move module into another chunk.
|
|
12
|
+
[39m
|
|
13
|
+
[1m[33m[plugin:vite:reporter][39m[22m [33m[plugin vite:reporter]
|
|
14
|
+
(!) /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/selectionHandlers.ts is dynamically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/hooks/useKeyboardShortcuts.ts but also statically imported by /home/runner/work/ifc-lite/ifc-lite/apps/viewer/src/components/viewer/useMouseControls.ts, dynamic import will not move module into another chunk.
|
|
12
15
|
[39m
|
|
13
16
|
computing gzip size...
|
|
14
17
|
[2mdist/[22m[32mindex.html [39m[1m[2m 3.66 kB[22m[1m[22m[2m │ gzip: 1.23 kB[22m
|
|
15
|
-
[2mdist/[22m[2massets/[22m[32mgeometry.worker-
|
|
18
|
+
[2mdist/[22m[2massets/[22m[32mgeometry.worker-xHHy-9DV.js [39m[1m[2m 42.60 kB[22m[1m[22m
|
|
16
19
|
[2mdist/[22m[2massets/[22m[32memscripten-module-NWak2PoB.wasm [39m[1m[2m 518.88 kB[22m[1m[22m
|
|
17
|
-
[2mdist/[22m[2massets/[22m[32mifc-lite_bg-
|
|
20
|
+
[2mdist/[22m[2massets/[22m[32mifc-lite_bg-ADjKXSms.wasm [39m[1m[2m 1,050.82 kB[22m[1m[22m
|
|
18
21
|
[2mdist/[22m[2massets/[22m[32memscripten-module-CGIn_cMh.wasm [39m[1m[2m 1,070.86 kB[22m[1m[22m
|
|
19
22
|
[2mdist/[22m[2massets/[22m[32memscripten-module-DYvzWiHh.wasm [39m[1m[2m 1,561.30 kB[22m[1m[22m
|
|
20
23
|
[2mdist/[22m[2massets/[22m[32marrow2_bg-4Y7xYo54.wasm [39m[1m[2m 5,000.39 kB[22m[1m[22m
|
|
@@ -22,32 +25,32 @@ computing gzip size...
|
|
|
22
25
|
[2mdist/[22m[2massets/[22m[32memscripten-module-BTRCZGcB.wasm [39m[1m[2m 6,623.52 kB[22m[1m[22m
|
|
23
26
|
[2mdist/[22m[2massets/[22m[32mesbuild-Cpd5nU_H.wasm [39m[1m[2m13,524.82 kB[22m[1m[22m
|
|
24
27
|
[2mdist/[22m[2massets/[22m[35mcesium-ADbP7waU.css [39m[1m[2m 24.30 kB[22m[1m[22m[2m │ gzip: 5.49 kB[22m
|
|
25
|
-
[2mdist/[22m[2massets/[22m[35mindex-
|
|
28
|
+
[2mdist/[22m[2massets/[22m[35mindex-COnQRuqY.css [39m[1m[2m 227.78 kB[22m[1m[22m[2m │ gzip: 33.44 kB[22m
|
|
26
29
|
[2mdist/[22m[2massets/[22m[36mtauri-dialog-stub-r7Wksg7o.js [39m[1m[2m 0.05 kB[22m[1m[22m[2m │ gzip: 0.07 kB[22m
|
|
27
30
|
[2mdist/[22m[2massets/[22m[36mesbuild-COv63sf-.js [39m[1m[2m 0.06 kB[22m[1m[22m[2m │ gzip: 0.08 kB[22m
|
|
28
31
|
[2mdist/[22m[2massets/[22m[36mtauri-core-stub-D8Fa-u43.js [39m[1m[2m 0.11 kB[22m[1m[22m[2m │ gzip: 0.12 kB[22m
|
|
29
32
|
[2mdist/[22m[2massets/[22m[36mtauri-fs-stub-BdeRC7aK.js [39m[1m[2m 0.13 kB[22m[1m[22m[2m │ gzip: 0.13 kB[22m
|
|
30
|
-
[2mdist/[22m[2massets/[22m[36mbasketViewActivator-
|
|
33
|
+
[2mdist/[22m[2massets/[22m[36mbasketViewActivator-Cm1QEk_R.js [39m[1m[2m 1.13 kB[22m[1m[22m[2m │ gzip: 0.60 kB[22m
|
|
31
34
|
[2mdist/[22m[2massets/[22m[36mevent-DIOks52T.js [39m[1m[2m 1.42 kB[22m[1m[22m[2m │ gzip: 0.66 kB[22m
|
|
32
|
-
[2mdist/[22m[2massets/[22m[36mwasm-bridge-
|
|
35
|
+
[2mdist/[22m[2massets/[22m[36mwasm-bridge-DyfBSB8z.js [39m[1m[2m 1.66 kB[22m[1m[22m[2m │ gzip: 0.80 kB[22m
|
|
33
36
|
[2mdist/[22m[2massets/[22m[36mifc-cache-BAN4vcd4.js [39m[1m[2m 2.77 kB[22m[1m[22m[2m │ gzip: 0.94 kB[22m
|
|
34
37
|
[2mdist/[22m[2massets/[22m[36mffi-DlhRHxHv.js [39m[1m[2m 6.14 kB[22m[1m[22m[2m │ gzip: 0.98 kB[22m
|
|
35
38
|
[2mdist/[22m[2massets/[22m[36mlens-CSASnhAL.js [39m[1m[2m 9.07 kB[22m[1m[22m[2m │ gzip: 2.81 kB[22m
|
|
36
39
|
[2mdist/[22m[2massets/[22m[36memscripten-module.browser-CY5t0Vfq.js [39m[1m[2m 12.70 kB[22m[1m[22m[2m │ gzip: 5.09 kB[22m
|
|
37
|
-
[2mdist/[22m[2massets/[22m[36mnative-bridge-
|
|
40
|
+
[2mdist/[22m[2massets/[22m[36mnative-bridge-SHXiQwFW.js [39m[1m[2m 18.70 kB[22m[1m[22m[2m │ gzip: 3.80 kB[22m
|
|
38
41
|
[2mdist/[22m[2massets/[22m[36mparquet-CEXmQNRO.js [39m[1m[2m 29.67 kB[22m[1m[22m[2m │ gzip: 6.89 kB[22m
|
|
39
|
-
[2mdist/[22m[2massets/[22m[36mserver-client-
|
|
42
|
+
[2mdist/[22m[2massets/[22m[36mserver-client-ncOQVNso.js [39m[1m[2m 31.43 kB[22m[1m[22m[2m │ gzip: 7.06 kB[22m
|
|
40
43
|
[2mdist/[22m[2massets/[22m[36mbcf-DOG9_WPX.js [39m[1m[2m 40.76 kB[22m[1m[22m[2m │ gzip: 12.67 kB[22m
|
|
41
44
|
[2mdist/[22m[2massets/[22m[36mids-DQ5jY0E8.js [39m[1m[2m 57.15 kB[22m[1m[22m[2m │ gzip: 12.98 kB[22m
|
|
42
45
|
[2mdist/[22m[2massets/[22m[36mbrowser-C5TFR7sH.js [39m[1m[2m 67.65 kB[22m[1m[22m[2m │ gzip: 18.94 kB[22m
|
|
43
46
|
[2mdist/[22m[2massets/[22m[36mdrawing-2d-DoxKMqbO.js [39m[1m[2m 71.45 kB[22m[1m[22m[2m │ gzip: 20.98 kB[22m
|
|
44
47
|
[2mdist/[22m[2massets/[22m[36mzip-DBEtpeu6.js [39m[1m[2m 97.03 kB[22m[1m[22m[2m │ gzip: 30.09 kB[22m
|
|
45
48
|
[2mdist/[22m[2massets/[22m[36marrow-CZ5kQ26f.js [39m[1m[2m 208.84 kB[22m[1m[22m[2m │ gzip: 50.09 kB[22m
|
|
46
|
-
[2mdist/[22m[2massets/[22m[36msandbox-
|
|
49
|
+
[2mdist/[22m[2massets/[22m[36msandbox-jez21HtV.js [39m[1m[2m 384.96 kB[22m[1m[22m[2m │ gzip: 62.02 kB[22m
|
|
47
50
|
[2mdist/[22m[2massets/[22m[36mmaplibre-gl-CGLcoNXc.js [39m[1m[2m 1,046.19 kB[22m[1m[22m[2m │ gzip: 282.97 kB[22m
|
|
48
|
-
[2mdist/[22m[2massets/[22m[36mexporters-
|
|
51
|
+
[2mdist/[22m[2massets/[22m[36mexporters-B_OBqIyD.js [39m[1m[2m 2,889.87 kB[22m[1m[22m[2m │ gzip: 157.97 kB[22m
|
|
49
52
|
[2mdist/[22m[2massets/[22m[36mepsg-index.generated-BjJrt_0S.js [39m[1m[2m 4,284.21 kB[22m[1m[22m[2m │ gzip: 440.44 kB[22m
|
|
50
|
-
[2mdist/[22m[2massets/[22m[36mindex-
|
|
53
|
+
[2mdist/[22m[2massets/[22m[36mindex-BKq-M3Mk.js [39m[1m[2m 5,258.30 kB[22m[1m[22m[2m │ gzip: 949.82 kB[22m
|
|
51
54
|
[2mdist/[22m[2massets/[22m[36mcesium-DUOzBlqv.js [39m[1m[2m 5,543.11 kB[22m[1m[22m[2m │ gzip: 1,373.81 kB[22m
|
|
52
55
|
[36m[vite-plugin-static-copy][39m [32mCopied 4 items.[39m
|
|
53
|
-
[32m✓ built in
|
|
56
|
+
[32m✓ built in 55.14s[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,518 @@
|
|
|
1
1
|
# @ifc-lite/viewer
|
|
2
2
|
|
|
3
|
+
## 1.18.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#598](https://github.com/louistrue/ifc-lite/pull/598) [`25c9877`](https://github.com/louistrue/ifc-lite/commit/25c9877969d2dcccb9c4e61f57b188cbf5fbbc3c) Thanks [@louistrue](https://github.com/louistrue)! - Add Element tool — instant 3D appearance, off-surface placement, 3D ghost preview.
|
|
8
|
+
|
|
9
|
+
Three UX-blocker fixes that turn the Add Element tool into a real
|
|
10
|
+
authoring surface (previously every drop emitted STEP into the overlay
|
|
11
|
+
but the user saw nothing in the 3D scene until export+reparse).
|
|
12
|
+
|
|
13
|
+
- **Instant 3D appearance.** Every `add*` action now also builds a
|
|
14
|
+
renderer-frame mesh for the new element and injects it via the
|
|
15
|
+
same `appendGeometryBatch` action `duplicateEntity` uses. Walls,
|
|
16
|
+
beams, and members are oriented thickness-extruded boxes;
|
|
17
|
+
columns, doors, and windows are axis-aligned boxes;
|
|
18
|
+
slabs / roofs / plates / spaces are polygon extrusions (with fan
|
|
19
|
+
triangulation good enough for typical room shapes). Storey
|
|
20
|
+
elevation is read from the spatial hierarchy so multi-storey
|
|
21
|
+
placements drop on the right floor. The new mesh is tagged with
|
|
22
|
+
the federation-aware globalId so picking + selection work
|
|
23
|
+
immediately and the property panel opens on the new entity.
|
|
24
|
+
- **Off-surface placement.** A new
|
|
25
|
+
`raycastStoreyFloor()` helper unprojects the cursor to a ray and
|
|
26
|
+
intersects the storey floor plane (renderer Y =
|
|
27
|
+
`storeyElevation`). The hover preview and click handler both
|
|
28
|
+
fall back to it when the scene raycast misses, so columns can
|
|
29
|
+
drop onto empty floor outside the existing geometry. Snap-to-
|
|
30
|
+
surface still wins whenever there is a mesh under the cursor.
|
|
31
|
+
- **3D ghost preview.** The SVG overlay now projects the about-to-
|
|
32
|
+
commit element's 8 corners (or polygon ring) to screen and
|
|
33
|
+
renders the silhouette via a convex-hull outline. Single-click
|
|
34
|
+
types (column / door / window) show the ghost on hover before
|
|
35
|
+
any clicks; two-click types (wall / beam / member) show it once
|
|
36
|
+
the start point is placed. The ghost reads live per-type form
|
|
37
|
+
params, so adjusting Width / Height / Thickness updates it in
|
|
38
|
+
real time.
|
|
39
|
+
|
|
40
|
+
Also includes a panel polish: when the active type is `space` an
|
|
41
|
+
**Auto Spaces** section appears with snap tolerance, min area,
|
|
42
|
+
height, naming pattern, and IfcSpaceTypeEnum settings + Preview /
|
|
43
|
+
Generate buttons that drive the wall-graph face finder.
|
|
44
|
+
|
|
45
|
+
- [#598](https://github.com/louistrue/ifc-lite/pull/598) [`25c9877`](https://github.com/louistrue/ifc-lite/commit/25c9877969d2dcccb9c4e61f57b188cbf5fbbc3c) Thanks [@louistrue](https://github.com/louistrue)! - Annotate-in-3D — drop pins on the scene with notes.
|
|
46
|
+
|
|
47
|
+
Press `P` (or pick the new `MapPin` button on the main toolbar),
|
|
48
|
+
click anywhere in the 3D scene, type a note. A pin lands at the
|
|
49
|
+
world point you clicked on, persists to localStorage, and re-anchors
|
|
50
|
+
itself as you orbit / pan. Pins are 14px amber dots with a
|
|
51
|
+
1-character glyph (numbered ≤ 9, dot beyond), drop shadow, idle-pulse
|
|
52
|
+
on first paint (respects `prefers-reduced-motion`), emerald selection
|
|
53
|
+
ring matching the existing constructive accent.
|
|
54
|
+
|
|
55
|
+
Flow:
|
|
56
|
+
|
|
57
|
+
- `P` toggles the Annotate tool. Toolbar gains a `MapPin` button
|
|
58
|
+
with an amber active-tone, distinct from the primary blue used
|
|
59
|
+
for Select / Walk / Measure / Section.
|
|
60
|
+
- Cursor switches to crosshair while annotating.
|
|
61
|
+
- Click → raycast into the scene → on hit, an inline note input
|
|
62
|
+
drops at the click site with a guiding "What's worth noting?"
|
|
63
|
+
label and the entity context inline (e.g. `· IfcSlab #2036`).
|
|
64
|
+
Misses are silent — annotations are anchored to surface points
|
|
65
|
+
by design, not floating in space.
|
|
66
|
+
- `Enter` saves, `⇧Enter` newline, `Esc` cancels. Outside-click
|
|
67
|
+
saves a non-empty draft and silently cancels an empty one.
|
|
68
|
+
- Click an existing pin → popover with note + relative time +
|
|
69
|
+
pen / trash icons. Edit mode mirrors the drop-input treatment.
|
|
70
|
+
- Tool stays active across drops so you can drop several pins
|
|
71
|
+
in sequence.
|
|
72
|
+
|
|
73
|
+
Architecture:
|
|
74
|
+
|
|
75
|
+
- New `annotationsSlice` — Map-keyed store (`begin/commit/cancel
|
|
76
|
+
Draft`, `update`, `remove`, `select`, `clearAll`). Notes are
|
|
77
|
+
clamped at 2000 chars, soft-warned at 200. Persists to
|
|
78
|
+
`ifc-lite:annotations:v1` in localStorage and survives a fresh
|
|
79
|
+
slice instantiation. Covered by 9 unit tests.
|
|
80
|
+
- New DOM-billboard overlay (`AnnotationLayer`) sitting on top of
|
|
81
|
+
the WebGPU canvas. A single rAF loop re-projects every pin's
|
|
82
|
+
world position to screen via `cameraCallbacks.projectToScreen`,
|
|
83
|
+
skipping `setState` when nothing changed (so the loop is cheap
|
|
84
|
+
when the camera is still). Pointer-events: none on the wrapper
|
|
85
|
+
so empty space passes through to canvas controls; pins +
|
|
86
|
+
popover opt back into pointer events explicitly.
|
|
87
|
+
- `AnnotationPin`, `AnnotationPopover`, `AnnotationDropInput` —
|
|
88
|
+
composable components, all amber-accented, edge-clamped,
|
|
89
|
+
backdrop-blurred where it matters.
|
|
90
|
+
|
|
91
|
+
Pins are NOT IFC entities — they live alongside the model as an
|
|
92
|
+
authoring overlay. Future PRs will wire BCF round-trip and
|
|
93
|
+
IfcAnnotation export, plus an annotations-list panel and category
|
|
94
|
+
tags.
|
|
95
|
+
|
|
96
|
+
- [#598](https://github.com/louistrue/ifc-lite/pull/598) [`25c9877`](https://github.com/louistrue/ifc-lite/commit/25c9877969d2dcccb9c4e61f57b188cbf5fbbc3c) Thanks [@louistrue](https://github.com/louistrue)! - Auto Spaces — diagnostics, broader wall coverage, and a sweep of
|
|
97
|
+
review feedback.
|
|
98
|
+
|
|
99
|
+
**Auto Spaces detection.** The "no enclosed regions detected"
|
|
100
|
+
failure mode now surfaces actionable counts — both in devtools
|
|
101
|
+
and in the panel itself.
|
|
102
|
+
|
|
103
|
+
- `extract-walls.ts` now tries the standard `Axis` representation
|
|
104
|
+
(`IfcShapeRepresentation` with `RepresentationIdentifier='Axis'`,
|
|
105
|
+
`IfcPolyline` items) **before** falling back to the
|
|
106
|
+
`addWallToStore` rectangle-profile convention. That covers
|
|
107
|
+
walls authored by Revit / ArchiCAD / IfcOpenShell — the previous
|
|
108
|
+
extractor only handled walls placed via the Add Element tool.
|
|
109
|
+
The placement chain is read once and the polyline endpoints are
|
|
110
|
+
transformed through it, so rotated walls work.
|
|
111
|
+
- Every wall that gets dropped is recorded with a typed reason
|
|
112
|
+
(`no-axis-or-rect-profile`, `placement-not-resolvable`,
|
|
113
|
+
`zero-length-axis`, …) — the panel summarises them as
|
|
114
|
+
`"3× no-axis-or-rect-profile, 1× zero-length-axis"`.
|
|
115
|
+
- `detectEnclosedAreas` exposes a
|
|
116
|
+
`detectEnclosedAreasWithStats(...)` companion that returns
|
|
117
|
+
per-stage counts (vertices, edges-after-split, faces total,
|
|
118
|
+
outer / below-min-area drops, largest area). The intersection
|
|
119
|
+
splitter's iteration cap now scales with input size
|
|
120
|
+
(`max(100, segments * 10)`) so dense floor plans don't bail
|
|
121
|
+
out early.
|
|
122
|
+
- `generateSpacesFromWalls` always logs a `console.info`
|
|
123
|
+
one-liner and threads a new `debug?: boolean` flag down to the
|
|
124
|
+
extractor + detector for verbose tracing. The viewer's Auto
|
|
125
|
+
Spaces panel exposes a "Verbose console logging" checkbox.
|
|
126
|
+
- The Auto Spaces diagnostic block now shows the graph stats
|
|
127
|
+
(`123v / 456e / 78f`), the drop counts, and per-reason wall
|
|
128
|
+
skips. Two amber hints fire automatically when walls were
|
|
129
|
+
extracted but no faces formed (likely snap tolerance), or
|
|
130
|
+
when nothing extracted (likely an unsupported geometry shape).
|
|
131
|
+
|
|
132
|
+
**Review-feedback sweep (PR #598).**
|
|
133
|
+
|
|
134
|
+
- `addElementMeshes.linearBox()` and the SVG `linearBoxCorners`
|
|
135
|
+
helper honour each endpoint's Y so a sloped beam previews as
|
|
136
|
+
a sloped prism instead of being flattened to the start.
|
|
137
|
+
- `bridge-store.requireStoreyId` rejects `0` (EXPRESS ids are
|
|
138
|
+
1-based, `#0` is never valid).
|
|
139
|
+
- `addWindow` / `addDoor` `tsParamTypes` include
|
|
140
|
+
`UserDefinedPartitioningType` / `UserDefinedOperationType`
|
|
141
|
+
so typed sandbox callers can hit the IFC4 round-trip without
|
|
142
|
+
casts.
|
|
143
|
+
- `AnnotationLayer.resolveEntityType` no longer falls back to
|
|
144
|
+
`ifcDataStore` when the annotation's `modelId` is missing
|
|
145
|
+
from a federated `models` map (would resolve the wrong
|
|
146
|
+
entity in multi-model sessions). Single-model sessions keep
|
|
147
|
+
the fallback.
|
|
148
|
+
- `addDoorToStore` / `addWindowToStore` validate
|
|
149
|
+
`OperationType` / `PartitioningType` against the IFC4 enum
|
|
150
|
+
and re-route unknown values through
|
|
151
|
+
`.USERDEFINED.` + `User-defined…Type` so custom labels
|
|
152
|
+
round-trip cleanly.
|
|
153
|
+
- `addWallToStore` defaults `PredefinedType` to `.NOTDEFINED.`
|
|
154
|
+
(was `.STANDARD.`) to match the rest of the in-store
|
|
155
|
+
builders.
|
|
156
|
+
- `duplicateInStore` / `resolveDuplicateSource` allow
|
|
157
|
+
`OwnerHistory` to be `null` (IFC4 made it optional). The
|
|
158
|
+
duplicate emits a bare `$` token instead of `#null` for the
|
|
159
|
+
omitted case.
|
|
160
|
+
- `StoreEditor.addEntity` accepts an injected schema-aware
|
|
161
|
+
normalizer (`setEntityTypeNormalizer`); `@ifc-lite/sdk`
|
|
162
|
+
registers `normalizeIfcTypeName` + `isKnownType` at load
|
|
163
|
+
time so direct callers — CLI scripts, sandbox bridge,
|
|
164
|
+
unit tests — see registry-grade rejection of typos like
|
|
165
|
+
`IfcWal`, plus canonical PascalCase on `EntityRef.type`.
|
|
166
|
+
|
|
167
|
+
- [#598](https://github.com/louistrue/ifc-lite/pull/598) [`25c9877`](https://github.com/louistrue/ifc-lite/commit/25c9877969d2dcccb9c4e61f57b188cbf5fbbc3c) Thanks [@louistrue](https://github.com/louistrue)! - Auto Spaces — generate IfcSpace volumes from a storey's walls.
|
|
168
|
+
|
|
169
|
+
Pick the **Space** type in the Add Element panel and the new **Auto
|
|
170
|
+
Spaces** section appears underneath the dimensions. Hit **Preview** to
|
|
171
|
+
see every enclosed region the wall graph forms (live SVG overlay,
|
|
172
|
+
labelled with area), then **Generate** to commit one IfcSpace per
|
|
173
|
+
region. Settings: snap tolerance (collapse sloppy wall ends), min area
|
|
174
|
+
(drop closets and slivers), height (extrusion), name pattern, and
|
|
175
|
+
IfcSpaceTypeEnum.
|
|
176
|
+
|
|
177
|
+
**`@ifc-lite/create`** — three new modules, all parser-pure:
|
|
178
|
+
|
|
179
|
+
- `auto-space-detect.ts` — planar-graph face finder. Snap →
|
|
180
|
+
resolve crossings → DCEL half-edge graph → leftmost-turn cycle
|
|
181
|
+
walk → drop unbounded faces → filter by min area. Handles
|
|
182
|
+
multi-component layouts (two non-touching rooms find both),
|
|
183
|
+
T-junctions, and snap-induced corner merges. 8 fixture tests.
|
|
184
|
+
- `extract-walls.ts` — pulls every wall axis on a target storey
|
|
185
|
+
from a parsed `IfcDataStore`. Walks
|
|
186
|
+
IfcRelContainedInSpatialStructure → IfcWall → placement chain →
|
|
187
|
+
IfcRectangleProfileDef.XDim. Optional overlay reader includes
|
|
188
|
+
walls created via the Add Element tool without a re-parse.
|
|
189
|
+
- `generate-spaces.ts` — orchestration: extract → detect → emit
|
|
190
|
+
via `addSpaceToStore` polygon mode. `dryRun` runs detection only.
|
|
191
|
+
|
|
192
|
+
**`@ifc-lite/viewer`** — `mutationSlice.generateSpacesFromWalls`
|
|
193
|
+
returns the detection result. `AddElementPanel` gains the Auto Spaces
|
|
194
|
+
section; `AddElementOverlay` projects detected outlines back to screen
|
|
195
|
+
using the storey's elevation so the preview tracks the camera in
|
|
196
|
+
real time.
|
|
197
|
+
|
|
198
|
+
- [#598](https://github.com/louistrue/ifc-lite/pull/598) [`25c9877`](https://github.com/louistrue/ifc-lite/commit/25c9877969d2dcccb9c4e61f57b188cbf5fbbc3c) Thanks [@louistrue](https://github.com/louistrue)! - Add the `bim.store.*` namespace — high-level editing of an already-parsed
|
|
199
|
+
`IfcDataStore` via the existing mutation overlay. Closes the merge-roundtrip
|
|
200
|
+
gap from #592 (you can edit `IfcRectangleProfileDef.XDim` or drop a fresh
|
|
201
|
+
`IfcColumn` into a model without round-tripping through a script + re-parse).
|
|
202
|
+
|
|
203
|
+
**`@ifc-lite/mutations`** — new `StoreEditor` facade plus four
|
|
204
|
+
`MutablePropertyView` extensions: positional-attribute mutations, overlay
|
|
205
|
+
entity creation/deletion (with watermark seeding), and three helpers used by
|
|
206
|
+
the viewer's undo/redo (`removePositionalMutation`, `restoreFromTombstone`,
|
|
207
|
+
`restoreNewEntity`).
|
|
208
|
+
|
|
209
|
+
**`@ifc-lite/create`** — new `in-store/` module: `addColumnToStore` builds a
|
|
210
|
+
12-entity IfcColumn sub-graph (placement, profile, extruded solid,
|
|
211
|
+
representation, product shape, rel-contained-in-spatial-structure) anchored
|
|
212
|
+
to a target `IfcBuildingStorey`. `resolveSpatialAnchor` walks the parsed
|
|
213
|
+
store to find the IfcOwnerHistory, the 'Body' representation context, and
|
|
214
|
+
the storey's local placement.
|
|
215
|
+
|
|
216
|
+
**`@ifc-lite/sdk`** — new `StoreNamespace` exposed as `bim.store` on
|
|
217
|
+
`BimContext`. Methods: `addEntity`, `removeEntity`, `setPositionalAttribute`,
|
|
218
|
+
`addColumn`. Backed by `StoreBackendMethods` on `BimBackend`; the
|
|
219
|
+
`RemoteBackend` proxy round-trips them through the transport.
|
|
220
|
+
|
|
221
|
+
**`@ifc-lite/sandbox`** — `bim.store.*` is bridged into the QuickJS sandbox
|
|
222
|
+
with full TypeScript types via `bim-globals.d.ts` and an LLM cheat sheet in
|
|
223
|
+
the system prompt. Gated on a new `store: true` permission (default
|
|
224
|
+
`false`, mirrors the existing `mutate` permission pattern).
|
|
225
|
+
|
|
226
|
+
**`@ifc-lite/cli`** — `HeadlessBackend.store` is now functional (was a
|
|
227
|
+
no-op before). Scripts run via the CLI can edit a parsed model and export it
|
|
228
|
+
with mutations applied.
|
|
229
|
+
|
|
230
|
+
**`@ifc-lite/viewer`** — three new UI surfaces:
|
|
231
|
+
|
|
232
|
+
- Raw STEP tab in `PropertiesPanel` — lists every positional STEP argument
|
|
233
|
+
with an inline pen-icon editor for scalar values (numbers, refs, enums,
|
|
234
|
+
null). Mutated rows show a purple dot and tinted background.
|
|
235
|
+
- `EntityContextMenu` gains "Delete entity" (red, calls `removeEntity`
|
|
236
|
+
with toast + undo support) and "Add column here…" (emerald, only enabled
|
|
237
|
+
when the right-clicked entity is an `IfcBuildingStorey`).
|
|
238
|
+
- `AddColumnDialog` modal — storey picker sorted by elevation, position
|
|
239
|
+
(storey-local metres), cross-section, height, name, optional collapsible
|
|
240
|
+
for Description/ObjectType/Tag. Anchor-resolution failures surface
|
|
241
|
+
inline, not as thrown exceptions.
|
|
242
|
+
|
|
243
|
+
Plus four new actions on `mutationSlice` (`setPositionalAttribute`,
|
|
244
|
+
`removeEntity`, `addColumn`, dialog open/close) backed by per-model
|
|
245
|
+
`StoreEditor` caches, with undo/redo wired for `UPDATE_POSITIONAL_ATTRIBUTE`,
|
|
246
|
+
`CREATE_ENTITY`, and `DELETE_ENTITY`.
|
|
247
|
+
|
|
248
|
+
**`@ifc-lite/parser`** — `package.json` `exports` re-ordered to put `types`
|
|
249
|
+
before `import` so downstream consumers using TS5 `nodenext` resolution
|
|
250
|
+
pick up the type declarations.
|
|
251
|
+
|
|
252
|
+
**`@ifc-lite/geometry`** — re-exports `MetadataBootstrapEntitySummary` and
|
|
253
|
+
`MetadataBootstrapSpatialNode` from the package index (used by viewer
|
|
254
|
+
desktop services).
|
|
255
|
+
|
|
256
|
+
**`@ifc-lite/renderer`** — `GPUBufferDescriptor` ambient declaration gains
|
|
257
|
+
`mappedAtCreation?: boolean`. Internal change; the renderer was already
|
|
258
|
+
using it at runtime to skip a Mojo IPC round-trip on Chrome/Dawn.
|
|
259
|
+
|
|
260
|
+
- [#598](https://github.com/louistrue/ifc-lite/pull/598) [`25c9877`](https://github.com/louistrue/ifc-lite/commit/25c9877969d2dcccb9c4e61f57b188cbf5fbbc3c) Thanks [@louistrue](https://github.com/louistrue)! - Duplicate-from-selection — pick any IfcRoot product, hit `⌘D` (or
|
|
261
|
+
right-click → Duplicate), get a fully-functional clone. The
|
|
262
|
+
duplicate is a first-class entity in the property panel, exports
|
|
263
|
+
cleanly to STEP with all its property associations preserved, and
|
|
264
|
+
ships in 6 directional variants sized to the source's bounding box.
|
|
265
|
+
|
|
266
|
+
**`@ifc-lite/create`**
|
|
267
|
+
|
|
268
|
+
- New `duplicateInStore(editor, source, options)` pure builder.
|
|
269
|
+
Emits a fresh placement chain (`IfcCartesianPoint` →
|
|
270
|
+
`IfcAxis2Placement3D` → `IfcLocalPlacement`) plus the duplicate
|
|
271
|
+
`IfcRoot` with a new GUID and the source's `Representation`
|
|
272
|
+
reference reused (geometry shared). Optional fresh
|
|
273
|
+
`IfcRelContainedInSpatialStructure` anchors to the source's
|
|
274
|
+
storey. Offset is configurable via `options.offset` — the slice
|
|
275
|
+
sizes it to the source's bbox.
|
|
276
|
+
- New `resolveDuplicateSource(store, expressId)` walks the parsed
|
|
277
|
+
`IfcDataStore` for placement / parent / location / storey /
|
|
278
|
+
associations.
|
|
279
|
+
- New `SourceAssociation` shape captures one
|
|
280
|
+
`IfcRelDefines*` / `IfcRelAssociates*` edge that references
|
|
281
|
+
the source. The builder replays each one against the duplicate
|
|
282
|
+
so the exported STEP carries identical psets / qsets /
|
|
283
|
+
materials / classifications / documents / type binding —
|
|
284
|
+
without modifying any existing rel.
|
|
285
|
+
- Resolver scans the five association rel types
|
|
286
|
+
(`IFCRELDEFINESBYPROPERTIES`, `IFCRELDEFINESBYTYPE`,
|
|
287
|
+
`IFCRELASSOCIATESMATERIAL`, `…CLASSIFICATION`, `…DOCUMENT`)
|
|
288
|
+
by direct numeric membership in `RelatedObjects`.
|
|
289
|
+
- `DuplicateBuildResult.associationRelIds: number[]` exposes the
|
|
290
|
+
fresh rel ids for caller introspection.
|
|
291
|
+
- 7 unit tests in `duplicate.test.ts`: full graph emission,
|
|
292
|
+
custom offset, no-storey path, root-placement parent, attribute
|
|
293
|
+
count guard, association replay (3 rel types in one go), and
|
|
294
|
+
the no-associations case.
|
|
295
|
+
|
|
296
|
+
**`@ifc-lite/mutations`**
|
|
297
|
+
|
|
298
|
+
- New `setEntityAlias(overlayId, sourceId | null)` /
|
|
299
|
+
`getEntityAlias(id)` / `resolveBaseEntityId(id)` public surface
|
|
300
|
+
on `MutablePropertyView`. Aliases redirect base property and
|
|
301
|
+
quantity reads from the duplicate to its source — so the
|
|
302
|
+
duplicate inherits psets/qsets without eagerly cloning them
|
|
303
|
+
into the overlay.
|
|
304
|
+
- Override slots stay scoped to the original (overlay) id, so
|
|
305
|
+
edits on the duplicate don't bleed into the source. Verified
|
|
306
|
+
by 4 new unit tests including the source-untouched path,
|
|
307
|
+
chain-cap (one hop, not transitive), and the self-alias guard.
|
|
308
|
+
|
|
309
|
+
**`@ifc-lite/viewer`**
|
|
310
|
+
|
|
311
|
+
- New `duplicateEntity(modelId, sourceExpressId, direction?)`
|
|
312
|
+
slice action. Wraps the create-package builder, sets the
|
|
313
|
+
mutation-view alias, and clones the source's mesh data into
|
|
314
|
+
the geometry result with the offset applied — so the duplicate
|
|
315
|
+
appears in 3D the moment the action fires, not just in the
|
|
316
|
+
export overlay. Per-vertex `entityIds` arrays are filled with
|
|
317
|
+
the new globalId so picking and selection resolve correctly.
|
|
318
|
+
- New `DuplicateDirection` type (`+X` / `-X` / `+Y` / `-Y` /
|
|
319
|
+
`+Z` / `-Z`). Magnitude per axis = the source's bounding-box
|
|
320
|
+
dimension on that axis, so a 3m wall steps 3m and a 0.4m
|
|
321
|
+
column steps 0.4m. Falls back to a 1m step when the source
|
|
322
|
+
has no mesh in geometry.
|
|
323
|
+
- Right-click menu's "Duplicate" item is now a `DuplicateRow`:
|
|
324
|
+
primary clickable label on the left (defaults to +X), 6 axis
|
|
325
|
+
chips on the right (→ ← ↗ ↙ ↑ ↓). Tooltips spell out
|
|
326
|
+
"+X (east)" through "−Z (down)".
|
|
327
|
+
- `⌘D` defaults to +X. `⇧⌘D` = +Z (up), `⌥⌘D` = +Y (north) —
|
|
328
|
+
modifier shortcuts for power users without forcing a mouse
|
|
329
|
+
trip to the chip row. Selection moves to the new globalId so
|
|
330
|
+
a Cmd+D chain ("stamp a row of columns") works without
|
|
331
|
+
re-clicking.
|
|
332
|
+
- **`resolveGlobalIdFromModels` two-pass overlay fallback** —
|
|
333
|
+
the federation resolver previously gated each model's id range
|
|
334
|
+
at parse-time `maxExpressId`, which excluded every
|
|
335
|
+
overlay-allocated id from selection. The fix: a second pass
|
|
336
|
+
consults each model's mutation view via `getNewEntity(localId)`
|
|
337
|
+
so overlay duplicates resolve to the right model with the
|
|
338
|
+
right local id. Without this, the property panel saw the
|
|
339
|
+
duplicate as "UNKNOWN / Unknown / no property sets" because
|
|
340
|
+
the alias couldn't take effect on a wrongly-resolved id.
|
|
341
|
+
- PropertiesPanel falls back to the overlay `NewEntity` record
|
|
342
|
+
for type / name / GUID / Description / ObjectType when the
|
|
343
|
+
parsed `entityNode` comes up empty. The bSDD attribute list
|
|
344
|
+
synthesises from the schema-defined positional names. The
|
|
345
|
+
Materials / Classifications / Documents / structural
|
|
346
|
+
Relationships sections all route through a new
|
|
347
|
+
`lookupExpressId` (alias-resolved) so they query the source's
|
|
348
|
+
parsed maps directly.
|
|
349
|
+
|
|
350
|
+
After: a freshly-duplicated wall is genuinely first-class — name
|
|
351
|
+
reads, properties show, quantities show, material layers show,
|
|
352
|
+
classifications show, documents show, and a round-tripped STEP
|
|
353
|
+
file carries every association.
|
|
354
|
+
|
|
355
|
+
- [#576](https://github.com/louistrue/ifc-lite/pull/576) [`1309f8c`](https://github.com/louistrue/ifc-lite/commit/1309f8cba128b3b6237ebfb9831bf359c426a742) Thanks [@louistrue](https://github.com/louistrue)! - Add the full IfcTask / 4D construction-schedule experience to the viewer.
|
|
356
|
+
|
|
357
|
+
**Gantt panel** — a lower-panel workspace combining a task tree, a zoomable
|
|
358
|
+
SVG timeline with task bars / milestones / dependency arrows / playback
|
|
359
|
+
cursor, a toolbar (work-schedule filter, play / pause / loop / speed, time
|
|
360
|
+
scale), and an empty state. Live Gantt ↔ 3D selection highlight (one-way,
|
|
361
|
+
no isolation) and playback-driven visibility through the rendererʼs
|
|
362
|
+
hidden-entity channel.
|
|
363
|
+
|
|
364
|
+
**Schedule editing** — Inspector Task card (name, identification,
|
|
365
|
+
predefined type, milestone, start / finish / duration with any-two-of-three
|
|
366
|
+
reconciliation, assigned products, delete with cascade). Undo / redo
|
|
367
|
+
(descriptor-based lightweight snapshots for field edits; full snapshot for
|
|
368
|
+
structural edits), store-scoped transactions (drag-coalesced), add / delete /
|
|
369
|
+
reorder tasks. IFC STEP export routes through a centralised schedule splice
|
|
370
|
+
helper so generated / edited schedules round-trip cleanly on every export
|
|
371
|
+
surface.
|
|
372
|
+
|
|
373
|
+
**Generate from hierarchy** — a Generate Schedule dialog produces a work
|
|
374
|
+
schedule + tasks from the modelʼs spatial hierarchy (Storey / Building) or
|
|
375
|
+
geometry (Height-slice, with optional Class / Type / Name subgroup). Linked
|
|
376
|
+
FS dependencies and ghost-preparation look-ahead are opt-in.
|
|
377
|
+
|
|
378
|
+
**4D animation** — Synchro-style phased lifecycle (preparation ghost →
|
|
379
|
+
ramp-in → active task-type colour → settling fade → complete), demolition
|
|
380
|
+
inversion, customizable palette, and configurable palette intensity /
|
|
381
|
+
look-ahead / hide-untasked products. Animation layers live in a priority-
|
|
382
|
+
composited overlay registry (`registerOverlayLayer`), with a single
|
|
383
|
+
compositor hook owning the write to the rendererʼs hidden-entity + colour-
|
|
384
|
+
override channels.
|
|
385
|
+
|
|
386
|
+
**LLM integration** — built-in "Construction schedule (4D)" script template,
|
|
387
|
+
PDF / spreadsheet chat attachments, and `bim.schedule.*` read APIs reachable
|
|
388
|
+
from the sandbox.
|
|
389
|
+
|
|
390
|
+
- [#598](https://github.com/louistrue/ifc-lite/pull/598) [`25c9877`](https://github.com/louistrue/ifc-lite/commit/25c9877969d2dcccb9c4e61f57b188cbf5fbbc3c) Thanks [@louistrue](https://github.com/louistrue)! - Raw STEP tab — drill into `#N` references and a tighter dev-leaning
|
|
391
|
+
visual treatment.
|
|
392
|
+
|
|
393
|
+
**Reference drill-through**
|
|
394
|
+
|
|
395
|
+
- Each `#N` token in the Raw STEP card is now a clickable chip.
|
|
396
|
+
Click → drills into the target entity and shows its positional
|
|
397
|
+
arguments inline; the breadcrumb at the top of the card tracks
|
|
398
|
+
the path back to the 3D-selected entity.
|
|
399
|
+
- **Auto-skip wrappers** — when the click target itself has only
|
|
400
|
+
a single positional arg and that arg is also a `#N`, the card
|
|
401
|
+
follows the chain in one click and lands on the first
|
|
402
|
+
"meaningful" entity. Capped at 16 hops to defend against
|
|
403
|
+
cyclic STEP graphs. So a real-world case like
|
|
404
|
+
`IfcRelDefinesByProperties → IfcPropertySet` steps cleanly,
|
|
405
|
+
and pure pass-through wrappers don't waste user clicks.
|
|
406
|
+
- Drill state resets when the 3D selection changes — drilling
|
|
407
|
+
stays scoped to a single click. Each breadcrumb segment is
|
|
408
|
+
clickable to jump back to that depth.
|
|
409
|
+
- Editing a `#N` ref still works via the pen icon — clicking the
|
|
410
|
+
chip itself navigates instead of entering edit mode, but the
|
|
411
|
+
hover-revealed pen still flips to inline-edit so a user can
|
|
412
|
+
re-type the reference target.
|
|
413
|
+
- Tombstoned entities short-circuit the auto-follow so the drill
|
|
414
|
+
doesn't render a deleted entity's body.
|
|
415
|
+
|
|
416
|
+
**True STEP literals on display**
|
|
417
|
+
|
|
418
|
+
- Tokens are read directly from the source bytes via a new
|
|
419
|
+
`extractRawStepTokens` helper, so refs render as `#42`, enums
|
|
420
|
+
stay `.AREA.`, and strings keep their on-disk quoted form. The
|
|
421
|
+
EntityExtractor's parsed JS shape strips reference prefixes
|
|
422
|
+
(it parses `#42` into the integer `42`), so the previous
|
|
423
|
+
formatter had no way to recover the distinction — `OwnerHistory`
|
|
424
|
+
would render as `18` instead of `#18`. Fixed.
|
|
425
|
+
- Overlay overrides serialize back through `serializeStepToken`
|
|
426
|
+
for parity with the unmodified base tokens.
|
|
427
|
+
|
|
428
|
+
**Overlay-aware row display**
|
|
429
|
+
|
|
430
|
+
- Edits to positional attributes now reflect immediately in the
|
|
431
|
+
row body. Previously the card re-extracted from the source
|
|
432
|
+
buffer and ignored the overlay map, so the displayed value
|
|
433
|
+
snapped back to the original after Save (only the purple
|
|
434
|
+
overlay-override dot updated correctly).
|
|
435
|
+
|
|
436
|
+
**Dev-leaning tab styling**
|
|
437
|
+
|
|
438
|
+
- Raw STEP tab restyled — replaces the "Raw" plain-text label
|
|
439
|
+
with a `</>` bracket glyph, shrinks the trigger to icon-only
|
|
440
|
+
width via `flex: 0 0 auto`. Frees up width so Properties /
|
|
441
|
+
Quantities / bSDD keep their text visible at the default
|
|
442
|
+
panel size, and signals "developer view" with a terminal-green
|
|
443
|
+
accent on hover / active state.
|
|
444
|
+
|
|
445
|
+
**Add-Column UI removed**
|
|
446
|
+
|
|
447
|
+
- The original `AddColumnDialog` + context-menu "Add column
|
|
448
|
+
here…" + EditToolbar "Column" button — premature for the
|
|
449
|
+
current workflow (single hard-coded element type with no
|
|
450
|
+
geometry preview). Removed cleanly:
|
|
451
|
+
`AddColumnDialog.tsx` (deleted), the `addColumnDialog` slice
|
|
452
|
+
state, the constructive `MenuItem` tone (only used by that
|
|
453
|
+
item), and the context-menu / toolbar entry points.
|
|
454
|
+
- Kept: the `addColumn` slice action and the
|
|
455
|
+
`bim.store.addColumn` SDK surface — those still drive scripts
|
|
456
|
+
and programmatic flows, just no UI affordance for now.
|
|
457
|
+
|
|
458
|
+
**Tombstoned mesh actually disappears**
|
|
459
|
+
|
|
460
|
+
- Delete entity now pairs the overlay tombstone with
|
|
461
|
+
`hideEntity(globalId)` so the rendered mesh is hidden from the
|
|
462
|
+
GPU buffers (and stops being pickable). Undo of `DELETE_ENTITY`
|
|
463
|
+
pairs `restoreFromTombstone` with `showEntity` so the entity
|
|
464
|
+
returns to the scene; redo re-hides. Symmetrical round-trip.
|
|
465
|
+
|
|
466
|
+
- [#588](https://github.com/louistrue/ifc-lite/pull/588) [`b75f0cc`](https://github.com/louistrue/ifc-lite/commit/b75f0cccb06c89f5e30272d6c04f986f3b47e574) Thanks [@louistrue](https://github.com/louistrue)! - Replace the SQL tab in the advanced search modal with a clean
|
|
467
|
+
chip-based **Filter** tab. Storey / IFC type / Predefined type / Name /
|
|
468
|
+
Property / Quantity rules compose with AND/OR + IsSet/IsNotSet and
|
|
469
|
+
run through an in-memory evaluator that scales to 4M-entity models
|
|
470
|
+
via `entityIndex.byType` / `spatialHierarchy.byStorey` prefilter,
|
|
471
|
+
cheap-first per-entity rule ordering, and async chunked yielding
|
|
472
|
+
with cancel + progress. The DuckDB engine, SQL editor, schema
|
|
473
|
+
browser, templates, error rewriter, and saved-SQL-queries module
|
|
474
|
+
have been removed — Builder is the whole UI now, with a single Run
|
|
475
|
+
button and CSV/JSON export. Builder dropdowns are schema-aware
|
|
476
|
+
(storeys + IFC types load eagerly, pset / qto names load lazily on
|
|
477
|
+
first use), the inline search-bar query promotes to a Name rule
|
|
478
|
+
with one click, multi-model row clicks route to the correct model,
|
|
479
|
+
and saved presets persist named `{name, combinator, rules}`
|
|
480
|
+
snapshots in localStorage.
|
|
481
|
+
|
|
482
|
+
### Patch Changes
|
|
483
|
+
|
|
484
|
+
- [#588](https://github.com/louistrue/ifc-lite/pull/588) [`b75f0cc`](https://github.com/louistrue/ifc-lite/commit/b75f0cccb06c89f5e30272d6c04f986f3b47e574) Thanks [@louistrue](https://github.com/louistrue)! - Address PR #588 review feedback that survived the Filter migration:
|
|
485
|
+
|
|
486
|
+
- Inline-bar Enter now flushes the 80ms debounce by re-scanning against
|
|
487
|
+
the live `searchQuery`, so committing inside the debounce window
|
|
488
|
+
selects the entity matching what the input shows (not the prior
|
|
489
|
+
query) and records the correct recent.
|
|
490
|
+
- The 50ms `frameSelection` timer in the inline bar is tracked via a
|
|
491
|
+
ref and cleared on rapid selection changes / unmount instead of
|
|
492
|
+
leaking orphan callbacks.
|
|
493
|
+
- Shift+Enter additive selection in the inline bar and the row-level
|
|
494
|
+
additive path in the Search modal now TOGGLE via `toggleEntitySelection`,
|
|
495
|
+
so the same interaction can deselect a previously-added row.
|
|
496
|
+
- New `addEntitiesToSelection` batch action on the selection slice;
|
|
497
|
+
the Search modal's "Select all" path uses it so a 5K-row select-all
|
|
498
|
+
dispatches one Zustand `set` instead of N.
|
|
499
|
+
- Tier-0 scoring now keeps the max across name/type/objectType/description
|
|
500
|
+
fields (matching Tier-1's behaviour). Without this, an entity with a
|
|
501
|
+
substring name hit and a type-exact hit ranked lower than it should
|
|
502
|
+
on Tier-0, breaking the comparable-ordering guarantee when results
|
|
503
|
+
came from a mix of Tier-0 and Tier-1 models.
|
|
504
|
+
|
|
505
|
+
- Updated dependencies [[`25c9877`](https://github.com/louistrue/ifc-lite/commit/25c9877969d2dcccb9c4e61f57b188cbf5fbbc3c), [`25c9877`](https://github.com/louistrue/ifc-lite/commit/25c9877969d2dcccb9c4e61f57b188cbf5fbbc3c), [`25c9877`](https://github.com/louistrue/ifc-lite/commit/25c9877969d2dcccb9c4e61f57b188cbf5fbbc3c), [`1309f8c`](https://github.com/louistrue/ifc-lite/commit/1309f8cba128b3b6237ebfb9831bf359c426a742), [`1309f8c`](https://github.com/louistrue/ifc-lite/commit/1309f8cba128b3b6237ebfb9831bf359c426a742), [`1309f8c`](https://github.com/louistrue/ifc-lite/commit/1309f8cba128b3b6237ebfb9831bf359c426a742), [`1309f8c`](https://github.com/louistrue/ifc-lite/commit/1309f8cba128b3b6237ebfb9831bf359c426a742), [`16d7a63`](https://github.com/louistrue/ifc-lite/commit/16d7a6361a78bb39a2bd61bba6990db5d3df0c04), [`945bb30`](https://github.com/louistrue/ifc-lite/commit/945bb30061ca044f4a51001f7299c17350ce99cf), [`25c9877`](https://github.com/louistrue/ifc-lite/commit/25c9877969d2dcccb9c4e61f57b188cbf5fbbc3c), [`370e084`](https://github.com/louistrue/ifc-lite/commit/370e084e94e8fce930bddf948344c4b639d196f3), [`18c6a37`](https://github.com/louistrue/ifc-lite/commit/18c6a37f1cc1426daa32ee60457dd0580a5257f5)]:
|
|
506
|
+
- @ifc-lite/mutations@1.15.0
|
|
507
|
+
- @ifc-lite/sdk@1.15.0
|
|
508
|
+
- @ifc-lite/sandbox@1.15.0
|
|
509
|
+
- @ifc-lite/parser@2.2.0
|
|
510
|
+
- @ifc-lite/geometry@1.16.6
|
|
511
|
+
- @ifc-lite/renderer@1.17.0
|
|
512
|
+
- @ifc-lite/query@1.14.7
|
|
513
|
+
- @ifc-lite/wasm@1.16.7
|
|
514
|
+
- @ifc-lite/export@1.18.0
|
|
515
|
+
|
|
3
516
|
## 1.17.6
|
|
4
517
|
|
|
5
518
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as o}from"./index-
|
|
1
|
+
import{u as o}from"./index-BKq-M3Mk.js";import"./cesium-DUOzBlqv.js";import"./arrow-CZ5kQ26f.js";import"./exporters-B_OBqIyD.js";import"./bcf-DOG9_WPX.js";import"./zip-DBEtpeu6.js";import"./sandbox-jez21HtV.js";import"./lens-CSASnhAL.js";import"./drawing-2d-DoxKMqbO.js";import"./server-client-ncOQVNso.js";import"./ids-DQ5jY0E8.js";const n=700;function v(s){const e=o.getState(),i=e.basketViews.find(t=>t.id===s);if(i){if(e.setDrawing2D(null),e.setDrawing2DPanelVisible(!1),e.updateDrawing2DDisplayOptions({show3DOverlay:!1}),e.clearEntitySelection(),e.restoreBasketEntities(i.entityRefs,s),i.viewpoint){const t=i.transitionMs??n;e.cameraCallbacks.applyViewpoint?.(i.viewpoint,!0,t)}if(i.section){const t=i.section;o.setState({sectionPlane:{...t.plane},drawing2DPanelVisible:!1}),t.plane.enabled?(e.activeTool!=="section"&&e.setSuppressNextSection2DPanelAutoOpen(!0),e.setActiveTool("section")):e.activeTool==="section"&&e.setActiveTool("select")}else{const t=o.getState().sectionPlane;o.setState({sectionPlane:{...t,enabled:!1}}),e.activeTool==="section"&&e.setActiveTool("select")}}}export{v as activateBasketViewFromStore};
|