three-cad-viewer 2.1.2 → 2.2.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.
@@ -97,14 +97,16 @@ class NestedGroup {
97
97
  1.0,
98
98
  color == null ? this.edgeColor : color,
99
99
  geomtype,
100
- "edges"
100
+ "edges",
101
101
  );
102
102
 
103
103
  var edges = this._renderEdges(
104
- (edgeList.edges)
104
+ edgeList.edges
105
105
  ? edgeList.edges // protocol version 2
106
- : edgeList, // protocol version 1
107
- lineWidth, color, state
106
+ : edgeList, // protocol version 1
107
+ lineWidth,
108
+ color,
109
+ state,
108
110
  );
109
111
  if (name) {
110
112
  edges.name = name;
@@ -124,20 +126,24 @@ class NestedGroup {
124
126
  1.0,
125
127
  color == null ? this.edgeColor : color,
126
128
  geomtype,
127
- "vertices"
129
+ "vertices",
128
130
  );
129
131
 
130
132
  const vertex_color = color == null ? this.edgeColor : color;
131
133
 
132
134
  let positions;
133
- if (vertexList.obj_vertices) { // protocol version 2
134
- positions = vertexList.obj_vertices instanceof Float32Array
135
- ? vertexList.obj_vertices
136
- : new Float32Array(vertexList.obj_vertices);
137
- } else { // protocol version 1
138
- positions = vertexList instanceof Float32Array
139
- ? vertexList.flat()
140
- : new Float32Array(vertexList.flat());
135
+ if (vertexList.obj_vertices) {
136
+ // protocol version 2
137
+ positions =
138
+ vertexList.obj_vertices instanceof Float32Array
139
+ ? vertexList.obj_vertices
140
+ : new Float32Array(vertexList.obj_vertices);
141
+ } else {
142
+ // protocol version 1
143
+ positions =
144
+ vertexList instanceof Float32Array
145
+ ? vertexList.flat()
146
+ : new Float32Array(vertexList.flat());
141
147
  }
142
148
  const geometry = new THREE.BufferGeometry();
143
149
  geometry.setAttribute(
@@ -167,7 +173,20 @@ class NestedGroup {
167
173
  return group;
168
174
  }
169
175
 
170
- renderShape(shape, color, alpha, renderback, path, name, states, geomtype = null, subtype = null) {
176
+ renderShape(
177
+ shape,
178
+ color,
179
+ alpha,
180
+ renderback,
181
+ path,
182
+ name,
183
+ states,
184
+ geomtype = null,
185
+ subtype = null,
186
+ texture_data = null,
187
+ texture_width = null,
188
+ texture_height = null,
189
+ ) {
171
190
  const positions =
172
191
  shape.vertices instanceof Float32Array
173
192
  ? shape.vertices
@@ -199,38 +218,74 @@ class NestedGroup {
199
218
  } else if (alpha < 1.0) {
200
219
  this.transparent = true;
201
220
  }
202
- var shapeGeometry = new THREE.BufferGeometry();
203
- shapeGeometry.setAttribute(
204
- "position",
205
- new THREE.BufferAttribute(positions, 3),
206
- );
207
- shapeGeometry.setAttribute("normal", new THREE.BufferAttribute(normals, 3));
208
- shapeGeometry.setIndex(new THREE.BufferAttribute(triangles, 1));
209
-
210
- // see https://stackoverflow.com/a/37651610
211
- // "A common draw configuration you see is to draw all the opaque object with depth testing on,
212
- // turn depth write off, then draw the transparent objects in a back to front order."
213
- const frontMaterial = new THREE.MeshStandardMaterial({
214
- color: color,
215
- metalness: this.metalness,
216
- roughness: this.roughness,
217
- // envMap: texture,
218
- polygonOffset: true,
219
- polygonOffsetFactor: 1.0,
220
- polygonOffsetUnits: 1.0,
221
- transparent: true,
222
- opacity: this.transparent ? this.defaultOpacity * alpha : alpha,
223
- // turn depth write off for transparent objects
224
- depthWrite: !this.transparent,
225
- // but keep depth test
226
- depthTest: true,
227
- clipIntersection: false,
228
- side: THREE.FrontSide,
229
- visible: states[0] == 1,
230
- });
221
+
222
+ var shapeGeometry;
223
+ var texture = null;
224
+ var frontMaterial = null;
225
+
226
+ if (texture_data != null) {
227
+ const url = `data:image/${texture_data.format};base64,${texture_data.data}`;
228
+ var img = new Image();
229
+ img.setAttribute("src", url);
230
+ shapeGeometry = new THREE.PlaneGeometry(texture_width, texture_height);
231
+
232
+ texture = new THREE.Texture(img);
233
+ texture.needsUpdate = true;
234
+ texture.colorSpace = THREE.SRGBColorSpace;
235
+
236
+ frontMaterial = new THREE.MeshBasicMaterial({
237
+ color: "#ffffff",
238
+ map: texture,
239
+ side: THREE.DoubleSide,
240
+ });
241
+ renderback = false;
242
+ } else {
243
+ shapeGeometry = new THREE.BufferGeometry();
244
+ shapeGeometry.setAttribute(
245
+ "position",
246
+ new THREE.BufferAttribute(positions, 3),
247
+ );
248
+ shapeGeometry.setAttribute(
249
+ "normal",
250
+ new THREE.BufferAttribute(normals, 3),
251
+ );
252
+ shapeGeometry.setIndex(new THREE.BufferAttribute(triangles, 1));
253
+ group.shapeGeometry = shapeGeometry;
254
+
255
+ // see https://stackoverflow.com/a/37651610
256
+ // "A common draw configuration you see is to draw all the opaque object with depth testing on,
257
+ // turn depth write off, then draw the transparent objects in a back to front order."
258
+ frontMaterial = new THREE.MeshStandardMaterial({
259
+ color: color,
260
+ metalness: this.metalness,
261
+ roughness: this.roughness,
262
+ // envMap: texture,
263
+ polygonOffset: true,
264
+ polygonOffsetFactor: 1.0,
265
+ polygonOffsetUnits: 1.0,
266
+ transparent: true,
267
+ opacity: this.transparent ? this.defaultOpacity * alpha : alpha,
268
+ // turn depth write off for transparent objects
269
+ depthWrite: !this.transparent,
270
+ // but keep depth test
271
+ depthTest: true,
272
+ clipIntersection: false,
273
+ side: THREE.FrontSide,
274
+ visible: states[0] == 1,
275
+ map: texture,
276
+ name:"frontMaterial"
277
+ });
278
+ }
279
+
280
+ const backColor =
281
+ group.subtype === "solid"
282
+ ? color
283
+ : new THREE.Color(
284
+ Math.round(Math.min(0xffffff, this.edgeColor * 1.25)),
285
+ );
231
286
 
232
287
  const backMaterial = new THREE.MeshBasicMaterial({
233
- color: new THREE.Color(this.edgeColor),
288
+ color: backColor,
234
289
  side: THREE.BackSide,
235
290
  polygonOffset: true,
236
291
  polygonOffsetFactor: 1.0,
@@ -243,14 +298,15 @@ class NestedGroup {
243
298
  depthTest: true,
244
299
  clipIntersection: false,
245
300
  visible: states[0] == 1 && (renderback || this.backVisible),
301
+ name: "backMaterial"
246
302
  });
247
303
 
248
- const front = new THREE.Mesh(shapeGeometry, frontMaterial);
249
- front.name = name;
250
-
251
304
  const back = new THREE.Mesh(shapeGeometry, backMaterial);
252
305
  back.name = name;
253
306
 
307
+ const front = new THREE.Mesh(shapeGeometry, frontMaterial);
308
+ front.name = name;
309
+
254
310
  // ensure, transparent objects will be rendered at the end
255
311
  if (alpha < 1.0) {
256
312
  back.renderOrder = 999;
@@ -282,7 +338,7 @@ class NestedGroup {
282
338
  }
283
339
 
284
340
  renderLoop(shapes, path, states) {
285
- const _render = (shape) => {
341
+ const _render = (shape, texture, width, height) => {
286
342
  var mesh;
287
343
  switch (shape.type) {
288
344
  case "edges":
@@ -318,6 +374,9 @@ class NestedGroup {
318
374
  states[shape.id],
319
375
  { topo: "face", geomtype: shape.geomtype },
320
376
  shape.subtype,
377
+ texture,
378
+ width,
379
+ height,
321
380
  );
322
381
  }
323
382
  // support object locations
@@ -346,7 +405,11 @@ class NestedGroup {
346
405
  if (shape.parts) {
347
406
  group.add(this.renderLoop(shape, path, states));
348
407
  } else {
349
- const objectGroup = _render(shape);
408
+ const has_texture = shape.texture != null;
409
+ var texture = has_texture ? shape.texture.image : null;
410
+ var width = has_texture ? shape.texture.width : null;
411
+ var height = has_texture ? shape.texture.height : null;
412
+ const objectGroup = _render(shape, texture, width, height);
350
413
  this.groups[shape.id] = objectGroup;
351
414
  group.add(objectGroup);
352
415
  }
@@ -369,10 +432,9 @@ class NestedGroup {
369
432
 
370
433
  _traverse(func, flag) {
371
434
  for (var path in this.groups) {
372
- for (var obj of this.groups[path].children) {
373
- if (obj instanceof ObjectGroup) {
374
- obj[func](flag);
375
- }
435
+ var obj = this.groups[path];
436
+ if (obj instanceof ObjectGroup) {
437
+ obj[func](flag);
376
438
  }
377
439
  }
378
440
  }
@@ -112,15 +112,19 @@ class ObjectGroup extends THREE.Group {
112
112
 
113
113
  setMetalness(value) {
114
114
  for (var child of this.children) {
115
- child.material.metalness = value;
116
- child.material.needsUpdate = true;
115
+ if (!child.name.startsWith("clipping")) {
116
+ child.material.metalness = value;
117
+ child.material.needsUpdate = true;
118
+ }
117
119
  }
118
120
  }
119
121
 
120
122
  setRoughness(value) {
121
123
  for (var child of this.children) {
122
- child.material.roughness = value;
123
- child.material.needsUpdate = true;
124
+ if (!child.name.startsWith("clipping")) {
125
+ child.material.roughness = value;
126
+ child.material.needsUpdate = true;
127
+ }
124
128
  }
125
129
  }
126
130
 
@@ -134,11 +138,13 @@ class ObjectGroup extends THREE.Group {
134
138
  : this.alpha;
135
139
  }
136
140
  for (var child of this.children) {
137
- // turn depth write off for transparent objects
138
- child.material.depthWrite = this.alpha < 1.0 ? false : !flag;
139
- // but keep depth test
140
- child.material.depthTest = true;
141
- child.material.needsUpdate = true;
141
+ if (!child.name.startsWith("clipping")){
142
+ // turn depth write off for transparent objects
143
+ child.material.depthWrite = this.alpha < 1.0 ? false : !flag;
144
+ // but keep depth test
145
+ child.material.depthTest = true;
146
+ child.material.needsUpdate = true;
147
+ }
142
148
  }
143
149
  }
144
150
 
@@ -193,9 +199,11 @@ class ObjectGroup extends THREE.Group {
193
199
 
194
200
  setClipIntersection(flag) {
195
201
  for (var child of this.children) {
196
- child.material.clipIntersection = flag;
197
- child.material.clipIntersection = flag;
198
- child.material.clipIntersection = flag;
202
+ if (!child.name.startsWith("clipping")) {
203
+ child.material.clipIntersection = flag;
204
+ child.material.clipIntersection = flag;
205
+ child.material.clipIntersection = flag;
206
+ }
199
207
  }
200
208
  }
201
209
 
package/src/slider.js CHANGED
@@ -91,7 +91,7 @@ class Slider {
91
91
  Math.min(value, this.slider.max),
92
92
  this.slider.min,
93
93
  );
94
- this.input.value = trimmed_value.toFixed(0);
94
+ this.input.value = Math.round(1000 * trimmed_value) / 1000;
95
95
  this.slider.value = value;
96
96
  this._handle(this.type, this.index, this.input.value);
97
97
  this._notify(value, notify);
package/src/toolbar.js CHANGED
@@ -145,12 +145,20 @@ class ClickButton extends BaseButton {
145
145
  }
146
146
  };
147
147
 
148
- // eslint-disable-next-line no-unused-vars
148
+ extractIdFromName = (name) => {
149
+ const match = "grid-";
150
+ const start = name.indexOf(match) + match.length;
151
+ const end = name.indexOf("_", start);
152
+ const result = name.slice(start, end);
153
+ return result;
154
+ };
155
+
149
156
  handler = (e) => {
150
- if (this.dropdown != null && this.dropdown.includes(e.target.innerHTML)) {
151
- this.action(`grid-${e.target.innerHTML}`, !this.checkElems[e.target.innerHTML].checked);
152
- e.preventDefault();
153
- e.stopPropagation();
157
+ const id = this.extractIdFromName(e.target.id);
158
+ if (this.dropdown != null && id && this.dropdown.includes(id)) {
159
+ const newstate = e.target.checked;
160
+ this.action(`grid-${id}`, newstate);
161
+ this.checkElems[id].checked = newstate;
154
162
  } else if (e.target.type === "button") {
155
163
  if (!this.state) {
156
164
  this.clearGroup();
package/src/treeview.js CHANGED
@@ -26,12 +26,13 @@ const States = {
26
26
  };
27
27
 
28
28
  class TreeView {
29
- constructor(states, tree, objectHandler, pickHandler, theme) {
29
+ constructor(states, tree, objectHandler, pickHandler, theme, newTreeBehavior) {
30
30
  this.states = states;
31
31
  this.tree = tree;
32
32
  this.objectHandler = objectHandler;
33
33
  this.pickHandler = pickHandler;
34
34
  this.theme = theme;
35
+ this.newTreeBehavior = newTreeBehavior;
35
36
  this.lastSelection = null;
36
37
 
37
38
  this.setupIcons(theme);
@@ -401,10 +402,19 @@ class TreeView {
401
402
  if (type == "leaf") {
402
403
  this.updateState(node, icon_id, newState);
403
404
  this.updateNodes(this.treeModel, icon_id);
405
+ if (this.newTreeBehavior && icon_id == 0) {
406
+ this.updateState(node, 1, newState);
407
+ this.updateNodes(this.treeModel, 1);
408
+ }
404
409
  this.objectHandler(this.states);
405
410
  } else if (type == "node") {
406
411
  this.propagateChange(node, icon_id, newState);
407
412
  this.updateNodes(this.treeModel, icon_id);
413
+ if (this.newTreeBehavior && icon_id == 0) {
414
+ this.objectHandler(this.states);
415
+ this.propagateChange(node, 1, newState);
416
+ this.updateNodes(this.treeModel, 1);
417
+ }
408
418
  this.objectHandler(this.states);
409
419
  } else {
410
420
  console.error(`Error, unknown type '${type}'`);