@inweb/viewer-three 26.8.2 → 26.9.1

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.
@@ -7,9 +7,9 @@ export declare const defaultViewPositions: {
7
7
  right: Vector3;
8
8
  bottom: Vector3;
9
9
  top: Vector3;
10
- ns: Vector3;
10
+ se: Vector3;
11
11
  sw: Vector3;
12
+ ne: Vector3;
12
13
  nw: Vector3;
13
- se: Vector3;
14
14
  };
15
15
  export declare function setDefaultViewPosition(viewer: Viewer, position: string): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inweb/viewer-three",
3
- "version": "26.8.2",
3
+ "version": "26.9.1",
4
4
  "description": "JavaScript library for rendering CAD and BIM files in a browser using Three.js",
5
5
  "homepage": "https://cloud.opendesign.com/docs/index.html",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -35,10 +35,10 @@
35
35
  "docs": "typedoc"
36
36
  },
37
37
  "dependencies": {
38
- "@inweb/client": "~26.8.2",
39
- "@inweb/eventemitter2": "~26.8.2",
40
- "@inweb/markup": "~26.8.2",
41
- "@inweb/viewer-core": "~26.8.2"
38
+ "@inweb/client": "~26.9.1",
39
+ "@inweb/eventemitter2": "~26.9.1",
40
+ "@inweb/markup": "~26.9.1",
41
+ "@inweb/viewer-core": "~26.9.1"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/three": "^0.179.0",
@@ -170,7 +170,7 @@ export class Viewer
170
170
 
171
171
  this.scene = new Scene();
172
172
  this.helpers = new Helpers();
173
- this.target = new Vector3();
173
+ this.target = new Vector3(0, 0, 0);
174
174
 
175
175
  const pixelRatio = window.devicePixelRatio;
176
176
  const rect = canvas.parentElement.getBoundingClientRect();
@@ -178,7 +178,7 @@ export class Viewer
178
178
  const height = rect.height || 1;
179
179
  const aspect = width / height;
180
180
 
181
- this.camera = new PerspectiveCamera(45, aspect, 0.01, 1000);
181
+ this.camera = new PerspectiveCamera(45, aspect, 0.001, 1000);
182
182
  this.camera.up.set(0, 1, 0);
183
183
  this.camera.position.set(0, 0, 1);
184
184
  this.camera.lookAt(this.target);
@@ -486,12 +486,6 @@ export class Viewer
486
486
  this.scene.clear();
487
487
  this.helpers.clear();
488
488
 
489
- this.models.forEach((model) => model.dispose());
490
- this.models = [];
491
-
492
- this.helpers.clear();
493
- this.scene.clear();
494
-
495
489
  this.syncOptions();
496
490
  this.syncOverlay();
497
491
  this.update(true);
@@ -667,7 +661,7 @@ export class Viewer
667
661
  camera.left = camera.bottom * aspect;
668
662
  camera.right = camera.top * aspect;
669
663
  camera.near = 0;
670
- camera.far = extentsSize * 100;
664
+ camera.far = extentsSize * 1000;
671
665
  camera.zoom = orthogonal_camera.view_to_world_scale;
672
666
  camera.updateProjectionMatrix();
673
667
 
@@ -692,8 +686,8 @@ export class Viewer
692
686
  const camera = new PerspectiveCamera();
693
687
  camera.fov = perspective_camera.field_of_view;
694
688
  camera.aspect = aspect;
695
- camera.near = extentsSize / 100;
696
- camera.far = extentsSize * 100;
689
+ camera.near = extentsSize / 1000;
690
+ camera.far = extentsSize * 1000;
697
691
  camera.updateProjectionMatrix();
698
692
 
699
693
  camera.up.copy(getVector3FromPoint3d(perspective_camera.up_vector));
@@ -21,36 +21,40 @@
21
21
  // acknowledge and accept the above terms.
22
22
  ///////////////////////////////////////////////////////////////////////////////
23
23
 
24
- import { Sphere, Vector3 } from "three";
24
+ import { Quaternion, Sphere, Vector3 } from "three";
25
25
  import type { Viewer } from "../Viewer";
26
26
  import { zoomTo } from "./ZoomTo";
27
27
 
28
28
  export const defaultViewPositions = {
29
- front: new Vector3(0, 0, 1),
30
- back: new Vector3(0, 0, -1),
31
- left: new Vector3(-1, 0, 0),
32
- right: new Vector3(1, 0, 0),
29
+ front: new Vector3(0, 0, -1),
30
+ back: new Vector3(0, 0, 1),
31
+ left: new Vector3(1, 0, 0),
32
+ right: new Vector3(-1, 0, 0),
33
33
  bottom: new Vector3(0, -1, 0),
34
34
  top: new Vector3(0, 1, 0),
35
- ns: new Vector3(-0.5, 1.0, -0.5).normalize(),
36
- sw: new Vector3(0.5, 1.0, -0.5).normalize(),
37
- nw: new Vector3(0.5, 1.0, 0.5).normalize(),
38
- se: new Vector3(-0.5, 1.0, 0.5).normalize(),
35
+ se: new Vector3(-1, 1, -1).normalize(),
36
+ sw: new Vector3(1, 1, -1).normalize(),
37
+ ne: new Vector3(-1, 1, 1).normalize(),
38
+ nw: new Vector3(1, 1, 1).normalize(),
39
39
  };
40
40
 
41
41
  export function setDefaultViewPosition(viewer: Viewer, position: string): void {
42
- const direction = defaultViewPositions[position] || defaultViewPositions["sw"];
42
+ const extentsCenter = viewer.extents.getCenter(new Vector3());
43
+ const extentsSize = viewer.extents.getBoundingSphere(new Sphere()).radius * 2;
43
44
 
44
- const center = viewer.extents.getCenter(new Vector3());
45
- const sphere = viewer.extents.getBoundingSphere(new Sphere());
46
- const offset = direction.clone().multiplyScalar(sphere.radius);
45
+ const upY = new Vector3(0, 1, 0);
46
+ const offsetY = defaultViewPositions[position] || defaultViewPositions["sw"];
47
+
48
+ const up = new Vector3().copy(viewer.camera.up);
49
+ const quaternion = new Quaternion().setFromUnitVectors(upY, up);
50
+ const offset = new Vector3().copy(offsetY).applyQuaternion(quaternion);
47
51
 
48
52
  const camera = viewer.camera;
49
- camera.position.copy(center).add(offset);
50
- camera.lookAt(center);
53
+ camera.position.copy(offset).multiplyScalar(extentsSize).add(extentsCenter);
54
+ camera.lookAt(extentsCenter);
51
55
  camera.updateMatrixWorld();
52
56
 
53
- viewer.target.copy(center);
57
+ viewer.target.copy(extentsCenter);
54
58
 
55
59
  viewer.update();
56
60
  viewer.emit({ type: "viewposition", data: position });
@@ -27,8 +27,8 @@ import type { Viewer } from "../Viewer";
27
27
  export function zoomTo(viewer: Viewer, box: Box3): void {
28
28
  if (box.isEmpty()) return;
29
29
 
30
- const center = box.getCenter(new Vector3());
31
- const sphere = box.getBoundingSphere(new Sphere());
30
+ const boxCenter = box.getCenter(new Vector3());
31
+ const boxSize = box.getBoundingSphere(new Sphere()).radius;
32
32
 
33
33
  const rendererSize = viewer.renderer.getSize(new Vector2());
34
34
  const aspect = rendererSize.x / rendererSize.y;
@@ -36,30 +36,30 @@ export function zoomTo(viewer: Viewer, box: Box3): void {
36
36
  const camera = viewer.camera as any;
37
37
 
38
38
  if (camera.isPerspectiveCamera) {
39
- const offset = new Vector3(0, 0, 1);
40
- offset.applyQuaternion(camera.quaternion);
41
- offset.multiplyScalar(sphere.radius / Math.tan(MathUtils.DEG2RAD * camera.fov * 0.5));
39
+ const offset = new Vector3(0, 0, 1)
40
+ .applyQuaternion(camera.quaternion)
41
+ .multiplyScalar(boxSize / Math.tan(MathUtils.DEG2RAD * camera.fov * 0.5));
42
42
 
43
- camera.position.copy(center).add(offset);
43
+ camera.position.copy(offset).add(boxCenter);
44
44
  camera.updateMatrixWorld();
45
45
  }
46
46
  if (camera.isOrthographicCamera) {
47
- camera.top = sphere.radius;
48
- camera.bottom = -sphere.radius;
47
+ camera.top = boxSize;
48
+ camera.bottom = -boxSize;
49
49
  camera.left = camera.bottom * aspect;
50
50
  camera.right = camera.top * aspect;
51
51
  camera.zoom = 1;
52
52
  camera.updateProjectionMatrix();
53
53
 
54
- const offset = new Vector3(0, 0, 1);
55
- offset.applyQuaternion(camera.quaternion);
56
- offset.multiplyScalar(viewer.extents.getBoundingSphere(new Sphere()).radius * 3);
54
+ const offset = new Vector3(0, 0, 1)
55
+ .applyQuaternion(camera.quaternion)
56
+ .multiplyScalar(viewer.extents.getBoundingSphere(new Sphere()).radius * 3);
57
57
 
58
- camera.position.copy(center).add(offset);
58
+ camera.position.copy(offset).add(boxCenter);
59
59
  camera.updateMatrixWorld();
60
60
  }
61
61
 
62
- viewer.target.copy(center);
62
+ viewer.target.copy(boxCenter);
63
63
 
64
64
  viewer.update();
65
65
  viewer.emitEvent({ type: "zoom" });
@@ -21,7 +21,7 @@
21
21
  // acknowledge and accept the above terms.
22
22
  ///////////////////////////////////////////////////////////////////////////////
23
23
 
24
- import { AmbientLight, DirectionalLight, HemisphereLight, Sphere, Vector3 } from "three";
24
+ import { AmbientLight, DirectionalLight, HemisphereLight, Quaternion, Sphere, Vector3 } from "three";
25
25
 
26
26
  import { IComponent } from "@inweb/viewer-core";
27
27
  import type { Viewer } from "../Viewer";
@@ -73,13 +73,15 @@ export class LightComponent implements IComponent {
73
73
  const extentsCenter = this.viewer.extents.getCenter(new Vector3());
74
74
  const extentsSize = this.viewer.extents.getBoundingSphere(new Sphere()).radius;
75
75
 
76
- const front = new Vector3()
77
- .copy(this.viewer.camera.up)
78
- .cross(new Vector3(1, 0, 0))
79
- .negate();
76
+ const upY = new Vector3(0, 1, 0);
77
+ const frontY = new Vector3(0, 0, -1);
78
+
79
+ const up = new Vector3().copy(this.viewer.camera.up);
80
+ const quaternion = new Quaternion().setFromUnitVectors(upY, up);
81
+ const front = new Vector3().copy(frontY).applyQuaternion(quaternion).negate();
80
82
 
81
83
  this.directionalLight.position
82
- .copy(this.viewer.camera.up)
84
+ .copy(up)
83
85
  .applyAxisAngle(front, (-Math.PI * 30) / 180)
84
86
  .multiplyScalar(extentsSize * 2)
85
87
  .add(extentsCenter);
@@ -23,7 +23,7 @@ import {
23
23
  BufferAttribute,
24
24
  LineBasicMaterial,
25
25
  } from "three";
26
- import { GltfStructure, GL_CONSTANTS } from "./GltfStructure.js";
26
+ import { GL_CONSTANTS } from "./GltfStructure.js";
27
27
  import { mergeGeometries } from "three/examples/jsm/utils/BufferGeometryUtils.js";
28
28
 
29
29
  export class DynamicGltfLoader {
@@ -94,6 +94,10 @@ export class DynamicGltfLoader {
94
94
  this.hiddenHandles = new Set();
95
95
  this.newOptimizedObjects = new Set();
96
96
  this.oldOptimizeObjects = new Set();
97
+
98
+ this.maxConcurrentChunks = 8;
99
+ this.activeChunkLoads = 0;
100
+ this.chunkQueue = [];
97
101
  }
98
102
 
99
103
  setVisibleEdges(visible) {
@@ -503,6 +507,7 @@ export class DynamicGltfLoader {
503
507
  const structureArray = Array.isArray(structures) ? structures : [structures];
504
508
 
505
509
  for (const structure of structureArray) {
510
+ await structure.initialize(this);
506
511
  this.structures.push(structure);
507
512
  }
508
513
 
@@ -894,13 +899,6 @@ export class DynamicGltfLoader {
894
899
  this.nodesToLoad = [];
895
900
  }
896
901
 
897
- async addStructure(loadController) {
898
- const structure = new GltfStructure();
899
- await structure.initialize(loadController);
900
- this.structures.push(structure);
901
- return structure;
902
- }
903
-
904
902
  removeOptimization() {
905
903
  this.originalObjects.forEach((obj) => (obj.visible = true));
906
904
 
@@ -932,7 +930,8 @@ export class DynamicGltfLoader {
932
930
  }
933
931
 
934
932
  clear() {
935
- // Clear all structures
933
+ this.chunkQueue = [];
934
+
936
935
  this.structures.forEach((structure) => {
937
936
  if (structure) {
938
937
  structure.clear();
@@ -973,7 +972,6 @@ export class DynamicGltfLoader {
973
972
  });
974
973
  this.loadedMeshes.clear();
975
974
 
976
- // Clear all structure roots and their children
977
975
  this.structureRoots.forEach((rootGroup) => {
978
976
  if (rootGroup) {
979
977
  rootGroup.traverse((child) => {
@@ -993,7 +991,6 @@ export class DynamicGltfLoader {
993
991
  });
994
992
  this.structureRoots.clear();
995
993
 
996
- // Clear all optimized objects
997
994
  this.mergedMesh.forEach((mesh) => {
998
995
  if (mesh.geometry) mesh.geometry.dispose();
999
996
  if (mesh.material) {
@@ -1746,7 +1743,6 @@ export class DynamicGltfLoader {
1746
1743
  });
1747
1744
  }
1748
1745
 
1749
- // Возвращает bounding box для конкретной структуры
1750
1746
  getStructureGeometryExtent(structureId) {
1751
1747
  const extent = new Box3();
1752
1748
  for (const [nodeId, node] of this.nodes.entries()) {
@@ -1764,4 +1760,33 @@ export class DynamicGltfLoader {
1764
1760
  }
1765
1761
  return extent;
1766
1762
  }
1763
+
1764
+ setMaxConcurrentChunks(maxChunks) {
1765
+ if (maxChunks < 1) {
1766
+ console.warn("Max concurrent chunks must be at least 1");
1767
+ return;
1768
+ }
1769
+ this.maxConcurrentChunks = maxChunks;
1770
+ }
1771
+
1772
+ waitForChunkSlot() {
1773
+ if (this.activeChunkLoads < this.maxConcurrentChunks) {
1774
+ this.activeChunkLoads++;
1775
+ return Promise.resolve();
1776
+ }
1777
+
1778
+ return new Promise((resolve) => {
1779
+ this.chunkQueue.push(resolve);
1780
+ });
1781
+ }
1782
+
1783
+ releaseChunkSlot() {
1784
+ this.activeChunkLoads--;
1785
+
1786
+ if (this.chunkQueue.length > 0) {
1787
+ const nextResolve = this.chunkQueue.shift();
1788
+ this.activeChunkLoads++;
1789
+ nextResolve();
1790
+ }
1791
+ }
1767
1792
  }
@@ -43,11 +43,12 @@ const MAX_GAP = 128 * 1024; // 128 KB
43
43
  const MAX_CHUNK = 30 * 1024 * 1024; // 100 MB
44
44
 
45
45
  export class GltfStructure {
46
- constructor(id) {
46
+ constructor(id, loadController) {
47
47
  this.id = `${id}`;
48
48
  this.json = null;
49
49
  this.baseUrl = "";
50
- this.loadController = null;
50
+ this.loadController = loadController;
51
+ this.loader = null;
51
52
  this.batchDelay = 10;
52
53
  this.maxBatchSize = 5 * 1024 * 1024;
53
54
  this.maxRangesPerRequest = 512;
@@ -59,10 +60,10 @@ export class GltfStructure {
59
60
  this.materialCache = new Map();
60
61
  }
61
62
 
62
- async initialize(loadController) {
63
- this.json = await loadController.loadJson();
64
- this.baseUrl = await loadController.baseUrl();
65
- this.loadController = loadController;
63
+ async initialize(loader) {
64
+ this.json = await this.loadController.loadJson();
65
+ this.baseUrl = await this.loadController.baseUrl();
66
+ this.loader = loader;
66
67
  }
67
68
 
68
69
  clear() {
@@ -75,10 +76,12 @@ export class GltfStructure {
75
76
  this.batchTimeout = null;
76
77
  }
77
78
 
78
- // Clear materials and textures
79
79
  this.disposeMaterials();
80
80
  this.textureCache.clear();
81
81
  this.materials.clear();
82
+
83
+ this.activeChunkLoads = 0;
84
+ this.chunkQueue = [];
82
85
  }
83
86
 
84
87
  getJson() {
@@ -157,35 +160,32 @@ export class GltfStructure {
157
160
  finalRanges.push({ start, end, requests });
158
161
  }
159
162
  }
160
- /*
161
- for (const range of finalRanges) {
162
- const length = range.end - range.start;
163
- const buffer = await this.loadController.loadBinaryData([
164
- { offset: range.start, length: length }
165
- ]);
166
- for (const req of range.requests) {
167
- const relOffset = req.offset - range.start;
168
- try {
169
- req._resolve({ buffer, relOffset, length: req.length });
170
- } catch (e) {
171
- req._reject(e);
163
+
164
+ const promises = finalRanges.map(async (range, index) => {
165
+ await this.loader.waitForChunkSlot();
166
+
167
+ try {
168
+ const length = range.end - range.start;
169
+ const buffer = await this.loadController.loadBinaryData([{ offset: range.start, length }]);
170
+
171
+ for (const req of range.requests) {
172
+ const relOffset = req.offset - range.start;
173
+ try {
174
+ req._resolve({ buffer, relOffset, length: req.length });
175
+ } catch (e) {
176
+ req._reject(e);
177
+ }
172
178
  }
173
- }
174
- }
175
- */
176
-
177
- const promises = finalRanges.map(async (range) => {
178
- const length = range.end - range.start;
179
- const buffer = await this.loadController.loadBinaryData([{ offset: range.start, length }]);
180
- for (const req of range.requests) {
181
- const relOffset = req.offset - range.start;
182
- try {
183
- req._resolve({ buffer, relOffset, length: req.length });
184
- } catch (e) {
185
- req._reject(e);
179
+ } catch (error) {
180
+ for (const req of range.requests) {
181
+ req._reject(error);
186
182
  }
183
+ console.warn(`Failed to load chunk ${index + 1}/${finalRanges.length} (${range.start}-${range.end}):`, error);
184
+ } finally {
185
+ this.loader.releaseChunkSlot();
187
186
  }
188
187
  });
188
+
189
189
  await Promise.all(promises);
190
190
 
191
191
  this.pendingRequests = [];
@@ -58,6 +58,7 @@ export class GLTFCloudDynamicLoader implements ILoader {
58
58
  this.gltfLoader = new DynamicGltfLoader(this.viewer.camera, scene, this.viewer.renderer);
59
59
  this.gltfLoader.memoryLimit = this.viewer.options.memoryLimit;
60
60
  this.gltfLoader.setVisibleEdges(this.viewer.options.edgeModel);
61
+ // this.gltfLoader.setMaxConcurrentChunks(this.viewer.options.maxConcurrentChunks);
61
62
 
62
63
  this.gltfLoader.addEventListener("databasechunk", (data) => {
63
64
  const modelImpl = new DynamicModelImpl(scene);
@@ -126,8 +127,7 @@ export class GLTFCloudDynamicLoader implements ILoader {
126
127
  baseUrl: () => Promise.resolve(`${model.httpClient.serverUrl}${model.path}/`),
127
128
  };
128
129
 
129
- const structure = new GltfStructure(model.id);
130
- await structure.initialize(loadController);
130
+ const structure = new GltfStructure(model.id, loadController);
131
131
 
132
132
  await this.gltfLoader.loadStructure(structure);
133
133
  await this.gltfLoader.loadNodes();
@@ -1,27 +0,0 @@
1
- import { Box3, Object3D } from "three";
2
- import { ILoader, IViewer } from "@inweb/viewer-core";
3
- /**
4
- * Model interface.
5
- */
6
- export interface IModelImpl {
7
- handle: string;
8
- scene: Object3D;
9
- loader: ILoader;
10
- viewer: IViewer;
11
- dispose(): void;
12
- getExtents(target: Box3): Box3;
13
- getObjects(): Object3D[];
14
- getVisibleObjects(): Object3D[];
15
- hasObject(objects: Object3D): boolean;
16
- getOwnObjects(objects: Object3D | Object3D[]): Object3D[];
17
- getObjectsByHandles(handles: string | string[]): Object3D[];
18
- getHandlesByObjects(objects: Object3D | Object3D[]): string[];
19
- hideObjects(objects: Object3D | Object3D[]): this;
20
- hideAllObjects(): this;
21
- isolateObjects(objects: Object3D | Object3D[]): this;
22
- showObjects(objects: Object3D | Object3D[]): this;
23
- showAllObjects(): this;
24
- showOriginalObjects(objects: Object3D | Object3D[]): this;
25
- hideOriginalObjects(objects: Object3D | Object3D[]): this;
26
- explode(scale: number, coeff?: number): this;
27
- }
@@ -1,27 +0,0 @@
1
- import { Box3, Object3D } from "three";
2
- import { ILoader } from "@inweb/viewer-core";
3
- import { IModelImpl } from "./IModelImpl";
4
- import { Viewer } from "../Viewer";
5
- export declare class ModelImpl implements IModelImpl {
6
- handle: string;
7
- scene: Object3D;
8
- loader: ILoader;
9
- viewer: Viewer;
10
- constructor(scene: Object3D);
11
- dispose(): void;
12
- getExtents(target: Box3): Box3;
13
- getObjects(): Object3D[];
14
- getVisibleObjects(): Object3D[];
15
- hasObject(object: Object3D): boolean;
16
- getOwnObjects(objects: Object3D | Object3D[]): Object3D[];
17
- getObjectsByHandles(handles: string | string[]): Object3D[];
18
- getHandlesByObjects(objects: Object3D | Object3D[]): string[];
19
- hideObjects(objects: Object3D | Object3D[]): this;
20
- hideAllObjects(): this;
21
- isolateObjects(objects: Object3D | Object3D[]): this;
22
- showObjects(objects: Object3D | Object3D[]): this;
23
- showAllObjects(): this;
24
- showOriginalObjects(objects: Object3D | Object3D[]): this;
25
- hideOriginalObjects(objects: Object3D | Object3D[]): this;
26
- explode(scale?: number, coeff?: number): this;
27
- }
@@ -1,2 +0,0 @@
1
- export * from "./IModelImpl";
2
- export * from "./ModelImpl";
@@ -1,67 +0,0 @@
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 { Box3, Object3D } from "three";
25
- import { ILoader, IViewer } from "@inweb/viewer-core";
26
-
27
- /**
28
- * Model interface.
29
- */
30
- export interface IModelImpl {
31
- handle: string;
32
- scene: Object3D;
33
- loader: ILoader;
34
- viewer: IViewer;
35
-
36
- dispose(): void;
37
-
38
- getExtents(target: Box3): Box3;
39
-
40
- getObjects(): Object3D[];
41
-
42
- getVisibleObjects(): Object3D[];
43
-
44
- hasObject(objects: Object3D): boolean;
45
-
46
- getOwnObjects(objects: Object3D | Object3D[]): Object3D[];
47
-
48
- getObjectsByHandles(handles: string | string[]): Object3D[];
49
-
50
- getHandlesByObjects(objects: Object3D | Object3D[]): string[];
51
-
52
- hideObjects(objects: Object3D | Object3D[]): this;
53
-
54
- hideAllObjects(): this;
55
-
56
- isolateObjects(objects: Object3D | Object3D[]): this;
57
-
58
- showObjects(objects: Object3D | Object3D[]): this;
59
-
60
- showAllObjects(): this;
61
-
62
- showOriginalObjects(objects: Object3D | Object3D[]): this;
63
-
64
- hideOriginalObjects(objects: Object3D | Object3D[]): this;
65
-
66
- explode(scale: number, coeff?: number): this;
67
- }