@inweb/viewer-visualize 26.10.6 → 26.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/dist/viewer-visualize.js +659 -496
- package/dist/viewer-visualize.js.map +1 -1
- package/dist/viewer-visualize.min.js +1 -1
- package/dist/viewer-visualize.module.js +585 -484
- package/dist/viewer-visualize.module.js.map +1 -1
- package/lib/Viewer/Commands/GetSelected2.d.ts +2 -0
- package/lib/Viewer/Commands/SetSelected.d.ts +1 -1
- package/lib/Viewer/Commands/SetSelected2.d.ts +2 -0
- package/lib/Viewer/Components/index.d.ts +8 -7
- package/lib/Viewer/Draggers/MeasureLineDragger/MeasureLineItem.d.ts +5 -1
- package/lib/Viewer/Draggers/MeasureLineDragger/index.d.ts +3 -2
- package/lib/Viewer/Loaders/VSFXCloudLoader.d.ts +1 -1
- package/lib/Viewer/Loaders/VSFXCloudPartialLoader.d.ts +1 -1
- package/lib/Viewer/Loaders/index.d.ts +14 -9
- package/lib/Viewer/Models/IModelImpl.d.ts +5 -0
- package/lib/Viewer/Models/ModelImpl.d.ts +5 -0
- package/lib/Viewer/Viewer.d.ts +130 -136
- package/package.json +5 -5
- package/src/Viewer/Commands/ClearSelected.ts +3 -1
- package/src/Viewer/Commands/GetSelected2.ts +33 -0
- package/src/Viewer/Commands/HideSelected.ts +3 -1
- package/src/Viewer/Commands/SelectModel.ts +2 -3
- package/src/Viewer/Commands/SetSelected.ts +5 -2
- package/src/Viewer/Commands/SetSelected2.ts +39 -0
- package/src/Viewer/Commands/index.ts +4 -0
- package/src/Viewer/Components/index.ts +8 -7
- package/src/Viewer/Draggers/Common/OdBaseDragger.ts +3 -2
- package/src/Viewer/Draggers/MeasureLineDragger/MeasureLineItem.ts +44 -13
- package/src/Viewer/Draggers/MeasureLineDragger/index.ts +53 -18
- package/src/Viewer/Draggers/OdJoyStickDragger.ts +2 -2
- package/src/Viewer/Loaders/VSFCloudLoader.ts +6 -0
- package/src/Viewer/Loaders/VSFFileLoader.ts +7 -1
- package/src/Viewer/Loaders/VSFXCloudLoader.ts +7 -1
- package/src/Viewer/Loaders/VSFXCloudPartialLoader.ts +8 -2
- package/src/Viewer/Loaders/VSFXCloudStreamingLoader.ts +7 -1
- package/src/Viewer/Loaders/VSFXFileLoader.ts +7 -1
- package/src/Viewer/Loaders/index.ts +14 -9
- package/src/Viewer/Models/IModelImpl.ts +29 -0
- package/src/Viewer/Models/ModelImpl.ts +32 -0
- package/src/Viewer/Viewer.ts +784 -775
|
@@ -23,14 +23,16 @@
|
|
|
23
23
|
|
|
24
24
|
import { Viewer } from "../Viewer";
|
|
25
25
|
|
|
26
|
-
export function setSelected(viewer: Viewer,
|
|
26
|
+
export function setSelected(viewer: Viewer, handles2: string[] = []): void {
|
|
27
27
|
if (!viewer.visualizeJs) return;
|
|
28
28
|
|
|
29
|
+
const handles = handles2.map((handle) => handle.slice(handle.indexOf(":") + 1));
|
|
30
|
+
|
|
29
31
|
const visLib = viewer.visLib();
|
|
30
32
|
const visViewer = viewer.visViewer();
|
|
31
33
|
|
|
32
34
|
const selectionSet = new visLib.OdTvSelectionSet();
|
|
33
|
-
handles
|
|
35
|
+
handles.forEach((handle) => {
|
|
34
36
|
const entityId = visViewer.getEntityByOriginalHandle(handle + "");
|
|
35
37
|
if (!entityId.isNull()) selectionSet.appendEntity(entityId);
|
|
36
38
|
});
|
|
@@ -39,6 +41,7 @@ export function setSelected(viewer: Viewer, handles: string[] = []): void {
|
|
|
39
41
|
|
|
40
42
|
viewer.update();
|
|
41
43
|
viewer.emitEvent({ type: "select", data: selectionSet, handles });
|
|
44
|
+
viewer.emitEvent({ type: "select2", data: selectionSet, handles: handles2 });
|
|
42
45
|
|
|
43
46
|
selectionSet.delete();
|
|
44
47
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
|
|
3
|
+
// All rights reserved.
|
|
4
|
+
//
|
|
5
|
+
// This software and its documentation and related materials are owned by
|
|
6
|
+
// the Alliance. The software may only be incorporated into application
|
|
7
|
+
// programs owned by members of the Alliance, subject to a signed
|
|
8
|
+
// Membership Agreement and Supplemental Software License Agreement with the
|
|
9
|
+
// Alliance. The structure and organization of this software are the valuable
|
|
10
|
+
// trade secrets of the Alliance and its suppliers. The software is also
|
|
11
|
+
// protected by copyright law and international treaty provisions. Application
|
|
12
|
+
// programs incorporating this software must include the following statement
|
|
13
|
+
// with their copyright notices:
|
|
14
|
+
//
|
|
15
|
+
// This application incorporates Open Design Alliance software pursuant to a
|
|
16
|
+
// license agreement with Open Design Alliance.
|
|
17
|
+
// Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
|
|
18
|
+
// All rights reserved.
|
|
19
|
+
//
|
|
20
|
+
// By use of this software, its documentation or related materials, you
|
|
21
|
+
// acknowledge and accept the above terms.
|
|
22
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
23
|
+
|
|
24
|
+
import { Viewer } from "../Viewer";
|
|
25
|
+
|
|
26
|
+
export function setSelected2(viewer: Viewer, handles2: string[] = []): void {
|
|
27
|
+
const handles = [];
|
|
28
|
+
|
|
29
|
+
handles2.forEach((handle) => {
|
|
30
|
+
if (!handle.includes(":")) {
|
|
31
|
+
handles.push(handle);
|
|
32
|
+
} else
|
|
33
|
+
viewer.models.forEach((model) => {
|
|
34
|
+
if (handle.split(":", 1)[0] === model.id + "") handles.push(handle);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return viewer.executeCommand("setSelected", handles);
|
|
39
|
+
}
|
|
@@ -32,6 +32,7 @@ import { explode, collect } from "./Explode";
|
|
|
32
32
|
import { getDefaultViewPositions } from "./GetDefaultViewPositions";
|
|
33
33
|
import { getModels } from "./GetModels";
|
|
34
34
|
import { getSelected } from "./GetSelected";
|
|
35
|
+
import { getSelected2 } from "./GetSelected2";
|
|
35
36
|
import { hideSelected } from "./HideSelected";
|
|
36
37
|
import { isolateSelected } from "./IsolateSelected";
|
|
37
38
|
import { regenerateAll } from "./RegenerateAll";
|
|
@@ -41,6 +42,7 @@ import { setActiveDragger } from "./SetActiveDragger";
|
|
|
41
42
|
import { setDefaultViewPosition } from "./SetDefaultViewPosition";
|
|
42
43
|
import { setMarkupColor } from "./SetMarkupColor";
|
|
43
44
|
import { setSelected } from "./SetSelected";
|
|
45
|
+
import { setSelected2 } from "./SetSelected2";
|
|
44
46
|
import { showAll } from "./ShowAll";
|
|
45
47
|
import { zoomToExtents } from "./ZoomToExtents";
|
|
46
48
|
import { zoomToObjects } from "./ZoomToObjects";
|
|
@@ -87,6 +89,7 @@ commands.registerCommand("collect", collect);
|
|
|
87
89
|
commands.registerCommand("getDefaultViewPositions", getDefaultViewPositions);
|
|
88
90
|
commands.registerCommand("getModels", getModels);
|
|
89
91
|
commands.registerCommand("getSelected", getSelected);
|
|
92
|
+
commands.registerCommand("getSelected2", getSelected2);
|
|
90
93
|
commands.registerCommand("hideSelected", hideSelected);
|
|
91
94
|
commands.registerCommand("isolateSelected", isolateSelected);
|
|
92
95
|
commands.registerCommand("regenerateAll", regenerateAll);
|
|
@@ -96,6 +99,7 @@ commands.registerCommand("setActiveDragger", setActiveDragger);
|
|
|
96
99
|
commands.registerCommand("setDefaultViewPosition", setDefaultViewPosition);
|
|
97
100
|
commands.registerCommand("setMarkupColor", setMarkupColor);
|
|
98
101
|
commands.registerCommand("setSelected", setSelected);
|
|
102
|
+
commands.registerCommand("setSelected2", setSelected2);
|
|
99
103
|
commands.registerCommand("showAll", showAll);
|
|
100
104
|
commands.registerCommand("zoomToExtents", zoomToExtents);
|
|
101
105
|
commands.registerCommand("zoomToObjects", zoomToObjects);
|
|
@@ -37,8 +37,8 @@ import { ResetComponent } from "./ResetComponent";
|
|
|
37
37
|
*
|
|
38
38
|
* 1. Define a component class implements {@link IComponent}.
|
|
39
39
|
* 2. Define a constructor with a `viewer` parameter and add mouse event listeners for the specified viewer.
|
|
40
|
-
* 3. Define the component logic in the event listeners. For example, listen for the `
|
|
41
|
-
*
|
|
40
|
+
* 3. Define the component logic in the event listeners. For example, listen for the `geometryend` event and
|
|
41
|
+
* implement post-processing logic for the model.
|
|
42
42
|
* 4. Override {@link IComponent.dispose} and remove mouse event listeners from the viewer.
|
|
43
43
|
* 5. Register component provider in the components registry by calling the
|
|
44
44
|
* {@link components.registerComponent}.
|
|
@@ -51,18 +51,19 @@ import { ResetComponent } from "./ResetComponent";
|
|
|
51
51
|
* class MyComponent implements IComponent {
|
|
52
52
|
* protected viewer: Viewer;
|
|
53
53
|
*
|
|
54
|
-
*
|
|
54
|
+
* constructor(viewer: Viewer) {
|
|
55
55
|
* this.viewer = viewer;
|
|
56
|
-
* this.viewer.addEventListener("
|
|
56
|
+
* this.viewer.addEventListener("geometryend", this.onGeometryEnd);
|
|
57
57
|
* }
|
|
58
58
|
*
|
|
59
59
|
* override dispose() {
|
|
60
|
-
* this.viewer.removeEventListener("
|
|
60
|
+
* this.viewer.removeEventListener("geometryend", this.onGeometryEnd);
|
|
61
61
|
* }
|
|
62
62
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
63
|
+
* onGeometryEnd = (event: MouseEvent) => {
|
|
64
|
+
* this.viewer.executeCommand("zoomToExtents");
|
|
65
65
|
* };
|
|
66
|
+
*
|
|
66
67
|
* }
|
|
67
68
|
*
|
|
68
69
|
* components.registerComponent( "MyComponent", (viewer): IComponent => new MyComponent(viewer));
|
|
@@ -135,8 +135,9 @@ export class OdBaseDragger extends OdaGeAction {
|
|
|
135
135
|
this.subject.update();
|
|
136
136
|
|
|
137
137
|
const selectionSet = viewer.getSelected();
|
|
138
|
-
|
|
139
|
-
this.onmessage({ type: "select", data: selectionSet, handles });
|
|
138
|
+
|
|
139
|
+
this.onmessage({ type: "select", data: selectionSet, handles: this.subject.getSelected() });
|
|
140
|
+
this.onmessage({ type: "select2", data: selectionSet, handles: this.subject.getSelected2() });
|
|
140
141
|
}
|
|
141
142
|
}
|
|
142
143
|
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
// By use of this software, its documentation or related materials, you
|
|
21
21
|
// acknowledge and accept the above terms.
|
|
22
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
23
|
+
|
|
23
24
|
import * as utils from "./MeasureUtils";
|
|
24
25
|
|
|
25
26
|
export class MeasureLineItem {
|
|
@@ -29,8 +30,9 @@ export class MeasureLineItem {
|
|
|
29
30
|
protected htmlElemTitle: HTMLElement;
|
|
30
31
|
protected startPoint: number[];
|
|
31
32
|
protected endPoint: number[];
|
|
32
|
-
protected unit: string;
|
|
33
33
|
protected scale: number;
|
|
34
|
+
protected unit: string;
|
|
35
|
+
protected precision: any;
|
|
34
36
|
protected size: number;
|
|
35
37
|
protected style: CSSStyleDeclaration;
|
|
36
38
|
protected viewer: any;
|
|
@@ -49,8 +51,9 @@ export class MeasureLineItem {
|
|
|
49
51
|
this.startPoint = null;
|
|
50
52
|
this.endPoint = null;
|
|
51
53
|
|
|
52
|
-
this.unit = "";
|
|
53
54
|
this.scale = 1.0;
|
|
55
|
+
this.unit = "";
|
|
56
|
+
this.precision = 2;
|
|
54
57
|
this.size = 10.0;
|
|
55
58
|
this.lineThickness = 2;
|
|
56
59
|
|
|
@@ -153,13 +156,11 @@ export class MeasureLineItem {
|
|
|
153
156
|
this.htmlElemLine.style.zIndex = "1";
|
|
154
157
|
this.htmlElemLine.style.height = `${height}px`;
|
|
155
158
|
|
|
156
|
-
const distance =
|
|
159
|
+
const distance = this.getDistance();
|
|
157
160
|
|
|
158
161
|
const pX = p1.x + dx / 2;
|
|
159
162
|
const pY = p1.y + dy / 2;
|
|
160
163
|
|
|
161
|
-
const widthTitle = distance.length * 10;
|
|
162
|
-
|
|
163
164
|
this.htmlElemTitle = utils.createHtmlElementIfNeed(this.htmlElemTitle, this.targetElement, "ruler-value");
|
|
164
165
|
this.htmlElemTitle.style.display = "block";
|
|
165
166
|
this.htmlElemTitle.style.cursor = "pointer";
|
|
@@ -167,9 +168,8 @@ export class MeasureLineItem {
|
|
|
167
168
|
this.htmlElemTitle.style.color = "white";
|
|
168
169
|
this.htmlElemTitle.style.position = "Absolute";
|
|
169
170
|
this.htmlElemTitle.style.top = `${pY}px`;
|
|
170
|
-
this.htmlElemTitle.style.left = `${pX
|
|
171
|
-
this.htmlElemTitle.style.
|
|
172
|
-
this.htmlElemTitle.style.transformOrigin = "0px 0px";
|
|
171
|
+
this.htmlElemTitle.style.left = `${pX}px`;
|
|
172
|
+
this.htmlElemTitle.style.transform = "translate(-50%, -50%)";
|
|
173
173
|
this.htmlElemTitle.style.borderRadius = "5px";
|
|
174
174
|
this.htmlElemTitle.style.boxShadow = this.style.boxShadow;
|
|
175
175
|
this.htmlElemTitle.style.border = "none";
|
|
@@ -177,7 +177,7 @@ export class MeasureLineItem {
|
|
|
177
177
|
this.htmlElemTitle.style.zIndex = "3";
|
|
178
178
|
this.htmlElemTitle.style.padding = "2px";
|
|
179
179
|
this.htmlElemTitle.style.textAlign = "center";
|
|
180
|
-
this.htmlElemTitle.innerHTML =
|
|
180
|
+
this.htmlElemTitle.innerHTML = this.formatDistance(distance);
|
|
181
181
|
} else {
|
|
182
182
|
this.htmlElemLine.style.display = "none";
|
|
183
183
|
this.htmlElemTitle.style.display = "none";
|
|
@@ -187,13 +187,39 @@ export class MeasureLineItem {
|
|
|
187
187
|
|
|
188
188
|
getDistance(): number {
|
|
189
189
|
let distance = utils.getDistance(this.startPoint, this.endPoint, this.moduleInstance);
|
|
190
|
-
if (Math.abs(this.scale
|
|
191
|
-
distance = (distance / this.scale).toFixed(2);
|
|
192
|
-
}
|
|
193
|
-
|
|
190
|
+
if (Math.abs(this.scale) > 1e-10) distance /= this.scale;
|
|
194
191
|
return distance;
|
|
195
192
|
}
|
|
196
193
|
|
|
194
|
+
calculatePrecision(value: number) {
|
|
195
|
+
const distance = Math.abs(value);
|
|
196
|
+
|
|
197
|
+
if (distance >= 1000) return 0;
|
|
198
|
+
if (distance >= 10) return 1;
|
|
199
|
+
if (distance >= 0.1) return 2;
|
|
200
|
+
if (distance >= 0.001) return 3;
|
|
201
|
+
|
|
202
|
+
return distance > 0 ? Math.floor(-Math.log10(distance)) + 1 : 2;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
formatDistance(distance: number): string {
|
|
206
|
+
let digits: number;
|
|
207
|
+
|
|
208
|
+
if (this.precision === "Auto") digits = this.calculatePrecision(distance);
|
|
209
|
+
else if (Number.isFinite(this.precision)) digits = this.precision;
|
|
210
|
+
else digits = parseFloat(this.precision);
|
|
211
|
+
|
|
212
|
+
if (!Number.isFinite(digits)) digits = 2;
|
|
213
|
+
else if (digits < 0) digits = 0;
|
|
214
|
+
else if (digits > 10) digits = 10;
|
|
215
|
+
|
|
216
|
+
let result = distance.toFixed(digits);
|
|
217
|
+
if (this.precision === "Auto") result = result.replace(/\.0+$/, "").replace(/\.$/, "");
|
|
218
|
+
if (+result !== distance) result = "~ " + result;
|
|
219
|
+
|
|
220
|
+
return `${result} ${this.unit}`;
|
|
221
|
+
}
|
|
222
|
+
|
|
197
223
|
setStartPoint(gePoint: number[]): void {
|
|
198
224
|
this.startPoint = gePoint;
|
|
199
225
|
this.drawMeasureLine();
|
|
@@ -233,6 +259,11 @@ export class MeasureLineItem {
|
|
|
233
259
|
this.drawMeasureLine();
|
|
234
260
|
}
|
|
235
261
|
|
|
262
|
+
setPrecision(precision: any): void {
|
|
263
|
+
this.precision = precision;
|
|
264
|
+
this.drawMeasureLine();
|
|
265
|
+
}
|
|
266
|
+
|
|
236
267
|
setStyle(style: CSSStyleDeclaration): void {
|
|
237
268
|
this.style = style;
|
|
238
269
|
this.drawMeasureLine();
|
|
@@ -34,22 +34,24 @@ export class MeasureLineDragger extends OdBaseDragger {
|
|
|
34
34
|
protected gripingRadius: number;
|
|
35
35
|
protected firstPoint: number[];
|
|
36
36
|
protected secondPoint: number[];
|
|
37
|
-
protected renameUnitTable: any;
|
|
38
37
|
protected items: MeasureLineItem[];
|
|
39
38
|
protected m_overlayElement: HTMLElement;
|
|
40
39
|
protected previewMeasureLine: MeasureLineItem;
|
|
41
40
|
protected conversionFactor: number;
|
|
42
|
-
protected
|
|
41
|
+
protected rulerUnitTable: any;
|
|
42
|
+
protected rulerUnit: string;
|
|
43
|
+
protected rulerPrecision: any;
|
|
43
44
|
|
|
44
45
|
constructor(subject: Viewer) {
|
|
45
46
|
super(subject);
|
|
47
|
+
|
|
46
48
|
this.lineThickness = 2;
|
|
47
49
|
this.press = false;
|
|
48
50
|
this.gripingRadius = 5.0;
|
|
49
51
|
this.firstPoint = null;
|
|
50
52
|
this.secondPoint = null;
|
|
51
53
|
|
|
52
|
-
this.
|
|
54
|
+
this.rulerUnitTable = {
|
|
53
55
|
Millimeters: "mm",
|
|
54
56
|
Centimeters: "cm",
|
|
55
57
|
Meters: "m",
|
|
@@ -59,14 +61,16 @@ export class MeasureLineDragger extends OdBaseDragger {
|
|
|
59
61
|
Kilometers: "km",
|
|
60
62
|
Miles: "mi",
|
|
61
63
|
Micrometers: "µm",
|
|
64
|
+
Mils: "mil",
|
|
62
65
|
MicroInches: "µin",
|
|
63
66
|
Default: "unit",
|
|
64
67
|
};
|
|
65
68
|
|
|
69
|
+
this.rulerUnit = subject.options.rulerUnit ?? "Default";
|
|
70
|
+
this.rulerPrecision = subject.options.rulerPrecision ?? "Default";
|
|
71
|
+
|
|
66
72
|
this.items = [];
|
|
67
|
-
this.canvasEvents.push("resize");
|
|
68
|
-
this.oldRulerUnit = subject.options.rulerUnit ?? "Default";
|
|
69
|
-
this.optionsChange = this.optionsChange.bind(this);
|
|
73
|
+
this.canvasEvents.push("resize", "optionsChange");
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
override initialize(): void {
|
|
@@ -174,9 +178,14 @@ export class MeasureLineDragger extends OdBaseDragger {
|
|
|
174
178
|
createMeasureLine(): MeasureLineItem {
|
|
175
179
|
const viewer = this.m_module.getViewer();
|
|
176
180
|
const item = new MeasureLineItem(this.m_overlayElement, viewer, this.m_module);
|
|
181
|
+
|
|
177
182
|
item.lineThickness = this.lineThickness || item.lineThickness;
|
|
178
|
-
|
|
179
|
-
|
|
183
|
+
|
|
184
|
+
const isDefaultUnit = this.rulerUnit === "Default";
|
|
185
|
+
const isDefaultPrecision = this.rulerPrecision === "Default";
|
|
186
|
+
|
|
187
|
+
item.setUnit(renameUnit(this.rulerUnitTable, isDefaultUnit ? viewer.getUnit() : this.rulerUnit));
|
|
188
|
+
|
|
180
189
|
if (!isDefaultUnit) {
|
|
181
190
|
const fromUnit = this.getKUnitByName(viewer.getUnit());
|
|
182
191
|
const toUnit = this.getKUnitByName(this.subject.options.rulerUnit);
|
|
@@ -186,6 +195,13 @@ export class MeasureLineDragger extends OdBaseDragger {
|
|
|
186
195
|
} else {
|
|
187
196
|
item.setConversionFactor(1.0);
|
|
188
197
|
}
|
|
198
|
+
|
|
199
|
+
if (!isDefaultPrecision) {
|
|
200
|
+
item.setPrecision(this.rulerPrecision);
|
|
201
|
+
} else {
|
|
202
|
+
item.setPrecision(2);
|
|
203
|
+
}
|
|
204
|
+
|
|
189
205
|
this.items.push(item);
|
|
190
206
|
return item;
|
|
191
207
|
}
|
|
@@ -193,22 +209,38 @@ export class MeasureLineDragger extends OdBaseDragger {
|
|
|
193
209
|
optionsChange(event): void {
|
|
194
210
|
const options: IOptions = event.data;
|
|
195
211
|
const toUnitName = options.rulerUnit ?? "Default";
|
|
196
|
-
|
|
197
|
-
|
|
212
|
+
const toPrecision = options.rulerPrecision ?? "Default";
|
|
213
|
+
|
|
214
|
+
const unitChanged = this.rulerUnit !== toUnitName;
|
|
215
|
+
const precisionChanged = this.rulerPrecision !== toPrecision;
|
|
216
|
+
|
|
217
|
+
if (!unitChanged && !precisionChanged) return;
|
|
218
|
+
|
|
219
|
+
this.rulerUnit = toUnitName;
|
|
220
|
+
this.rulerPrecision = toPrecision;
|
|
198
221
|
|
|
199
222
|
const drawingUnit = this.m_module.getViewer().getUnit();
|
|
200
223
|
const eToUnit = this.getKUnitByName(toUnitName);
|
|
201
224
|
const eFromUnit = this.getKUnitByName(drawingUnit);
|
|
202
225
|
|
|
203
226
|
this.items.forEach((item) => {
|
|
204
|
-
if (
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
227
|
+
if (unitChanged) {
|
|
228
|
+
if (toUnitName === "Default") {
|
|
229
|
+
item.setUnit(renameUnit(this.rulerUnitTable, drawingUnit));
|
|
230
|
+
item.setConversionFactor(1.0);
|
|
231
|
+
} else {
|
|
232
|
+
item.setUnit(renameUnit(this.rulerUnitTable, toUnitName));
|
|
233
|
+
const multiplier = this.m_module.getViewer().getUnitsConversionCoef(eFromUnit, eToUnit);
|
|
234
|
+
this.conversionFactor = 1 / multiplier;
|
|
235
|
+
item.setConversionFactor(this.conversionFactor);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (precisionChanged) {
|
|
239
|
+
if (toPrecision === "Default") {
|
|
240
|
+
item.setPrecision(2);
|
|
241
|
+
} else {
|
|
242
|
+
item.setPrecision(toPrecision);
|
|
243
|
+
}
|
|
212
244
|
}
|
|
213
245
|
});
|
|
214
246
|
}
|
|
@@ -243,6 +275,9 @@ export class MeasureLineDragger extends OdBaseDragger {
|
|
|
243
275
|
case "Micrometers":
|
|
244
276
|
eUnit = this.m_module.Units.kMicrometers;
|
|
245
277
|
break;
|
|
278
|
+
case "Mils":
|
|
279
|
+
eUnit = this.m_module.Units.kMils;
|
|
280
|
+
break;
|
|
246
281
|
case "MicroInches":
|
|
247
282
|
eUnit = this.m_module.Units.kMicroInches;
|
|
248
283
|
break;
|
|
@@ -100,7 +100,7 @@ export class OdJoyStickDragger {
|
|
|
100
100
|
callback({
|
|
101
101
|
x: 100 * ((movedX - centerX) / maxMoveStick),
|
|
102
102
|
y: 100 * ((movedY - centerY) / maxMoveStick) * -1,
|
|
103
|
-
global
|
|
103
|
+
global,
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
106
|
};
|
|
@@ -116,7 +116,7 @@ export class OdJoyStickDragger {
|
|
|
116
116
|
callback({
|
|
117
117
|
x: 100 * ((movedX - centerX) / maxMoveStick),
|
|
118
118
|
y: 100 * ((movedY - centerY) / maxMoveStick) * -1,
|
|
119
|
-
global
|
|
119
|
+
global,
|
|
120
120
|
});
|
|
121
121
|
};
|
|
122
122
|
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
import { Loader } from "@inweb/viewer-core";
|
|
25
25
|
import { Viewer } from "../Viewer";
|
|
26
|
+
import { ModelImpl } from "../Models/ModelImpl";
|
|
26
27
|
|
|
27
28
|
export class VSFCloudLoader extends Loader {
|
|
28
29
|
public viewer: Viewer;
|
|
@@ -70,6 +71,11 @@ export class VSFCloudLoader extends Loader {
|
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
if (i === 0) {
|
|
74
|
+
const modelImpl = new ModelImpl();
|
|
75
|
+
modelImpl.id = model.file.id;
|
|
76
|
+
|
|
77
|
+
this.viewer.models.push(modelImpl);
|
|
78
|
+
|
|
73
79
|
this.viewer.syncOptions();
|
|
74
80
|
this.viewer.syncOverlay();
|
|
75
81
|
this.viewer.update(true);
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
import { Loader, LoadParams } from "@inweb/viewer-core";
|
|
25
25
|
import { Viewer } from "../Viewer";
|
|
26
|
+
import { ModelImpl } from "../Models/ModelImpl";
|
|
26
27
|
import { FileLoader } from "./FileLoader";
|
|
27
28
|
|
|
28
29
|
export class VSFFileLoader extends Loader {
|
|
@@ -40,7 +41,7 @@ export class VSFFileLoader extends Loader {
|
|
|
40
41
|
);
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
override async load(file: any, format?: string, params
|
|
44
|
+
override async load(file: any, format?: string, params: LoadParams = {}): Promise<this> {
|
|
44
45
|
if (!this.viewer.visualizeJs) return this;
|
|
45
46
|
|
|
46
47
|
const visViewer = this.viewer.visViewer();
|
|
@@ -68,6 +69,11 @@ export class VSFFileLoader extends Loader {
|
|
|
68
69
|
throw error;
|
|
69
70
|
}
|
|
70
71
|
|
|
72
|
+
const modelImpl = new ModelImpl();
|
|
73
|
+
modelImpl.id = params.modelId || this.extractFileName(file);
|
|
74
|
+
|
|
75
|
+
this.viewer.models.push(modelImpl);
|
|
76
|
+
|
|
71
77
|
this.viewer.syncOptions();
|
|
72
78
|
this.viewer.syncOverlay();
|
|
73
79
|
this.viewer.update(true);
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
import { Loader } from "@inweb/viewer-core";
|
|
25
25
|
import { Viewer } from "../Viewer";
|
|
26
|
+
import { ModelImpl } from "../Models/ModelImpl";
|
|
26
27
|
|
|
27
28
|
export class VSFXCloudLoader extends Loader {
|
|
28
29
|
public viewer: Viewer;
|
|
@@ -42,7 +43,7 @@ export class VSFXCloudLoader extends Loader {
|
|
|
42
43
|
);
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
override async load(model: any
|
|
46
|
+
override async load(model: any): Promise<this> {
|
|
46
47
|
if (!this.viewer.visualizeJs) return Promise.resolve(this);
|
|
47
48
|
|
|
48
49
|
const visViewer = this.viewer.visViewer();
|
|
@@ -65,6 +66,11 @@ export class VSFXCloudLoader extends Loader {
|
|
|
65
66
|
throw error;
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
const modelImpl = new ModelImpl();
|
|
70
|
+
modelImpl.id = model.file.id;
|
|
71
|
+
|
|
72
|
+
this.viewer.models.push(modelImpl);
|
|
73
|
+
|
|
68
74
|
this.viewer.syncOptions();
|
|
69
75
|
this.viewer.syncOverlay();
|
|
70
76
|
this.viewer.update(true);
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
import { Loader } from "@inweb/viewer-core";
|
|
25
25
|
import { Viewer } from "../Viewer";
|
|
26
|
+
import { ModelImpl } from "../Models/ModelImpl";
|
|
26
27
|
import { UpdateController, UpdateType } from "./UpdateController";
|
|
27
28
|
|
|
28
29
|
const PENDING_REQUESTS_SIZE = 50;
|
|
@@ -49,7 +50,7 @@ export class VSFXCloudPartialLoader extends Loader {
|
|
|
49
50
|
);
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
override async load(model: any
|
|
53
|
+
override async load(model: any): Promise<this> {
|
|
53
54
|
if (!this.viewer.visualizeJs) return this;
|
|
54
55
|
|
|
55
56
|
const visViewer = this.viewer.visViewer();
|
|
@@ -81,10 +82,15 @@ export class VSFXCloudPartialLoader extends Loader {
|
|
|
81
82
|
this.viewer.emitEvent({ type: "geometryprogress", data: progress, file: model.file, model });
|
|
82
83
|
|
|
83
84
|
if (isDatabaseChunk) {
|
|
85
|
+
const modelImpl = new ModelImpl();
|
|
86
|
+
modelImpl.id = model.file.id;
|
|
87
|
+
|
|
88
|
+
this.viewer.models.push(modelImpl);
|
|
89
|
+
|
|
84
90
|
this.viewer.syncOptions();
|
|
85
91
|
this.viewer.syncOverlay();
|
|
86
|
-
|
|
87
92
|
updateController.update(UpdateType.kForce);
|
|
93
|
+
|
|
88
94
|
this.viewer.emitEvent({ type: "databasechunk", data: chunk, file: model.file, model });
|
|
89
95
|
} else {
|
|
90
96
|
updateController.update(UpdateType.kDelay);
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
import { Loader } from "@inweb/viewer-core";
|
|
25
25
|
import { Viewer } from "../Viewer";
|
|
26
|
+
import { ModelImpl } from "../Models/ModelImpl";
|
|
26
27
|
import { UpdateController, UpdateType } from "./UpdateController";
|
|
27
28
|
|
|
28
29
|
export class VSFXCloudStreamingLoader extends Loader {
|
|
@@ -79,10 +80,15 @@ export class VSFXCloudStreamingLoader extends Loader {
|
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
if (isDatabaseChunk) {
|
|
83
|
+
const modelImpl = new ModelImpl();
|
|
84
|
+
modelImpl.id = model.file.id;
|
|
85
|
+
|
|
86
|
+
this.viewer.models.push(modelImpl);
|
|
87
|
+
|
|
82
88
|
this.viewer.syncOptions();
|
|
83
89
|
this.viewer.syncOverlay();
|
|
84
|
-
|
|
85
90
|
updateController.update(UpdateType.kForce);
|
|
91
|
+
|
|
86
92
|
this.viewer.emitEvent({ type: "databasechunk", data: chunk, file: model.file, model });
|
|
87
93
|
} else {
|
|
88
94
|
updateController.update(UpdateType.kDelay);
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
import { Loader, LoadParams } from "@inweb/viewer-core";
|
|
25
25
|
import { Viewer } from "../Viewer";
|
|
26
|
+
import { ModelImpl } from "../Models/ModelImpl";
|
|
26
27
|
import { FileLoader } from "./FileLoader";
|
|
27
28
|
|
|
28
29
|
export class VSFXFileLoader extends Loader {
|
|
@@ -40,7 +41,7 @@ export class VSFXFileLoader extends Loader {
|
|
|
40
41
|
);
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
override async load(file: any, format?: string, params
|
|
44
|
+
override async load(file: any, format?: string, params: LoadParams = {}): Promise<this> {
|
|
44
45
|
if (!this.viewer.visualizeJs) return this;
|
|
45
46
|
|
|
46
47
|
const visViewer = this.viewer.visViewer();
|
|
@@ -68,6 +69,11 @@ export class VSFXFileLoader extends Loader {
|
|
|
68
69
|
throw error;
|
|
69
70
|
}
|
|
70
71
|
|
|
72
|
+
const modelImpl = new ModelImpl();
|
|
73
|
+
modelImpl.id = params.modelId || this.extractFileName(file);
|
|
74
|
+
|
|
75
|
+
this.viewer.models.push(modelImpl);
|
|
76
|
+
|
|
71
77
|
this.viewer.syncOptions();
|
|
72
78
|
this.viewer.syncOverlay();
|
|
73
79
|
this.viewer.update(true);
|
|
@@ -38,23 +38,24 @@ import { VSFXCloudPartialLoader } from "./VSFXCloudPartialLoader";
|
|
|
38
38
|
*
|
|
39
39
|
* 1. Define a loader class implements {@link ILoader}.
|
|
40
40
|
* 2. Define a constructor with a `viewer` parameter.
|
|
41
|
-
* 3. Override {@link ILoader.isSupport} and
|
|
41
|
+
* 3. Override {@link ILoader.isSupport} and check if the loader can load the specified file.
|
|
42
42
|
* 4. Override {@link ILoader.load} and define the logic for loading the model from the file.
|
|
43
43
|
*
|
|
44
44
|
* The loader should do:
|
|
45
45
|
*
|
|
46
46
|
* - Load model data from file into the buffer. The model data must be a `VSFX` format.
|
|
47
47
|
* - Parse data buffer with the `VisualizeJS` viewer instance.
|
|
48
|
+
* - Create `ModelImpl` instance with unique model ID add it to the viewer `models` list.
|
|
48
49
|
* - Synchronize viewer styles, options and overlay.
|
|
49
50
|
* - Update the viewer.
|
|
50
51
|
*
|
|
51
52
|
* The loader must emit events:
|
|
52
53
|
*
|
|
53
|
-
* - `geometryprogress` - during loading
|
|
54
|
-
* after the load is complete.
|
|
54
|
+
* - `geometryprogress` - during loading (or once at 100% when complete).
|
|
55
55
|
* - `databasechunk` - when model is loaded and ready to render.
|
|
56
56
|
* 5. Override {@link ILoader.dispose} and release loader resources, if required.
|
|
57
|
-
* 6.
|
|
57
|
+
* 6. Use `this.abortController` (defined in `Loader` class) to abort loading raw data.
|
|
58
|
+
* 7. Register loader provider in the loaders registry by calling the {@link loaders.registerLoader}.
|
|
58
59
|
*
|
|
59
60
|
* @example Implementing a custom loader.
|
|
60
61
|
*
|
|
@@ -70,21 +71,25 @@ import { VSFXCloudPartialLoader } from "./VSFXCloudPartialLoader";
|
|
|
70
71
|
* }
|
|
71
72
|
*
|
|
72
73
|
* override isSupport(file, format): Boolean {
|
|
73
|
-
* //
|
|
74
|
-
* return
|
|
74
|
+
* // check if this loader supports the file source and format
|
|
75
|
+
* return type file === "string" && format === "myformat";
|
|
75
76
|
* }
|
|
76
77
|
*
|
|
77
78
|
* override load(file, format, params): Promise<this> {
|
|
79
|
+
* // load VSFX data from file (custom loading logic)
|
|
80
|
+
* const data = await fetch(file).then((result) => result.arrayBuffer());
|
|
78
81
|
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
82
|
+
* const modelImpl = new ModelImpl();
|
|
83
|
+
* modelImpl.id = params.modelId;
|
|
81
84
|
*
|
|
82
|
-
* this.viewer.
|
|
85
|
+
* this.viewer.visViewer().parseVsfx(new Uint8Array(data));
|
|
86
|
+
* this.viewer.models.push(modelImpl);
|
|
83
87
|
*
|
|
84
88
|
* this.viewer.syncOptions();
|
|
85
89
|
* this.viewer.syncOverlay();
|
|
86
90
|
* this.viewer.update();
|
|
87
91
|
*
|
|
92
|
+
* this.viewer.emitEvent({ type: "geometryprogress", data: 1, file });
|
|
88
93
|
* this.viewer.emitEvent({ type: "databasechunk", data, file });
|
|
89
94
|
*
|
|
90
95
|
* return Promise.resove(this);
|