@buerli.io/headless 0.7.1-beta.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,27 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __asyncValues = (this && this.__asyncValues) || function (o) {
26
3
  if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
27
4
  var m = o[Symbol.asyncIterator], i;
@@ -34,7 +11,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
34
11
  const classcad_1 = require("@buerli.io/classcad");
35
12
  const core_1 = require("@buerli.io/core");
36
13
  const three_1 = require("three");
37
- const BufferGeometryUtils_ = __importStar(require("three/examples/jsm/utils/BufferGeometryUtils"));
14
+ const three_stdlib_1 = require("three-stdlib");
38
15
  const selection_1 = require("./utils/selection");
39
16
  const meshes_1 = require("./utils/meshes");
40
17
  const featureAPI = classcad_1.ccAPI.feature;
@@ -46,10 +23,6 @@ const geometryAPI = classcad_1.ccAPI.geometry;
46
23
  const baseUtils = classcad_1.ccUtils.base;
47
24
  const asmUtils = classcad_1.ccUtils.assembly;
48
25
  const partUtils = classcad_1.ccUtils.part;
49
- let BufferGeometryUtils = BufferGeometryUtils_;
50
- if (BufferGeometryUtils.BufferGeometryUtils) {
51
- BufferGeometryUtils = BufferGeometryUtils.BufferGeometryUtils;
52
- }
53
26
  const resolveVec = (value) => {
54
27
  if (Array.isArray(value))
55
28
  return { x: value[0], y: value[1], z: value[2] };
@@ -104,7 +77,7 @@ const createRecursiveBufferGeometry = async (object, drawingId, bufferGeomArray)
104
77
  }
105
78
  if (geometries.length > 0) {
106
79
  const transformation = cDrawing.api.structure.calculateGlobalTransformation(object.id);
107
- const bufferGeom = BufferGeometryUtils.mergeBufferGeometries(geometries);
80
+ const bufferGeom = (0, three_stdlib_1.mergeBufferGeometries)(geometries);
108
81
  bufferGeom.applyMatrix4(transformation);
109
82
  bufferGeomArray.push(bufferGeom);
110
83
  }
@@ -138,8 +111,9 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
138
111
  const entities = object.link ? tree[object.link].solids : object.solids;
139
112
  if (entities != undefined) {
140
113
  const part = new three_1.Group();
141
- part.matrix = object.coordinateSystem ? core_1.MathUtils.convertToMatrix4(object.coordinateSystem) : new three_1.Matrix4();
142
- part.matrixAutoUpdate = false;
114
+ const matrix = object.coordinateSystem ? core_1.MathUtils.convertToMatrix4(object.coordinateSystem) : new three_1.Matrix4();
115
+ matrix.decompose(part.position, part.quaternion, part.scale);
116
+ part.updateMatrix();
143
117
  part.userData = { id: object.id }; // product reference id
144
118
  part.name = object.name; // product reference name
145
119
  for (const entity of entities) {
@@ -154,55 +128,92 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
154
128
  const solidObject = cDrawing.structure.tree[cachedEntity.container.ownerId];
155
129
  if (solidObject) {
156
130
  const _solid = new three_1.Group();
157
- _solid.name = solidObject.name;
131
+ _solid.name = solidObject.name + '_solid';
158
132
  _solid.userData = { id: solidObject.id }; // add solid id to the userData
159
133
  if (options === null || options === void 0 ? void 0 : options.meshPerGeometry) {
160
134
  // Create a mesh for each geometry element
161
- cachedEntity.meshes.forEach(m => {
135
+ cachedEntity.meshes.forEach((m, i) => {
162
136
  const mesh = new three_1.Mesh();
137
+ mesh.name = solidObject.name + '_' + i;
163
138
  mesh.userData = { id: m.graphicId }; // add graphic id to the userData
164
- mesh.geometry = m.geometry;
165
- mesh.material = new three_1.MeshStandardMaterial({
166
- color: m.color ? m.color : cachedEntity.color,
167
- transparent: m.color ? m.opacity < 1 : cachedEntity.opacity < 1,
168
- opacity: m.color ? m.opacity : cachedEntity.opacity,
169
- });
139
+ if (!(options === null || options === void 0 ? void 0 : options.structureOnly)) {
140
+ mesh.geometry = m.geometry;
141
+ mesh.material = new three_1.MeshStandardMaterial({
142
+ color: m.color ? m.color : cachedEntity.color,
143
+ transparent: m.color ? m.opacity < 1 : cachedEntity.opacity < 1,
144
+ opacity: m.color ? m.opacity : cachedEntity.opacity,
145
+ });
146
+ mesh.material.name = mesh.name + '_material';
147
+ result.materials[mesh.material.name] = mesh.material;
148
+ }
149
+ result.nodes[mesh.name] = mesh;
170
150
  _solid.add(mesh);
171
- result.meshes.push(mesh);
172
151
  });
152
+ part.add(_solid);
153
+ result.nodes[_solid.name] = _solid;
173
154
  }
174
155
  else {
175
156
  // Merge all geometries into one mesh, sort them by color
176
157
  const colorMeshesMap = (0, meshes_1.getDifferentColoredMeshesFromEntity)(cachedEntity);
177
- Object.keys(colorMeshesMap).forEach(key => {
178
- const mesh = new three_1.Mesh();
179
- mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(colorMeshesMap[key].meshes.map(m => m.geometry));
180
- mesh.material = new three_1.MeshStandardMaterial({
181
- color: colorMeshesMap[key].color,
182
- transparent: colorMeshesMap[key].opacity < 1,
183
- opacity: colorMeshesMap[key].opacity,
158
+ const colorMeshes = Object.keys(colorMeshesMap);
159
+ if (colorMeshes.length > 1) {
160
+ // If the solid consists of multiple meshes we must keep the group
161
+ colorMeshes.forEach((key, i) => {
162
+ const mesh = new three_1.Mesh();
163
+ mesh.name = solidObject.name + '_' + i;
164
+ mesh.userData = { id: solidObject.id }; // add solid id to the userData
165
+ if (!(options === null || options === void 0 ? void 0 : options.structureOnly)) {
166
+ mesh.geometry = (0, three_stdlib_1.mergeBufferGeometries)(colorMeshesMap[key].meshes.map(m => m.geometry));
167
+ mesh.material = new three_1.MeshStandardMaterial({
168
+ color: colorMeshesMap[key].color,
169
+ transparent: colorMeshesMap[key].opacity < 1,
170
+ opacity: colorMeshesMap[key].opacity,
171
+ });
172
+ mesh.material.name = mesh.name + '_material';
173
+ result.materials[mesh.material.name] = mesh.material;
174
+ }
175
+ result.nodes[mesh.name] = mesh; // Collect mesh to return result later
176
+ _solid.add(mesh); // Add mesh to solid of the scene
184
177
  });
185
- _solid.add(mesh); // Add mesh to solid of the scene
186
- result.meshes.push(mesh); // Collect mesh to return result later
187
- });
178
+ part.add(_solid);
179
+ result.nodes[_solid.name] = _solid;
180
+ }
181
+ else {
182
+ // Otherwise we can use the mesh itself
183
+ const key = colorMeshes[0];
184
+ const mesh = new three_1.Mesh();
185
+ mesh.name = solidObject.name;
186
+ mesh.userData = { id: solidObject.id }; // add solid id to the userData
187
+ if (!(options === null || options === void 0 ? void 0 : options.structureOnly)) {
188
+ mesh.geometry = (0, three_stdlib_1.mergeBufferGeometries)(colorMeshesMap[key].meshes.map(m => m.geometry));
189
+ mesh.material = new three_1.MeshStandardMaterial({
190
+ color: colorMeshesMap[key].color,
191
+ transparent: colorMeshesMap[key].opacity < 1,
192
+ opacity: colorMeshesMap[key].opacity,
193
+ });
194
+ mesh.material.name = mesh.name + '_material';
195
+ result.materials[mesh.material.name] = mesh.material;
196
+ }
197
+ result.nodes[mesh.name] = mesh;
198
+ part.add(mesh);
199
+ }
188
200
  }
189
- part.add(_solid);
190
- result.solids.push(_solid);
191
201
  }
192
202
  }
193
203
  }
194
204
  root.add(part);
195
- result.nodes.push(part);
205
+ result.nodes[part.name] = part;
196
206
  }
197
207
  }
198
208
  else if (object.children) {
199
209
  // Assembly
200
210
  const assembly = new three_1.Group();
201
- assembly.matrix = object.coordinateSystem ? core_1.MathUtils.convertToMatrix4(object.coordinateSystem) : new three_1.Matrix4();
202
- assembly.matrixAutoUpdate = false;
211
+ const matrix = object.coordinateSystem ? core_1.MathUtils.convertToMatrix4(object.coordinateSystem) : new three_1.Matrix4();
212
+ matrix.decompose(assembly.position, assembly.quaternion, assembly.scale);
213
+ assembly.updateMatrix();
203
214
  assembly.userData = { id: object.id }; // assembly root or product reference id
204
215
  assembly.name = object.name; // assembly root or product reference name
205
- result.nodes.push(assembly);
216
+ result.nodes[assembly.name] = assembly;
206
217
  root.add(assembly);
207
218
  for (const child of object.children) {
208
219
  if (classcad_1.ccUtils.base.isA(tree[child].class, classcad_1.CCClasses.IProductReference)) {
@@ -211,29 +222,6 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
211
222
  }
212
223
  }
213
224
  };
214
- /**
215
- * Helper function to log relevant points to find geometry to the console.
216
- * This helps the user to copy the points directly from console to parameter of
217
- * findOrSelect() method.
218
- * @param points Array of points array to log to the console
219
- */
220
- const logPoints = (points) => {
221
- let log = 'Relevant points of selected gometry = [[';
222
- if (points && points.length > 0) {
223
- for (let i = 0; i < points.length; i++) {
224
- for (let j = 0; j < points[i].length; j++) {
225
- const point = resolveVec(points[i][j]);
226
- const x = Math.round(point.x * 1000) / 1000;
227
- const y = Math.round(point.y * 1000) / 1000;
228
- const z = Math.round(point.z * 1000) / 1000;
229
- log += '{ x: ' + x + ', y: ' + y + ', z: ' + z + '}';
230
- log += points[i].length - 1 === j ? '' : ',';
231
- }
232
- log += points.length - 1 === i ? ']]' : '],[';
233
- }
234
- console.info(log);
235
- }
236
- };
237
225
  class CAD {
238
226
  constructor() {
239
227
  this.drawingId = null;
@@ -1063,14 +1051,13 @@ class CAD {
1063
1051
  createScene: async (objectId, options) => {
1064
1052
  await this.queue;
1065
1053
  this.queue = Promise.resolve(0);
1066
- const rObjectId = await objectId;
1067
1054
  const cDrawing = (0, core_1.getDrawing)(drawingId);
1068
1055
  const structureTree = cDrawing.structure.tree;
1056
+ const rObjectId = objectId ? await objectId : cDrawing.structure.root;
1069
1057
  const scene = new three_1.Scene();
1070
1058
  const result = {
1071
- nodes: [],
1072
- solids: [],
1073
- meshes: [],
1059
+ nodes: {},
1060
+ materials: {},
1074
1061
  };
1075
1062
  if (rObjectId != null) {
1076
1063
  const rootObj = structureTree[rObjectId];
@@ -1142,10 +1129,10 @@ class CAD {
1142
1129
  return null;
1143
1130
  }, partId, ...references);
1144
1131
  },
1145
- createWorkCoordSystem: (partId, type, references, coordinateSystem, offset, rotation, inverted = false, local = false, name) => {
1132
+ createWorkCoordSystem: (partId, type, references, offset, rotation, inverted = false, name) => {
1146
1133
  return this.resolve(async ([rPartId, ...rReferences]) => {
1147
1134
  const wCSName = name ? name : 'WorkCoordSystem';
1148
- const wCSId = await featureAPI.createWorkGeometry(drawingId, rPartId, classcad_1.CCClasses.CCWorkCoordSystem, wCSName);
1135
+ const wCSId = await featureAPI.createWorkGeometry(drawingId, rPartId, classcad_1.CCClasses.CCWorkCSys, wCSName);
1149
1136
  if (wCSId != null) {
1150
1137
  const offsetParam = {
1151
1138
  value: resolveVec(offset),
@@ -1155,7 +1142,7 @@ class CAD {
1155
1142
  value: resolveVec(rotation),
1156
1143
  isExpr: typeof rotation === 'string',
1157
1144
  };
1158
- await featureAPI.updateWorkCoordSystem(drawingId, wCSId, type, rReferences, coordinateSystem.map(resolveVec), offsetParam, rotationParam, inverted ? 1 : 0, local);
1145
+ await featureAPI.updateWorkCSys(drawingId, wCSId, type, rReferences, offsetParam, rotationParam, inverted ? 1 : 0);
1159
1146
  return wCSId;
1160
1147
  }
1161
1148
  return null;
@@ -1208,36 +1195,37 @@ class CAD {
1208
1195
  return null;
1209
1196
  }, partId, references);
1210
1197
  },
1211
- findOrSelect: (partId, type, length, positions) => {
1212
- return this.resolve(async ([rPartId]) => {
1213
- let filter = core_1.lineSegmentsFilter;
1214
- switch (type) {
1215
- case 0: // Vertex
1216
- filter = core_1.pointFilter;
1217
- break;
1218
- case 1: // Edge
1219
- filter = core_1.lineSegmentsFilter;
1220
- break;
1221
- case 2: // Loop
1222
- filter = core_1.loopFilter;
1223
- break;
1224
- case 3: // Face
1225
- filter = core_1.planeFilter;
1226
- break;
1227
- }
1228
- const geometries = positions
1229
- ? await geometryAPI.findGeometriesByPoints(drawingId, rPartId, type, positions.map(p => p.map(resolveVec)))
1230
- : await (0, selection_1.waitForSelect)(length, filter, (resolveSelection, items, diff) => {
1231
- if (items.length > length - 1) {
1232
- resolveSelection(items.map(i => i.data.graphicId));
1233
- geometryAPI
1234
- .getPointsByGeometries(drawingId, items.map(i => i.data.graphicId))
1235
- .then(points => {
1236
- logPoints(points);
1237
- });
1238
- }
1198
+ selectGeometry: (types, count) => {
1199
+ return this.resolve(async ([]) => {
1200
+ const filter = (scope, data) => scope === core_1.BuerliScope && types.some(type => type === data);
1201
+ // Check count param. If not set use by default 1, else check if not < 1
1202
+ const lCount = count ? (count < 1 ? 1 : count) : 1;
1203
+ const selections = await (0, selection_1.waitForSelect)(lCount, filter, (resolveSelection, items, diff) => {
1204
+ if (items.length > lCount - 1) {
1205
+ resolveSelection(items);
1206
+ }
1207
+ });
1208
+ const interactionInfos = [];
1209
+ for (const selection of selections) {
1210
+ // Get matching points from selected geometry and add to userData. TODO: Only if in part mode useful?
1211
+ const points = await geometryAPI.getPointsByGeometries(drawingId, [selection.data.graphicId]);
1212
+ const interactionInfo = (0, core_1.createInfo)({
1213
+ objectId: selection.data.container.ownerId,
1214
+ prodRefId: selection.data.productId,
1215
+ containerId: selection.data.container.id,
1216
+ graphicId: selection.data.graphicId,
1217
+ // objectPath: ?, TODO: Add path to the root in expanded tree, as soon as available
1218
+ userData: Object.assign(Object.assign({}, selection.data), { matchingPoints: points }),
1239
1219
  });
1240
- return geometries;
1220
+ interactionInfos.push(interactionInfo);
1221
+ }
1222
+ return interactionInfos;
1223
+ });
1224
+ },
1225
+ findGeometry: (partId, type, positions) => {
1226
+ return this.resolve(async ([rPartId]) => {
1227
+ const geoms = await geometryAPI.findGeometriesByPoints(drawingId, rPartId, type, positions.map(p => p.map(resolveVec)));
1228
+ return geoms;
1241
1229
  }, partId);
1242
1230
  },
1243
1231
  getAssemblyFromContainer: (asmName) => {
@@ -1536,10 +1524,29 @@ class CAD {
1536
1524
  await sketcherAPI.setSketchRefs(drawingId, rSketchId, rPlaneId, invertPlane, rAxisId, isXAxis, invertAxis, rOriginId);
1537
1525
  }, sketchId, planeId, axisId, originId);
1538
1526
  },
1539
- transformNode: (referenceId, ownerId, transformation) => {
1540
- return this.resolve(async ([rRefId, rOwnerId]) => {
1541
- await assemblyBuilderAPI.setNodeTransformation(drawingId, rRefId, rOwnerId, transformation);
1542
- }, referenceId, ownerId);
1527
+ transformNodes: async (...nodes) => {
1528
+ var e_11, _a;
1529
+ const nodesToTransform = [];
1530
+ try {
1531
+ for (var nodes_2 = __asyncValues(nodes), nodes_2_1; nodes_2_1 = await nodes_2.next(), !nodes_2_1.done;) {
1532
+ const node = nodes_2_1.value;
1533
+ const [rReferenceId] = await new Promise(res => this.resolve(id => res(id), node.referenceId));
1534
+ const nodeParam = {
1535
+ referenceId: rReferenceId,
1536
+ transformation: node.transformation,
1537
+ options: { isLocal: true }, // in non-interactive mode, the transformation is local to the owner
1538
+ };
1539
+ nodesToTransform.push(nodeParam);
1540
+ }
1541
+ }
1542
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
1543
+ finally {
1544
+ try {
1545
+ if (nodes_2_1 && !nodes_2_1.done && (_a = nodes_2.return)) await _a.call(nodes_2);
1546
+ }
1547
+ finally { if (e_11) throw e_11.error; }
1548
+ }
1549
+ return assemblyBuilderAPI.transformNodes(drawingId, nodesToTransform);
1543
1550
  },
1544
1551
  translate: (partId, featureIds, references, inverted, distance) => {
1545
1552
  return this.resolve(async ([rPartId, rFeatureIds, ...rReferences]) => {
@@ -1597,6 +1604,7 @@ class CAD {
1597
1604
  },
1598
1605
  pick: (partId, type, points) => {
1599
1606
  return this.resolve(async ([rPartId]) => {
1607
+ console.warn('Warning: pick() is deprecated, use findGeometry() instead, pick() will be removed in a future release.');
1600
1608
  const refs = await featureAPI.pick(drawingId, rPartId, type, points.map(resolveVec));
1601
1609
  if (refs != undefined) {
1602
1610
  return Array.isArray(refs) ? refs : [refs];
@@ -1700,6 +1708,50 @@ class CAD {
1700
1708
  return asmUtils.getMatePath(drawingId, rRefId);
1701
1709
  }, refId);
1702
1710
  },
1711
+ slice: async (partId, operations, reference, sideFlag) => {
1712
+ const [rPartId] = await new Promise(res => this.resolve(ids => res(ids), partId));
1713
+ const rOperations = await new Promise(res => this.resolve(ids => res(ids), ...operations));
1714
+ const [rReference] = await new Promise(res => this.resolve(paths => res(paths), reference));
1715
+ const cDrawing = (0, core_1.getDrawing)(drawingId);
1716
+ const entArray = [];
1717
+ for (const rOperation of rOperations) {
1718
+ const entities = cDrawing.structure.tree[rOperation].children;
1719
+ if (entities != undefined && entities.length > 0) {
1720
+ entArray.push(entities[0]); // use first entity of operation
1721
+ }
1722
+ }
1723
+ const sliceId = await featureAPI.createFeature(drawingId, rPartId, classcad_1.CCClasses.CCSlice, 'Slice');
1724
+ if (sliceId != null) {
1725
+ await featureAPI.openFeature(drawingId, sliceId);
1726
+ if (entArray.length > 0) {
1727
+ await featureAPI.updateSlice(drawingId, sliceId, entArray, rReference, sideFlag ? 1 : 0);
1728
+ await featureAPI.closeFeature(drawingId, sliceId);
1729
+ return sliceId;
1730
+ }
1731
+ await featureAPI.closeFeature(drawingId, sliceId);
1732
+ await baseModelerAPI.deleteObjects(drawingId, [sliceId]);
1733
+ }
1734
+ return null;
1735
+ },
1736
+ sliceBySheet: async (partId, operationToSlice, operationOfSheet, sideFlag) => {
1737
+ const [rPartId] = await new Promise(res => this.resolve(ids => res(ids), partId));
1738
+ const [rOperationToSlice] = await new Promise(res => this.resolve(ids => res(ids), operationToSlice));
1739
+ const [rOperationOfSheet] = await new Promise(res => this.resolve(ids => res(ids), operationOfSheet));
1740
+ const entityToSlice = (0, core_1.getDrawing)(drawingId).structure.tree[rOperationToSlice].children;
1741
+ const entityOfSheet = (0, core_1.getDrawing)(drawingId).structure.tree[rOperationOfSheet].children;
1742
+ const sliceBySheetId = await featureAPI.createFeature(drawingId, rPartId, classcad_1.CCClasses.CCSliceBySheet, 'SliceBySheet');
1743
+ if (sliceBySheetId != null) {
1744
+ await featureAPI.openFeature(drawingId, sliceBySheetId);
1745
+ if (entityToSlice && entityToSlice.length > 0 && entityOfSheet && entityOfSheet.length > 0) {
1746
+ await featureAPI.updateSliceBySheet(drawingId, sliceBySheetId, entityToSlice[0], entityOfSheet[0], sideFlag ? 1 : 0);
1747
+ await featureAPI.closeFeature(drawingId, sliceBySheetId);
1748
+ return sliceBySheetId;
1749
+ }
1750
+ await featureAPI.closeFeature(drawingId, sliceBySheetId);
1751
+ await baseModelerAPI.deleteObjects(drawingId, [sliceBySheetId]);
1752
+ }
1753
+ return null;
1754
+ },
1703
1755
  };
1704
1756
  callback(publicApi);
1705
1757
  resolve(drawingId);
@@ -1,27 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __asyncValues = (this && this.__asyncValues) || function (o) {
26
3
  if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
27
4
  var m = o[Symbol.asyncIterator], i;
@@ -35,13 +12,9 @@ exports.createPolyline = void 0;
35
12
  const classcad_1 = require("@buerli.io/classcad");
36
13
  const core_1 = require("@buerli.io/core");
37
14
  const three_1 = require("three");
38
- const BufferGeometryUtils_ = __importStar(require("three/examples/jsm/utils/BufferGeometryUtils"));
15
+ const three_stdlib_1 = require("three-stdlib");
39
16
  const meshes_1 = require("./utils/meshes");
40
17
  const solidAPI = classcad_1.ccAPI.solid;
41
- let BufferGeometryUtils = BufferGeometryUtils_;
42
- if (BufferGeometryUtils.BufferGeometryUtils) {
43
- BufferGeometryUtils = BufferGeometryUtils.BufferGeometryUtils;
44
- }
45
18
  const toCCVec = (args) => ({ x: args[0], y: args[1], z: args[2] });
46
19
  const toCCNbrVec = (args) => ({ x: args[0], y: args[1], z: args[2] });
47
20
  const toArray = (v) => (Array.isArray(v) ? v : v.toArray());
@@ -263,7 +236,7 @@ class CAD {
263
236
  await classcad_1.ccAPI.baseModeler.requestVisualisationOfObject(drawingId, rSolid);
264
237
  const entity = await getEntity(drawingId, rSolid);
265
238
  if (entity != null) {
266
- return BufferGeometryUtils.mergeBufferGeometries(entity.meshes.map(m => m.geometry));
239
+ return (0, three_stdlib_1.mergeBufferGeometries)(entity.meshes.map(m => m.geometry));
267
240
  }
268
241
  },
269
242
  createScene: async (solids, options) => {
@@ -310,7 +283,7 @@ class CAD {
310
283
  const colorMeshesMap = (0, meshes_1.getDifferentColoredMeshesFromEntity)(entity);
311
284
  Object.keys(colorMeshesMap).forEach(key => {
312
285
  const mesh = new three_1.Mesh();
313
- mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(colorMeshesMap[key].meshes.map(m => m.geometry));
286
+ mesh.geometry = (0, three_stdlib_1.mergeBufferGeometries)(colorMeshesMap[key].meshes.map(m => m.geometry));
314
287
  mesh.material = new three_1.MeshStandardMaterial({
315
288
  color: colorMeshesMap[key].color,
316
289
  transparent: colorMeshesMap[key].opacity < 1,
@@ -7,9 +7,9 @@ var __asyncValues = (this && this.__asyncValues) || function (o) {
7
7
  };
8
8
  /* eslint-disable max-lines */
9
9
  import { ccAPI, CCClasses, ccUtils, DataType, SVGModusType, } from '@buerli.io/classcad';
10
- import { api, getDrawing, lineSegmentsFilter, loopFilter, MathUtils, planeFilter, pointFilter, } from '@buerli.io/core';
10
+ import { api, getDrawing, MathUtils, BuerliScope, createInfo, } from '@buerli.io/core';
11
11
  import { Group, Matrix4, Mesh, MeshStandardMaterial, Scene } from 'three';
12
- import * as BufferGeometryUtils_ from 'three/examples/jsm/utils/BufferGeometryUtils';
12
+ import { mergeBufferGeometries } from 'three-stdlib';
13
13
  import { waitForSelect } from './utils/selection';
14
14
  import { getDifferentColoredMeshesFromEntity } from './utils/meshes';
15
15
  const featureAPI = ccAPI.feature;
@@ -21,10 +21,6 @@ const geometryAPI = ccAPI.geometry;
21
21
  const baseUtils = ccUtils.base;
22
22
  const asmUtils = ccUtils.assembly;
23
23
  const partUtils = ccUtils.part;
24
- let BufferGeometryUtils = BufferGeometryUtils_;
25
- if (BufferGeometryUtils.BufferGeometryUtils) {
26
- BufferGeometryUtils = BufferGeometryUtils.BufferGeometryUtils;
27
- }
28
24
  const resolveVec = (value) => {
29
25
  if (Array.isArray(value))
30
26
  return { x: value[0], y: value[1], z: value[2] };
@@ -79,7 +75,7 @@ const createRecursiveBufferGeometry = async (object, drawingId, bufferGeomArray)
79
75
  }
80
76
  if (geometries.length > 0) {
81
77
  const transformation = cDrawing.api.structure.calculateGlobalTransformation(object.id);
82
- const bufferGeom = BufferGeometryUtils.mergeBufferGeometries(geometries);
78
+ const bufferGeom = mergeBufferGeometries(geometries);
83
79
  bufferGeom.applyMatrix4(transformation);
84
80
  bufferGeomArray.push(bufferGeom);
85
81
  }
@@ -113,8 +109,9 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
113
109
  const entities = object.link ? tree[object.link].solids : object.solids;
114
110
  if (entities != undefined) {
115
111
  const part = new Group();
116
- part.matrix = object.coordinateSystem ? MathUtils.convertToMatrix4(object.coordinateSystem) : new Matrix4();
117
- part.matrixAutoUpdate = false;
112
+ const matrix = object.coordinateSystem ? MathUtils.convertToMatrix4(object.coordinateSystem) : new Matrix4();
113
+ matrix.decompose(part.position, part.quaternion, part.scale);
114
+ part.updateMatrix();
118
115
  part.userData = { id: object.id }; // product reference id
119
116
  part.name = object.name; // product reference name
120
117
  for (const entity of entities) {
@@ -129,55 +126,92 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
129
126
  const solidObject = cDrawing.structure.tree[cachedEntity.container.ownerId];
130
127
  if (solidObject) {
131
128
  const _solid = new Group();
132
- _solid.name = solidObject.name;
129
+ _solid.name = solidObject.name + '_solid';
133
130
  _solid.userData = { id: solidObject.id }; // add solid id to the userData
134
131
  if (options === null || options === void 0 ? void 0 : options.meshPerGeometry) {
135
132
  // Create a mesh for each geometry element
136
- cachedEntity.meshes.forEach(m => {
133
+ cachedEntity.meshes.forEach((m, i) => {
137
134
  const mesh = new Mesh();
135
+ mesh.name = solidObject.name + '_' + i;
138
136
  mesh.userData = { id: m.graphicId }; // add graphic id to the userData
139
- mesh.geometry = m.geometry;
140
- mesh.material = new MeshStandardMaterial({
141
- color: m.color ? m.color : cachedEntity.color,
142
- transparent: m.color ? m.opacity < 1 : cachedEntity.opacity < 1,
143
- opacity: m.color ? m.opacity : cachedEntity.opacity,
144
- });
137
+ if (!(options === null || options === void 0 ? void 0 : options.structureOnly)) {
138
+ mesh.geometry = m.geometry;
139
+ mesh.material = new MeshStandardMaterial({
140
+ color: m.color ? m.color : cachedEntity.color,
141
+ transparent: m.color ? m.opacity < 1 : cachedEntity.opacity < 1,
142
+ opacity: m.color ? m.opacity : cachedEntity.opacity,
143
+ });
144
+ mesh.material.name = mesh.name + '_material';
145
+ result.materials[mesh.material.name] = mesh.material;
146
+ }
147
+ result.nodes[mesh.name] = mesh;
145
148
  _solid.add(mesh);
146
- result.meshes.push(mesh);
147
149
  });
150
+ part.add(_solid);
151
+ result.nodes[_solid.name] = _solid;
148
152
  }
149
153
  else {
150
154
  // Merge all geometries into one mesh, sort them by color
151
155
  const colorMeshesMap = getDifferentColoredMeshesFromEntity(cachedEntity);
152
- Object.keys(colorMeshesMap).forEach(key => {
153
- const mesh = new Mesh();
154
- mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(colorMeshesMap[key].meshes.map(m => m.geometry));
155
- mesh.material = new MeshStandardMaterial({
156
- color: colorMeshesMap[key].color,
157
- transparent: colorMeshesMap[key].opacity < 1,
158
- opacity: colorMeshesMap[key].opacity,
156
+ const colorMeshes = Object.keys(colorMeshesMap);
157
+ if (colorMeshes.length > 1) {
158
+ // If the solid consists of multiple meshes we must keep the group
159
+ colorMeshes.forEach((key, i) => {
160
+ const mesh = new Mesh();
161
+ mesh.name = solidObject.name + '_' + i;
162
+ mesh.userData = { id: solidObject.id }; // add solid id to the userData
163
+ if (!(options === null || options === void 0 ? void 0 : options.structureOnly)) {
164
+ mesh.geometry = mergeBufferGeometries(colorMeshesMap[key].meshes.map(m => m.geometry));
165
+ mesh.material = new MeshStandardMaterial({
166
+ color: colorMeshesMap[key].color,
167
+ transparent: colorMeshesMap[key].opacity < 1,
168
+ opacity: colorMeshesMap[key].opacity,
169
+ });
170
+ mesh.material.name = mesh.name + '_material';
171
+ result.materials[mesh.material.name] = mesh.material;
172
+ }
173
+ result.nodes[mesh.name] = mesh; // Collect mesh to return result later
174
+ _solid.add(mesh); // Add mesh to solid of the scene
159
175
  });
160
- _solid.add(mesh); // Add mesh to solid of the scene
161
- result.meshes.push(mesh); // Collect mesh to return result later
162
- });
176
+ part.add(_solid);
177
+ result.nodes[_solid.name] = _solid;
178
+ }
179
+ else {
180
+ // Otherwise we can use the mesh itself
181
+ const key = colorMeshes[0];
182
+ const mesh = new Mesh();
183
+ mesh.name = solidObject.name;
184
+ mesh.userData = { id: solidObject.id }; // add solid id to the userData
185
+ if (!(options === null || options === void 0 ? void 0 : options.structureOnly)) {
186
+ mesh.geometry = mergeBufferGeometries(colorMeshesMap[key].meshes.map(m => m.geometry));
187
+ mesh.material = new MeshStandardMaterial({
188
+ color: colorMeshesMap[key].color,
189
+ transparent: colorMeshesMap[key].opacity < 1,
190
+ opacity: colorMeshesMap[key].opacity,
191
+ });
192
+ mesh.material.name = mesh.name + '_material';
193
+ result.materials[mesh.material.name] = mesh.material;
194
+ }
195
+ result.nodes[mesh.name] = mesh;
196
+ part.add(mesh);
197
+ }
163
198
  }
164
- part.add(_solid);
165
- result.solids.push(_solid);
166
199
  }
167
200
  }
168
201
  }
169
202
  root.add(part);
170
- result.nodes.push(part);
203
+ result.nodes[part.name] = part;
171
204
  }
172
205
  }
173
206
  else if (object.children) {
174
207
  // Assembly
175
208
  const assembly = new Group();
176
- assembly.matrix = object.coordinateSystem ? MathUtils.convertToMatrix4(object.coordinateSystem) : new Matrix4();
177
- assembly.matrixAutoUpdate = false;
209
+ const matrix = object.coordinateSystem ? MathUtils.convertToMatrix4(object.coordinateSystem) : new Matrix4();
210
+ matrix.decompose(assembly.position, assembly.quaternion, assembly.scale);
211
+ assembly.updateMatrix();
178
212
  assembly.userData = { id: object.id }; // assembly root or product reference id
179
213
  assembly.name = object.name; // assembly root or product reference name
180
- result.nodes.push(assembly);
214
+ result.nodes[assembly.name] = assembly;
181
215
  root.add(assembly);
182
216
  for (const child of object.children) {
183
217
  if (ccUtils.base.isA(tree[child].class, CCClasses.IProductReference)) {
@@ -186,29 +220,6 @@ const createRecursiveScene = async (object, drawingId, root, result, options) =>
186
220
  }
187
221
  }
188
222
  };
189
- /**
190
- * Helper function to log relevant points to find geometry to the console.
191
- * This helps the user to copy the points directly from console to parameter of
192
- * findOrSelect() method.
193
- * @param points Array of points array to log to the console
194
- */
195
- const logPoints = (points) => {
196
- let log = 'Relevant points of selected gometry = [[';
197
- if (points && points.length > 0) {
198
- for (let i = 0; i < points.length; i++) {
199
- for (let j = 0; j < points[i].length; j++) {
200
- const point = resolveVec(points[i][j]);
201
- const x = Math.round(point.x * 1000) / 1000;
202
- const y = Math.round(point.y * 1000) / 1000;
203
- const z = Math.round(point.z * 1000) / 1000;
204
- log += '{ x: ' + x + ', y: ' + y + ', z: ' + z + '}';
205
- log += points[i].length - 1 === j ? '' : ',';
206
- }
207
- log += points.length - 1 === i ? ']]' : '],[';
208
- }
209
- console.info(log);
210
- }
211
- };
212
223
  export default class CAD {
213
224
  constructor() {
214
225
  this.drawingId = null;
@@ -1038,14 +1049,13 @@ export default class CAD {
1038
1049
  createScene: async (objectId, options) => {
1039
1050
  await this.queue;
1040
1051
  this.queue = Promise.resolve(0);
1041
- const rObjectId = await objectId;
1042
1052
  const cDrawing = getDrawing(drawingId);
1043
1053
  const structureTree = cDrawing.structure.tree;
1054
+ const rObjectId = objectId ? await objectId : cDrawing.structure.root;
1044
1055
  const scene = new Scene();
1045
1056
  const result = {
1046
- nodes: [],
1047
- solids: [],
1048
- meshes: [],
1057
+ nodes: {},
1058
+ materials: {},
1049
1059
  };
1050
1060
  if (rObjectId != null) {
1051
1061
  const rootObj = structureTree[rObjectId];
@@ -1117,10 +1127,10 @@ export default class CAD {
1117
1127
  return null;
1118
1128
  }, partId, ...references);
1119
1129
  },
1120
- createWorkCoordSystem: (partId, type, references, coordinateSystem, offset, rotation, inverted = false, local = false, name) => {
1130
+ createWorkCoordSystem: (partId, type, references, offset, rotation, inverted = false, name) => {
1121
1131
  return this.resolve(async ([rPartId, ...rReferences]) => {
1122
1132
  const wCSName = name ? name : 'WorkCoordSystem';
1123
- const wCSId = await featureAPI.createWorkGeometry(drawingId, rPartId, CCClasses.CCWorkCoordSystem, wCSName);
1133
+ const wCSId = await featureAPI.createWorkGeometry(drawingId, rPartId, CCClasses.CCWorkCSys, wCSName);
1124
1134
  if (wCSId != null) {
1125
1135
  const offsetParam = {
1126
1136
  value: resolveVec(offset),
@@ -1130,7 +1140,7 @@ export default class CAD {
1130
1140
  value: resolveVec(rotation),
1131
1141
  isExpr: typeof rotation === 'string',
1132
1142
  };
1133
- await featureAPI.updateWorkCoordSystem(drawingId, wCSId, type, rReferences, coordinateSystem.map(resolveVec), offsetParam, rotationParam, inverted ? 1 : 0, local);
1143
+ await featureAPI.updateWorkCSys(drawingId, wCSId, type, rReferences, offsetParam, rotationParam, inverted ? 1 : 0);
1134
1144
  return wCSId;
1135
1145
  }
1136
1146
  return null;
@@ -1183,36 +1193,37 @@ export default class CAD {
1183
1193
  return null;
1184
1194
  }, partId, references);
1185
1195
  },
1186
- findOrSelect: (partId, type, length, positions) => {
1187
- return this.resolve(async ([rPartId]) => {
1188
- let filter = lineSegmentsFilter;
1189
- switch (type) {
1190
- case 0: // Vertex
1191
- filter = pointFilter;
1192
- break;
1193
- case 1: // Edge
1194
- filter = lineSegmentsFilter;
1195
- break;
1196
- case 2: // Loop
1197
- filter = loopFilter;
1198
- break;
1199
- case 3: // Face
1200
- filter = planeFilter;
1201
- break;
1202
- }
1203
- const geometries = positions
1204
- ? await geometryAPI.findGeometriesByPoints(drawingId, rPartId, type, positions.map(p => p.map(resolveVec)))
1205
- : await waitForSelect(length, filter, (resolveSelection, items, diff) => {
1206
- if (items.length > length - 1) {
1207
- resolveSelection(items.map(i => i.data.graphicId));
1208
- geometryAPI
1209
- .getPointsByGeometries(drawingId, items.map(i => i.data.graphicId))
1210
- .then(points => {
1211
- logPoints(points);
1212
- });
1213
- }
1196
+ selectGeometry: (types, count) => {
1197
+ return this.resolve(async ([]) => {
1198
+ const filter = (scope, data) => scope === BuerliScope && types.some(type => type === data);
1199
+ // Check count param. If not set use by default 1, else check if not < 1
1200
+ const lCount = count ? (count < 1 ? 1 : count) : 1;
1201
+ const selections = await waitForSelect(lCount, filter, (resolveSelection, items, diff) => {
1202
+ if (items.length > lCount - 1) {
1203
+ resolveSelection(items);
1204
+ }
1205
+ });
1206
+ const interactionInfos = [];
1207
+ for (const selection of selections) {
1208
+ // Get matching points from selected geometry and add to userData. TODO: Only if in part mode useful?
1209
+ const points = await geometryAPI.getPointsByGeometries(drawingId, [selection.data.graphicId]);
1210
+ const interactionInfo = createInfo({
1211
+ objectId: selection.data.container.ownerId,
1212
+ prodRefId: selection.data.productId,
1213
+ containerId: selection.data.container.id,
1214
+ graphicId: selection.data.graphicId,
1215
+ // objectPath: ?, TODO: Add path to the root in expanded tree, as soon as available
1216
+ userData: Object.assign(Object.assign({}, selection.data), { matchingPoints: points }),
1214
1217
  });
1215
- return geometries;
1218
+ interactionInfos.push(interactionInfo);
1219
+ }
1220
+ return interactionInfos;
1221
+ });
1222
+ },
1223
+ findGeometry: (partId, type, positions) => {
1224
+ return this.resolve(async ([rPartId]) => {
1225
+ const geoms = await geometryAPI.findGeometriesByPoints(drawingId, rPartId, type, positions.map(p => p.map(resolveVec)));
1226
+ return geoms;
1216
1227
  }, partId);
1217
1228
  },
1218
1229
  getAssemblyFromContainer: (asmName) => {
@@ -1511,10 +1522,29 @@ export default class CAD {
1511
1522
  await sketcherAPI.setSketchRefs(drawingId, rSketchId, rPlaneId, invertPlane, rAxisId, isXAxis, invertAxis, rOriginId);
1512
1523
  }, sketchId, planeId, axisId, originId);
1513
1524
  },
1514
- transformNode: (referenceId, ownerId, transformation) => {
1515
- return this.resolve(async ([rRefId, rOwnerId]) => {
1516
- await assemblyBuilderAPI.setNodeTransformation(drawingId, rRefId, rOwnerId, transformation);
1517
- }, referenceId, ownerId);
1525
+ transformNodes: async (...nodes) => {
1526
+ var e_11, _a;
1527
+ const nodesToTransform = [];
1528
+ try {
1529
+ for (var nodes_2 = __asyncValues(nodes), nodes_2_1; nodes_2_1 = await nodes_2.next(), !nodes_2_1.done;) {
1530
+ const node = nodes_2_1.value;
1531
+ const [rReferenceId] = await new Promise(res => this.resolve(id => res(id), node.referenceId));
1532
+ const nodeParam = {
1533
+ referenceId: rReferenceId,
1534
+ transformation: node.transformation,
1535
+ options: { isLocal: true }, // in non-interactive mode, the transformation is local to the owner
1536
+ };
1537
+ nodesToTransform.push(nodeParam);
1538
+ }
1539
+ }
1540
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
1541
+ finally {
1542
+ try {
1543
+ if (nodes_2_1 && !nodes_2_1.done && (_a = nodes_2.return)) await _a.call(nodes_2);
1544
+ }
1545
+ finally { if (e_11) throw e_11.error; }
1546
+ }
1547
+ return assemblyBuilderAPI.transformNodes(drawingId, nodesToTransform);
1518
1548
  },
1519
1549
  translate: (partId, featureIds, references, inverted, distance) => {
1520
1550
  return this.resolve(async ([rPartId, rFeatureIds, ...rReferences]) => {
@@ -1572,6 +1602,7 @@ export default class CAD {
1572
1602
  },
1573
1603
  pick: (partId, type, points) => {
1574
1604
  return this.resolve(async ([rPartId]) => {
1605
+ console.warn('Warning: pick() is deprecated, use findGeometry() instead, pick() will be removed in a future release.');
1575
1606
  const refs = await featureAPI.pick(drawingId, rPartId, type, points.map(resolveVec));
1576
1607
  if (refs != undefined) {
1577
1608
  return Array.isArray(refs) ? refs : [refs];
@@ -1675,6 +1706,50 @@ export default class CAD {
1675
1706
  return asmUtils.getMatePath(drawingId, rRefId);
1676
1707
  }, refId);
1677
1708
  },
1709
+ slice: async (partId, operations, reference, sideFlag) => {
1710
+ const [rPartId] = await new Promise(res => this.resolve(ids => res(ids), partId));
1711
+ const rOperations = await new Promise(res => this.resolve(ids => res(ids), ...operations));
1712
+ const [rReference] = await new Promise(res => this.resolve(paths => res(paths), reference));
1713
+ const cDrawing = getDrawing(drawingId);
1714
+ const entArray = [];
1715
+ for (const rOperation of rOperations) {
1716
+ const entities = cDrawing.structure.tree[rOperation].children;
1717
+ if (entities != undefined && entities.length > 0) {
1718
+ entArray.push(entities[0]); // use first entity of operation
1719
+ }
1720
+ }
1721
+ const sliceId = await featureAPI.createFeature(drawingId, rPartId, CCClasses.CCSlice, 'Slice');
1722
+ if (sliceId != null) {
1723
+ await featureAPI.openFeature(drawingId, sliceId);
1724
+ if (entArray.length > 0) {
1725
+ await featureAPI.updateSlice(drawingId, sliceId, entArray, rReference, sideFlag ? 1 : 0);
1726
+ await featureAPI.closeFeature(drawingId, sliceId);
1727
+ return sliceId;
1728
+ }
1729
+ await featureAPI.closeFeature(drawingId, sliceId);
1730
+ await baseModelerAPI.deleteObjects(drawingId, [sliceId]);
1731
+ }
1732
+ return null;
1733
+ },
1734
+ sliceBySheet: async (partId, operationToSlice, operationOfSheet, sideFlag) => {
1735
+ const [rPartId] = await new Promise(res => this.resolve(ids => res(ids), partId));
1736
+ const [rOperationToSlice] = await new Promise(res => this.resolve(ids => res(ids), operationToSlice));
1737
+ const [rOperationOfSheet] = await new Promise(res => this.resolve(ids => res(ids), operationOfSheet));
1738
+ const entityToSlice = getDrawing(drawingId).structure.tree[rOperationToSlice].children;
1739
+ const entityOfSheet = getDrawing(drawingId).structure.tree[rOperationOfSheet].children;
1740
+ const sliceBySheetId = await featureAPI.createFeature(drawingId, rPartId, CCClasses.CCSliceBySheet, 'SliceBySheet');
1741
+ if (sliceBySheetId != null) {
1742
+ await featureAPI.openFeature(drawingId, sliceBySheetId);
1743
+ if (entityToSlice && entityToSlice.length > 0 && entityOfSheet && entityOfSheet.length > 0) {
1744
+ await featureAPI.updateSliceBySheet(drawingId, sliceBySheetId, entityToSlice[0], entityOfSheet[0], sideFlag ? 1 : 0);
1745
+ await featureAPI.closeFeature(drawingId, sliceBySheetId);
1746
+ return sliceBySheetId;
1747
+ }
1748
+ await featureAPI.closeFeature(drawingId, sliceBySheetId);
1749
+ await baseModelerAPI.deleteObjects(drawingId, [sliceBySheetId]);
1750
+ }
1751
+ return null;
1752
+ },
1678
1753
  };
1679
1754
  callback(publicApi);
1680
1755
  resolve(drawingId);
@@ -9,13 +9,9 @@ var __asyncValues = (this && this.__asyncValues) || function (o) {
9
9
  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
- import * as BufferGeometryUtils_ from 'three/examples/jsm/utils/BufferGeometryUtils';
12
+ import { mergeBufferGeometries } from 'three-stdlib';
13
13
  import { getDifferentColoredMeshesFromEntity } from './utils/meshes';
14
14
  const solidAPI = ccAPI.solid;
15
- let BufferGeometryUtils = BufferGeometryUtils_;
16
- if (BufferGeometryUtils.BufferGeometryUtils) {
17
- BufferGeometryUtils = BufferGeometryUtils.BufferGeometryUtils;
18
- }
19
15
  const toCCVec = (args) => ({ x: args[0], y: args[1], z: args[2] });
20
16
  const toCCNbrVec = (args) => ({ x: args[0], y: args[1], z: args[2] });
21
17
  const toArray = (v) => (Array.isArray(v) ? v : v.toArray());
@@ -236,7 +232,7 @@ export default class CAD {
236
232
  await ccAPI.baseModeler.requestVisualisationOfObject(drawingId, rSolid);
237
233
  const entity = await getEntity(drawingId, rSolid);
238
234
  if (entity != null) {
239
- return BufferGeometryUtils.mergeBufferGeometries(entity.meshes.map(m => m.geometry));
235
+ return mergeBufferGeometries(entity.meshes.map(m => m.geometry));
240
236
  }
241
237
  },
242
238
  createScene: async (solids, options) => {
@@ -283,7 +279,7 @@ export default class CAD {
283
279
  const colorMeshesMap = getDifferentColoredMeshesFromEntity(entity);
284
280
  Object.keys(colorMeshesMap).forEach(key => {
285
281
  const mesh = new Mesh();
286
- mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(colorMeshesMap[key].meshes.map(m => m.geometry));
282
+ mesh.geometry = mergeBufferGeometries(colorMeshesMap[key].meshes.map(m => m.geometry));
287
283
  mesh.material = new MeshStandardMaterial({
288
284
  color: colorMeshesMap[key].color,
289
285
  transparent: colorMeshesMap[key].opacity < 1,
@@ -1,6 +1,6 @@
1
- import { BooleanOperationType, ChamferType, FlipType, ReorientedType, WorkAxisType, WorkCoordSystemType, WorkPlaneType, WorkPointType, ViewType, OrientationType, ExtrusionType, BrepElemType, WorkGeomType, SVGModusType, LimitsParam, LimitedValue } from '@buerli.io/classcad';
2
- import { ObjectIdent, ObjectID, PointMemValue } from '@buerli.io/core';
3
- import { BufferGeometry, Group, Mesh, Scene } from 'three';
1
+ import { BooleanOperationType, ChamferType, FlipType, ReorientedType, WorkAxisType, WorkCoordSystemType, WorkPlaneType, WorkPointType, ViewType, OrientationType, ExtrusionType, WorkGeomType, SVGModusType, LimitsParam, LimitedValue } from '@buerli.io/classcad';
2
+ import { DrawingID, ObjectIdent, ObjectID, PointMemValue, GraphicType, InteractionInfo } from '@buerli.io/core';
3
+ import { BufferGeometry, Material, Object3D, Scene } from 'three';
4
4
  export declare type Vec = number[] | PointMemValue | THREE.Vector3 | THREE.Euler;
5
5
  /**
6
6
  * History based modeling is similar to solid modeling, but it is non-destructive and
@@ -338,13 +338,13 @@ export declare type ApiHistory = {
338
338
  *
339
339
  * // Creates a part template and adds geometry to it
340
340
  * const partTempl1 = await api.createPartAsTemplate('Part_Template1')
341
- * const wcs1 = await api.createWorkCoordSystem(partTempl1, 'Custom', [], offset1, rot, 0, false, 'wcs1')
342
- * const wcs3 = await api.createWorkCoordSystem(partTempl1, 'Custom', [], offset3, rot, 0, false, 'wcs3')
341
+ * const wcs1 = await api.createWorkCoordSystem(partTempl1, WorkCoordSystemType.WCS_Custom, [], offset1, rot, false, 'wcs1')
342
+ * const wcs3 = await api.createWorkCoordSystem(partTempl1, WorkCoordSystemType.WCS_Custom, [], offset3, rot, false, 'wcs3')
343
343
  * api.box(partTempl1, [wcs1], 30, 30, 30)
344
344
  *
345
345
  * // Creates another part template and adds geometry to it
346
346
  * const partTempl2 = await api.createPartAsTemplate('Part_Template2')
347
- * const wcs2 = await api.createWorkCoordSystem(partTempl2, 'Custom', [], offset2, rot, 0, false, 'wcs2')
347
+ * const wcs2 = await api.createWorkCoordSystem(partTempl2, WorkCoordSystemType.WCS_Custom, [], offset2, rot, false, 'wcs2')
348
348
  * api.cone(partTempl2, [wcs2], 30, 0.1, 30)
349
349
  *
350
350
  * // Adds the created part templates as nodes to the root assembly
@@ -397,8 +397,8 @@ export declare type ApiHistory = {
397
397
  *
398
398
  * // Creates a part template and adds geometry to it
399
399
  * const partTempl = await api.createPartAsTemplate('Part_Template')
400
- * const wcs1 = await api.createWorkCoordSystem(partTempl, 'Custom', [], offset1, rot, 0, false, 'wcs')
401
- * const wcs2 = await api.createWorkCoordSystem(partTempl, 'Custom', [], offset2, rot, 0, false, 'wcs')
400
+ * const wcs1 = await api.createWorkCoordSystem(partTempl, WorkCoordSystemType.WCS_Custom, [], offset1, rot, false, 'wcs')
401
+ * const wcs2 = await api.createWorkCoordSystem(partTempl, WorkCoordSystemType.WCS_Custom, [], offset2, rot, false, 'wcs')
402
402
  * api.box(partTempl, [wcs1], 30, 30, 30)
403
403
  *
404
404
  * // Adds the created part template as a node to the root assembly
@@ -610,13 +610,17 @@ export declare type ApiHistory = {
610
610
  * @return object containing all the created THREE objects like scene, nodes, solids and meshes
611
611
  * @example // tbd
612
612
  */
613
- createScene: (productId: VID, options?: {
613
+ createScene: (productId?: VID, options?: {
614
614
  meshPerGeometry?: boolean;
615
+ structureOnly?: boolean;
615
616
  }) => Promise<{
616
617
  scene: Scene;
617
- nodes: Group[];
618
- solids: Group[];
619
- meshes: Mesh[];
618
+ nodes: {
619
+ [key: string]: Object3D;
620
+ };
621
+ materials: {
622
+ [key: string]: Material;
623
+ };
620
624
  }>;
621
625
  /**
622
626
  * Creates one or more expressions.
@@ -655,12 +659,12 @@ export declare type ApiHistory = {
655
659
  *
656
660
  * // Creates a part template and adds geometry to it
657
661
  * const partTempl1 = await api.createPartAsTemplate('Part_Template1')
658
- * const wcs1 = await api.createWorkCoordSystem(partTempl1, 'Custom', [], offset1, rot, 0, false, 'wcs1')
662
+ * const wcs1 = await api.createWorkCoordSystem(partTempl1, WorkCoordSystemType.WCS_Custom, [], offset1, rot, false, 'wcs1')
659
663
  * api.box(partTempl1, [wcs1], 30, 30, 30)
660
664
  *
661
665
  * // Creates another part template and adds geometry to it
662
666
  * const partTempl2 = await api.createPartAsTemplate('Part_Template2')
663
- * const wcs2 = await api.createWorkCoordSystem(partTempl2, 'Custom', [], offset2, rot, 0, false, 'wcs2')
667
+ * const wcs2 = await api.createWorkCoordSystem(partTempl2, WorkCoordSystemType.WCS_Custom, [], offset2, rot, false, 'wcs2')
664
668
  * api.cone(partTempl2, [wcs2], 30, 0.1, 30)
665
669
  *
666
670
  * // Adds the created part templates as nodes to the assembly
@@ -691,7 +695,7 @@ export declare type ApiHistory = {
691
695
  *
692
696
  * // Creates a part template and adds geometry to it
693
697
  * const partTempl = await api.createPartAsTemplate('Part_Template')
694
- * const wcs = await api.createWorkCoordSystem(partTempl, 'Custom', [], offset, rot, 0, false, 'wcs')
698
+ * const wcs = await api.createWorkCoordSystem(partTempl, WorkCoordSystemType.WCS_Custom, [], offset, rot, false, 'wcs')
695
699
  * api.box(partTempl, [wcs], 30, 30, 10)
696
700
  *
697
701
  * // Adds the created part template as a node to the root assembly
@@ -729,7 +733,7 @@ export declare type ApiHistory = {
729
733
  *
730
734
  * // Creates a part template and adds geometry to it
731
735
  * const partTempl = await api.createPartAsTemplate('Part_Template')
732
- * const wcs = await api.createWorkCoordSystem(partTempl, 'Custom', [], offset, rot, 0, false, 'wcs')
736
+ * const wcs = await api.createWorkCoordSystem(partTempl, WorkCoordSystemType.WCS_Custom, [], offset, rot, false, 'wcs')
733
737
  * api.box(partTempl, [wcs], 30, 30, 10)
734
738
  *
735
739
  * // Adds the created part template as a node to the root assembly
@@ -758,7 +762,6 @@ export declare type ApiHistory = {
758
762
  * @param offset offset from work coordinate system in x-, y- and z-direction
759
763
  * @param rotation rotation around x-, y- and z-axis from work coordinate system
760
764
  * @param inverted inverts the constraint between mate1 and mate2
761
- * @param local if true, work coordinate system is set in local coordinates of part???
762
765
  * @param name name of the work coordinate system, if not set default name = 'WorkCoordSystem'
763
766
  * @example
764
767
  * // Defines some consts
@@ -775,13 +778,13 @@ export declare type ApiHistory = {
775
778
  *
776
779
  * // Creates a part template and adds geometry to it
777
780
  * const partTempl1 = await api.createPartAsTemplate('Part_Template1')
778
- * const wcs1 = await api.createWorkCoordSystem(partTempl1, WorkCoordSystemType.WCS_Custom, [], offset1, rot, 0, false, 'wcs1')
779
- * const wcs3 = await api.createWorkCoordSystem(partTempl1, WorkCoordSystemType.WCS_Custom, [], offset3, rot, 0, false, 'wcs3')
781
+ * const wcs1 = await api.createWorkCoordSystem(partTempl1, WorkCoordSystemType.WCS_Custom, [], offset1, rot, false, 'wcs1')
782
+ * const wcs3 = await api.createWorkCoordSystem(partTempl1, WorkCoordSystemType.WCS_Custom, [], offset3, rot, false, 'wcs3')
780
783
  * api.box(partTempl1, [wcs1], 30, 30, 30)
781
784
  *
782
785
  * // Creates another part template and adds geometry to it
783
786
  * const partTempl2 = await api.createPartAsTemplate('Part_Template2')
784
- * const wcs2 = await api.createWorkCoordSystem(partTempl2, WorkCoordSystemType.WCS_Custom, [], offset2, rot, 0, false, 'wcs2')
787
+ * const wcs2 = await api.createWorkCoordSystem(partTempl2, WorkCoordSystemType.WCS_Custom, [], offset2, rot, false, 'wcs2')
785
788
  * api.cone(partTempl2, [wcs2], 30, 0.1, 30)
786
789
  *
787
790
  * // Adds the created part templates as nodes to the root assembly
@@ -793,7 +796,7 @@ export declare type ApiHistory = {
793
796
  * const geoms = await api.createBufferGeometry(rootAsm)
794
797
  * return geoms.map(geom => new THREE.Mesh(geom, new THREE.MeshStandardMaterial()))
795
798
  */
796
- createWorkCoordSystem: (partId: VID, type: WorkCoordSystemType, references: VID[], coordinateSystem: Vec[], offset: Vec, rotation: Vec, inverted: boolean, local: boolean, name?: string) => ID;
799
+ createWorkCoordSystem: (partId: VID, type: WorkCoordSystemType, references: VID[], offset: Vec, rotation: Vec, inverted: boolean, name?: string) => ID;
797
800
  /**
798
801
  * Creates a new work plane for the given part
799
802
  * @param partId id of the part to add the new work plane to
@@ -895,15 +898,27 @@ export declare type ApiHistory = {
895
898
  */
896
899
  fillet: (partId: VID, references: VIDs, radius: number | string) => ID;
897
900
  /**
898
- * Find geometry (vertices, edges, faces, loops) by given positions or selection. If positions parameter is null,
899
- * user can select geometry in graphical interface. For all selected geometries this function logs its
900
- * relevant points into console, to find the geometry later by points
901
- * @param partId id of the part looking for geometry in or selecting them
902
- * @param type type of geometry to find or select
903
- * @param length number of selections to make before resolving the selection
904
- * @param positions array of point arrays where to look for geometry or null if the geometry wants to be selected
901
+ * Important note: To use this method, you need to add the BuerliGeometry component to your application.
902
+ * Otherwise the selection of geometry won't work.
903
+ * @see https://buerli.io/docs/training-for-programmers/More/graphics#3-using-the-buerligeometry-react-component
904
+ *
905
+ * Lets the user select geometry in graphical interface. As soon as the geometry of given type has been selected, the method
906
+ * will return necessary information about it.
907
+ * @see https://buerli.io/docs/training-for-programmers/history/HowTos/useSelectionInHeadless
908
+ * @param types array of types to filter user selection.
909
+ * @param count optional number of selections to make (count must be >= 1). Default = 1.
910
+ */
911
+ selectGeometry: (types: GrT[], count?: number) => Promise<InteractionInfo[]>;
912
+ /**
913
+ * Find geometries of given type on solids in the given part at the given global positions.
914
+ * @param partId Id of the part where geometries tried to be found.
915
+ * @param type Type of the geometry to look for
916
+ * @param positions Array of elements containing one or more positions to look for the geometry
917
+ * @example
918
+ * // Find planes at two different positions
919
+ * const planes = await api.findGeometry(productId, GraphicType.PLANE, [[{x: 50, y: 50, z: 100}], [{x: 100, y: 50, z: 50}]])
905
920
  */
906
- findOrSelect: (partId: VID, type: BrepElemType, length: number, positions: Vec[][] | null) => IDs;
921
+ findGeometry: (partId: VID, type: GrT, positions: Vec[][]) => IDs;
907
922
  /**
908
923
  * Returns the assembly with given name from assembly container.
909
924
  * If asmName is empty, all assemblies from assembly container will be returned.
@@ -1170,14 +1185,18 @@ export declare type ApiHistory = {
1170
1185
  referenceId: VID | ObjectIdent;
1171
1186
  }[]) => Promise<void>;
1172
1187
  /**
1173
- * Transforms the node with referenceId with the given transformation within an assembly
1188
+ * Transforms the nodes with referenceId with the given transformation within an assembly.
1189
+ * The transformations are local to the nodes parent (owner), which is an assembly.
1174
1190
  *
1175
- * @param referenceId id of the node to transform
1176
- * @param ownerId id of the owner (parent) of node we want to transform
1177
- * @param transformation array of three vectors [origin, xAxis, yAxis]
1191
+ * @param nodes array of node parameter objects. See following descriptions.
1192
+ * @param referenceId id or identifier of the node to transform
1193
+ * @param transformation transformation (origin, xDir, yDir) of the node (local to the owner).
1178
1194
  * @example // tbd
1179
1195
  */
1180
- transformNode: (referenceId: VID, ownerId: VID, transformation: Transform) => Promise<void>;
1196
+ transformNodes: (...nodes: {
1197
+ referenceId: VID | ObjectIdent;
1198
+ transformation: Transform;
1199
+ }[]) => Promise<void>;
1181
1200
  /**
1182
1201
  * Translates a feature along a given axis.
1183
1202
  * @param partId id ot the part where features will be translated
@@ -1198,6 +1217,8 @@ export declare type ApiHistory = {
1198
1217
  */
1199
1218
  updateTranslate: (translationId: VID, distance: number) => Promise<void>;
1200
1219
  /**
1220
+ * @deprecated use findGeometry() instead, pick() will be removed in a future release.
1221
+ *
1201
1222
  * Returns found vertices, edges or faces depending on
1202
1223
  * given type an points. Given points define where to look for elements.
1203
1224
  * @param partId id of the part to pick elements
@@ -1251,9 +1272,27 @@ export declare type ApiHistory = {
1251
1272
  * @param refId id of the node to set the constraint on
1252
1273
  */
1253
1274
  getMatePath: (refId: VID) => Promise<ObjectID[]>;
1275
+ /**
1276
+ * Slices the entities of the given operations by the given reference.
1277
+ * @param partId id of the part where the slice will be created
1278
+ * @param operations ids of the operations from which its entities will be sliced
1279
+ * @param reference id of the workplane reference to use for the slice
1280
+ * @param sideFlag flag to toggle which side of the sliced entities will be kept
1281
+ * @return id of the slice operation
1282
+ */
1283
+ slice: (partId: VID, operations: VID[], reference: VID, sideFlag: boolean) => ID;
1284
+ /**
1285
+ * Slices the entity of an operation with a sheet entity of another operation
1286
+ * @param partId id of the part where the slice will be created
1287
+ * @param operationToSlice id of the operation of which its entity will be sliced
1288
+ * @param operationOfSheet id of the operation of which its entity is a sheet and used to slice the entity of operationToSlice
1289
+ * @param sideFlag flag to toggle which side of the sliced entity will be kept
1290
+ * @return id of the slice by sheet operation
1291
+ */
1292
+ sliceBySheet: (partId: VID, operationToSlice: VID, operationOfSheet: VID, sideFlag: boolean) => ID;
1254
1293
  };
1255
1294
  export default class CAD {
1256
- private drawingId;
1295
+ drawingId: DrawingID | null;
1257
1296
  queue: Promise<number>;
1258
1297
  constructor();
1259
1298
  resolve(callback: (...results: any) => Promise<any>, ...args: any[]): Promise<any>;
@@ -1279,6 +1318,7 @@ declare type MateParam = {
1279
1318
  flip: FlipType;
1280
1319
  reoriented: ReorientedType;
1281
1320
  };
1321
+ declare type GrT = GraphicType.POINT | GraphicType.LINE | GraphicType.ARC | GraphicType.CIRCLE | GraphicType.PLANE | GraphicType.CYLINDER | GraphicType.CONE | GraphicType.SPHERE | GraphicType.NURBSCURVE | GraphicType.NURBSSURFACE;
1282
1322
  export declare type Transform = [Point, Point, Point];
1283
1323
  export declare type DimensionType = {
1284
1324
  productId: VID;
@@ -1,4 +1,4 @@
1
- import { ObjectID } from '@buerli.io/core';
1
+ import { DrawingID, ObjectID } from '@buerli.io/core';
2
2
  import { BufferGeometry, Scene, Vector3 } from 'three';
3
3
  /**
4
4
  * A simple and intuitive javascript based api that incorporates solid operations like
@@ -442,7 +442,7 @@ export declare type ApiNoHistory = {
442
442
  */
443
443
  export declare function createPolyline(fPts: FilletPoint[]): Polyline;
444
444
  export default class CAD {
445
- private drawingId;
445
+ drawingId: DrawingID | null;
446
446
  queue: Promise<number>;
447
447
  constructor();
448
448
  resolve(callback: (...results: any) => Promise<any>, ...args: any[]): Promise<any>;
@@ -1,4 +1,4 @@
1
1
  import { SelectedItem } from '@buerli.io/core';
2
2
  declare type CustomSelect<T> = (resolve: (result: T) => Promise<T>, newItems: SelectedItem[], diff: SelectedItem[]) => void;
3
- export declare function waitForSelect<T>(length: number, filter: any, onChange: CustomSelect<T>): Promise<number[]>;
3
+ export declare function waitForSelect<T>(length: number, filter: any, onChange: CustomSelect<T>): Promise<SelectedItem<any>[]>;
4
4
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buerli.io/headless",
3
- "version": "0.7.1-beta.2",
3
+ "version": "0.8.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",
@@ -20,17 +20,19 @@
20
20
  "prettify": "prettier --write \"./{src,tests}/**/*.{js,jsx,ts,tsx,json}\""
21
21
  },
22
22
  "devDependencies": {
23
- "@types/three": "^0.143",
23
+ "@types/three": "^0.152.1",
24
24
  "copyfiles": "^2.1.1",
25
25
  "rimraf": "^2.6.3",
26
- "three": "^0.143",
26
+ "three": "^0.153",
27
+ "three-stdlib": "2.23.5",
27
28
  "typescript": "4.8.4"
28
29
  },
29
30
  "peerDependencies": {
30
- "three": ">=0.138"
31
+ "three": ">=0.138",
32
+ "three-stdlib": ">=2.11.0"
31
33
  },
32
34
  "dependencies": {
33
- "@buerli.io/classcad": "0.7.1-beta.2",
35
+ "@buerli.io/classcad": "0.8.0",
34
36
  "flat-promise": "^1.0.3"
35
37
  }
36
38
  }