@ifc-lite/bcf 1.14.2 → 1.15.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/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/overlay-renderer.d.ts +69 -0
- package/dist/overlay-renderer.d.ts.map +1 -0
- package/dist/overlay-renderer.js +419 -0
- package/dist/overlay-renderer.js.map +1 -0
- package/dist/overlay.d.ts +130 -0
- package/dist/overlay.d.ts.map +1 -0
- package/dist/overlay.js +152 -0
- package/dist/overlay.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ export { readBCF } from './reader.js';
|
|
|
13
13
|
export { writeBCF } from './writer.js';
|
|
14
14
|
export type { ViewerCameraState, ViewerSectionPlane, ViewerBounds } from './viewpoint.js';
|
|
15
15
|
export { cameraToPerspective, cameraToOrthogonal, perspectiveToCamera, orthogonalToCamera, sectionPlaneToClippingPlane, clippingPlaneToSectionPlane, createViewpoint, extractViewpointState, } from './viewpoint.js';
|
|
16
|
+
export type { OverlayPoint3D, OverlayBBox, BCFMarker3D, BCFOverlayProjection, EntityBoundsLookup, ComputeMarkersOptions, } from './overlay.js';
|
|
17
|
+
export { computeMarkerPositions } from './overlay.js';
|
|
18
|
+
export type { BCFOverlayRendererOptions } from './overlay-renderer.js';
|
|
19
|
+
export { BCFOverlayRenderer } from './overlay-renderer.js';
|
|
16
20
|
export type { IDSReportInput, IDSSpecResultInput, IDSEntityResultInput, IDSRequirementResultInput, IDSBCFExportOptions, EntityBoundsInput, } from './ids-reporter.js';
|
|
17
21
|
export { createBCFFromIDSReport } from './ids-reporter.js';
|
|
18
22
|
import type { BCFProject, BCFTopic, BCFComment, BCFViewpoint } from './types.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,8 @@ export { readBCF } from './reader.js';
|
|
|
8
8
|
// Writer
|
|
9
9
|
export { writeBCF } from './writer.js';
|
|
10
10
|
export { cameraToPerspective, cameraToOrthogonal, perspectiveToCamera, orthogonalToCamera, sectionPlaneToClippingPlane, clippingPlaneToSectionPlane, createViewpoint, extractViewpointState, } from './viewpoint.js';
|
|
11
|
+
export { computeMarkerPositions } from './overlay.js';
|
|
12
|
+
export { BCFOverlayRenderer } from './overlay-renderer.js';
|
|
11
13
|
export { createBCFFromIDSReport } from './ids-reporter.js';
|
|
12
14
|
import { generateUuid } from './guid.js';
|
|
13
15
|
/**
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BCF 3D Overlay Renderer — pure DOM, no framework dependency.
|
|
3
|
+
*
|
|
4
|
+
* Renders BCFMarker3D items as positioned HTML elements overlaid on a 3D
|
|
5
|
+
* canvas. Works with any renderer that implements BCFOverlayProjection.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Markers anchored to 3D objects — track correctly during orbit/pan/zoom
|
|
9
|
+
* - Color-coded by priority / status
|
|
10
|
+
* - Click, hover callbacks
|
|
11
|
+
* - Continuous re-projection every frame via onCameraChange
|
|
12
|
+
* - Connector lines from marker to projected anchor point
|
|
13
|
+
* - Depth-based scaling (farther markers appear smaller)
|
|
14
|
+
*/
|
|
15
|
+
import type { BCFMarker3D, BCFOverlayProjection } from './overlay.js';
|
|
16
|
+
export interface BCFOverlayRendererOptions {
|
|
17
|
+
/** Show connector lines from marker to 3D anchor (default true) */
|
|
18
|
+
showConnectors?: boolean;
|
|
19
|
+
/** Show tooltip on hover (default true) */
|
|
20
|
+
showTooltips?: boolean;
|
|
21
|
+
/** Minimum marker scale at far distance (default 0.65) */
|
|
22
|
+
minScale?: number;
|
|
23
|
+
/** Maximum marker scale at near distance (default 1.0) */
|
|
24
|
+
maxScale?: number;
|
|
25
|
+
/** Offset in pixels above the projected point (default 36) */
|
|
26
|
+
verticalOffset?: number;
|
|
27
|
+
}
|
|
28
|
+
export declare class BCFOverlayRenderer {
|
|
29
|
+
private container;
|
|
30
|
+
private svgLayer;
|
|
31
|
+
private markerElements;
|
|
32
|
+
private connectorElements;
|
|
33
|
+
private markers;
|
|
34
|
+
private activeMarkerId;
|
|
35
|
+
private projection;
|
|
36
|
+
private unsubCamera;
|
|
37
|
+
private clickCallbacks;
|
|
38
|
+
private hoverCallbacks;
|
|
39
|
+
private opts;
|
|
40
|
+
private _visible;
|
|
41
|
+
private _disposed;
|
|
42
|
+
constructor(parentElement: HTMLElement, projection: BCFOverlayProjection, options?: BCFOverlayRendererOptions);
|
|
43
|
+
/** Update the set of markers to display */
|
|
44
|
+
setMarkers(markers: BCFMarker3D[]): void;
|
|
45
|
+
/** Highlight a specific marker as active */
|
|
46
|
+
setActiveMarker(topicGuid: string | null): void;
|
|
47
|
+
/** Show/hide the entire overlay layer */
|
|
48
|
+
setVisible(visible: boolean): void;
|
|
49
|
+
/** Register click callback */
|
|
50
|
+
onMarkerClick(callback: (topicGuid: string) => void): () => void;
|
|
51
|
+
/** Register hover callback */
|
|
52
|
+
onMarkerHover(callback: (topicGuid: string | null) => void): () => void;
|
|
53
|
+
/**
|
|
54
|
+
* Re-project all markers from world space to screen space.
|
|
55
|
+
* Called directly from the camera-change polling RAF — no extra
|
|
56
|
+
* scheduling, so markers track the camera with zero frame delay.
|
|
57
|
+
*/
|
|
58
|
+
updatePositions(): void;
|
|
59
|
+
/** Clean up all DOM elements and listeners */
|
|
60
|
+
dispose(): void;
|
|
61
|
+
private createMarkerElement;
|
|
62
|
+
private updateMarkerContent;
|
|
63
|
+
private updateMarkerInnerHTML;
|
|
64
|
+
private getPriorityColor;
|
|
65
|
+
private escapeHtml;
|
|
66
|
+
private static stylesInjected;
|
|
67
|
+
private injectStyles;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=overlay-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlay-renderer.d.ts","sourceRoot":"","sources":["../src/overlay-renderer.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AA8BtE,MAAM,WAAW,yBAAyB;IACxC,mEAAmE;IACnE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,cAAc,CAA0C;IAChE,OAAO,CAAC,iBAAiB,CAA0C;IACnE,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,cAAc,CAA0C;IAChE,OAAO,CAAC,cAAc,CAAiD;IACvE,OAAO,CAAC,IAAI,CAAsC;IAClD,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,SAAS,CAAS;gBAGxB,aAAa,EAAE,WAAW,EAC1B,UAAU,EAAE,oBAAoB,EAChC,OAAO,CAAC,EAAE,yBAAyB;IAmCrC,2CAA2C;IAC3C,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI;IA8BxC,4CAA4C;IAC5C,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAY/C,yCAAyC;IACzC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKlC,8BAA8B;IAC9B,aAAa,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAOhE,8BAA8B;IAC9B,aAAa,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI;IAOvE;;;;OAIG;IACH,eAAe,IAAI,IAAI;IAuFvB,8CAA8C;IAC9C,OAAO,IAAI,IAAI;IAcf,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAS;IAEtC,OAAO,CAAC,YAAY;CA6HrB"}
|
|
@@ -0,0 +1,419 @@
|
|
|
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
|
+
// Constants
|
|
6
|
+
// ============================================================================
|
|
7
|
+
const MARKER_CLASS = 'bcf-overlay-marker';
|
|
8
|
+
const CONNECTOR_CLASS = 'bcf-overlay-connector';
|
|
9
|
+
const ACTIVE_CLASS = 'bcf-overlay-active';
|
|
10
|
+
const TOOLTIP_CLASS = 'bcf-overlay-tooltip';
|
|
11
|
+
const PRIORITY_COLORS = {
|
|
12
|
+
high: '#f7768e',
|
|
13
|
+
critical: '#f7768e',
|
|
14
|
+
medium: '#ff9e64',
|
|
15
|
+
normal: '#ff9e64',
|
|
16
|
+
low: '#9ece6a',
|
|
17
|
+
};
|
|
18
|
+
const STATUS_ICONS = {
|
|
19
|
+
open: '●',
|
|
20
|
+
'in progress': '◐',
|
|
21
|
+
resolved: '✓',
|
|
22
|
+
closed: '○',
|
|
23
|
+
};
|
|
24
|
+
export class BCFOverlayRenderer {
|
|
25
|
+
container;
|
|
26
|
+
svgLayer;
|
|
27
|
+
markerElements = new Map();
|
|
28
|
+
connectorElements = new Map();
|
|
29
|
+
markers = [];
|
|
30
|
+
activeMarkerId = null;
|
|
31
|
+
projection;
|
|
32
|
+
unsubCamera = null;
|
|
33
|
+
clickCallbacks = [];
|
|
34
|
+
hoverCallbacks = [];
|
|
35
|
+
opts;
|
|
36
|
+
_visible = true;
|
|
37
|
+
_disposed = false;
|
|
38
|
+
constructor(parentElement, projection, options) {
|
|
39
|
+
this.projection = projection;
|
|
40
|
+
this.opts = {
|
|
41
|
+
showConnectors: options?.showConnectors ?? true,
|
|
42
|
+
showTooltips: options?.showTooltips ?? true,
|
|
43
|
+
minScale: options?.minScale ?? 0.65,
|
|
44
|
+
maxScale: options?.maxScale ?? 1.0,
|
|
45
|
+
verticalOffset: options?.verticalOffset ?? 36,
|
|
46
|
+
};
|
|
47
|
+
// Create overlay container (positioned over the canvas)
|
|
48
|
+
this.container = document.createElement('div');
|
|
49
|
+
this.container.style.cssText =
|
|
50
|
+
'position:absolute;inset:0;pointer-events:none;overflow:hidden;z-index:20;';
|
|
51
|
+
parentElement.appendChild(this.container);
|
|
52
|
+
// Create SVG layer for connector lines
|
|
53
|
+
this.svgLayer = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
54
|
+
this.svgLayer.style.cssText =
|
|
55
|
+
'position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;';
|
|
56
|
+
this.container.appendChild(this.svgLayer);
|
|
57
|
+
// Inject shared styles once
|
|
58
|
+
this.injectStyles();
|
|
59
|
+
// Subscribe to camera changes — callback fires synchronously in the
|
|
60
|
+
// polling RAF so we project in the same frame, zero lag.
|
|
61
|
+
this.unsubCamera = projection.onCameraChange(() => this.updatePositions());
|
|
62
|
+
}
|
|
63
|
+
// --------------------------------------------------------------------------
|
|
64
|
+
// Public API
|
|
65
|
+
// --------------------------------------------------------------------------
|
|
66
|
+
/** Update the set of markers to display */
|
|
67
|
+
setMarkers(markers) {
|
|
68
|
+
this.markers = markers;
|
|
69
|
+
// Remove elements for markers no longer present
|
|
70
|
+
const newGuids = new Set(markers.map((m) => m.topicGuid));
|
|
71
|
+
for (const [guid, el] of this.markerElements) {
|
|
72
|
+
if (!newGuids.has(guid)) {
|
|
73
|
+
el.remove();
|
|
74
|
+
this.markerElements.delete(guid);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
for (const [guid, el] of this.connectorElements) {
|
|
78
|
+
if (!newGuids.has(guid)) {
|
|
79
|
+
el.remove();
|
|
80
|
+
this.connectorElements.delete(guid);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Create/update marker elements
|
|
84
|
+
for (const marker of markers) {
|
|
85
|
+
if (!this.markerElements.has(marker.topicGuid)) {
|
|
86
|
+
this.createMarkerElement(marker);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this.updateMarkerContent(marker);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
this.updatePositions();
|
|
93
|
+
}
|
|
94
|
+
/** Highlight a specific marker as active */
|
|
95
|
+
setActiveMarker(topicGuid) {
|
|
96
|
+
if (this.activeMarkerId) {
|
|
97
|
+
const prev = this.markerElements.get(this.activeMarkerId);
|
|
98
|
+
if (prev)
|
|
99
|
+
prev.classList.remove(ACTIVE_CLASS);
|
|
100
|
+
}
|
|
101
|
+
this.activeMarkerId = topicGuid;
|
|
102
|
+
if (topicGuid) {
|
|
103
|
+
const el = this.markerElements.get(topicGuid);
|
|
104
|
+
if (el)
|
|
105
|
+
el.classList.add(ACTIVE_CLASS);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** Show/hide the entire overlay layer */
|
|
109
|
+
setVisible(visible) {
|
|
110
|
+
this._visible = visible;
|
|
111
|
+
this.container.style.display = visible ? '' : 'none';
|
|
112
|
+
}
|
|
113
|
+
/** Register click callback */
|
|
114
|
+
onMarkerClick(callback) {
|
|
115
|
+
this.clickCallbacks.push(callback);
|
|
116
|
+
return () => {
|
|
117
|
+
this.clickCallbacks = this.clickCallbacks.filter((c) => c !== callback);
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/** Register hover callback */
|
|
121
|
+
onMarkerHover(callback) {
|
|
122
|
+
this.hoverCallbacks.push(callback);
|
|
123
|
+
return () => {
|
|
124
|
+
this.hoverCallbacks = this.hoverCallbacks.filter((c) => c !== callback);
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Re-project all markers from world space to screen space.
|
|
129
|
+
* Called directly from the camera-change polling RAF — no extra
|
|
130
|
+
* scheduling, so markers track the camera with zero frame delay.
|
|
131
|
+
*/
|
|
132
|
+
updatePositions() {
|
|
133
|
+
if (this._disposed || !this._visible)
|
|
134
|
+
return;
|
|
135
|
+
const { width, height } = this.projection.getCanvasSize();
|
|
136
|
+
if (width === 0 || height === 0)
|
|
137
|
+
return;
|
|
138
|
+
const camPos = this.projection.getCameraPosition?.();
|
|
139
|
+
for (const marker of this.markers) {
|
|
140
|
+
const el = this.markerElements.get(marker.topicGuid);
|
|
141
|
+
if (!el)
|
|
142
|
+
continue;
|
|
143
|
+
// Project the marker's world-space position to screen
|
|
144
|
+
const markerScreen = this.projection.projectToScreen(marker.position);
|
|
145
|
+
if (!markerScreen ||
|
|
146
|
+
markerScreen.x < -80 || markerScreen.y < -80 ||
|
|
147
|
+
markerScreen.x > width + 80 || markerScreen.y > height + 80) {
|
|
148
|
+
el.style.display = 'none';
|
|
149
|
+
const conn = this.connectorElements.get(marker.topicGuid);
|
|
150
|
+
if (conn)
|
|
151
|
+
conn.style.display = 'none';
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
el.style.display = '';
|
|
155
|
+
// Depth-based scaling: farther markers appear smaller
|
|
156
|
+
let scale = 1.0;
|
|
157
|
+
if (camPos) {
|
|
158
|
+
const dx = marker.position.x - camPos.x;
|
|
159
|
+
const dy = marker.position.y - camPos.y;
|
|
160
|
+
const dz = marker.position.z - camPos.z;
|
|
161
|
+
const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
162
|
+
const t = Math.max(0, Math.min(1, (dist - 20) / 180));
|
|
163
|
+
scale = this.opts.maxScale + t * (this.opts.minScale - this.opts.maxScale);
|
|
164
|
+
}
|
|
165
|
+
// Position the marker pin at the projected point
|
|
166
|
+
const markerX = markerScreen.x;
|
|
167
|
+
const markerY = markerScreen.y;
|
|
168
|
+
el.style.transform =
|
|
169
|
+
`translate(${markerX}px, ${markerY}px) translate(-50%, -100%) scale(${scale.toFixed(3)})`;
|
|
170
|
+
// Depth-based opacity: far markers slightly translucent
|
|
171
|
+
const opacity = camPos
|
|
172
|
+
? 0.6 + (1 - Math.max(0, Math.min(1, (Math.sqrt((marker.position.x - camPos.x) ** 2 +
|
|
173
|
+
(marker.position.y - camPos.y) ** 2 +
|
|
174
|
+
(marker.position.z - camPos.z) ** 2) - 20) / 250))) * 0.4
|
|
175
|
+
: 1;
|
|
176
|
+
el.style.opacity = opacity.toFixed(2);
|
|
177
|
+
// Connector line from marker to the anchor point (bbox top-center)
|
|
178
|
+
if (this.opts.showConnectors) {
|
|
179
|
+
const anchor = marker.connectorAnchor ?? marker.position;
|
|
180
|
+
const anchorScreen = this.projection.projectToScreen(anchor);
|
|
181
|
+
let conn = this.connectorElements.get(marker.topicGuid);
|
|
182
|
+
if (!conn) {
|
|
183
|
+
conn = document.createElementNS('http://www.w3.org/2000/svg', 'line');
|
|
184
|
+
conn.classList.add(CONNECTOR_CLASS);
|
|
185
|
+
this.svgLayer.appendChild(conn);
|
|
186
|
+
this.connectorElements.set(marker.topicGuid, conn);
|
|
187
|
+
}
|
|
188
|
+
if (!anchorScreen) {
|
|
189
|
+
conn.style.display = 'none';
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
conn.style.display = '';
|
|
193
|
+
const color = this.getPriorityColor(marker.priority);
|
|
194
|
+
conn.setAttribute('x1', String(markerX));
|
|
195
|
+
conn.setAttribute('y1', String(markerY));
|
|
196
|
+
conn.setAttribute('x2', String(anchorScreen.x));
|
|
197
|
+
conn.setAttribute('y2', String(anchorScreen.y));
|
|
198
|
+
conn.setAttribute('stroke', color);
|
|
199
|
+
conn.setAttribute('stroke-width', '1.5');
|
|
200
|
+
conn.setAttribute('stroke-dasharray', '3 2');
|
|
201
|
+
conn.setAttribute('stroke-opacity', String((opacity * 0.5).toFixed(2)));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/** Clean up all DOM elements and listeners */
|
|
206
|
+
dispose() {
|
|
207
|
+
this._disposed = true;
|
|
208
|
+
if (this.unsubCamera)
|
|
209
|
+
this.unsubCamera();
|
|
210
|
+
this.container.remove();
|
|
211
|
+
this.markerElements.clear();
|
|
212
|
+
this.connectorElements.clear();
|
|
213
|
+
this.clickCallbacks = [];
|
|
214
|
+
this.hoverCallbacks = [];
|
|
215
|
+
}
|
|
216
|
+
// --------------------------------------------------------------------------
|
|
217
|
+
// Internal
|
|
218
|
+
// --------------------------------------------------------------------------
|
|
219
|
+
createMarkerElement(marker) {
|
|
220
|
+
const el = document.createElement('div');
|
|
221
|
+
el.className = MARKER_CLASS;
|
|
222
|
+
el.dataset.topicGuid = marker.topicGuid;
|
|
223
|
+
this.updateMarkerInnerHTML(el, marker);
|
|
224
|
+
// Click handler
|
|
225
|
+
el.addEventListener('click', (e) => {
|
|
226
|
+
e.stopPropagation();
|
|
227
|
+
for (const cb of this.clickCallbacks)
|
|
228
|
+
cb(marker.topicGuid);
|
|
229
|
+
});
|
|
230
|
+
// Hover handlers
|
|
231
|
+
el.addEventListener('mouseenter', () => {
|
|
232
|
+
for (const cb of this.hoverCallbacks)
|
|
233
|
+
cb(marker.topicGuid);
|
|
234
|
+
const tooltip = el.querySelector(`.${TOOLTIP_CLASS}`);
|
|
235
|
+
if (tooltip)
|
|
236
|
+
tooltip.style.display = '';
|
|
237
|
+
});
|
|
238
|
+
el.addEventListener('mouseleave', () => {
|
|
239
|
+
for (const cb of this.hoverCallbacks)
|
|
240
|
+
cb(null);
|
|
241
|
+
const tooltip = el.querySelector(`.${TOOLTIP_CLASS}`);
|
|
242
|
+
if (tooltip)
|
|
243
|
+
tooltip.style.display = 'none';
|
|
244
|
+
});
|
|
245
|
+
if (marker.topicGuid === this.activeMarkerId) {
|
|
246
|
+
el.classList.add(ACTIVE_CLASS);
|
|
247
|
+
}
|
|
248
|
+
this.container.appendChild(el);
|
|
249
|
+
this.markerElements.set(marker.topicGuid, el);
|
|
250
|
+
}
|
|
251
|
+
updateMarkerContent(marker) {
|
|
252
|
+
const el = this.markerElements.get(marker.topicGuid);
|
|
253
|
+
if (!el)
|
|
254
|
+
return;
|
|
255
|
+
this.updateMarkerInnerHTML(el, marker);
|
|
256
|
+
if (marker.topicGuid === this.activeMarkerId) {
|
|
257
|
+
el.classList.add(ACTIVE_CLASS);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
el.classList.remove(ACTIVE_CLASS);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
updateMarkerInnerHTML(el, marker) {
|
|
264
|
+
const color = this.getPriorityColor(marker.priority);
|
|
265
|
+
const statusIcon = STATUS_ICONS[marker.status.toLowerCase()] ?? '●';
|
|
266
|
+
el.innerHTML = `
|
|
267
|
+
<div class="bcf-marker-pin" style="--marker-color:${color};">
|
|
268
|
+
<span class="bcf-marker-index">${marker.index}</span>
|
|
269
|
+
</div>
|
|
270
|
+
<div class="${TOOLTIP_CLASS}" style="display:none;">
|
|
271
|
+
<div class="bcf-tooltip-header">
|
|
272
|
+
<span class="bcf-tooltip-status" style="color:${color}">${statusIcon}</span>
|
|
273
|
+
<span class="bcf-tooltip-title">${this.escapeHtml(marker.title)}</span>
|
|
274
|
+
</div>
|
|
275
|
+
<div class="bcf-tooltip-meta">
|
|
276
|
+
${this.escapeHtml(marker.status)}${marker.commentCount > 0 ? ` · ${marker.commentCount} comment${marker.commentCount !== 1 ? 's' : ''}` : ''}
|
|
277
|
+
</div>
|
|
278
|
+
</div>
|
|
279
|
+
`;
|
|
280
|
+
}
|
|
281
|
+
getPriorityColor(priority) {
|
|
282
|
+
return PRIORITY_COLORS[priority.toLowerCase()] ?? '#7aa2f7';
|
|
283
|
+
}
|
|
284
|
+
escapeHtml(text) {
|
|
285
|
+
const div = document.createElement('div');
|
|
286
|
+
div.textContent = text;
|
|
287
|
+
return div.innerHTML;
|
|
288
|
+
}
|
|
289
|
+
// --------------------------------------------------------------------------
|
|
290
|
+
// Shared CSS (injected once per document)
|
|
291
|
+
// --------------------------------------------------------------------------
|
|
292
|
+
static stylesInjected = false;
|
|
293
|
+
injectStyles() {
|
|
294
|
+
if (BCFOverlayRenderer.stylesInjected)
|
|
295
|
+
return;
|
|
296
|
+
BCFOverlayRenderer.stylesInjected = true;
|
|
297
|
+
const style = document.createElement('style');
|
|
298
|
+
style.textContent = `
|
|
299
|
+
/* BCF 3D Overlay Markers */
|
|
300
|
+
|
|
301
|
+
.${MARKER_CLASS} {
|
|
302
|
+
position: absolute;
|
|
303
|
+
left: 0;
|
|
304
|
+
top: 0;
|
|
305
|
+
pointer-events: auto;
|
|
306
|
+
cursor: pointer;
|
|
307
|
+
will-change: transform, opacity;
|
|
308
|
+
z-index: 21;
|
|
309
|
+
filter: drop-shadow(0 2px 6px rgba(0,0,0,0.35));
|
|
310
|
+
transform-origin: center bottom;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.bcf-marker-pin {
|
|
314
|
+
width: 28px;
|
|
315
|
+
height: 28px;
|
|
316
|
+
border-radius: 50% 50% 50% 0;
|
|
317
|
+
background: var(--marker-color, #7aa2f7);
|
|
318
|
+
transform: rotate(-45deg);
|
|
319
|
+
display: flex;
|
|
320
|
+
align-items: center;
|
|
321
|
+
justify-content: center;
|
|
322
|
+
border: 2px solid rgba(255,255,255,0.9);
|
|
323
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.25);
|
|
324
|
+
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.${MARKER_CLASS}:hover .bcf-marker-pin {
|
|
328
|
+
transform: rotate(-45deg) scale(1.2);
|
|
329
|
+
box-shadow: 0 4px 16px rgba(0,0,0,0.4);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.${ACTIVE_CLASS} .bcf-marker-pin {
|
|
333
|
+
transform: rotate(-45deg) scale(1.25);
|
|
334
|
+
box-shadow: 0 0 0 4px rgba(122,162,247,0.35), 0 4px 16px rgba(0,0,0,0.4);
|
|
335
|
+
animation: bcf-pulse 1.8s ease-in-out infinite;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.bcf-marker-index {
|
|
339
|
+
transform: rotate(45deg);
|
|
340
|
+
font-size: 11px;
|
|
341
|
+
font-weight: 700;
|
|
342
|
+
color: white;
|
|
343
|
+
font-family: ui-monospace, monospace;
|
|
344
|
+
line-height: 1;
|
|
345
|
+
user-select: none;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/* Tooltip */
|
|
349
|
+
.${TOOLTIP_CLASS} {
|
|
350
|
+
position: absolute;
|
|
351
|
+
bottom: calc(100% + 6px);
|
|
352
|
+
left: 50%;
|
|
353
|
+
transform: translateX(-50%);
|
|
354
|
+
background: #1a1b26;
|
|
355
|
+
color: #a9b1d6;
|
|
356
|
+
border: 1px solid #3b4261;
|
|
357
|
+
padding: 8px 12px;
|
|
358
|
+
min-width: 160px;
|
|
359
|
+
max-width: 260px;
|
|
360
|
+
font-family: ui-monospace, monospace;
|
|
361
|
+
font-size: 11px;
|
|
362
|
+
line-height: 1.4;
|
|
363
|
+
white-space: nowrap;
|
|
364
|
+
z-index: 100;
|
|
365
|
+
pointer-events: none;
|
|
366
|
+
box-shadow: 0 4px 16px rgba(0,0,0,0.5);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.${TOOLTIP_CLASS}::after {
|
|
370
|
+
content: '';
|
|
371
|
+
position: absolute;
|
|
372
|
+
top: 100%;
|
|
373
|
+
left: 50%;
|
|
374
|
+
transform: translateX(-50%);
|
|
375
|
+
border: 5px solid transparent;
|
|
376
|
+
border-top-color: #3b4261;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
.bcf-tooltip-header {
|
|
380
|
+
display: flex;
|
|
381
|
+
align-items: center;
|
|
382
|
+
gap: 6px;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.bcf-tooltip-status {
|
|
386
|
+
font-size: 10px;
|
|
387
|
+
flex-shrink: 0;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
.bcf-tooltip-title {
|
|
391
|
+
font-weight: 600;
|
|
392
|
+
color: #c0caf5;
|
|
393
|
+
overflow: hidden;
|
|
394
|
+
text-overflow: ellipsis;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
.bcf-tooltip-meta {
|
|
398
|
+
margin-top: 3px;
|
|
399
|
+
font-size: 10px;
|
|
400
|
+
color: #565f89;
|
|
401
|
+
text-transform: uppercase;
|
|
402
|
+
letter-spacing: 0.05em;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/* Connector lines */
|
|
406
|
+
.${CONNECTOR_CLASS} {
|
|
407
|
+
pointer-events: none;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/* Pulse animation for active marker */
|
|
411
|
+
@keyframes bcf-pulse {
|
|
412
|
+
0%, 100% { box-shadow: 0 0 0 4px rgba(122,162,247,0.35), 0 4px 16px rgba(0,0,0,0.4); }
|
|
413
|
+
50% { box-shadow: 0 0 0 8px rgba(122,162,247,0.1), 0 4px 16px rgba(0,0,0,0.4); }
|
|
414
|
+
}
|
|
415
|
+
`;
|
|
416
|
+
document.head.appendChild(style);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
//# sourceMappingURL=overlay-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlay-renderer.js","sourceRoot":"","sources":["../src/overlay-renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BCF 3D Overlay — viewer-agnostic types and position computation
|
|
3
|
+
*
|
|
4
|
+
* Derives 3D marker positions from BCF topics so they can be rendered
|
|
5
|
+
* as floating overlays in any 3D viewer (WebGPU, Three.js, Babylon, etc.).
|
|
6
|
+
*
|
|
7
|
+
* Position derivation strategy (in priority order):
|
|
8
|
+
* 1. Selected component bounding-box center (most accurate)
|
|
9
|
+
* 2. Camera target point — the orbit center from the viewpoint (robust fallback)
|
|
10
|
+
* 3. Camera viewpoint position itself (last resort)
|
|
11
|
+
*/
|
|
12
|
+
import type { BCFTopic } from './types.js';
|
|
13
|
+
/** A 3D point in the viewer's Y-up coordinate system */
|
|
14
|
+
export interface OverlayPoint3D {
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
z: number;
|
|
18
|
+
}
|
|
19
|
+
/** Axis-aligned bounding box */
|
|
20
|
+
export interface OverlayBBox {
|
|
21
|
+
min: OverlayPoint3D;
|
|
22
|
+
max: OverlayPoint3D;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A positioned 3D marker derived from a BCF topic.
|
|
26
|
+
* Contains everything a renderer needs to display the marker.
|
|
27
|
+
*/
|
|
28
|
+
export interface BCFMarker3D {
|
|
29
|
+
/** Topic GUID — unique identifier */
|
|
30
|
+
topicGuid: string;
|
|
31
|
+
/**
|
|
32
|
+
* World-space position (Y-up) where the marker pin-tip sits.
|
|
33
|
+
* For component-based markers this is well above the bbox top
|
|
34
|
+
* so the marker floats above geometry from any camera angle.
|
|
35
|
+
*/
|
|
36
|
+
position: OverlayPoint3D;
|
|
37
|
+
/**
|
|
38
|
+
* World-space anchor point where the connector line ends.
|
|
39
|
+
* Typically the bbox top-center of the referenced component.
|
|
40
|
+
* If absent, the connector ends at `position`.
|
|
41
|
+
*/
|
|
42
|
+
connectorAnchor?: OverlayPoint3D;
|
|
43
|
+
/** Topic title */
|
|
44
|
+
title: string;
|
|
45
|
+
/** Topic status (e.g. 'Open', 'In Progress', 'Resolved', 'Closed') */
|
|
46
|
+
status: string;
|
|
47
|
+
/** Priority (e.g. 'High', 'Medium', 'Low') */
|
|
48
|
+
priority: string;
|
|
49
|
+
/** Topic type (e.g. 'Error', 'Warning', 'Info') */
|
|
50
|
+
topicType: string;
|
|
51
|
+
/** Number of comments */
|
|
52
|
+
commentCount: number;
|
|
53
|
+
/** Whether the topic has at least one viewpoint */
|
|
54
|
+
hasViewpoint: boolean;
|
|
55
|
+
/** Optional snapshot thumbnail (data URL) from the first viewpoint */
|
|
56
|
+
snapshot?: string;
|
|
57
|
+
/** How the position was derived — useful for debugging */
|
|
58
|
+
positionSource: 'component' | 'camera-target' | 'camera-position';
|
|
59
|
+
/** Topic index (for numbering markers) */
|
|
60
|
+
index: number;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Viewer-agnostic projection interface.
|
|
64
|
+
* Each renderer (WebGPU, Three.js, Babylon.js, etc.) provides an
|
|
65
|
+
* implementation of this interface to enable BCF 3D overlays.
|
|
66
|
+
*/
|
|
67
|
+
export interface BCFOverlayProjection {
|
|
68
|
+
/**
|
|
69
|
+
* Project a world-space position to screen coordinates (pixels).
|
|
70
|
+
* Returns null if the point is behind the camera.
|
|
71
|
+
*/
|
|
72
|
+
projectToScreen(worldPos: OverlayPoint3D): {
|
|
73
|
+
x: number;
|
|
74
|
+
y: number;
|
|
75
|
+
} | null;
|
|
76
|
+
/**
|
|
77
|
+
* Get the axis-aligned bounding box for an entity by its expressId.
|
|
78
|
+
* Returns null if the entity is not found.
|
|
79
|
+
*/
|
|
80
|
+
getEntityBounds(expressId: number): OverlayBBox | null;
|
|
81
|
+
/** Get the canvas/viewport dimensions in pixels */
|
|
82
|
+
getCanvasSize(): {
|
|
83
|
+
width: number;
|
|
84
|
+
height: number;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Get the current camera position in world space (Y-up).
|
|
88
|
+
* Used for depth-based scaling. Optional — markers render at
|
|
89
|
+
* uniform size if not provided.
|
|
90
|
+
*/
|
|
91
|
+
getCameraPosition?(): OverlayPoint3D;
|
|
92
|
+
/**
|
|
93
|
+
* Subscribe to camera/render changes.
|
|
94
|
+
* The callback is invoked **synchronously inside the polling RAF**
|
|
95
|
+
* so the overlay can re-project in the same animation frame
|
|
96
|
+
* for zero-lag tracking during orbit/pan/zoom.
|
|
97
|
+
* Returns an unsubscribe function.
|
|
98
|
+
*/
|
|
99
|
+
onCameraChange(callback: () => void): () => void;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Callback that resolves an IFC GlobalId (22-char base64) to
|
|
103
|
+
* a bounding box in Y-up viewer coordinates.
|
|
104
|
+
* Returns null when the entity is not loaded or has no geometry.
|
|
105
|
+
*/
|
|
106
|
+
export type EntityBoundsLookup = (ifcGuid: string) => OverlayBBox | null;
|
|
107
|
+
export interface ComputeMarkersOptions {
|
|
108
|
+
/**
|
|
109
|
+
* Camera-to-target distance in world units. Used when a viewpoint has
|
|
110
|
+
* camera data but no resolvable component selection. Should match the
|
|
111
|
+
* viewer's camera distance (e.g. `camera.getDistance()`).
|
|
112
|
+
* Default 50.
|
|
113
|
+
*/
|
|
114
|
+
targetDistance?: number;
|
|
115
|
+
/** Only include topics with these statuses (default: all) */
|
|
116
|
+
statusFilter?: string[];
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Compute positioned 3D markers from BCF topics.
|
|
120
|
+
*
|
|
121
|
+
* This is a **pure function** — no DOM, no renderer dependency.
|
|
122
|
+
* It takes a lookup callback so any renderer can provide entity bounds.
|
|
123
|
+
*
|
|
124
|
+
* @param topics Array of BCF topics to create markers for
|
|
125
|
+
* @param boundsLookup Callback to resolve IFC GlobalId → bounding box (Y-up)
|
|
126
|
+
* @param options Optional configuration
|
|
127
|
+
* @returns Array of positioned markers (topics without derivable positions are skipped)
|
|
128
|
+
*/
|
|
129
|
+
export declare function computeMarkerPositions(topics: BCFTopic[], boundsLookup: EntityBoundsLookup, options?: ComputeMarkersOptions): BCFMarker3D[];
|
|
130
|
+
//# sourceMappingURL=overlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../src/overlay.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAA0B,MAAM,YAAY,CAAC;AAMnE,wDAAwD;AACxD,MAAM,WAAW,cAAc;IAC7B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,gCAAgC;AAChC,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,cAAc,CAAC;IACpB,GAAG,EAAE,cAAc,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,QAAQ,EAAE,cAAc,CAAC;IACzB;;;;OAIG;IACH,eAAe,CAAC,EAAE,cAAc,CAAC;IACjC,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,YAAY,EAAE,OAAO,CAAC;IACtB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,cAAc,EAAE,WAAW,GAAG,eAAe,GAAG,iBAAiB,CAAC;IAClE,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;CACf;AAMD;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,eAAe,CAAC,QAAQ,EAAE,cAAc,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAE3E;;;OAGG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IAEvD,mDAAmD;IACnD,aAAa,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAEnD;;;;OAIG;IACH,iBAAiB,CAAC,IAAI,cAAc,CAAC;IAErC;;;;;;OAMG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CAClD;AAMD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,WAAW,GAAG,IAAI,CAAC;AAiIzE,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,QAAQ,EAAE,EAClB,YAAY,EAAE,kBAAkB,EAChC,OAAO,CAAC,EAAE,qBAAqB,GAC9B,WAAW,EAAE,CAyCf"}
|
package/dist/overlay.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
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
|
+
// Position computation — internal helpers
|
|
6
|
+
// ============================================================================
|
|
7
|
+
/**
|
|
8
|
+
* Convert a BCF Z-up point to the viewer's Y-up coordinate system.
|
|
9
|
+
*
|
|
10
|
+
* BCF (Z-up): +X=right, +Y=forward, +Z=up
|
|
11
|
+
* Viewer (Y-up): +X=right, +Y=up, +Z=towards viewer
|
|
12
|
+
*/
|
|
13
|
+
function bcfPointToYUp(p) {
|
|
14
|
+
return { x: p.x, y: p.z, z: -p.y };
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Compute the camera's TARGET point (orbit center) from BCF viewpoint data.
|
|
18
|
+
*
|
|
19
|
+
* BCF only stores viewPoint + direction (no target distance), so we need
|
|
20
|
+
* the distance from the caller. This target is the point the user was
|
|
21
|
+
* looking at — a reliable anchor for the marker.
|
|
22
|
+
*/
|
|
23
|
+
function cameraTargetFromViewpoint(viewpoint, targetDistance) {
|
|
24
|
+
const cam = viewpoint.perspectiveCamera ?? viewpoint.orthogonalCamera;
|
|
25
|
+
if (!cam)
|
|
26
|
+
return null;
|
|
27
|
+
const origin = bcfPointToYUp(cam.cameraViewPoint);
|
|
28
|
+
const dir = bcfPointToYUp(cam.cameraDirection);
|
|
29
|
+
const len = Math.sqrt(dir.x * dir.x + dir.y * dir.y + dir.z * dir.z);
|
|
30
|
+
if (len < 1e-6)
|
|
31
|
+
return null;
|
|
32
|
+
const nx = dir.x / len;
|
|
33
|
+
const ny = dir.y / len;
|
|
34
|
+
const nz = dir.z / len;
|
|
35
|
+
return {
|
|
36
|
+
x: origin.x + nx * targetDistance,
|
|
37
|
+
y: origin.y + ny * targetDistance,
|
|
38
|
+
z: origin.z + nz * targetDistance,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Build marker + anchor from a component bounding box.
|
|
43
|
+
*
|
|
44
|
+
* - `position` is placed well above the bbox top so the marker
|
|
45
|
+
* floats above the element from any camera angle.
|
|
46
|
+
* - `connectorAnchor` is the bbox top-center where the dotted
|
|
47
|
+
* connector line terminates.
|
|
48
|
+
*/
|
|
49
|
+
function markerFromBBox(bbox) {
|
|
50
|
+
const cx = (bbox.min.x + bbox.max.x) / 2;
|
|
51
|
+
const cz = (bbox.min.z + bbox.max.z) / 2;
|
|
52
|
+
const topY = bbox.max.y;
|
|
53
|
+
const height = bbox.max.y - bbox.min.y;
|
|
54
|
+
// Float the marker 30% of height above the top, minimum 0.5 m
|
|
55
|
+
const lift = Math.max(height * 0.3, 0.5);
|
|
56
|
+
return {
|
|
57
|
+
position: { x: cx, y: topY + lift, z: cz },
|
|
58
|
+
connectorAnchor: { x: cx, y: topY, z: cz },
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function positionFromViewpoint(viewpoint, boundsLookup, targetDistance) {
|
|
62
|
+
// Strategy 1: Selected component bounding-box
|
|
63
|
+
const selected = viewpoint.components?.selection;
|
|
64
|
+
if (selected && selected.length > 0) {
|
|
65
|
+
for (const comp of selected) {
|
|
66
|
+
if (!comp.ifcGuid)
|
|
67
|
+
continue;
|
|
68
|
+
const bbox = boundsLookup(comp.ifcGuid);
|
|
69
|
+
if (bbox) {
|
|
70
|
+
const m = markerFromBBox(bbox);
|
|
71
|
+
return { ...m, source: 'component' };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Strategy 1b: Visible-exception components (isolation mode)
|
|
76
|
+
const visibility = viewpoint.components?.visibility;
|
|
77
|
+
if (visibility && !visibility.defaultVisibility && visibility.exceptions && visibility.exceptions.length > 0) {
|
|
78
|
+
for (const comp of visibility.exceptions) {
|
|
79
|
+
if (!comp.ifcGuid)
|
|
80
|
+
continue;
|
|
81
|
+
const bbox = boundsLookup(comp.ifcGuid);
|
|
82
|
+
if (bbox) {
|
|
83
|
+
const m = markerFromBBox(bbox);
|
|
84
|
+
return { ...m, source: 'component' };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Strategy 2: Camera target point (orbit center)
|
|
89
|
+
const target = cameraTargetFromViewpoint(viewpoint, targetDistance);
|
|
90
|
+
if (target) {
|
|
91
|
+
return { position: target, source: 'camera-target' };
|
|
92
|
+
}
|
|
93
|
+
// Strategy 3: Camera viewpoint position (last resort)
|
|
94
|
+
const cam = viewpoint.perspectiveCamera ?? viewpoint.orthogonalCamera;
|
|
95
|
+
if (cam) {
|
|
96
|
+
return {
|
|
97
|
+
position: bcfPointToYUp(cam.cameraViewPoint),
|
|
98
|
+
source: 'camera-position',
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Compute positioned 3D markers from BCF topics.
|
|
105
|
+
*
|
|
106
|
+
* This is a **pure function** — no DOM, no renderer dependency.
|
|
107
|
+
* It takes a lookup callback so any renderer can provide entity bounds.
|
|
108
|
+
*
|
|
109
|
+
* @param topics Array of BCF topics to create markers for
|
|
110
|
+
* @param boundsLookup Callback to resolve IFC GlobalId → bounding box (Y-up)
|
|
111
|
+
* @param options Optional configuration
|
|
112
|
+
* @returns Array of positioned markers (topics without derivable positions are skipped)
|
|
113
|
+
*/
|
|
114
|
+
export function computeMarkerPositions(topics, boundsLookup, options) {
|
|
115
|
+
const { targetDistance = 50, statusFilter } = options ?? {};
|
|
116
|
+
const markers = [];
|
|
117
|
+
for (let i = 0; i < topics.length; i++) {
|
|
118
|
+
const topic = topics[i];
|
|
119
|
+
// Status filter
|
|
120
|
+
if (statusFilter && statusFilter.length > 0) {
|
|
121
|
+
const s = (topic.topicStatus ?? '').toLowerCase();
|
|
122
|
+
if (!statusFilter.some((f) => f.toLowerCase() === s))
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
// Try each viewpoint to derive a position (first valid wins)
|
|
126
|
+
let result = null;
|
|
127
|
+
for (const vp of topic.viewpoints) {
|
|
128
|
+
result = positionFromViewpoint(vp, boundsLookup, targetDistance);
|
|
129
|
+
if (result)
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
if (!result)
|
|
133
|
+
continue;
|
|
134
|
+
const firstVp = topic.viewpoints[0];
|
|
135
|
+
markers.push({
|
|
136
|
+
topicGuid: topic.guid,
|
|
137
|
+
position: result.position,
|
|
138
|
+
connectorAnchor: result.connectorAnchor,
|
|
139
|
+
title: topic.title,
|
|
140
|
+
status: topic.topicStatus ?? 'Open',
|
|
141
|
+
priority: topic.priority ?? 'Normal',
|
|
142
|
+
topicType: topic.topicType ?? 'Issue',
|
|
143
|
+
commentCount: topic.comments.length,
|
|
144
|
+
hasViewpoint: topic.viewpoints.length > 0,
|
|
145
|
+
snapshot: firstVp?.snapshot,
|
|
146
|
+
positionSource: result.source,
|
|
147
|
+
index: topic.index ?? i + 1,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
return markers;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=overlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlay.js","sourceRoot":"","sources":["../src/overlay.ts"],"names":[],"mappings":"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"}
|