@inweb/viewer-three 26.7.2 → 26.8.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.
@@ -1,11 +1,11 @@
1
- import { LineBasicMaterial, MeshBasicMaterial, Object3D, WebGLRenderTarget } from "three";
1
+ import { LineBasicMaterial, MeshPhongMaterial, Object3D, WebGLRenderTarget } from "three";
2
2
  import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";
3
3
  import { IComponent, ResizeEvent } from "@inweb/viewer-core";
4
4
  import { Viewer } from "../Viewer";
5
5
  export declare class HighlighterComponent implements IComponent {
6
6
  protected viewer: Viewer;
7
7
  renderTarget: WebGLRenderTarget;
8
- highlightMaterial: MeshBasicMaterial;
8
+ highlightMaterial: MeshPhongMaterial;
9
9
  outlineMaterial: LineMaterial;
10
10
  highlightLineMaterial: LineBasicMaterial;
11
11
  highlightLineGlowMaterial: LineMaterial;
@@ -1,10 +1,8 @@
1
- import { Group } from "three";
2
1
  import { ILoader, LoadParams } from "@inweb/viewer-core";
3
2
  import { Viewer } from "../Viewer";
4
3
  import { DynamicGltfLoader } from "./DynamicGltfLoader/DynamicGltfLoader.js";
5
4
  export declare class GLTFCloudDynamicLoader implements ILoader {
6
5
  viewer: Viewer;
7
- scene: Group;
8
6
  gltfLoader: DynamicGltfLoader;
9
7
  requestId: number;
10
8
  constructor(viewer: Viewer);
@@ -11,7 +11,7 @@ import { ILoadersRegistry } from "@inweb/viewer-core";
11
11
  *
12
12
  * The loader should do:
13
13
  *
14
- * - Load scene from file. The scene must be a Three.js object of type `Object3D` or a descendant of it.
14
+ * - Load raw data from file and convert it to the `Three.js` scene.
15
15
  * - Add scene to the viewer `scene`.
16
16
  * - Create `ModelImpl` for the scene and to the viewer `models` list.
17
17
  * - Synchronize viewer options and overlay.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inweb/viewer-three",
3
- "version": "26.7.2",
3
+ "version": "26.8.0",
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.7.2",
39
- "@inweb/eventemitter2": "~26.7.2",
40
- "@inweb/markup": "~26.7.2",
41
- "@inweb/viewer-core": "~26.7.2"
38
+ "@inweb/client": "~26.8.0",
39
+ "@inweb/eventemitter2": "~26.8.0",
40
+ "@inweb/markup": "~26.8.0",
41
+ "@inweb/viewer-core": "~26.8.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/three": "^0.173.0",
@@ -154,14 +154,19 @@ export class Viewer
154
154
 
155
155
  this.scene = new Scene();
156
156
  this.helpers = new Scene();
157
+ this.target = new Vector3();
157
158
 
158
159
  const pixelRatio = window.devicePixelRatio;
159
160
  const rect = canvas.parentElement.getBoundingClientRect();
160
161
  const width = rect.width || 1;
161
162
  const height = rect.height || 1;
162
163
  const aspect = width / height;
164
+
163
165
  this.camera = new PerspectiveCamera(45, aspect, 0.01, 1000);
164
- this.camera.up.set(0, 0, 1);
166
+ this.camera.up.set(0, 1, 0);
167
+ this.camera.position.set(0, 0, 1);
168
+ this.camera.lookAt(this.target);
169
+ this.camera.updateProjectionMatrix();
165
170
 
166
171
  this.renderer = new WebGLRenderer({
167
172
  canvas,
@@ -30,6 +30,7 @@ export function setSelected(viewer: Viewer, handles: string[] = []): void {
30
30
 
31
31
  viewer.models.forEach((model) => {
32
32
  const objects = model.getObjectsByHandles(handles);
33
+ model.showObjects(objects);
33
34
  selection.select(objects, model);
34
35
  });
35
36
 
@@ -80,9 +80,9 @@ commands.registerCommand("applyModelTransform", applyModelTransform);
80
80
  commands.registerCommand("clearMarkup", clearMarkup);
81
81
  commands.registerCommand("clearSelected", clearSelected);
82
82
  commands.registerCommand("clearSlices", clearSlices);
83
+ commands.registerCommand("collect", collect);
83
84
  commands.registerCommand("createPreview", createPreview);
84
85
  commands.registerCommand("explode", explode);
85
- commands.registerCommand("collect", collect);
86
86
  commands.registerCommand("getDefaultViewPositions", getDefaultViewPositions);
87
87
  commands.registerCommand("getModels", getModels);
88
88
  commands.registerCommand("getSelected", getSelected);
@@ -53,7 +53,6 @@ export class CameraComponent implements IComponent {
53
53
  });
54
54
  if (sceneCamera) {
55
55
  this.viewer.camera = sceneCamera.clone();
56
- this.viewer.camera.up.set(0, 0, 1);
57
56
  this.viewer.camera.scale.set(1, 1, 1); // <- Visualize fix
58
57
  }
59
58
 
@@ -25,7 +25,7 @@ import {
25
25
  Color,
26
26
  EdgesGeometry,
27
27
  LineBasicMaterial,
28
- MeshBasicMaterial,
28
+ MeshPhongMaterial,
29
29
  Object3D,
30
30
  RGBAFormat,
31
31
  UnsignedByteType,
@@ -43,7 +43,7 @@ import { HighlighterUtils } from "./HighlighterUtils";
43
43
  export class HighlighterComponent implements IComponent {
44
44
  protected viewer: Viewer;
45
45
  public renderTarget: WebGLRenderTarget;
46
- public highlightMaterial: MeshBasicMaterial;
46
+ public highlightMaterial: MeshPhongMaterial;
47
47
  public outlineMaterial: LineMaterial;
48
48
  public highlightLineMaterial: LineBasicMaterial;
49
49
  public highlightLineGlowMaterial: LineMaterial;
@@ -76,6 +76,8 @@ export class HighlighterComponent implements IComponent {
76
76
  }
77
77
 
78
78
  highlight(objects: Object3D | Object3D[]) {
79
+ const { edgesVisibility } = this.viewer.options;
80
+
79
81
  if (!Array.isArray(objects)) objects = [objects];
80
82
  if (!objects.length) return;
81
83
 
@@ -93,25 +95,27 @@ export class HighlighterComponent implements IComponent {
93
95
  wireframe.position.copy(object.position);
94
96
  wireframe.rotation.copy(object.rotation);
95
97
  wireframe.scale.copy(object.scale);
98
+ wireframe.visible = edgesVisibility;
96
99
 
97
100
  object.parent.add(wireframe);
101
+ object.userData.highlightWireframe = wireframe;
98
102
 
99
- object.userData.highlightwireframe = wireframe;
100
103
  object.userData.originalMaterial = object.material;
101
104
  object.material = this.highlightLineMaterial;
102
105
  object.isHighlighted = true;
103
106
  } else if (object.isMesh) {
104
- const edgesGeometry = new EdgesGeometry(object.geometry, 30);
107
+ const edgesGeometry = new EdgesGeometry(object.geometry, 60);
105
108
  const lineGeometry = new LineSegmentsGeometry().fromEdgesGeometry(edgesGeometry);
106
109
 
107
110
  const wireframe = new Wireframe(lineGeometry, this.outlineMaterial);
108
111
  wireframe.position.copy(object.position);
109
112
  wireframe.rotation.copy(object.rotation);
110
113
  wireframe.scale.copy(object.scale);
114
+ wireframe.visible = edgesVisibility;
111
115
 
112
116
  object.parent.add(wireframe);
117
+ object.userData.highlightWireframe = wireframe;
113
118
 
114
- object.userData.highlightwireframe = wireframe;
115
119
  object.userData.originalMaterial = object.material;
116
120
  object.material = this.highlightMaterial;
117
121
  object.isHighlighted = true;
@@ -128,29 +132,35 @@ export class HighlighterComponent implements IComponent {
128
132
 
129
133
  object.isHighlighted = false;
130
134
  object.material = object.userData.originalMaterial;
131
- object.userData.highlightwireframe.removeFromParent();
135
+ object.userData.highlightWireframe.removeFromParent();
132
136
 
133
137
  delete object.userData.originalMaterial;
134
- delete object.userData.highlightwireframe;
138
+ delete object.userData.highlightWireframe;
135
139
  });
136
140
  }
137
141
 
138
142
  geometryEnd = () => {
139
- const { facesColor, facesTransparancy, edgesColor } = this.viewer.options;
143
+ const { facesColor, facesTransparancy, edgesColor, edgesOverlap, facesOverlap } = this.viewer.options;
140
144
 
141
- this.highlightMaterial = new MeshBasicMaterial({
145
+ this.highlightMaterial = new MeshPhongMaterial({
142
146
  color: new Color(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255),
143
147
  transparent: true,
144
148
  opacity: (255 - facesTransparancy) / 255,
145
- depthTest: false,
146
- depthWrite: false,
149
+ depthTest: !facesOverlap,
150
+ depthWrite: !facesOverlap,
151
+ specular: 0x222222,
152
+ shininess: 10,
153
+ reflectivity: 0.05,
154
+ polygonOffset: true,
155
+ polygonOffsetFactor: 1,
156
+ polygonOffsetUnits: 1,
147
157
  });
148
158
 
149
159
  this.outlineMaterial = new LineMaterial({
150
160
  color: new Color(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255),
151
161
  linewidth: 1.5,
152
- depthTest: false,
153
- depthWrite: false,
162
+ depthTest: !edgesOverlap,
163
+ depthWrite: !edgesOverlap,
154
164
  resolution: new Vector2(window.innerWidth, window.innerHeight),
155
165
  });
156
166
 
@@ -165,21 +175,33 @@ export class HighlighterComponent implements IComponent {
165
175
  linewidth: 5,
166
176
  transparent: true,
167
177
  opacity: 0.8,
168
- depthTest: true,
169
- depthWrite: true,
178
+ depthTest: !edgesOverlap,
179
+ depthWrite: !edgesOverlap,
170
180
  resolution: new Vector2(window.innerWidth, window.innerHeight),
171
181
  });
172
182
  };
173
183
 
174
184
  optionsChange = () => {
175
- const { facesColor, facesTransparancy, edgesColor } = this.viewer.options;
185
+ const { facesColor, facesTransparancy, edgesColor, edgesVisibility, edgesOverlap, facesOverlap } =
186
+ this.viewer.options;
176
187
 
177
188
  this.highlightMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
178
189
  this.highlightMaterial.opacity = (255 - facesTransparancy) / 255;
190
+ this.highlightMaterial.depthTest = !facesOverlap;
191
+ this.highlightMaterial.depthWrite = !facesOverlap;
192
+
179
193
  this.outlineMaterial.color.setRGB(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255);
194
+ this.outlineMaterial.depthTest = !edgesOverlap;
195
+ this.outlineMaterial.depthWrite = !edgesOverlap;
196
+
180
197
  this.highlightLineMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
181
198
  this.highlightLineGlowMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
182
199
 
200
+ this.viewer.selected.forEach((selected) => {
201
+ const wireframe = selected.userData.highlightWireframe;
202
+ if (wireframe) wireframe.visible = edgesVisibility;
203
+ });
204
+
183
205
  this.viewer.update();
184
206
  };
185
207
 
@@ -36,20 +36,10 @@ export class LightComponent implements IComponent {
36
36
  constructor(viewer: Viewer) {
37
37
  this.viewer = viewer;
38
38
 
39
- this.ambientLight = new AmbientLight(0xffffff, 1);
40
- this.viewer.scene.add(this.ambientLight);
41
-
42
- this.directionalLight = new DirectionalLight(0xffffff, 1);
43
- this.directionalLight.position.set(0.5, 0, 0.866); // ~60º
44
- this.viewer.scene.add(this.directionalLight);
45
-
39
+ this.ambientLight = new AmbientLight(0xffffff, 1.0);
40
+ this.directionalLight = new DirectionalLight(0xffffff, 1.0);
46
41
  this.frontLight = new DirectionalLight(0xffffff, 1.25);
47
- this.frontLight.position.set(0, 1, 0);
48
- this.viewer.scene.add(this.frontLight);
49
-
50
42
  this.hemisphereLight = new HemisphereLight(0xffffff, 0x444444, 1.25);
51
- this.hemisphereLight.position.set(0, 0, 1);
52
- this.viewer.scene.add(this.hemisphereLight);
53
43
 
54
44
  this.viewer.addEventListener("databasechunk", this.geometryEnd);
55
45
  this.viewer.addEventListener("clear", this.geometryEnd);
@@ -84,15 +74,21 @@ export class LightComponent implements IComponent {
84
74
  const extentsSize = this.viewer.extents.getBoundingSphere(new Sphere()).radius;
85
75
 
86
76
  this.directionalLight.position
87
- .set(0.5, 0, 0.866)
77
+ .set(0.5, 0.866, 0) // ~60º
88
78
  .multiplyScalar(extentsSize * 2)
89
79
  .add(extentsCenter);
90
80
  this.directionalLight.target.position.copy(extentsCenter);
91
81
 
92
- this.frontLight.position.set(0, extentsSize * 2, 0).add(extentsCenter);
82
+ this.frontLight.position
83
+ .set(0, 0, 1)
84
+ .multiplyScalar(extentsSize * 2)
85
+ .add(extentsCenter);
93
86
  this.frontLight.target.position.copy(extentsCenter);
94
87
 
95
- this.hemisphereLight.position.set(0, extentsSize * 3, 0).add(extentsCenter);
88
+ this.hemisphereLight.position
89
+ .set(0, 0, 1)
90
+ .multiplyScalar(extentsSize * 3)
91
+ .add(extentsCenter);
96
92
 
97
93
  this.viewer.scene.add(this.ambientLight);
98
94
  this.viewer.scene.add(this.directionalLight);
@@ -68,7 +68,7 @@ export class SelectionComponent implements IComponent {
68
68
  this.viewer.models.forEach((model) => {
69
69
  const objects = model.getVisibleObjects();
70
70
  const intersects = this.getPointerIntersects(upPosition, objects);
71
- intersections.push(...intersects.map((x) => ({ ...x, model })));
71
+ if (intersects.length > 0) intersections.push({ ...intersects[0], model });
72
72
  });
73
73
  intersections = intersections.sort((a, b) => a.distance - b.distance);
74
74
 
@@ -126,7 +126,6 @@ export class SelectionComponent implements IComponent {
126
126
  if (!Array.isArray(objects)) objects = [objects];
127
127
  if (!objects.length) return;
128
128
 
129
- model.showObjects(objects);
130
129
  model.showOriginalObjects(objects);
131
130
  this.highlighter.highlight(objects);
132
131