@thatopen/services 0.3.10 → 0.3.12
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/cli/commands/revit.d.ts +9 -0
- package/dist/cli/lib/revit-addin.d.ts +20 -0
- package/dist/cli.js +101 -0
- package/dist/cloud/LasToPotree.d.ts +59 -0
- package/dist/cloud/SplatToFq.d.ts +38 -0
- package/dist/cloud/index.d.ts +2 -0
- package/docs/builtin/paths.json +86 -86
- package/docs/cloud/GaussianSplatConverter.md +43 -0
- package/docs/cloud/PointCloudConverter.md +53 -0
- package/docs/revit-collab-quickstart.md +151 -0
- package/package.json +95 -95
- package/src/built-in/ClashesManager/example.ts +283 -283
- package/src/built-in/UIManager/src/clashes-panel/example.ts +160 -160
- package/src/built-in/UIManager/src/models-list/example.ts +122 -118
- package/src/cli/templates/app/README.md +217 -241
- package/src/cli/templates/app/package.json +33 -33
- package/src/cli/templates/app/src/setups/camera-tools.ts +0 -63
- package/src/cli/templates/app/src/setups/camera-views.ts +0 -201
- package/src/cli/templates/app/src/setups/card-header.ts +0 -35
- package/src/cli/templates/app/src/setups/clipper-tool.ts +0 -773
- package/src/cli/templates/app/src/setups/clipper.ts +0 -75
- package/src/cli/templates/app/src/setups/cloud-runner.ts +0 -13
- package/src/cli/templates/app/src/setups/exploded-view.ts +0 -246
- package/src/cli/templates/app/src/setups/helper-panel.ts +0 -88
- package/src/cli/templates/app/src/setups/hider.ts +0 -98
- package/src/cli/templates/app/src/setups/index.ts +0 -23
- package/src/cli/templates/app/src/setups/inspection.ts +0 -136
- package/src/cli/templates/app/src/setups/measurement-panel.ts +0 -188
- package/src/cli/templates/app/src/setups/measurement-tool.ts +0 -588
- package/src/cli/templates/app/src/setups/measurements.ts +0 -133
- package/src/cli/templates/app/src/setups/navigation-gizmo.ts +0 -316
- package/src/cli/templates/app/src/setups/plans-panel.ts +0 -619
- package/src/cli/templates/app/src/setups/right-sidebar.ts +0 -178
- package/src/cli/templates/app/src/setups/styles-panel.ts +0 -110
- package/src/cli/templates/app/src/setups/styles.ts +0 -375
- package/src/cli/templates/app/src/setups/tool-mode-manager.ts +0 -156
- package/src/cli/templates/app/src/setups/tool-mode.ts +0 -23
- package/src/cli/templates/app/src/setups/toolbar.ts +0 -229
- package/src/cli/templates/app/src/setups/ui-manager.ts +0 -27
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import * as THREE from "three";
|
|
2
|
-
import * as OBC from "@thatopen/components";
|
|
3
|
-
import * as BUI from "@thatopen/ui";
|
|
4
|
-
import { cameraTools } from "./camera-tools";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Camera navigation — a COMPACT floating overlay pinned top-right of the
|
|
8
|
-
* viewport (mirrors visibility-toolbar's self-mounting floating-grid overlay).
|
|
9
|
-
*
|
|
10
|
-
* Controls:
|
|
11
|
-
* - View presets (Iso / Top / Bottom / Front / Back / Left / Right) via a
|
|
12
|
-
* compact dropdown. Each frames the union bounding box of all loaded models:
|
|
13
|
-
* `setLookAt` along the preset axis, then `fitToSphere` to frame precisely
|
|
14
|
-
* while keeping the new direction.
|
|
15
|
-
* - Zoom-to-fit + Perspective⇄Orthographic toggle — reused from
|
|
16
|
-
* `cameraTools(components)` (no reimplementation).
|
|
17
|
-
*
|
|
18
|
-
* Self-mounts into the viewport overlay. Wire from main.ts with one line
|
|
19
|
-
* (after the viewport exists), like the visibility toolbar:
|
|
20
|
-
*
|
|
21
|
-
* cameraViews(components, viewerElement);
|
|
22
|
-
*
|
|
23
|
-
* @param components engine components
|
|
24
|
-
* @param container optional viewport element to overlay; if omitted, the first
|
|
25
|
-
* world's renderer container is used.
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
// Preset → camera direction (from target toward camera). Normalized + scaled by
|
|
29
|
-
// the model radius at apply time.
|
|
30
|
-
const VIEWS: Record<string, [number, number, number]> = {
|
|
31
|
-
Iso: [1, 0.8, 1],
|
|
32
|
-
Top: [0, 1, 0],
|
|
33
|
-
Bottom: [0, -1, 0],
|
|
34
|
-
Front: [0, 0, 1],
|
|
35
|
-
Back: [0, 0, -1],
|
|
36
|
-
Left: [-1, 0, 0],
|
|
37
|
-
Right: [1, 0, 0],
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export const cameraViews = (
|
|
41
|
-
components: OBC.Components,
|
|
42
|
-
container?: HTMLElement,
|
|
43
|
-
) => {
|
|
44
|
-
const fragments = components.get(OBC.FragmentsManager);
|
|
45
|
-
const cam = cameraTools(components);
|
|
46
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
47
|
-
const firstWorld = (): any => [...components.get(OBC.Worlds).list.values()][0];
|
|
48
|
-
|
|
49
|
-
const unionBox = () => {
|
|
50
|
-
const box = new THREE.Box3();
|
|
51
|
-
for (const model of fragments.list.values()) {
|
|
52
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
53
|
-
const b = (model as any).box as THREE.Box3 | undefined;
|
|
54
|
-
if (b && !b.isEmpty()) box.union(b);
|
|
55
|
-
}
|
|
56
|
-
return box;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const setView = async (name: string) => {
|
|
60
|
-
const dir = VIEWS[name];
|
|
61
|
-
if (!dir) return;
|
|
62
|
-
const controls = firstWorld()?.camera?.controls;
|
|
63
|
-
if (!controls?.setLookAt) return;
|
|
64
|
-
const box = unionBox();
|
|
65
|
-
if (box.isEmpty()) return;
|
|
66
|
-
const sphere = box.getBoundingSphere(new THREE.Sphere());
|
|
67
|
-
const r = sphere.radius || 1;
|
|
68
|
-
const c = sphere.center;
|
|
69
|
-
const v = new THREE.Vector3(dir[0], dir[1], dir[2])
|
|
70
|
-
.normalize()
|
|
71
|
-
.multiplyScalar(r * 3);
|
|
72
|
-
try {
|
|
73
|
-
// Move to the preset direction, then frame the sphere exactly (keeps the
|
|
74
|
-
// new direction, snaps the distance to fit).
|
|
75
|
-
await controls.setLookAt(
|
|
76
|
-
c.x + v.x, c.y + v.y, c.z + v.z,
|
|
77
|
-
c.x, c.y, c.z,
|
|
78
|
-
true,
|
|
79
|
-
);
|
|
80
|
-
await controls.fitToSphere(sphere, true);
|
|
81
|
-
} catch (error) {
|
|
82
|
-
console.warn("[camera-views] setView failed", error);
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
let busy = false;
|
|
87
|
-
const run = async (fn: () => void | Promise<void>) => {
|
|
88
|
-
if (busy) return;
|
|
89
|
-
busy = true;
|
|
90
|
-
try {
|
|
91
|
-
await fn();
|
|
92
|
-
} catch (error) {
|
|
93
|
-
console.warn("[camera-views] action failed", error);
|
|
94
|
-
} finally {
|
|
95
|
-
busy = false;
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
let tick = 0;
|
|
100
|
-
const [bar, barUpdate] = BUI.Component.create<HTMLElement, { tick: number }>(
|
|
101
|
-
// Param required: create() returns a single element (not the [element,
|
|
102
|
-
// update] tuple) when the template has arity 0.
|
|
103
|
-
(_state) => {
|
|
104
|
-
// Guard: the very first render can run before a world exists, and reading
|
|
105
|
-
// the projection spreads the (possibly empty/not-yet-ready) worlds list.
|
|
106
|
-
let ortho = false;
|
|
107
|
-
try {
|
|
108
|
-
ortho = cam.orthoToggle.active();
|
|
109
|
-
} catch {
|
|
110
|
-
/* world not ready yet — default to perspective icon, re-render later */
|
|
111
|
-
}
|
|
112
|
-
return BUI.html`
|
|
113
|
-
<bim-toolbar
|
|
114
|
-
style="
|
|
115
|
-
pointer-events: auto; overflow: visible; padding: 0.15rem;
|
|
116
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
|
|
117
|
-
"
|
|
118
|
-
>
|
|
119
|
-
<bim-toolbar-section label-hidden style="background: transparent;">
|
|
120
|
-
<bim-dropdown
|
|
121
|
-
icon="mdi:camera-control"
|
|
122
|
-
style="min-width: 6rem;"
|
|
123
|
-
@change=${(e: Event) => {
|
|
124
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
125
|
-
const picked = (e.target as any).value?.[0];
|
|
126
|
-
if (picked) void run(() => setView(String(picked)));
|
|
127
|
-
}}
|
|
128
|
-
>
|
|
129
|
-
${Object.keys(VIEWS).map(
|
|
130
|
-
(name) => BUI.html`<bim-option label=${name}></bim-option>`,
|
|
131
|
-
)}
|
|
132
|
-
</bim-dropdown>
|
|
133
|
-
</bim-toolbar-section>
|
|
134
|
-
<bim-toolbar-section label-hidden style="background: transparent;">
|
|
135
|
-
<bim-button
|
|
136
|
-
icon=${cam.fitAll.icon}
|
|
137
|
-
@click=${() => run(() => cam.fitAll.run())}
|
|
138
|
-
style="width: 1.9rem; min-width: 1.9rem; height: 1.9rem;"
|
|
139
|
-
><bim-tooltip placement="bottom">${cam.fitAll.label}</bim-tooltip></bim-button>
|
|
140
|
-
<bim-button
|
|
141
|
-
icon=${ortho ? "mdi:perspective-less" : "mdi:perspective-more"}
|
|
142
|
-
@click=${() =>
|
|
143
|
-
run(async () => {
|
|
144
|
-
if (cam.orthoToggle.active()) await cam.orthoToggle.deactivate();
|
|
145
|
-
else await cam.orthoToggle.activate();
|
|
146
|
-
barUpdate({ tick: ++tick });
|
|
147
|
-
})}
|
|
148
|
-
style="width: 1.9rem; min-width: 1.9rem; height: 1.9rem;"
|
|
149
|
-
><bim-tooltip placement="bottom">${
|
|
150
|
-
ortho
|
|
151
|
-
? "Orthographic — switch to Perspective"
|
|
152
|
-
: "Perspective — switch to Orthographic"
|
|
153
|
-
}</bim-tooltip></bim-button>
|
|
154
|
-
</bim-toolbar-section>
|
|
155
|
-
</bim-toolbar>
|
|
156
|
-
`;
|
|
157
|
-
},
|
|
158
|
-
{ tick: 0 },
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
// ── Floating grid overlay: bar pinned TOP-RIGHT; empty areas click through ──
|
|
162
|
-
const grid = BUI.Component.create(() => {
|
|
163
|
-
const onCreated = (element?: Element) => {
|
|
164
|
-
if (!element) return;
|
|
165
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
166
|
-
const g = element as any;
|
|
167
|
-
g.elements = { bar };
|
|
168
|
-
g.layouts = {
|
|
169
|
-
main: {
|
|
170
|
-
template: `
|
|
171
|
-
"restL bar" auto
|
|
172
|
-
"fillL fillR" 1fr
|
|
173
|
-
/ 1fr auto
|
|
174
|
-
`,
|
|
175
|
-
},
|
|
176
|
-
};
|
|
177
|
-
g.layout = "main";
|
|
178
|
-
};
|
|
179
|
-
return BUI.html`
|
|
180
|
-
<bim-grid style="padding: 1rem;" ${BUI.ref(onCreated)} floating></bim-grid>
|
|
181
|
-
`;
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
const resolveContainer = (): HTMLElement | undefined => {
|
|
185
|
-
if (container) return container;
|
|
186
|
-
const world = [...components.get(OBC.Worlds).list.values()][0] as
|
|
187
|
-
| { renderer?: { three?: { domElement?: HTMLElement } } }
|
|
188
|
-
| undefined;
|
|
189
|
-
const canvas = world?.renderer?.three?.domElement;
|
|
190
|
-
return (canvas?.parentElement as HTMLElement | undefined) ?? undefined;
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
const host = resolveContainer();
|
|
194
|
-
if (host) host.append(grid);
|
|
195
|
-
else
|
|
196
|
-
console.warn(
|
|
197
|
-
"[camera-views] no viewport found to overlay; append the returned element manually",
|
|
198
|
-
);
|
|
199
|
-
|
|
200
|
-
return bar;
|
|
201
|
-
};
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import * as BUI from "@thatopen/ui";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* A card title styled to match the nxt-bld-demo panels: an icon (#99A0AE) +
|
|
5
|
-
* a white→#99A0AE gradient text label, semibold with wide letter-spacing.
|
|
6
|
-
* Use inside a `header-hidden` `bim-panel` (replaces the default header). Sticky
|
|
7
|
-
* to the top so it stays put while the card body scrolls.
|
|
8
|
-
*
|
|
9
|
-
* @param icon iconify/mdi name (e.g. "mdi:file-tree")
|
|
10
|
-
* @param label the title text
|
|
11
|
-
* @param padLeft left padding so the title aligns with the card's content inset
|
|
12
|
-
*/
|
|
13
|
-
export const cardHeader = (icon: string, label: string, padLeft = "0.6rem") => BUI.html`
|
|
14
|
-
<div
|
|
15
|
-
style="
|
|
16
|
-
position: sticky; top: 0; z-index: 2;
|
|
17
|
-
display: flex; align-items: center; gap: 0.45rem;
|
|
18
|
-
padding: 0.4rem 0.6rem 0.4rem ${padLeft};
|
|
19
|
-
font-size: 0.8rem; font-weight: 600; letter-spacing: 0.04em;
|
|
20
|
-
/* Opaque surface bg (#262629 = panel bg) so scrolled content doesn't show
|
|
21
|
-
behind the sticky title. */
|
|
22
|
-
background: var(--bim-ui_bg-contrast-10, #262629);
|
|
23
|
-
border-bottom: 1px solid var(--bim-ui_bg-contrast-20, rgba(255, 255, 255, 0.1));
|
|
24
|
-
"
|
|
25
|
-
>
|
|
26
|
-
<bim-icon icon=${icon} style="color: #99A0AE; font-size: 0.95rem;"></bim-icon>
|
|
27
|
-
<span
|
|
28
|
-
style="
|
|
29
|
-
background: linear-gradient(90deg, #ffffff 0%, #99a0ae 100%);
|
|
30
|
-
-webkit-background-clip: text; background-clip: text;
|
|
31
|
-
-webkit-text-fill-color: transparent; color: transparent;
|
|
32
|
-
"
|
|
33
|
-
>${label}</span>
|
|
34
|
-
</div>
|
|
35
|
-
`;
|