@buerli.io/headless 0.5.0 → 0.6.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.
@@ -36,6 +36,7 @@ const core_1 = require("@buerli.io/core");
36
36
  const three_1 = require("three");
37
37
  const BufferGeometryUtils_ = __importStar(require("three/examples/jsm/utils/BufferGeometryUtils"));
38
38
  const selection_1 = require("./utils/selection");
39
+ const meshes_1 = require("./utils/meshes");
39
40
  const featureAPI = classcad_1.ccAPI.feature;
40
41
  const sketcherAPI = classcad_1.ccAPI.sketcher;
41
42
  const baseModelerAPI = classcad_1.ccAPI.baseModeler;
@@ -63,33 +64,6 @@ const getDimensionType = (type) => {
63
64
  }
64
65
  return cclass;
65
66
  };
66
- /**
67
- * Transforms the transformation which is local to the ownerId into global
68
- * transformation and returns it.
69
- * @param ownerId node to get the global transformation from
70
- * @param localTransformation transformation local to the owner, will be calculated into global transformation
71
- * @returns the global transformation from local transformation to owner
72
- */
73
- const getGlobalTransformation = (drawingId, ownerId, localTransformation) => {
74
- const lT = localTransformation;
75
- const coordSysOwner = asmUtils.getCoordSysFromNode(drawingId, ownerId);
76
- if (coordSysOwner) {
77
- const origin = [lT[0].x, lT[0].y, lT[0].z];
78
- const xAxis = [lT[1].x, lT[1].y, lT[1].z];
79
- const yAxis = [lT[2].x, lT[2].y, lT[2].z];
80
- const zAxis = new three_1.Vector3().crossVectors(new three_1.Vector3(lT[1].x, lT[1].y, lT[1].z), new three_1.Vector3(lT[2].x, lT[2].y, lT[2].z));
81
- const matrix = core_1.MathUtils.convertToMatrix4([origin, xAxis, yAxis, [zAxis.x, zAxis.y, zAxis.z]]);
82
- const transformation = core_1.MathUtils.convertToMatrix4(coordSysOwner).clone().multiply(matrix);
83
- const transformationCoords = core_1.MathUtils.convertToCoordinateSystem(transformation);
84
- const tC = transformationCoords;
85
- return [
86
- { x: tC[0][0], y: tC[0][1], z: tC[0][2] },
87
- { x: tC[1][0], y: tC[1][1], z: tC[1][2] },
88
- { x: tC[2][0], y: tC[2][1], z: tC[2][2] },
89
- ];
90
- }
91
- return undefined;
92
- };
93
67
  /**
94
68
  * Helps to create the buffer geometry of the given object recursively.
95
69
  * @param object object to create the buffergeometry from
@@ -133,7 +107,7 @@ const createRecursiveBufferGeometry = async (object, drawingId, bufferGeomArray)
133
107
  else if (object.children) {
134
108
  // Assembly
135
109
  for (const child of object.children) {
136
- if (tree[child].class === classcad_1.CCClasses.CCProductReference || tree[child].class === classcad_1.CCClasses.CCProductReferenceET) {
110
+ if (classcad_1.ccUtils.base.isA(tree[child].class, classcad_1.CCClasses.IProductReference)) {
137
111
  await createRecursiveBufferGeometry(tree[child], drawingId, bufferGeomArray);
138
112
  }
139
113
  }
@@ -183,9 +157,9 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
183
157
  mesh.userData = { id: m.graphicId }; // add graphic id to the userData
184
158
  mesh.geometry = m.geometry;
185
159
  mesh.material = new three_1.MeshStandardMaterial({
186
- color: m.color,
187
- transparent: m.opacity < 1,
188
- opacity: m.opacity,
160
+ color: m.color ? m.color : cachedEntity.color,
161
+ transparent: m.color ? m.opacity < 1 : cachedEntity.opacity < 1,
162
+ opacity: m.color ? m.opacity : cachedEntity.opacity,
189
163
  });
190
164
  _solid.add(mesh);
191
165
  result.meshes.push(mesh);
@@ -193,15 +167,14 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
193
167
  }
194
168
  else {
195
169
  // Merge all geometries into one mesh, sort them by color
196
- const colorMeshesMap = getDifferentColoredMeshesFromEntity(cachedEntity);
170
+ const colorMeshesMap = (0, meshes_1.getDifferentColoredMeshesFromEntity)(cachedEntity);
197
171
  Object.keys(colorMeshesMap).forEach(key => {
198
- const coloredMeshes = colorMeshesMap[key];
199
172
  const mesh = new three_1.Mesh();
200
- mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(coloredMeshes.map(m => m.geometry));
173
+ mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(colorMeshesMap[key].meshes.map(m => m.geometry));
201
174
  mesh.material = new three_1.MeshStandardMaterial({
202
- color: coloredMeshes[0].color,
203
- transparent: coloredMeshes[0].opacity < 1,
204
- opacity: coloredMeshes[0].opacity,
175
+ color: colorMeshesMap[key].color,
176
+ transparent: colorMeshesMap[key].opacity < 1,
177
+ opacity: colorMeshesMap[key].opacity,
205
178
  });
206
179
  _solid.add(mesh); // Add mesh to solid of the scene
207
180
  result.meshes.push(mesh); // Collect mesh to return result later
@@ -226,30 +199,12 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
226
199
  result.nodes.push(assembly);
227
200
  root.add(assembly);
228
201
  for (const child of object.children) {
229
- if (tree[child].class === classcad_1.CCClasses.CCProductReference || tree[child].class === classcad_1.CCClasses.CCProductReferenceET) {
202
+ if (classcad_1.ccUtils.base.isA(tree[child].class, classcad_1.CCClasses.IProductReference)) {
230
203
  await createRecursiveScene(tree[child], drawingId, assembly, result, options);
231
204
  }
232
205
  }
233
206
  }
234
207
  };
235
- /**
236
- * Get all meshes in a map, sorted by their color / transparency
237
- * @param entity entity to look for the meshes
238
- * @returns map (key = color/transparency as string, value = meshes array)
239
- */
240
- const getDifferentColoredMeshesFromEntity = (entity) => {
241
- const colorMeshesMap = {};
242
- entity.meshes.forEach(mesh => {
243
- const key = mesh.color.getHexString() + mesh.opacity.toString();
244
- if (colorMeshesMap[key]) {
245
- colorMeshesMap[key].push(mesh);
246
- }
247
- else {
248
- colorMeshesMap[key] = [mesh];
249
- }
250
- });
251
- return colorMeshesMap;
252
- };
253
208
  /**
254
209
  * Helper function to log relevant points to find geometry to the console.
255
210
  * This helps the user to copy the points directly from console to parameter of
@@ -302,8 +257,9 @@ class CAD {
302
257
  const nodeParam = {
303
258
  referenceId: rProductId,
304
259
  ownerId: rOwnerId,
305
- transformation: getGlobalTransformation(drawingId, rOwnerId, node.transformation) || node.transformation,
260
+ transformation: node.transformation,
306
261
  name: node.name,
262
+ options: Object.assign(Object.assign({}, node.options), { isLocal: true }), // in non-interactive mode, the transformation is local to the owner
307
263
  };
308
264
  nodesToAdd.push(nodeParam);
309
265
  }
@@ -1140,9 +1096,9 @@ class CAD {
1140
1096
  return await assemblyBuilderAPI.createAssemblyAsTemplate(drawingId, name);
1141
1097
  });
1142
1098
  },
1143
- createRootAssembly: (name) => {
1099
+ createRootAssembly: (name, options) => {
1144
1100
  return this.resolve(async ([]) => {
1145
- return await assemblyBuilderAPI.createRootAssembly(drawingId, name);
1101
+ return await assemblyBuilderAPI.createRootAssembly(drawingId, name, options);
1146
1102
  });
1147
1103
  },
1148
1104
  createPart: (name) => {
@@ -1286,6 +1242,18 @@ class CAD {
1286
1242
  return null;
1287
1243
  }, refId);
1288
1244
  },
1245
+ getProductOfNode: (refIds) => {
1246
+ return this.resolve(async ([rRefIds]) => {
1247
+ const drawing = (0, core_1.getDrawing)(drawingId);
1248
+ const tree = drawing.structure.tree;
1249
+ const products = [];
1250
+ for (const rRefId of rRefIds) {
1251
+ const product = asmUtils.findProduct(rRefId, tree);
1252
+ products.push(product);
1253
+ }
1254
+ return products;
1255
+ }, refIds);
1256
+ },
1289
1257
  setCurrentNode: (refId) => {
1290
1258
  return this.resolve(async ([rRefId]) => {
1291
1259
  await assemblyBuilderAPI.setCurrentNode(drawingId, rRefId);
@@ -1596,11 +1564,11 @@ class CAD {
1596
1564
  loadFromUrl: (url, filetype) => {
1597
1565
  return baseModelerAPI.loadFromUrl(drawingId, url, filetype, true);
1598
1566
  },
1599
- loadProduct: (content, type) => {
1600
- return assemblyBuilderAPI.loadProduct(drawingId, content, type);
1567
+ loadProduct: (content, type, options) => {
1568
+ return assemblyBuilderAPI.loadProduct(drawingId, content, type, '', options);
1601
1569
  },
1602
- loadProductFromUrl: (url, filetype) => {
1603
- return assemblyBuilderAPI.loadProductFromUrl(drawingId, url, filetype);
1570
+ loadProductFromUrl: (url, filetype, options) => {
1571
+ return assemblyBuilderAPI.loadProductFromUrl(drawingId, url, filetype, options);
1604
1572
  },
1605
1573
  pick: (partId, type, points) => {
1606
1574
  return this.resolve(async ([rPartId]) => {
@@ -1702,6 +1670,11 @@ class CAD {
1702
1670
  await baseModelerAPI.deleteObjects(drawingId, toRemoveOps);
1703
1671
  }
1704
1672
  },
1673
+ getMatePath: async (refId) => {
1674
+ return this.resolve(async ([rRefId]) => {
1675
+ return asmUtils.getMatePath(drawingId, rRefId);
1676
+ }, refId);
1677
+ },
1705
1678
  };
1706
1679
  callback(publicApi);
1707
1680
  resolve(drawingId);
@@ -36,6 +36,7 @@ const classcad_1 = require("@buerli.io/classcad");
36
36
  const core_1 = require("@buerli.io/core");
37
37
  const three_1 = require("three");
38
38
  const BufferGeometryUtils_ = __importStar(require("three/examples/jsm/utils/BufferGeometryUtils"));
39
+ const meshes_1 = require("./utils/meshes");
39
40
  const solidAPI = classcad_1.ccAPI.solid;
40
41
  let BufferGeometryUtils = BufferGeometryUtils_;
41
42
  if (BufferGeometryUtils.BufferGeometryUtils) {
@@ -296,25 +297,28 @@ class CAD {
296
297
  mesh.userData = { id: m.graphicId }; // add graphic id to the userData
297
298
  mesh.geometry = m.geometry;
298
299
  mesh.material = new three_1.MeshStandardMaterial({
299
- color: m.color,
300
- transparent: m.opacity < 1,
301
- opacity: m.opacity,
300
+ color: m.color ? m.color : entity.color,
301
+ transparent: m.opacity ? m.opacity < 1 : entity.opacity < 1,
302
+ opacity: m.opacity ? m.opacity : entity.opacity,
302
303
  });
303
304
  _solid.add(mesh);
304
305
  meshes.push(mesh);
305
306
  });
306
307
  }
307
308
  else {
308
- // Merge all geometries into one mesh
309
- const mesh = new three_1.Mesh();
310
- mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(entity.meshes.map(m => m.geometry));
311
- mesh.material = new three_1.MeshStandardMaterial({
312
- color: entity.meshes[0].color,
313
- transparent: entity.meshes[0].opacity < 1,
314
- opacity: entity.meshes[0].opacity,
309
+ // Merge all geometries into one mesh, sort them by color
310
+ const colorMeshesMap = (0, meshes_1.getDifferentColoredMeshesFromEntity)(entity);
311
+ Object.keys(colorMeshesMap).forEach(key => {
312
+ const mesh = new three_1.Mesh();
313
+ mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(colorMeshesMap[key].meshes.map(m => m.geometry));
314
+ mesh.material = new three_1.MeshStandardMaterial({
315
+ color: colorMeshesMap[key].color,
316
+ transparent: colorMeshesMap[key].opacity < 1,
317
+ opacity: colorMeshesMap[key].opacity,
318
+ });
319
+ _solid.add(mesh); // Add mesh to solid of the scene
320
+ meshes.push(mesh); // Collect mesh to return later
315
321
  });
316
- _solid.add(mesh); // Add mesh to solid of the scene
317
- meshes.push(mesh); // Collect mesh to return later
318
322
  }
319
323
  part.add(_solid); // Add solid to part of the scene
320
324
  _solids.push(_solid); // Collect solid to return later
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDifferentColoredMeshesFromEntity = void 0;
4
+ /**
5
+ * Get all meshes in a map, sorted by their color / opacity
6
+ * @param entity entity to look for the meshes
7
+ * @returns map (key = color/opacity as string, value = object containing the meshes, color and opacity)
8
+ */
9
+ const getDifferentColoredMeshesFromEntity = (entity) => {
10
+ const colorMeshesMap = {};
11
+ entity.meshes.forEach(mesh => {
12
+ const color = mesh.color ? mesh.color : entity.color;
13
+ const opacity = mesh.opacity ? mesh.opacity : entity.opacity;
14
+ const key = (color === null || color === void 0 ? void 0 : color.getHexString()) + (opacity === null || opacity === void 0 ? void 0 : opacity.toString());
15
+ if (colorMeshesMap[key]) {
16
+ colorMeshesMap[key].meshes.push(mesh);
17
+ }
18
+ else {
19
+ colorMeshesMap[key] = { meshes: [mesh], color, opacity };
20
+ }
21
+ });
22
+ return colorMeshesMap;
23
+ };
24
+ exports.getDifferentColoredMeshesFromEntity = getDifferentColoredMeshesFromEntity;
@@ -8,9 +8,10 @@ var __asyncValues = (this && this.__asyncValues) || function (o) {
8
8
  /* eslint-disable max-lines */
9
9
  import { ccAPI, CCClasses, ccUtils, DataType, SVGModusType, } from '@buerli.io/classcad';
10
10
  import { api, getDrawing, lineSegmentsFilter, loopFilter, MathUtils, planeFilter, pointFilter, } from '@buerli.io/core';
11
- import { Group, Mesh, MeshStandardMaterial, Scene, Vector3 } from 'three';
11
+ import { Group, Mesh, MeshStandardMaterial, Scene } from 'three';
12
12
  import * as BufferGeometryUtils_ from 'three/examples/jsm/utils/BufferGeometryUtils';
13
13
  import { waitForSelect } from './utils/selection';
14
+ import { getDifferentColoredMeshesFromEntity } from './utils/meshes';
14
15
  const featureAPI = ccAPI.feature;
15
16
  const sketcherAPI = ccAPI.sketcher;
16
17
  const baseModelerAPI = ccAPI.baseModeler;
@@ -38,33 +39,6 @@ const getDimensionType = (type) => {
38
39
  }
39
40
  return cclass;
40
41
  };
41
- /**
42
- * Transforms the transformation which is local to the ownerId into global
43
- * transformation and returns it.
44
- * @param ownerId node to get the global transformation from
45
- * @param localTransformation transformation local to the owner, will be calculated into global transformation
46
- * @returns the global transformation from local transformation to owner
47
- */
48
- const getGlobalTransformation = (drawingId, ownerId, localTransformation) => {
49
- const lT = localTransformation;
50
- const coordSysOwner = asmUtils.getCoordSysFromNode(drawingId, ownerId);
51
- if (coordSysOwner) {
52
- const origin = [lT[0].x, lT[0].y, lT[0].z];
53
- const xAxis = [lT[1].x, lT[1].y, lT[1].z];
54
- const yAxis = [lT[2].x, lT[2].y, lT[2].z];
55
- const zAxis = new Vector3().crossVectors(new Vector3(lT[1].x, lT[1].y, lT[1].z), new Vector3(lT[2].x, lT[2].y, lT[2].z));
56
- const matrix = MathUtils.convertToMatrix4([origin, xAxis, yAxis, [zAxis.x, zAxis.y, zAxis.z]]);
57
- const transformation = MathUtils.convertToMatrix4(coordSysOwner).clone().multiply(matrix);
58
- const transformationCoords = MathUtils.convertToCoordinateSystem(transformation);
59
- const tC = transformationCoords;
60
- return [
61
- { x: tC[0][0], y: tC[0][1], z: tC[0][2] },
62
- { x: tC[1][0], y: tC[1][1], z: tC[1][2] },
63
- { x: tC[2][0], y: tC[2][1], z: tC[2][2] },
64
- ];
65
- }
66
- return undefined;
67
- };
68
42
  /**
69
43
  * Helps to create the buffer geometry of the given object recursively.
70
44
  * @param object object to create the buffergeometry from
@@ -108,7 +82,7 @@ const createRecursiveBufferGeometry = async (object, drawingId, bufferGeomArray)
108
82
  else if (object.children) {
109
83
  // Assembly
110
84
  for (const child of object.children) {
111
- if (tree[child].class === CCClasses.CCProductReference || tree[child].class === CCClasses.CCProductReferenceET) {
85
+ if (ccUtils.base.isA(tree[child].class, CCClasses.IProductReference)) {
112
86
  await createRecursiveBufferGeometry(tree[child], drawingId, bufferGeomArray);
113
87
  }
114
88
  }
@@ -158,9 +132,9 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
158
132
  mesh.userData = { id: m.graphicId }; // add graphic id to the userData
159
133
  mesh.geometry = m.geometry;
160
134
  mesh.material = new MeshStandardMaterial({
161
- color: m.color,
162
- transparent: m.opacity < 1,
163
- opacity: m.opacity,
135
+ color: m.color ? m.color : cachedEntity.color,
136
+ transparent: m.color ? m.opacity < 1 : cachedEntity.opacity < 1,
137
+ opacity: m.color ? m.opacity : cachedEntity.opacity,
164
138
  });
165
139
  _solid.add(mesh);
166
140
  result.meshes.push(mesh);
@@ -170,13 +144,12 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
170
144
  // Merge all geometries into one mesh, sort them by color
171
145
  const colorMeshesMap = getDifferentColoredMeshesFromEntity(cachedEntity);
172
146
  Object.keys(colorMeshesMap).forEach(key => {
173
- const coloredMeshes = colorMeshesMap[key];
174
147
  const mesh = new Mesh();
175
- mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(coloredMeshes.map(m => m.geometry));
148
+ mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(colorMeshesMap[key].meshes.map(m => m.geometry));
176
149
  mesh.material = new MeshStandardMaterial({
177
- color: coloredMeshes[0].color,
178
- transparent: coloredMeshes[0].opacity < 1,
179
- opacity: coloredMeshes[0].opacity,
150
+ color: colorMeshesMap[key].color,
151
+ transparent: colorMeshesMap[key].opacity < 1,
152
+ opacity: colorMeshesMap[key].opacity,
180
153
  });
181
154
  _solid.add(mesh); // Add mesh to solid of the scene
182
155
  result.meshes.push(mesh); // Collect mesh to return result later
@@ -201,30 +174,12 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
201
174
  result.nodes.push(assembly);
202
175
  root.add(assembly);
203
176
  for (const child of object.children) {
204
- if (tree[child].class === CCClasses.CCProductReference || tree[child].class === CCClasses.CCProductReferenceET) {
177
+ if (ccUtils.base.isA(tree[child].class, CCClasses.IProductReference)) {
205
178
  await createRecursiveScene(tree[child], drawingId, assembly, result, options);
206
179
  }
207
180
  }
208
181
  }
209
182
  };
210
- /**
211
- * Get all meshes in a map, sorted by their color / transparency
212
- * @param entity entity to look for the meshes
213
- * @returns map (key = color/transparency as string, value = meshes array)
214
- */
215
- const getDifferentColoredMeshesFromEntity = (entity) => {
216
- const colorMeshesMap = {};
217
- entity.meshes.forEach(mesh => {
218
- const key = mesh.color.getHexString() + mesh.opacity.toString();
219
- if (colorMeshesMap[key]) {
220
- colorMeshesMap[key].push(mesh);
221
- }
222
- else {
223
- colorMeshesMap[key] = [mesh];
224
- }
225
- });
226
- return colorMeshesMap;
227
- };
228
183
  /**
229
184
  * Helper function to log relevant points to find geometry to the console.
230
185
  * This helps the user to copy the points directly from console to parameter of
@@ -277,8 +232,9 @@ export default class CAD {
277
232
  const nodeParam = {
278
233
  referenceId: rProductId,
279
234
  ownerId: rOwnerId,
280
- transformation: getGlobalTransformation(drawingId, rOwnerId, node.transformation) || node.transformation,
235
+ transformation: node.transformation,
281
236
  name: node.name,
237
+ options: Object.assign(Object.assign({}, node.options), { isLocal: true }), // in non-interactive mode, the transformation is local to the owner
282
238
  };
283
239
  nodesToAdd.push(nodeParam);
284
240
  }
@@ -1115,9 +1071,9 @@ export default class CAD {
1115
1071
  return await assemblyBuilderAPI.createAssemblyAsTemplate(drawingId, name);
1116
1072
  });
1117
1073
  },
1118
- createRootAssembly: (name) => {
1074
+ createRootAssembly: (name, options) => {
1119
1075
  return this.resolve(async ([]) => {
1120
- return await assemblyBuilderAPI.createRootAssembly(drawingId, name);
1076
+ return await assemblyBuilderAPI.createRootAssembly(drawingId, name, options);
1121
1077
  });
1122
1078
  },
1123
1079
  createPart: (name) => {
@@ -1261,6 +1217,18 @@ export default class CAD {
1261
1217
  return null;
1262
1218
  }, refId);
1263
1219
  },
1220
+ getProductOfNode: (refIds) => {
1221
+ return this.resolve(async ([rRefIds]) => {
1222
+ const drawing = getDrawing(drawingId);
1223
+ const tree = drawing.structure.tree;
1224
+ const products = [];
1225
+ for (const rRefId of rRefIds) {
1226
+ const product = asmUtils.findProduct(rRefId, tree);
1227
+ products.push(product);
1228
+ }
1229
+ return products;
1230
+ }, refIds);
1231
+ },
1264
1232
  setCurrentNode: (refId) => {
1265
1233
  return this.resolve(async ([rRefId]) => {
1266
1234
  await assemblyBuilderAPI.setCurrentNode(drawingId, rRefId);
@@ -1571,11 +1539,11 @@ export default class CAD {
1571
1539
  loadFromUrl: (url, filetype) => {
1572
1540
  return baseModelerAPI.loadFromUrl(drawingId, url, filetype, true);
1573
1541
  },
1574
- loadProduct: (content, type) => {
1575
- return assemblyBuilderAPI.loadProduct(drawingId, content, type);
1542
+ loadProduct: (content, type, options) => {
1543
+ return assemblyBuilderAPI.loadProduct(drawingId, content, type, '', options);
1576
1544
  },
1577
- loadProductFromUrl: (url, filetype) => {
1578
- return assemblyBuilderAPI.loadProductFromUrl(drawingId, url, filetype);
1545
+ loadProductFromUrl: (url, filetype, options) => {
1546
+ return assemblyBuilderAPI.loadProductFromUrl(drawingId, url, filetype, options);
1579
1547
  },
1580
1548
  pick: (partId, type, points) => {
1581
1549
  return this.resolve(async ([rPartId]) => {
@@ -1677,6 +1645,11 @@ export default class CAD {
1677
1645
  await baseModelerAPI.deleteObjects(drawingId, toRemoveOps);
1678
1646
  }
1679
1647
  },
1648
+ getMatePath: async (refId) => {
1649
+ return this.resolve(async ([rRefId]) => {
1650
+ return asmUtils.getMatePath(drawingId, rRefId);
1651
+ }, refId);
1652
+ },
1680
1653
  };
1681
1654
  callback(publicApi);
1682
1655
  resolve(drawingId);
@@ -10,6 +10,7 @@ import { ccAPI } from '@buerli.io/classcad';
10
10
  import { api, getDrawing } from '@buerli.io/core';
11
11
  import { Group, Mesh, MeshStandardMaterial, Scene, Shape } from 'three';
12
12
  import * as BufferGeometryUtils_ from 'three/examples/jsm/utils/BufferGeometryUtils';
13
+ import { getDifferentColoredMeshesFromEntity } from './utils/meshes';
13
14
  const solidAPI = ccAPI.solid;
14
15
  let BufferGeometryUtils = BufferGeometryUtils_;
15
16
  if (BufferGeometryUtils.BufferGeometryUtils) {
@@ -269,25 +270,28 @@ export default class CAD {
269
270
  mesh.userData = { id: m.graphicId }; // add graphic id to the userData
270
271
  mesh.geometry = m.geometry;
271
272
  mesh.material = new MeshStandardMaterial({
272
- color: m.color,
273
- transparent: m.opacity < 1,
274
- opacity: m.opacity,
273
+ color: m.color ? m.color : entity.color,
274
+ transparent: m.opacity ? m.opacity < 1 : entity.opacity < 1,
275
+ opacity: m.opacity ? m.opacity : entity.opacity,
275
276
  });
276
277
  _solid.add(mesh);
277
278
  meshes.push(mesh);
278
279
  });
279
280
  }
280
281
  else {
281
- // Merge all geometries into one mesh
282
- const mesh = new Mesh();
283
- mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(entity.meshes.map(m => m.geometry));
284
- mesh.material = new MeshStandardMaterial({
285
- color: entity.meshes[0].color,
286
- transparent: entity.meshes[0].opacity < 1,
287
- opacity: entity.meshes[0].opacity,
282
+ // Merge all geometries into one mesh, sort them by color
283
+ const colorMeshesMap = getDifferentColoredMeshesFromEntity(entity);
284
+ Object.keys(colorMeshesMap).forEach(key => {
285
+ const mesh = new Mesh();
286
+ mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(colorMeshesMap[key].meshes.map(m => m.geometry));
287
+ mesh.material = new MeshStandardMaterial({
288
+ color: colorMeshesMap[key].color,
289
+ transparent: colorMeshesMap[key].opacity < 1,
290
+ opacity: colorMeshesMap[key].opacity,
291
+ });
292
+ _solid.add(mesh); // Add mesh to solid of the scene
293
+ meshes.push(mesh); // Collect mesh to return later
288
294
  });
289
- _solid.add(mesh); // Add mesh to solid of the scene
290
- meshes.push(mesh); // Collect mesh to return later
291
295
  }
292
296
  part.add(_solid); // Add solid to part of the scene
293
297
  _solids.push(_solid); // Collect solid to return later
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Get all meshes in a map, sorted by their color / opacity
3
+ * @param entity entity to look for the meshes
4
+ * @returns map (key = color/opacity as string, value = object containing the meshes, color and opacity)
5
+ */
6
+ export const getDifferentColoredMeshesFromEntity = (entity) => {
7
+ const colorMeshesMap = {};
8
+ entity.meshes.forEach(mesh => {
9
+ const color = mesh.color ? mesh.color : entity.color;
10
+ const opacity = mesh.opacity ? mesh.opacity : entity.opacity;
11
+ const key = (color === null || color === void 0 ? void 0 : color.getHexString()) + (opacity === null || opacity === void 0 ? void 0 : opacity.toString());
12
+ if (colorMeshesMap[key]) {
13
+ colorMeshesMap[key].meshes.push(mesh);
14
+ }
15
+ else {
16
+ colorMeshesMap[key] = { meshes: [mesh], color, opacity };
17
+ }
18
+ });
19
+ return colorMeshesMap;
20
+ };
@@ -1,5 +1,5 @@
1
1
  import { BooleanOperationType, ChamferType, FlipType, ReorientedType, WorkAxisType, WorkCoordSystemType, WorkPlaneType, WorkPointType, ViewType, OrientationType, ExtrusionType, BrepElemType, WorkGeomType, SVGModusType, LimitsParam, LimitedValue } from '@buerli.io/classcad';
2
- import { ObjectID, PointMemValue } from '@buerli.io/core';
2
+ import { ObjectIdent, ObjectID, PointMemValue } from '@buerli.io/core';
3
3
  import { BufferGeometry, Group, Mesh, Scene } from 'three';
4
4
  /**
5
5
  * History based modeling is similar to solid modeling, but it is non-destructive and
@@ -27,17 +27,21 @@ export declare type ApiHistory = {
27
27
  /**
28
28
  * Adds multiple products as nodes to an existing assembly at once
29
29
  * @param nodes array of node parameter objects. See following descriptions.
30
- * @param productId id of the product template to add
31
- * @param ownerId id of the owner where the product template will be added to
30
+ * @param productId id or identifier of the product template to add
31
+ * @param ownerId id or identifier of the owner where the product template will be added to
32
32
  * @param transformation transformation of the product template in x-, y- and z-axis
33
33
  * @param name optional name for adding node
34
+ * @param options optional object containing ident property, to define a identifier for the added node
34
35
  * @example // tbd
35
36
  */
36
37
  addNodes: (...nodes: {
37
- productId: VID;
38
- ownerId: VID;
38
+ productId: VID | ObjectIdent;
39
+ ownerId: VID | ObjectIdent;
39
40
  transformation: Transform;
40
41
  name?: string;
42
+ options?: {
43
+ ident?: ObjectIdent;
44
+ };
41
45
  }[]) => Promise<ObjectID[] | null>;
42
46
  /**
43
47
  * Adds multiple dimensions to products in the 3D view
@@ -615,7 +619,7 @@ export declare type ApiHistory = {
615
619
  }>;
616
620
  /**
617
621
  * Creates one or more expressions.
618
- * @param partId id of part where to create the expression
622
+ * @param partId id or identifier of part where to create the expression
619
623
  * @param members array of members which contain a name and a value. Value can be an expression, e.g. '2 * laenge'
620
624
  * @example
621
625
  * // Creates an expression and links it with the width of the box
@@ -625,7 +629,7 @@ export declare type ApiHistory = {
625
629
  * const geoms = await api.createBufferGeometry(part)
626
630
  * return geoms.map(geom => new THREE.Mesh(geom, new THREE.MeshStandardMaterial()))
627
631
  */
628
- createExpressions: (partId: VID, ...members: {
632
+ createExpressions: (partId: VID | ObjectIdent, ...members: {
629
633
  name: string;
630
634
  value: number | string;
631
635
  }[]) => Promise<boolean>;
@@ -672,6 +676,7 @@ export declare type ApiHistory = {
672
676
  /**
673
677
  * Creates a new rootAssembly. This is the top level assembly.
674
678
  * @param name [optional] name of the root assembly. Default = 'AssemblyRoot'
679
+ * @param options optional object containing ident property, to define a identifier for the created root assembly
675
680
  * @example
676
681
  * // Defines some consts
677
682
  * const orig = { x: 0, y: 0, z: 0 }
@@ -693,7 +698,9 @@ export declare type ApiHistory = {
693
698
  * const geoms = await api.createBufferGeometry(rootAsm)
694
699
  * return geoms.map(geom => new THREE.Mesh(geom, new THREE.MeshStandardMaterial()))
695
700
  */
696
- createRootAssembly: (name?: string) => ID;
701
+ createRootAssembly: (name?: string, options?: {
702
+ ident?: ObjectIdent;
703
+ }) => ID;
697
704
  /**
698
705
  * Creates a new part.
699
706
  * @param name [optional] name of the part. Default = 'Part'
@@ -814,7 +821,7 @@ export declare type ApiHistory = {
814
821
  createWorkPoint: (partId: VID, type: WorkPointType, references: VID[], position: PointMemValue, local: boolean, name?: string) => ID;
815
822
  /**
816
823
  * Deletes an existing expression.
817
- * @param partId id of part to delete expressions from
824
+ * @param partId id or identifier of part to delete expressions from
818
825
  * @param members name of members to delete
819
826
  * @example
820
827
  * // Deletes an expression from part's expression set
@@ -825,7 +832,7 @@ export declare type ApiHistory = {
825
832
  * const geoms = await api.createBufferGeometry(part)
826
833
  * return geoms.map(geom => new THREE.Mesh(geom, new THREE.MeshStandardMaterial()))
827
834
  */
828
- deleteExpressions: (partId: VID, members: string[]) => Promise<boolean>;
835
+ deleteExpressions: (partId: VID | ObjectIdent, members: string[]) => Promise<boolean>;
829
836
  /**
830
837
  * Loads a sketch from a ofb filestream and adds its elements to a new sketch.
831
838
  * The id of this new created sketch will be returned.
@@ -911,6 +918,12 @@ export declare type ApiHistory = {
911
918
  * @example // tbd
912
919
  */
913
920
  getAssemblyNode: (refId: VID, nodeName?: string) => IDs;
921
+ /**
922
+ * Returns the products (array of product ids) of the given nodes (refIds).
923
+ * @param refIds ids of the nodes (product references) to get the product (part or assembly) from
924
+ * @example // tbd
925
+ */
926
+ getProductOfNode: (refIds: VID[]) => IDs;
914
927
  /**
915
928
  * Returns the id of the current product
916
929
  * @example // tbd
@@ -1106,20 +1119,26 @@ export declare type ApiHistory = {
1106
1119
  * Loads a product into the current drawing.
1107
1120
  * @param content data as arraybuffer
1108
1121
  * @param type type of the data to load
1122
+ * @param options optional object containing ident property, to define a identifier for the loaded product
1109
1123
  * @example
1110
1124
  * // Loads an existing product
1111
1125
  * const part = api.loadProduct(arraybuffer, 'ofb')
1112
1126
  * const geoms = await api.createBufferGeometry(part)
1113
1127
  * return geoms.map(geom => new THREE.Mesh(geom, new THREE.MeshStandardMaterial()))
1114
1128
  */
1115
- loadProduct: (content: ArrayBuffer, type: 'ofb' | 'stp') => Promise<number[] | null>;
1129
+ loadProduct: (content: ArrayBuffer, type: 'ofb' | 'stp', options?: {
1130
+ ident?: ObjectIdent;
1131
+ }) => Promise<number[] | null>;
1116
1132
  /**
1117
1133
  * Loads a product from the given URL into the current drawing.
1118
1134
  * @param url The url to load data from.
1119
1135
  * @param filetype The type of data delivered by the url ('ofb', 'stp').
1136
+ * @param options optional object containing ident property, to define a identifier for the loaded product
1120
1137
  * @example // tbd
1121
1138
  */
1122
- loadProductFromUrl: (url: string, filetype: 'ofb' | 'stp') => Promise<number[] | null>;
1139
+ loadProductFromUrl: (url: string, filetype: 'ofb' | 'stp', options?: {
1140
+ ident?: ObjectIdent;
1141
+ }) => Promise<number[] | null>;
1123
1142
  /**
1124
1143
  * Creates a new feature and appends geometry to it. This method can be used to import specific geometry
1125
1144
  * which can be used for further operations like boolean, translations and so on.
@@ -1133,13 +1152,11 @@ export declare type ApiHistory = {
1133
1152
  /**
1134
1153
  * Removes multiple nodes from an assembly node at once
1135
1154
  * @param nodes array of node parameter objects. See following descriptions.
1136
- * @param referenceId id of the node to remove
1137
- * @param ownerId id of the assembly node to remove the node from
1155
+ * @param referenceId id or identifier of the node to remove
1138
1156
  * @example // tbd
1139
1157
  */
1140
1158
  removeNodes: (...nodes: {
1141
- referenceId: VID;
1142
- ownerId: VID;
1159
+ referenceId: VID | ObjectIdent;
1143
1160
  }[]) => Promise<void>;
1144
1161
  /**
1145
1162
  * Transforms the node with referenceId with the given transformation within an assembly
@@ -1189,13 +1206,13 @@ export declare type ApiHistory = {
1189
1206
  * Updates multiple expressions in different parts at once
1190
1207
  *
1191
1208
  * @param expressions array of expression objects containing the part id and the expression to set
1192
- * @param partId id of part to update expression
1209
+ * @param partId id or identifier of part to update expression
1193
1210
  * @param members array of members to update which contain a name and a value. Value can be an expression, e.g. '2 * laenge'
1194
1211
  * @example // tbd
1195
1212
  * @returns true, if updating expressions in all parts was successfull
1196
1213
  */
1197
1214
  setExpressions: (...expressions: {
1198
- partId: number;
1215
+ partId: VID | ObjectIdent;
1199
1216
  members: {
1200
1217
  name: string;
1201
1218
  value: number | string;
@@ -1216,6 +1233,13 @@ export declare type ApiHistory = {
1216
1233
  * @param toOperation all operations, from rollback bar until the id of this operation, will be deleted
1217
1234
  */
1218
1235
  removeOperations: (operations: VID[], toOperation: VID) => Promise<void>;
1236
+ /**
1237
+ * Creates and returns the mate path as array from the given reference id up to the current node.
1238
+ * This helps to get the right path to set constraints between nodes which are located in
1239
+ * subassemblies.
1240
+ * @param refId id of the node to set the constraint on
1241
+ */
1242
+ getMatePath: (refId: VID) => Promise<ObjectID[]>;
1219
1243
  };
1220
1244
  export default class CAD {
1221
1245
  private drawingId;
@@ -0,0 +1,14 @@
1
+ import { ContainerGeometryT, MeshGeometry } from '@buerli.io/core';
2
+ import { Color } from 'three';
3
+ declare type ColorMeshMap = Record<string, {
4
+ meshes: MeshGeometry[];
5
+ color: Color | undefined;
6
+ opacity: number;
7
+ }>;
8
+ /**
9
+ * Get all meshes in a map, sorted by their color / opacity
10
+ * @param entity entity to look for the meshes
11
+ * @returns map (key = color/opacity as string, value = object containing the meshes, color and opacity)
12
+ */
13
+ export declare const getDifferentColoredMeshesFromEntity: (entity: ContainerGeometryT) => ColorMeshMap;
14
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buerli.io/headless",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "A non-manifold CAD workflow for the web",
5
5
  "author": "AWV Informatik AG <info@awv-informatik.ch>",
6
6
  "license": "ISC",
@@ -30,7 +30,7 @@
30
30
  "three": ">=0.138"
31
31
  },
32
32
  "dependencies": {
33
- "@buerli.io/classcad": "0.5.0",
33
+ "@buerli.io/classcad": "0.6.0",
34
34
  "flat-promise": "^1.0.3"
35
35
  }
36
36
  }