3dviewer-sdk 1.1.0 → 1.1.2
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/package.json +1 -1
- package/dist/index.d.mts +0 -664
- package/dist/index.d.ts +0 -664
- package/dist/index.js +0 -1642
- package/dist/index.mjs +0 -1615
package/dist/index.js
DELETED
|
@@ -1,1642 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
Viewer3D: () => Viewer3D
|
|
24
|
-
});
|
|
25
|
-
module.exports = __toCommonJS(index_exports);
|
|
26
|
-
|
|
27
|
-
// src/core/emitter.ts
|
|
28
|
-
var Emitter = class {
|
|
29
|
-
constructor() {
|
|
30
|
-
this.listeners = {};
|
|
31
|
-
}
|
|
32
|
-
on(event, cb) {
|
|
33
|
-
if (!this.listeners[event]) {
|
|
34
|
-
this.listeners[event] = [];
|
|
35
|
-
}
|
|
36
|
-
const arr = this.listeners[event];
|
|
37
|
-
arr.push(cb);
|
|
38
|
-
return () => this.off(event, cb);
|
|
39
|
-
}
|
|
40
|
-
off(event, cb) {
|
|
41
|
-
const arr = this.listeners[event];
|
|
42
|
-
if (!arr) return;
|
|
43
|
-
const idx = arr.indexOf(cb);
|
|
44
|
-
if (idx >= 0) arr.splice(idx, 1);
|
|
45
|
-
if (arr.length === 0) delete this.listeners[event];
|
|
46
|
-
}
|
|
47
|
-
emit(event, payload) {
|
|
48
|
-
var _a;
|
|
49
|
-
(_a = this.listeners[event]) == null ? void 0 : _a.forEach((cb) => cb(payload));
|
|
50
|
-
}
|
|
51
|
-
clear() {
|
|
52
|
-
this.listeners = {};
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
// src/modules/camera.module.ts
|
|
57
|
-
function createRequestId(prefix) {
|
|
58
|
-
return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
59
|
-
}
|
|
60
|
-
function resolveTimeoutMs(timeoutMs) {
|
|
61
|
-
return Math.max(1e3, timeoutMs != null ? timeoutMs : 1e4);
|
|
62
|
-
}
|
|
63
|
-
var CameraModule = class {
|
|
64
|
-
constructor(viewer) {
|
|
65
|
-
this.viewer = viewer;
|
|
66
|
-
this.on = {
|
|
67
|
-
home: (cb) => this.viewer._on("camera:home", cb),
|
|
68
|
-
zoom: (cb) => this.viewer._on("camera:zoom", cb)
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
zoomIn(percent) {
|
|
72
|
-
this.viewer.postToViewer("viewer-zoom" /* ZOOM */, { action: "in", percent });
|
|
73
|
-
}
|
|
74
|
-
zoomOut(percent) {
|
|
75
|
-
this.viewer.postToViewer("viewer-zoom" /* ZOOM */, { action: "out", percent });
|
|
76
|
-
}
|
|
77
|
-
home() {
|
|
78
|
-
this.viewer.postToViewer("viewer-home" /* HOME */, {});
|
|
79
|
-
}
|
|
80
|
-
getZoom(options) {
|
|
81
|
-
const requestId = createRequestId("camera_zoom");
|
|
82
|
-
const timeoutMs = resolveTimeoutMs(options == null ? void 0 : options.timeoutMs);
|
|
83
|
-
return new Promise((resolve, reject) => {
|
|
84
|
-
const timer = setTimeout(() => {
|
|
85
|
-
off();
|
|
86
|
-
reject(new Error("Timeout while getting camera zoom state from viewer"));
|
|
87
|
-
}, timeoutMs);
|
|
88
|
-
const off = this.viewer._on("camera:zoom", (payload) => {
|
|
89
|
-
if (payload.requestId !== requestId) return;
|
|
90
|
-
clearTimeout(timer);
|
|
91
|
-
off();
|
|
92
|
-
resolve(payload);
|
|
93
|
-
});
|
|
94
|
-
this.postCameraGetZoom({ requestId });
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
postCameraGetZoom(payload) {
|
|
98
|
-
this.viewer.postToViewer("viewer-camera-get-zoom" /* CAMERA_GET_ZOOM */, payload);
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
// src/modules/interaction.module.ts
|
|
103
|
-
var InteractionModule = class {
|
|
104
|
-
constructor(viewer) {
|
|
105
|
-
this.viewer = viewer;
|
|
106
|
-
this.on = {
|
|
107
|
-
panChange: (cb) => this.viewer._on("interaction:pan-change", cb)
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
pan() {
|
|
111
|
-
this.viewer.postToViewer("viewer-pan-toggle" /* PAN_TOGGLE */);
|
|
112
|
-
}
|
|
113
|
-
select() {
|
|
114
|
-
this.viewer.postToViewer("viewer-select" /* SELECT */);
|
|
115
|
-
}
|
|
116
|
-
areaSelect() {
|
|
117
|
-
this.viewer.postToViewer("viewer-area-select" /* AREA_SELECT */);
|
|
118
|
-
}
|
|
119
|
-
orbit() {
|
|
120
|
-
this.viewer.postToViewer("viewer-orbit" /* ORBIT */);
|
|
121
|
-
}
|
|
122
|
-
rotateZ() {
|
|
123
|
-
this.viewer.postToViewer("viewer-rotate-z" /* ROTATE_Z */);
|
|
124
|
-
}
|
|
125
|
-
walkThrough() {
|
|
126
|
-
this.viewer.postToViewer("viewer-walk-through" /* WALK_THROUGH */);
|
|
127
|
-
}
|
|
128
|
-
zoomWindow() {
|
|
129
|
-
this.viewer.postToViewer("viewer-zoom-window" /* ZOOM_WINDOW */);
|
|
130
|
-
}
|
|
131
|
-
zoomFit() {
|
|
132
|
-
this.viewer.postToViewer("viewer-zoom-fit" /* ZOOM_FIT */);
|
|
133
|
-
}
|
|
134
|
-
drawModeShaded() {
|
|
135
|
-
this.setDrawMode("shaded");
|
|
136
|
-
}
|
|
137
|
-
drawModeWireframe() {
|
|
138
|
-
this.setDrawMode("wireframe");
|
|
139
|
-
}
|
|
140
|
-
drawModeHiddenLine() {
|
|
141
|
-
this.setDrawMode("hidden-line");
|
|
142
|
-
}
|
|
143
|
-
drawModeShadedWire() {
|
|
144
|
-
this.setDrawMode("shaded-wire");
|
|
145
|
-
}
|
|
146
|
-
drawModeXRay() {
|
|
147
|
-
this.setDrawMode("xray");
|
|
148
|
-
}
|
|
149
|
-
drawModeGhosting() {
|
|
150
|
-
this.setDrawMode("ghosting");
|
|
151
|
-
}
|
|
152
|
-
explode(magnitude) {
|
|
153
|
-
this.viewer.postToViewer("viewer-explode" /* EXPLODE */, { magnitude });
|
|
154
|
-
}
|
|
155
|
-
explodeOff() {
|
|
156
|
-
this.explode(0);
|
|
157
|
-
}
|
|
158
|
-
setDrawMode(mode) {
|
|
159
|
-
this.viewer.postToViewer("viewer-draw-mode" /* DRAW_MODE */, { mode });
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
// src/modules/node.module.ts
|
|
164
|
-
var NodeModule = class {
|
|
165
|
-
constructor(viewer) {
|
|
166
|
-
this.viewer = viewer;
|
|
167
|
-
this.on = {
|
|
168
|
-
select: (cb) => this.viewer._on("node:select", cb),
|
|
169
|
-
selectionChange: (cb) => this.viewer._on("node:selection-change", cb)
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
// src/modules/files.module.ts
|
|
175
|
-
var DEFAULT_CONVERSION_URL = "https://dev.3dviewer.anybim.vn/service/conversion";
|
|
176
|
-
var DEFAULT_VIEWER_BASE_URL = "https://dev.3dviewer.anybim.vn";
|
|
177
|
-
var SDK_VIEWER_PATH = "/mainviewer-sdk";
|
|
178
|
-
var FilesModule = class {
|
|
179
|
-
constructor(viewer) {
|
|
180
|
-
this.viewer = viewer;
|
|
181
|
-
this.config = {};
|
|
182
|
-
this.operationStartTime = 0;
|
|
183
|
-
this.state = {
|
|
184
|
-
isLoading: false,
|
|
185
|
-
stage: "idle"
|
|
186
|
-
};
|
|
187
|
-
this.lastUploadSession = null;
|
|
188
|
-
this.on = {
|
|
189
|
-
state: (cb) => this.viewer._on("files:state", cb),
|
|
190
|
-
uploadStart: (cb) => this.viewer._on("files:upload:start", cb),
|
|
191
|
-
uploadSuccess: (cb) => this.viewer._on("files:upload:success", cb),
|
|
192
|
-
uploadError: (cb) => this.viewer._on("files:upload:error", cb),
|
|
193
|
-
conversionStart: (cb) => this.viewer._on("files:conversion:start", cb),
|
|
194
|
-
conversionSuccess: (cb) => this.viewer._on("files:conversion:success", cb),
|
|
195
|
-
conversionError: (cb) => this.viewer._on("files:conversion:error", cb),
|
|
196
|
-
renderStart: (cb) => this.viewer._on("files:render:start", cb),
|
|
197
|
-
renderSuccess: (cb) => this.viewer._on("files:render:success", cb),
|
|
198
|
-
renderError: (cb) => this.viewer._on("files:render:error", cb),
|
|
199
|
-
loadSuccess: (cb) => this.viewer._on("files:load:success", cb),
|
|
200
|
-
loadError: (cb) => this.viewer._on("files:load:error", cb)
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
// Merge file-pipeline runtime config.
|
|
204
|
-
setConfig(next) {
|
|
205
|
-
this.config = { ...this.config, ...next };
|
|
206
|
-
}
|
|
207
|
-
// Return a snapshot of current loading state.
|
|
208
|
-
getState() {
|
|
209
|
-
return { ...this.state };
|
|
210
|
-
}
|
|
211
|
-
// ---------- public pipeline ----------
|
|
212
|
-
// Upload file to conversion server and keep generated baseFileId in session.
|
|
213
|
-
async upload(file) {
|
|
214
|
-
const target = this.resolveFile(file);
|
|
215
|
-
return this.withOperation({ stage: "uploading", message: "Uploading file..." }, async () => {
|
|
216
|
-
var _a;
|
|
217
|
-
this.viewer._emit("files:upload:start", { fileName: target.name });
|
|
218
|
-
await this.uploadInternal(target);
|
|
219
|
-
const baseFileId = ((_a = this.getUploadSessionForFile(target)) == null ? void 0 : _a.baseFileId) || "";
|
|
220
|
-
this.viewer._emit("files:upload:success", { fileName: target.name, baseFileId });
|
|
221
|
-
return { fileName: target.name, baseFileId };
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
// Trigger conversion flow and resolve final viewer metadata.
|
|
225
|
-
async convert(file, options = {}) {
|
|
226
|
-
const target = this.resolveFile(file);
|
|
227
|
-
return this.withOperation({ stage: "converting", message: "Converting file..." }, async () => {
|
|
228
|
-
this.viewer._emit("files:conversion:start", { fileName: target.name });
|
|
229
|
-
try {
|
|
230
|
-
const prepared = await this.convertInternal(target, options);
|
|
231
|
-
this.viewer._emit("files:conversion:success", prepared);
|
|
232
|
-
return prepared;
|
|
233
|
-
} catch (e) {
|
|
234
|
-
this.viewer._emit("files:conversion:error", { fileName: target.name, error: this.toErrorMessage(e) });
|
|
235
|
-
throw e;
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
// Convenience API: upload first, then convert in one call.
|
|
240
|
-
async prepare(file, options = {}) {
|
|
241
|
-
const target = this.resolveFile(file);
|
|
242
|
-
return this.withOperation({ stage: "uploading", message: "Preparing file..." }, async () => {
|
|
243
|
-
await this.uploadInternal(target);
|
|
244
|
-
const prepared = await this.convertInternal(target, options);
|
|
245
|
-
return prepared;
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
// Trigger the newer downloadUrl-based conversion flow.
|
|
249
|
-
async convertV2(options) {
|
|
250
|
-
return this.withOperation({ stage: "converting", message: "Converting file..." }, async () => {
|
|
251
|
-
this.viewer._emit("files:conversion:start", { fileName: options.filename });
|
|
252
|
-
try {
|
|
253
|
-
const prepared = await this.convertV2Internal(options);
|
|
254
|
-
this.viewer._emit("files:conversion:success", prepared);
|
|
255
|
-
return prepared;
|
|
256
|
-
} catch (e) {
|
|
257
|
-
this.viewer._emit("files:conversion:error", { fileName: options.filename, error: this.toErrorMessage(e) });
|
|
258
|
-
throw e;
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
// Check stream file info by one or more baseFileId values.
|
|
263
|
-
async checkFileInfo(baseFileIds) {
|
|
264
|
-
const payload = this.buildFileInfoPayload(baseFileIds);
|
|
265
|
-
const hostConversion = await this.resolveHostConversion();
|
|
266
|
-
const url = `${hostConversion}/api/StreamFile/info`;
|
|
267
|
-
const response = await fetch(url, {
|
|
268
|
-
method: "POST",
|
|
269
|
-
headers: {
|
|
270
|
-
"Content-Type": "application/json",
|
|
271
|
-
Accept: "application/json"
|
|
272
|
-
},
|
|
273
|
-
body: JSON.stringify(payload)
|
|
274
|
-
});
|
|
275
|
-
if (!response.ok) {
|
|
276
|
-
throw new Error(`Check file info failed (${response.status} ${response.statusText})`);
|
|
277
|
-
}
|
|
278
|
-
const text = await response.text();
|
|
279
|
-
if (!text) return null;
|
|
280
|
-
try {
|
|
281
|
-
return JSON.parse(text);
|
|
282
|
-
} catch {
|
|
283
|
-
return text;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
// Open iframe with an already prepared viewer URL.
|
|
287
|
-
open(input) {
|
|
288
|
-
const url = input.url;
|
|
289
|
-
this.viewer._emit("files:render:start", { url });
|
|
290
|
-
try {
|
|
291
|
-
this.viewer.open(url);
|
|
292
|
-
this.viewer._emit("files:render:success", { url });
|
|
293
|
-
} catch (e) {
|
|
294
|
-
this.viewer._emit("files:render:error", { url, error: this.toErrorMessage(e) });
|
|
295
|
-
throw e;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
// Full pipeline: upload + convert + open iframe.
|
|
299
|
-
async render(file, options = {}) {
|
|
300
|
-
const target = this.resolveFile(file);
|
|
301
|
-
return this.withOperation({ stage: "uploading", message: "Uploading + converting + opening..." }, async () => {
|
|
302
|
-
await this.upload(target);
|
|
303
|
-
const prepared = await this.convert(target, options);
|
|
304
|
-
this.updateState({ stage: "rendering", message: "Opening viewer..." });
|
|
305
|
-
this.open(prepared);
|
|
306
|
-
this.viewer._emit("files:load:success", prepared);
|
|
307
|
-
return prepared;
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
// Resolve file argument, fallback to options.file, and persist it back.
|
|
311
|
-
resolveFile(file) {
|
|
312
|
-
const optFile = this.viewer.getOptions().file;
|
|
313
|
-
const target = file || optFile;
|
|
314
|
-
if (!target) throw new Error("No file provided. Pass a File or set options.file");
|
|
315
|
-
this.viewer.patchOptions({ file: target });
|
|
316
|
-
return target;
|
|
317
|
-
}
|
|
318
|
-
// Trim input URL and remove trailing slash.
|
|
319
|
-
normalizeBaseUrl(input) {
|
|
320
|
-
return input.trim().replace(/\/+$/, "");
|
|
321
|
-
}
|
|
322
|
-
// Resolve conversion API URL with default fallback.
|
|
323
|
-
resolveConversionUrl() {
|
|
324
|
-
const raw = this.config.conversionUrl || this.viewer.getOptions().conversionUrl || DEFAULT_CONVERSION_URL;
|
|
325
|
-
return this.normalizeBaseUrl(raw);
|
|
326
|
-
}
|
|
327
|
-
// Resolve viewer route path for all SDK flows.
|
|
328
|
-
resolveViewerPath() {
|
|
329
|
-
const configuredPath = this.config.viewerPath || this.viewer.getOptions().viewerPath;
|
|
330
|
-
if (!configuredPath) {
|
|
331
|
-
const viewerUrl = this.viewer.getOptions().url;
|
|
332
|
-
if (viewerUrl) {
|
|
333
|
-
try {
|
|
334
|
-
const pathname = new URL(viewerUrl, window.location.href).pathname;
|
|
335
|
-
if (pathname && pathname !== "/") return this.normalizeViewerPath(pathname);
|
|
336
|
-
} catch {
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return this.normalizeViewerPath(configuredPath || SDK_VIEWER_PATH);
|
|
341
|
-
}
|
|
342
|
-
normalizeViewerPath(path) {
|
|
343
|
-
const p = path.trim();
|
|
344
|
-
if (!p) return SDK_VIEWER_PATH;
|
|
345
|
-
return p.startsWith("/") ? p : `/${p}`;
|
|
346
|
-
}
|
|
347
|
-
// Viewer host used to open iframe after conversion completes.
|
|
348
|
-
resolveViewerOrigin() {
|
|
349
|
-
const configuredViewerBaseUrl = this.config.baseUrl || this.viewer.getOptions().baseUrl;
|
|
350
|
-
if (configuredViewerBaseUrl) {
|
|
351
|
-
try {
|
|
352
|
-
return this.normalizeBaseUrl(new URL(configuredViewerBaseUrl, window.location.href).origin);
|
|
353
|
-
} catch {
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
const viewerUrl = this.viewer.getOptions().url;
|
|
357
|
-
if (viewerUrl) {
|
|
358
|
-
try {
|
|
359
|
-
return this.normalizeBaseUrl(new URL(viewerUrl, window.location.href).origin);
|
|
360
|
-
} catch {
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
return this.normalizeBaseUrl(DEFAULT_VIEWER_BASE_URL);
|
|
364
|
-
}
|
|
365
|
-
// Resolve conversion service root from configured conversion URL.
|
|
366
|
-
// Do not auto-append path segments (e.g. "/service/conversion").
|
|
367
|
-
resolveHostConversion() {
|
|
368
|
-
return this.resolveConversionUrl();
|
|
369
|
-
}
|
|
370
|
-
// Resolve upload path sent to conversion APIs.
|
|
371
|
-
getUploadPath() {
|
|
372
|
-
return this.config.uploadPath || this.viewer.getOptions().uploadPath || ".";
|
|
373
|
-
}
|
|
374
|
-
// Build a stable in-memory signature to identify same file uploads.
|
|
375
|
-
fileSignature(file) {
|
|
376
|
-
return `${file.name}::${file.size}::${file.lastModified}`;
|
|
377
|
-
}
|
|
378
|
-
// Create a UUID-like baseFileId when caller does not provide one.
|
|
379
|
-
createBaseFileId() {
|
|
380
|
-
if (typeof crypto !== "undefined" && "randomUUID" in crypto) return crypto.randomUUID();
|
|
381
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
382
|
-
const r = Math.floor(Math.random() * 16);
|
|
383
|
-
const v = c === "x" ? r : r & 3 | 8;
|
|
384
|
-
return v.toString(16);
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
// Create upload session metadata reused between upload and convert.
|
|
388
|
-
createUploadSession(file) {
|
|
389
|
-
return {
|
|
390
|
-
signature: this.fileSignature(file),
|
|
391
|
-
baseFileId: this.createBaseFileId(),
|
|
392
|
-
fileName: file.name,
|
|
393
|
-
uploadPath: this.getUploadPath()
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
// Return previous upload session for same file and upload path.
|
|
397
|
-
getUploadSessionForFile(file) {
|
|
398
|
-
if (!this.lastUploadSession) return null;
|
|
399
|
-
const sameFile = this.lastUploadSession.signature === this.fileSignature(file);
|
|
400
|
-
const samePath = this.lastUploadSession.uploadPath === this.getUploadPath();
|
|
401
|
-
return sameFile && samePath ? this.lastUploadSession : null;
|
|
402
|
-
}
|
|
403
|
-
// Call upload endpoint and persist upload session on success.
|
|
404
|
-
async uploadInternal(file) {
|
|
405
|
-
this.updateState({ stage: "uploading", message: "Uploading file..." });
|
|
406
|
-
try {
|
|
407
|
-
const existing = this.getUploadSessionForFile(file);
|
|
408
|
-
const session = existing || this.createUploadSession(file);
|
|
409
|
-
const hostConversion = this.resolveHostConversion();
|
|
410
|
-
const path = this.getUploadPath();
|
|
411
|
-
const url = `${hostConversion}/api/File/upload?path=${encodeURIComponent(path)}`;
|
|
412
|
-
const formData = new FormData();
|
|
413
|
-
formData.append("file", file, file.name);
|
|
414
|
-
const res = await fetch(url, { method: "POST", body: formData, headers: { Accept: "text/plain" } });
|
|
415
|
-
if (!res.ok) throw new Error(`Upload failed (${res.status} ${res.statusText})`);
|
|
416
|
-
this.lastUploadSession = session;
|
|
417
|
-
} catch (e) {
|
|
418
|
-
const msg = this.toErrorMessage(e);
|
|
419
|
-
this.viewer._emit("files:upload:error", { fileName: file.name, error: msg });
|
|
420
|
-
throw e;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
// Build StreamFile payload compatible with conversion service.
|
|
424
|
-
buildCachePayload(file, baseFileId, options = {}) {
|
|
425
|
-
const createdDate = (/* @__PURE__ */ new Date()).toISOString();
|
|
426
|
-
return {
|
|
427
|
-
filename: file.name,
|
|
428
|
-
...options.downloadUrl ? { downloadUrl: options.downloadUrl } : {},
|
|
429
|
-
baseFileId,
|
|
430
|
-
baseMajorRev: 0,
|
|
431
|
-
baseMinorRev: 0,
|
|
432
|
-
isChecked: false,
|
|
433
|
-
status: { size: file.size },
|
|
434
|
-
child: [],
|
|
435
|
-
isDirectory: false,
|
|
436
|
-
createdDate,
|
|
437
|
-
cacheStatus: 0,
|
|
438
|
-
modelFileId: "",
|
|
439
|
-
id: "",
|
|
440
|
-
originalFilePath: this.getUploadPath(),
|
|
441
|
-
streamLocation: null,
|
|
442
|
-
converter: "Hoops",
|
|
443
|
-
originalSize: 0,
|
|
444
|
-
cacheSize: 0,
|
|
445
|
-
importTime: 0,
|
|
446
|
-
importAssemblyTreeTime: 0,
|
|
447
|
-
creator: {
|
|
448
|
-
id: "00000000-0000-0000-0000-000000000000",
|
|
449
|
-
name: "Anonymous"
|
|
450
|
-
},
|
|
451
|
-
originalFile: file.name,
|
|
452
|
-
multiStream: false,
|
|
453
|
-
isRootModel: 0,
|
|
454
|
-
extraConvertOutput: "",
|
|
455
|
-
cacheFilename: null,
|
|
456
|
-
errorMassage: null,
|
|
457
|
-
convertOptions: {
|
|
458
|
-
convert3DModel: 1,
|
|
459
|
-
convert2DSheet: 1,
|
|
460
|
-
extractProperties: 1,
|
|
461
|
-
childModels: 0
|
|
462
|
-
},
|
|
463
|
-
drawingConvertStatus: {
|
|
464
|
-
convert3DModel: 5,
|
|
465
|
-
convert2DSheet: 5,
|
|
466
|
-
extractProperties: 5
|
|
467
|
-
},
|
|
468
|
-
attemptedConvertTimes: 0
|
|
469
|
-
};
|
|
470
|
-
}
|
|
471
|
-
// Build payload for POST /api/StreamFile/convert.
|
|
472
|
-
buildConvertV2Payload(options) {
|
|
473
|
-
var _a, _b;
|
|
474
|
-
const convertOptions = {
|
|
475
|
-
convert3DModel: 1,
|
|
476
|
-
convert2DSheet: 1,
|
|
477
|
-
extractProperties: 1,
|
|
478
|
-
childModels: 0,
|
|
479
|
-
...options.convertOptions
|
|
480
|
-
};
|
|
481
|
-
return {
|
|
482
|
-
filename: options.filename,
|
|
483
|
-
originalFilePath: options.originalFilePath,
|
|
484
|
-
convertOptions,
|
|
485
|
-
downloadUrl: options.downloadUrl,
|
|
486
|
-
workflowId: options.workflowId,
|
|
487
|
-
taskId: options.taskId,
|
|
488
|
-
baseFileId: options.baseFileId,
|
|
489
|
-
baseMajorRev: (_a = options.baseMajorRev) != null ? _a : 0,
|
|
490
|
-
baseMinorRev: (_b = options.baseMinorRev) != null ? _b : 0
|
|
491
|
-
};
|
|
492
|
-
}
|
|
493
|
-
buildFileInfoPayload(baseFileIds) {
|
|
494
|
-
const payload = (Array.isArray(baseFileIds) ? baseFileIds : [baseFileIds]).map((item) => {
|
|
495
|
-
var _a, _b, _c;
|
|
496
|
-
if (typeof item === "string") {
|
|
497
|
-
return {
|
|
498
|
-
baseFileId: item.trim(),
|
|
499
|
-
baseMajorRev: 0,
|
|
500
|
-
baseMinorRev: 0
|
|
501
|
-
};
|
|
502
|
-
}
|
|
503
|
-
return {
|
|
504
|
-
baseFileId: String((_a = item.baseFileId) != null ? _a : "").trim(),
|
|
505
|
-
baseMajorRev: (_b = item.baseMajorRev) != null ? _b : 0,
|
|
506
|
-
baseMinorRev: (_c = item.baseMinorRev) != null ? _c : 0
|
|
507
|
-
};
|
|
508
|
-
}).filter((item) => item.baseFileId);
|
|
509
|
-
if (payload.length === 0) {
|
|
510
|
-
throw new Error("No baseFileId provided");
|
|
511
|
-
}
|
|
512
|
-
return payload;
|
|
513
|
-
}
|
|
514
|
-
// Submit conversion/caching request and return service response.
|
|
515
|
-
async cacheFile(file, baseFileId, options = {}) {
|
|
516
|
-
const hostConversion = await this.resolveHostConversion();
|
|
517
|
-
const url = `${hostConversion}/api/StreamFile?overwrite=true&ignore_line_weight=1`;
|
|
518
|
-
const payload = this.buildCachePayload(file, baseFileId, options);
|
|
519
|
-
const response = await fetch(url, {
|
|
520
|
-
method: "POST",
|
|
521
|
-
headers: {
|
|
522
|
-
"Content-Type": "application/json",
|
|
523
|
-
Accept: "application/json"
|
|
524
|
-
},
|
|
525
|
-
body: JSON.stringify(payload)
|
|
526
|
-
});
|
|
527
|
-
if (!response.ok) {
|
|
528
|
-
throw new Error(
|
|
529
|
-
`Cache/convert failed (${response.status} ${response.statusText})`
|
|
530
|
-
);
|
|
531
|
-
}
|
|
532
|
-
return await response.json();
|
|
533
|
-
}
|
|
534
|
-
// Submit conversion request to the newer downloadUrl-based endpoint.
|
|
535
|
-
async cacheFileV2(options) {
|
|
536
|
-
var _a;
|
|
537
|
-
const hostConversion = await this.resolveHostConversion();
|
|
538
|
-
const params = new URLSearchParams();
|
|
539
|
-
params.set("overwrite", String((_a = options.overwrite) != null ? _a : true));
|
|
540
|
-
params.set("ignore_line_weight", "1");
|
|
541
|
-
if (options.project) {
|
|
542
|
-
params.set("project", options.project);
|
|
543
|
-
}
|
|
544
|
-
const query = params.toString();
|
|
545
|
-
const url = `${hostConversion}/api/StreamFile/convert${query ? `?${query}` : ""}`;
|
|
546
|
-
const payload = this.buildConvertV2Payload(options);
|
|
547
|
-
const response = await fetch(url, {
|
|
548
|
-
method: "POST",
|
|
549
|
-
headers: {
|
|
550
|
-
"Content-Type": "application/json",
|
|
551
|
-
Accept: "application/json"
|
|
552
|
-
},
|
|
553
|
-
body: JSON.stringify(payload)
|
|
554
|
-
});
|
|
555
|
-
if (!response.ok) {
|
|
556
|
-
throw new Error(
|
|
557
|
-
`Cache/convert v2 failed (${response.status} ${response.statusText})`
|
|
558
|
-
);
|
|
559
|
-
}
|
|
560
|
-
return await response.json();
|
|
561
|
-
}
|
|
562
|
-
// Convert file and generate final iframe URL with query string.
|
|
563
|
-
async convertInternal(file, options = {}) {
|
|
564
|
-
var _a, _b, _c, _d;
|
|
565
|
-
this.updateState({ stage: "converting", message: "Converting file..." });
|
|
566
|
-
const uploadSession = this.getUploadSessionForFile(file) || this.createUploadSession(file);
|
|
567
|
-
const seedBaseFileId = uploadSession.baseFileId;
|
|
568
|
-
const cacheResult = await this.cacheFile(file, seedBaseFileId, options);
|
|
569
|
-
const baseFileId = (_a = cacheResult.baseFileId) != null ? _a : seedBaseFileId;
|
|
570
|
-
const baseMajorRev = (_b = cacheResult.baseMajorRev) != null ? _b : 0;
|
|
571
|
-
const baseMinorRev = (_c = cacheResult.baseMinorRev) != null ? _c : 0;
|
|
572
|
-
const fileName = cacheResult.filename || cacheResult.fileName || file.name;
|
|
573
|
-
const cacheListItem = { baseFileId, baseMajorRev, baseMinorRev, fileName };
|
|
574
|
-
if (cacheResult.cacheStatus !== 2) {
|
|
575
|
-
throw new Error(`Conversion not ready after first request (cacheStatus=${(_d = cacheResult.cacheStatus) != null ? _d : "unknown"})`);
|
|
576
|
-
}
|
|
577
|
-
const query = new URLSearchParams({ fileList: JSON.stringify([cacheListItem]) }).toString();
|
|
578
|
-
const viewerBase = this.resolveViewerOrigin();
|
|
579
|
-
const viewerPath = this.resolveViewerPath();
|
|
580
|
-
const url = `${viewerBase}${viewerPath}?${query}`;
|
|
581
|
-
return { baseFileId, baseMajorRev, baseMinorRev, fileName, query, url };
|
|
582
|
-
}
|
|
583
|
-
async convertV2Internal(options) {
|
|
584
|
-
var _a, _b, _c, _d, _e;
|
|
585
|
-
this.updateState({ stage: "converting", message: "Converting file..." });
|
|
586
|
-
const cacheResult = await this.cacheFileV2(options);
|
|
587
|
-
const baseFileId = (_a = cacheResult.baseFileId) != null ? _a : options.baseFileId;
|
|
588
|
-
const baseMajorRev = (_c = (_b = cacheResult.baseMajorRev) != null ? _b : options.baseMajorRev) != null ? _c : 0;
|
|
589
|
-
const baseMinorRev = (_e = (_d = cacheResult.baseMinorRev) != null ? _d : options.baseMinorRev) != null ? _e : 0;
|
|
590
|
-
const fileName = cacheResult.filename || cacheResult.fileName || options.filename;
|
|
591
|
-
if (cacheResult.cacheStatus !== void 0 && cacheResult.cacheStatus !== 2) {
|
|
592
|
-
throw new Error(`Conversion not ready after v2 request (cacheStatus=${cacheResult.cacheStatus})`);
|
|
593
|
-
}
|
|
594
|
-
const cacheListItem = { baseFileId, baseMajorRev, baseMinorRev, fileName };
|
|
595
|
-
const query = new URLSearchParams({ fileList: JSON.stringify([cacheListItem]) }).toString();
|
|
596
|
-
const viewerBase = this.resolveViewerOrigin();
|
|
597
|
-
const viewerPath = this.resolveViewerPath();
|
|
598
|
-
const url = `${viewerBase}${viewerPath}?${query}`;
|
|
599
|
-
return { baseFileId, baseMajorRev, baseMinorRev, fileName, query, url };
|
|
600
|
-
}
|
|
601
|
-
// Update internal loading state and emit state event.
|
|
602
|
-
updateState(next) {
|
|
603
|
-
const elapsedMs = this.operationStartTime > 0 ? Date.now() - this.operationStartTime : 0;
|
|
604
|
-
this.state = { ...this.state, ...next, elapsedMs };
|
|
605
|
-
this.viewer._emit("files:state", this.state);
|
|
606
|
-
}
|
|
607
|
-
// Shared wrapper to handle loading state lifecycle and top-level errors.
|
|
608
|
-
async withOperation(initial, run) {
|
|
609
|
-
this.operationStartTime = Date.now();
|
|
610
|
-
this.updateState({
|
|
611
|
-
isLoading: true,
|
|
612
|
-
stage: initial.stage,
|
|
613
|
-
message: initial.message
|
|
614
|
-
});
|
|
615
|
-
try {
|
|
616
|
-
const result = await run();
|
|
617
|
-
this.updateState({ isLoading: false, stage: "completed", message: "Completed" });
|
|
618
|
-
return result;
|
|
619
|
-
} catch (e) {
|
|
620
|
-
const msg = this.toErrorMessage(e);
|
|
621
|
-
this.updateState({ isLoading: false, stage: "error", message: msg });
|
|
622
|
-
this.viewer._emit("files:load:error", { error: msg });
|
|
623
|
-
throw e;
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
// Normalize unknown error shape into displayable message.
|
|
627
|
-
toErrorMessage(e) {
|
|
628
|
-
return e instanceof Error ? e.message : String(e);
|
|
629
|
-
}
|
|
630
|
-
};
|
|
631
|
-
|
|
632
|
-
// src/modules/toolbar.module.ts
|
|
633
|
-
function createRequestId2(prefix) {
|
|
634
|
-
return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
635
|
-
}
|
|
636
|
-
var ALL_3D_TOOLBAR_OPERATORS = [
|
|
637
|
-
"home",
|
|
638
|
-
"select",
|
|
639
|
-
"areaSelect",
|
|
640
|
-
"pan",
|
|
641
|
-
"zoomIn",
|
|
642
|
-
"zoomOut",
|
|
643
|
-
"zoomWindow",
|
|
644
|
-
"zoomFit",
|
|
645
|
-
"orbit",
|
|
646
|
-
"rotateZ",
|
|
647
|
-
"walkThrough",
|
|
648
|
-
"drawMode-shaded",
|
|
649
|
-
"drawMode-wireframe",
|
|
650
|
-
"drawMode-shaded-wire",
|
|
651
|
-
"drawMode-hidden-line",
|
|
652
|
-
"drawMode-xray",
|
|
653
|
-
"drawMode-ghosting",
|
|
654
|
-
"cutting-plane",
|
|
655
|
-
"clipping-commands",
|
|
656
|
-
"explode",
|
|
657
|
-
"setting",
|
|
658
|
-
"propertyPanel",
|
|
659
|
-
"model-tree",
|
|
660
|
-
"linkedObjects",
|
|
661
|
-
"statesObjects",
|
|
662
|
-
"synchronized"
|
|
663
|
-
];
|
|
664
|
-
var ALL_PDF_TOOLBAR_OPERATORS = [
|
|
665
|
-
"home",
|
|
666
|
-
"select",
|
|
667
|
-
"pan",
|
|
668
|
-
"zoomIn",
|
|
669
|
-
"zoomOut",
|
|
670
|
-
"zoomWindow",
|
|
671
|
-
"zoomFit",
|
|
672
|
-
"rotateZ",
|
|
673
|
-
"save",
|
|
674
|
-
"setting",
|
|
675
|
-
"plan-mode",
|
|
676
|
-
"document-mode",
|
|
677
|
-
"first-page",
|
|
678
|
-
"previous-page",
|
|
679
|
-
"next-page",
|
|
680
|
-
"last-page",
|
|
681
|
-
"current-page"
|
|
682
|
-
];
|
|
683
|
-
var ToolbarModule = class {
|
|
684
|
-
constructor(viewer) {
|
|
685
|
-
this.viewer = viewer;
|
|
686
|
-
this.on = {
|
|
687
|
-
planMode: (cb) => this.viewer._on("toolbar:pdf-plan-mode", cb),
|
|
688
|
-
documentMode: (cb) => this.viewer._on("toolbar:pdf-document-mode", cb),
|
|
689
|
-
firstPage: (cb) => this.viewer._on("toolbar:pdf-first-page", cb),
|
|
690
|
-
previousPage: (cb) => this.viewer._on("toolbar:pdf-previous-page", cb),
|
|
691
|
-
nextPage: (cb) => this.viewer._on("toolbar:pdf-next-page", cb),
|
|
692
|
-
lastPage: (cb) => this.viewer._on("toolbar:pdf-last-page", cb),
|
|
693
|
-
currentPage: (cb) => this.viewer._on("toolbar:pdf-current-page", cb)
|
|
694
|
-
};
|
|
695
|
-
}
|
|
696
|
-
setDisabled3D(operators) {
|
|
697
|
-
this.postConfig({ format: "3d", mode: "set", operators });
|
|
698
|
-
}
|
|
699
|
-
setDisabledPdf(operators) {
|
|
700
|
-
this.postConfig({ format: "pdf", mode: "set", operators });
|
|
701
|
-
}
|
|
702
|
-
clearDisabled3D() {
|
|
703
|
-
this.postConfig({ format: "3d", mode: "clear" });
|
|
704
|
-
}
|
|
705
|
-
clearDisabledPdf() {
|
|
706
|
-
this.postConfig({ format: "pdf", mode: "clear" });
|
|
707
|
-
}
|
|
708
|
-
disableAll3D() {
|
|
709
|
-
this.setDisabled3D(ALL_3D_TOOLBAR_OPERATORS);
|
|
710
|
-
}
|
|
711
|
-
disableAllPdf() {
|
|
712
|
-
this.setDisabledPdf(ALL_PDF_TOOLBAR_OPERATORS);
|
|
713
|
-
}
|
|
714
|
-
enableAll3D() {
|
|
715
|
-
this.clearDisabled3D();
|
|
716
|
-
}
|
|
717
|
-
enableAllPdf() {
|
|
718
|
-
this.clearDisabledPdf();
|
|
719
|
-
}
|
|
720
|
-
useToolbar(target = "all") {
|
|
721
|
-
this.postToolbarUse({ target });
|
|
722
|
-
}
|
|
723
|
-
useLeftToolbar() {
|
|
724
|
-
this.useToolbar("left");
|
|
725
|
-
}
|
|
726
|
-
useCenterToolbar() {
|
|
727
|
-
this.useToolbar("center");
|
|
728
|
-
}
|
|
729
|
-
useRightToolbar() {
|
|
730
|
-
this.useToolbar("right");
|
|
731
|
-
}
|
|
732
|
-
usePanel(panel, format) {
|
|
733
|
-
this.postPanelOpen({ panel, format });
|
|
734
|
-
}
|
|
735
|
-
openClippingPlanes() {
|
|
736
|
-
this.usePanel("clipping-commands", "3d");
|
|
737
|
-
}
|
|
738
|
-
closeClippingPlanes() {
|
|
739
|
-
this.postPanelClose({ panel: "clipping-commands", format: "3d" });
|
|
740
|
-
}
|
|
741
|
-
openSetting() {
|
|
742
|
-
this.usePanel("setting");
|
|
743
|
-
}
|
|
744
|
-
closeSetting() {
|
|
745
|
-
this.postPanelClose({ panel: "setting" });
|
|
746
|
-
}
|
|
747
|
-
openSetting3D() {
|
|
748
|
-
this.usePanel("setting", "3d");
|
|
749
|
-
}
|
|
750
|
-
closeSetting3D() {
|
|
751
|
-
this.postPanelClose({ panel: "setting", format: "3d" });
|
|
752
|
-
}
|
|
753
|
-
openSettingPdf() {
|
|
754
|
-
this.usePanel("setting", "pdf");
|
|
755
|
-
}
|
|
756
|
-
closeSettingPdf() {
|
|
757
|
-
this.postPanelClose({ panel: "setting", format: "pdf" });
|
|
758
|
-
}
|
|
759
|
-
openStatesObjects() {
|
|
760
|
-
this.usePanel("statesObjects", "3d");
|
|
761
|
-
}
|
|
762
|
-
closeStatesObjects() {
|
|
763
|
-
this.postPanelClose({ panel: "statesObjects", format: "3d" });
|
|
764
|
-
}
|
|
765
|
-
openLinkedObjects() {
|
|
766
|
-
this.usePanel("linkedObjects", "3d");
|
|
767
|
-
}
|
|
768
|
-
closeLinkedObjects() {
|
|
769
|
-
this.postPanelClose({ panel: "linkedObjects", format: "3d" });
|
|
770
|
-
}
|
|
771
|
-
openModelTree() {
|
|
772
|
-
this.usePanel("model-tree", "3d");
|
|
773
|
-
}
|
|
774
|
-
closeModelTree() {
|
|
775
|
-
this.postPanelClose({ panel: "model-tree", format: "3d" });
|
|
776
|
-
}
|
|
777
|
-
openObjectProperties() {
|
|
778
|
-
this.usePanel("object-properties", "3d");
|
|
779
|
-
}
|
|
780
|
-
closeObjectProperties() {
|
|
781
|
-
this.postPanelClose({ panel: "object-properties", format: "3d" });
|
|
782
|
-
}
|
|
783
|
-
openSheets() {
|
|
784
|
-
this.usePanel("sheets", "3d");
|
|
785
|
-
}
|
|
786
|
-
closeSheets() {
|
|
787
|
-
this.postPanelClose({ panel: "sheets", format: "3d" });
|
|
788
|
-
}
|
|
789
|
-
getSheets(options) {
|
|
790
|
-
var _a;
|
|
791
|
-
const requestId = createRequestId2("sheets");
|
|
792
|
-
const timeoutMs = Math.max(1e3, (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : 1e4);
|
|
793
|
-
return new Promise((resolve, reject) => {
|
|
794
|
-
const timer = setTimeout(() => {
|
|
795
|
-
off();
|
|
796
|
-
reject(new Error("Timeout while getting sheets list from viewer"));
|
|
797
|
-
}, timeoutMs);
|
|
798
|
-
const off = this.viewer._on("sheets:list", (payload) => {
|
|
799
|
-
if (payload.requestId !== requestId) return;
|
|
800
|
-
clearTimeout(timer);
|
|
801
|
-
off();
|
|
802
|
-
resolve(payload.sheets);
|
|
803
|
-
});
|
|
804
|
-
this.postSheetsGetList({ requestId });
|
|
805
|
-
});
|
|
806
|
-
}
|
|
807
|
-
getObjectProperties(options) {
|
|
808
|
-
var _a;
|
|
809
|
-
const requestId = createRequestId2("object_properties");
|
|
810
|
-
const timeoutMs = Math.max(1e3, (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : 1e4);
|
|
811
|
-
return new Promise((resolve, reject) => {
|
|
812
|
-
var _a2;
|
|
813
|
-
const timer = setTimeout(() => {
|
|
814
|
-
off();
|
|
815
|
-
reject(new Error("Timeout while getting object properties list from viewer"));
|
|
816
|
-
}, timeoutMs);
|
|
817
|
-
const off = this.viewer._on("object-properties:list", (payload) => {
|
|
818
|
-
if (payload.requestId !== requestId) return;
|
|
819
|
-
clearTimeout(timer);
|
|
820
|
-
off();
|
|
821
|
-
resolve(payload.properties);
|
|
822
|
-
});
|
|
823
|
-
this.postObjectPropertiesGetList({
|
|
824
|
-
requestId,
|
|
825
|
-
nodeIds: Array.from(new Set(((_a2 = options == null ? void 0 : options.nodeIds) != null ? _a2 : []).map(String).filter(Boolean)))
|
|
826
|
-
});
|
|
827
|
-
});
|
|
828
|
-
}
|
|
829
|
-
getLinkedObjects(options) {
|
|
830
|
-
var _a;
|
|
831
|
-
const requestId = createRequestId2("linked_objects");
|
|
832
|
-
const timeoutMs = Math.max(1e3, (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : 1e4);
|
|
833
|
-
return new Promise((resolve, reject) => {
|
|
834
|
-
const timer = setTimeout(() => {
|
|
835
|
-
off();
|
|
836
|
-
reject(new Error("Timeout while getting linked objects list from viewer"));
|
|
837
|
-
}, timeoutMs);
|
|
838
|
-
const off = this.viewer._on("linked-objects:list", (payload) => {
|
|
839
|
-
if (payload.requestId !== requestId) return;
|
|
840
|
-
clearTimeout(timer);
|
|
841
|
-
off();
|
|
842
|
-
resolve(payload.linkedObjects);
|
|
843
|
-
});
|
|
844
|
-
this.postLinkedObjectsGetList({ requestId });
|
|
845
|
-
});
|
|
846
|
-
}
|
|
847
|
-
getStatesObjects(options) {
|
|
848
|
-
var _a;
|
|
849
|
-
const requestId = createRequestId2("states_objects");
|
|
850
|
-
const timeoutMs = Math.max(1e3, (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : 1e4);
|
|
851
|
-
return new Promise((resolve, reject) => {
|
|
852
|
-
const timer = setTimeout(() => {
|
|
853
|
-
off();
|
|
854
|
-
reject(new Error("Timeout while getting states objects list from viewer"));
|
|
855
|
-
}, timeoutMs);
|
|
856
|
-
const off = this.viewer._on("states-objects:list", (payload) => {
|
|
857
|
-
if (payload.requestId !== requestId) return;
|
|
858
|
-
clearTimeout(timer);
|
|
859
|
-
off();
|
|
860
|
-
resolve(payload.statesObjects);
|
|
861
|
-
});
|
|
862
|
-
this.postStatesObjectsGetList({ requestId });
|
|
863
|
-
});
|
|
864
|
-
}
|
|
865
|
-
applySheet(sheetId) {
|
|
866
|
-
this.postSheetsApply({ sheetId });
|
|
867
|
-
}
|
|
868
|
-
cuttingCloseSections() {
|
|
869
|
-
this.postCuttingAction({ action: "close" });
|
|
870
|
-
}
|
|
871
|
-
cuttingMultipleSides() {
|
|
872
|
-
this.postCuttingAction({ action: "multi" });
|
|
873
|
-
}
|
|
874
|
-
cuttingToggleSelection() {
|
|
875
|
-
this.postCuttingAction({ action: "toggle-section" });
|
|
876
|
-
}
|
|
877
|
-
cuttingTogglePlanes() {
|
|
878
|
-
this.postCuttingAction({ action: "toggle-plane" });
|
|
879
|
-
}
|
|
880
|
-
cuttingPlaneX() {
|
|
881
|
-
this.postCuttingAction({ action: "plane-x" });
|
|
882
|
-
}
|
|
883
|
-
cuttingPlaneY() {
|
|
884
|
-
this.postCuttingAction({ action: "plane-y" });
|
|
885
|
-
}
|
|
886
|
-
cuttingPlaneZ() {
|
|
887
|
-
this.postCuttingAction({ action: "plane-z" });
|
|
888
|
-
}
|
|
889
|
-
cuttingPlaneBox() {
|
|
890
|
-
this.postCuttingAction({ action: "plane-box" });
|
|
891
|
-
}
|
|
892
|
-
cuttingRotateBox() {
|
|
893
|
-
this.postCuttingAction({ action: "rotate-box" });
|
|
894
|
-
}
|
|
895
|
-
cuttingReversePlaneX() {
|
|
896
|
-
this.postCuttingAction({ action: "reverse-plane-x" });
|
|
897
|
-
}
|
|
898
|
-
cuttingReversePlaneY() {
|
|
899
|
-
this.postCuttingAction({ action: "reverse-plane-y" });
|
|
900
|
-
}
|
|
901
|
-
cuttingReversePlaneZ() {
|
|
902
|
-
this.postCuttingAction({ action: "reverse-plane-z" });
|
|
903
|
-
}
|
|
904
|
-
postConfig(payload) {
|
|
905
|
-
this.viewer.postToViewer("viewer-toolbar-config" /* TOOLBAR_CONFIG */, payload);
|
|
906
|
-
}
|
|
907
|
-
postToolbarUse(payload) {
|
|
908
|
-
this.viewer.postToViewer("viewer-toolbar-use" /* TOOLBAR_USE */, payload);
|
|
909
|
-
}
|
|
910
|
-
postPanelOpen(payload) {
|
|
911
|
-
this.viewer.postToViewer("viewer-panel-open" /* PANEL_OPEN */, payload);
|
|
912
|
-
}
|
|
913
|
-
postPanelClose(payload) {
|
|
914
|
-
this.viewer.postToViewer("viewer-panel-close" /* PANEL_CLOSE */, payload);
|
|
915
|
-
}
|
|
916
|
-
postCuttingAction(payload) {
|
|
917
|
-
this.viewer.postToViewer("viewer-cutting-plane-action" /* CUTTING_PLANE_ACTION */, payload);
|
|
918
|
-
}
|
|
919
|
-
postSheetsGetList(payload) {
|
|
920
|
-
this.viewer.postToViewer("viewer-sheets-get-list" /* SHEETS_GET_LIST */, payload);
|
|
921
|
-
}
|
|
922
|
-
postSheetsApply(payload) {
|
|
923
|
-
this.viewer.postToViewer("viewer-sheets-apply" /* SHEETS_APPLY */, payload);
|
|
924
|
-
}
|
|
925
|
-
postObjectPropertiesGetList(payload) {
|
|
926
|
-
this.viewer.postToViewer("viewer-object-properties-get-list" /* OBJECT_PROPERTIES_GET_LIST */, payload);
|
|
927
|
-
}
|
|
928
|
-
postLinkedObjectsGetList(payload) {
|
|
929
|
-
this.viewer.postToViewer("viewer-linked-objects-get-list" /* LINKED_OBJECTS_GET_LIST */, payload);
|
|
930
|
-
}
|
|
931
|
-
postStatesObjectsGetList(payload) {
|
|
932
|
-
this.viewer.postToViewer("viewer-states-objects-get-list" /* STATES_OBJECTS_GET_LIST */, payload);
|
|
933
|
-
}
|
|
934
|
-
};
|
|
935
|
-
|
|
936
|
-
// src/modules/model-tree.module.ts
|
|
937
|
-
function createRequestId3(prefix) {
|
|
938
|
-
return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
939
|
-
}
|
|
940
|
-
function buildTree(nodes, rootNodeIds) {
|
|
941
|
-
const uniqueNodes = Array.from(
|
|
942
|
-
nodes.reduce((map, node) => {
|
|
943
|
-
map.set(node.id, node);
|
|
944
|
-
return map;
|
|
945
|
-
}, /* @__PURE__ */ new Map()),
|
|
946
|
-
([, node]) => node
|
|
947
|
-
);
|
|
948
|
-
const hierarchyMap = new Map(
|
|
949
|
-
uniqueNodes.map((node) => [node.id, { ...node, children: [] }])
|
|
950
|
-
);
|
|
951
|
-
const childrenByParent = /* @__PURE__ */ new Map();
|
|
952
|
-
uniqueNodes.forEach((node) => {
|
|
953
|
-
var _a;
|
|
954
|
-
if (!node.parent) return;
|
|
955
|
-
const current = (_a = childrenByParent.get(node.parent)) != null ? _a : [];
|
|
956
|
-
current.push(node.id);
|
|
957
|
-
childrenByParent.set(node.parent, current);
|
|
958
|
-
});
|
|
959
|
-
hierarchyMap.forEach((node) => {
|
|
960
|
-
var _a, _b;
|
|
961
|
-
const childIdsFromNode = ((_a = node.childs) != null ? _a : []).filter((childId) => hierarchyMap.has(childId));
|
|
962
|
-
const fallbackChildIds = (_b = childrenByParent.get(node.id)) != null ? _b : [];
|
|
963
|
-
const childIds = childIdsFromNode.length > 0 ? childIdsFromNode : fallbackChildIds;
|
|
964
|
-
node.children = Array.from(new Set(childIds)).map((childId) => hierarchyMap.get(childId)).filter((child) => Boolean(child));
|
|
965
|
-
});
|
|
966
|
-
const rootIds = Array.isArray(rootNodeIds) && rootNodeIds.length > 0 ? rootNodeIds.filter((id) => hierarchyMap.has(id)) : uniqueNodes.filter((node) => !node.parent || !hierarchyMap.has(node.parent)).map((node) => node.id);
|
|
967
|
-
return Array.from(new Set(rootIds)).map((id) => hierarchyMap.get(id)).filter((node) => Boolean(node));
|
|
968
|
-
}
|
|
969
|
-
var ModelTreeModule = class {
|
|
970
|
-
constructor(viewer) {
|
|
971
|
-
this.viewer = viewer;
|
|
972
|
-
}
|
|
973
|
-
open() {
|
|
974
|
-
this.postPanelOpen({
|
|
975
|
-
panel: "model-tree",
|
|
976
|
-
format: "3d"
|
|
977
|
-
});
|
|
978
|
-
}
|
|
979
|
-
selectNode(nodeId) {
|
|
980
|
-
console.log("[3dviewer-sdk] modelTree.selectNode", { nodeId });
|
|
981
|
-
this.postTreeSelectNode({
|
|
982
|
-
nodeId: String(nodeId)
|
|
983
|
-
});
|
|
984
|
-
}
|
|
985
|
-
selectNodes(nodeIds) {
|
|
986
|
-
const normalizedNodeIds = this.normalizeNodeIds(nodeIds);
|
|
987
|
-
console.log("[3dviewer-sdk] modelTree.selectNodes post message", {
|
|
988
|
-
nodeIds,
|
|
989
|
-
normalizedNodeIds,
|
|
990
|
-
willClearSelection: normalizedNodeIds.length === 0
|
|
991
|
-
});
|
|
992
|
-
this.postTreeSelectNode({
|
|
993
|
-
nodeIds: normalizedNodeIds
|
|
994
|
-
});
|
|
995
|
-
}
|
|
996
|
-
setNodeVisibility(nodeIds, visible) {
|
|
997
|
-
const normalizedNodeIds = this.normalizeNodeIds(nodeIds);
|
|
998
|
-
if (normalizedNodeIds.length === 0) return;
|
|
999
|
-
this.postTreeSetNodeVisibility({
|
|
1000
|
-
nodeIds: normalizedNodeIds,
|
|
1001
|
-
visible
|
|
1002
|
-
});
|
|
1003
|
-
}
|
|
1004
|
-
hideNode(nodeIds) {
|
|
1005
|
-
this.setNodeVisibility(nodeIds, false);
|
|
1006
|
-
}
|
|
1007
|
-
showNode(nodeIds) {
|
|
1008
|
-
this.setNodeVisibility(nodeIds, true);
|
|
1009
|
-
}
|
|
1010
|
-
getNodeIds(options) {
|
|
1011
|
-
const requestId = createRequestId3("tree");
|
|
1012
|
-
const timeoutMs = this.resolveTimeoutMs(options);
|
|
1013
|
-
return new Promise((resolve, reject) => {
|
|
1014
|
-
const timer = setTimeout(() => {
|
|
1015
|
-
off();
|
|
1016
|
-
reject(new Error("Timeout while getting node ids from viewer"));
|
|
1017
|
-
}, timeoutMs);
|
|
1018
|
-
const off = this.viewer._on("modelTree:node-ids", (payload) => {
|
|
1019
|
-
if (payload.requestId !== requestId) return;
|
|
1020
|
-
clearTimeout(timer);
|
|
1021
|
-
off();
|
|
1022
|
-
resolve(payload.nodeIds);
|
|
1023
|
-
});
|
|
1024
|
-
this.postTreeGetNodeIds({
|
|
1025
|
-
requestId,
|
|
1026
|
-
onlyRealNodes: (options == null ? void 0 : options.onlyRealNodes) !== false
|
|
1027
|
-
});
|
|
1028
|
-
});
|
|
1029
|
-
}
|
|
1030
|
-
getNodes(options) {
|
|
1031
|
-
return this.requestNodes(options).then((response) => response.nodes);
|
|
1032
|
-
}
|
|
1033
|
-
getTree(options) {
|
|
1034
|
-
return this.requestNodes(options).then((response) => buildTree(response.nodes, response.rootNodeIds));
|
|
1035
|
-
}
|
|
1036
|
-
requestNodes(options) {
|
|
1037
|
-
const requestId = createRequestId3("tree_nodes");
|
|
1038
|
-
const timeoutMs = this.resolveTimeoutMs(options);
|
|
1039
|
-
return new Promise((resolve, reject) => {
|
|
1040
|
-
const timer = setTimeout(() => {
|
|
1041
|
-
off();
|
|
1042
|
-
reject(new Error("Timeout while getting model tree nodes from viewer"));
|
|
1043
|
-
}, timeoutMs);
|
|
1044
|
-
const off = this.viewer._on("modelTree:nodes", (payload) => {
|
|
1045
|
-
if (payload.requestId !== requestId) return;
|
|
1046
|
-
clearTimeout(timer);
|
|
1047
|
-
off();
|
|
1048
|
-
resolve({
|
|
1049
|
-
nodes: payload.nodes,
|
|
1050
|
-
rootNodeIds: payload.rootNodeIds
|
|
1051
|
-
});
|
|
1052
|
-
});
|
|
1053
|
-
this.postTreeGetNodes({
|
|
1054
|
-
requestId,
|
|
1055
|
-
// For backward compatibility, default includes helper/system nodes unless caller opts in.
|
|
1056
|
-
onlyRealNodes: (options == null ? void 0 : options.onlyRealNodes) === true
|
|
1057
|
-
});
|
|
1058
|
-
});
|
|
1059
|
-
}
|
|
1060
|
-
resolveTimeoutMs(options) {
|
|
1061
|
-
var _a;
|
|
1062
|
-
return Math.max(1e3, (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : 1e4);
|
|
1063
|
-
}
|
|
1064
|
-
normalizeNodeIds(nodeIds) {
|
|
1065
|
-
return Array.from(
|
|
1066
|
-
new Set(
|
|
1067
|
-
nodeIds.map((nodeId) => String(nodeId).trim()).filter((nodeId) => nodeId !== "")
|
|
1068
|
-
)
|
|
1069
|
-
);
|
|
1070
|
-
}
|
|
1071
|
-
postPanelOpen(payload) {
|
|
1072
|
-
this.viewer.postToViewer("viewer-panel-open" /* PANEL_OPEN */, payload);
|
|
1073
|
-
}
|
|
1074
|
-
postTreeSelectNode(payload) {
|
|
1075
|
-
this.viewer.postToViewer("viewer-tree-select-node" /* TREE_SELECT_NODE */, payload);
|
|
1076
|
-
}
|
|
1077
|
-
postTreeSetNodeVisibility(payload) {
|
|
1078
|
-
this.viewer.postToViewer("viewer-tree-set-node-visibility" /* TREE_SET_NODE_VISIBILITY */, payload);
|
|
1079
|
-
}
|
|
1080
|
-
postTreeGetNodeIds(payload) {
|
|
1081
|
-
this.viewer.postToViewer("viewer-tree-get-node-ids" /* TREE_GET_NODE_IDS */, payload);
|
|
1082
|
-
}
|
|
1083
|
-
postTreeGetNodes(payload) {
|
|
1084
|
-
this.viewer.postToViewer("viewer-tree-get-nodes" /* TREE_GET_NODES */, payload);
|
|
1085
|
-
}
|
|
1086
|
-
};
|
|
1087
|
-
|
|
1088
|
-
// src/modules/markup.module.ts
|
|
1089
|
-
function createRequestId4(prefix) {
|
|
1090
|
-
return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
1091
|
-
}
|
|
1092
|
-
var MarkupModule = class {
|
|
1093
|
-
constructor(viewer) {
|
|
1094
|
-
this.viewer = viewer;
|
|
1095
|
-
}
|
|
1096
|
-
action(action) {
|
|
1097
|
-
this.viewer.postToViewer("viewer-markup-action" /* MARKUP_ACTION */, { action });
|
|
1098
|
-
}
|
|
1099
|
-
drawLine() {
|
|
1100
|
-
this.action("line");
|
|
1101
|
-
}
|
|
1102
|
-
drawArrow() {
|
|
1103
|
-
this.action("arrow");
|
|
1104
|
-
}
|
|
1105
|
-
drawCircle() {
|
|
1106
|
-
this.action("circle");
|
|
1107
|
-
}
|
|
1108
|
-
drawEllipse() {
|
|
1109
|
-
this.action("ellipse");
|
|
1110
|
-
}
|
|
1111
|
-
drawRectangle() {
|
|
1112
|
-
this.action("rectangle");
|
|
1113
|
-
}
|
|
1114
|
-
drawPolygon() {
|
|
1115
|
-
this.action("polygon");
|
|
1116
|
-
}
|
|
1117
|
-
drawPolyline() {
|
|
1118
|
-
this.action("polyline");
|
|
1119
|
-
}
|
|
1120
|
-
drawTextBox() {
|
|
1121
|
-
this.action("textbox");
|
|
1122
|
-
}
|
|
1123
|
-
drawNote() {
|
|
1124
|
-
this.action("note");
|
|
1125
|
-
}
|
|
1126
|
-
drawCallout() {
|
|
1127
|
-
this.action("callout");
|
|
1128
|
-
}
|
|
1129
|
-
drawCloud() {
|
|
1130
|
-
this.action("cloud");
|
|
1131
|
-
}
|
|
1132
|
-
drawFreehand() {
|
|
1133
|
-
this.action("freehand");
|
|
1134
|
-
}
|
|
1135
|
-
save(options) {
|
|
1136
|
-
return this.runRequest("markup-save", "viewer-markup-save" /* MARKUP_SAVE */, "markup:save", options);
|
|
1137
|
-
}
|
|
1138
|
-
cancel(options) {
|
|
1139
|
-
return this.runRequest("markup-cancel", "viewer-markup-cancel" /* MARKUP_CANCEL */, "markup:cancel", options);
|
|
1140
|
-
}
|
|
1141
|
-
getList(options) {
|
|
1142
|
-
var _a;
|
|
1143
|
-
const requestId = createRequestId4("markup-list");
|
|
1144
|
-
const timeoutMs = Math.max(1e3, (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : 1e4);
|
|
1145
|
-
return new Promise((resolve, reject) => {
|
|
1146
|
-
const timer = setTimeout(() => {
|
|
1147
|
-
off();
|
|
1148
|
-
reject(new Error("Timeout while getting markup list from viewer"));
|
|
1149
|
-
}, timeoutMs);
|
|
1150
|
-
const off = this.viewer._on("markup:list", (payload) => {
|
|
1151
|
-
if (payload.requestId !== requestId) return;
|
|
1152
|
-
clearTimeout(timer);
|
|
1153
|
-
off();
|
|
1154
|
-
resolve(payload.markups);
|
|
1155
|
-
});
|
|
1156
|
-
this.viewer.postToViewer("viewer-markup-get-list" /* MARKUP_GET_LIST */, { requestId });
|
|
1157
|
-
});
|
|
1158
|
-
}
|
|
1159
|
-
runRequest(prefix, messageType, eventName, options) {
|
|
1160
|
-
var _a;
|
|
1161
|
-
const requestId = createRequestId4(prefix);
|
|
1162
|
-
const timeoutMs = Math.max(1e3, (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : 1e4);
|
|
1163
|
-
return new Promise((resolve, reject) => {
|
|
1164
|
-
const timer = setTimeout(() => {
|
|
1165
|
-
off();
|
|
1166
|
-
reject(new Error(`Timeout while waiting for ${prefix} result from viewer`));
|
|
1167
|
-
}, timeoutMs);
|
|
1168
|
-
const off = this.viewer._on(eventName, (payload) => {
|
|
1169
|
-
if (payload.requestId !== requestId) return;
|
|
1170
|
-
clearTimeout(timer);
|
|
1171
|
-
off();
|
|
1172
|
-
if (payload.success) {
|
|
1173
|
-
resolve();
|
|
1174
|
-
return;
|
|
1175
|
-
}
|
|
1176
|
-
reject(new Error(payload.error || `Viewer ${prefix} failed`));
|
|
1177
|
-
});
|
|
1178
|
-
this.viewer.postToViewer(messageType, { requestId });
|
|
1179
|
-
});
|
|
1180
|
-
}
|
|
1181
|
-
};
|
|
1182
|
-
|
|
1183
|
-
// src/modules/language.module.ts
|
|
1184
|
-
var LanguageModule = class {
|
|
1185
|
-
constructor(viewer) {
|
|
1186
|
-
this.viewer = viewer;
|
|
1187
|
-
}
|
|
1188
|
-
change(language) {
|
|
1189
|
-
this.viewer.postToViewer("viewer-language-change" /* LANGUAGE_CHANGE */, {
|
|
1190
|
-
language,
|
|
1191
|
-
timestamp: Date.now()
|
|
1192
|
-
});
|
|
1193
|
-
}
|
|
1194
|
-
set(language) {
|
|
1195
|
-
this.change(language);
|
|
1196
|
-
}
|
|
1197
|
-
};
|
|
1198
|
-
|
|
1199
|
-
// src/modules/object-properties.module.ts
|
|
1200
|
-
var OBJECT_PROPERTIES_TIMEOUT_ERROR = "Timeout while getting object properties from viewer";
|
|
1201
|
-
function createObjectPropertiesError(message, errorStatus) {
|
|
1202
|
-
const error = new Error(message);
|
|
1203
|
-
error.name = "ObjectPropertiesError";
|
|
1204
|
-
error.errorStatus = errorStatus;
|
|
1205
|
-
return error;
|
|
1206
|
-
}
|
|
1207
|
-
function createRequestId5(prefix) {
|
|
1208
|
-
return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
1209
|
-
}
|
|
1210
|
-
function normalizeNodeIds(nodeIds) {
|
|
1211
|
-
return Array.from(new Set(
|
|
1212
|
-
nodeIds.map((nodeId) => String(nodeId).trim()).filter((nodeId) => nodeId !== "")
|
|
1213
|
-
));
|
|
1214
|
-
}
|
|
1215
|
-
var ObjectPropertiesModule = class {
|
|
1216
|
-
constructor(viewer) {
|
|
1217
|
-
this.viewer = viewer;
|
|
1218
|
-
}
|
|
1219
|
-
get(nodeIds, options) {
|
|
1220
|
-
return this.getByNodeIds(nodeIds, options);
|
|
1221
|
-
}
|
|
1222
|
-
getByNodeIds(nodeIds, options) {
|
|
1223
|
-
var _a;
|
|
1224
|
-
const normalizedNodeIds = normalizeNodeIds(nodeIds);
|
|
1225
|
-
const requestId = createRequestId5("object_properties");
|
|
1226
|
-
if (normalizedNodeIds.length === 0) {
|
|
1227
|
-
return Promise.resolve({
|
|
1228
|
-
requestId,
|
|
1229
|
-
selectionKey: "",
|
|
1230
|
-
nodeIds: [],
|
|
1231
|
-
persistentIds: [],
|
|
1232
|
-
properties: [],
|
|
1233
|
-
timestamp: Date.now()
|
|
1234
|
-
});
|
|
1235
|
-
}
|
|
1236
|
-
const timeoutMs = Math.max(1e3, (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : 12e4);
|
|
1237
|
-
return new Promise((resolve, reject) => {
|
|
1238
|
-
const timer = setTimeout(() => {
|
|
1239
|
-
off();
|
|
1240
|
-
reject(createObjectPropertiesError(OBJECT_PROPERTIES_TIMEOUT_ERROR, "TIMEOUT"));
|
|
1241
|
-
}, timeoutMs);
|
|
1242
|
-
const off = this.viewer._on("object-properties:list", (payload2) => {
|
|
1243
|
-
if (payload2.requestId !== requestId) return;
|
|
1244
|
-
clearTimeout(timer);
|
|
1245
|
-
off();
|
|
1246
|
-
resolve(payload2);
|
|
1247
|
-
});
|
|
1248
|
-
const payload = {
|
|
1249
|
-
requestId,
|
|
1250
|
-
nodeIds: normalizedNodeIds
|
|
1251
|
-
};
|
|
1252
|
-
if (typeof (options == null ? void 0 : options.expandToRealNodes) === "boolean") {
|
|
1253
|
-
payload.expandToRealNodes = options.expandToRealNodes;
|
|
1254
|
-
}
|
|
1255
|
-
if (typeof (options == null ? void 0 : options.includeSelectionMeta) === "boolean") {
|
|
1256
|
-
payload.includeSelectionMeta = options.includeSelectionMeta;
|
|
1257
|
-
}
|
|
1258
|
-
this.viewer.postToViewer("viewer-object-properties-get-list" /* OBJECT_PROPERTIES_GET_LIST */, payload);
|
|
1259
|
-
});
|
|
1260
|
-
}
|
|
1261
|
-
};
|
|
1262
|
-
|
|
1263
|
-
// src/viewer.ts
|
|
1264
|
-
var Viewer3D = class {
|
|
1265
|
-
constructor(options) {
|
|
1266
|
-
this.options = options;
|
|
1267
|
-
this.containerEl = null;
|
|
1268
|
-
this.iframeEl = null;
|
|
1269
|
-
this.initialized = false;
|
|
1270
|
-
this.emitter = new Emitter();
|
|
1271
|
-
this.handleMessage = (event) => {
|
|
1272
|
-
var _a, _b, _c, _d, _e;
|
|
1273
|
-
const data = event.data;
|
|
1274
|
-
if (!data || typeof data !== "object") return;
|
|
1275
|
-
switch (data.type) {
|
|
1276
|
-
case "viewer-home-click" /* HOME_CLICK */:
|
|
1277
|
-
this._emit("camera:home", { timestamp: Date.now() });
|
|
1278
|
-
break;
|
|
1279
|
-
case "viewer-camera-zoom" /* CAMERA_ZOOM */: {
|
|
1280
|
-
const payload = data.payload;
|
|
1281
|
-
if (!payload) break;
|
|
1282
|
-
this._emit("camera:zoom", {
|
|
1283
|
-
requestId: payload.requestId ? String(payload.requestId) : void 0,
|
|
1284
|
-
percent: Number(payload.percent) || 0,
|
|
1285
|
-
zoomFactor: Number(payload.zoomFactor) || 1,
|
|
1286
|
-
timestamp: Number(payload.timestamp) || Date.now()
|
|
1287
|
-
});
|
|
1288
|
-
break;
|
|
1289
|
-
}
|
|
1290
|
-
case "viewer-node-select" /* NODE_SELECT */:
|
|
1291
|
-
this._emit("node:select", { nodeId: String((_b = (_a = data.payload) == null ? void 0 : _a.nodeId) != null ? _b : ""), timestamp: Date.now() });
|
|
1292
|
-
break;
|
|
1293
|
-
case "viewer-node-selection-change" /* NODE_SELECTION_CHANGE */: {
|
|
1294
|
-
const payload = data.payload;
|
|
1295
|
-
const rawNodeIds = payload == null ? void 0 : payload.nodeIds;
|
|
1296
|
-
const nodeIds = Array.isArray(rawNodeIds) ? rawNodeIds.map((nodeId) => String(nodeId)) : [];
|
|
1297
|
-
this._emit("node:selection-change", {
|
|
1298
|
-
nodeIds,
|
|
1299
|
-
timestamp: Number(payload == null ? void 0 : payload.timestamp) || Date.now()
|
|
1300
|
-
});
|
|
1301
|
-
break;
|
|
1302
|
-
}
|
|
1303
|
-
case "viewer-pan-change" /* PAN_CHANGE */:
|
|
1304
|
-
this._emit("interaction:pan-change", { enabled: Boolean((_c = data.payload) == null ? void 0 : _c.enabled) });
|
|
1305
|
-
break;
|
|
1306
|
-
case "viewer-pdf-plan-mode" /* PDF_PLAN_MODE */: {
|
|
1307
|
-
const payload = data.payload;
|
|
1308
|
-
this._emit("toolbar:pdf-plan-mode", {
|
|
1309
|
-
mode: "plan",
|
|
1310
|
-
timestamp: Number(payload == null ? void 0 : payload.timestamp) || Date.now()
|
|
1311
|
-
});
|
|
1312
|
-
break;
|
|
1313
|
-
}
|
|
1314
|
-
case "viewer-pdf-document-mode" /* PDF_DOCUMENT_MODE */: {
|
|
1315
|
-
const payload = data.payload;
|
|
1316
|
-
this._emit("toolbar:pdf-document-mode", {
|
|
1317
|
-
mode: "document",
|
|
1318
|
-
timestamp: Number(payload == null ? void 0 : payload.timestamp) || Date.now()
|
|
1319
|
-
});
|
|
1320
|
-
break;
|
|
1321
|
-
}
|
|
1322
|
-
case "viewer-pdf-first-page" /* PDF_FIRST_PAGE */: {
|
|
1323
|
-
const payload = data.payload;
|
|
1324
|
-
this._emit("toolbar:pdf-first-page", {
|
|
1325
|
-
timestamp: Number(payload == null ? void 0 : payload.timestamp) || Date.now()
|
|
1326
|
-
});
|
|
1327
|
-
break;
|
|
1328
|
-
}
|
|
1329
|
-
case "viewer-pdf-previous-page" /* PDF_PREVIOUS_PAGE */: {
|
|
1330
|
-
const payload = data.payload;
|
|
1331
|
-
this._emit("toolbar:pdf-previous-page", {
|
|
1332
|
-
timestamp: Number(payload == null ? void 0 : payload.timestamp) || Date.now()
|
|
1333
|
-
});
|
|
1334
|
-
break;
|
|
1335
|
-
}
|
|
1336
|
-
case "viewer-pdf-next-page" /* PDF_NEXT_PAGE */: {
|
|
1337
|
-
const payload = data.payload;
|
|
1338
|
-
this._emit("toolbar:pdf-next-page", {
|
|
1339
|
-
timestamp: Number(payload == null ? void 0 : payload.timestamp) || Date.now()
|
|
1340
|
-
});
|
|
1341
|
-
break;
|
|
1342
|
-
}
|
|
1343
|
-
case "viewer-pdf-last-page" /* PDF_LAST_PAGE */: {
|
|
1344
|
-
const payload = data.payload;
|
|
1345
|
-
this._emit("toolbar:pdf-last-page", {
|
|
1346
|
-
timestamp: Number(payload == null ? void 0 : payload.timestamp) || Date.now()
|
|
1347
|
-
});
|
|
1348
|
-
break;
|
|
1349
|
-
}
|
|
1350
|
-
case "viewer-pdf-current-page" /* PDF_CURRENT_PAGE */: {
|
|
1351
|
-
const payload = data.payload;
|
|
1352
|
-
if (!payload) break;
|
|
1353
|
-
this._emit("toolbar:pdf-current-page", {
|
|
1354
|
-
pageIndex: Number(payload.pageIndex) || 0,
|
|
1355
|
-
pageNumber: Number(payload.pageNumber) || 1,
|
|
1356
|
-
timestamp: Number(payload.timestamp) || Date.now()
|
|
1357
|
-
});
|
|
1358
|
-
break;
|
|
1359
|
-
}
|
|
1360
|
-
case "viewer-tree-node-ids" /* TREE_NODE_IDS */: {
|
|
1361
|
-
const payload = data.payload;
|
|
1362
|
-
if (!payload || !payload.requestId || !Array.isArray(payload.nodeIds)) break;
|
|
1363
|
-
this._emit("modelTree:node-ids", {
|
|
1364
|
-
requestId: String(payload.requestId),
|
|
1365
|
-
nodeIds: payload.nodeIds.map(String),
|
|
1366
|
-
timestamp: Number(payload.timestamp) || Date.now()
|
|
1367
|
-
});
|
|
1368
|
-
break;
|
|
1369
|
-
}
|
|
1370
|
-
case "viewer-tree-nodes" /* TREE_NODES */: {
|
|
1371
|
-
const payload = data.payload;
|
|
1372
|
-
if (!payload || !payload.requestId || !Array.isArray(payload.nodes)) break;
|
|
1373
|
-
this._emit("modelTree:nodes", {
|
|
1374
|
-
requestId: String(payload.requestId),
|
|
1375
|
-
nodes: payload.nodes.filter((node) => node && typeof node === "object").map((node) => {
|
|
1376
|
-
var _a2, _b2;
|
|
1377
|
-
return {
|
|
1378
|
-
id: String((_a2 = node.id) != null ? _a2 : ""),
|
|
1379
|
-
name: String((_b2 = node.name) != null ? _b2 : ""),
|
|
1380
|
-
type: Number(node.type) || 0,
|
|
1381
|
-
parent: node.parent ? String(node.parent) : void 0,
|
|
1382
|
-
childs: Array.isArray(node.childs) ? node.childs.map(String) : [],
|
|
1383
|
-
modelFileId: node.modelFileId ? String(node.modelFileId) : void 0,
|
|
1384
|
-
persistentId: node.persistentId ? String(node.persistentId) : void 0,
|
|
1385
|
-
categoryName: node.categoryName ? String(node.categoryName) : void 0,
|
|
1386
|
-
familyName: node.familyName ? String(node.familyName) : void 0,
|
|
1387
|
-
typeName: node.typeName ? String(node.typeName) : void 0,
|
|
1388
|
-
isRealNode: Boolean(node.isRealNode)
|
|
1389
|
-
};
|
|
1390
|
-
}),
|
|
1391
|
-
rootNodeIds: Array.isArray(payload.rootNodeIds) ? payload.rootNodeIds.map(String) : void 0,
|
|
1392
|
-
timestamp: Number(payload.timestamp) || Date.now()
|
|
1393
|
-
});
|
|
1394
|
-
break;
|
|
1395
|
-
}
|
|
1396
|
-
case "viewer-sheets-list" /* SHEETS_LIST */: {
|
|
1397
|
-
const payload = data.payload;
|
|
1398
|
-
if (!payload || !payload.requestId || !Array.isArray(payload.sheets)) break;
|
|
1399
|
-
this._emit("sheets:list", {
|
|
1400
|
-
requestId: String(payload.requestId),
|
|
1401
|
-
sheets: payload.sheets.map((sheet) => {
|
|
1402
|
-
var _a2;
|
|
1403
|
-
return {
|
|
1404
|
-
id: sheet.id,
|
|
1405
|
-
name: String((_a2 = sheet.name) != null ? _a2 : ""),
|
|
1406
|
-
is3D: Boolean(sheet.is3D),
|
|
1407
|
-
viewId: sheet.viewId ? String(sheet.viewId) : void 0
|
|
1408
|
-
};
|
|
1409
|
-
}),
|
|
1410
|
-
activeSheetId: (_d = payload.activeSheetId) != null ? _d : null,
|
|
1411
|
-
timestamp: Number(payload.timestamp) || Date.now()
|
|
1412
|
-
});
|
|
1413
|
-
break;
|
|
1414
|
-
}
|
|
1415
|
-
case "viewer-object-properties-list" /* OBJECT_PROPERTIES_LIST */: {
|
|
1416
|
-
const payload = data.payload;
|
|
1417
|
-
if (!payload || !payload.requestId || !Array.isArray(payload.properties)) break;
|
|
1418
|
-
this._emit("object-properties:list", {
|
|
1419
|
-
requestId: String(payload.requestId),
|
|
1420
|
-
selectionKey: String((_e = payload.selectionKey) != null ? _e : ""),
|
|
1421
|
-
nodeIds: Array.isArray(payload.nodeIds) ? payload.nodeIds.map(String) : [],
|
|
1422
|
-
persistentIds: Array.isArray(payload.persistentIds) ? payload.persistentIds.map(String) : [],
|
|
1423
|
-
properties: payload.properties.filter((item) => item && typeof item === "object").map((item) => ({ ...item })),
|
|
1424
|
-
timestamp: Number(payload.timestamp) || Date.now()
|
|
1425
|
-
});
|
|
1426
|
-
break;
|
|
1427
|
-
}
|
|
1428
|
-
case "viewer-linked-objects-list" /* LINKED_OBJECTS_LIST */: {
|
|
1429
|
-
const payload = data.payload;
|
|
1430
|
-
if (!payload || !payload.requestId || !Array.isArray(payload.linkedObjects)) break;
|
|
1431
|
-
this._emit("linked-objects:list", {
|
|
1432
|
-
requestId: String(payload.requestId),
|
|
1433
|
-
linkedObjects: payload.linkedObjects.filter((item) => item && typeof item === "object").map((item) => ({ ...item })),
|
|
1434
|
-
timestamp: Number(payload.timestamp) || Date.now()
|
|
1435
|
-
});
|
|
1436
|
-
break;
|
|
1437
|
-
}
|
|
1438
|
-
case "viewer-states-objects-list" /* STATES_OBJECTS_LIST */: {
|
|
1439
|
-
const payload = data.payload;
|
|
1440
|
-
if (!payload || !payload.requestId || !Array.isArray(payload.statesObjects)) break;
|
|
1441
|
-
this._emit("states-objects:list", {
|
|
1442
|
-
requestId: String(payload.requestId),
|
|
1443
|
-
statesObjects: payload.statesObjects.map((item) => {
|
|
1444
|
-
var _a2, _b2, _c2, _d2, _e2, _f, _g;
|
|
1445
|
-
return {
|
|
1446
|
-
id: String((_a2 = item.id) != null ? _a2 : ""),
|
|
1447
|
-
name: String((_b2 = item.name) != null ? _b2 : ""),
|
|
1448
|
-
char: String((_c2 = item.char) != null ? _c2 : ""),
|
|
1449
|
-
object: Array.isArray(item.object) ? item.object.map((objectItem) => {
|
|
1450
|
-
var _a3;
|
|
1451
|
-
return {
|
|
1452
|
-
name: String((_a3 = objectItem == null ? void 0 : objectItem.name) != null ? _a3 : ""),
|
|
1453
|
-
id: Number(objectItem == null ? void 0 : objectItem.id) || 0
|
|
1454
|
-
};
|
|
1455
|
-
}) : [],
|
|
1456
|
-
states: {
|
|
1457
|
-
color: String((_e2 = (_d2 = item.states) == null ? void 0 : _d2.color) != null ? _e2 : ""),
|
|
1458
|
-
type: String((_g = (_f = item.states) == null ? void 0 : _f.type) != null ? _g : "")
|
|
1459
|
-
}
|
|
1460
|
-
};
|
|
1461
|
-
}),
|
|
1462
|
-
timestamp: Number(payload.timestamp) || Date.now()
|
|
1463
|
-
});
|
|
1464
|
-
break;
|
|
1465
|
-
}
|
|
1466
|
-
case "viewer-markup-list" /* MARKUP_LIST */: {
|
|
1467
|
-
const payload = data.payload;
|
|
1468
|
-
if (!payload || !payload.requestId || !Array.isArray(payload.markups)) break;
|
|
1469
|
-
this._emit("markup:list", {
|
|
1470
|
-
requestId: String(payload.requestId),
|
|
1471
|
-
markups: payload.markups.map((markup) => {
|
|
1472
|
-
var _a2, _b2;
|
|
1473
|
-
return {
|
|
1474
|
-
id: String(markup.id),
|
|
1475
|
-
viewId: String(markup.viewId),
|
|
1476
|
-
viewName: markup.viewName ? String(markup.viewName) : void 0,
|
|
1477
|
-
title: String((_a2 = markup.title) != null ? _a2 : ""),
|
|
1478
|
-
type: String((_b2 = markup.type) != null ? _b2 : ""),
|
|
1479
|
-
shapeName: markup.shapeName ? String(markup.shapeName) : void 0,
|
|
1480
|
-
createdDate: markup.createdDate ? String(markup.createdDate) : void 0,
|
|
1481
|
-
modifiedDate: markup.modifiedDate ? String(markup.modifiedDate) : void 0,
|
|
1482
|
-
createdBy: markup.createdBy ? String(markup.createdBy) : void 0,
|
|
1483
|
-
lastModifiedBy: markup.lastModifiedBy ? String(markup.lastModifiedBy) : void 0
|
|
1484
|
-
};
|
|
1485
|
-
}),
|
|
1486
|
-
timestamp: Number(payload.timestamp) || Date.now()
|
|
1487
|
-
});
|
|
1488
|
-
break;
|
|
1489
|
-
}
|
|
1490
|
-
case "viewer-markup-save-result" /* MARKUP_SAVE_RESULT */: {
|
|
1491
|
-
const payload = data.payload;
|
|
1492
|
-
if (!payload || !payload.requestId) break;
|
|
1493
|
-
this._emit("markup:save", {
|
|
1494
|
-
requestId: String(payload.requestId),
|
|
1495
|
-
success: Boolean(payload.success),
|
|
1496
|
-
error: payload.error ? String(payload.error) : void 0,
|
|
1497
|
-
timestamp: Number(payload.timestamp) || Date.now()
|
|
1498
|
-
});
|
|
1499
|
-
break;
|
|
1500
|
-
}
|
|
1501
|
-
case "viewer-markup-cancel-result" /* MARKUP_CANCEL_RESULT */: {
|
|
1502
|
-
const payload = data.payload;
|
|
1503
|
-
if (!payload || !payload.requestId) break;
|
|
1504
|
-
this._emit("markup:cancel", {
|
|
1505
|
-
requestId: String(payload.requestId),
|
|
1506
|
-
success: Boolean(payload.success),
|
|
1507
|
-
error: payload.error ? String(payload.error) : void 0,
|
|
1508
|
-
timestamp: Number(payload.timestamp) || Date.now()
|
|
1509
|
-
});
|
|
1510
|
-
break;
|
|
1511
|
-
}
|
|
1512
|
-
default:
|
|
1513
|
-
break;
|
|
1514
|
-
}
|
|
1515
|
-
};
|
|
1516
|
-
this.camera = new CameraModule(this);
|
|
1517
|
-
this.interaction = new InteractionModule(this);
|
|
1518
|
-
this.node = new NodeModule(this);
|
|
1519
|
-
this.files = new FilesModule(this);
|
|
1520
|
-
this.toolbar = new ToolbarModule(this);
|
|
1521
|
-
this.modelTree = new ModelTreeModule(this);
|
|
1522
|
-
this.markup = new MarkupModule(this);
|
|
1523
|
-
this.language = new LanguageModule(this);
|
|
1524
|
-
this.objectProperties = new ObjectPropertiesModule(this);
|
|
1525
|
-
}
|
|
1526
|
-
// ===== options helpers =====
|
|
1527
|
-
getOptions() {
|
|
1528
|
-
return this.options;
|
|
1529
|
-
}
|
|
1530
|
-
patchOptions(next) {
|
|
1531
|
-
this.options = { ...this.options, ...next };
|
|
1532
|
-
}
|
|
1533
|
-
getUrl() {
|
|
1534
|
-
var _a;
|
|
1535
|
-
return (_a = this.options.url) != null ? _a : null;
|
|
1536
|
-
}
|
|
1537
|
-
// ===== lifecycle =====
|
|
1538
|
-
init() {
|
|
1539
|
-
if (this.initialized) return;
|
|
1540
|
-
this.containerEl = typeof this.options.container === "string" ? document.querySelector(this.options.container) : this.options.container;
|
|
1541
|
-
if (!this.containerEl) throw new Error("Container element not found");
|
|
1542
|
-
window.addEventListener("message", this.handleMessage);
|
|
1543
|
-
this.initialized = true;
|
|
1544
|
-
}
|
|
1545
|
-
async render(file) {
|
|
1546
|
-
this.ensureInit();
|
|
1547
|
-
if (this.iframeEl) return;
|
|
1548
|
-
if (!this.options.url) return this.files.render(file);
|
|
1549
|
-
const iframe = document.createElement("iframe");
|
|
1550
|
-
iframe.src = this.withInitialOptions(this.options.url);
|
|
1551
|
-
iframe.style.border = "none";
|
|
1552
|
-
iframe.style.width = this.options.width || "100%";
|
|
1553
|
-
iframe.style.height = this.options.height || "100%";
|
|
1554
|
-
iframe.width = this.options.width || "100%";
|
|
1555
|
-
iframe.height = this.options.height || "100%";
|
|
1556
|
-
if (this.options.sandbox) iframe.setAttribute("sandbox", this.options.sandbox);
|
|
1557
|
-
this.containerEl.appendChild(iframe);
|
|
1558
|
-
this.iframeEl = iframe;
|
|
1559
|
-
}
|
|
1560
|
-
open(url) {
|
|
1561
|
-
this.ensureInit();
|
|
1562
|
-
this.options.url = url;
|
|
1563
|
-
const finalUrl = this.withInitialOptions(url);
|
|
1564
|
-
if (!this.iframeEl) {
|
|
1565
|
-
this.render();
|
|
1566
|
-
return;
|
|
1567
|
-
}
|
|
1568
|
-
this.iframeEl.src = finalUrl;
|
|
1569
|
-
}
|
|
1570
|
-
destroy() {
|
|
1571
|
-
window.removeEventListener("message", this.handleMessage);
|
|
1572
|
-
if (this.iframeEl && this.containerEl) {
|
|
1573
|
-
try {
|
|
1574
|
-
this.containerEl.removeChild(this.iframeEl);
|
|
1575
|
-
} catch {
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
this.iframeEl = null;
|
|
1579
|
-
this.containerEl = null;
|
|
1580
|
-
this.initialized = false;
|
|
1581
|
-
}
|
|
1582
|
-
ensureInit() {
|
|
1583
|
-
if (!this.initialized) throw new Error("Call viewer.init() before using viewer");
|
|
1584
|
-
}
|
|
1585
|
-
withInitialOptions(url) {
|
|
1586
|
-
try {
|
|
1587
|
-
const parsedUrl = new URL(url, window.location.href);
|
|
1588
|
-
const initialToolbar = this.normalizeInitialToolbar();
|
|
1589
|
-
if (initialToolbar) {
|
|
1590
|
-
parsedUrl.searchParams.set("useToolbar", JSON.stringify(initialToolbar));
|
|
1591
|
-
}
|
|
1592
|
-
return parsedUrl.toString();
|
|
1593
|
-
} catch {
|
|
1594
|
-
return url;
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
normalizeInitialToolbar() {
|
|
1598
|
-
const initialToolbar = this.options.initialToolbar;
|
|
1599
|
-
if (!initialToolbar) return null;
|
|
1600
|
-
if (typeof initialToolbar === "string") {
|
|
1601
|
-
return { [initialToolbar]: true };
|
|
1602
|
-
}
|
|
1603
|
-
if (Array.isArray(initialToolbar)) {
|
|
1604
|
-
return initialToolbar.reduce((result, target) => {
|
|
1605
|
-
result[target] = true;
|
|
1606
|
-
return result;
|
|
1607
|
-
}, {});
|
|
1608
|
-
}
|
|
1609
|
-
const entries = Object.entries(initialToolbar).filter(([, enabled]) => enabled === true);
|
|
1610
|
-
if (entries.length === 0) return null;
|
|
1611
|
-
return entries.reduce((result, [target]) => {
|
|
1612
|
-
result[target] = true;
|
|
1613
|
-
return result;
|
|
1614
|
-
}, {});
|
|
1615
|
-
}
|
|
1616
|
-
// ===== typed internal events used by modules =====
|
|
1617
|
-
_on(event, cb) {
|
|
1618
|
-
return this.emitter.on(event, cb);
|
|
1619
|
-
}
|
|
1620
|
-
_off(event, cb) {
|
|
1621
|
-
this.emitter.off(event, cb);
|
|
1622
|
-
}
|
|
1623
|
-
_emit(event, payload) {
|
|
1624
|
-
this.emitter.emit(event, payload);
|
|
1625
|
-
}
|
|
1626
|
-
// ===== postMessage bridge =====
|
|
1627
|
-
postToViewer(type, payload) {
|
|
1628
|
-
var _a;
|
|
1629
|
-
if (!((_a = this.iframeEl) == null ? void 0 : _a.contentWindow)) return;
|
|
1630
|
-
const message = {
|
|
1631
|
-
source: "HC_SDK" /* SDK */,
|
|
1632
|
-
type,
|
|
1633
|
-
payload
|
|
1634
|
-
};
|
|
1635
|
-
const targetOrigin = this.options.allowedOrigin || "*";
|
|
1636
|
-
this.iframeEl.contentWindow.postMessage(message, targetOrigin);
|
|
1637
|
-
}
|
|
1638
|
-
};
|
|
1639
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
1640
|
-
0 && (module.exports = {
|
|
1641
|
-
Viewer3D
|
|
1642
|
-
});
|