@thatopen/services 0.3.11 → 0.3.13

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.
Files changed (38) hide show
  1. package/dist/cli/commands/revit.d.ts +9 -0
  2. package/dist/cli/lib/revit-addin.d.ts +20 -0
  3. package/dist/cli.js +128 -0
  4. package/dist/cloud/LasToPotree.d.ts +59 -0
  5. package/dist/cloud/SplatToFq.d.ts +38 -0
  6. package/dist/cloud/index.d.ts +2 -0
  7. package/docs/builtin/paths.json +86 -86
  8. package/docs/cloud/GaussianSplatConverter.md +43 -0
  9. package/docs/cloud/PointCloudConverter.md +53 -0
  10. package/docs/revit-collab-quickstart.md +205 -0
  11. package/package.json +95 -95
  12. package/src/built-in/ClashesManager/example.ts +283 -283
  13. package/src/built-in/UIManager/src/clashes-panel/example.ts +160 -160
  14. package/src/built-in/UIManager/src/models-list/example.ts +122 -118
  15. package/src/cli/templates/app/package.json +33 -33
  16. package/src/cli/templates/app/src/setups/camera-tools.ts +0 -63
  17. package/src/cli/templates/app/src/setups/camera-views.ts +0 -201
  18. package/src/cli/templates/app/src/setups/card-header.ts +0 -35
  19. package/src/cli/templates/app/src/setups/clipper-tool.ts +0 -773
  20. package/src/cli/templates/app/src/setups/clipper.ts +0 -75
  21. package/src/cli/templates/app/src/setups/cloud-runner.ts +0 -13
  22. package/src/cli/templates/app/src/setups/exploded-view.ts +0 -246
  23. package/src/cli/templates/app/src/setups/helper-panel.ts +0 -88
  24. package/src/cli/templates/app/src/setups/hider.ts +0 -98
  25. package/src/cli/templates/app/src/setups/index.ts +0 -23
  26. package/src/cli/templates/app/src/setups/inspection.ts +0 -136
  27. package/src/cli/templates/app/src/setups/measurement-panel.ts +0 -188
  28. package/src/cli/templates/app/src/setups/measurement-tool.ts +0 -588
  29. package/src/cli/templates/app/src/setups/measurements.ts +0 -133
  30. package/src/cli/templates/app/src/setups/navigation-gizmo.ts +0 -316
  31. package/src/cli/templates/app/src/setups/plans-panel.ts +0 -619
  32. package/src/cli/templates/app/src/setups/right-sidebar.ts +0 -178
  33. package/src/cli/templates/app/src/setups/styles-panel.ts +0 -110
  34. package/src/cli/templates/app/src/setups/styles.ts +0 -375
  35. package/src/cli/templates/app/src/setups/tool-mode-manager.ts +0 -156
  36. package/src/cli/templates/app/src/setups/tool-mode.ts +0 -23
  37. package/src/cli/templates/app/src/setups/toolbar.ts +0 -229
  38. package/src/cli/templates/app/src/setups/ui-manager.ts +0 -27
@@ -1,63 +0,0 @@
1
- import * as THREE from "three";
2
- import * as OBC from "@thatopen/components";
3
-
4
- /**
5
- * Camera tools for the viewer toolbar. Returns controllers matching the
6
- * toolbar's integration contract:
7
- * - `fitAll` — ACTION: fit the camera to the whole loaded model.
8
- * - `orthoToggle` — TOGGLE: switch the projection Perspective ⇄ Orthographic.
9
- */
10
-
11
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
- const firstWorld = (components: OBC.Components): any =>
13
- [...components.get(OBC.Worlds).list.values()][0];
14
-
15
- export interface CameraTools {
16
- fitAll: { label: string; icon: string; run(): Promise<void> };
17
- orthoToggle: {
18
- label: string;
19
- icon: string;
20
- active(): boolean;
21
- activate(): Promise<void>;
22
- deactivate(): Promise<void>;
23
- };
24
- }
25
-
26
- export const cameraTools = (components: OBC.Components): CameraTools => {
27
- const fragments = components.get(OBC.FragmentsManager);
28
-
29
- return {
30
- fitAll: {
31
- label: "Zoom to fit",
32
- icon: "mdi:fit-to-page-outline",
33
- async run() {
34
- const controls = firstWorld(components)?.camera?.controls;
35
- if (!controls) return;
36
- // Union every loaded model's bounding box, then frame its sphere —
37
- // fitToSphere preserves the current view direction (no rotation snap).
38
- const box = new THREE.Box3();
39
- for (const model of fragments.list.values()) {
40
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
- const b = (model as any).box as THREE.Box3 | undefined;
42
- if (b && !b.isEmpty()) box.union(b);
43
- }
44
- if (box.isEmpty()) return;
45
- const sphere = box.getBoundingSphere(new THREE.Sphere());
46
- await controls.fitToSphere(sphere, true);
47
- },
48
- },
49
- orthoToggle: {
50
- label: "Orthographic",
51
- icon: "mdi:angle-right",
52
- active() {
53
- return firstWorld(components)?.camera?.projection?.current === "Orthographic";
54
- },
55
- async activate() {
56
- await firstWorld(components)?.camera?.projection?.set?.("Orthographic");
57
- },
58
- async deactivate() {
59
- await firstWorld(components)?.camera?.projection?.set?.("Perspective");
60
- },
61
- },
62
- };
63
- };
@@ -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
- `;