@ifc-lite/viewer 1.6.1 → 1.7.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/CHANGELOG.md +71 -0
- package/dist/assets/{Arrow.dom-Be1tgmo6.js → Arrow.dom-BGPQieQQ.js} +1 -1
- package/dist/assets/ifc-lite_bg-DyIN_nBM.wasm +0 -0
- package/dist/assets/{index-D1Du89Pa.js → index-dgdgiQ9p.js} +40198 -29999
- package/dist/assets/index-yTqs8kgX.css +1 -0
- package/dist/assets/{native-bridge-A6zNnTfi.js → native-bridge-DD0SNyQ5.js} +1 -1
- package/dist/assets/{wasm-bridge-DkRhgSvE.js → wasm-bridge-D54YMO7X.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +18 -15
- package/src/components/viewer/BCFPanel.tsx +7 -789
- package/src/components/viewer/Drawing2DCanvas.tsx +1048 -0
- package/src/components/viewer/DrawingSettingsPanel.tsx +3 -3
- package/src/components/viewer/HierarchyPanel.tsx +110 -842
- package/src/components/viewer/IDSExportDialog.tsx +281 -0
- package/src/components/viewer/IDSPanel.tsx +126 -17
- package/src/components/viewer/KeyboardShortcutsDialog.tsx +9 -0
- package/src/components/viewer/LensPanel.tsx +603 -0
- package/src/components/viewer/MainToolbar.tsx +188 -21
- package/src/components/viewer/PropertiesPanel.tsx +171 -652
- package/src/components/viewer/PropertyEditor.tsx +866 -77
- package/src/components/viewer/Section2DPanel.tsx +76 -2648
- package/src/components/viewer/ToolOverlays.tsx +3 -1097
- package/src/components/viewer/ViewerLayout.tsx +132 -45
- package/src/components/viewer/Viewport.tsx +237 -1659
- package/src/components/viewer/ViewportContainer.tsx +11 -3
- package/src/components/viewer/bcf/BCFCreateTopicForm.tsx +134 -0
- package/src/components/viewer/bcf/BCFTopicDetail.tsx +388 -0
- package/src/components/viewer/bcf/BCFTopicList.tsx +239 -0
- package/src/components/viewer/bcf/bcfHelpers.tsx +109 -0
- package/src/components/viewer/hierarchy/HierarchyNode.tsx +328 -0
- package/src/components/viewer/hierarchy/treeDataBuilder.ts +464 -0
- package/src/components/viewer/hierarchy/types.ts +54 -0
- package/src/components/viewer/hierarchy/useHierarchyTree.ts +280 -0
- package/src/components/viewer/lists/ListBuilder.tsx +486 -0
- package/src/components/viewer/lists/ListPanel.tsx +540 -0
- package/src/components/viewer/lists/ListResultsTable.tsx +193 -0
- package/src/components/viewer/properties/ClassificationCard.tsx +70 -0
- package/src/components/viewer/properties/CoordinateDisplay.tsx +49 -0
- package/src/components/viewer/properties/DocumentCard.tsx +89 -0
- package/src/components/viewer/properties/MaterialCard.tsx +201 -0
- package/src/components/viewer/properties/ModelMetadataPanel.tsx +335 -0
- package/src/components/viewer/properties/PropertySetCard.tsx +132 -0
- package/src/components/viewer/properties/QuantitySetCard.tsx +79 -0
- package/src/components/viewer/properties/RelationshipsCard.tsx +100 -0
- package/src/components/viewer/properties/encodingUtils.ts +29 -0
- package/src/components/viewer/tools/MeasurePanel.tsx +218 -0
- package/src/components/viewer/tools/MeasurementVisuals.tsx +644 -0
- package/src/components/viewer/tools/SectionPanel.tsx +183 -0
- package/src/components/viewer/tools/SectionVisualization.tsx +78 -0
- package/src/components/viewer/tools/formatDistance.ts +18 -0
- package/src/components/viewer/tools/sectionConstants.ts +14 -0
- package/src/components/viewer/useAnimationLoop.ts +166 -0
- package/src/components/viewer/useGeometryStreaming.ts +398 -0
- package/src/components/viewer/useKeyboardControls.ts +221 -0
- package/src/components/viewer/useMouseControls.ts +1009 -0
- package/src/components/viewer/useRenderUpdates.ts +165 -0
- package/src/components/viewer/useTouchControls.ts +245 -0
- package/src/hooks/ids/idsColorSystem.ts +125 -0
- package/src/hooks/ids/idsDataAccessor.ts +237 -0
- package/src/hooks/ids/idsExportService.ts +444 -0
- package/src/hooks/useBCF.ts +7 -0
- package/src/hooks/useDrawingExport.ts +627 -0
- package/src/hooks/useDrawingGeneration.ts +627 -0
- package/src/hooks/useFloorplanView.ts +108 -0
- package/src/hooks/useIDS.ts +270 -463
- package/src/hooks/useIfc.ts +26 -1628
- package/src/hooks/useIfcFederation.ts +803 -0
- package/src/hooks/useIfcLoader.ts +508 -0
- package/src/hooks/useIfcServer.ts +465 -0
- package/src/hooks/useKeyboardShortcuts.ts +1 -1
- package/src/hooks/useLens.ts +129 -0
- package/src/hooks/useMeasure2D.ts +365 -0
- package/src/hooks/useViewControls.ts +218 -0
- package/src/lib/ifc4-pset-definitions.test.ts +161 -0
- package/src/lib/ifc4-pset-definitions.ts +621 -0
- package/src/lib/ifc4-qto-definitions.ts +315 -0
- package/src/lib/lens/adapter.ts +138 -0
- package/src/lib/lens/index.ts +5 -0
- package/src/lib/lists/adapter.ts +69 -0
- package/src/lib/lists/index.ts +28 -0
- package/src/lib/lists/persistence.ts +64 -0
- package/src/services/fs-cache.ts +1 -1
- package/src/services/tauri-modules.d.ts +25 -0
- package/src/store/index.ts +38 -2
- package/src/store/slices/cameraSlice.ts +14 -1
- package/src/store/slices/dataSlice.ts +14 -1
- package/src/store/slices/lensSlice.ts +184 -0
- package/src/store/slices/listSlice.ts +74 -0
- package/src/store/slices/pinboardSlice.ts +114 -0
- package/src/store/types.ts +5 -0
- package/src/utils/ifcConfig.ts +16 -3
- package/src/utils/serverDataModel.ts +64 -101
- package/src/vite-env.d.ts +3 -0
- package/dist/assets/ifc-lite_bg-C6kblxf9.wasm +0 -0
- package/dist/assets/index-v3mcCUPN.css +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
|
|
5
|
-
import { useEffect } from 'react';
|
|
5
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
6
6
|
import { Panel, Group as PanelGroup, Separator as PanelResizeHandle } from 'react-resizable-panels';
|
|
7
7
|
import { TooltipProvider } from '@/components/ui/tooltip';
|
|
8
8
|
import { MainToolbar } from './MainToolbar';
|
|
@@ -17,6 +17,12 @@ import { EntityContextMenu } from './EntityContextMenu';
|
|
|
17
17
|
import { HoverTooltip } from './HoverTooltip';
|
|
18
18
|
import { BCFPanel } from './BCFPanel';
|
|
19
19
|
import { IDSPanel } from './IDSPanel';
|
|
20
|
+
import { LensPanel } from './LensPanel';
|
|
21
|
+
import { ListPanel } from './lists/ListPanel';
|
|
22
|
+
|
|
23
|
+
const BOTTOM_PANEL_MIN_HEIGHT = 120;
|
|
24
|
+
const BOTTOM_PANEL_DEFAULT_HEIGHT = 300;
|
|
25
|
+
const BOTTOM_PANEL_MAX_RATIO = 0.7; // max 70% of container
|
|
20
26
|
|
|
21
27
|
export function ViewerLayout() {
|
|
22
28
|
// Initialize keyboard shortcuts
|
|
@@ -35,6 +41,60 @@ export function ViewerLayout() {
|
|
|
35
41
|
const setBcfPanelVisible = useViewerStore((s) => s.setBcfPanelVisible);
|
|
36
42
|
const idsPanelVisible = useViewerStore((s) => s.idsPanelVisible);
|
|
37
43
|
const setIdsPanelVisible = useViewerStore((s) => s.setIdsPanelVisible);
|
|
44
|
+
const listPanelVisible = useViewerStore((s) => s.listPanelVisible);
|
|
45
|
+
const setListPanelVisible = useViewerStore((s) => s.setListPanelVisible);
|
|
46
|
+
const lensPanelVisible = useViewerStore((s) => s.lensPanelVisible);
|
|
47
|
+
const setLensPanelVisible = useViewerStore((s) => s.setLensPanelVisible);
|
|
48
|
+
|
|
49
|
+
// Bottom panel resize state (pixel height, persisted in ref to avoid re-renders during drag)
|
|
50
|
+
const [bottomHeight, setBottomHeight] = useState(BOTTOM_PANEL_DEFAULT_HEIGHT);
|
|
51
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
52
|
+
const isDraggingRef = useRef(false);
|
|
53
|
+
const cleanupRef = useRef<(() => void) | null>(null);
|
|
54
|
+
|
|
55
|
+
// Cleanup drag listeners on unmount
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
return () => { cleanupRef.current?.(); };
|
|
58
|
+
}, []);
|
|
59
|
+
|
|
60
|
+
const handleResizeStart = useCallback((e: React.MouseEvent) => {
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
isDraggingRef.current = true;
|
|
63
|
+
|
|
64
|
+
const startY = e.clientY;
|
|
65
|
+
const startHeight = bottomHeight;
|
|
66
|
+
|
|
67
|
+
const onMouseMove = (moveEvent: MouseEvent) => {
|
|
68
|
+
if (!isDraggingRef.current) return;
|
|
69
|
+
const container = containerRef.current;
|
|
70
|
+
if (!container) return;
|
|
71
|
+
|
|
72
|
+
const maxHeight = container.clientHeight * BOTTOM_PANEL_MAX_RATIO;
|
|
73
|
+
const delta = startY - moveEvent.clientY;
|
|
74
|
+
const newHeight = Math.min(
|
|
75
|
+
maxHeight,
|
|
76
|
+
Math.max(BOTTOM_PANEL_MIN_HEIGHT, startHeight + delta)
|
|
77
|
+
);
|
|
78
|
+
setBottomHeight(newHeight);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const cleanup = () => {
|
|
82
|
+
isDraggingRef.current = false;
|
|
83
|
+
document.removeEventListener('mousemove', onMouseMove);
|
|
84
|
+
document.removeEventListener('mouseup', onMouseUp);
|
|
85
|
+
document.body.style.cursor = '';
|
|
86
|
+
document.body.style.userSelect = '';
|
|
87
|
+
cleanupRef.current = null;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const onMouseUp = () => { cleanup(); };
|
|
91
|
+
|
|
92
|
+
document.addEventListener('mousemove', onMouseMove);
|
|
93
|
+
document.addEventListener('mouseup', onMouseUp);
|
|
94
|
+
document.body.style.cursor = 'row-resize';
|
|
95
|
+
document.body.style.userSelect = 'none';
|
|
96
|
+
cleanupRef.current = cleanup;
|
|
97
|
+
}, [bottomHeight]);
|
|
38
98
|
|
|
39
99
|
// Detect mobile viewport
|
|
40
100
|
useEffect(() => {
|
|
@@ -79,50 +139,71 @@ export function ViewerLayout() {
|
|
|
79
139
|
|
|
80
140
|
{/* Main Content Area - Desktop Layout */}
|
|
81
141
|
{!isMobile && (
|
|
82
|
-
<
|
|
83
|
-
{/*
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
142
|
+
<div ref={containerRef} className="flex-1 min-h-0 flex flex-col">
|
|
143
|
+
{/* Top: horizontal split (hierarchy | viewport | properties) */}
|
|
144
|
+
<div className="flex-1 min-h-0">
|
|
145
|
+
<PanelGroup orientation="horizontal" className="h-full">
|
|
146
|
+
{/* Left Panel - Hierarchy */}
|
|
147
|
+
<Panel
|
|
148
|
+
id="left-panel"
|
|
149
|
+
defaultSize={20}
|
|
150
|
+
minSize={10}
|
|
151
|
+
collapsible
|
|
152
|
+
collapsedSize={0}
|
|
153
|
+
>
|
|
154
|
+
<div className="h-full w-full overflow-hidden">
|
|
155
|
+
<HierarchyPanel />
|
|
156
|
+
</div>
|
|
157
|
+
</Panel>
|
|
95
158
|
|
|
96
|
-
|
|
159
|
+
<PanelResizeHandle className="w-1.5 bg-border hover:bg-primary/50 active:bg-primary/70 transition-colors cursor-col-resize" />
|
|
97
160
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
161
|
+
{/* Center - Viewport */}
|
|
162
|
+
<Panel id="viewport-panel" defaultSize={58} minSize={30}>
|
|
163
|
+
<div className="h-full w-full overflow-hidden">
|
|
164
|
+
<ViewportContainer />
|
|
165
|
+
</div>
|
|
166
|
+
</Panel>
|
|
167
|
+
|
|
168
|
+
<PanelResizeHandle className="w-1.5 bg-border hover:bg-primary/50 active:bg-primary/70 transition-colors cursor-col-resize" />
|
|
169
|
+
|
|
170
|
+
{/* Right Panel - Properties, BCF, or IDS */}
|
|
171
|
+
<Panel
|
|
172
|
+
id="right-panel"
|
|
173
|
+
defaultSize={22}
|
|
174
|
+
minSize={15}
|
|
175
|
+
collapsible
|
|
176
|
+
collapsedSize={0}
|
|
177
|
+
>
|
|
178
|
+
<div className="h-full w-full overflow-hidden">
|
|
179
|
+
{lensPanelVisible ? (
|
|
180
|
+
<LensPanel onClose={() => setLensPanelVisible(false)} />
|
|
181
|
+
) : idsPanelVisible ? (
|
|
182
|
+
<IDSPanel onClose={() => setIdsPanelVisible(false)} />
|
|
183
|
+
) : bcfPanelVisible ? (
|
|
184
|
+
<BCFPanel onClose={() => setBcfPanelVisible(false)} />
|
|
185
|
+
) : (
|
|
186
|
+
<PropertiesPanel />
|
|
187
|
+
)}
|
|
188
|
+
</div>
|
|
189
|
+
</Panel>
|
|
190
|
+
</PanelGroup>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
{/* Bottom Panel - Lists (custom resizable, outside PanelGroup) */}
|
|
194
|
+
{listPanelVisible && (
|
|
195
|
+
<div style={{ height: bottomHeight, flexShrink: 0 }} className="relative">
|
|
196
|
+
{/* Drag handle */}
|
|
197
|
+
<div
|
|
198
|
+
className="absolute inset-x-0 top-0 h-1.5 bg-border hover:bg-primary/50 active:bg-primary/70 transition-colors cursor-row-resize z-10"
|
|
199
|
+
onMouseDown={handleResizeStart}
|
|
200
|
+
/>
|
|
201
|
+
<div className="h-full w-full overflow-hidden border-t pt-1.5">
|
|
202
|
+
<ListPanel onClose={() => setListPanelVisible(false)} />
|
|
203
|
+
</div>
|
|
123
204
|
</div>
|
|
124
|
-
|
|
125
|
-
</
|
|
205
|
+
)}
|
|
206
|
+
</div>
|
|
126
207
|
)}
|
|
127
208
|
|
|
128
209
|
{/* Main Content Area - Mobile Layout */}
|
|
@@ -154,18 +235,20 @@ export function ViewerLayout() {
|
|
|
154
235
|
</div>
|
|
155
236
|
)}
|
|
156
237
|
|
|
157
|
-
{/* Mobile Bottom Sheet - Properties, BCF, or
|
|
238
|
+
{/* Mobile Bottom Sheet - Properties, BCF, IDS, or Lists */}
|
|
158
239
|
{!rightPanelCollapsed && (
|
|
159
240
|
<div className="absolute inset-x-0 bottom-0 h-[50vh] bg-background border-t rounded-t-xl shadow-xl z-40 animate-in slide-in-from-bottom">
|
|
160
241
|
<div className="flex items-center justify-between p-2 border-b">
|
|
161
242
|
<span className="font-medium text-sm">
|
|
162
|
-
{idsPanelVisible ? 'IDS Validation' : bcfPanelVisible ? 'BCF Issues' : 'Properties'}
|
|
243
|
+
{listPanelVisible ? 'Lists' : lensPanelVisible ? 'Lens' : idsPanelVisible ? 'IDS Validation' : bcfPanelVisible ? 'BCF Issues' : 'Properties'}
|
|
163
244
|
</span>
|
|
164
245
|
<button
|
|
165
246
|
className="p-1 hover:bg-muted rounded"
|
|
166
247
|
onClick={() => {
|
|
167
248
|
setRightPanelCollapsed(true);
|
|
249
|
+
if (listPanelVisible) setListPanelVisible(false);
|
|
168
250
|
if (bcfPanelVisible) setBcfPanelVisible(false);
|
|
251
|
+
if (lensPanelVisible) setLensPanelVisible(false);
|
|
169
252
|
if (idsPanelVisible) setIdsPanelVisible(false);
|
|
170
253
|
}}
|
|
171
254
|
>
|
|
@@ -176,7 +259,11 @@ export function ViewerLayout() {
|
|
|
176
259
|
</button>
|
|
177
260
|
</div>
|
|
178
261
|
<div className="h-[calc(50vh-48px)] overflow-auto">
|
|
179
|
-
{
|
|
262
|
+
{listPanelVisible ? (
|
|
263
|
+
<ListPanel onClose={() => setListPanelVisible(false)} />
|
|
264
|
+
) : lensPanelVisible ? (
|
|
265
|
+
<LensPanel onClose={() => setLensPanelVisible(false)} />
|
|
266
|
+
) : idsPanelVisible ? (
|
|
180
267
|
<IDSPanel onClose={() => setIdsPanelVisible(false)} />
|
|
181
268
|
) : bcfPanelVisible ? (
|
|
182
269
|
<BCFPanel onClose={() => setBcfPanelVisible(false)} />
|