@buerli.io/headless 1.0.0 → 1.0.1-beta.2
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/README.md +24 -24
- package/build/cjs/history.js +2308 -2308
- package/build/cjs/index.js +36 -36
- package/build/cjs/solid.js +479 -479
- package/build/cjs/utils/meshes.js +24 -24
- package/build/cjs/utils/selection.js +32 -32
- package/build/esm/history.js +2303 -2303
- package/build/esm/index.js +8 -8
- package/build/esm/solid.js +473 -473
- package/build/esm/utils/meshes.js +20 -20
- package/build/esm/utils/selection.js +25 -25
- package/build/types/history.d.ts +1852 -1852
- package/build/types/index.d.ts +29 -29
- package/build/types/solid.d.ts +524 -524
- package/build/types/utils/meshes.d.ts +14 -14
- package/build/types/utils/selection.d.ts +4 -4
- package/package.json +2 -2
package/build/cjs/solid.js
CHANGED
|
@@ -1,479 +1,479 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
3
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
4
|
-
var m = o[Symbol.asyncIterator], i;
|
|
5
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
6
|
-
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
7
|
-
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
8
|
-
};
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.solid = exports.Solid = exports.createPolyline = void 0;
|
|
11
|
-
/* eslint-disable max-lines */
|
|
12
|
-
const classcad_1 = require("@buerli.io/classcad");
|
|
13
|
-
const core_1 = require("@buerli.io/core");
|
|
14
|
-
const three_1 = require("three");
|
|
15
|
-
const three_stdlib_1 = require("three-stdlib");
|
|
16
|
-
const meshes_1 = require("./utils/meshes");
|
|
17
|
-
const isShape = (entity) => entity && entity.type === 'Shape';
|
|
18
|
-
const toCCVec = (args) => ({ x: args[0], y: args[1], z: args[2] });
|
|
19
|
-
const toCCNbrVec = (args) => ({ x: args[0], y: args[1], z: args[2] });
|
|
20
|
-
const toArray = (v) => (Array.isArray(v) ? v : v.toArray());
|
|
21
|
-
const toEuler = (v) => toArray(v);
|
|
22
|
-
const makeVec = (v) => toCCVec(toArray(v));
|
|
23
|
-
const makeNbrVec = (v) => toCCNbrVec(toArray(v));
|
|
24
|
-
const makeEuler = (v) => toCCVec(toEuler(v));
|
|
25
|
-
const makeNbrEuler = (v) => toCCNbrVec(toEuler(v));
|
|
26
|
-
/**
|
|
27
|
-
* Returns the entity of solid from structure tree
|
|
28
|
-
* @param drawingId Id of current drawing
|
|
29
|
-
* @param solid Solid to get entity from
|
|
30
|
-
*/
|
|
31
|
-
const getEntity = async (drawingId, _solid) => {
|
|
32
|
-
const rSolid = await _solid;
|
|
33
|
-
const cDrawing = (0, core_1.getDrawing)(drawingId);
|
|
34
|
-
const object = cDrawing.structure.tree[rSolid];
|
|
35
|
-
if (object != undefined) {
|
|
36
|
-
const entities = object.geometryIdList;
|
|
37
|
-
if (entities != undefined && entities.length > 0) {
|
|
38
|
-
return cDrawing.geometry.cache[entities[0]];
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
console.warn(`There is no cached entry for ${rSolid}!`, cDrawing.geometry.cache);
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
console.warn(`There is no cached entry for ${rSolid}!`, cDrawing.geometry.cache);
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
/**
|
|
51
|
-
* Returns the adjacent points of the fillet arc. These are the points where fillet arc tangentially touches the lines.
|
|
52
|
-
* @param info contains all information for the fillet, like start- and endpoints of adjacent lines and control point
|
|
53
|
-
* @param radius radius of the fillet arc
|
|
54
|
-
*/
|
|
55
|
-
const getTouchPoints = (info, radius) => {
|
|
56
|
-
const controlPos = info.control;
|
|
57
|
-
const linearTolerance = 1e-3;
|
|
58
|
-
const dirs = [];
|
|
59
|
-
const maxDists = [];
|
|
60
|
-
for (let i = 0; i < 2; i++) {
|
|
61
|
-
const startPos = info.lineStarts[i];
|
|
62
|
-
const endPos = info.lineEnds[i];
|
|
63
|
-
const dir = endPos.clone().sub(startPos).normalize();
|
|
64
|
-
const maxDist = endPos.distanceTo(controlPos);
|
|
65
|
-
dirs.push(dir);
|
|
66
|
-
maxDists.push(maxDist);
|
|
67
|
-
}
|
|
68
|
-
if (radius + linearTolerance >= Math.min(maxDists[0], maxDists[1])) {
|
|
69
|
-
return null; // too large fillet
|
|
70
|
-
}
|
|
71
|
-
// Calculate distance from controlpt to touchpoint
|
|
72
|
-
const scalar = Math.abs(radius / Math.tan(getIncludingAngle(info) / 2));
|
|
73
|
-
return dirs.map(dir => dir
|
|
74
|
-
.clone()
|
|
75
|
-
.multiplyScalar(scalar)
|
|
76
|
-
.add(controlPos));
|
|
77
|
-
};
|
|
78
|
-
/**
|
|
79
|
-
* 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
|
|
80
|
-
* @param info Info contains information about lines
|
|
81
|
-
*/
|
|
82
|
-
const getIncludingAngle = (info) => {
|
|
83
|
-
// First line (line to point)
|
|
84
|
-
const line1 = info.lineEnds[0]
|
|
85
|
-
.clone()
|
|
86
|
-
.sub(info.lineStarts[0])
|
|
87
|
-
.normalize();
|
|
88
|
-
// Second line (line from point)
|
|
89
|
-
const line2 = info.lineEnds[1]
|
|
90
|
-
.clone()
|
|
91
|
-
.sub(info.lineStarts[1])
|
|
92
|
-
.normalize();
|
|
93
|
-
// Angle, measured from first line to second line counterclockwise.
|
|
94
|
-
// If angle exceeds 180°, measuring is clockwise but negative angle
|
|
95
|
-
const angle = Math.atan2(line1.x * line2.y - line1.y * line2.x, line1.x * line2.x + line1.y * line2.y);
|
|
96
|
-
return angle;
|
|
97
|
-
};
|
|
98
|
-
/**
|
|
99
|
-
* 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.
|
|
100
|
-
* @param info
|
|
101
|
-
*/
|
|
102
|
-
const getIncludingBulgeAngle = (info) => {
|
|
103
|
-
// angle of first line, control point and second line
|
|
104
|
-
const angle = getIncludingAngle(info);
|
|
105
|
-
// Opposite angle of the angle which was calculated from control point and its adjacent lines
|
|
106
|
-
const oppositeAngle = Math.PI - Math.abs(angle);
|
|
107
|
-
const sign = angle / Math.abs(angle);
|
|
108
|
-
return oppositeAngle * sign * -1; // -1 because of bulges definition
|
|
109
|
-
};
|
|
110
|
-
/**
|
|
111
|
-
* Creates a polyline from the given fillet points
|
|
112
|
-
* @param fPts points of the polyline with its associated fillet radius
|
|
113
|
-
* @example
|
|
114
|
-
* // Creates a polyline with three points
|
|
115
|
-
* const fp0 = { point: new THREE.Vector3(20, 20, 0), radius: 4 }
|
|
116
|
-
* const fp1 = { point: new THREE.Vector3(40, 0, 0), radius: 2 }
|
|
117
|
-
* const fp2 = { point: new THREE.Vector3(0, 0, 0), radius: 2 }
|
|
118
|
-
* const polyline = createPolyline([fp0, fp1, fp2])
|
|
119
|
-
*/
|
|
120
|
-
function createPolyline(fPts) {
|
|
121
|
-
const newVertices = [];
|
|
122
|
-
const newBulges = [];
|
|
123
|
-
for (let i = 0; i < fPts.length; i++) {
|
|
124
|
-
// if fillet point has radius, calculate fillet info, touchpoints and bulge
|
|
125
|
-
if (fPts[i].radius > 0) {
|
|
126
|
-
const j = i - 1 < 0 ? fPts.length - 1 : i - 1;
|
|
127
|
-
const k = i + 1 > fPts.length - 1 ? 0 : i + 1;
|
|
128
|
-
const filletInfo = {
|
|
129
|
-
control: fPts[i].point,
|
|
130
|
-
lineStarts: [fPts[i].point, fPts[i].point],
|
|
131
|
-
lineEnds: [fPts[j].point, fPts[k].point],
|
|
132
|
-
};
|
|
133
|
-
const touchPts = getTouchPoints(filletInfo, fPts[i].radius); // returns two points
|
|
134
|
-
if (touchPts != undefined && (touchPts === null || touchPts === void 0 ? void 0 : touchPts.length) > 0) {
|
|
135
|
-
const angle = getIncludingBulgeAngle(filletInfo);
|
|
136
|
-
const bulge = Math.tan(angle / 4);
|
|
137
|
-
newVertices.push(...touchPts);
|
|
138
|
-
newBulges.push(bulge); // bulge for first point
|
|
139
|
-
newBulges.push(0); // bulge for second point
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
newVertices.push(fPts[i].point);
|
|
144
|
-
newBulges.push(0);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
return { points: newVertices, bulges: newBulges };
|
|
148
|
-
}
|
|
149
|
-
exports.createPolyline = createPolyline;
|
|
150
|
-
/**
|
|
151
|
-
* 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.
|
|
152
|
-
* @param curves THREE.Shape.curves
|
|
153
|
-
*/
|
|
154
|
-
const makeCCData = (curves) => {
|
|
155
|
-
return curves.map((curve) => {
|
|
156
|
-
switch (curve.type) {
|
|
157
|
-
// [pStart, p1, p2, p3]
|
|
158
|
-
case 'CubicBezierCurve':
|
|
159
|
-
return [curve.type, curve.v0.toArray(), curve.v1.toArray(), curve.v2.toArray(), curve.v3.toArray()];
|
|
160
|
-
// [pStart, p1, p2]
|
|
161
|
-
case 'QuadraticBezierCurve':
|
|
162
|
-
return [curve.type, curve.v0.toArray(), curve.v1.toArray(), curve.v2.toArray()];
|
|
163
|
-
// [p1, p2]
|
|
164
|
-
case 'LineCurve':
|
|
165
|
-
return [curve.type, curve.v1.toArray(), curve.v2.toArray()];
|
|
166
|
-
// [...points]
|
|
167
|
-
case 'SplineCurve':
|
|
168
|
-
return [curve.type, curve.points.map((point) => point.toArray())];
|
|
169
|
-
// [pA, radius, angles, clockwise, rotation]
|
|
170
|
-
case 'EllipseCurve':
|
|
171
|
-
case 'ArcCurve':
|
|
172
|
-
const { aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation } = curve;
|
|
173
|
-
return [
|
|
174
|
-
curve.type,
|
|
175
|
-
[aX, aY],
|
|
176
|
-
[xRadius, yRadius],
|
|
177
|
-
[(aStartAngle / Math.PI) * 180, (aEndAngle / Math.PI) * 180],
|
|
178
|
-
aClockwise,
|
|
179
|
-
aRotation,
|
|
180
|
-
];
|
|
181
|
-
default:
|
|
182
|
-
return undefined;
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
};
|
|
186
|
-
class Solid {
|
|
187
|
-
constructor() {
|
|
188
|
-
this.drawingId = null;
|
|
189
|
-
this.queue = Promise.resolve(0);
|
|
190
|
-
this.queue = Promise.resolve(0);
|
|
191
|
-
}
|
|
192
|
-
resolve(callback, ...args) {
|
|
193
|
-
return (this.queue = this.queue
|
|
194
|
-
.then(() => Promise.all(args).then(callback))
|
|
195
|
-
.catch(e => {
|
|
196
|
-
// catch is necessary to avoid error promises in the queue
|
|
197
|
-
}));
|
|
198
|
-
}
|
|
199
|
-
init(callback) {
|
|
200
|
-
const promise = new Promise(async (resolve, reject) => {
|
|
201
|
-
const drawingId = await classcad_1.BuerliCadFacade.utils.connect('solid');
|
|
202
|
-
if (!drawingId)
|
|
203
|
-
throw new Error('Connection/Drawing could not be created');
|
|
204
|
-
this.drawingId = drawingId;
|
|
205
|
-
const { solid: solidAPI, baseModeler: baseModelerAPI, common: commonAPI } = (0, classcad_1.createApi)(drawingId).v0;
|
|
206
|
-
await solidAPI.init();
|
|
207
|
-
const publicApi = {
|
|
208
|
-
getDrawingId: () => drawingId,
|
|
209
|
-
getDrawing: () => (0, core_1.getDrawing)(drawingId),
|
|
210
|
-
getState: () => core_1.api.getState(),
|
|
211
|
-
setFacetingParameters: (distanceTol, angleTol) => this.resolve(async () => commonAPI.setFacetingParameters(distanceTol, angleTol)),
|
|
212
|
-
box: (length, width, height) => {
|
|
213
|
-
return this.resolve(async () => {
|
|
214
|
-
return solidAPI.createBox(length, width, height);
|
|
215
|
-
});
|
|
216
|
-
},
|
|
217
|
-
clearSolids: () => {
|
|
218
|
-
return this.resolve(async () => {
|
|
219
|
-
return solidAPI.clearSolids();
|
|
220
|
-
});
|
|
221
|
-
},
|
|
222
|
-
clearSolid: (target) => {
|
|
223
|
-
return this.resolve(async ([rTarget]) => {
|
|
224
|
-
return solidAPI.clearSolid(rTarget);
|
|
225
|
-
}, target);
|
|
226
|
-
},
|
|
227
|
-
cone: (length, diameter1, diameter2) => {
|
|
228
|
-
return this.resolve(async () => {
|
|
229
|
-
return solidAPI.createCone(length, diameter1, diameter2);
|
|
230
|
-
});
|
|
231
|
-
},
|
|
232
|
-
copy: (target) => {
|
|
233
|
-
return this.resolve(async ([rTarget]) => {
|
|
234
|
-
return solidAPI.copy(rTarget);
|
|
235
|
-
}, target);
|
|
236
|
-
},
|
|
237
|
-
createBufferGeometry: async (_solid) => {
|
|
238
|
-
await this.queue;
|
|
239
|
-
this.queue = Promise.resolve(0);
|
|
240
|
-
const rSolid = await _solid;
|
|
241
|
-
await baseModelerAPI.requestVisualisationOfObject(rSolid);
|
|
242
|
-
const entity = await getEntity(drawingId, rSolid);
|
|
243
|
-
if (entity != null) {
|
|
244
|
-
return (0, three_stdlib_1.mergeBufferGeometries)(entity.meshes.map(m => m.geometry));
|
|
245
|
-
}
|
|
246
|
-
},
|
|
247
|
-
createScene: async (solids, options) => {
|
|
248
|
-
var e_1, _a;
|
|
249
|
-
await this.queue;
|
|
250
|
-
this.queue = Promise.resolve(0);
|
|
251
|
-
const scene = new three_1.Scene();
|
|
252
|
-
scene.name = 'Scene'; // Default name for the scene
|
|
253
|
-
const part = new three_1.Group();
|
|
254
|
-
part.name = 'Part'; // Default name for the part
|
|
255
|
-
const _solids = [];
|
|
256
|
-
const meshes = [];
|
|
257
|
-
try {
|
|
258
|
-
for (var solids_1 = __asyncValues(solids), solids_1_1; solids_1_1 = await solids_1.next(), !solids_1_1.done;) {
|
|
259
|
-
const _solid = solids_1_1.value;
|
|
260
|
-
await baseModelerAPI.requestVisualisationOfObject(_solid);
|
|
261
|
-
const cDrawing = (0, core_1.getDrawing)(drawingId);
|
|
262
|
-
const solidObject = cDrawing.structure.tree[_solid];
|
|
263
|
-
if (solidObject) {
|
|
264
|
-
const _solidGroup = new three_1.Group();
|
|
265
|
-
_solidGroup.name = solidObject.name;
|
|
266
|
-
_solidGroup.userData = { id: solidObject.id }; // add solid id to the userData
|
|
267
|
-
const entities = solidObject.geometryIdList;
|
|
268
|
-
if (entities && entities.length > 0) {
|
|
269
|
-
const entity = cDrawing.geometry.cache[entities[0]];
|
|
270
|
-
if (entity && entity.meshes.length > 0) {
|
|
271
|
-
if (options === null || options === void 0 ? void 0 : options.meshPerGeometry) {
|
|
272
|
-
// Create a mesh for each geometry element
|
|
273
|
-
entity.meshes.forEach(m => {
|
|
274
|
-
const mesh = new three_1.Mesh();
|
|
275
|
-
mesh.userData = { id: m.graphicId }; // add graphic id to the userData
|
|
276
|
-
mesh.geometry = m.geometry;
|
|
277
|
-
mesh.material = new three_1.MeshStandardMaterial({
|
|
278
|
-
color: m.color ? m.color : entity.color,
|
|
279
|
-
transparent: m.opacity ? m.opacity < 1 : entity.opacity < 1,
|
|
280
|
-
opacity: m.opacity ? m.opacity : entity.opacity,
|
|
281
|
-
});
|
|
282
|
-
_solidGroup.add(mesh);
|
|
283
|
-
meshes.push(mesh);
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
else {
|
|
287
|
-
// Merge all geometries into one mesh, sort them by color
|
|
288
|
-
const colorMeshesMap = (0, meshes_1.getDifferentColoredMeshesFromEntity)(entity);
|
|
289
|
-
Object.keys(colorMeshesMap).forEach(key => {
|
|
290
|
-
const mesh = new three_1.Mesh();
|
|
291
|
-
mesh.geometry = (0, three_stdlib_1.mergeBufferGeometries)(colorMeshesMap[key].meshes.map(m => m.geometry));
|
|
292
|
-
mesh.material = new three_1.MeshStandardMaterial({
|
|
293
|
-
color: colorMeshesMap[key].color,
|
|
294
|
-
transparent: colorMeshesMap[key].opacity < 1,
|
|
295
|
-
opacity: colorMeshesMap[key].opacity,
|
|
296
|
-
});
|
|
297
|
-
_solidGroup.add(mesh); // Add mesh to solid of the scene
|
|
298
|
-
meshes.push(mesh); // Collect mesh to return later
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
part.add(_solidGroup); // Add solid to part of the scene
|
|
302
|
-
_solids.push(_solidGroup); // Collect solid to return later
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
309
|
-
finally {
|
|
310
|
-
try {
|
|
311
|
-
if (solids_1_1 && !solids_1_1.done && (_a = solids_1.return)) await _a.call(solids_1);
|
|
312
|
-
}
|
|
313
|
-
finally { if (e_1) throw e_1.error; }
|
|
314
|
-
}
|
|
315
|
-
scene.add(part); // Add part to the scene
|
|
316
|
-
return { scene, part, solids: _solids, meshes };
|
|
317
|
-
},
|
|
318
|
-
cylinder: (length, diameter) => {
|
|
319
|
-
return this.resolve(async () => {
|
|
320
|
-
return solidAPI.createCylinder(length, diameter);
|
|
321
|
-
});
|
|
322
|
-
},
|
|
323
|
-
edgeLoops: (breps) => {
|
|
324
|
-
return this.resolve(async ([rBreps]) => {
|
|
325
|
-
return solidAPI.edgeLoops(rBreps);
|
|
326
|
-
}, breps);
|
|
327
|
-
},
|
|
328
|
-
export: (solidIds) => {
|
|
329
|
-
return this.resolve(async ([rSolidIds]) => {
|
|
330
|
-
return solidAPI.export('stp', rSolidIds);
|
|
331
|
-
}, solidIds);
|
|
332
|
-
},
|
|
333
|
-
extendSolidAtPlane: (target, point, normal, distance) => {
|
|
334
|
-
return this.resolve(async ([rTarget]) => {
|
|
335
|
-
return solidAPI.solidExtendAtPlane(rTarget, makeNbrVec(point), makeNbrVec(normal), distance);
|
|
336
|
-
}, target);
|
|
337
|
-
},
|
|
338
|
-
extrude: (height, region) => {
|
|
339
|
-
return this.resolve(async () => {
|
|
340
|
-
if (isShape(region)) {
|
|
341
|
-
const curveArray = makeCCData(region.curves);
|
|
342
|
-
return solidAPI.createExtrudeRegion(makeNbrVec(height), curveArray);
|
|
343
|
-
}
|
|
344
|
-
else {
|
|
345
|
-
return solidAPI.createExtrude(makeNbrVec(height), region.points, region.bulges);
|
|
346
|
-
}
|
|
347
|
-
});
|
|
348
|
-
},
|
|
349
|
-
fillet: (radius, edges) => {
|
|
350
|
-
return this.resolve(async ([rEdges]) => {
|
|
351
|
-
return solidAPI.createFillet(radius, rEdges);
|
|
352
|
-
}, edges);
|
|
353
|
-
},
|
|
354
|
-
import: (data) => {
|
|
355
|
-
return this.resolve(async () => {
|
|
356
|
-
return solidAPI.import(data, 'stp');
|
|
357
|
-
});
|
|
358
|
-
},
|
|
359
|
-
intersect: (solidId, keepSolid, ...bodies) => {
|
|
360
|
-
return this.resolve(async ([rSolidId, ...rBodies]) => {
|
|
361
|
-
for (const rBody of rBodies) {
|
|
362
|
-
solidAPI.intersect(rSolidId, keepSolid, rBody);
|
|
363
|
-
}
|
|
364
|
-
return rSolidId;
|
|
365
|
-
}, solidId, ...bodies);
|
|
366
|
-
},
|
|
367
|
-
load: (data) => {
|
|
368
|
-
return this.resolve(async () => {
|
|
369
|
-
const productId = await solidAPI.load(data, 'ofb', true);
|
|
370
|
-
if (productId !== null) {
|
|
371
|
-
const drawing = (0, core_1.getDrawing)(drawingId);
|
|
372
|
-
const solids = drawing.structure.tree[productId].solids;
|
|
373
|
-
if (solids !== undefined) {
|
|
374
|
-
return solids.map(innerId => drawing.graphic.containers[innerId].owner);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
return [];
|
|
378
|
-
});
|
|
379
|
-
},
|
|
380
|
-
mirror: (target, point, normal) => {
|
|
381
|
-
return this.resolve(async ([rTarget]) => {
|
|
382
|
-
return solidAPI.mirror(rTarget, makeNbrVec(point), makeNbrEuler(normal));
|
|
383
|
-
}, target);
|
|
384
|
-
},
|
|
385
|
-
moveTo: (target, position) => {
|
|
386
|
-
return this.resolve(async ([rTarget]) => {
|
|
387
|
-
return solidAPI.moveTo(rTarget, makeNbrVec(position));
|
|
388
|
-
}, target);
|
|
389
|
-
},
|
|
390
|
-
offset: (target, offsetDistance) => {
|
|
391
|
-
return this.resolve(async ([rTarget]) => {
|
|
392
|
-
return solidAPI.offset(rTarget, offsetDistance);
|
|
393
|
-
}, target);
|
|
394
|
-
},
|
|
395
|
-
pick: (target, type, ...points) => {
|
|
396
|
-
return this.resolve(async ([rTarget]) => {
|
|
397
|
-
const pts = points.map(pt => makeNbrVec(pt));
|
|
398
|
-
const breps = await solidAPI.pick(rTarget, type, ...pts);
|
|
399
|
-
if (breps !== null) {
|
|
400
|
-
return Array.isArray(breps) ? breps : [breps];
|
|
401
|
-
}
|
|
402
|
-
}, target);
|
|
403
|
-
},
|
|
404
|
-
revolve: (position, direction, angle, region) => {
|
|
405
|
-
return this.resolve(async () => {
|
|
406
|
-
if (isShape(region)) {
|
|
407
|
-
const curveArray = makeCCData(region.curves);
|
|
408
|
-
return solidAPI.createRevolveRegion(makeNbrVec(position), makeNbrVec(direction), angle, curveArray);
|
|
409
|
-
}
|
|
410
|
-
else {
|
|
411
|
-
return solidAPI.createRevolve(makeNbrVec(position), makeNbrVec(direction), (angle / Math.PI) * 180, region.points, region.bulges);
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
},
|
|
415
|
-
rotateTo: (target, point) => {
|
|
416
|
-
return this.resolve(async ([rTarget]) => {
|
|
417
|
-
return solidAPI.rotateTo(rTarget, makeNbrEuler(point));
|
|
418
|
-
}, target);
|
|
419
|
-
},
|
|
420
|
-
save: () => {
|
|
421
|
-
return this.resolve(async () => {
|
|
422
|
-
return solidAPI.save('ofb');
|
|
423
|
-
});
|
|
424
|
-
},
|
|
425
|
-
scale: (target, pointOrFactor) => {
|
|
426
|
-
return this.resolve(async ([rTarget]) => {
|
|
427
|
-
const lPointOrFactor = typeof pointOrFactor === 'number' ? pointOrFactor : makeNbrVec(pointOrFactor);
|
|
428
|
-
return solidAPI.scale(rTarget, lPointOrFactor);
|
|
429
|
-
}, target);
|
|
430
|
-
},
|
|
431
|
-
setFacetingParams: (distanceTol, angleTol) => {
|
|
432
|
-
return this.resolve(async () => {
|
|
433
|
-
return commonAPI.setFacetingParameters(distanceTol, angleTol);
|
|
434
|
-
});
|
|
435
|
-
},
|
|
436
|
-
slice: (target, point, normal) => {
|
|
437
|
-
return this.resolve(async ([rTarget]) => {
|
|
438
|
-
return solidAPI.slice(rTarget, makeNbrVec(point), makeNbrVec(normal));
|
|
439
|
-
}, target);
|
|
440
|
-
},
|
|
441
|
-
sphere: (radius) => {
|
|
442
|
-
return this.resolve(async () => {
|
|
443
|
-
return solidAPI.createSphere(radius);
|
|
444
|
-
});
|
|
445
|
-
},
|
|
446
|
-
subtract: (solidId, keepSolid, ...bodies) => {
|
|
447
|
-
return this.resolve(async ([rSolidId, ...rBodies]) => {
|
|
448
|
-
for (const rBody of rBodies) {
|
|
449
|
-
solidAPI.subtract(rSolidId, keepSolid, rBody);
|
|
450
|
-
}
|
|
451
|
-
return rSolidId;
|
|
452
|
-
}, solidId, ...bodies);
|
|
453
|
-
},
|
|
454
|
-
union: (solidId, keepSolid, ...bodies) => {
|
|
455
|
-
return this.resolve(async ([rSolidId, ...rBodies]) => {
|
|
456
|
-
for (const rBody of rBodies) {
|
|
457
|
-
solidAPI.union(rSolidId, keepSolid, rBody);
|
|
458
|
-
}
|
|
459
|
-
return rSolidId;
|
|
460
|
-
}, solidId, ...bodies);
|
|
461
|
-
},
|
|
462
|
-
};
|
|
463
|
-
callback(publicApi);
|
|
464
|
-
resolve(drawingId);
|
|
465
|
-
});
|
|
466
|
-
return () => promise.then(drawingId => core_1.api.getState().api.removeDrawing(drawingId));
|
|
467
|
-
}
|
|
468
|
-
destroy() {
|
|
469
|
-
this.drawingId && core_1.api.getState().api.removeDrawing(this.drawingId);
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
exports.Solid = Solid;
|
|
473
|
-
class solid extends Solid {
|
|
474
|
-
constructor() {
|
|
475
|
-
super();
|
|
476
|
-
console.warn("Warning: 'solid' is deprecated, use 'Solid' instead, 'solid' will be removed in a future release.");
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
exports.solid = solid;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
3
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
4
|
+
var m = o[Symbol.asyncIterator], i;
|
|
5
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
6
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
7
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.solid = exports.Solid = exports.createPolyline = void 0;
|
|
11
|
+
/* eslint-disable max-lines */
|
|
12
|
+
const classcad_1 = require("@buerli.io/classcad");
|
|
13
|
+
const core_1 = require("@buerli.io/core");
|
|
14
|
+
const three_1 = require("three");
|
|
15
|
+
const three_stdlib_1 = require("three-stdlib");
|
|
16
|
+
const meshes_1 = require("./utils/meshes");
|
|
17
|
+
const isShape = (entity) => entity && entity.type === 'Shape';
|
|
18
|
+
const toCCVec = (args) => ({ x: args[0], y: args[1], z: args[2] });
|
|
19
|
+
const toCCNbrVec = (args) => ({ x: args[0], y: args[1], z: args[2] });
|
|
20
|
+
const toArray = (v) => (Array.isArray(v) ? v : v.toArray());
|
|
21
|
+
const toEuler = (v) => toArray(v);
|
|
22
|
+
const makeVec = (v) => toCCVec(toArray(v));
|
|
23
|
+
const makeNbrVec = (v) => toCCNbrVec(toArray(v));
|
|
24
|
+
const makeEuler = (v) => toCCVec(toEuler(v));
|
|
25
|
+
const makeNbrEuler = (v) => toCCNbrVec(toEuler(v));
|
|
26
|
+
/**
|
|
27
|
+
* Returns the entity of solid from structure tree
|
|
28
|
+
* @param drawingId Id of current drawing
|
|
29
|
+
* @param solid Solid to get entity from
|
|
30
|
+
*/
|
|
31
|
+
const getEntity = async (drawingId, _solid) => {
|
|
32
|
+
const rSolid = await _solid;
|
|
33
|
+
const cDrawing = (0, core_1.getDrawing)(drawingId);
|
|
34
|
+
const object = cDrawing.structure.tree[rSolid];
|
|
35
|
+
if (object != undefined) {
|
|
36
|
+
const entities = object.geometryIdList;
|
|
37
|
+
if (entities != undefined && entities.length > 0) {
|
|
38
|
+
return cDrawing.geometry.cache[entities[0]];
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
console.warn(`There is no cached entry for ${rSolid}!`, cDrawing.geometry.cache);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
console.warn(`There is no cached entry for ${rSolid}!`, cDrawing.geometry.cache);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Returns the adjacent points of the fillet arc. These are the points where fillet arc tangentially touches the lines.
|
|
52
|
+
* @param info contains all information for the fillet, like start- and endpoints of adjacent lines and control point
|
|
53
|
+
* @param radius radius of the fillet arc
|
|
54
|
+
*/
|
|
55
|
+
const getTouchPoints = (info, radius) => {
|
|
56
|
+
const controlPos = info.control;
|
|
57
|
+
const linearTolerance = 1e-3;
|
|
58
|
+
const dirs = [];
|
|
59
|
+
const maxDists = [];
|
|
60
|
+
for (let i = 0; i < 2; i++) {
|
|
61
|
+
const startPos = info.lineStarts[i];
|
|
62
|
+
const endPos = info.lineEnds[i];
|
|
63
|
+
const dir = endPos.clone().sub(startPos).normalize();
|
|
64
|
+
const maxDist = endPos.distanceTo(controlPos);
|
|
65
|
+
dirs.push(dir);
|
|
66
|
+
maxDists.push(maxDist);
|
|
67
|
+
}
|
|
68
|
+
if (radius + linearTolerance >= Math.min(maxDists[0], maxDists[1])) {
|
|
69
|
+
return null; // too large fillet
|
|
70
|
+
}
|
|
71
|
+
// Calculate distance from controlpt to touchpoint
|
|
72
|
+
const scalar = Math.abs(radius / Math.tan(getIncludingAngle(info) / 2));
|
|
73
|
+
return dirs.map(dir => dir
|
|
74
|
+
.clone()
|
|
75
|
+
.multiplyScalar(scalar)
|
|
76
|
+
.add(controlPos));
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* 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
|
|
80
|
+
* @param info Info contains information about lines
|
|
81
|
+
*/
|
|
82
|
+
const getIncludingAngle = (info) => {
|
|
83
|
+
// First line (line to point)
|
|
84
|
+
const line1 = info.lineEnds[0]
|
|
85
|
+
.clone()
|
|
86
|
+
.sub(info.lineStarts[0])
|
|
87
|
+
.normalize();
|
|
88
|
+
// Second line (line from point)
|
|
89
|
+
const line2 = info.lineEnds[1]
|
|
90
|
+
.clone()
|
|
91
|
+
.sub(info.lineStarts[1])
|
|
92
|
+
.normalize();
|
|
93
|
+
// Angle, measured from first line to second line counterclockwise.
|
|
94
|
+
// If angle exceeds 180°, measuring is clockwise but negative angle
|
|
95
|
+
const angle = Math.atan2(line1.x * line2.y - line1.y * line2.x, line1.x * line2.x + line1.y * line2.y);
|
|
96
|
+
return angle;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* 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.
|
|
100
|
+
* @param info
|
|
101
|
+
*/
|
|
102
|
+
const getIncludingBulgeAngle = (info) => {
|
|
103
|
+
// angle of first line, control point and second line
|
|
104
|
+
const angle = getIncludingAngle(info);
|
|
105
|
+
// Opposite angle of the angle which was calculated from control point and its adjacent lines
|
|
106
|
+
const oppositeAngle = Math.PI - Math.abs(angle);
|
|
107
|
+
const sign = angle / Math.abs(angle);
|
|
108
|
+
return oppositeAngle * sign * -1; // -1 because of bulges definition
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Creates a polyline from the given fillet points
|
|
112
|
+
* @param fPts points of the polyline with its associated fillet radius
|
|
113
|
+
* @example
|
|
114
|
+
* // Creates a polyline with three points
|
|
115
|
+
* const fp0 = { point: new THREE.Vector3(20, 20, 0), radius: 4 }
|
|
116
|
+
* const fp1 = { point: new THREE.Vector3(40, 0, 0), radius: 2 }
|
|
117
|
+
* const fp2 = { point: new THREE.Vector3(0, 0, 0), radius: 2 }
|
|
118
|
+
* const polyline = createPolyline([fp0, fp1, fp2])
|
|
119
|
+
*/
|
|
120
|
+
function createPolyline(fPts) {
|
|
121
|
+
const newVertices = [];
|
|
122
|
+
const newBulges = [];
|
|
123
|
+
for (let i = 0; i < fPts.length; i++) {
|
|
124
|
+
// if fillet point has radius, calculate fillet info, touchpoints and bulge
|
|
125
|
+
if (fPts[i].radius > 0) {
|
|
126
|
+
const j = i - 1 < 0 ? fPts.length - 1 : i - 1;
|
|
127
|
+
const k = i + 1 > fPts.length - 1 ? 0 : i + 1;
|
|
128
|
+
const filletInfo = {
|
|
129
|
+
control: fPts[i].point,
|
|
130
|
+
lineStarts: [fPts[i].point, fPts[i].point],
|
|
131
|
+
lineEnds: [fPts[j].point, fPts[k].point],
|
|
132
|
+
};
|
|
133
|
+
const touchPts = getTouchPoints(filletInfo, fPts[i].radius); // returns two points
|
|
134
|
+
if (touchPts != undefined && (touchPts === null || touchPts === void 0 ? void 0 : touchPts.length) > 0) {
|
|
135
|
+
const angle = getIncludingBulgeAngle(filletInfo);
|
|
136
|
+
const bulge = Math.tan(angle / 4);
|
|
137
|
+
newVertices.push(...touchPts);
|
|
138
|
+
newBulges.push(bulge); // bulge for first point
|
|
139
|
+
newBulges.push(0); // bulge for second point
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
newVertices.push(fPts[i].point);
|
|
144
|
+
newBulges.push(0);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return { points: newVertices, bulges: newBulges };
|
|
148
|
+
}
|
|
149
|
+
exports.createPolyline = createPolyline;
|
|
150
|
+
/**
|
|
151
|
+
* 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.
|
|
152
|
+
* @param curves THREE.Shape.curves
|
|
153
|
+
*/
|
|
154
|
+
const makeCCData = (curves) => {
|
|
155
|
+
return curves.map((curve) => {
|
|
156
|
+
switch (curve.type) {
|
|
157
|
+
// [pStart, p1, p2, p3]
|
|
158
|
+
case 'CubicBezierCurve':
|
|
159
|
+
return [curve.type, curve.v0.toArray(), curve.v1.toArray(), curve.v2.toArray(), curve.v3.toArray()];
|
|
160
|
+
// [pStart, p1, p2]
|
|
161
|
+
case 'QuadraticBezierCurve':
|
|
162
|
+
return [curve.type, curve.v0.toArray(), curve.v1.toArray(), curve.v2.toArray()];
|
|
163
|
+
// [p1, p2]
|
|
164
|
+
case 'LineCurve':
|
|
165
|
+
return [curve.type, curve.v1.toArray(), curve.v2.toArray()];
|
|
166
|
+
// [...points]
|
|
167
|
+
case 'SplineCurve':
|
|
168
|
+
return [curve.type, curve.points.map((point) => point.toArray())];
|
|
169
|
+
// [pA, radius, angles, clockwise, rotation]
|
|
170
|
+
case 'EllipseCurve':
|
|
171
|
+
case 'ArcCurve':
|
|
172
|
+
const { aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation } = curve;
|
|
173
|
+
return [
|
|
174
|
+
curve.type,
|
|
175
|
+
[aX, aY],
|
|
176
|
+
[xRadius, yRadius],
|
|
177
|
+
[(aStartAngle / Math.PI) * 180, (aEndAngle / Math.PI) * 180],
|
|
178
|
+
aClockwise,
|
|
179
|
+
aRotation,
|
|
180
|
+
];
|
|
181
|
+
default:
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
class Solid {
|
|
187
|
+
constructor() {
|
|
188
|
+
this.drawingId = null;
|
|
189
|
+
this.queue = Promise.resolve(0);
|
|
190
|
+
this.queue = Promise.resolve(0);
|
|
191
|
+
}
|
|
192
|
+
resolve(callback, ...args) {
|
|
193
|
+
return (this.queue = this.queue
|
|
194
|
+
.then(() => Promise.all(args).then(callback))
|
|
195
|
+
.catch(e => {
|
|
196
|
+
// catch is necessary to avoid error promises in the queue
|
|
197
|
+
}));
|
|
198
|
+
}
|
|
199
|
+
init(callback) {
|
|
200
|
+
const promise = new Promise(async (resolve, reject) => {
|
|
201
|
+
const drawingId = await classcad_1.BuerliCadFacade.utils.connect('solid');
|
|
202
|
+
if (!drawingId)
|
|
203
|
+
throw new Error('Connection/Drawing could not be created');
|
|
204
|
+
this.drawingId = drawingId;
|
|
205
|
+
const { solid: solidAPI, baseModeler: baseModelerAPI, common: commonAPI } = (0, classcad_1.createApi)(drawingId).v0;
|
|
206
|
+
await solidAPI.init();
|
|
207
|
+
const publicApi = {
|
|
208
|
+
getDrawingId: () => drawingId,
|
|
209
|
+
getDrawing: () => (0, core_1.getDrawing)(drawingId),
|
|
210
|
+
getState: () => core_1.api.getState(),
|
|
211
|
+
setFacetingParameters: (distanceTol, angleTol) => this.resolve(async () => commonAPI.setFacetingParameters(distanceTol, angleTol)),
|
|
212
|
+
box: (length, width, height) => {
|
|
213
|
+
return this.resolve(async () => {
|
|
214
|
+
return solidAPI.createBox(length, width, height);
|
|
215
|
+
});
|
|
216
|
+
},
|
|
217
|
+
clearSolids: () => {
|
|
218
|
+
return this.resolve(async () => {
|
|
219
|
+
return solidAPI.clearSolids();
|
|
220
|
+
});
|
|
221
|
+
},
|
|
222
|
+
clearSolid: (target) => {
|
|
223
|
+
return this.resolve(async ([rTarget]) => {
|
|
224
|
+
return solidAPI.clearSolid(rTarget);
|
|
225
|
+
}, target);
|
|
226
|
+
},
|
|
227
|
+
cone: (length, diameter1, diameter2) => {
|
|
228
|
+
return this.resolve(async () => {
|
|
229
|
+
return solidAPI.createCone(length, diameter1, diameter2);
|
|
230
|
+
});
|
|
231
|
+
},
|
|
232
|
+
copy: (target) => {
|
|
233
|
+
return this.resolve(async ([rTarget]) => {
|
|
234
|
+
return solidAPI.copy(rTarget);
|
|
235
|
+
}, target);
|
|
236
|
+
},
|
|
237
|
+
createBufferGeometry: async (_solid) => {
|
|
238
|
+
await this.queue;
|
|
239
|
+
this.queue = Promise.resolve(0);
|
|
240
|
+
const rSolid = await _solid;
|
|
241
|
+
await baseModelerAPI.requestVisualisationOfObject(rSolid);
|
|
242
|
+
const entity = await getEntity(drawingId, rSolid);
|
|
243
|
+
if (entity != null) {
|
|
244
|
+
return (0, three_stdlib_1.mergeBufferGeometries)(entity.meshes.map(m => m.geometry));
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
createScene: async (solids, options) => {
|
|
248
|
+
var e_1, _a;
|
|
249
|
+
await this.queue;
|
|
250
|
+
this.queue = Promise.resolve(0);
|
|
251
|
+
const scene = new three_1.Scene();
|
|
252
|
+
scene.name = 'Scene'; // Default name for the scene
|
|
253
|
+
const part = new three_1.Group();
|
|
254
|
+
part.name = 'Part'; // Default name for the part
|
|
255
|
+
const _solids = [];
|
|
256
|
+
const meshes = [];
|
|
257
|
+
try {
|
|
258
|
+
for (var solids_1 = __asyncValues(solids), solids_1_1; solids_1_1 = await solids_1.next(), !solids_1_1.done;) {
|
|
259
|
+
const _solid = solids_1_1.value;
|
|
260
|
+
await baseModelerAPI.requestVisualisationOfObject(_solid);
|
|
261
|
+
const cDrawing = (0, core_1.getDrawing)(drawingId);
|
|
262
|
+
const solidObject = cDrawing.structure.tree[_solid];
|
|
263
|
+
if (solidObject) {
|
|
264
|
+
const _solidGroup = new three_1.Group();
|
|
265
|
+
_solidGroup.name = solidObject.name;
|
|
266
|
+
_solidGroup.userData = { id: solidObject.id }; // add solid id to the userData
|
|
267
|
+
const entities = solidObject.geometryIdList;
|
|
268
|
+
if (entities && entities.length > 0) {
|
|
269
|
+
const entity = cDrawing.geometry.cache[entities[0]];
|
|
270
|
+
if (entity && entity.meshes.length > 0) {
|
|
271
|
+
if (options === null || options === void 0 ? void 0 : options.meshPerGeometry) {
|
|
272
|
+
// Create a mesh for each geometry element
|
|
273
|
+
entity.meshes.forEach(m => {
|
|
274
|
+
const mesh = new three_1.Mesh();
|
|
275
|
+
mesh.userData = { id: m.graphicId }; // add graphic id to the userData
|
|
276
|
+
mesh.geometry = m.geometry;
|
|
277
|
+
mesh.material = new three_1.MeshStandardMaterial({
|
|
278
|
+
color: m.color ? m.color : entity.color,
|
|
279
|
+
transparent: m.opacity ? m.opacity < 1 : entity.opacity < 1,
|
|
280
|
+
opacity: m.opacity ? m.opacity : entity.opacity,
|
|
281
|
+
});
|
|
282
|
+
_solidGroup.add(mesh);
|
|
283
|
+
meshes.push(mesh);
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
// Merge all geometries into one mesh, sort them by color
|
|
288
|
+
const colorMeshesMap = (0, meshes_1.getDifferentColoredMeshesFromEntity)(entity);
|
|
289
|
+
Object.keys(colorMeshesMap).forEach(key => {
|
|
290
|
+
const mesh = new three_1.Mesh();
|
|
291
|
+
mesh.geometry = (0, three_stdlib_1.mergeBufferGeometries)(colorMeshesMap[key].meshes.map(m => m.geometry));
|
|
292
|
+
mesh.material = new three_1.MeshStandardMaterial({
|
|
293
|
+
color: colorMeshesMap[key].color,
|
|
294
|
+
transparent: colorMeshesMap[key].opacity < 1,
|
|
295
|
+
opacity: colorMeshesMap[key].opacity,
|
|
296
|
+
});
|
|
297
|
+
_solidGroup.add(mesh); // Add mesh to solid of the scene
|
|
298
|
+
meshes.push(mesh); // Collect mesh to return later
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
part.add(_solidGroup); // Add solid to part of the scene
|
|
302
|
+
_solids.push(_solidGroup); // Collect solid to return later
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
309
|
+
finally {
|
|
310
|
+
try {
|
|
311
|
+
if (solids_1_1 && !solids_1_1.done && (_a = solids_1.return)) await _a.call(solids_1);
|
|
312
|
+
}
|
|
313
|
+
finally { if (e_1) throw e_1.error; }
|
|
314
|
+
}
|
|
315
|
+
scene.add(part); // Add part to the scene
|
|
316
|
+
return { scene, part, solids: _solids, meshes };
|
|
317
|
+
},
|
|
318
|
+
cylinder: (length, diameter) => {
|
|
319
|
+
return this.resolve(async () => {
|
|
320
|
+
return solidAPI.createCylinder(length, diameter);
|
|
321
|
+
});
|
|
322
|
+
},
|
|
323
|
+
edgeLoops: (breps) => {
|
|
324
|
+
return this.resolve(async ([rBreps]) => {
|
|
325
|
+
return solidAPI.edgeLoops(rBreps);
|
|
326
|
+
}, breps);
|
|
327
|
+
},
|
|
328
|
+
export: (solidIds) => {
|
|
329
|
+
return this.resolve(async ([rSolidIds]) => {
|
|
330
|
+
return solidAPI.export('stp', rSolidIds);
|
|
331
|
+
}, solidIds);
|
|
332
|
+
},
|
|
333
|
+
extendSolidAtPlane: (target, point, normal, distance) => {
|
|
334
|
+
return this.resolve(async ([rTarget]) => {
|
|
335
|
+
return solidAPI.solidExtendAtPlane(rTarget, makeNbrVec(point), makeNbrVec(normal), distance);
|
|
336
|
+
}, target);
|
|
337
|
+
},
|
|
338
|
+
extrude: (height, region) => {
|
|
339
|
+
return this.resolve(async () => {
|
|
340
|
+
if (isShape(region)) {
|
|
341
|
+
const curveArray = makeCCData(region.curves);
|
|
342
|
+
return solidAPI.createExtrudeRegion(makeNbrVec(height), curveArray);
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
return solidAPI.createExtrude(makeNbrVec(height), region.points, region.bulges);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
},
|
|
349
|
+
fillet: (radius, edges) => {
|
|
350
|
+
return this.resolve(async ([rEdges]) => {
|
|
351
|
+
return solidAPI.createFillet(radius, rEdges);
|
|
352
|
+
}, edges);
|
|
353
|
+
},
|
|
354
|
+
import: (data) => {
|
|
355
|
+
return this.resolve(async () => {
|
|
356
|
+
return solidAPI.import(data, 'stp');
|
|
357
|
+
});
|
|
358
|
+
},
|
|
359
|
+
intersect: (solidId, keepSolid, ...bodies) => {
|
|
360
|
+
return this.resolve(async ([rSolidId, ...rBodies]) => {
|
|
361
|
+
for (const rBody of rBodies) {
|
|
362
|
+
solidAPI.intersect(rSolidId, keepSolid, rBody);
|
|
363
|
+
}
|
|
364
|
+
return rSolidId;
|
|
365
|
+
}, solidId, ...bodies);
|
|
366
|
+
},
|
|
367
|
+
load: (data) => {
|
|
368
|
+
return this.resolve(async () => {
|
|
369
|
+
const productId = await solidAPI.load(data, 'ofb', true);
|
|
370
|
+
if (productId !== null) {
|
|
371
|
+
const drawing = (0, core_1.getDrawing)(drawingId);
|
|
372
|
+
const solids = drawing.structure.tree[productId].solids;
|
|
373
|
+
if (solids !== undefined) {
|
|
374
|
+
return solids.map(innerId => drawing.graphic.containers[innerId].owner);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return [];
|
|
378
|
+
});
|
|
379
|
+
},
|
|
380
|
+
mirror: (target, point, normal) => {
|
|
381
|
+
return this.resolve(async ([rTarget]) => {
|
|
382
|
+
return solidAPI.mirror(rTarget, makeNbrVec(point), makeNbrEuler(normal));
|
|
383
|
+
}, target);
|
|
384
|
+
},
|
|
385
|
+
moveTo: (target, position) => {
|
|
386
|
+
return this.resolve(async ([rTarget]) => {
|
|
387
|
+
return solidAPI.moveTo(rTarget, makeNbrVec(position));
|
|
388
|
+
}, target);
|
|
389
|
+
},
|
|
390
|
+
offset: (target, offsetDistance) => {
|
|
391
|
+
return this.resolve(async ([rTarget]) => {
|
|
392
|
+
return solidAPI.offset(rTarget, offsetDistance);
|
|
393
|
+
}, target);
|
|
394
|
+
},
|
|
395
|
+
pick: (target, type, ...points) => {
|
|
396
|
+
return this.resolve(async ([rTarget]) => {
|
|
397
|
+
const pts = points.map(pt => makeNbrVec(pt));
|
|
398
|
+
const breps = await solidAPI.pick(rTarget, type, ...pts);
|
|
399
|
+
if (breps !== null) {
|
|
400
|
+
return Array.isArray(breps) ? breps : [breps];
|
|
401
|
+
}
|
|
402
|
+
}, target);
|
|
403
|
+
},
|
|
404
|
+
revolve: (position, direction, angle, region) => {
|
|
405
|
+
return this.resolve(async () => {
|
|
406
|
+
if (isShape(region)) {
|
|
407
|
+
const curveArray = makeCCData(region.curves);
|
|
408
|
+
return solidAPI.createRevolveRegion(makeNbrVec(position), makeNbrVec(direction), angle, curveArray);
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
return solidAPI.createRevolve(makeNbrVec(position), makeNbrVec(direction), (angle / Math.PI) * 180, region.points, region.bulges);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
},
|
|
415
|
+
rotateTo: (target, point) => {
|
|
416
|
+
return this.resolve(async ([rTarget]) => {
|
|
417
|
+
return solidAPI.rotateTo(rTarget, makeNbrEuler(point));
|
|
418
|
+
}, target);
|
|
419
|
+
},
|
|
420
|
+
save: () => {
|
|
421
|
+
return this.resolve(async () => {
|
|
422
|
+
return solidAPI.save('ofb');
|
|
423
|
+
});
|
|
424
|
+
},
|
|
425
|
+
scale: (target, pointOrFactor) => {
|
|
426
|
+
return this.resolve(async ([rTarget]) => {
|
|
427
|
+
const lPointOrFactor = typeof pointOrFactor === 'number' ? pointOrFactor : makeNbrVec(pointOrFactor);
|
|
428
|
+
return solidAPI.scale(rTarget, lPointOrFactor);
|
|
429
|
+
}, target);
|
|
430
|
+
},
|
|
431
|
+
setFacetingParams: (distanceTol, angleTol) => {
|
|
432
|
+
return this.resolve(async () => {
|
|
433
|
+
return commonAPI.setFacetingParameters(distanceTol, angleTol);
|
|
434
|
+
});
|
|
435
|
+
},
|
|
436
|
+
slice: (target, point, normal) => {
|
|
437
|
+
return this.resolve(async ([rTarget]) => {
|
|
438
|
+
return solidAPI.slice(rTarget, makeNbrVec(point), makeNbrVec(normal));
|
|
439
|
+
}, target);
|
|
440
|
+
},
|
|
441
|
+
sphere: (radius) => {
|
|
442
|
+
return this.resolve(async () => {
|
|
443
|
+
return solidAPI.createSphere(radius);
|
|
444
|
+
});
|
|
445
|
+
},
|
|
446
|
+
subtract: (solidId, keepSolid, ...bodies) => {
|
|
447
|
+
return this.resolve(async ([rSolidId, ...rBodies]) => {
|
|
448
|
+
for (const rBody of rBodies) {
|
|
449
|
+
solidAPI.subtract(rSolidId, keepSolid, rBody);
|
|
450
|
+
}
|
|
451
|
+
return rSolidId;
|
|
452
|
+
}, solidId, ...bodies);
|
|
453
|
+
},
|
|
454
|
+
union: (solidId, keepSolid, ...bodies) => {
|
|
455
|
+
return this.resolve(async ([rSolidId, ...rBodies]) => {
|
|
456
|
+
for (const rBody of rBodies) {
|
|
457
|
+
solidAPI.union(rSolidId, keepSolid, rBody);
|
|
458
|
+
}
|
|
459
|
+
return rSolidId;
|
|
460
|
+
}, solidId, ...bodies);
|
|
461
|
+
},
|
|
462
|
+
};
|
|
463
|
+
callback(publicApi);
|
|
464
|
+
resolve(drawingId);
|
|
465
|
+
});
|
|
466
|
+
return () => promise.then(drawingId => core_1.api.getState().api.removeDrawing(drawingId));
|
|
467
|
+
}
|
|
468
|
+
destroy() {
|
|
469
|
+
this.drawingId && core_1.api.getState().api.removeDrawing(this.drawingId);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
exports.Solid = Solid;
|
|
473
|
+
class solid extends Solid {
|
|
474
|
+
constructor() {
|
|
475
|
+
super();
|
|
476
|
+
console.warn("Warning: 'solid' is deprecated, use 'Solid' instead, 'solid' will be removed in a future release.");
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
exports.solid = solid;
|