@buerli.io/headless 0.0.33 → 0.0.35-beta.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.
- package/build/cjs/history.js +814 -0
- package/build/cjs/index.js +31 -0
- package/build/cjs/solid.js +352 -0
- package/build/{history.js → esm/history.js} +47 -14
- package/build/{index.js → esm/index.js} +0 -0
- package/build/{solid.js → esm/solid.js} +7 -3
- package/build/{history.d.ts → types/history.d.ts} +31 -4
- package/build/{index.d.ts → types/index.d.ts} +2 -1
- package/build/{solid.d.ts → types/solid.d.ts} +0 -0
- package/package.json +10 -8
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.createPolyline = exports.history = exports.solid = void 0;
|
|
26
|
+
const history_1 = __importDefault(require("./history"));
|
|
27
|
+
exports.history = history_1.default;
|
|
28
|
+
const solid_1 = __importStar(require("./solid"));
|
|
29
|
+
exports.solid = solid_1.default;
|
|
30
|
+
Object.defineProperty(exports, "createPolyline", { enumerable: true, get: function () { return solid_1.createPolyline; } });
|
|
31
|
+
//#endregion Re-export type definitions
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.createPolyline = void 0;
|
|
23
|
+
/* eslint-disable max-lines */
|
|
24
|
+
const classcad_1 = require("@buerli.io/classcad");
|
|
25
|
+
const core_1 = require("@buerli.io/core");
|
|
26
|
+
const three_1 = require("three");
|
|
27
|
+
const BufferGeometryUtils_ = __importStar(require("three/examples/jsm/utils/BufferGeometryUtils"));
|
|
28
|
+
let BufferGeometryUtils = BufferGeometryUtils_;
|
|
29
|
+
if (BufferGeometryUtils.BufferGeometryUtils) {
|
|
30
|
+
BufferGeometryUtils = BufferGeometryUtils.BufferGeometryUtils;
|
|
31
|
+
}
|
|
32
|
+
// Qeued execute, returns the first result and expects it to be an ObjectID or
|
|
33
|
+
// a stream, in case of save() or export() is called
|
|
34
|
+
const exec = (instance, drawing, namespace, fn, stream, returnStream, ...args) => {
|
|
35
|
+
return (instance.queue = instance.queue.then(() => Promise.all(args).then(resolvedArgs => {
|
|
36
|
+
return classcad_1.ccAPI.base.callSafeAPI(drawing, namespace, fn, resolvedArgs, stream).then(res => {
|
|
37
|
+
if (returnStream) {
|
|
38
|
+
return (res && res.results);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return (res && res.results[0].result);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
})));
|
|
45
|
+
};
|
|
46
|
+
const toCCVec = (args) => ({ x: args[0], y: args[1], z: args[2] });
|
|
47
|
+
const toArray = (v) => (Array.isArray(v) ? v : v.toArray());
|
|
48
|
+
const toEuler = (v) => toArray(v);
|
|
49
|
+
const makeVec = (v) => toCCVec(toArray(v));
|
|
50
|
+
const makeEuler = (v) => toCCVec(toEuler(v));
|
|
51
|
+
const makeBoolean = (instance, drawingId, type) => (target, keepSolid, ...bodies) => {
|
|
52
|
+
for (const body of bodies)
|
|
53
|
+
exec(instance, drawingId, 'Solid', type, undefined, false, target, keepSolid, body);
|
|
54
|
+
return target;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Returns the entity of solid from structure tree
|
|
58
|
+
* @param drawingId Id of current drawing
|
|
59
|
+
* @param solid Solid to get entity from
|
|
60
|
+
*/
|
|
61
|
+
const getEntity = async (drawingId, solid) => {
|
|
62
|
+
const rSolid = await solid;
|
|
63
|
+
const cDrawing = core_1.getDrawing(drawingId);
|
|
64
|
+
const object = cDrawing.structure.tree[rSolid];
|
|
65
|
+
if (object != undefined) {
|
|
66
|
+
const entities = object.geometryIdList;
|
|
67
|
+
if (entities != undefined && entities.length > 0) {
|
|
68
|
+
return cDrawing.geometry.cache[entities[0]];
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
console.warn(`There is no cached entry for ${rSolid}!`, cDrawing.geometry.cache);
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
console.warn(`There is no cached entry for ${rSolid}!`, cDrawing.geometry.cache);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Returns the adjacent points of the fillet arc. These are the points where fillet arc tangentially touches the lines.
|
|
82
|
+
* @param info contains all information for the fillet, like start- and endpoints of adjacent lines and control point
|
|
83
|
+
* @param radius radius of the fillet arc
|
|
84
|
+
*/
|
|
85
|
+
const getTouchPoints = (info, radius) => {
|
|
86
|
+
const controlPos = info.control;
|
|
87
|
+
const linearTolerance = 1e-3;
|
|
88
|
+
const dirs = [];
|
|
89
|
+
const maxDists = [];
|
|
90
|
+
for (let i = 0; i < 2; i++) {
|
|
91
|
+
const startPos = info.lineStarts[i];
|
|
92
|
+
const endPos = info.lineEnds[i];
|
|
93
|
+
const dir = endPos
|
|
94
|
+
.clone()
|
|
95
|
+
.sub(startPos)
|
|
96
|
+
.normalize();
|
|
97
|
+
const maxDist = endPos.distanceTo(controlPos);
|
|
98
|
+
dirs.push(dir);
|
|
99
|
+
maxDists.push(maxDist);
|
|
100
|
+
}
|
|
101
|
+
if (radius + linearTolerance >= Math.min(maxDists[0], maxDists[1])) {
|
|
102
|
+
return null; // too large fillet
|
|
103
|
+
}
|
|
104
|
+
// Calculate distance from controlpt to touchpoint
|
|
105
|
+
const scalar = Math.abs(radius / Math.tan(getIncludingAngle(info) / 2));
|
|
106
|
+
return dirs.map(dir => dir
|
|
107
|
+
.clone()
|
|
108
|
+
.multiplyScalar(scalar)
|
|
109
|
+
.add(controlPos));
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Calculates the including angle between two lines. The angle is measured from first to second line counterclockwise. If angle exceeds 180°, measuring is clockwise but negative angle
|
|
113
|
+
* @param info Info contains information about lines
|
|
114
|
+
*/
|
|
115
|
+
const getIncludingAngle = (info) => {
|
|
116
|
+
// First line (line to point)
|
|
117
|
+
const line1 = info.lineEnds[0]
|
|
118
|
+
.clone()
|
|
119
|
+
.sub(info.lineStarts[0])
|
|
120
|
+
.normalize();
|
|
121
|
+
// Second line (line from point)
|
|
122
|
+
const line2 = info.lineEnds[1]
|
|
123
|
+
.clone()
|
|
124
|
+
.sub(info.lineStarts[1])
|
|
125
|
+
.normalize();
|
|
126
|
+
// Angle, measured from first line to second line counterclockwise.
|
|
127
|
+
// If angle exceeds 180°, measuring is clockwise but negative angle
|
|
128
|
+
const angle = Math.atan2(line1.x * line2.y - line1.y * line2.x, line1.x * line2.x + line1.y * line2.y);
|
|
129
|
+
return angle;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Calculates and returns the including angle between the touchpoints of the fillet. Attention: It is the angle of touchpoints and center of fillet arc and not the one between touchpoints and control point.
|
|
133
|
+
* @param info
|
|
134
|
+
*/
|
|
135
|
+
const getIncludingBulgeAngle = (info) => {
|
|
136
|
+
// angle of first line, control point and second line
|
|
137
|
+
const angle = getIncludingAngle(info);
|
|
138
|
+
// Opposite angle of the angle which was calculated from control point and its adjacent lines
|
|
139
|
+
const oppositeAngle = Math.PI - Math.abs(angle);
|
|
140
|
+
const sign = angle / Math.abs(angle);
|
|
141
|
+
return oppositeAngle * sign * -1; // -1 because of bulges definition
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Creates a polyline from the given fillet points
|
|
145
|
+
* @param fPts points of the polyline with its associated fillet radius
|
|
146
|
+
* @example
|
|
147
|
+
* // Creates a polyline with three points
|
|
148
|
+
* const fp0 = { point: new THREE.Vector3(20, 20, 0), radius: 4 }
|
|
149
|
+
* const fp1 = { point: new THREE.Vector3(40, 0, 0), radius: 2 }
|
|
150
|
+
* const fp2 = { point: new THREE.Vector3(0, 0, 0), radius: 2 }
|
|
151
|
+
* const polyline = createPolyline([fp0, fp1, fp2])
|
|
152
|
+
*/
|
|
153
|
+
function createPolyline(fPts) {
|
|
154
|
+
const newVertices = [];
|
|
155
|
+
const newBulges = [];
|
|
156
|
+
for (let i = 0; i < fPts.length; i++) {
|
|
157
|
+
// if fillet point has radius, calculate fillet info, touchpoints and bulge
|
|
158
|
+
if (fPts[i].radius > 0) {
|
|
159
|
+
const j = i - 1 < 0 ? fPts.length - 1 : i - 1;
|
|
160
|
+
const k = i + 1 > fPts.length - 1 ? 0 : i + 1;
|
|
161
|
+
const filletInfo = {
|
|
162
|
+
control: fPts[i].point,
|
|
163
|
+
lineStarts: [fPts[i].point, fPts[i].point],
|
|
164
|
+
lineEnds: [fPts[j].point, fPts[k].point],
|
|
165
|
+
};
|
|
166
|
+
const touchPts = getTouchPoints(filletInfo, fPts[i].radius); // returns two points
|
|
167
|
+
if (touchPts != undefined && (touchPts === null || touchPts === void 0 ? void 0 : touchPts.length) > 0) {
|
|
168
|
+
const angle = getIncludingBulgeAngle(filletInfo);
|
|
169
|
+
const bulge = Math.tan(angle / 4);
|
|
170
|
+
newVertices.push(...touchPts);
|
|
171
|
+
newBulges.push(bulge); // bulge for first point
|
|
172
|
+
newBulges.push(0); // bulge for second point
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
newVertices.push(fPts[i].point);
|
|
177
|
+
newBulges.push(0);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return { points: newVertices, bulges: newBulges };
|
|
181
|
+
}
|
|
182
|
+
exports.createPolyline = createPolyline;
|
|
183
|
+
/**
|
|
184
|
+
* Creates the specific curve array from THREE.Shape.curves to draw the region in ClassCAD. It contains the type and all necessary points and control points in a multidimensional array.
|
|
185
|
+
* @param curves THREE.Shape.curves
|
|
186
|
+
*/
|
|
187
|
+
const makeCCData = (curves) => {
|
|
188
|
+
return curves.map((curve) => {
|
|
189
|
+
switch (curve.type) {
|
|
190
|
+
// [pStart, p1, p2, p3]
|
|
191
|
+
case 'CubicBezierCurve':
|
|
192
|
+
return [curve.type, curve.v0.toArray(), curve.v1.toArray(), curve.v2.toArray(), curve.v3.toArray()];
|
|
193
|
+
// [pStart, p1, p2]
|
|
194
|
+
case 'QuadraticBezierCurve':
|
|
195
|
+
return [curve.type, curve.v0.toArray(), curve.v1.toArray(), curve.v2.toArray()];
|
|
196
|
+
// [p1, p2]
|
|
197
|
+
case 'LineCurve':
|
|
198
|
+
return [curve.type, curve.v1.toArray(), curve.v2.toArray()];
|
|
199
|
+
// [...points]
|
|
200
|
+
case 'SplineCurve':
|
|
201
|
+
return [curve.type, curve.points.map((point) => point.toArray())];
|
|
202
|
+
// [pA, radii, angles, clockwise, rotation]
|
|
203
|
+
case 'EllipseCurve':
|
|
204
|
+
case 'ArcCurve':
|
|
205
|
+
const { aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation } = curve;
|
|
206
|
+
return [
|
|
207
|
+
curve.type,
|
|
208
|
+
[aX, aY],
|
|
209
|
+
[xRadius, yRadius],
|
|
210
|
+
[(aStartAngle / Math.PI) * 180, (aEndAngle / Math.PI) * 180],
|
|
211
|
+
aClockwise,
|
|
212
|
+
aRotation,
|
|
213
|
+
];
|
|
214
|
+
default:
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
};
|
|
219
|
+
class CAD {
|
|
220
|
+
constructor(target) {
|
|
221
|
+
this.drawingId = null;
|
|
222
|
+
this.queue = Promise.resolve(0);
|
|
223
|
+
this.queue = Promise.resolve(0);
|
|
224
|
+
if (typeof target !== 'string')
|
|
225
|
+
this.target = target;
|
|
226
|
+
core_1.init({ url: typeof target === 'string' ? target : '' });
|
|
227
|
+
}
|
|
228
|
+
init(callback) {
|
|
229
|
+
const promise = new Promise(async (resolve, reject) => {
|
|
230
|
+
const drawingId = await classcad_1.ccAPI.base.createCCDrawing('solid', this.target);
|
|
231
|
+
if (!drawingId)
|
|
232
|
+
throw new Error('Drawing could not be created');
|
|
233
|
+
this.drawingId = drawingId;
|
|
234
|
+
await exec(this, drawingId, 'Solid', 'Init', undefined, false);
|
|
235
|
+
const publicApi = {
|
|
236
|
+
box: (length, width, height) => exec(this, drawingId, 'Solid', 'CreateBox', undefined, false, length, width, height),
|
|
237
|
+
clearSolids: () => exec(this, drawingId, 'Solid', 'ClearSolids', undefined, false),
|
|
238
|
+
clearSolid: (target) => exec(this, drawingId, 'Solid', 'ClearSolid', undefined, false, target),
|
|
239
|
+
cone: (length, diameter1, diameter2) => exec(this, drawingId, 'Solid', 'CreateCone', undefined, false, length, diameter1, diameter2),
|
|
240
|
+
copy: (target) => exec(this, drawingId, 'Solid', 'Copy', undefined, false, target),
|
|
241
|
+
createBufferGeometry: async (solid) => {
|
|
242
|
+
await this.queue;
|
|
243
|
+
this.queue = Promise.resolve(0);
|
|
244
|
+
const rSolid = await solid;
|
|
245
|
+
await classcad_1.ccAPI.baseModeler.requestVisualisationOfObject(drawingId, rSolid);
|
|
246
|
+
const entity = await getEntity(drawingId, rSolid);
|
|
247
|
+
if (entity != null) {
|
|
248
|
+
return BufferGeometryUtils.mergeBufferGeometries(entity.meshes.map(m => m.geometry));
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
createScene: async (solid) => {
|
|
252
|
+
await this.queue;
|
|
253
|
+
this.queue = Promise.resolve(0);
|
|
254
|
+
const rSolid = await solid;
|
|
255
|
+
await classcad_1.ccAPI.baseModeler.requestVisualisationOfObject(drawingId, rSolid);
|
|
256
|
+
const entity = await getEntity(drawingId, rSolid);
|
|
257
|
+
const group = new three_1.Scene();
|
|
258
|
+
group.userData = { id: rSolid };
|
|
259
|
+
if (entity != null) {
|
|
260
|
+
for (const mesh of entity.meshes) {
|
|
261
|
+
group.add(new three_1.Mesh(mesh.geometry, new three_1.MeshStandardMaterial({
|
|
262
|
+
color: mesh.color,
|
|
263
|
+
transparent: mesh.opacity < 1,
|
|
264
|
+
opacity: mesh.opacity,
|
|
265
|
+
})));
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return group;
|
|
269
|
+
},
|
|
270
|
+
cylinder: (length, diameter) => exec(this, drawingId, 'Solid', 'CreateCylinder', undefined, false, length, diameter),
|
|
271
|
+
edgeLoops: (target) => exec(this, drawingId, 'Solid', 'EdgeLoops', undefined, false, target).then(async (id) => {
|
|
272
|
+
return Array.isArray(id) ? id : [id];
|
|
273
|
+
}),
|
|
274
|
+
export: (solidIds) => exec(this, drawingId, 'Solid', 'Export', undefined, true, null, 'stp', solidIds).then(async (resp) => {
|
|
275
|
+
if (resp && resp[0].result) {
|
|
276
|
+
const res = resp[0];
|
|
277
|
+
const key = res.result;
|
|
278
|
+
if (key && res.streamData) {
|
|
279
|
+
return res.streamData[key] || null;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}),
|
|
283
|
+
extendSolidAtPlane: (target, point, normal, distance) => exec(this, drawingId, 'Solid', 'SolidExtendAtPlane', undefined, false, target, makeVec(point), makeVec(normal), distance),
|
|
284
|
+
extrude: (height, region) => {
|
|
285
|
+
if (region instanceof three_1.Shape) {
|
|
286
|
+
const curveArray = makeCCData(region.curves);
|
|
287
|
+
return exec(this, drawingId, 'Solid', 'CreateExtrudeRegion', undefined, false, makeVec(height), curveArray);
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
return exec(this, drawingId, 'Solid', 'CreateExtrude', undefined, false, makeVec(height), region.points, region.bulges);
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
fillet: (radius, edges) => exec(this, drawingId, 'Solid', 'CreateFillet', undefined, false, radius, edges),
|
|
294
|
+
import: (data) => exec(this, drawingId, 'Solid', 'Import', { data }, false, 'data', 'stp').then(async (id) => {
|
|
295
|
+
return Array.isArray(id) ? id : [id];
|
|
296
|
+
}),
|
|
297
|
+
intersect: makeBoolean(this, drawingId, 'Intersect'),
|
|
298
|
+
load: (data) => exec(this, drawingId, 'Solid', 'Load', { data }, false, 'data', 'of1', true).then(async (id) => {
|
|
299
|
+
if (id !== null) {
|
|
300
|
+
const drawing = core_1.getDrawing(drawingId);
|
|
301
|
+
const solids = drawing.structure.tree[id].solids;
|
|
302
|
+
if (solids !== undefined) {
|
|
303
|
+
return solids.map(innerId => drawing.graphic.containers[innerId].owner);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return [];
|
|
307
|
+
}),
|
|
308
|
+
mirror: (target, point, normal) => exec(this, drawingId, 'Solid', 'Mirror', undefined, false, target, makeVec(point), makeVec(normal)),
|
|
309
|
+
moveTo: (target, position) => exec(this, drawingId, 'Solid', 'MoveTo', undefined, false, target, makeVec(position)),
|
|
310
|
+
offset: (target, offsetDistance) => exec(this, drawingId, 'Solid', 'Offset', undefined, false, target, offsetDistance),
|
|
311
|
+
pick: (target, type, ...points) => exec(this, drawingId, 'Solid', 'Pick', undefined, false, target, type, points.map(makeVec)).then(async (id) => {
|
|
312
|
+
return Array.isArray(id) ? id : [id];
|
|
313
|
+
}),
|
|
314
|
+
revolve: (position, direction, angle, region) => {
|
|
315
|
+
if (region instanceof three_1.Shape) {
|
|
316
|
+
const curveArray = makeCCData(region.curves);
|
|
317
|
+
return exec(this, drawingId, 'Solid', 'CreateRevolveRegion', undefined, false, makeVec(position), makeVec(direction), angle, curveArray);
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
return exec(this, drawingId, 'Solid', 'CreateRevolve', undefined, false, makeVec(position), makeVec(direction), (angle / Math.PI) * 180, region.points, region.bulges);
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
rotateTo: (target, point) => exec(this, drawingId, 'Solid', 'RotateTo', undefined, false, target, makeEuler(point)),
|
|
324
|
+
save: () => exec(this, drawingId, 'Solid', 'Save', undefined, true, null, 'of1').then(async (resp) => {
|
|
325
|
+
if (resp && resp[0].result) {
|
|
326
|
+
const res = resp[0];
|
|
327
|
+
const key = res.result;
|
|
328
|
+
if (key && res.streamData) {
|
|
329
|
+
return res.streamData[key] || null;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}),
|
|
333
|
+
scale: (target, pointOrFactor) => {
|
|
334
|
+
const lPointOrFactor = typeof pointOrFactor === 'number' ? pointOrFactor : makeVec(pointOrFactor);
|
|
335
|
+
return exec(this, drawingId, 'Solid', 'Scale', undefined, false, target, lPointOrFactor);
|
|
336
|
+
},
|
|
337
|
+
setFacetingParams: (distanceTol, angleTol) => exec(this, drawingId, 'BaseModeler', 'SetFacetingParams', undefined, false, distanceTol, angleTol),
|
|
338
|
+
slice: (target, point, normal) => exec(this, drawingId, 'Solid', 'Slice', undefined, false, target, makeVec(point), makeVec(normal)),
|
|
339
|
+
sphere: (radius) => exec(this, drawingId, 'Solid', 'CreateSphere', undefined, false, radius),
|
|
340
|
+
subtract: makeBoolean(this, drawingId, 'Subtract'),
|
|
341
|
+
union: makeBoolean(this, drawingId, 'Union'),
|
|
342
|
+
};
|
|
343
|
+
callback(publicApi);
|
|
344
|
+
resolve(drawingId);
|
|
345
|
+
});
|
|
346
|
+
return () => promise.then(drawingId => core_1.api.getState().api.removeDrawing(drawingId));
|
|
347
|
+
}
|
|
348
|
+
destroy() {
|
|
349
|
+
this.drawingId && core_1.api.getState().api.removeDrawing(this.drawingId);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
exports.default = CAD;
|
|
@@ -2,8 +2,12 @@
|
|
|
2
2
|
import { BooleanOperationType, ccAPI, CCClasses, ccUtils, ChamferType, DataType, WorkAxisType, WorkCoordSystemType, WorkPlaneType, WorkPointType } from '@buerli.io/classcad';
|
|
3
3
|
import { api, getDrawing, init, MathUtils, } from '@buerli.io/core';
|
|
4
4
|
import { Group, Mesh, MeshStandardMaterial, Scene } from 'three';
|
|
5
|
-
import
|
|
5
|
+
import * as BufferGeometryUtils_ from 'three/examples/jsm/utils/BufferGeometryUtils';
|
|
6
6
|
const featureAPI = ccAPI.feature;
|
|
7
|
+
let BufferGeometryUtils = BufferGeometryUtils_;
|
|
8
|
+
if (BufferGeometryUtils.BufferGeometryUtils) {
|
|
9
|
+
BufferGeometryUtils = BufferGeometryUtils.BufferGeometryUtils;
|
|
10
|
+
}
|
|
7
11
|
// Qeued execute, returns the first result and expects it to be an ObjectID
|
|
8
12
|
const exec = (instance, drawing, namespace, fn, stream, ...args) => {
|
|
9
13
|
return (instance.queue = instance.queue.then(() => Promise.all(args).then(resolvedArgs => {
|
|
@@ -180,7 +184,7 @@ const createRecursiveBufferGeometry = async (object, drawingId, bufferGeomArray)
|
|
|
180
184
|
}
|
|
181
185
|
}
|
|
182
186
|
};
|
|
183
|
-
const createRecursiveScene = async (object, drawingId, root) => {
|
|
187
|
+
const createRecursiveScene = async (object, drawingId, root, options) => {
|
|
184
188
|
let cDrawing = getDrawing(drawingId);
|
|
185
189
|
const tree = cDrawing.structure.tree;
|
|
186
190
|
if (object.link || object.solids) {
|
|
@@ -200,15 +204,27 @@ const createRecursiveScene = async (object, drawingId, root) => {
|
|
|
200
204
|
meshes = [...meshes, ...cachedSolid.meshes.map(m => m)];
|
|
201
205
|
}
|
|
202
206
|
if (meshes.length > 0) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
207
|
+
if (options?.meshPerFace) {
|
|
208
|
+
const part = new Group();
|
|
209
|
+
part.matrix = MathUtils.convertToMatrix4(object.coordinateSystem);
|
|
210
|
+
part.matrixAutoUpdate = false;
|
|
211
|
+
part.userData = { id: object.id };
|
|
212
|
+
part.name = object.name;
|
|
213
|
+
for (const mesh of meshes) {
|
|
214
|
+
part.add(new Mesh(mesh.geometry, new MeshStandardMaterial({ color: mesh.color, transparent: mesh.opacity < 1, opacity: mesh.opacity })));
|
|
215
|
+
}
|
|
216
|
+
root.add(part);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
const mesh = new Mesh();
|
|
220
|
+
mesh.matrix = MathUtils.convertToMatrix4(object.coordinateSystem);
|
|
221
|
+
mesh.matrixAutoUpdate = false;
|
|
222
|
+
mesh.userData = { id: object.id };
|
|
223
|
+
mesh.name = object.name;
|
|
224
|
+
mesh.geometry = BufferGeometryUtils.mergeBufferGeometries(meshes.map(m => m.geometry));
|
|
225
|
+
mesh.material = new MeshStandardMaterial();
|
|
226
|
+
root.add(mesh);
|
|
210
227
|
}
|
|
211
|
-
root.add(part);
|
|
212
228
|
}
|
|
213
229
|
}
|
|
214
230
|
}
|
|
@@ -222,7 +238,7 @@ const createRecursiveScene = async (object, drawingId, root) => {
|
|
|
222
238
|
root.add(assembly);
|
|
223
239
|
for (const child of object.children) {
|
|
224
240
|
if (tree[child].class === CCClasses.CCProductReference || tree[child].class === CCClasses.CCProductReferenceET) {
|
|
225
|
-
await createRecursiveScene(tree[child], drawingId, assembly);
|
|
241
|
+
await createRecursiveScene(tree[child], drawingId, assembly, options);
|
|
226
242
|
}
|
|
227
243
|
}
|
|
228
244
|
}
|
|
@@ -247,10 +263,18 @@ export default class CAD {
|
|
|
247
263
|
const publicApi = {
|
|
248
264
|
addNode: (productId, ownerId, transformation, name) => {
|
|
249
265
|
return this.resolve(async ([rProductId, rOwnerId]) => {
|
|
250
|
-
ccAPI.assemblyBuilder.setCurrentNode(drawingId, rOwnerId);
|
|
251
266
|
return ccAPI.assemblyBuilder.addNode(drawingId, rProductId, rOwnerId, transformation, name);
|
|
252
267
|
}, productId, ownerId);
|
|
253
268
|
},
|
|
269
|
+
addNodes: (...nodes) => {
|
|
270
|
+
return this.resolve(async ([]) => {
|
|
271
|
+
const nodesToAdd = [];
|
|
272
|
+
nodes.forEach(node => {
|
|
273
|
+
nodesToAdd.push([node.productId, node.ownerId, node.transformation, node.name]);
|
|
274
|
+
});
|
|
275
|
+
return ccAPI.assemblyBuilder.addNodes(drawingId, nodesToAdd);
|
|
276
|
+
});
|
|
277
|
+
},
|
|
254
278
|
boolean: (partId, type, entities) => {
|
|
255
279
|
return this.resolve(async ([rPartId, ...rEntities]) => {
|
|
256
280
|
const cDrawing = await getDrawing(drawingId);
|
|
@@ -414,7 +438,7 @@ export default class CAD {
|
|
|
414
438
|
}
|
|
415
439
|
return undefined;
|
|
416
440
|
},
|
|
417
|
-
createScene: async (objectId) => {
|
|
441
|
+
createScene: async (objectId, options) => {
|
|
418
442
|
await this.queue;
|
|
419
443
|
this.queue = Promise.resolve(0);
|
|
420
444
|
const rObjectId = await objectId;
|
|
@@ -423,7 +447,7 @@ export default class CAD {
|
|
|
423
447
|
const scene = new Scene();
|
|
424
448
|
if (rObjectId != null) {
|
|
425
449
|
const rootObj = structureTree[rObjectId];
|
|
426
|
-
await createRecursiveScene(rootObj, drawingId, scene);
|
|
450
|
+
await createRecursiveScene(rootObj, drawingId, scene, options);
|
|
427
451
|
}
|
|
428
452
|
return scene;
|
|
429
453
|
},
|
|
@@ -649,6 +673,15 @@ export default class CAD {
|
|
|
649
673
|
await ccAPI.assemblyBuilder.removeNode(drawingId, rReferenceId, rOwnerId);
|
|
650
674
|
}, referenceId, ownerId);
|
|
651
675
|
},
|
|
676
|
+
removeNodes: (...nodes) => {
|
|
677
|
+
return this.resolve(async ([]) => {
|
|
678
|
+
const nodesToRemove = [];
|
|
679
|
+
nodes.forEach(node => {
|
|
680
|
+
nodesToRemove.push([node.referenceId, node.ownerId]);
|
|
681
|
+
});
|
|
682
|
+
return ccAPI.assemblyBuilder.removeNodes(drawingId, nodesToRemove);
|
|
683
|
+
});
|
|
684
|
+
},
|
|
652
685
|
importFeature: (partId, content, format, name) => {
|
|
653
686
|
return this.resolve(async ([rPartId]) => {
|
|
654
687
|
const featureName = name ? name : 'Import';
|
|
File without changes
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
/* eslint-disable max-lines */
|
|
2
2
|
import { ccAPI } from '@buerli.io/classcad';
|
|
3
3
|
import { api, getDrawing, init } from '@buerli.io/core';
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
4
|
+
import { Mesh, MeshStandardMaterial, Scene, Shape } from 'three';
|
|
5
|
+
import * as BufferGeometryUtils_ from 'three/examples/jsm/utils/BufferGeometryUtils';
|
|
6
|
+
let BufferGeometryUtils = BufferGeometryUtils_;
|
|
7
|
+
if (BufferGeometryUtils.BufferGeometryUtils) {
|
|
8
|
+
BufferGeometryUtils = BufferGeometryUtils.BufferGeometryUtils;
|
|
9
|
+
}
|
|
6
10
|
// Qeued execute, returns the first result and expects it to be an ObjectID or
|
|
7
11
|
// a stream, in case of save() or export() is called
|
|
8
12
|
const exec = (instance, drawing, namespace, fn, stream, returnStream, ...args) => {
|
|
@@ -138,7 +142,7 @@ export function createPolyline(fPts) {
|
|
|
138
142
|
lineEnds: [fPts[j].point, fPts[k].point],
|
|
139
143
|
};
|
|
140
144
|
const touchPts = getTouchPoints(filletInfo, fPts[i].radius); // returns two points
|
|
141
|
-
if (touchPts != undefined &&
|
|
145
|
+
if (touchPts != undefined && touchPts?.length > 0) {
|
|
142
146
|
const angle = getIncludingBulgeAngle(filletInfo);
|
|
143
147
|
const bulge = Math.tan(angle / 4);
|
|
144
148
|
newVertices.push(...touchPts);
|
|
@@ -53,6 +53,18 @@ export declare type ApiHistory = {
|
|
|
53
53
|
* @image /doc/assets/history/addNode.jpg
|
|
54
54
|
*/
|
|
55
55
|
addNode: (productId: VID, ownerId: VID, transformation: Transform, name?: string) => ID;
|
|
56
|
+
/**
|
|
57
|
+
* Adds multiple products as nodes to an existing assembly at once
|
|
58
|
+
* @param nodes array of node parameter objects. See also addNode().
|
|
59
|
+
* @example // tbd
|
|
60
|
+
* @image // tbd
|
|
61
|
+
*/
|
|
62
|
+
addNodes: (...nodes: {
|
|
63
|
+
productId: number;
|
|
64
|
+
ownerId: number;
|
|
65
|
+
transformation: Transform;
|
|
66
|
+
name?: string;
|
|
67
|
+
}[]) => IDs;
|
|
56
68
|
/**
|
|
57
69
|
* Creates a boolean operation.
|
|
58
70
|
* @param partId id of the part where the operation will be created on
|
|
@@ -326,10 +338,15 @@ export declare type ApiHistory = {
|
|
|
326
338
|
/**
|
|
327
339
|
* Creates ThreeJS scene from current product
|
|
328
340
|
* @param productId id of the product to create scene from
|
|
341
|
+
* @param options optional object to define different settings.
|
|
342
|
+
* @param meshPerFace boolean flag to define if a part/solid will have a mesh for each face
|
|
343
|
+
* or if the faces will be combined to one mesh
|
|
329
344
|
* @example // tbd
|
|
330
345
|
* @image // tbd
|
|
331
346
|
*/
|
|
332
|
-
createScene: (productId: VID
|
|
347
|
+
createScene: (productId: VID, options?: {
|
|
348
|
+
meshPerFace?: boolean;
|
|
349
|
+
}) => Promise<Scene>;
|
|
333
350
|
/**
|
|
334
351
|
* Creates one or more expressions.
|
|
335
352
|
* @param partId id of part where to create the expression
|
|
@@ -660,7 +677,7 @@ export declare type ApiHistory = {
|
|
|
660
677
|
* @example // tbd
|
|
661
678
|
* @image // tbd
|
|
662
679
|
*/
|
|
663
|
-
load: (content: ArrayBuffer, type: DataTypes) => Promise<number | null>;
|
|
680
|
+
load: (content: ArrayBuffer, type: DataTypes) => Promise<number[] | null>;
|
|
664
681
|
/**
|
|
665
682
|
* Loads a product into the current drawing.
|
|
666
683
|
* @param content data as arraybuffer
|
|
@@ -672,7 +689,7 @@ export declare type ApiHistory = {
|
|
|
672
689
|
* return geoms.map(geom => new THREE.Mesh(geom, new THREE.MeshStandardMaterial()))
|
|
673
690
|
* @image // tbd
|
|
674
691
|
*/
|
|
675
|
-
loadProduct: (content: ArrayBuffer, type: DataTypes) => Promise<number | null>;
|
|
692
|
+
loadProduct: (content: ArrayBuffer, type: DataTypes) => Promise<number[] | null>;
|
|
676
693
|
/**
|
|
677
694
|
* Creates a new feature and appends geometry to it. This method can be used to import specific geometry
|
|
678
695
|
* which can be used for further operations like boolean, translations and so on.
|
|
@@ -692,6 +709,16 @@ export declare type ApiHistory = {
|
|
|
692
709
|
* @image // tbd
|
|
693
710
|
*/
|
|
694
711
|
removeNode: (referenceId: ObjectID, ownerId: ObjectID) => Promise<void>;
|
|
712
|
+
/**
|
|
713
|
+
* Removes multiple nodes from an assembly node at once
|
|
714
|
+
* @param nodes array of node parameter objects. See also removeNode().
|
|
715
|
+
* @example // tbd
|
|
716
|
+
* @image // tbd
|
|
717
|
+
*/
|
|
718
|
+
removeNodes: (...nodes: {
|
|
719
|
+
referenceId: number;
|
|
720
|
+
ownerId: number;
|
|
721
|
+
}[]) => Promise<void>;
|
|
695
722
|
/**
|
|
696
723
|
* Translates a feature along a given axis.
|
|
697
724
|
* @param partId id ot the part where features will be translated
|
|
@@ -763,7 +790,7 @@ declare type Point = {
|
|
|
763
790
|
y: number;
|
|
764
791
|
z: number;
|
|
765
792
|
};
|
|
766
|
-
declare type Transform = [Point, Point, Point];
|
|
793
|
+
export declare type Transform = [Point, Point, Point];
|
|
767
794
|
declare type BooleanTypes = 'Union' | 'Subtraction' | 'Intersection';
|
|
768
795
|
declare type WCSTypes = 'XYAxisOrigin' | 'Custom';
|
|
769
796
|
declare type WATypes = 'Custom' | 'WorkPoints' | 'PointAndDirection' | 'SketchLine' | 'Curve' | '2Points' | '2Planes';
|
|
@@ -7,9 +7,10 @@ export { solid, history, createPolyline };
|
|
|
7
7
|
*
|
|
8
8
|
* Please have a look at https://github.com/awv-informatik/buerli/pull/129 for more information.
|
|
9
9
|
*/
|
|
10
|
-
import { ApiHistory as ApiHistory1, ConstraintType as ConstraintType1 } from './history';
|
|
10
|
+
import { ApiHistory as ApiHistory1, ConstraintType as ConstraintType1, Transform as Transform1 } from './history';
|
|
11
11
|
export declare type ApiHistory = ApiHistory1;
|
|
12
12
|
export declare type ConstraintType = ConstraintType1;
|
|
13
|
+
export declare type Transform = Transform1;
|
|
13
14
|
import { ApiNoHistory as ApiNoHistory1, FilletPoint as FilletPoint1, Polyline as Polyline1 } from './solid';
|
|
14
15
|
export declare type ApiNoHistory = ApiNoHistory1;
|
|
15
16
|
export declare type Polyline = Polyline1;
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buerli.io/headless",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.35-beta.0",
|
|
4
4
|
"description": "A non-manifold CAD workflow for the web",
|
|
5
5
|
"author": "AWV Informatik AG <info@awv-informatik.ch>",
|
|
6
6
|
"repository": {},
|
|
7
|
-
"main": "build/index.js",
|
|
8
|
-
"module": "build/index.js",
|
|
9
|
-
"types": "build/index.d.ts",
|
|
7
|
+
"main": "build/cjs/index.js",
|
|
8
|
+
"module": "build/esm/index.js",
|
|
9
|
+
"types": "build/types/index.d.ts",
|
|
10
10
|
"sideEffects": false,
|
|
11
11
|
"scripts": {
|
|
12
12
|
"ver": "npm version",
|
|
13
13
|
"prepack": "npm run build:dist",
|
|
14
14
|
"clean": "rimraf ./build",
|
|
15
|
-
"build": "
|
|
16
|
-
"build:dist": "npm run clean &&
|
|
17
|
-
"build:
|
|
15
|
+
"build": "npm run build:esm -- --sourceMap true --declaration true --declarationDir ./build/types",
|
|
16
|
+
"build:dist": "npm run clean && npm run build:esm && npm run build:cjs && npm run build:types && echo DONE",
|
|
17
|
+
"build:esm": "tsc --target es2020 --module esNext --declaration false --declarationDir null --sourceMap false --outDir ./build/esm",
|
|
18
|
+
"build:cjs": "tsc --target es2017 --module commonjs --declaration false --declarationDir null --sourceMap false --outDir ./build/cjs",
|
|
19
|
+
"build:types": "tsc --declaration --emitDeclarationOnly --outDir ./build/types",
|
|
18
20
|
"test": "echo no tests yet",
|
|
19
21
|
"lint": "eslint \"./src/**/*.ts?(x)\"",
|
|
20
22
|
"prettier": "prettier --write \"./{src,tests}/**/*.{js,jsx,ts,tsx,json}\""
|
|
@@ -51,6 +53,6 @@
|
|
|
51
53
|
"three": ">=0.128"
|
|
52
54
|
},
|
|
53
55
|
"dependencies": {
|
|
54
|
-
"@buerli.io/classcad": "0.0.
|
|
56
|
+
"@buerli.io/classcad": "0.0.35-beta.0"
|
|
55
57
|
}
|
|
56
58
|
}
|