@buerli.io/headless 0.5.0-beta.4 → 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,12 +36,16 @@ 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;
42
43
  const assemblyBuilderAPI = classcad_1.ccAPI.assemblyBuilder;
44
+ const drawing2DAPI = classcad_1.ccAPI.drawing2D;
45
+ const geometryAPI = classcad_1.ccAPI.geometry;
43
46
  const baseUtils = classcad_1.ccUtils.base;
44
47
  const asmUtils = classcad_1.ccUtils.assembly;
48
+ const partUtils = classcad_1.ccUtils.part;
45
49
  let BufferGeometryUtils = BufferGeometryUtils_;
46
50
  if (BufferGeometryUtils.BufferGeometryUtils) {
47
51
  BufferGeometryUtils = BufferGeometryUtils.BufferGeometryUtils;
@@ -60,33 +64,6 @@ const getDimensionType = (type) => {
60
64
  }
61
65
  return cclass;
62
66
  };
63
- /**
64
- * Transforms the transformation which is local to the ownerId into global
65
- * transformation and returns it.
66
- * @param ownerId node to get the global transformation from
67
- * @param localTransformation transformation local to the owner, will be calculated into global transformation
68
- * @returns the global transformation from local transformation to owner
69
- */
70
- const getGlobalTransformation = (drawingId, ownerId, localTransformation) => {
71
- const lT = localTransformation;
72
- const coordSysOwner = asmUtils.getCoordSysFromNode(drawingId, ownerId);
73
- if (coordSysOwner) {
74
- const origin = [lT[0].x, lT[0].y, lT[0].z];
75
- const xAxis = [lT[1].x, lT[1].y, lT[1].z];
76
- const yAxis = [lT[2].x, lT[2].y, lT[2].z];
77
- 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));
78
- const matrix = core_1.MathUtils.convertToMatrix4([origin, xAxis, yAxis, [zAxis.x, zAxis.y, zAxis.z]]);
79
- const transformation = core_1.MathUtils.convertToMatrix4(coordSysOwner).clone().multiply(matrix);
80
- const transformationCoords = core_1.MathUtils.convertToCoordinateSystem(transformation);
81
- const tC = transformationCoords;
82
- return [
83
- { x: tC[0][0], y: tC[0][1], z: tC[0][2] },
84
- { x: tC[1][0], y: tC[1][1], z: tC[1][2] },
85
- { x: tC[2][0], y: tC[2][1], z: tC[2][2] },
86
- ];
87
- }
88
- return undefined;
89
- };
90
67
  /**
91
68
  * Helps to create the buffer geometry of the given object recursively.
92
69
  * @param object object to create the buffergeometry from
@@ -108,7 +85,7 @@ const createRecursiveBufferGeometry = async (object, drawingId, bufferGeomArray)
108
85
  }
109
86
  else {
110
87
  // else get visualisation from classcad
111
- await classcad_1.ccAPI.baseModeler.requestVisualisationOfEntities(drawingId, [solid]);
88
+ await baseModelerAPI.requestVisualisationOfEntities(drawingId, [solid]);
112
89
  cDrawing = (0, core_1.getDrawing)(drawingId); // get current drawing state after request
113
90
  cachedSolid = cDrawing.geometry.cache[solid];
114
91
  if (cachedSolid) {
@@ -130,7 +107,7 @@ const createRecursiveBufferGeometry = async (object, drawingId, bufferGeomArray)
130
107
  else if (object.children) {
131
108
  // Assembly
132
109
  for (const child of object.children) {
133
- 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)) {
134
111
  await createRecursiveBufferGeometry(tree[child], drawingId, bufferGeomArray);
135
112
  }
136
113
  }
@@ -163,7 +140,7 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
163
140
  let cachedEntity = cDrawing.geometry.cache[entity];
164
141
  if (!cachedEntity) {
165
142
  // else get visualisation from classcad
166
- await classcad_1.ccAPI.baseModeler.requestVisualisationOfEntities(drawingId, [entity]);
143
+ await baseModelerAPI.requestVisualisationOfEntities(drawingId, [entity]);
167
144
  cDrawing = (0, core_1.getDrawing)(drawingId); // get current drawing state after request
168
145
  cachedEntity = cDrawing.geometry.cache[entity];
169
146
  }
@@ -180,9 +157,9 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
180
157
  mesh.userData = { id: m.graphicId }; // add graphic id to the userData
181
158
  mesh.geometry = m.geometry;
182
159
  mesh.material = new three_1.MeshStandardMaterial({
183
- color: m.color,
184
- transparent: m.opacity < 1,
185
- 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,
186
163
  });
187
164
  _solid.add(mesh);
188
165
  result.meshes.push(mesh);
@@ -190,15 +167,14 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
190
167
  }
191
168
  else {
192
169
  // Merge all geometries into one mesh, sort them by color
193
- const colorMeshesMap = getDifferentColoredMeshesFromEntity(cachedEntity);
170
+ const colorMeshesMap = (0, meshes_1.getDifferentColoredMeshesFromEntity)(cachedEntity);
194
171
  Object.keys(colorMeshesMap).forEach(key => {
195
- const coloredMeshes = colorMeshesMap[key];
196
172
  const mesh = new three_1.Mesh();
197
- mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(coloredMeshes.map(m => m.geometry));
173
+ mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(colorMeshesMap[key].meshes.map(m => m.geometry));
198
174
  mesh.material = new three_1.MeshStandardMaterial({
199
- color: coloredMeshes[0].color,
200
- transparent: coloredMeshes[0].opacity < 1,
201
- opacity: coloredMeshes[0].opacity,
175
+ color: colorMeshesMap[key].color,
176
+ transparent: colorMeshesMap[key].opacity < 1,
177
+ opacity: colorMeshesMap[key].opacity,
202
178
  });
203
179
  _solid.add(mesh); // Add mesh to solid of the scene
204
180
  result.meshes.push(mesh); // Collect mesh to return result later
@@ -223,30 +199,12 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
223
199
  result.nodes.push(assembly);
224
200
  root.add(assembly);
225
201
  for (const child of object.children) {
226
- 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)) {
227
203
  await createRecursiveScene(tree[child], drawingId, assembly, result, options);
228
204
  }
229
205
  }
230
206
  }
231
207
  };
232
- /**
233
- * Get all meshes in a map, sorted by their color / transparency
234
- * @param entity entity to look for the meshes
235
- * @returns map (key = color/transparency as string, value = meshes array)
236
- */
237
- const getDifferentColoredMeshesFromEntity = (entity) => {
238
- const colorMeshesMap = {};
239
- entity.meshes.forEach(mesh => {
240
- const key = mesh.color.getHexString() + mesh.opacity.toString();
241
- if (colorMeshesMap[key]) {
242
- colorMeshesMap[key].push(mesh);
243
- }
244
- else {
245
- colorMeshesMap[key] = [mesh];
246
- }
247
- });
248
- return colorMeshesMap;
249
- };
250
208
  /**
251
209
  * Helper function to log relevant points to find geometry to the console.
252
210
  * This helps the user to copy the points directly from console to parameter of
@@ -299,8 +257,9 @@ class CAD {
299
257
  const nodeParam = {
300
258
  referenceId: rProductId,
301
259
  ownerId: rOwnerId,
302
- transformation: getGlobalTransformation(drawingId, rOwnerId, node.transformation) || node.transformation,
260
+ transformation: node.transformation,
303
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
304
263
  };
305
264
  nodesToAdd.push(nodeParam);
306
265
  }
@@ -312,7 +271,7 @@ class CAD {
312
271
  }
313
272
  finally { if (e_1) throw e_1.error; }
314
273
  }
315
- return classcad_1.ccAPI.assemblyBuilder.addNodes(drawingId, nodesToAdd);
274
+ return assemblyBuilderAPI.addNodes(drawingId, nodesToAdd);
316
275
  },
317
276
  addDimensions: async (...dimensions) => {
318
277
  var e_2, _a;
@@ -349,13 +308,13 @@ class CAD {
349
308
  }
350
309
  finally { if (e_2) throw e_2.error; }
351
310
  }
352
- return classcad_1.ccAPI.drawing2D.addDimensions(drawingId, dimParamsToAdd);
311
+ return drawing2DAPI.addDimensions(drawingId, dimParamsToAdd);
353
312
  },
354
313
  create2DViews: (productId, viewTypes, viewOptions) => {
355
314
  return this.resolve(async ([rProductId]) => {
356
- const viewIds = await classcad_1.ccAPI.drawing2D.create2DViews(drawingId, rProductId, viewTypes, viewOptions);
315
+ const viewIds = await drawing2DAPI.create2DViews(drawingId, rProductId, viewTypes, viewOptions);
357
316
  if (viewIds !== null) {
358
- await classcad_1.ccAPI.drawing2D.centerAllViews(drawingId, rProductId, viewTypes);
317
+ await drawing2DAPI.centerAllViews(drawingId, rProductId, viewTypes);
359
318
  return viewIds;
360
319
  }
361
320
  return null;
@@ -363,30 +322,30 @@ class CAD {
363
322
  },
364
323
  getBoundaryBoxFromViews: (productId, viewTypes) => {
365
324
  return this.resolve(async ([rProductId]) => {
366
- const bbs = await classcad_1.ccAPI.drawing2D.getBoundaryBoxFromViews(drawingId, rProductId, viewTypes);
325
+ const bbs = await drawing2DAPI.getBoundaryBoxFromViews(drawingId, rProductId, viewTypes);
367
326
  return bbs;
368
327
  }, productId);
369
328
  },
370
329
  place2DViews: (productId, viewPositions) => {
371
330
  return this.resolve(async ([rProductId]) => {
372
- return classcad_1.ccAPI.drawing2D.place2DViews(drawingId, rProductId, viewPositions);
331
+ return drawing2DAPI.place2DViews(drawingId, rProductId, viewPositions);
373
332
  }, productId);
374
333
  },
375
334
  exportDXF: (productId, dxfTemplateFilename) => {
376
335
  return this.resolve(async ([rProductId]) => {
377
- return classcad_1.ccAPI.drawing2D.exportDXF(drawingId, rProductId, dxfTemplateFilename);
336
+ return drawing2DAPI.exportDXF(drawingId, rProductId, dxfTemplateFilename);
378
337
  }, productId);
379
338
  },
380
339
  exportSVG: (productId, modus, renderSize, dxfTemplateFilename) => {
381
340
  return this.resolve(async ([rProductId]) => {
382
341
  modus = modus ? modus : classcad_1.SVGModusType.FIT_WHOLE_DRAWING;
383
342
  const renderSizeParam = (renderSize === null || renderSize === void 0 ? void 0 : renderSize.x) && (renderSize === null || renderSize === void 0 ? void 0 : renderSize.y) ? [renderSize.x, renderSize.y] : undefined;
384
- return classcad_1.ccAPI.drawing2D.exportSVG(drawingId, rProductId, modus, renderSizeParam, dxfTemplateFilename);
343
+ return drawing2DAPI.exportSVG(drawingId, rProductId, modus, renderSizeParam, dxfTemplateFilename);
385
344
  }, productId);
386
345
  },
387
346
  removeDimensions: (dimensionIds) => {
388
347
  return this.resolve(async ([...rDimensionIds]) => {
389
- return classcad_1.ccAPI.drawing2D.removeDimensions(drawingId, rDimensionIds);
348
+ return drawing2DAPI.removeDimensions(drawingId, rDimensionIds);
390
349
  }, ...dimensionIds);
391
350
  },
392
351
  linearPattern: (partId, entities, references1, params1, references2, params2) => {
@@ -477,14 +436,11 @@ class CAD {
477
436
  return null;
478
437
  }, partId, entities, ...references);
479
438
  },
480
- extrusion: (partId, sketchId, type, limit1, limit2, taperAngle, direction, capEnds) => {
481
- return this.resolve(async ([rPartId, rSketchId]) => {
439
+ extrusion: (partId, sketchOrRegionIds, type, limit1, limit2, taperAngle, direction, capEnds) => {
440
+ return this.resolve(async ([rPartId, rSketchOrRegionIds]) => {
482
441
  const extrusion = await featureAPI.createExtrusion(drawingId, rPartId);
483
442
  if (extrusion) {
484
- const cDrawing = await (0, core_1.getDrawing)(drawingId);
485
- const sketchLines = [];
486
- // TODO: Which sketch lines need to be included, is CCClasses.CCCurve and its derivation enough?
487
- sketchLines.push(...baseUtils.getChildren(rSketchId, classcad_1.CCClasses.CCCurve, cDrawing.structure.tree));
443
+ const sketchLines = partUtils.getSketchlines(drawingId, rSketchOrRegionIds);
488
444
  if (sketchLines) {
489
445
  const limit1Param = { value: limit1, isExpr: typeof limit1 === 'string' };
490
446
  const limit2Param = { value: limit2, isExpr: typeof limit2 === 'string' };
@@ -500,16 +456,13 @@ class CAD {
500
456
  return extrusion;
501
457
  }
502
458
  }
503
- }, partId, sketchId);
459
+ }, partId, sketchOrRegionIds);
504
460
  },
505
- revolve: (partId, sketchId, axisIds, angle1, angle2, inverted) => {
506
- return this.resolve(async ([rPartId, rSketchId, ...rAxisIds]) => {
461
+ revolve: (partId, sketchOrRegionIds, axisIds, angle1, angle2, inverted) => {
462
+ return this.resolve(async ([rPartId, rSketchOrRegionIds, ...rAxisIds]) => {
507
463
  const revolve = await featureAPI.createRevolve(drawingId, rPartId);
508
464
  if (revolve) {
509
- const cDrawing = await (0, core_1.getDrawing)(drawingId);
510
- const sketchLines = [];
511
- sketchLines.push(...baseUtils.getChildren(rSketchId, classcad_1.CCClasses.CCCircle, cDrawing.structure.tree));
512
- sketchLines.push(...baseUtils.getChildren(rSketchId, classcad_1.CCClasses.CCLine, cDrawing.structure.tree));
465
+ const sketchLines = partUtils.getSketchlines(drawingId, rSketchOrRegionIds);
513
466
  if (sketchLines) {
514
467
  const angle1Param = { value: angle1, isExpr: typeof angle1 === 'string' };
515
468
  const angle2Param = { value: angle2, isExpr: typeof angle2 === 'string' };
@@ -517,7 +470,7 @@ class CAD {
517
470
  return revolve;
518
471
  }
519
472
  }
520
- }, partId, sketchId, ...axisIds);
473
+ }, partId, sketchOrRegionIds, ...axisIds);
521
474
  },
522
475
  boolean: (partId, type, entities) => {
523
476
  return this.resolve(async ([rPartId, rEntities]) => {
@@ -1143,9 +1096,9 @@ class CAD {
1143
1096
  return await assemblyBuilderAPI.createAssemblyAsTemplate(drawingId, name);
1144
1097
  });
1145
1098
  },
1146
- createRootAssembly: (name) => {
1099
+ createRootAssembly: (name, options) => {
1147
1100
  return this.resolve(async ([]) => {
1148
- return await assemblyBuilderAPI.createRootAssembly(drawingId, name);
1101
+ return await assemblyBuilderAPI.createRootAssembly(drawingId, name, options);
1149
1102
  });
1150
1103
  },
1151
1104
  createPart: (name) => {
@@ -1257,11 +1210,11 @@ class CAD {
1257
1210
  break;
1258
1211
  }
1259
1212
  const geometries = positions
1260
- ? await classcad_1.ccAPI.geometry.findGeometriesByPoints(drawingId, rPartId, type, positions)
1213
+ ? await geometryAPI.findGeometriesByPoints(drawingId, rPartId, type, positions)
1261
1214
  : await (0, selection_1.waitForSelect)(length, filter, (resolveSelection, items, diff) => {
1262
1215
  if (items.length > length - 1) {
1263
1216
  resolveSelection(items.map(i => i.data.graphicId));
1264
- classcad_1.ccAPI.geometry
1217
+ geometryAPI
1265
1218
  .getPointsByGeometries(drawingId, items.map(i => i.data.graphicId))
1266
1219
  .then(points => {
1267
1220
  logPoints(points);
@@ -1289,6 +1242,18 @@ class CAD {
1289
1242
  return null;
1290
1243
  }, refId);
1291
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
+ },
1292
1257
  setCurrentNode: (refId) => {
1293
1258
  return this.resolve(async ([rRefId]) => {
1294
1259
  await assemblyBuilderAPI.setCurrentNode(drawingId, rRefId);
@@ -1311,7 +1276,7 @@ class CAD {
1311
1276
  },
1312
1277
  setCurrentProduct: (productId) => {
1313
1278
  return this.resolve(async ([rProductId]) => {
1314
- await classcad_1.ccAPI.baseModeler.setCurrentProduct(drawingId, rProductId);
1279
+ await baseModelerAPI.setCurrentProduct(drawingId, rProductId);
1315
1280
  }, productId);
1316
1281
  },
1317
1282
  getCurrentProduct: () => {
@@ -1339,6 +1304,15 @@ class CAD {
1339
1304
  return null;
1340
1305
  }, refId);
1341
1306
  },
1307
+ getSketchRegion: (refId, sketchRegionName) => {
1308
+ return this.resolve(async ([rRefId]) => {
1309
+ const sRIds = partUtils.getSketchRegion(drawingId, rRefId, sketchRegionName);
1310
+ if (sRIds != undefined) {
1311
+ return Array.isArray(sRIds) ? sRIds : [sRIds];
1312
+ }
1313
+ return null;
1314
+ }, refId);
1315
+ },
1342
1316
  getWorkGeometry: (refId, type, wgName) => {
1343
1317
  return this.resolve(async ([rRefId]) => {
1344
1318
  const wgIds = asmUtils.getWorkGeometry(drawingId, rRefId, type, wgName);
@@ -1579,22 +1553,22 @@ class CAD {
1579
1553
  }, translationId);
1580
1554
  },
1581
1555
  save: (type) => {
1582
- return classcad_1.ccAPI.baseModeler.save(drawingId, type);
1556
+ return baseModelerAPI.save(drawingId, type);
1583
1557
  },
1584
1558
  saveToUrl: (url, filetype) => {
1585
- return classcad_1.ccAPI.baseModeler.saveToUrl(drawingId, url, filetype);
1559
+ return baseModelerAPI.saveToUrl(drawingId, url, filetype);
1586
1560
  },
1587
1561
  load: (content, type) => {
1588
- return classcad_1.ccAPI.baseModeler.load(drawingId, content, type);
1562
+ return baseModelerAPI.load(drawingId, content, type);
1589
1563
  },
1590
1564
  loadFromUrl: (url, filetype) => {
1591
- return classcad_1.ccAPI.baseModeler.loadFromUrl(drawingId, url, filetype, true);
1565
+ return baseModelerAPI.loadFromUrl(drawingId, url, filetype, true);
1592
1566
  },
1593
- loadProduct: (content, type) => {
1594
- return classcad_1.ccAPI.assemblyBuilder.loadProduct(drawingId, content, type);
1567
+ loadProduct: (content, type, options) => {
1568
+ return assemblyBuilderAPI.loadProduct(drawingId, content, type, '', options);
1595
1569
  },
1596
- loadProductFromUrl: (url, filetype) => {
1597
- return classcad_1.ccAPI.assemblyBuilder.loadProductFromUrl(drawingId, url, filetype);
1570
+ loadProductFromUrl: (url, filetype, options) => {
1571
+ return assemblyBuilderAPI.loadProductFromUrl(drawingId, url, filetype, options);
1598
1572
  },
1599
1573
  pick: (partId, type, points) => {
1600
1574
  return this.resolve(async ([rPartId]) => {
@@ -1696,6 +1670,11 @@ class CAD {
1696
1670
  await baseModelerAPI.deleteObjects(drawingId, toRemoveOps);
1697
1671
  }
1698
1672
  },
1673
+ getMatePath: async (refId) => {
1674
+ return this.resolve(async ([rRefId]) => {
1675
+ return asmUtils.getMatePath(drawingId, rRefId);
1676
+ }, refId);
1677
+ },
1699
1678
  };
1700
1679
  callback(publicApi);
1701
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,15 +8,19 @@ 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;
17
18
  const assemblyBuilderAPI = ccAPI.assemblyBuilder;
19
+ const drawing2DAPI = ccAPI.drawing2D;
20
+ const geometryAPI = ccAPI.geometry;
18
21
  const baseUtils = ccUtils.base;
19
22
  const asmUtils = ccUtils.assembly;
23
+ const partUtils = ccUtils.part;
20
24
  let BufferGeometryUtils = BufferGeometryUtils_;
21
25
  if (BufferGeometryUtils.BufferGeometryUtils) {
22
26
  BufferGeometryUtils = BufferGeometryUtils.BufferGeometryUtils;
@@ -35,33 +39,6 @@ const getDimensionType = (type) => {
35
39
  }
36
40
  return cclass;
37
41
  };
38
- /**
39
- * Transforms the transformation which is local to the ownerId into global
40
- * transformation and returns it.
41
- * @param ownerId node to get the global transformation from
42
- * @param localTransformation transformation local to the owner, will be calculated into global transformation
43
- * @returns the global transformation from local transformation to owner
44
- */
45
- const getGlobalTransformation = (drawingId, ownerId, localTransformation) => {
46
- const lT = localTransformation;
47
- const coordSysOwner = asmUtils.getCoordSysFromNode(drawingId, ownerId);
48
- if (coordSysOwner) {
49
- const origin = [lT[0].x, lT[0].y, lT[0].z];
50
- const xAxis = [lT[1].x, lT[1].y, lT[1].z];
51
- const yAxis = [lT[2].x, lT[2].y, lT[2].z];
52
- 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));
53
- const matrix = MathUtils.convertToMatrix4([origin, xAxis, yAxis, [zAxis.x, zAxis.y, zAxis.z]]);
54
- const transformation = MathUtils.convertToMatrix4(coordSysOwner).clone().multiply(matrix);
55
- const transformationCoords = MathUtils.convertToCoordinateSystem(transformation);
56
- const tC = transformationCoords;
57
- return [
58
- { x: tC[0][0], y: tC[0][1], z: tC[0][2] },
59
- { x: tC[1][0], y: tC[1][1], z: tC[1][2] },
60
- { x: tC[2][0], y: tC[2][1], z: tC[2][2] },
61
- ];
62
- }
63
- return undefined;
64
- };
65
42
  /**
66
43
  * Helps to create the buffer geometry of the given object recursively.
67
44
  * @param object object to create the buffergeometry from
@@ -83,7 +60,7 @@ const createRecursiveBufferGeometry = async (object, drawingId, bufferGeomArray)
83
60
  }
84
61
  else {
85
62
  // else get visualisation from classcad
86
- await ccAPI.baseModeler.requestVisualisationOfEntities(drawingId, [solid]);
63
+ await baseModelerAPI.requestVisualisationOfEntities(drawingId, [solid]);
87
64
  cDrawing = getDrawing(drawingId); // get current drawing state after request
88
65
  cachedSolid = cDrawing.geometry.cache[solid];
89
66
  if (cachedSolid) {
@@ -105,7 +82,7 @@ const createRecursiveBufferGeometry = async (object, drawingId, bufferGeomArray)
105
82
  else if (object.children) {
106
83
  // Assembly
107
84
  for (const child of object.children) {
108
- if (tree[child].class === CCClasses.CCProductReference || tree[child].class === CCClasses.CCProductReferenceET) {
85
+ if (ccUtils.base.isA(tree[child].class, CCClasses.IProductReference)) {
109
86
  await createRecursiveBufferGeometry(tree[child], drawingId, bufferGeomArray);
110
87
  }
111
88
  }
@@ -138,7 +115,7 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
138
115
  let cachedEntity = cDrawing.geometry.cache[entity];
139
116
  if (!cachedEntity) {
140
117
  // else get visualisation from classcad
141
- await ccAPI.baseModeler.requestVisualisationOfEntities(drawingId, [entity]);
118
+ await baseModelerAPI.requestVisualisationOfEntities(drawingId, [entity]);
142
119
  cDrawing = getDrawing(drawingId); // get current drawing state after request
143
120
  cachedEntity = cDrawing.geometry.cache[entity];
144
121
  }
@@ -155,9 +132,9 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
155
132
  mesh.userData = { id: m.graphicId }; // add graphic id to the userData
156
133
  mesh.geometry = m.geometry;
157
134
  mesh.material = new MeshStandardMaterial({
158
- color: m.color,
159
- transparent: m.opacity < 1,
160
- 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,
161
138
  });
162
139
  _solid.add(mesh);
163
140
  result.meshes.push(mesh);
@@ -167,13 +144,12 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
167
144
  // Merge all geometries into one mesh, sort them by color
168
145
  const colorMeshesMap = getDifferentColoredMeshesFromEntity(cachedEntity);
169
146
  Object.keys(colorMeshesMap).forEach(key => {
170
- const coloredMeshes = colorMeshesMap[key];
171
147
  const mesh = new Mesh();
172
- mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(coloredMeshes.map(m => m.geometry));
148
+ mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(colorMeshesMap[key].meshes.map(m => m.geometry));
173
149
  mesh.material = new MeshStandardMaterial({
174
- color: coloredMeshes[0].color,
175
- transparent: coloredMeshes[0].opacity < 1,
176
- opacity: coloredMeshes[0].opacity,
150
+ color: colorMeshesMap[key].color,
151
+ transparent: colorMeshesMap[key].opacity < 1,
152
+ opacity: colorMeshesMap[key].opacity,
177
153
  });
178
154
  _solid.add(mesh); // Add mesh to solid of the scene
179
155
  result.meshes.push(mesh); // Collect mesh to return result later
@@ -198,30 +174,12 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
198
174
  result.nodes.push(assembly);
199
175
  root.add(assembly);
200
176
  for (const child of object.children) {
201
- if (tree[child].class === CCClasses.CCProductReference || tree[child].class === CCClasses.CCProductReferenceET) {
177
+ if (ccUtils.base.isA(tree[child].class, CCClasses.IProductReference)) {
202
178
  await createRecursiveScene(tree[child], drawingId, assembly, result, options);
203
179
  }
204
180
  }
205
181
  }
206
182
  };
207
- /**
208
- * Get all meshes in a map, sorted by their color / transparency
209
- * @param entity entity to look for the meshes
210
- * @returns map (key = color/transparency as string, value = meshes array)
211
- */
212
- const getDifferentColoredMeshesFromEntity = (entity) => {
213
- const colorMeshesMap = {};
214
- entity.meshes.forEach(mesh => {
215
- const key = mesh.color.getHexString() + mesh.opacity.toString();
216
- if (colorMeshesMap[key]) {
217
- colorMeshesMap[key].push(mesh);
218
- }
219
- else {
220
- colorMeshesMap[key] = [mesh];
221
- }
222
- });
223
- return colorMeshesMap;
224
- };
225
183
  /**
226
184
  * Helper function to log relevant points to find geometry to the console.
227
185
  * This helps the user to copy the points directly from console to parameter of
@@ -274,8 +232,9 @@ export default class CAD {
274
232
  const nodeParam = {
275
233
  referenceId: rProductId,
276
234
  ownerId: rOwnerId,
277
- transformation: getGlobalTransformation(drawingId, rOwnerId, node.transformation) || node.transformation,
235
+ transformation: node.transformation,
278
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
279
238
  };
280
239
  nodesToAdd.push(nodeParam);
281
240
  }
@@ -287,7 +246,7 @@ export default class CAD {
287
246
  }
288
247
  finally { if (e_1) throw e_1.error; }
289
248
  }
290
- return ccAPI.assemblyBuilder.addNodes(drawingId, nodesToAdd);
249
+ return assemblyBuilderAPI.addNodes(drawingId, nodesToAdd);
291
250
  },
292
251
  addDimensions: async (...dimensions) => {
293
252
  var e_2, _a;
@@ -324,13 +283,13 @@ export default class CAD {
324
283
  }
325
284
  finally { if (e_2) throw e_2.error; }
326
285
  }
327
- return ccAPI.drawing2D.addDimensions(drawingId, dimParamsToAdd);
286
+ return drawing2DAPI.addDimensions(drawingId, dimParamsToAdd);
328
287
  },
329
288
  create2DViews: (productId, viewTypes, viewOptions) => {
330
289
  return this.resolve(async ([rProductId]) => {
331
- const viewIds = await ccAPI.drawing2D.create2DViews(drawingId, rProductId, viewTypes, viewOptions);
290
+ const viewIds = await drawing2DAPI.create2DViews(drawingId, rProductId, viewTypes, viewOptions);
332
291
  if (viewIds !== null) {
333
- await ccAPI.drawing2D.centerAllViews(drawingId, rProductId, viewTypes);
292
+ await drawing2DAPI.centerAllViews(drawingId, rProductId, viewTypes);
334
293
  return viewIds;
335
294
  }
336
295
  return null;
@@ -338,30 +297,30 @@ export default class CAD {
338
297
  },
339
298
  getBoundaryBoxFromViews: (productId, viewTypes) => {
340
299
  return this.resolve(async ([rProductId]) => {
341
- const bbs = await ccAPI.drawing2D.getBoundaryBoxFromViews(drawingId, rProductId, viewTypes);
300
+ const bbs = await drawing2DAPI.getBoundaryBoxFromViews(drawingId, rProductId, viewTypes);
342
301
  return bbs;
343
302
  }, productId);
344
303
  },
345
304
  place2DViews: (productId, viewPositions) => {
346
305
  return this.resolve(async ([rProductId]) => {
347
- return ccAPI.drawing2D.place2DViews(drawingId, rProductId, viewPositions);
306
+ return drawing2DAPI.place2DViews(drawingId, rProductId, viewPositions);
348
307
  }, productId);
349
308
  },
350
309
  exportDXF: (productId, dxfTemplateFilename) => {
351
310
  return this.resolve(async ([rProductId]) => {
352
- return ccAPI.drawing2D.exportDXF(drawingId, rProductId, dxfTemplateFilename);
311
+ return drawing2DAPI.exportDXF(drawingId, rProductId, dxfTemplateFilename);
353
312
  }, productId);
354
313
  },
355
314
  exportSVG: (productId, modus, renderSize, dxfTemplateFilename) => {
356
315
  return this.resolve(async ([rProductId]) => {
357
316
  modus = modus ? modus : SVGModusType.FIT_WHOLE_DRAWING;
358
317
  const renderSizeParam = (renderSize === null || renderSize === void 0 ? void 0 : renderSize.x) && (renderSize === null || renderSize === void 0 ? void 0 : renderSize.y) ? [renderSize.x, renderSize.y] : undefined;
359
- return ccAPI.drawing2D.exportSVG(drawingId, rProductId, modus, renderSizeParam, dxfTemplateFilename);
318
+ return drawing2DAPI.exportSVG(drawingId, rProductId, modus, renderSizeParam, dxfTemplateFilename);
360
319
  }, productId);
361
320
  },
362
321
  removeDimensions: (dimensionIds) => {
363
322
  return this.resolve(async ([...rDimensionIds]) => {
364
- return ccAPI.drawing2D.removeDimensions(drawingId, rDimensionIds);
323
+ return drawing2DAPI.removeDimensions(drawingId, rDimensionIds);
365
324
  }, ...dimensionIds);
366
325
  },
367
326
  linearPattern: (partId, entities, references1, params1, references2, params2) => {
@@ -452,14 +411,11 @@ export default class CAD {
452
411
  return null;
453
412
  }, partId, entities, ...references);
454
413
  },
455
- extrusion: (partId, sketchId, type, limit1, limit2, taperAngle, direction, capEnds) => {
456
- return this.resolve(async ([rPartId, rSketchId]) => {
414
+ extrusion: (partId, sketchOrRegionIds, type, limit1, limit2, taperAngle, direction, capEnds) => {
415
+ return this.resolve(async ([rPartId, rSketchOrRegionIds]) => {
457
416
  const extrusion = await featureAPI.createExtrusion(drawingId, rPartId);
458
417
  if (extrusion) {
459
- const cDrawing = await getDrawing(drawingId);
460
- const sketchLines = [];
461
- // TODO: Which sketch lines need to be included, is CCClasses.CCCurve and its derivation enough?
462
- sketchLines.push(...baseUtils.getChildren(rSketchId, CCClasses.CCCurve, cDrawing.structure.tree));
418
+ const sketchLines = partUtils.getSketchlines(drawingId, rSketchOrRegionIds);
463
419
  if (sketchLines) {
464
420
  const limit1Param = { value: limit1, isExpr: typeof limit1 === 'string' };
465
421
  const limit2Param = { value: limit2, isExpr: typeof limit2 === 'string' };
@@ -475,16 +431,13 @@ export default class CAD {
475
431
  return extrusion;
476
432
  }
477
433
  }
478
- }, partId, sketchId);
434
+ }, partId, sketchOrRegionIds);
479
435
  },
480
- revolve: (partId, sketchId, axisIds, angle1, angle2, inverted) => {
481
- return this.resolve(async ([rPartId, rSketchId, ...rAxisIds]) => {
436
+ revolve: (partId, sketchOrRegionIds, axisIds, angle1, angle2, inverted) => {
437
+ return this.resolve(async ([rPartId, rSketchOrRegionIds, ...rAxisIds]) => {
482
438
  const revolve = await featureAPI.createRevolve(drawingId, rPartId);
483
439
  if (revolve) {
484
- const cDrawing = await getDrawing(drawingId);
485
- const sketchLines = [];
486
- sketchLines.push(...baseUtils.getChildren(rSketchId, CCClasses.CCCircle, cDrawing.structure.tree));
487
- sketchLines.push(...baseUtils.getChildren(rSketchId, CCClasses.CCLine, cDrawing.structure.tree));
440
+ const sketchLines = partUtils.getSketchlines(drawingId, rSketchOrRegionIds);
488
441
  if (sketchLines) {
489
442
  const angle1Param = { value: angle1, isExpr: typeof angle1 === 'string' };
490
443
  const angle2Param = { value: angle2, isExpr: typeof angle2 === 'string' };
@@ -492,7 +445,7 @@ export default class CAD {
492
445
  return revolve;
493
446
  }
494
447
  }
495
- }, partId, sketchId, ...axisIds);
448
+ }, partId, sketchOrRegionIds, ...axisIds);
496
449
  },
497
450
  boolean: (partId, type, entities) => {
498
451
  return this.resolve(async ([rPartId, rEntities]) => {
@@ -1118,9 +1071,9 @@ export default class CAD {
1118
1071
  return await assemblyBuilderAPI.createAssemblyAsTemplate(drawingId, name);
1119
1072
  });
1120
1073
  },
1121
- createRootAssembly: (name) => {
1074
+ createRootAssembly: (name, options) => {
1122
1075
  return this.resolve(async ([]) => {
1123
- return await assemblyBuilderAPI.createRootAssembly(drawingId, name);
1076
+ return await assemblyBuilderAPI.createRootAssembly(drawingId, name, options);
1124
1077
  });
1125
1078
  },
1126
1079
  createPart: (name) => {
@@ -1232,11 +1185,11 @@ export default class CAD {
1232
1185
  break;
1233
1186
  }
1234
1187
  const geometries = positions
1235
- ? await ccAPI.geometry.findGeometriesByPoints(drawingId, rPartId, type, positions)
1188
+ ? await geometryAPI.findGeometriesByPoints(drawingId, rPartId, type, positions)
1236
1189
  : await waitForSelect(length, filter, (resolveSelection, items, diff) => {
1237
1190
  if (items.length > length - 1) {
1238
1191
  resolveSelection(items.map(i => i.data.graphicId));
1239
- ccAPI.geometry
1192
+ geometryAPI
1240
1193
  .getPointsByGeometries(drawingId, items.map(i => i.data.graphicId))
1241
1194
  .then(points => {
1242
1195
  logPoints(points);
@@ -1264,6 +1217,18 @@ export default class CAD {
1264
1217
  return null;
1265
1218
  }, refId);
1266
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
+ },
1267
1232
  setCurrentNode: (refId) => {
1268
1233
  return this.resolve(async ([rRefId]) => {
1269
1234
  await assemblyBuilderAPI.setCurrentNode(drawingId, rRefId);
@@ -1286,7 +1251,7 @@ export default class CAD {
1286
1251
  },
1287
1252
  setCurrentProduct: (productId) => {
1288
1253
  return this.resolve(async ([rProductId]) => {
1289
- await ccAPI.baseModeler.setCurrentProduct(drawingId, rProductId);
1254
+ await baseModelerAPI.setCurrentProduct(drawingId, rProductId);
1290
1255
  }, productId);
1291
1256
  },
1292
1257
  getCurrentProduct: () => {
@@ -1314,6 +1279,15 @@ export default class CAD {
1314
1279
  return null;
1315
1280
  }, refId);
1316
1281
  },
1282
+ getSketchRegion: (refId, sketchRegionName) => {
1283
+ return this.resolve(async ([rRefId]) => {
1284
+ const sRIds = partUtils.getSketchRegion(drawingId, rRefId, sketchRegionName);
1285
+ if (sRIds != undefined) {
1286
+ return Array.isArray(sRIds) ? sRIds : [sRIds];
1287
+ }
1288
+ return null;
1289
+ }, refId);
1290
+ },
1317
1291
  getWorkGeometry: (refId, type, wgName) => {
1318
1292
  return this.resolve(async ([rRefId]) => {
1319
1293
  const wgIds = asmUtils.getWorkGeometry(drawingId, rRefId, type, wgName);
@@ -1554,22 +1528,22 @@ export default class CAD {
1554
1528
  }, translationId);
1555
1529
  },
1556
1530
  save: (type) => {
1557
- return ccAPI.baseModeler.save(drawingId, type);
1531
+ return baseModelerAPI.save(drawingId, type);
1558
1532
  },
1559
1533
  saveToUrl: (url, filetype) => {
1560
- return ccAPI.baseModeler.saveToUrl(drawingId, url, filetype);
1534
+ return baseModelerAPI.saveToUrl(drawingId, url, filetype);
1561
1535
  },
1562
1536
  load: (content, type) => {
1563
- return ccAPI.baseModeler.load(drawingId, content, type);
1537
+ return baseModelerAPI.load(drawingId, content, type);
1564
1538
  },
1565
1539
  loadFromUrl: (url, filetype) => {
1566
- return ccAPI.baseModeler.loadFromUrl(drawingId, url, filetype, true);
1540
+ return baseModelerAPI.loadFromUrl(drawingId, url, filetype, true);
1567
1541
  },
1568
- loadProduct: (content, type) => {
1569
- return ccAPI.assemblyBuilder.loadProduct(drawingId, content, type);
1542
+ loadProduct: (content, type, options) => {
1543
+ return assemblyBuilderAPI.loadProduct(drawingId, content, type, '', options);
1570
1544
  },
1571
- loadProductFromUrl: (url, filetype) => {
1572
- return ccAPI.assemblyBuilder.loadProductFromUrl(drawingId, url, filetype);
1545
+ loadProductFromUrl: (url, filetype, options) => {
1546
+ return assemblyBuilderAPI.loadProductFromUrl(drawingId, url, filetype, options);
1573
1547
  },
1574
1548
  pick: (partId, type, points) => {
1575
1549
  return this.resolve(async ([rPartId]) => {
@@ -1671,6 +1645,11 @@ export default class CAD {
1671
1645
  await baseModelerAPI.deleteObjects(drawingId, toRemoveOps);
1672
1646
  }
1673
1647
  },
1648
+ getMatePath: async (refId) => {
1649
+ return this.resolve(async ([rRefId]) => {
1650
+ return asmUtils.getMatePath(drawingId, rRefId);
1651
+ }, refId);
1652
+ },
1674
1653
  };
1675
1654
  callback(publicApi);
1676
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
@@ -213,7 +217,7 @@ export declare type ApiHistory = {
213
217
  /**
214
218
  * Creates an extrusion
215
219
  * @param partId Id of the part to create the extrusion in.
216
- * @param sketchId Id of the sketch to extrude
220
+ * @param sketchOrRegionIds Id of the sketch to extrude or multiple ids of sketch regions
217
221
  * @param type Type of extrusion (up, down, symmetric, custom)
218
222
  * @param limit1 Start of extrusion (0 = start at sketch, only for type custom necessary)
219
223
  * @param limit2 End of extrusion, which is actually the height
@@ -221,17 +225,17 @@ export declare type ApiHistory = {
221
225
  * @param direction Direction of extrusion
222
226
  * @param capEnds If true, ends will be capped, else a sheet will be created
223
227
  */
224
- extrusion: (partId: VID, sketchId: VID, type: ExtrusionType, limit1: number | string, limit2: number | string, taperAngle: number | string, direction: PointMemValue, capEnds: 0 | 1) => ID;
228
+ extrusion: (partId: VID, sketchOrRegionIds: VID | VIDs, type: ExtrusionType, limit1: number | string, limit2: number | string, taperAngle: number | string, direction: PointMemValue, capEnds: 0 | 1) => ID;
225
229
  /**
226
230
  * Creates a revolve
227
231
  * @param partId Id of the part to create the revolve in.
228
- * @param sketchId Id of the sketch to revolve
232
+ * @param sketchOrRegionIds Id of the sketch to extrude or multiple ids of sketch regions
229
233
  * @param axisIds Array of ids, either [lineId] or [point1Id, point2Id], ids can be both ccId or graphicId
230
234
  * @param angle1 Start of revolve in degrees
231
235
  * @param angle2 End of revolve in degrees
232
236
  * @param inverted flag, whether to invert the axis or not
233
237
  */
234
- revolve: (partId: VID, sketchId: VID, axisIds: VID[], angle1: number | string, angle2: number | string, inverted: 0 | 1) => ID;
238
+ revolve: (partId: VID, sketchOrRegionIds: VID | VIDs, axisIds: VID[], angle1: number | string, angle2: number | string, inverted: 0 | 1) => ID;
235
239
  /**
236
240
  * Creates a boolean operation.
237
241
  * @param partId id of the part where the operation will be created on
@@ -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
@@ -972,6 +985,14 @@ export declare type ApiHistory = {
972
985
  * return geoms.map(geom => new THREE.Mesh(geom, new THREE.MeshStandardMaterial()))
973
986
  */
974
987
  getWorkCoordSystem: (refId: VID, wcsName?: string) => IDs;
988
+ /**
989
+ * Returns the sketch region with the given sketchRegionName from the given reference.
990
+ * If sketchRegionName is not set, all sketch regions of the reference will be returned.
991
+ * @param refId id of the reference to look for the sketch region
992
+ * @param wcsName name of the sketch region to look for
993
+ * @example // tbd
994
+ */
995
+ getSketchRegion: (refId: VID, sketchRegionName?: string) => IDs;
975
996
  /**
976
997
  * Returns the work geometry of given type with given name. If the name of the work geometry is empty,
977
998
  * all found work geometry of given type is returned
@@ -1098,20 +1119,26 @@ export declare type ApiHistory = {
1098
1119
  * Loads a product into the current drawing.
1099
1120
  * @param content data as arraybuffer
1100
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
1101
1123
  * @example
1102
1124
  * // Loads an existing product
1103
1125
  * const part = api.loadProduct(arraybuffer, 'ofb')
1104
1126
  * const geoms = await api.createBufferGeometry(part)
1105
1127
  * return geoms.map(geom => new THREE.Mesh(geom, new THREE.MeshStandardMaterial()))
1106
1128
  */
1107
- loadProduct: (content: ArrayBuffer, type: 'ofb' | 'stp') => Promise<number[] | null>;
1129
+ loadProduct: (content: ArrayBuffer, type: 'ofb' | 'stp', options?: {
1130
+ ident?: ObjectIdent;
1131
+ }) => Promise<number[] | null>;
1108
1132
  /**
1109
1133
  * Loads a product from the given URL into the current drawing.
1110
1134
  * @param url The url to load data from.
1111
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
1112
1137
  * @example // tbd
1113
1138
  */
1114
- loadProductFromUrl: (url: string, filetype: 'ofb' | 'stp') => Promise<number[] | null>;
1139
+ loadProductFromUrl: (url: string, filetype: 'ofb' | 'stp', options?: {
1140
+ ident?: ObjectIdent;
1141
+ }) => Promise<number[] | null>;
1115
1142
  /**
1116
1143
  * Creates a new feature and appends geometry to it. This method can be used to import specific geometry
1117
1144
  * which can be used for further operations like boolean, translations and so on.
@@ -1125,13 +1152,11 @@ export declare type ApiHistory = {
1125
1152
  /**
1126
1153
  * Removes multiple nodes from an assembly node at once
1127
1154
  * @param nodes array of node parameter objects. See following descriptions.
1128
- * @param referenceId id of the node to remove
1129
- * @param ownerId id of the assembly node to remove the node from
1155
+ * @param referenceId id or identifier of the node to remove
1130
1156
  * @example // tbd
1131
1157
  */
1132
1158
  removeNodes: (...nodes: {
1133
- referenceId: VID;
1134
- ownerId: VID;
1159
+ referenceId: VID | ObjectIdent;
1135
1160
  }[]) => Promise<void>;
1136
1161
  /**
1137
1162
  * Transforms the node with referenceId with the given transformation within an assembly
@@ -1181,13 +1206,13 @@ export declare type ApiHistory = {
1181
1206
  * Updates multiple expressions in different parts at once
1182
1207
  *
1183
1208
  * @param expressions array of expression objects containing the part id and the expression to set
1184
- * @param partId id of part to update expression
1209
+ * @param partId id or identifier of part to update expression
1185
1210
  * @param members array of members to update which contain a name and a value. Value can be an expression, e.g. '2 * laenge'
1186
1211
  * @example // tbd
1187
1212
  * @returns true, if updating expressions in all parts was successfull
1188
1213
  */
1189
1214
  setExpressions: (...expressions: {
1190
- partId: number;
1215
+ partId: VID | ObjectIdent;
1191
1216
  members: {
1192
1217
  name: string;
1193
1218
  value: number | string;
@@ -1208,6 +1233,13 @@ export declare type ApiHistory = {
1208
1233
  * @param toOperation all operations, from rollback bar until the id of this operation, will be deleted
1209
1234
  */
1210
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[]>;
1211
1243
  };
1212
1244
  export default class CAD {
1213
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-beta.4",
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-beta.4",
33
+ "@buerli.io/classcad": "0.6.0",
34
34
  "flat-promise": "^1.0.3"
35
35
  }
36
36
  }