@buerli.io/headless 0.2.0-beta.1 → 0.2.1

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.
package/build/solid.d.ts CHANGED
@@ -41,7 +41,7 @@ export declare type ApiNoHistory = {
41
41
  * api.clearSolids()
42
42
  * @image // tbd
43
43
  */
44
- clearSolids: () => ID;
44
+ clearSolids: () => Promise<void>;
45
45
  /**
46
46
  * Clears the target solid in the drawing.
47
47
  * @param solidId id of the solid to be deleted
@@ -54,7 +54,7 @@ export declare type ApiNoHistory = {
54
54
  * const mesh = new THREE.Mesh( geom, new THREE.MeshStandardMaterial({}))
55
55
  * @image // tbd
56
56
  */
57
- clearSolid: (solidId: VID) => ID;
57
+ clearSolid: (solidId: VID) => Promise<void>;
58
58
  /**
59
59
  * Creates a simple cone.
60
60
  * @param height height of the cone (z-axis)
@@ -116,7 +116,7 @@ export declare type ApiNoHistory = {
116
116
  cylinder: (height: number, diameter: number) => ID;
117
117
  /**
118
118
  * Returns all adjacent edges of a face or vertex
119
- * @param target face or vertex id to get the adjacent edges from
119
+ * @param breps face or vertex ids to get the adjacent edges from
120
120
  * @example
121
121
  * // Returns all edges from the top surface of box and adds a fillet on them
122
122
  * const boxId = api.box(10, 25, 15)
@@ -127,7 +127,7 @@ export declare type ApiNoHistory = {
127
127
  * const mesh = new THREE.Mesh(geom, new THREE.MeshStandardMaterial({}))
128
128
  * @image /doc/assets/solid/edgeLoops.jpg
129
129
  */
130
- edgeLoops: (target: VIDs) => IDs;
130
+ edgeLoops: (breps: VIDs) => IDs;
131
131
  /**
132
132
  * Writes the current solid or specific solids to a stream in stp data format
133
133
  * and returns the data.
@@ -157,7 +157,7 @@ export declare type ApiNoHistory = {
157
157
  * const mesh = new THREE.Mesh(geom, new THREE.MeshStandardMaterial({}))
158
158
  * @image /doc/assets/solid/extendSolidAtPlane.jpg
159
159
  */
160
- extendSolidAtPlane: (target: VID, point: Vec, normal: Vec, distance: number) => ID;
160
+ extendSolidAtPlane: (target: VID, point: Vec, normal: Vec, distance: number) => Promise<void>;
161
161
  /**
162
162
  * Creates an extrusion.
163
163
  * @param height height of extrusion
@@ -244,7 +244,7 @@ export declare type ApiNoHistory = {
244
244
  * const mesh = new THREE.Mesh(geom, new THREE.MeshStandardMaterial({}))
245
245
  * @image /doc/assets/solid/mirror.jpg
246
246
  */
247
- mirror: (solidId: VID, point: Vec, normal: Vec) => ID;
247
+ mirror: (solidId: VID, point: Vec, normal: Vec) => Promise<void>;
248
248
  /**
249
249
  * Moves the solid to the given position.
250
250
  * @param solidId id of the solid which will be moved
@@ -259,7 +259,7 @@ export declare type ApiNoHistory = {
259
259
  * const mesh = new THREE.Mesh(geom, new THREE.MeshStandardMaterial({}))
260
260
  * @image /doc/assets/solid/moveTo.jpg
261
261
  */
262
- moveTo: (solidId: VID, position: Vec) => ID;
262
+ moveTo: (solidId: VID, position: Vec) => Promise<void>;
263
263
  /**
264
264
  * Creates an offset of the solid.
265
265
  * @param solidId solid which becomes an offset
@@ -287,12 +287,12 @@ export declare type ApiNoHistory = {
287
287
  * const mesh = new THREE.Mesh(geom, new THREE.MeshStandardMaterial({}))
288
288
  * @image /doc/assets/solid/pick.jpg
289
289
  */
290
- pick: (solidId: VID, type: string, ...points: Vec[]) => IDs;
290
+ pick: (solidId: VID, type: 'vertex' | 'edge' | 'face', ...points: Vec[]) => IDs;
291
291
  /**
292
292
  * Revolves the given region.
293
293
  * @param position position of rotation axis
294
294
  * @param direction direction of rotation axis
295
- * @param angle angle of rotation
295
+ * @param angle angle of rotation in rad
296
296
  * @param region region which will be revolved, defined by Polyline or THREE.Shape
297
297
  * @example
298
298
  * // Creates a closed polyline from three points and revolves it
@@ -318,7 +318,7 @@ export declare type ApiNoHistory = {
318
318
  * const mesh = new THREE.Mesh(geom, new THREE.MeshStandardMaterial({}))
319
319
  * @image /doc/assets/solid/rotateTo.jpg
320
320
  */
321
- rotateTo: (solidId: VID, rotationVec: Vec) => ID;
321
+ rotateTo: (solidId: VID, rotationVec: Vec) => Promise<void>;
322
322
  /**
323
323
  * Writes the current drawing as native file format to a stream and returns the data.
324
324
  * Native file is 'of1', for 'stp' file format use export method.
@@ -348,15 +348,15 @@ export declare type ApiNoHistory = {
348
348
  * const mesh = new THREE.Mesh(geom, new THREE.MeshStandardMaterial({}))
349
349
  * @image /doc/assets/solid/scale.jpg
350
350
  */
351
- scale: (solidId: VID, vectorOrFactor: Vec | number) => ID;
351
+ scale: (solidId: VID, vectorOrFactor: Vec | number) => Promise<void>;
352
352
  /**
353
353
  * Sets the faceting parameters of graphic objects. This defines how detailed solids will be displayed.
354
354
  * @param distanceTol tolerated distance between theoretic and tesselated arc
355
355
  * @param angleTol tolerated angle between normal vectors of faces which build an arc
356
356
  * @example
357
357
  * // Creates a cylinder with low tessellation
358
- * const cylinderId = api.cylinder(50, 20)
359
358
  * api.setFacetingParams(0.5, 0)
359
+ * const cylinderId = api.cylinder(50, 20)
360
360
  * const geom = await api.createBufferGeometry(cylinderId)
361
361
  * const mesh = new THREE.Mesh(geom, new THREE.MeshStandardMaterial({}))
362
362
  * @image /doc/assets/solid/setFacetingParams.jpg
@@ -375,7 +375,7 @@ export declare type ApiNoHistory = {
375
375
  * const mesh = new THREE.Mesh(geom, new THREE.MeshStandardMaterial({}))
376
376
  * @image /doc/assets/solid/slice.jpg
377
377
  */
378
- slice: (solidId: VID, point: Vec, normal: Vec) => ID;
378
+ slice: (solidId: VID, point: Vec, normal: Vec) => Promise<void>;
379
379
  /**
380
380
  * Creates a simple sphere.
381
381
  * @param radius radius of the sphere
@@ -435,6 +435,7 @@ export default class CAD {
435
435
  private drawingId;
436
436
  queue: Promise<number>;
437
437
  constructor();
438
+ resolve(callback: (...results: any) => Promise<any>, ...args: any[]): Promise<any>;
438
439
  init(callback: (api: ApiNoHistory) => void): () => Promise<void>;
439
440
  destroy(): void;
440
441
  }
package/build/solid.js CHANGED
@@ -3,34 +3,19 @@ import { ccAPI } from '@buerli.io/classcad';
3
3
  import { api, getDrawing } from '@buerli.io/core';
4
4
  import { Mesh, MeshStandardMaterial, Scene, Shape } from 'three';
5
5
  import * as BufferGeometryUtils_ from 'three/examples/jsm/utils/BufferGeometryUtils';
6
+ const solidAPI = ccAPI.solid;
6
7
  let BufferGeometryUtils = BufferGeometryUtils_;
7
8
  if (BufferGeometryUtils.BufferGeometryUtils) {
8
9
  BufferGeometryUtils = BufferGeometryUtils.BufferGeometryUtils;
9
10
  }
10
- // Qeued execute, returns the first result and expects it to be an ObjectID or
11
- // a stream, in case of save() or export() is called
12
- const exec = (instance, drawing, namespace, fn, stream, returnStream, ...args) => {
13
- return (instance.queue = instance.queue.then(() => Promise.all(args).then(resolvedArgs => {
14
- return ccAPI.base.callSafeAPI(drawing, namespace, fn, resolvedArgs, stream).then(res => {
15
- if (returnStream) {
16
- return (res && res.results);
17
- }
18
- else {
19
- return (res && res.results[0].result);
20
- }
21
- });
22
- })));
23
- };
24
11
  const toCCVec = (args) => ({ x: args[0], y: args[1], z: args[2] });
12
+ const toCCNbrVec = (args) => ({ x: args[0], y: args[1], z: args[2] });
25
13
  const toArray = (v) => (Array.isArray(v) ? v : v.toArray());
26
14
  const toEuler = (v) => toArray(v);
27
15
  const makeVec = (v) => toCCVec(toArray(v));
16
+ const makeNbrVec = (v) => toCCNbrVec(toArray(v));
28
17
  const makeEuler = (v) => toCCVec(toEuler(v));
29
- const makeBoolean = (instance, drawingId, type) => (target, keepSolid, ...bodies) => {
30
- for (const body of bodies)
31
- exec(instance, drawingId, 'Solid', type, undefined, false, target, keepSolid, body);
32
- return target;
33
- };
18
+ const makeNbrEuler = (v) => toCCNbrVec(toEuler(v));
34
19
  /**
35
20
  * Returns the entity of solid from structure tree
36
21
  * @param drawingId Id of current drawing
@@ -173,7 +158,7 @@ const makeCCData = (curves) => {
173
158
  // [...points]
174
159
  case 'SplineCurve':
175
160
  return [curve.type, curve.points.map((point) => point.toArray())];
176
- // [pA, radii, angles, clockwise, rotation]
161
+ // [pA, radius, angles, clockwise, rotation]
177
162
  case 'EllipseCurve':
178
163
  case 'ArcCurve':
179
164
  const { aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation } = curve;
@@ -196,19 +181,42 @@ export default class CAD {
196
181
  this.queue = Promise.resolve(0);
197
182
  this.queue = Promise.resolve(0);
198
183
  }
184
+ resolve(callback, ...args) {
185
+ return (this.queue = this.queue.then(() => Promise.all(args).then(callback)));
186
+ }
199
187
  init(callback) {
200
188
  const promise = new Promise(async (resolve, reject) => {
201
189
  const drawingId = await ccAPI.base.createCCDrawing('solid');
202
190
  if (!drawingId)
203
191
  throw new Error('Drawing could not be created');
204
192
  this.drawingId = drawingId;
205
- await exec(this, drawingId, 'Solid', 'Init', undefined, false);
193
+ await solidAPI.init(drawingId);
206
194
  const publicApi = {
207
- box: (length, width, height) => exec(this, drawingId, 'Solid', 'CreateBox', undefined, false, length, width, height),
208
- clearSolids: () => exec(this, drawingId, 'Solid', 'ClearSolids', undefined, false),
209
- clearSolid: (target) => exec(this, drawingId, 'Solid', 'ClearSolid', undefined, false, target),
210
- cone: (length, diameter1, diameter2) => exec(this, drawingId, 'Solid', 'CreateCone', undefined, false, length, diameter1, diameter2),
211
- copy: (target) => exec(this, drawingId, 'Solid', 'Copy', undefined, false, target),
195
+ box: (length, width, height) => {
196
+ return this.resolve(async () => {
197
+ return solidAPI.createBox(drawingId, length, width, height);
198
+ });
199
+ },
200
+ clearSolids: () => {
201
+ return this.resolve(async () => {
202
+ return solidAPI.clearSolids(drawingId);
203
+ });
204
+ },
205
+ clearSolid: (target) => {
206
+ return this.resolve(async ([rTarget]) => {
207
+ return solidAPI.clearSolid(drawingId, rTarget);
208
+ }, target);
209
+ },
210
+ cone: (length, diameter1, diameter2) => {
211
+ return this.resolve(async () => {
212
+ return solidAPI.createCone(drawingId, length, diameter1, diameter2);
213
+ });
214
+ },
215
+ copy: (target) => {
216
+ return this.resolve(async ([rTarget]) => {
217
+ return solidAPI.copy(drawingId, rTarget);
218
+ }, target);
219
+ },
212
220
  createBufferGeometry: async (solid) => {
213
221
  await this.queue;
214
222
  this.queue = Promise.resolve(0);
@@ -227,6 +235,7 @@ export default class CAD {
227
235
  const entity = await getEntity(drawingId, rSolid);
228
236
  const group = new Scene();
229
237
  group.userData = { id: rSolid };
238
+ group.name = 'Solid';
230
239
  if (entity != null) {
231
240
  for (const mesh of entity.meshes) {
232
241
  group.add(new Mesh(mesh.geometry, new MeshStandardMaterial({
@@ -238,78 +247,150 @@ export default class CAD {
238
247
  }
239
248
  return group;
240
249
  },
241
- cylinder: (length, diameter) => exec(this, drawingId, 'Solid', 'CreateCylinder', undefined, false, length, diameter),
242
- edgeLoops: (target) => exec(this, drawingId, 'Solid', 'EdgeLoops', undefined, false, target).then(async (id) => {
243
- return Array.isArray(id) ? id : [id];
244
- }),
245
- export: (solidIds) => exec(this, drawingId, 'Solid', 'Export', undefined, true, null, 'stp', solidIds).then(async (resp) => {
246
- if (resp && resp[0].result) {
247
- const res = resp[0];
248
- const key = res.result;
249
- if (key && res.streamData) {
250
- return res.streamData[key] || null;
251
- }
252
- }
253
- }),
254
- extendSolidAtPlane: (target, point, normal, distance) => exec(this, drawingId, 'Solid', 'SolidExtendAtPlane', undefined, false, target, makeVec(point), makeVec(normal), distance),
250
+ cylinder: (length, diameter) => {
251
+ return this.resolve(async () => {
252
+ return solidAPI.createCylinder(drawingId, length, diameter);
253
+ });
254
+ },
255
+ edgeLoops: (breps) => {
256
+ return this.resolve(async ([rBreps]) => {
257
+ return solidAPI.edgeLoops(drawingId, rBreps);
258
+ }, breps);
259
+ },
260
+ export: (solidIds) => {
261
+ return this.resolve(async ([rSolidIds]) => {
262
+ return solidAPI.export(drawingId, 'stp', rSolidIds);
263
+ }, solidIds);
264
+ },
265
+ extendSolidAtPlane: (target, point, normal, distance) => {
266
+ return this.resolve(async ([rTarget]) => {
267
+ return solidAPI.solidExtendAtPlane(drawingId, rTarget, makeNbrVec(point), makeNbrVec(normal), distance);
268
+ }, target);
269
+ },
255
270
  extrude: (height, region) => {
256
- if (region instanceof Shape) {
257
- const curveArray = makeCCData(region.curves);
258
- return exec(this, drawingId, 'Solid', 'CreateExtrudeRegion', undefined, false, makeVec(height), curveArray);
259
- }
260
- else {
261
- return exec(this, drawingId, 'Solid', 'CreateExtrude', undefined, false, makeVec(height), region.points, region.bulges);
262
- }
271
+ return this.resolve(async () => {
272
+ if (region instanceof Shape) {
273
+ const curveArray = makeCCData(region.curves);
274
+ return solidAPI.createExtrudeRegion(drawingId, makeNbrVec(height), curveArray);
275
+ }
276
+ else {
277
+ return solidAPI.createExtrude(drawingId, makeNbrVec(height), region.points, region.bulges);
278
+ }
279
+ });
263
280
  },
264
- fillet: (radius, edges) => exec(this, drawingId, 'Solid', 'CreateFillet', undefined, false, radius, edges),
265
- import: (data) => exec(this, drawingId, 'Solid', 'Import', { data }, false, 'data', 'stp').then(async (id) => {
266
- return Array.isArray(id) ? id : [id];
267
- }),
268
- intersect: makeBoolean(this, drawingId, 'Intersect'),
269
- load: (data) => exec(this, drawingId, 'Solid', 'Load', { data }, false, 'data', 'of1', true).then(async (id) => {
270
- if (id !== null) {
271
- const drawing = getDrawing(drawingId);
272
- const solids = drawing.structure.tree[id].solids;
273
- if (solids !== undefined) {
274
- return solids.map(innerId => drawing.graphic.containers[innerId].owner);
281
+ fillet: (radius, edges) => {
282
+ return this.resolve(async ([rEdges]) => {
283
+ return solidAPI.createFillet(drawingId, radius, rEdges);
284
+ }, edges);
285
+ },
286
+ import: (data) => {
287
+ return this.resolve(async () => {
288
+ return solidAPI.import(drawingId, data, 'stp');
289
+ });
290
+ },
291
+ intersect: (solidId, keepSolid, ...bodies) => {
292
+ return this.resolve(async ([rSolidId, ...rBodies]) => {
293
+ for (const rBody of rBodies) {
294
+ solidAPI.intersect(drawingId, rSolidId, keepSolid, rBody);
275
295
  }
276
- }
277
- return [];
278
- }),
279
- mirror: (target, point, normal) => exec(this, drawingId, 'Solid', 'Mirror', undefined, false, target, makeVec(point), makeVec(normal)),
280
- moveTo: (target, position) => exec(this, drawingId, 'Solid', 'MoveTo', undefined, false, target, makeVec(position)),
281
- offset: (target, offsetDistance) => exec(this, drawingId, 'Solid', 'Offset', undefined, false, target, offsetDistance),
282
- pick: (target, type, ...points) => exec(this, drawingId, 'Solid', 'Pick', undefined, false, target, type, points.map(makeVec)).then(async (id) => {
283
- return Array.isArray(id) ? id : [id];
284
- }),
285
- revolve: (position, direction, angle, region) => {
286
- if (region instanceof Shape) {
287
- const curveArray = makeCCData(region.curves);
288
- return exec(this, drawingId, 'Solid', 'CreateRevolveRegion', undefined, false, makeVec(position), makeVec(direction), angle, curveArray);
289
- }
290
- else {
291
- return exec(this, drawingId, 'Solid', 'CreateRevolve', undefined, false, makeVec(position), makeVec(direction), (angle / Math.PI) * 180, region.points, region.bulges);
292
- }
296
+ return rSolidId;
297
+ }, solidId, ...bodies);
293
298
  },
294
- rotateTo: (target, point) => exec(this, drawingId, 'Solid', 'RotateTo', undefined, false, target, makeEuler(point)),
295
- save: () => exec(this, drawingId, 'Solid', 'Save', undefined, true, null, 'of1').then(async (resp) => {
296
- if (resp && resp[0].result) {
297
- const res = resp[0];
298
- const key = res.result;
299
- if (key && res.streamData) {
300
- return res.streamData[key] || null;
299
+ load: (data) => {
300
+ return this.resolve(async () => {
301
+ const productId = await solidAPI.load(drawingId, data, 'of1', true);
302
+ if (productId !== null) {
303
+ const drawing = getDrawing(drawingId);
304
+ const solids = drawing.structure.tree[productId].solids;
305
+ if (solids !== undefined) {
306
+ return solids.map(innerId => drawing.graphic.containers[innerId].owner);
307
+ }
301
308
  }
302
- }
303
- }),
309
+ return [];
310
+ });
311
+ },
312
+ mirror: (target, point, normal) => {
313
+ return this.resolve(async ([rTarget]) => {
314
+ return solidAPI.mirror(drawingId, rTarget, makeNbrVec(point), makeNbrEuler(normal));
315
+ }, target);
316
+ },
317
+ moveTo: (target, position) => {
318
+ return this.resolve(async ([rTarget]) => {
319
+ return solidAPI.moveTo(drawingId, rTarget, makeNbrVec(position));
320
+ }, target);
321
+ },
322
+ offset: (target, offsetDistance) => {
323
+ return this.resolve(async ([rTarget]) => {
324
+ return solidAPI.offset(drawingId, rTarget, offsetDistance);
325
+ }, target);
326
+ },
327
+ pick: (target, type, ...points) => {
328
+ return this.resolve(async ([rTarget]) => {
329
+ const pts = points.map(pt => makeNbrVec(pt));
330
+ const breps = await solidAPI.pick(drawingId, rTarget, type, ...pts);
331
+ if (breps !== null) {
332
+ return Array.isArray(breps) ? breps : [breps];
333
+ }
334
+ }, target);
335
+ },
336
+ revolve: (position, direction, angle, region) => {
337
+ return this.resolve(async () => {
338
+ if (region instanceof Shape) {
339
+ const curveArray = makeCCData(region.curves);
340
+ return solidAPI.createRevolveRegion(drawingId, makeNbrVec(position), makeNbrVec(direction), angle, curveArray);
341
+ }
342
+ else {
343
+ return solidAPI.createRevolve(drawingId, makeNbrVec(position), makeNbrVec(direction), (angle / Math.PI) * 180, region.points, region.bulges);
344
+ }
345
+ });
346
+ },
347
+ rotateTo: (target, point) => {
348
+ return this.resolve(async ([rTarget]) => {
349
+ return solidAPI.rotateTo(drawingId, rTarget, makeNbrEuler(point));
350
+ }, target);
351
+ },
352
+ save: () => {
353
+ return this.resolve(async () => {
354
+ return solidAPI.save(drawingId, 'of1');
355
+ });
356
+ },
304
357
  scale: (target, pointOrFactor) => {
305
- const lPointOrFactor = typeof pointOrFactor === 'number' ? pointOrFactor : makeVec(pointOrFactor);
306
- return exec(this, drawingId, 'Solid', 'Scale', undefined, false, target, lPointOrFactor);
358
+ return this.resolve(async ([rTarget]) => {
359
+ const lPointOrFactor = typeof pointOrFactor === 'number' ? pointOrFactor : makeNbrVec(pointOrFactor);
360
+ return solidAPI.scale(drawingId, rTarget, lPointOrFactor);
361
+ }, target);
362
+ },
363
+ setFacetingParams: (distanceTol, angleTol) => {
364
+ return this.resolve(async () => {
365
+ return ccAPI.common.setFacetingParameters(drawingId, distanceTol, angleTol);
366
+ });
367
+ },
368
+ slice: (target, point, normal) => {
369
+ return this.resolve(async ([rTarget]) => {
370
+ return solidAPI.slice(drawingId, rTarget, makeNbrVec(point), makeNbrVec(normal));
371
+ }, target);
372
+ },
373
+ sphere: (radius) => {
374
+ return this.resolve(async () => {
375
+ return solidAPI.createSphere(drawingId, radius);
376
+ });
377
+ },
378
+ subtract: (solidId, keepSolid, ...bodies) => {
379
+ return this.resolve(async ([rSolidId, ...rBodies]) => {
380
+ for (const rBody of rBodies) {
381
+ solidAPI.subtract(drawingId, rSolidId, keepSolid, rBody);
382
+ }
383
+ return rSolidId;
384
+ }, solidId, ...bodies);
385
+ },
386
+ union: (solidId, keepSolid, ...bodies) => {
387
+ return this.resolve(async ([rSolidId, ...rBodies]) => {
388
+ for (const rBody of rBodies) {
389
+ solidAPI.union(drawingId, rSolidId, keepSolid, rBody);
390
+ }
391
+ return rSolidId;
392
+ }, solidId, ...bodies);
307
393
  },
308
- setFacetingParams: (distanceTol, angleTol) => exec(this, drawingId, 'BaseModeler', 'SetFacetingParams', undefined, false, distanceTol, angleTol),
309
- slice: (target, point, normal) => exec(this, drawingId, 'Solid', 'Slice', undefined, false, target, makeVec(point), makeVec(normal)),
310
- sphere: (radius) => exec(this, drawingId, 'Solid', 'CreateSphere', undefined, false, radius),
311
- subtract: makeBoolean(this, drawingId, 'Subtract'),
312
- union: makeBoolean(this, drawingId, 'Union'),
313
394
  };
314
395
  callback(publicApi);
315
396
  resolve(drawingId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buerli.io/headless",
3
- "version": "0.2.0-beta.1",
3
+ "version": "0.2.1",
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",
@@ -29,6 +29,6 @@
29
29
  "three": ">=0.138"
30
30
  },
31
31
  "dependencies": {
32
- "@buerli.io/classcad": "0.2.0-beta.1"
32
+ "@buerli.io/classcad": "0.2.1"
33
33
  }
34
34
  }