@jwc/jscad-utils 5.2.0 → 5.5.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/README.md +1 -5
- package/dist/compat.js +641 -100
- package/dist/examples/bisect.jscad +471 -93
- package/dist/examples/bisect2.jscad +2614 -0
- package/dist/examples/boxes.jscad +481 -102
- package/dist/examples/chamfer.jscad +471 -93
- package/dist/examples/fillet.jscad +471 -93
- package/dist/examples/fit.jscad +471 -93
- package/dist/examples/groups.jscad +471 -93
- package/dist/examples/midlineTo.jscad +471 -93
- package/dist/examples/parts-hexagon.jscad +471 -93
- package/dist/examples/rabett-tb.jscad +471 -93
- package/dist/examples/rabett.jscad +471 -93
- package/dist/examples/rabett2.jscad +471 -93
- package/dist/examples/rabett3.jscad +2614 -0
- package/dist/examples/retraction-test.jscad +471 -93
- package/dist/examples/size.jscad +471 -93
- package/dist/examples/snap.jscad +471 -93
- package/dist/examples/text.jscad +471 -93
- package/dist/examples/wedge.jscad +471 -93
- package/dist/index.js +638 -100
- package/package.json +8 -4
- package/src/add-prototype.js +5 -1
- package/src/boxes.js +11 -3
- package/src/compat.js +3 -0
- package/src/group.js +13 -11
- package/src/parts.js +25 -23
- package/src/util.js +239 -72
- package/src/validate.js +335 -0
|
@@ -0,0 +1,2614 @@
|
|
|
1
|
+
function main() {
|
|
2
|
+
// var jscadUtils = initJscadutils();
|
|
3
|
+
util.init(CSG, { debug: 'jscadUtils:*' });
|
|
4
|
+
|
|
5
|
+
const sideThickness = 3;
|
|
6
|
+
const bottomThickness = 5;
|
|
7
|
+
const bbox = Parts.Cube([88.5, 57.39, 18.21]).center();
|
|
8
|
+
|
|
9
|
+
const exteriorSize = bbox.size();
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
console.log('bbox size', bbox.size());
|
|
13
|
+
const exterior = Parts.RoundedCube(
|
|
14
|
+
exteriorSize.x,
|
|
15
|
+
exteriorSize.y,
|
|
16
|
+
exteriorSize.z,
|
|
17
|
+
sideThickness
|
|
18
|
+
)
|
|
19
|
+
.align(bbox, 'xyz')
|
|
20
|
+
.enlarge([sideThickness * 2, sideThickness * 2, 0])
|
|
21
|
+
.stretch('z', bottomThickness + sideThickness, 0)
|
|
22
|
+
// .translate([0, 0, -bottomThickness])
|
|
23
|
+
// .translate([0, 0, -(bottomThickness - 0.5)])
|
|
24
|
+
.snap(bbox, 'z', 'inside+', sideThickness)
|
|
25
|
+
.subtract(bbox);
|
|
26
|
+
console.log('exterior size', exterior.size());
|
|
27
|
+
|
|
28
|
+
var p = util.bisect(exterior, 'z', -5, { color: true });
|
|
29
|
+
|
|
30
|
+
var q = util.bisect(p.parts.negative, 'z', -7, { color: true });
|
|
31
|
+
|
|
32
|
+
return q.combine();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// include:js
|
|
36
|
+
// ../dist/compat.js
|
|
37
|
+
var Parts, Boxes, Group, Debug, array, triUtils;
|
|
38
|
+
|
|
39
|
+
function initJscadutils(_CSG, options = {}) {
|
|
40
|
+
options = Object.assign({
|
|
41
|
+
debug: ""
|
|
42
|
+
}, options);
|
|
43
|
+
var jsCadCSG = {
|
|
44
|
+
CSG,
|
|
45
|
+
CAG
|
|
46
|
+
};
|
|
47
|
+
var scadApi = {
|
|
48
|
+
vector_text,
|
|
49
|
+
rectangular_extrude,
|
|
50
|
+
vector_char,
|
|
51
|
+
primitives3d: {
|
|
52
|
+
cube,
|
|
53
|
+
sphere,
|
|
54
|
+
cylinder
|
|
55
|
+
},
|
|
56
|
+
extrusions: {
|
|
57
|
+
rectangular_extrude
|
|
58
|
+
},
|
|
59
|
+
text: {
|
|
60
|
+
vector_text,
|
|
61
|
+
vector_char
|
|
62
|
+
},
|
|
63
|
+
booleanOps: {
|
|
64
|
+
union
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var jscadUtilsDebug = (options.debug.split(",") || []).reduce((checks, check) => {
|
|
68
|
+
if (check.startsWith("-")) {
|
|
69
|
+
checks.disabled.push(new RegExp(`^${check.slice(1).replace(/\*/g, ".*?")}$`));
|
|
70
|
+
} else {
|
|
71
|
+
checks.enabled.push(new RegExp(`^${check.replace(/\*/g, ".*?")}$`));
|
|
72
|
+
}
|
|
73
|
+
return checks;
|
|
74
|
+
}, {
|
|
75
|
+
enabled: [],
|
|
76
|
+
disabled: []
|
|
77
|
+
});
|
|
78
|
+
var jscadUtilsAssertValidCSGWarnings = options.assertValidCSGWarnings || false;
|
|
79
|
+
var jscadUtilsAssertValidCSG = options.assertValidCSG || false;
|
|
80
|
+
var jscadUtils = function(exports, jsCadCSG, scadApi) {
|
|
81
|
+
"use strict";
|
|
82
|
+
function _interopDefaultLegacy(e) {
|
|
83
|
+
return e && typeof e === "object" && "default" in e ? e : {
|
|
84
|
+
default: e
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
var jsCadCSG__default = _interopDefaultLegacy(jsCadCSG);
|
|
88
|
+
var scadApi__default = _interopDefaultLegacy(scadApi);
|
|
89
|
+
var util = Object.freeze({
|
|
90
|
+
__proto__: null,
|
|
91
|
+
get NOZZEL_SIZE() {
|
|
92
|
+
return NOZZEL_SIZE;
|
|
93
|
+
},
|
|
94
|
+
get nearest() {
|
|
95
|
+
return nearest;
|
|
96
|
+
},
|
|
97
|
+
get identity() {
|
|
98
|
+
return identity;
|
|
99
|
+
},
|
|
100
|
+
get result() {
|
|
101
|
+
return result;
|
|
102
|
+
},
|
|
103
|
+
get defaults() {
|
|
104
|
+
return defaults;
|
|
105
|
+
},
|
|
106
|
+
get isEmpty() {
|
|
107
|
+
return isEmpty;
|
|
108
|
+
},
|
|
109
|
+
get isNegative() {
|
|
110
|
+
return isNegative;
|
|
111
|
+
},
|
|
112
|
+
get print() {
|
|
113
|
+
return print;
|
|
114
|
+
},
|
|
115
|
+
get jscadToString() {
|
|
116
|
+
return jscadToString;
|
|
117
|
+
},
|
|
118
|
+
get error() {
|
|
119
|
+
return error;
|
|
120
|
+
},
|
|
121
|
+
get depreciated() {
|
|
122
|
+
return depreciated;
|
|
123
|
+
},
|
|
124
|
+
get inch() {
|
|
125
|
+
return inch;
|
|
126
|
+
},
|
|
127
|
+
get cm() {
|
|
128
|
+
return cm;
|
|
129
|
+
},
|
|
130
|
+
get label() {
|
|
131
|
+
return label;
|
|
132
|
+
},
|
|
133
|
+
get text() {
|
|
134
|
+
return text;
|
|
135
|
+
},
|
|
136
|
+
get unitCube() {
|
|
137
|
+
return unitCube;
|
|
138
|
+
},
|
|
139
|
+
get unitAxis() {
|
|
140
|
+
return unitAxis;
|
|
141
|
+
},
|
|
142
|
+
get toArray() {
|
|
143
|
+
return toArray;
|
|
144
|
+
},
|
|
145
|
+
get ifArray() {
|
|
146
|
+
return ifArray;
|
|
147
|
+
},
|
|
148
|
+
get segment() {
|
|
149
|
+
return segment;
|
|
150
|
+
},
|
|
151
|
+
get zipObject() {
|
|
152
|
+
return zipObject;
|
|
153
|
+
},
|
|
154
|
+
get map() {
|
|
155
|
+
return map;
|
|
156
|
+
},
|
|
157
|
+
get mapValues() {
|
|
158
|
+
return mapValues;
|
|
159
|
+
},
|
|
160
|
+
get pick() {
|
|
161
|
+
return pick;
|
|
162
|
+
},
|
|
163
|
+
get mapPick() {
|
|
164
|
+
return mapPick;
|
|
165
|
+
},
|
|
166
|
+
get divA() {
|
|
167
|
+
return divA;
|
|
168
|
+
},
|
|
169
|
+
get divxyz() {
|
|
170
|
+
return divxyz;
|
|
171
|
+
},
|
|
172
|
+
get div() {
|
|
173
|
+
return div;
|
|
174
|
+
},
|
|
175
|
+
get mulxyz() {
|
|
176
|
+
return mulxyz;
|
|
177
|
+
},
|
|
178
|
+
get mul() {
|
|
179
|
+
return mul;
|
|
180
|
+
},
|
|
181
|
+
get xyz2array() {
|
|
182
|
+
return xyz2array;
|
|
183
|
+
},
|
|
184
|
+
get rotationAxes() {
|
|
185
|
+
return rotationAxes;
|
|
186
|
+
},
|
|
187
|
+
get size() {
|
|
188
|
+
return size;
|
|
189
|
+
},
|
|
190
|
+
get scale() {
|
|
191
|
+
return scale;
|
|
192
|
+
},
|
|
193
|
+
get center() {
|
|
194
|
+
return center;
|
|
195
|
+
},
|
|
196
|
+
get centerY() {
|
|
197
|
+
return centerY;
|
|
198
|
+
},
|
|
199
|
+
get centerX() {
|
|
200
|
+
return centerX;
|
|
201
|
+
},
|
|
202
|
+
get enlarge() {
|
|
203
|
+
return enlarge;
|
|
204
|
+
},
|
|
205
|
+
get fit() {
|
|
206
|
+
return fit;
|
|
207
|
+
},
|
|
208
|
+
get shift() {
|
|
209
|
+
return shift;
|
|
210
|
+
},
|
|
211
|
+
get zero() {
|
|
212
|
+
return zero;
|
|
213
|
+
},
|
|
214
|
+
get mirrored4() {
|
|
215
|
+
return mirrored4;
|
|
216
|
+
},
|
|
217
|
+
get flushSide() {
|
|
218
|
+
return flushSide;
|
|
219
|
+
},
|
|
220
|
+
get calcFlush() {
|
|
221
|
+
return calcFlush;
|
|
222
|
+
},
|
|
223
|
+
get calcSnap() {
|
|
224
|
+
return calcSnap;
|
|
225
|
+
},
|
|
226
|
+
get snap() {
|
|
227
|
+
return snap;
|
|
228
|
+
},
|
|
229
|
+
get flush() {
|
|
230
|
+
return flush;
|
|
231
|
+
},
|
|
232
|
+
get axisApply() {
|
|
233
|
+
return axisApply;
|
|
234
|
+
},
|
|
235
|
+
get axis2array() {
|
|
236
|
+
return axis2array;
|
|
237
|
+
},
|
|
238
|
+
get centroid() {
|
|
239
|
+
return centroid;
|
|
240
|
+
},
|
|
241
|
+
get calcmidlineTo() {
|
|
242
|
+
return calcmidlineTo;
|
|
243
|
+
},
|
|
244
|
+
get midlineTo() {
|
|
245
|
+
return midlineTo;
|
|
246
|
+
},
|
|
247
|
+
get translator() {
|
|
248
|
+
return translator;
|
|
249
|
+
},
|
|
250
|
+
get calcCenterWith() {
|
|
251
|
+
return calcCenterWith;
|
|
252
|
+
},
|
|
253
|
+
get centerWith() {
|
|
254
|
+
return centerWith;
|
|
255
|
+
},
|
|
256
|
+
get getDelta() {
|
|
257
|
+
return getDelta;
|
|
258
|
+
},
|
|
259
|
+
get bisect() {
|
|
260
|
+
return bisect;
|
|
261
|
+
},
|
|
262
|
+
get slice() {
|
|
263
|
+
return slice;
|
|
264
|
+
},
|
|
265
|
+
get wedge() {
|
|
266
|
+
return wedge;
|
|
267
|
+
},
|
|
268
|
+
get stretch() {
|
|
269
|
+
return stretch;
|
|
270
|
+
},
|
|
271
|
+
get poly2solid() {
|
|
272
|
+
return poly2solid;
|
|
273
|
+
},
|
|
274
|
+
get slices2poly() {
|
|
275
|
+
return slices2poly;
|
|
276
|
+
},
|
|
277
|
+
get normalVector() {
|
|
278
|
+
return normalVector;
|
|
279
|
+
},
|
|
280
|
+
get sliceParams() {
|
|
281
|
+
return sliceParams;
|
|
282
|
+
},
|
|
283
|
+
get reShape() {
|
|
284
|
+
return reShape;
|
|
285
|
+
},
|
|
286
|
+
get chamfer() {
|
|
287
|
+
return chamfer;
|
|
288
|
+
},
|
|
289
|
+
get fillet() {
|
|
290
|
+
return fillet;
|
|
291
|
+
},
|
|
292
|
+
get calcRotate() {
|
|
293
|
+
return calcRotate;
|
|
294
|
+
},
|
|
295
|
+
get rotateAround() {
|
|
296
|
+
return rotateAround;
|
|
297
|
+
},
|
|
298
|
+
get clone() {
|
|
299
|
+
return clone;
|
|
300
|
+
},
|
|
301
|
+
get addConnector() {
|
|
302
|
+
return addConnector;
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
function _arrayLikeToArray(r, a) {
|
|
306
|
+
(null == a || a > r.length) && (a = r.length);
|
|
307
|
+
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
308
|
+
return n;
|
|
309
|
+
}
|
|
310
|
+
function _arrayWithHoles(r) {
|
|
311
|
+
if (Array.isArray(r)) return r;
|
|
312
|
+
}
|
|
313
|
+
function _createForOfIteratorHelper(r, e) {
|
|
314
|
+
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
315
|
+
if (!t) {
|
|
316
|
+
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
|
|
317
|
+
t && (r = t);
|
|
318
|
+
var n = 0, F = function() {};
|
|
319
|
+
return {
|
|
320
|
+
s: F,
|
|
321
|
+
n: function() {
|
|
322
|
+
return n >= r.length ? {
|
|
323
|
+
done: !0
|
|
324
|
+
} : {
|
|
325
|
+
done: !1,
|
|
326
|
+
value: r[n++]
|
|
327
|
+
};
|
|
328
|
+
},
|
|
329
|
+
e: function(r) {
|
|
330
|
+
throw r;
|
|
331
|
+
},
|
|
332
|
+
f: F
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
336
|
+
}
|
|
337
|
+
var o, a = !0, u = !1;
|
|
338
|
+
return {
|
|
339
|
+
s: function() {
|
|
340
|
+
t = t.call(r);
|
|
341
|
+
},
|
|
342
|
+
n: function() {
|
|
343
|
+
var r = t.next();
|
|
344
|
+
return a = r.done, r;
|
|
345
|
+
},
|
|
346
|
+
e: function(r) {
|
|
347
|
+
u = !0, o = r;
|
|
348
|
+
},
|
|
349
|
+
f: function() {
|
|
350
|
+
try {
|
|
351
|
+
a || null == t.return || t.return();
|
|
352
|
+
} finally {
|
|
353
|
+
if (u) throw o;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
function _defineProperty(e, r, t) {
|
|
359
|
+
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
360
|
+
value: t,
|
|
361
|
+
enumerable: !0,
|
|
362
|
+
configurable: !0,
|
|
363
|
+
writable: !0
|
|
364
|
+
}) : e[r] = t, e;
|
|
365
|
+
}
|
|
366
|
+
function _iterableToArrayLimit(r, l) {
|
|
367
|
+
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
368
|
+
if (null != t) {
|
|
369
|
+
var e, n, i, u, a = [], f = !0, o = !1;
|
|
370
|
+
try {
|
|
371
|
+
if (i = (t = t.call(r)).next, 0 === l) {
|
|
372
|
+
if (Object(t) !== t) return;
|
|
373
|
+
f = !1;
|
|
374
|
+
} else for (;!(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0) ;
|
|
375
|
+
} catch (r) {
|
|
376
|
+
o = !0, n = r;
|
|
377
|
+
} finally {
|
|
378
|
+
try {
|
|
379
|
+
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
|
|
380
|
+
} finally {
|
|
381
|
+
if (o) throw n;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return a;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
function _nonIterableRest() {
|
|
388
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
389
|
+
}
|
|
390
|
+
function ownKeys(e, r) {
|
|
391
|
+
var t = Object.keys(e);
|
|
392
|
+
if (Object.getOwnPropertySymbols) {
|
|
393
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
394
|
+
r && (o = o.filter(function(r) {
|
|
395
|
+
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
396
|
+
})), t.push.apply(t, o);
|
|
397
|
+
}
|
|
398
|
+
return t;
|
|
399
|
+
}
|
|
400
|
+
function _objectSpread2(e) {
|
|
401
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
402
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
403
|
+
r % 2 ? ownKeys(Object(t), !0).forEach(function(r) {
|
|
404
|
+
_defineProperty(e, r, t[r]);
|
|
405
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r) {
|
|
406
|
+
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
return e;
|
|
410
|
+
}
|
|
411
|
+
function _slicedToArray(r, e) {
|
|
412
|
+
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
|
|
413
|
+
}
|
|
414
|
+
function _toPrimitive(t, r) {
|
|
415
|
+
if ("object" != typeof t || !t) return t;
|
|
416
|
+
var e = t[Symbol.toPrimitive];
|
|
417
|
+
if (void 0 !== e) {
|
|
418
|
+
var i = e.call(t, r || "default");
|
|
419
|
+
if ("object" != typeof i) return i;
|
|
420
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
421
|
+
}
|
|
422
|
+
return ("string" === r ? String : Number)(t);
|
|
423
|
+
}
|
|
424
|
+
function _toPropertyKey(t) {
|
|
425
|
+
var i = _toPrimitive(t, "string");
|
|
426
|
+
return "symbol" == typeof i ? i : i + "";
|
|
427
|
+
}
|
|
428
|
+
function _typeof(o) {
|
|
429
|
+
"@babel/helpers - typeof";
|
|
430
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
431
|
+
return typeof o;
|
|
432
|
+
} : function(o) {
|
|
433
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
434
|
+
}, _typeof(o);
|
|
435
|
+
}
|
|
436
|
+
function _unsupportedIterableToArray(r, a) {
|
|
437
|
+
if (r) {
|
|
438
|
+
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
439
|
+
var t = {}.toString.call(r).slice(8, -1);
|
|
440
|
+
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
var toRadians = function toRadians(deg) {
|
|
444
|
+
return deg / 180 * Math.PI;
|
|
445
|
+
};
|
|
446
|
+
var toDegrees = function toDegrees(rad) {
|
|
447
|
+
return rad * (180 / Math.PI);
|
|
448
|
+
};
|
|
449
|
+
var solve = function solve(p1, p2) {
|
|
450
|
+
var r = {
|
|
451
|
+
c: 90,
|
|
452
|
+
A: Math.abs(p2.x - p1.x),
|
|
453
|
+
B: Math.abs(p2.y - p1.y)
|
|
454
|
+
};
|
|
455
|
+
var brad = Math.atan2(r.B, r.A);
|
|
456
|
+
r.b = this.toDegrees(brad);
|
|
457
|
+
r.C = r.B / Math.sin(brad);
|
|
458
|
+
r.a = 90 - r.b;
|
|
459
|
+
return r;
|
|
460
|
+
};
|
|
461
|
+
var solve90SA = function solve90SA(r) {
|
|
462
|
+
r = Object.assign(r, {
|
|
463
|
+
C: 90
|
|
464
|
+
});
|
|
465
|
+
r.A = r.A || 90 - r.B;
|
|
466
|
+
r.B = r.B || 90 - r.A;
|
|
467
|
+
var arad = toRadians(r.A);
|
|
468
|
+
r.a = r.a || (r.c ? r.c * Math.sin(arad) : r.b * Math.tan(arad));
|
|
469
|
+
r.c = r.c || r.a / Math.sin(arad);
|
|
470
|
+
r.b = r.b || r.a / Math.tan(arad);
|
|
471
|
+
return r;
|
|
472
|
+
};
|
|
473
|
+
var solve90ac = function solve90ac(r) {
|
|
474
|
+
r = Object.assign(r, {
|
|
475
|
+
C: 90
|
|
476
|
+
});
|
|
477
|
+
var arad = Math.asin(r.a / r.c);
|
|
478
|
+
r.A = toDegrees(arad);
|
|
479
|
+
r.B = 90 - r.A;
|
|
480
|
+
r.b = Math.sqrt(Math.pow(r.c, 2) - Math.pow(r.a, 2));
|
|
481
|
+
return r;
|
|
482
|
+
};
|
|
483
|
+
function solveab(r) {
|
|
484
|
+
r = Object.assign(r, {
|
|
485
|
+
C: 90
|
|
486
|
+
});
|
|
487
|
+
r.c = Math.sqrt(Math.pow(r.a, 2) + Math.pow(r.b, 2));
|
|
488
|
+
r.A = toDegrees(Math.asin(r.a / r.c));
|
|
489
|
+
r.B = toDegrees(Math.asin(r.b / r.c));
|
|
490
|
+
return r;
|
|
491
|
+
}
|
|
492
|
+
var triUtils = Object.freeze({
|
|
493
|
+
__proto__: null,
|
|
494
|
+
toRadians,
|
|
495
|
+
toDegrees,
|
|
496
|
+
solve,
|
|
497
|
+
solve90SA,
|
|
498
|
+
solve90ac,
|
|
499
|
+
solveab
|
|
500
|
+
});
|
|
501
|
+
var div$1 = function div(a, f) {
|
|
502
|
+
return a.map(function(e) {
|
|
503
|
+
return e / f;
|
|
504
|
+
});
|
|
505
|
+
};
|
|
506
|
+
var addValue = function addValue(a, f) {
|
|
507
|
+
return a.map(function(e) {
|
|
508
|
+
return e + f;
|
|
509
|
+
});
|
|
510
|
+
};
|
|
511
|
+
var addArray = function addArray(a, f) {
|
|
512
|
+
return a.map(function(e, i) {
|
|
513
|
+
return e + f[i];
|
|
514
|
+
});
|
|
515
|
+
};
|
|
516
|
+
var add = function add(a) {
|
|
517
|
+
return Array.prototype.slice.call(arguments, 1).reduce(function(result, arg) {
|
|
518
|
+
if (Array.isArray(arg)) {
|
|
519
|
+
result = addArray(result, arg);
|
|
520
|
+
} else {
|
|
521
|
+
result = addValue(result, arg);
|
|
522
|
+
}
|
|
523
|
+
return result;
|
|
524
|
+
}, a);
|
|
525
|
+
};
|
|
526
|
+
var fromxyz = function fromxyz(object) {
|
|
527
|
+
return Array.isArray(object) ? object : [ object.x, object.y, object.z ];
|
|
528
|
+
};
|
|
529
|
+
var toxyz = function toxyz(a) {
|
|
530
|
+
return {
|
|
531
|
+
x: a[0],
|
|
532
|
+
y: a[1],
|
|
533
|
+
z: a[2]
|
|
534
|
+
};
|
|
535
|
+
};
|
|
536
|
+
var first = function first(a) {
|
|
537
|
+
return a ? a[0] : undefined;
|
|
538
|
+
};
|
|
539
|
+
var last = function last(a) {
|
|
540
|
+
return a && a.length > 0 ? a[a.length - 1] : undefined;
|
|
541
|
+
};
|
|
542
|
+
var min = function min(a) {
|
|
543
|
+
return a.reduce(function(result, value) {
|
|
544
|
+
return value < result ? value : result;
|
|
545
|
+
}, Number.MAX_VALUE);
|
|
546
|
+
};
|
|
547
|
+
var range = function range(a, b) {
|
|
548
|
+
var result = [];
|
|
549
|
+
for (var i = a; i < b; i++) {
|
|
550
|
+
result.push(i);
|
|
551
|
+
}
|
|
552
|
+
return result;
|
|
553
|
+
};
|
|
554
|
+
var array = Object.freeze({
|
|
555
|
+
__proto__: null,
|
|
556
|
+
div: div$1,
|
|
557
|
+
addValue,
|
|
558
|
+
addArray,
|
|
559
|
+
add,
|
|
560
|
+
fromxyz,
|
|
561
|
+
toxyz,
|
|
562
|
+
first,
|
|
563
|
+
last,
|
|
564
|
+
min,
|
|
565
|
+
range
|
|
566
|
+
});
|
|
567
|
+
var debugColors = [ "#e41a1c", "#377eb8", "#4daf4a", "#984ea3", "#ff7f00", "#ffff33", "#a65628", "#f781bf", "#999999" ];
|
|
568
|
+
var termColors = [ "\\033[0;34m", "\\033[0;32m", "\\033[0;36m", "\\033[0;31m", "\\033[0;35m", "\\033[0;33m", "\\033[1;33m", "\\033[0;30m", "\\033[1;34m" ];
|
|
569
|
+
var debugCount = 0;
|
|
570
|
+
var Debug = function Debug(name) {
|
|
571
|
+
var checks = Object.assign({
|
|
572
|
+
enabled: [],
|
|
573
|
+
disabled: [],
|
|
574
|
+
options: {
|
|
575
|
+
browser: true
|
|
576
|
+
}
|
|
577
|
+
}, jscadUtilsDebug || {});
|
|
578
|
+
var style = checks.options.browser ? "color:".concat(debugColors[debugCount++ % debugColors.length]) : "".concat(termColors[debugCount++ % termColors.length]);
|
|
579
|
+
var enabled = checks.enabled.some(function checkEnabled(check) {
|
|
580
|
+
return check.test(name);
|
|
581
|
+
}) && !checks.disabled.some(function checkEnabled(check) {
|
|
582
|
+
return check.test(name);
|
|
583
|
+
});
|
|
584
|
+
var logger = enabled ? checks.options.browser ? function() {
|
|
585
|
+
var _console;
|
|
586
|
+
for (var _len = arguments.length, msg = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
587
|
+
msg[_key] = arguments[_key];
|
|
588
|
+
}
|
|
589
|
+
(_console = console).log.apply(_console, [ "%c%s", style, name ].concat(msg));
|
|
590
|
+
} : function() {
|
|
591
|
+
var _console2;
|
|
592
|
+
for (var _len2 = arguments.length, msg = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
593
|
+
msg[_key2] = arguments[_key2];
|
|
594
|
+
}
|
|
595
|
+
(_console2 = console).log.apply(_console2, [ "".concat(name) ].concat(msg));
|
|
596
|
+
} : function() {
|
|
597
|
+
return undefined;
|
|
598
|
+
};
|
|
599
|
+
logger.enabled = enabled;
|
|
600
|
+
return logger;
|
|
601
|
+
};
|
|
602
|
+
var nameArray = {
|
|
603
|
+
aliceblue: "#f0f8ff",
|
|
604
|
+
antiquewhite: "#faebd7",
|
|
605
|
+
aqua: "#00ffff",
|
|
606
|
+
aquamarine: "#7fffd4",
|
|
607
|
+
azure: "#f0ffff",
|
|
608
|
+
beige: "#f5f5dc",
|
|
609
|
+
bisque: "#ffe4c4",
|
|
610
|
+
black: "#000000",
|
|
611
|
+
blanchedalmond: "#ffebcd",
|
|
612
|
+
blue: "#0000ff",
|
|
613
|
+
blueviolet: "#8a2be2",
|
|
614
|
+
brown: "#a52a2a",
|
|
615
|
+
burlywood: "#deb887",
|
|
616
|
+
cadetblue: "#5f9ea0",
|
|
617
|
+
chartreuse: "#7fff00",
|
|
618
|
+
chocolate: "#d2691e",
|
|
619
|
+
coral: "#ff7f50",
|
|
620
|
+
cornflowerblue: "#6495ed",
|
|
621
|
+
cornsilk: "#fff8dc",
|
|
622
|
+
crimson: "#dc143c",
|
|
623
|
+
cyan: "#00ffff",
|
|
624
|
+
darkblue: "#00008b",
|
|
625
|
+
darkcyan: "#008b8b",
|
|
626
|
+
darkgoldenrod: "#b8860b",
|
|
627
|
+
darkgray: "#a9a9a9",
|
|
628
|
+
darkgrey: "#a9a9a9",
|
|
629
|
+
darkgreen: "#006400",
|
|
630
|
+
darkkhaki: "#bdb76b",
|
|
631
|
+
darkmagenta: "#8b008b",
|
|
632
|
+
darkolivegreen: "#556b2f",
|
|
633
|
+
darkorange: "#ff8c00",
|
|
634
|
+
darkorchid: "#9932cc",
|
|
635
|
+
darkred: "#8b0000",
|
|
636
|
+
darksalmon: "#e9967a",
|
|
637
|
+
darkseagreen: "#8fbc8f",
|
|
638
|
+
darkslateblue: "#483d8b",
|
|
639
|
+
darkslategray: "#2f4f4f",
|
|
640
|
+
darkslategrey: "#2f4f4f",
|
|
641
|
+
darkturquoise: "#00ced1",
|
|
642
|
+
darkviolet: "#9400d3",
|
|
643
|
+
deeppink: "#ff1493",
|
|
644
|
+
deepskyblue: "#00bfff",
|
|
645
|
+
dimgray: "#696969",
|
|
646
|
+
dimgrey: "#696969",
|
|
647
|
+
dodgerblue: "#1e90ff",
|
|
648
|
+
firebrick: "#b22222",
|
|
649
|
+
floralwhite: "#fffaf0",
|
|
650
|
+
forestgreen: "#228b22",
|
|
651
|
+
fuchsia: "#ff00ff",
|
|
652
|
+
gainsboro: "#dcdcdc",
|
|
653
|
+
ghostwhite: "#f8f8ff",
|
|
654
|
+
gold: "#ffd700",
|
|
655
|
+
goldenrod: "#daa520",
|
|
656
|
+
gray: "#808080",
|
|
657
|
+
grey: "#808080",
|
|
658
|
+
green: "#008000",
|
|
659
|
+
greenyellow: "#adff2f",
|
|
660
|
+
honeydew: "#f0fff0",
|
|
661
|
+
hotpink: "#ff69b4",
|
|
662
|
+
indianred: "#cd5c5c",
|
|
663
|
+
indigo: "#4b0082",
|
|
664
|
+
ivory: "#fffff0",
|
|
665
|
+
khaki: "#f0e68c",
|
|
666
|
+
lavender: "#e6e6fa",
|
|
667
|
+
lavenderblush: "#fff0f5",
|
|
668
|
+
lawngreen: "#7cfc00",
|
|
669
|
+
lemonchiffon: "#fffacd",
|
|
670
|
+
lightblue: "#add8e6",
|
|
671
|
+
lightcoral: "#f08080",
|
|
672
|
+
lightcyan: "#e0ffff",
|
|
673
|
+
lightgoldenrodyellow: "#fafad2",
|
|
674
|
+
lightgray: "#d3d3d3",
|
|
675
|
+
lightgrey: "#d3d3d3",
|
|
676
|
+
lightgreen: "#90ee90",
|
|
677
|
+
lightpink: "#ffb6c1",
|
|
678
|
+
lightsalmon: "#ffa07a",
|
|
679
|
+
lightseagreen: "#20b2aa",
|
|
680
|
+
lightskyblue: "#87cefa",
|
|
681
|
+
lightslategray: "#778899",
|
|
682
|
+
lightslategrey: "#778899",
|
|
683
|
+
lightsteelblue: "#b0c4de",
|
|
684
|
+
lightyellow: "#ffffe0",
|
|
685
|
+
lime: "#00ff00",
|
|
686
|
+
limegreen: "#32cd32",
|
|
687
|
+
linen: "#faf0e6",
|
|
688
|
+
magenta: "#ff00ff",
|
|
689
|
+
maroon: "#800000",
|
|
690
|
+
mediumaquamarine: "#66cdaa",
|
|
691
|
+
mediumblue: "#0000cd",
|
|
692
|
+
mediumorchid: "#ba55d3",
|
|
693
|
+
mediumpurple: "#9370d8",
|
|
694
|
+
mediumseagreen: "#3cb371",
|
|
695
|
+
mediumslateblue: "#7b68ee",
|
|
696
|
+
mediumspringgreen: "#00fa9a",
|
|
697
|
+
mediumturquoise: "#48d1cc",
|
|
698
|
+
mediumvioletred: "#c71585",
|
|
699
|
+
midnightblue: "#191970",
|
|
700
|
+
mintcream: "#f5fffa",
|
|
701
|
+
mistyrose: "#ffe4e1",
|
|
702
|
+
moccasin: "#ffe4b5",
|
|
703
|
+
navajowhite: "#ffdead",
|
|
704
|
+
navy: "#000080",
|
|
705
|
+
oldlace: "#fdf5e6",
|
|
706
|
+
olive: "#808000",
|
|
707
|
+
olivedrab: "#6b8e23",
|
|
708
|
+
orange: "#ffa500",
|
|
709
|
+
orangered: "#ff4500",
|
|
710
|
+
orchid: "#da70d6",
|
|
711
|
+
palegoldenrod: "#eee8aa",
|
|
712
|
+
palegreen: "#98fb98",
|
|
713
|
+
paleturquoise: "#afeeee",
|
|
714
|
+
palevioletred: "#d87093",
|
|
715
|
+
papayawhip: "#ffefd5",
|
|
716
|
+
peachpuff: "#ffdab9",
|
|
717
|
+
peru: "#cd853f",
|
|
718
|
+
pink: "#ffc0cb",
|
|
719
|
+
plum: "#dda0dd",
|
|
720
|
+
powderblue: "#b0e0e6",
|
|
721
|
+
purple: "#800080",
|
|
722
|
+
red: "#ff0000",
|
|
723
|
+
rosybrown: "#bc8f8f",
|
|
724
|
+
royalblue: "#4169e1",
|
|
725
|
+
saddlebrown: "#8b4513",
|
|
726
|
+
salmon: "#fa8072",
|
|
727
|
+
sandybrown: "#f4a460",
|
|
728
|
+
seagreen: "#2e8b57",
|
|
729
|
+
seashell: "#fff5ee",
|
|
730
|
+
sienna: "#a0522d",
|
|
731
|
+
silver: "#c0c0c0",
|
|
732
|
+
skyblue: "#87ceeb",
|
|
733
|
+
slateblue: "#6a5acd",
|
|
734
|
+
slategray: "#708090",
|
|
735
|
+
slategrey: "#708090",
|
|
736
|
+
snow: "#fffafa",
|
|
737
|
+
springgreen: "#00ff7f",
|
|
738
|
+
steelblue: "#4682b4",
|
|
739
|
+
tan: "#d2b48c",
|
|
740
|
+
teal: "#008080",
|
|
741
|
+
thistle: "#d8bfd8",
|
|
742
|
+
tomato: "#ff6347",
|
|
743
|
+
turquoise: "#40e0d0",
|
|
744
|
+
violet: "#ee82ee",
|
|
745
|
+
wheat: "#f5deb3",
|
|
746
|
+
white: "#ffffff",
|
|
747
|
+
whitesmoke: "#f5f5f5",
|
|
748
|
+
yellow: "#ffff00",
|
|
749
|
+
yellowgreen: "#9acd32"
|
|
750
|
+
};
|
|
751
|
+
function name2hex(n) {
|
|
752
|
+
n = n.toLowerCase();
|
|
753
|
+
if (!nameArray[n]) return "Invalid Color Name";
|
|
754
|
+
return nameArray[n];
|
|
755
|
+
}
|
|
756
|
+
function hex2rgb(h) {
|
|
757
|
+
h = h.replace(/^\#/, "");
|
|
758
|
+
if (h.length === 6) {
|
|
759
|
+
return [ parseInt(h.substr(0, 2), 16), parseInt(h.substr(2, 2), 16), parseInt(h.substr(4, 2), 16) ];
|
|
760
|
+
} else {
|
|
761
|
+
return [ 0, 0, 0 ];
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
var _name2rgb = {};
|
|
765
|
+
function name2rgb(n) {
|
|
766
|
+
if (!_name2rgb[n]) _name2rgb[n] = hex2rgb(name2hex(n));
|
|
767
|
+
return _name2rgb[n];
|
|
768
|
+
}
|
|
769
|
+
function color(o, r, g, b, a) {
|
|
770
|
+
if (typeof r !== "string") return o.setColor(r, g, b, a);
|
|
771
|
+
if (r === "") return o;
|
|
772
|
+
var c = name2rgb(r).map(function(x) {
|
|
773
|
+
return x / 255;
|
|
774
|
+
});
|
|
775
|
+
c[3] = g || 1;
|
|
776
|
+
return o.setColor(c);
|
|
777
|
+
}
|
|
778
|
+
function validateCSG(csg, options) {
|
|
779
|
+
var errors = [];
|
|
780
|
+
var warnings = [];
|
|
781
|
+
if (!csg || !csg.polygons || csg.polygons.length === 0) {
|
|
782
|
+
errors.push("Empty mesh: no polygons");
|
|
783
|
+
return {
|
|
784
|
+
ok: false,
|
|
785
|
+
errors,
|
|
786
|
+
warnings
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
var opts = _objectSpread2({
|
|
790
|
+
fixTJunctions: true
|
|
791
|
+
}, options);
|
|
792
|
+
if (opts.fixTJunctions && typeof csg.canonicalized === "function") {
|
|
793
|
+
csg = csg.canonicalized();
|
|
794
|
+
if (typeof csg.reTesselated === "function") {
|
|
795
|
+
csg = csg.reTesselated();
|
|
796
|
+
}
|
|
797
|
+
if (typeof csg.fixTJunctions === "function") {
|
|
798
|
+
csg = csg.fixTJunctions();
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
var AREA_EPS = 1e-10;
|
|
802
|
+
var KEY_EPS = 1e-5;
|
|
803
|
+
var degenerateCount = 0;
|
|
804
|
+
var invalidVertexCount = 0;
|
|
805
|
+
var _iterator = _createForOfIteratorHelper(csg.polygons), _step;
|
|
806
|
+
try {
|
|
807
|
+
for (_iterator.s(); !(_step = _iterator.n()).done; ) {
|
|
808
|
+
var npoly = _step.value;
|
|
809
|
+
var _iterator4 = _createForOfIteratorHelper(npoly.vertices), _step4;
|
|
810
|
+
try {
|
|
811
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done; ) {
|
|
812
|
+
var nvert = _step4.value;
|
|
813
|
+
var np = nvert.pos;
|
|
814
|
+
if (!Number.isFinite(np.x) || !Number.isFinite(np.y) || !Number.isFinite(np.z) || Number.isNaN(np.x) || Number.isNaN(np.y) || Number.isNaN(np.z)) {
|
|
815
|
+
invalidVertexCount++;
|
|
816
|
+
break;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
} catch (err) {
|
|
820
|
+
_iterator4.e(err);
|
|
821
|
+
} finally {
|
|
822
|
+
_iterator4.f();
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
} catch (err) {
|
|
826
|
+
_iterator.e(err);
|
|
827
|
+
} finally {
|
|
828
|
+
_iterator.f();
|
|
829
|
+
}
|
|
830
|
+
if (invalidVertexCount > 0) {
|
|
831
|
+
errors.push(invalidVertexCount + " polygon(s) with invalid vertex coordinates (NaN or Infinity)");
|
|
832
|
+
}
|
|
833
|
+
function vtxKey(v) {
|
|
834
|
+
var p = v.pos;
|
|
835
|
+
return Math.round(p.x / KEY_EPS) + "," + Math.round(p.y / KEY_EPS) + "," + Math.round(p.z / KEY_EPS);
|
|
836
|
+
}
|
|
837
|
+
var validPolygons = [];
|
|
838
|
+
var _iterator2 = _createForOfIteratorHelper(csg.polygons), _step2;
|
|
839
|
+
try {
|
|
840
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) {
|
|
841
|
+
var poly = _step2.value;
|
|
842
|
+
var verts = poly.vertices;
|
|
843
|
+
var nv = verts.length;
|
|
844
|
+
if (nv < 3) {
|
|
845
|
+
degenerateCount++;
|
|
846
|
+
continue;
|
|
847
|
+
}
|
|
848
|
+
var hasInvalid = false;
|
|
849
|
+
var _iterator5 = _createForOfIteratorHelper(verts), _step5;
|
|
850
|
+
try {
|
|
851
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done; ) {
|
|
852
|
+
var vert = _step5.value;
|
|
853
|
+
var ip = vert.pos;
|
|
854
|
+
if (!Number.isFinite(ip.x) || !Number.isFinite(ip.y) || !Number.isFinite(ip.z)) {
|
|
855
|
+
hasInvalid = true;
|
|
856
|
+
break;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
} catch (err) {
|
|
860
|
+
_iterator5.e(err);
|
|
861
|
+
} finally {
|
|
862
|
+
_iterator5.f();
|
|
863
|
+
}
|
|
864
|
+
if (hasInvalid) continue;
|
|
865
|
+
var area = 0;
|
|
866
|
+
for (var ai = 0; ai < nv - 2; ai++) {
|
|
867
|
+
area += verts[ai + 1].pos.minus(verts[0].pos).cross(verts[ai + 2].pos.minus(verts[ai + 1].pos)).length();
|
|
868
|
+
}
|
|
869
|
+
area *= .5;
|
|
870
|
+
if (area < AREA_EPS) {
|
|
871
|
+
degenerateCount++;
|
|
872
|
+
continue;
|
|
873
|
+
}
|
|
874
|
+
validPolygons.push(poly);
|
|
875
|
+
}
|
|
876
|
+
} catch (err) {
|
|
877
|
+
_iterator2.e(err);
|
|
878
|
+
} finally {
|
|
879
|
+
_iterator2.f();
|
|
880
|
+
}
|
|
881
|
+
if (degenerateCount > 0) {
|
|
882
|
+
warnings.push(degenerateCount + " degenerate polygon(s) (fewer than 3 vertices or near-zero area)");
|
|
883
|
+
if (opts.fixTJunctions && typeof CSG !== "undefined") {
|
|
884
|
+
var cleaned = CSG.fromPolygons(validPolygons);
|
|
885
|
+
cleaned = cleaned.canonicalized();
|
|
886
|
+
if (typeof cleaned.reTesselated === "function") {
|
|
887
|
+
cleaned = cleaned.reTesselated();
|
|
888
|
+
}
|
|
889
|
+
if (typeof cleaned.fixTJunctions === "function") {
|
|
890
|
+
cleaned = cleaned.fixTJunctions();
|
|
891
|
+
}
|
|
892
|
+
validPolygons = [];
|
|
893
|
+
var _iterator3 = _createForOfIteratorHelper(cleaned.polygons), _step3;
|
|
894
|
+
try {
|
|
895
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done; ) {
|
|
896
|
+
var cpoly = _step3.value;
|
|
897
|
+
var cverts = cpoly.vertices;
|
|
898
|
+
var cnv = cverts.length;
|
|
899
|
+
if (cnv < 3) continue;
|
|
900
|
+
var carea = 0;
|
|
901
|
+
for (var cai = 0; cai < cnv - 2; cai++) {
|
|
902
|
+
carea += cverts[cai + 1].pos.minus(cverts[0].pos).cross(cverts[cai + 2].pos.minus(cverts[cai + 1].pos)).length();
|
|
903
|
+
}
|
|
904
|
+
carea *= .5;
|
|
905
|
+
if (carea < AREA_EPS) continue;
|
|
906
|
+
validPolygons.push(cpoly);
|
|
907
|
+
}
|
|
908
|
+
} catch (err) {
|
|
909
|
+
_iterator3.e(err);
|
|
910
|
+
} finally {
|
|
911
|
+
_iterator3.f();
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
var edgeCounts = {};
|
|
916
|
+
for (var _i = 0, _validPolygons = validPolygons; _i < _validPolygons.length; _i++) {
|
|
917
|
+
var vpoly = _validPolygons[_i];
|
|
918
|
+
var vverts = vpoly.vertices;
|
|
919
|
+
var vnv = vverts.length;
|
|
920
|
+
for (var ei = 0; ei < vnv; ei++) {
|
|
921
|
+
var v0 = vverts[ei];
|
|
922
|
+
var v1 = vverts[(ei + 1) % vnv];
|
|
923
|
+
var edgeKey = vtxKey(v0) + "/" + vtxKey(v1);
|
|
924
|
+
edgeCounts[edgeKey] = (edgeCounts[edgeKey] || 0) + 1;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
var unmatchedEdges = 0;
|
|
928
|
+
var nonManifoldEdges = 0;
|
|
929
|
+
var checked = {};
|
|
930
|
+
for (var _i2 = 0, _Object$keys = Object.keys(edgeCounts); _i2 < _Object$keys.length; _i2++) {
|
|
931
|
+
var _edgeKey = _Object$keys[_i2];
|
|
932
|
+
if (checked[_edgeKey]) continue;
|
|
933
|
+
var parts = _edgeKey.split("/");
|
|
934
|
+
var reverseKey = parts[1] + "/" + parts[0];
|
|
935
|
+
var forwardCount = edgeCounts[_edgeKey] || 0;
|
|
936
|
+
var reverseCount = edgeCounts[reverseKey] || 0;
|
|
937
|
+
checked[_edgeKey] = true;
|
|
938
|
+
checked[reverseKey] = true;
|
|
939
|
+
if (forwardCount !== reverseCount) {
|
|
940
|
+
unmatchedEdges += Math.abs(forwardCount - reverseCount);
|
|
941
|
+
}
|
|
942
|
+
if (forwardCount > 1 || reverseCount > 1) {
|
|
943
|
+
nonManifoldEdges++;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
if (unmatchedEdges > 0) {
|
|
947
|
+
errors.push(unmatchedEdges + " unmatched edge(s): mesh is not watertight");
|
|
948
|
+
}
|
|
949
|
+
if (nonManifoldEdges > 0) {
|
|
950
|
+
errors.push(nonManifoldEdges + " non-manifold edge(s): edge shared by more than 2 polygons");
|
|
951
|
+
}
|
|
952
|
+
return {
|
|
953
|
+
ok: errors.length === 0,
|
|
954
|
+
errors,
|
|
955
|
+
warnings
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
function _noOp(csg) {
|
|
959
|
+
return csg;
|
|
960
|
+
}
|
|
961
|
+
function _makeAssertFn(warnEnabled) {
|
|
962
|
+
return function _assert(csg) {
|
|
963
|
+
var functionName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "unknown";
|
|
964
|
+
var moduleName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "unknown";
|
|
965
|
+
if (!csg || csg.polygons === undefined) return csg;
|
|
966
|
+
var result = validateCSG(csg);
|
|
967
|
+
if (!result.ok) {
|
|
968
|
+
throw new Error(moduleName + ":" + functionName + ": " + "invalid CSG: " + result.errors.join(", "));
|
|
969
|
+
}
|
|
970
|
+
if (warnEnabled && result.warnings.length > 0) {
|
|
971
|
+
throw new Error(moduleName + ":" + functionName + ": " + "CSG warnings: " + result.warnings.join(", "));
|
|
972
|
+
}
|
|
973
|
+
return csg;
|
|
974
|
+
};
|
|
975
|
+
}
|
|
976
|
+
var _assertFn = _noOp;
|
|
977
|
+
function _resolveFromGlobals() {
|
|
978
|
+
var enabled = typeof jscadUtilsAssertValidCSG !== "undefined" && !!jscadUtilsAssertValidCSG;
|
|
979
|
+
var warnEnabled = typeof jscadUtilsAssertValidCSGWarnings !== "undefined" && !!jscadUtilsAssertValidCSGWarnings;
|
|
980
|
+
return enabled ? _makeAssertFn(warnEnabled) : _noOp;
|
|
981
|
+
}
|
|
982
|
+
function AssertValidCSG() {
|
|
983
|
+
var moduleName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "unknown";
|
|
984
|
+
{
|
|
985
|
+
_assertFn = _resolveFromGlobals();
|
|
986
|
+
}
|
|
987
|
+
return function(csg, name) {
|
|
988
|
+
return _assertFn(csg, name, moduleName);
|
|
989
|
+
};
|
|
990
|
+
}
|
|
991
|
+
function init(proto) {
|
|
992
|
+
if (proto.prototype._jscadutilsinit) return;
|
|
993
|
+
proto.prototype.color = function(r, g, b, a) {
|
|
994
|
+
if (!r) return this;
|
|
995
|
+
return color(this, r, g, b, a);
|
|
996
|
+
};
|
|
997
|
+
proto.prototype.flush = function flush$1(to, axis, mside, wside) {
|
|
998
|
+
return flush(this, to, axis, mside, wside);
|
|
999
|
+
};
|
|
1000
|
+
proto.prototype.snap = function snap$1(to, axis, orientation, delta) {
|
|
1001
|
+
return snap(this, to, axis, orientation, delta);
|
|
1002
|
+
};
|
|
1003
|
+
proto.prototype.calcSnap = function calcSnap$1(to, axis, orientation, delta) {
|
|
1004
|
+
return calcSnap(this, to, axis, orientation, delta);
|
|
1005
|
+
};
|
|
1006
|
+
proto.prototype.midlineTo = function midlineTo$1(axis, to) {
|
|
1007
|
+
return midlineTo(this, axis, to);
|
|
1008
|
+
};
|
|
1009
|
+
proto.prototype.calcmidlineTo = function midlineTo(axis, to) {
|
|
1010
|
+
return calcmidlineTo(this, axis, to);
|
|
1011
|
+
};
|
|
1012
|
+
proto.prototype.centerWith = function centerWith$1(axis, to) {
|
|
1013
|
+
depreciated("centerWith", true, "Use align instead.");
|
|
1014
|
+
return centerWith(this, axis, to);
|
|
1015
|
+
};
|
|
1016
|
+
if (proto.center) echo("proto already has .center");
|
|
1017
|
+
proto.prototype.center = function center(axis) {
|
|
1018
|
+
return centerWith(this, axis || "xyz", unitCube());
|
|
1019
|
+
};
|
|
1020
|
+
proto.prototype.calcCenter = function centerWith(axis) {
|
|
1021
|
+
return calcCenterWith(this, axis || "xyz", unitCube(), 0);
|
|
1022
|
+
};
|
|
1023
|
+
proto.prototype.align = function align(to, axis) {
|
|
1024
|
+
return centerWith(this, axis, to);
|
|
1025
|
+
};
|
|
1026
|
+
proto.prototype.calcAlign = function calcAlign(to, axis, delta) {
|
|
1027
|
+
return calcCenterWith(this, axis, to, delta);
|
|
1028
|
+
};
|
|
1029
|
+
proto.prototype.enlarge = function enlarge$1(x, y, z) {
|
|
1030
|
+
return enlarge(this, x, y, z);
|
|
1031
|
+
};
|
|
1032
|
+
proto.prototype.fit = function fit$1(x, y, z, a) {
|
|
1033
|
+
return fit(this, x, y, z, a);
|
|
1034
|
+
};
|
|
1035
|
+
if (proto.size) echo("proto already has .size");
|
|
1036
|
+
proto.prototype.size = function() {
|
|
1037
|
+
return size(this.getBounds());
|
|
1038
|
+
};
|
|
1039
|
+
proto.prototype.centroid = function() {
|
|
1040
|
+
return centroid(this);
|
|
1041
|
+
};
|
|
1042
|
+
proto.prototype.Zero = function zero$1() {
|
|
1043
|
+
return zero(this);
|
|
1044
|
+
};
|
|
1045
|
+
proto.prototype.Center = function Center(axes) {
|
|
1046
|
+
return this.align(unitCube(), axes || "xy");
|
|
1047
|
+
};
|
|
1048
|
+
proto.Vector2D.prototype.map = function Vector2D_map(cb) {
|
|
1049
|
+
return new proto.Vector2D(cb(this.x), cb(this.y));
|
|
1050
|
+
};
|
|
1051
|
+
proto.prototype.fillet = function fillet$1(radius, orientation, options) {
|
|
1052
|
+
return fillet(this, radius, orientation, options);
|
|
1053
|
+
};
|
|
1054
|
+
proto.prototype.chamfer = function chamfer$1(radius, orientation, options) {
|
|
1055
|
+
return chamfer(this, radius, orientation, options);
|
|
1056
|
+
};
|
|
1057
|
+
proto.prototype.bisect = function bisect$1() {
|
|
1058
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1059
|
+
args[_key] = arguments[_key];
|
|
1060
|
+
}
|
|
1061
|
+
return bisect.apply(util, [ this ].concat(args));
|
|
1062
|
+
};
|
|
1063
|
+
proto.prototype.slice = function slice$1() {
|
|
1064
|
+
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
1065
|
+
args[_key2] = arguments[_key2];
|
|
1066
|
+
}
|
|
1067
|
+
return slice.apply(util, [ this ].concat(args));
|
|
1068
|
+
};
|
|
1069
|
+
proto.prototype.wedge = function wedge$1() {
|
|
1070
|
+
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
1071
|
+
args[_key3] = arguments[_key3];
|
|
1072
|
+
}
|
|
1073
|
+
return wedge.apply(util, [ this ].concat(args));
|
|
1074
|
+
};
|
|
1075
|
+
proto.prototype.stretch = function stretch$1(axis, distance, offset) {
|
|
1076
|
+
return stretch(this, axis, distance, offset);
|
|
1077
|
+
};
|
|
1078
|
+
proto.prototype.unionIf = function unionIf(object, condition) {
|
|
1079
|
+
return condition ? this.union(result(this, object)) : this;
|
|
1080
|
+
};
|
|
1081
|
+
proto.prototype.subtractIf = function subtractIf(object, condition) {
|
|
1082
|
+
return condition ? this.subtract(result(this, object)) : this;
|
|
1083
|
+
};
|
|
1084
|
+
proto.prototype.validate = function validate(options) {
|
|
1085
|
+
return validateCSG(this, options);
|
|
1086
|
+
};
|
|
1087
|
+
proto.prototype._translate = proto.prototype.translate;
|
|
1088
|
+
proto.prototype.translate = function translate() {
|
|
1089
|
+
if (arguments.length === 1) {
|
|
1090
|
+
return this._translate(arguments[0]);
|
|
1091
|
+
} else {
|
|
1092
|
+
var t = Array.prototype.slice.call(arguments, 0).reduce(function(result, arg) {
|
|
1093
|
+
result = undefined(result, arg);
|
|
1094
|
+
return result;
|
|
1095
|
+
}, [ 0, 0, 0 ]);
|
|
1096
|
+
return this._translate(t);
|
|
1097
|
+
}
|
|
1098
|
+
};
|
|
1099
|
+
proto.prototype.addConnector = function addConnector$1(name, point, axis, normal) {
|
|
1100
|
+
return addConnector(this, name, point, axis, normal);
|
|
1101
|
+
};
|
|
1102
|
+
proto.prototype.connect = function connectTo(myConnectorName, otherConnector) {
|
|
1103
|
+
var mirror = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
1104
|
+
var normalrotation = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
|
|
1105
|
+
var myConnector = myConnectorName.split(".").reduce(function(a, v) {
|
|
1106
|
+
return a[v];
|
|
1107
|
+
}, this.properties);
|
|
1108
|
+
if (!myConnector) {
|
|
1109
|
+
error("The connector '".concat(myConnectorName, "' does not exist on the object [").concat(Object.keys(this.properties).join(","), "]"), "Missing connector property");
|
|
1110
|
+
}
|
|
1111
|
+
return this.connectTo(myConnector, otherConnector, mirror, normalrotation);
|
|
1112
|
+
};
|
|
1113
|
+
proto.prototype._jscadutilsinit = true;
|
|
1114
|
+
}
|
|
1115
|
+
var init$1 = Object.freeze({
|
|
1116
|
+
__proto__: null,
|
|
1117
|
+
default: init
|
|
1118
|
+
});
|
|
1119
|
+
var CSG$1 = jsCadCSG__default["default"].CSG, CAG = jsCadCSG__default["default"].CAG;
|
|
1120
|
+
var rectangular_extrude = scadApi__default["default"].extrusions.rectangular_extrude;
|
|
1121
|
+
var _scadApi$text = scadApi__default["default"].text, vector_text = _scadApi$text.vector_text, vector_char = _scadApi$text.vector_char;
|
|
1122
|
+
var union = scadApi__default["default"].booleanOps.union;
|
|
1123
|
+
init(CSG$1);
|
|
1124
|
+
var debug$3 = Debug("jscadUtils:group");
|
|
1125
|
+
var assertValidCSG$2 = AssertValidCSG("group");
|
|
1126
|
+
function JsCadUtilsGroup() {
|
|
1127
|
+
var names = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
1128
|
+
var parts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1129
|
+
var holes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
1130
|
+
this.name = "";
|
|
1131
|
+
this.names = names;
|
|
1132
|
+
this.parts = parts;
|
|
1133
|
+
this.holes = holes;
|
|
1134
|
+
}
|
|
1135
|
+
JsCadUtilsGroup.prototype.add = function(object, name, hidden, subparts, parts) {
|
|
1136
|
+
debug$3("add", object, name, hidden, subparts, parts);
|
|
1137
|
+
var self = this;
|
|
1138
|
+
if (object.parts) {
|
|
1139
|
+
if (name) {
|
|
1140
|
+
if (!hidden) self.names.push(name);
|
|
1141
|
+
self.parts[name] = object.combine(parts);
|
|
1142
|
+
if (subparts) {
|
|
1143
|
+
Object.keys(object.parts).forEach(function(key) {
|
|
1144
|
+
self.parts[subparts + key] = object.parts[key];
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
} else {
|
|
1148
|
+
Object.assign(self.parts, object.parts);
|
|
1149
|
+
if (!hidden) self.names = self.names.concat(object.names);
|
|
1150
|
+
}
|
|
1151
|
+
} else {
|
|
1152
|
+
if (!hidden) self.names.push(name);
|
|
1153
|
+
self.parts[name] = object;
|
|
1154
|
+
}
|
|
1155
|
+
return self;
|
|
1156
|
+
};
|
|
1157
|
+
JsCadUtilsGroup.prototype.combine = function(pieces) {
|
|
1158
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1159
|
+
var map = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function(x) {
|
|
1160
|
+
return x;
|
|
1161
|
+
};
|
|
1162
|
+
try {
|
|
1163
|
+
var self = this;
|
|
1164
|
+
options = Object.assign({
|
|
1165
|
+
noholes: false
|
|
1166
|
+
}, options);
|
|
1167
|
+
pieces = pieces ? pieces.split(",") : self.names;
|
|
1168
|
+
if (pieces.length === 0) {
|
|
1169
|
+
throw new Error("no pieces found in ".concat(self.name, " pieces: ").concat(pieces, " parts: ").concat(Object.keys(self.parts), " names: ").concat(self.names));
|
|
1170
|
+
}
|
|
1171
|
+
debug$3("combine", self.names, self.parts);
|
|
1172
|
+
var g = union(mapPick(self.parts, pieces, function(value, key, index, object) {
|
|
1173
|
+
debug$3("combine mapPick", value, key, object);
|
|
1174
|
+
return map ? map(value, key, index, object) : identity(value);
|
|
1175
|
+
}, self.name));
|
|
1176
|
+
return assertValidCSG$2(g.subtractIf(self.holes && Array.isArray(self.holes) ? union(self.holes) : self.holes, self.holes && !options.noholes), "combine");
|
|
1177
|
+
} catch (err) {
|
|
1178
|
+
debug$3("combine error", this, pieces, options, err);
|
|
1179
|
+
throw error('group::combine error "'.concat(err.message || err.toString(), '"\nthis: ').concat(this, '\npieces: "').concat(pieces, '"\noptions: ').concat(JSON.stringify(options, null, 2), "\nstack: ").concat(err.stack, "\n"), "JSCAD_UTILS_GROUP_ERROR");
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
JsCadUtilsGroup.prototype.map = function(cb) {
|
|
1183
|
+
var self = this;
|
|
1184
|
+
self.parts = Object.keys(self.parts).filter(function(k) {
|
|
1185
|
+
return k !== "holes";
|
|
1186
|
+
}).reduce(function(result, key) {
|
|
1187
|
+
result[key] = cb(self.parts[key], key);
|
|
1188
|
+
return result;
|
|
1189
|
+
}, {});
|
|
1190
|
+
if (self.holes) {
|
|
1191
|
+
if (Array.isArray(self.holes)) {
|
|
1192
|
+
self.holes = self.holes.map(function(hole, idx) {
|
|
1193
|
+
return cb(hole, idx);
|
|
1194
|
+
});
|
|
1195
|
+
} else {
|
|
1196
|
+
self.holes = cb(self.holes, "holes");
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
return self;
|
|
1200
|
+
};
|
|
1201
|
+
JsCadUtilsGroup.prototype.clone = function(name, map) {
|
|
1202
|
+
debug$3("clone", name, _typeof(name), map);
|
|
1203
|
+
var self = this;
|
|
1204
|
+
if (typeof name == "function") {
|
|
1205
|
+
map = name;
|
|
1206
|
+
name = undefined;
|
|
1207
|
+
}
|
|
1208
|
+
if (!map) map = identity;
|
|
1209
|
+
var group = Group(name);
|
|
1210
|
+
Object.keys(self.parts).forEach(function(key) {
|
|
1211
|
+
var part = self.parts[key];
|
|
1212
|
+
var hidden = self.names.indexOf(key) == -1;
|
|
1213
|
+
group.add(map(clone(part)), key, hidden);
|
|
1214
|
+
});
|
|
1215
|
+
if (self.holes) {
|
|
1216
|
+
group.holes = toArray(self.holes).map(function(part) {
|
|
1217
|
+
return assertValidCSG$2(map(CSG$1.fromPolygons(part.toPolygons()), "holes"), "clone");
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
return group;
|
|
1221
|
+
};
|
|
1222
|
+
JsCadUtilsGroup.prototype.rotate = function(solid, axis, angle) {
|
|
1223
|
+
var self = this;
|
|
1224
|
+
var axes = {
|
|
1225
|
+
x: [ 1, 0, 0 ],
|
|
1226
|
+
y: [ 0, 1, 0 ],
|
|
1227
|
+
z: [ 0, 0, 1 ]
|
|
1228
|
+
};
|
|
1229
|
+
if (typeof solid === "string") {
|
|
1230
|
+
var _names = solid;
|
|
1231
|
+
solid = self.combine(_names);
|
|
1232
|
+
}
|
|
1233
|
+
var rotationCenter = solid.centroid();
|
|
1234
|
+
var rotationAxis = axes[axis];
|
|
1235
|
+
self.map(function(part) {
|
|
1236
|
+
return assertValidCSG$2(part.rotate(rotationCenter, rotationAxis, angle), "rotate");
|
|
1237
|
+
});
|
|
1238
|
+
return self;
|
|
1239
|
+
};
|
|
1240
|
+
JsCadUtilsGroup.prototype.combineAll = function(options, map) {
|
|
1241
|
+
var self = this;
|
|
1242
|
+
return self.combine(Object.keys(self.parts).join(","), options, map);
|
|
1243
|
+
};
|
|
1244
|
+
JsCadUtilsGroup.prototype.snap = function snap(part, to, axis, orientation, delta) {
|
|
1245
|
+
try {
|
|
1246
|
+
var self = this;
|
|
1247
|
+
var t = calcSnap(self.combine(part), to, axis, orientation, delta);
|
|
1248
|
+
self.map(function(part) {
|
|
1249
|
+
return assertValidCSG$2(part.translate(t), "snap");
|
|
1250
|
+
});
|
|
1251
|
+
return self;
|
|
1252
|
+
} catch (err) {
|
|
1253
|
+
debug$3("snap error", this, part, to, axis, delta, err);
|
|
1254
|
+
throw error('group::snap error "'.concat(err.message || err.toString(), '"\nthis: ').concat(this, '\npart: "').concat(part, '"\nto: ').concat(to, '\naxis: "').concat(axis, '"\norientation: "').concat(orientation, '"\ndelta: "').concat(delta, '"\nstack: ').concat(err.stack, "\n"), "JSCAD_UTILS_GROUP_ERROR");
|
|
1255
|
+
}
|
|
1256
|
+
};
|
|
1257
|
+
JsCadUtilsGroup.prototype.align = function align(part, to, axis, delta) {
|
|
1258
|
+
try {
|
|
1259
|
+
var self = this;
|
|
1260
|
+
var t = calcCenterWith(self.combine(part, {
|
|
1261
|
+
noholes: true
|
|
1262
|
+
}), axis, to, delta);
|
|
1263
|
+
self.map(function(part) {
|
|
1264
|
+
return assertValidCSG$2(part.translate(t), "align");
|
|
1265
|
+
});
|
|
1266
|
+
return self;
|
|
1267
|
+
} catch (err) {
|
|
1268
|
+
debug$3("align error", this, part, to, axis, delta, err);
|
|
1269
|
+
throw error('group::align error "'.concat(err.message || err.toString(), '"\nthis: ').concat(this, '\npart: "').concat(part, '"\nto: ').concat(to, '\naxis: "').concat(axis, '"\ndelta: "').concat(delta, '"\nstack: ').concat(err.stack, "\n"), "JSCAD_UTILS_GROUP_ERROR");
|
|
1270
|
+
}
|
|
1271
|
+
};
|
|
1272
|
+
JsCadUtilsGroup.prototype.center = function center(part) {
|
|
1273
|
+
var self = this;
|
|
1274
|
+
return self.align(part, unitCube(), "xyz");
|
|
1275
|
+
};
|
|
1276
|
+
JsCadUtilsGroup.prototype.zero = function zero(part) {
|
|
1277
|
+
var self = this;
|
|
1278
|
+
var bounds = self.parts[part].getBounds();
|
|
1279
|
+
return self.translate([ 0, 0, -bounds[0].z ]);
|
|
1280
|
+
};
|
|
1281
|
+
JsCadUtilsGroup.prototype.connectTo = function connectTo(partName, connectorName, to, toConnectorName) {
|
|
1282
|
+
var mirror = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
|
|
1283
|
+
var normalrotation = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
|
|
1284
|
+
debug$3("connectTo", {
|
|
1285
|
+
partName,
|
|
1286
|
+
connectorName,
|
|
1287
|
+
to,
|
|
1288
|
+
toConnectorName,
|
|
1289
|
+
mirror,
|
|
1290
|
+
normalrotation
|
|
1291
|
+
});
|
|
1292
|
+
var self = this;
|
|
1293
|
+
var myConnector = connectorName.split(".").reduce(function(a, v) {
|
|
1294
|
+
return a[v];
|
|
1295
|
+
}, self.parts[partName].properties);
|
|
1296
|
+
debug$3("toConnector", to instanceof CSG$1.Connector);
|
|
1297
|
+
var toConnector = toConnectorName.split(".").reduce(function(a, v) {
|
|
1298
|
+
return a[v];
|
|
1299
|
+
}, to.properties);
|
|
1300
|
+
var matrix = myConnector.getTransformationTo(toConnector, mirror, normalrotation);
|
|
1301
|
+
debug$3("connectTo", matrix);
|
|
1302
|
+
self.map(function(part) {
|
|
1303
|
+
return assertValidCSG$2(part.transform(matrix), "connectTo");
|
|
1304
|
+
});
|
|
1305
|
+
return self;
|
|
1306
|
+
};
|
|
1307
|
+
JsCadUtilsGroup.prototype.midlineTo = function midlineTo(part, axis, to) {
|
|
1308
|
+
var self = this;
|
|
1309
|
+
var size = self.combine(part).size();
|
|
1310
|
+
var t = axisApply(axis, function(i, a) {
|
|
1311
|
+
return to - size[a] / 2;
|
|
1312
|
+
});
|
|
1313
|
+
self.map(function(part) {
|
|
1314
|
+
return assertValidCSG$2(part.translate(t), "midlineTo");
|
|
1315
|
+
});
|
|
1316
|
+
return self;
|
|
1317
|
+
};
|
|
1318
|
+
JsCadUtilsGroup.prototype.translate = function translate(x, y, z) {
|
|
1319
|
+
var self = this;
|
|
1320
|
+
var t = Array.isArray(x) ? x : [ x, y, z ];
|
|
1321
|
+
debug$3("translate", t);
|
|
1322
|
+
self.map(function(part) {
|
|
1323
|
+
return assertValidCSG$2(part.translate(t), "translate");
|
|
1324
|
+
});
|
|
1325
|
+
return self;
|
|
1326
|
+
};
|
|
1327
|
+
JsCadUtilsGroup.prototype.pick = function(parts, map) {
|
|
1328
|
+
var self = this;
|
|
1329
|
+
var p = parts && parts.length > 0 && parts.split(",") || self.names;
|
|
1330
|
+
if (!map) map = identity;
|
|
1331
|
+
var g = Group();
|
|
1332
|
+
p.forEach(function(name) {
|
|
1333
|
+
g.add(assertValidCSG$2(map(CSG$1.fromPolygons(self.parts[name].toPolygons()), name), "pick"), name);
|
|
1334
|
+
});
|
|
1335
|
+
return g;
|
|
1336
|
+
};
|
|
1337
|
+
JsCadUtilsGroup.prototype.array = function(parts, map) {
|
|
1338
|
+
var _this = this;
|
|
1339
|
+
var self = this;
|
|
1340
|
+
var p = parts && parts.length > 0 && parts.split(",") || self.names;
|
|
1341
|
+
if (!map) map = identity;
|
|
1342
|
+
var a = [];
|
|
1343
|
+
p.forEach(function(name) {
|
|
1344
|
+
if (!self.parts[name]) {
|
|
1345
|
+
debug$3("array error", _this, parts);
|
|
1346
|
+
throw error('group::array error "'.concat(name, '" not found.\nthis: ').concat(_this, '\nparts: "').concat(parts, '"\n'), "JSCAD_UTILS_GROUP_ERROR");
|
|
1347
|
+
}
|
|
1348
|
+
a.push(assertValidCSG$2(map(CSG$1.fromPolygons(self.parts[name].toPolygons()), name), "array"));
|
|
1349
|
+
});
|
|
1350
|
+
return a;
|
|
1351
|
+
};
|
|
1352
|
+
JsCadUtilsGroup.prototype.toArray = function(pieces) {
|
|
1353
|
+
var self = this;
|
|
1354
|
+
var piecesArray = pieces ? pieces.split(",") : self.names;
|
|
1355
|
+
return piecesArray.map(function(piece) {
|
|
1356
|
+
if (!self.parts[piece]) console.error("Cannot find ".concat(piece, " in ").concat(self.names));
|
|
1357
|
+
return self.parts[piece];
|
|
1358
|
+
});
|
|
1359
|
+
};
|
|
1360
|
+
JsCadUtilsGroup.prototype.toString = function() {
|
|
1361
|
+
return '{\n name: "'.concat(this.name, '",\n names: "').concat(this.names.join(","), '", \n parts: "').concat(Object.keys(this.parts), '",\n holes: ').concat(Array.isArray(this.holes) ? this.holes.length : this.holes ? 1 : 0, "\n}");
|
|
1362
|
+
};
|
|
1363
|
+
JsCadUtilsGroup.prototype.setName = function(name) {
|
|
1364
|
+
this.name = name;
|
|
1365
|
+
return this;
|
|
1366
|
+
};
|
|
1367
|
+
function Group(objectNames, addObjects) {
|
|
1368
|
+
debug$3("Group", objectNames, addObjects);
|
|
1369
|
+
var self = {
|
|
1370
|
+
name: "",
|
|
1371
|
+
names: [],
|
|
1372
|
+
parts: {}
|
|
1373
|
+
};
|
|
1374
|
+
if (objectNames) {
|
|
1375
|
+
if (addObjects) {
|
|
1376
|
+
var names = objectNames;
|
|
1377
|
+
var objects = addObjects;
|
|
1378
|
+
self.names = names && names.length > 0 && names.split(",") || [];
|
|
1379
|
+
if (Array.isArray(objects)) {
|
|
1380
|
+
self.parts = zipObject(self.names, objects);
|
|
1381
|
+
} else if (objects instanceof CSG$1) {
|
|
1382
|
+
self.parts = zipObject(self.names, [ objects ]);
|
|
1383
|
+
} else {
|
|
1384
|
+
self.parts = objects || {};
|
|
1385
|
+
}
|
|
1386
|
+
} else {
|
|
1387
|
+
if (typeof objectNames == "string") {
|
|
1388
|
+
self.name = objectNames;
|
|
1389
|
+
} else {
|
|
1390
|
+
var objects = objectNames;
|
|
1391
|
+
self.names = Object.keys(objects).filter(function(k) {
|
|
1392
|
+
return k !== "holes";
|
|
1393
|
+
});
|
|
1394
|
+
self.parts = Object.assign({}, objects);
|
|
1395
|
+
self.holes = objects.holes;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
return new JsCadUtilsGroup(self.names, self.parts, self.holes);
|
|
1400
|
+
}
|
|
1401
|
+
var debug$2 = Debug("jscadUtils:util");
|
|
1402
|
+
var assertValidCSG$1 = AssertValidCSG("util");
|
|
1403
|
+
var NOZZEL_SIZE = .4;
|
|
1404
|
+
var nearest = {
|
|
1405
|
+
under: function under(desired) {
|
|
1406
|
+
var nozzel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : NOZZEL_SIZE;
|
|
1407
|
+
var nozzie = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
1408
|
+
return (Math.floor(desired / nozzel) + nozzie) * nozzel;
|
|
1409
|
+
},
|
|
1410
|
+
over: function over(desired) {
|
|
1411
|
+
var nozzel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : NOZZEL_SIZE;
|
|
1412
|
+
var nozzie = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
1413
|
+
return (Math.ceil(desired / nozzel) + nozzie) * nozzel;
|
|
1414
|
+
}
|
|
1415
|
+
};
|
|
1416
|
+
function identity(solid) {
|
|
1417
|
+
return solid;
|
|
1418
|
+
}
|
|
1419
|
+
function result(object, f) {
|
|
1420
|
+
if (typeof f === "function") {
|
|
1421
|
+
return f.call(object);
|
|
1422
|
+
} else {
|
|
1423
|
+
return f;
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
function defaults(target, defaults) {
|
|
1427
|
+
depreciated("defaults", true, "use Object.assign instead");
|
|
1428
|
+
return Object.assign(defaults, target);
|
|
1429
|
+
}
|
|
1430
|
+
function isEmpty(variable) {
|
|
1431
|
+
return typeof variable === "undefined" || variable === null;
|
|
1432
|
+
}
|
|
1433
|
+
function isNegative(n) {
|
|
1434
|
+
return ((n = +n) || 1 / n) < 0;
|
|
1435
|
+
}
|
|
1436
|
+
function print(msg, o) {
|
|
1437
|
+
debug$2(msg, JSON.stringify(o.getBounds()), JSON.stringify(this.size(o.getBounds())));
|
|
1438
|
+
}
|
|
1439
|
+
function jscadToString(o) {
|
|
1440
|
+
if (_typeof(o) == "object") {
|
|
1441
|
+
if (o.polygons) {
|
|
1442
|
+
return "{\npolygons: ".concat(o.polygons.length, ',\nproperties: "').concat(Object.keys(o.properties), '"\n}\n');
|
|
1443
|
+
}
|
|
1444
|
+
} else {
|
|
1445
|
+
return o.toString();
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
function error(msg, name, error) {
|
|
1449
|
+
if (console && console.error) console.error(msg, error);
|
|
1450
|
+
var err = new Error(msg);
|
|
1451
|
+
err.name = name || "JSCAD_UTILS_ERROR";
|
|
1452
|
+
err._error = error;
|
|
1453
|
+
throw err;
|
|
1454
|
+
}
|
|
1455
|
+
function depreciated(method, error, message) {
|
|
1456
|
+
var msg = method + " is depreciated." + (" " + message || "");
|
|
1457
|
+
if (!error && console && console.error) console[error ? "error" : "warn"](msg);
|
|
1458
|
+
if (error) {
|
|
1459
|
+
var err = new Error(msg);
|
|
1460
|
+
err.name = "JSCAD_UTILS_DEPRECATED";
|
|
1461
|
+
throw err;
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
function inch(x) {
|
|
1465
|
+
return x * 25.4;
|
|
1466
|
+
}
|
|
1467
|
+
function cm(x) {
|
|
1468
|
+
return x / 25.4;
|
|
1469
|
+
}
|
|
1470
|
+
function label(text, x, y, width, height) {
|
|
1471
|
+
var l = vector_text(x || 0, y || 0, text);
|
|
1472
|
+
var o = [];
|
|
1473
|
+
l.forEach(function(pl) {
|
|
1474
|
+
o.push(rectangular_extrude(pl, {
|
|
1475
|
+
w: width || 2,
|
|
1476
|
+
h: height || 2
|
|
1477
|
+
}));
|
|
1478
|
+
});
|
|
1479
|
+
return assertValidCSG$1(center(union(o)), "label");
|
|
1480
|
+
}
|
|
1481
|
+
function text(text) {
|
|
1482
|
+
var l = vector_char(0, 0, text);
|
|
1483
|
+
var _char = l.segments.reduce(function(result, segment) {
|
|
1484
|
+
var path = new CSG$1.Path2D(segment);
|
|
1485
|
+
var cag = path.expandToCAG(2);
|
|
1486
|
+
return result ? result.union(cag) : cag;
|
|
1487
|
+
}, undefined);
|
|
1488
|
+
return _char;
|
|
1489
|
+
}
|
|
1490
|
+
function unitCube(length, radius) {
|
|
1491
|
+
radius = radius || .5;
|
|
1492
|
+
return assertValidCSG$1(CSG$1.cube({
|
|
1493
|
+
center: [ 0, 0, 0 ],
|
|
1494
|
+
radius: [ radius, radius, length || .5 ]
|
|
1495
|
+
}), "unitCube");
|
|
1496
|
+
}
|
|
1497
|
+
function unitAxis(length, radius, centroid) {
|
|
1498
|
+
debug$2("unitAxis", length, radius, centroid);
|
|
1499
|
+
centroid = centroid || [ 0, 0, 0 ];
|
|
1500
|
+
var unitaxis = unitCube(length, radius).setColor(1, 0, 0).union([ unitCube(length, radius).rotateY(90).setColor(0, 1, 0), unitCube(length, radius).rotateX(90).setColor(0, 0, 1) ]);
|
|
1501
|
+
unitaxis.properties.origin = new CSG$1.Connector([ 0, 0, 0 ], [ 1, 0, 0 ], [ 0, 1, 0 ]);
|
|
1502
|
+
return assertValidCSG$1(unitaxis.translate(centroid), "unitAxis");
|
|
1503
|
+
}
|
|
1504
|
+
function toArray(a) {
|
|
1505
|
+
return Array.isArray(a) ? a : [ a ];
|
|
1506
|
+
}
|
|
1507
|
+
function ifArray(a, cb) {
|
|
1508
|
+
return Array.isArray(a) ? a.map(cb) : cb(a);
|
|
1509
|
+
}
|
|
1510
|
+
function segment(object, segments, axis) {
|
|
1511
|
+
var size = object.size()[axis];
|
|
1512
|
+
var width = size / segments;
|
|
1513
|
+
var result = [];
|
|
1514
|
+
for (var i = width; i < size; i += width) {
|
|
1515
|
+
result.push(i);
|
|
1516
|
+
}
|
|
1517
|
+
return result;
|
|
1518
|
+
}
|
|
1519
|
+
function zipObject(names, values) {
|
|
1520
|
+
return names.reduce(function(result, value, idx) {
|
|
1521
|
+
result[value] = values[idx];
|
|
1522
|
+
return result;
|
|
1523
|
+
}, {});
|
|
1524
|
+
}
|
|
1525
|
+
function map(o, f) {
|
|
1526
|
+
return Object.keys(o).map(function(key) {
|
|
1527
|
+
return f(o[key], key, o);
|
|
1528
|
+
});
|
|
1529
|
+
}
|
|
1530
|
+
function mapValues(o, f) {
|
|
1531
|
+
return Object.keys(o).map(function(key) {
|
|
1532
|
+
return f(o[key], key);
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
function pick(o, names) {
|
|
1536
|
+
return names.reduce(function(result, name) {
|
|
1537
|
+
result[name] = o[name];
|
|
1538
|
+
return result;
|
|
1539
|
+
}, {});
|
|
1540
|
+
}
|
|
1541
|
+
function mapPick(o, names, f, options) {
|
|
1542
|
+
return names.reduce(function(result, name, index) {
|
|
1543
|
+
if (!o[name]) {
|
|
1544
|
+
throw new Error("".concat(name, " not found in ").concat(options.name, ": ").concat(Object.keys(o).join(",")));
|
|
1545
|
+
}
|
|
1546
|
+
result.push(f ? f(o[name], name, index, o) : o[name]);
|
|
1547
|
+
return result;
|
|
1548
|
+
}, []);
|
|
1549
|
+
}
|
|
1550
|
+
function divA(a, f) {
|
|
1551
|
+
return div$1(a, f);
|
|
1552
|
+
}
|
|
1553
|
+
function divxyz(size, x, y, z) {
|
|
1554
|
+
return {
|
|
1555
|
+
x: size.x / x,
|
|
1556
|
+
y: size.y / y,
|
|
1557
|
+
z: size.z / z
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
function div(size, d) {
|
|
1561
|
+
return this.divxyz(size, d, d, d);
|
|
1562
|
+
}
|
|
1563
|
+
function mulxyz(size, x, y, z) {
|
|
1564
|
+
return {
|
|
1565
|
+
x: size.x * x,
|
|
1566
|
+
y: size.y * y,
|
|
1567
|
+
z: size.z * z
|
|
1568
|
+
};
|
|
1569
|
+
}
|
|
1570
|
+
function mul(size, d) {
|
|
1571
|
+
return this.divxyz(size, d, d, d);
|
|
1572
|
+
}
|
|
1573
|
+
function xyz2array(size) {
|
|
1574
|
+
return [ size.x, size.y, size.z ];
|
|
1575
|
+
}
|
|
1576
|
+
var rotationAxes = {
|
|
1577
|
+
x: [ 1, 0, 0 ],
|
|
1578
|
+
y: [ 0, 1, 0 ],
|
|
1579
|
+
z: [ 0, 0, 1 ]
|
|
1580
|
+
};
|
|
1581
|
+
function size(o) {
|
|
1582
|
+
var bbox = o.getBounds ? o.getBounds() : o;
|
|
1583
|
+
var foo = bbox[1].minus(bbox[0]);
|
|
1584
|
+
return foo;
|
|
1585
|
+
}
|
|
1586
|
+
function scale(size, value) {
|
|
1587
|
+
if (value == 0) return 1;
|
|
1588
|
+
return 1 + 100 / (size / value) / 100;
|
|
1589
|
+
}
|
|
1590
|
+
function center(object, objectSize) {
|
|
1591
|
+
objectSize = objectSize || size(object.getBounds());
|
|
1592
|
+
return assertValidCSG$1(centerY(centerX(object, objectSize), objectSize), "center");
|
|
1593
|
+
}
|
|
1594
|
+
function centerY(object, objectSize) {
|
|
1595
|
+
objectSize = objectSize || size(object.getBounds());
|
|
1596
|
+
return assertValidCSG$1(object.translate([ 0, -objectSize.y / 2, 0 ]), "centerY");
|
|
1597
|
+
}
|
|
1598
|
+
function centerX(object, objectSize) {
|
|
1599
|
+
objectSize = objectSize || size(object.getBounds());
|
|
1600
|
+
return assertValidCSG$1(object.translate([ -objectSize.x / 2, 0, 0 ]), "centerX");
|
|
1601
|
+
}
|
|
1602
|
+
function enlarge(object, x, y, z) {
|
|
1603
|
+
var a;
|
|
1604
|
+
if (Array.isArray(x)) {
|
|
1605
|
+
a = x;
|
|
1606
|
+
} else {
|
|
1607
|
+
a = [ x, y || x, z || x ];
|
|
1608
|
+
}
|
|
1609
|
+
var objectSize = size(object);
|
|
1610
|
+
var objectCentroid = centroid(object, objectSize);
|
|
1611
|
+
var idx = 0;
|
|
1612
|
+
var t = map(objectSize, function(i) {
|
|
1613
|
+
return scale(i, a[idx++]);
|
|
1614
|
+
});
|
|
1615
|
+
var new_object = object.scale(t);
|
|
1616
|
+
var new_centroid = centroid(new_object);
|
|
1617
|
+
var delta = new_centroid.minus(objectCentroid).times(-1);
|
|
1618
|
+
return assertValidCSG$1(new_object.translate(delta), "enlarge");
|
|
1619
|
+
}
|
|
1620
|
+
function fit(object, x, y, z, keep_aspect_ratio) {
|
|
1621
|
+
var a;
|
|
1622
|
+
if (Array.isArray(x)) {
|
|
1623
|
+
a = x;
|
|
1624
|
+
keep_aspect_ratio = y;
|
|
1625
|
+
x = a[0];
|
|
1626
|
+
y = a[1];
|
|
1627
|
+
z = a[2];
|
|
1628
|
+
} else {
|
|
1629
|
+
a = [ x, y, z ];
|
|
1630
|
+
}
|
|
1631
|
+
var objectSize = size(object.getBounds());
|
|
1632
|
+
function scale(size, value) {
|
|
1633
|
+
if (value == 0) return 1;
|
|
1634
|
+
return value / size;
|
|
1635
|
+
}
|
|
1636
|
+
var s = [ scale(objectSize.x, x), scale(objectSize.y, y), scale(objectSize.z, z) ];
|
|
1637
|
+
var min$1 = min(s);
|
|
1638
|
+
return assertValidCSG$1(centerWith(object.scale(s.map(function(d, i) {
|
|
1639
|
+
if (a[i] === 0) return 1;
|
|
1640
|
+
return keep_aspect_ratio ? min$1 : d;
|
|
1641
|
+
})), "xyz", object), "fit");
|
|
1642
|
+
}
|
|
1643
|
+
function shift(object, x, y, z) {
|
|
1644
|
+
var hsize = this.div(this.size(object.getBounds()), 2);
|
|
1645
|
+
return object.translate(this.xyz2array(this.mulxyz(hsize, x, y, z)));
|
|
1646
|
+
}
|
|
1647
|
+
function zero(object) {
|
|
1648
|
+
var bounds = object.getBounds();
|
|
1649
|
+
return assertValidCSG$1(object.translate([ 0, 0, -bounds[0].z ]), "zero");
|
|
1650
|
+
}
|
|
1651
|
+
function mirrored4(x) {
|
|
1652
|
+
return assertValidCSG$1(x.union([ x.mirroredY(90), x.mirroredX(90), x.mirroredY(90).mirroredX(90) ]), "mirrored4");
|
|
1653
|
+
}
|
|
1654
|
+
var flushSide = {
|
|
1655
|
+
"above-outside": [ 1, 0 ],
|
|
1656
|
+
"above-inside": [ 1, 1 ],
|
|
1657
|
+
"below-outside": [ 0, 1 ],
|
|
1658
|
+
"below-inside": [ 0, 0 ],
|
|
1659
|
+
"outside+": [ 0, 1 ],
|
|
1660
|
+
"outside-": [ 1, 0 ],
|
|
1661
|
+
"inside+": [ 1, 1 ],
|
|
1662
|
+
"inside-": [ 0, 0 ],
|
|
1663
|
+
"center+": [ -1, 1 ],
|
|
1664
|
+
"center-": [ -1, 0 ]
|
|
1665
|
+
};
|
|
1666
|
+
function calcFlush(moveobj, withobj, axes, mside, wside) {
|
|
1667
|
+
depreciated("calcFlush", false, "Use calcSnap instead.");
|
|
1668
|
+
var side;
|
|
1669
|
+
if (mside === 0 || mside === 1) {
|
|
1670
|
+
side = [ wside !== undefined ? wside : mside, mside ];
|
|
1671
|
+
} else {
|
|
1672
|
+
side = flushSide[mside];
|
|
1673
|
+
if (!side) error("invalid side: " + mside);
|
|
1674
|
+
}
|
|
1675
|
+
var m = moveobj.getBounds();
|
|
1676
|
+
var w = withobj.getBounds();
|
|
1677
|
+
if (side[0] === -1) {
|
|
1678
|
+
w[-1] = toxyz(withobj.centroid());
|
|
1679
|
+
}
|
|
1680
|
+
return this.axisApply(axes, function(i, axis) {
|
|
1681
|
+
return w[side[0]][axis] - m[side[1]][axis];
|
|
1682
|
+
});
|
|
1683
|
+
}
|
|
1684
|
+
function calcSnap(moveobj, withobj, axes, orientation) {
|
|
1685
|
+
var delta = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
|
|
1686
|
+
var side = flushSide[orientation];
|
|
1687
|
+
if (!side) {
|
|
1688
|
+
var fix = {
|
|
1689
|
+
"01": "outside+",
|
|
1690
|
+
10: "outside-",
|
|
1691
|
+
11: "inside+",
|
|
1692
|
+
"00": "inside-",
|
|
1693
|
+
"-11": "center+",
|
|
1694
|
+
"-10": "center-"
|
|
1695
|
+
};
|
|
1696
|
+
error("calcSnap: invalid side: " + orientation + " should be " + fix["" + orientation + delta]);
|
|
1697
|
+
}
|
|
1698
|
+
var m = moveobj.getBounds();
|
|
1699
|
+
var w = withobj.getBounds();
|
|
1700
|
+
if (side[0] === -1) {
|
|
1701
|
+
w[-1] = withobj.centroid();
|
|
1702
|
+
}
|
|
1703
|
+
var t = axisApply(axes, function(i, axis) {
|
|
1704
|
+
return w[side[0]][axis] - m[side[1]][axis];
|
|
1705
|
+
});
|
|
1706
|
+
return delta ? axisApply(axes, function(i) {
|
|
1707
|
+
return t[i] + delta;
|
|
1708
|
+
}) : t;
|
|
1709
|
+
}
|
|
1710
|
+
function snap(moveobj, withobj, axis, orientation, delta) {
|
|
1711
|
+
debug$2("snap", moveobj, withobj, axis, orientation, delta);
|
|
1712
|
+
var t = calcSnap(moveobj, withobj, axis, orientation, delta);
|
|
1713
|
+
return assertValidCSG$1(moveobj.translate(t), "snap");
|
|
1714
|
+
}
|
|
1715
|
+
function flush(moveobj, withobj, axis, mside, wside) {
|
|
1716
|
+
return assertValidCSG$1(moveobj.translate(calcFlush(moveobj, withobj, axis, mside, wside)), "flush");
|
|
1717
|
+
}
|
|
1718
|
+
function axisApply(axes, valfun, a) {
|
|
1719
|
+
debug$2("axisApply", axes, valfun, a);
|
|
1720
|
+
var retval = a || [ 0, 0, 0 ];
|
|
1721
|
+
var lookup = {
|
|
1722
|
+
x: 0,
|
|
1723
|
+
y: 1,
|
|
1724
|
+
z: 2
|
|
1725
|
+
};
|
|
1726
|
+
axes.split("").forEach(function(axis) {
|
|
1727
|
+
retval[lookup[axis]] = valfun(lookup[axis], axis);
|
|
1728
|
+
});
|
|
1729
|
+
return retval;
|
|
1730
|
+
}
|
|
1731
|
+
function axis2array(axes, valfun) {
|
|
1732
|
+
depreciated("axis2array", false, "Use axisApply instead.");
|
|
1733
|
+
var a = [ 0, 0, 0 ];
|
|
1734
|
+
var lookup = {
|
|
1735
|
+
x: 0,
|
|
1736
|
+
y: 1,
|
|
1737
|
+
z: 2
|
|
1738
|
+
};
|
|
1739
|
+
axes.split("").forEach(function(axis) {
|
|
1740
|
+
var i = lookup[axis];
|
|
1741
|
+
a[i] = valfun(i, axis);
|
|
1742
|
+
});
|
|
1743
|
+
return a;
|
|
1744
|
+
}
|
|
1745
|
+
function centroid(o, objectSize) {
|
|
1746
|
+
try {
|
|
1747
|
+
var bounds = o.getBounds();
|
|
1748
|
+
objectSize = objectSize || size(bounds);
|
|
1749
|
+
return bounds[0].plus(objectSize.dividedBy(2));
|
|
1750
|
+
} catch (err) {
|
|
1751
|
+
error("centroid error o:".concat(jscadToString(o), " objectSize: ").concat(objectSize), undefined, err);
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
function calcmidlineTo(o, axis, to) {
|
|
1755
|
+
var bounds = o.getBounds();
|
|
1756
|
+
var objectSize = size(bounds);
|
|
1757
|
+
return axisApply(axis, function(i, a) {
|
|
1758
|
+
return to - objectSize[a] / 2;
|
|
1759
|
+
});
|
|
1760
|
+
}
|
|
1761
|
+
function midlineTo(o, axis, to) {
|
|
1762
|
+
return assertValidCSG$1(o.translate(calcmidlineTo(o, axis, to)), "midlineTo");
|
|
1763
|
+
}
|
|
1764
|
+
function translator(o, axis, withObj) {
|
|
1765
|
+
var objectCentroid = centroid(o);
|
|
1766
|
+
var withCentroid = centroid(withObj);
|
|
1767
|
+
var t = axisApply(axis, function(i) {
|
|
1768
|
+
return withCentroid[i] - objectCentroid[i];
|
|
1769
|
+
});
|
|
1770
|
+
return t;
|
|
1771
|
+
}
|
|
1772
|
+
function calcCenterWith(o, axes, withObj) {
|
|
1773
|
+
var delta = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
|
|
1774
|
+
var objectCentroid = centroid(o);
|
|
1775
|
+
var withCentroid = centroid(withObj);
|
|
1776
|
+
var t = axisApply(axes, function(i, axis) {
|
|
1777
|
+
return withCentroid[axis] - objectCentroid[axis];
|
|
1778
|
+
});
|
|
1779
|
+
return delta ? add(t, delta) : t;
|
|
1780
|
+
}
|
|
1781
|
+
function centerWith(o, axis, withObj) {
|
|
1782
|
+
return assertValidCSG$1(o.translate(calcCenterWith(o, axis, withObj)), "centerWith");
|
|
1783
|
+
}
|
|
1784
|
+
function getDelta(size, bounds, axis, offset, nonzero) {
|
|
1785
|
+
if (!isEmpty(offset) && nonzero) {
|
|
1786
|
+
if (Math.abs(offset) < 1e-4) {
|
|
1787
|
+
offset = 1e-4 * (isNegative(offset) ? -1 : 1);
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
var dist = isNegative(offset) ? offset = size[axis] + offset : offset;
|
|
1791
|
+
return axisApply(axis, function(i, a) {
|
|
1792
|
+
return bounds[0][a] + (isEmpty(dist) ? size[axis] / 2 : dist);
|
|
1793
|
+
});
|
|
1794
|
+
}
|
|
1795
|
+
var EPS = 1e-5;
|
|
1796
|
+
function splitCSGByPlane(csg, plane) {
|
|
1797
|
+
var frontPolys = [];
|
|
1798
|
+
var backPolys = [];
|
|
1799
|
+
csg.polygons.forEach(function(poly) {
|
|
1800
|
+
var vertices = poly.vertices;
|
|
1801
|
+
var numVerts = vertices.length;
|
|
1802
|
+
var hasfront = false;
|
|
1803
|
+
var hasback = false;
|
|
1804
|
+
var vertexIsBack = [];
|
|
1805
|
+
for (var i = 0; i < numVerts; i++) {
|
|
1806
|
+
var t = plane.normal.dot(vertices[i].pos) - plane.w;
|
|
1807
|
+
vertexIsBack.push(t < 0);
|
|
1808
|
+
if (t > EPS) hasfront = true;
|
|
1809
|
+
if (t < -EPS) hasback = true;
|
|
1810
|
+
}
|
|
1811
|
+
if (!hasfront && !hasback) {
|
|
1812
|
+
var d = plane.normal.dot(poly.plane.normal);
|
|
1813
|
+
if (d >= 0) {
|
|
1814
|
+
frontPolys.push(poly);
|
|
1815
|
+
} else {
|
|
1816
|
+
backPolys.push(poly);
|
|
1817
|
+
}
|
|
1818
|
+
} else if (!hasback) {
|
|
1819
|
+
frontPolys.push(poly);
|
|
1820
|
+
} else if (!hasfront) {
|
|
1821
|
+
backPolys.push(poly);
|
|
1822
|
+
} else {
|
|
1823
|
+
var fv = [];
|
|
1824
|
+
var bv = [];
|
|
1825
|
+
for (var vi = 0; vi < numVerts; vi++) {
|
|
1826
|
+
var vertex = vertices[vi];
|
|
1827
|
+
var nextVi = (vi + 1) % numVerts;
|
|
1828
|
+
var isback = vertexIsBack[vi];
|
|
1829
|
+
var nextisback = vertexIsBack[nextVi];
|
|
1830
|
+
if (isback === nextisback) {
|
|
1831
|
+
if (isback) {
|
|
1832
|
+
bv.push(vertex);
|
|
1833
|
+
} else {
|
|
1834
|
+
fv.push(vertex);
|
|
1835
|
+
}
|
|
1836
|
+
} else {
|
|
1837
|
+
var point = vertex.pos;
|
|
1838
|
+
var nextpoint = vertices[nextVi].pos;
|
|
1839
|
+
var ip = plane.splitLineBetweenPoints(point, nextpoint);
|
|
1840
|
+
var iv = new CSG$1.Vertex(ip);
|
|
1841
|
+
if (isback) {
|
|
1842
|
+
bv.push(vertex);
|
|
1843
|
+
bv.push(iv);
|
|
1844
|
+
fv.push(iv);
|
|
1845
|
+
} else {
|
|
1846
|
+
fv.push(vertex);
|
|
1847
|
+
fv.push(iv);
|
|
1848
|
+
bv.push(iv);
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
var EPSEPS = EPS * EPS;
|
|
1853
|
+
if (fv.length >= 3) {
|
|
1854
|
+
var prev = fv[fv.length - 1];
|
|
1855
|
+
for (var fi = 0; fi < fv.length; fi++) {
|
|
1856
|
+
var curr = fv[fi];
|
|
1857
|
+
if (curr.pos.distanceToSquared(prev.pos) < EPSEPS) {
|
|
1858
|
+
fv.splice(fi, 1);
|
|
1859
|
+
fi--;
|
|
1860
|
+
}
|
|
1861
|
+
prev = curr;
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
if (bv.length >= 3) {
|
|
1865
|
+
var prev = bv[bv.length - 1];
|
|
1866
|
+
for (var bi = 0; bi < bv.length; bi++) {
|
|
1867
|
+
var curr = bv[bi];
|
|
1868
|
+
if (curr.pos.distanceToSquared(prev.pos) < EPSEPS) {
|
|
1869
|
+
bv.splice(bi, 1);
|
|
1870
|
+
bi--;
|
|
1871
|
+
}
|
|
1872
|
+
prev = curr;
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
if (fv.length >= 3) frontPolys.push(new CSG$1.Polygon(fv, poly.shared, poly.plane));
|
|
1876
|
+
if (bv.length >= 3) backPolys.push(new CSG$1.Polygon(bv, poly.shared, poly.plane));
|
|
1877
|
+
}
|
|
1878
|
+
});
|
|
1879
|
+
return {
|
|
1880
|
+
front: CSG$1.fromPolygons(frontPolys),
|
|
1881
|
+
back: CSG$1.fromPolygons(backPolys)
|
|
1882
|
+
};
|
|
1883
|
+
}
|
|
1884
|
+
function bisect() {
|
|
1885
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1886
|
+
args[_key] = arguments[_key];
|
|
1887
|
+
}
|
|
1888
|
+
if (args.length < 2) {
|
|
1889
|
+
error("bisect requires an object and an axis", "JSCAD_UTILS_INVALID_ARGS");
|
|
1890
|
+
}
|
|
1891
|
+
var object = args[0];
|
|
1892
|
+
var axis = args[1];
|
|
1893
|
+
var offset, angle = 0, rotateaxis, rotateoffset, options = {};
|
|
1894
|
+
for (var i = 2; i < args.length; i++) {
|
|
1895
|
+
if (args[i] instanceof Object) {
|
|
1896
|
+
options = args[i];
|
|
1897
|
+
if (options.offset) offset = options.offset;
|
|
1898
|
+
if (options.angle) angle = options.angle;
|
|
1899
|
+
if (options.rotateaxis) rotateaxis = options.rotateaxis;
|
|
1900
|
+
if (options.rotateoffset) rotateoffset = options.rotateoffset;
|
|
1901
|
+
} else {
|
|
1902
|
+
switch (i) {
|
|
1903
|
+
case 2:
|
|
1904
|
+
offset = args[i];
|
|
1905
|
+
break;
|
|
1906
|
+
|
|
1907
|
+
case 3:
|
|
1908
|
+
angle = args[i];
|
|
1909
|
+
break;
|
|
1910
|
+
|
|
1911
|
+
case 4:
|
|
1912
|
+
rotateaxis = args[i];
|
|
1913
|
+
break;
|
|
1914
|
+
|
|
1915
|
+
case 5:
|
|
1916
|
+
rotateoffset = args[i];
|
|
1917
|
+
break;
|
|
1918
|
+
|
|
1919
|
+
case 6:
|
|
1920
|
+
options = args[i];
|
|
1921
|
+
break;
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
options = Object.assign({
|
|
1926
|
+
addRotationCenter: false
|
|
1927
|
+
}, options);
|
|
1928
|
+
angle = angle || 0;
|
|
1929
|
+
var info = normalVector(axis);
|
|
1930
|
+
var bounds = object.getBounds();
|
|
1931
|
+
var objectSize = size(object);
|
|
1932
|
+
rotateaxis = rotateaxis || {
|
|
1933
|
+
x: "y",
|
|
1934
|
+
y: "x",
|
|
1935
|
+
z: "x"
|
|
1936
|
+
}[axis];
|
|
1937
|
+
var cutDelta = options.cutDelta || getDelta(objectSize, bounds, axis, offset);
|
|
1938
|
+
var rotateOffsetAxis = {
|
|
1939
|
+
xy: "z",
|
|
1940
|
+
yz: "x",
|
|
1941
|
+
xz: "y"
|
|
1942
|
+
}[[ axis, rotateaxis ].sort().join("")];
|
|
1943
|
+
var centroid = object.centroid();
|
|
1944
|
+
var rotateDelta = getDelta(objectSize, bounds, rotateOffsetAxis, rotateoffset);
|
|
1945
|
+
var rotationCenter = options.rotationCenter || new CSG$1.Vector3D(axisApply("xyz", function(i, a) {
|
|
1946
|
+
if (a == axis) return cutDelta[i];
|
|
1947
|
+
if (a == rotateOffsetAxis) return rotateDelta[i];
|
|
1948
|
+
return centroid[a];
|
|
1949
|
+
}));
|
|
1950
|
+
var theRotationAxis = rotationAxes[rotateaxis];
|
|
1951
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).translate(cutDelta).rotate(rotationCenter, theRotationAxis, angle);
|
|
1952
|
+
debug$2("bisect", debug$2.enabled && {
|
|
1953
|
+
axis,
|
|
1954
|
+
offset,
|
|
1955
|
+
angle,
|
|
1956
|
+
rotateaxis,
|
|
1957
|
+
cutDelta,
|
|
1958
|
+
rotateOffsetAxis,
|
|
1959
|
+
rotationCenter,
|
|
1960
|
+
theRotationAxis,
|
|
1961
|
+
cutplane,
|
|
1962
|
+
options
|
|
1963
|
+
});
|
|
1964
|
+
var negative = object.cutByPlane(cutplane.plane);
|
|
1965
|
+
var positive = object.cutByPlane(cutplane.plane.flipped());
|
|
1966
|
+
var negSize = size(negative);
|
|
1967
|
+
var posSize = size(positive);
|
|
1968
|
+
if (negSize[axis] >= objectSize[axis] - EPS || posSize[axis] >= objectSize[axis] - EPS) {
|
|
1969
|
+
var halves = splitCSGByPlane(object, cutplane.plane);
|
|
1970
|
+
if (negSize[axis] >= objectSize[axis] - EPS) {
|
|
1971
|
+
negative = halves.back;
|
|
1972
|
+
try {
|
|
1973
|
+
negative = negative.cutByPlane(cutplane.plane);
|
|
1974
|
+
} catch (e) {}
|
|
1975
|
+
}
|
|
1976
|
+
if (posSize[axis] >= objectSize[axis] - EPS) {
|
|
1977
|
+
positive = halves.front;
|
|
1978
|
+
try {
|
|
1979
|
+
positive = positive.cutByPlane(cutplane.plane.flipped());
|
|
1980
|
+
} catch (e) {}
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
var g = Group("negative,positive", [ negative.color(options.color && "red"), positive.color(options.color && "blue") ]);
|
|
1984
|
+
if (options.addRotationCenter) g.add(unitAxis(objectSize.length() + 10, .1, rotationCenter), "rotationCenter");
|
|
1985
|
+
return g;
|
|
1986
|
+
}
|
|
1987
|
+
function slice(object) {
|
|
1988
|
+
var angle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 15;
|
|
1989
|
+
var axis = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "x";
|
|
1990
|
+
var rotateaxis = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "z";
|
|
1991
|
+
var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {
|
|
1992
|
+
color: true,
|
|
1993
|
+
addRotationCenter: true
|
|
1994
|
+
};
|
|
1995
|
+
var info = normalVector(axis);
|
|
1996
|
+
var rotationCenter = options.rotationCenter || new CSG$1.Vector3D(0, 0, 0);
|
|
1997
|
+
var theRotationAxis = rotationAxes[rotateaxis];
|
|
1998
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).rotate(rotationCenter, theRotationAxis, angle);
|
|
1999
|
+
var g = Group("negative,positive", [ object.cutByPlane(cutplane.plane).color(options.color && "red"), object.cutByPlane(cutplane.plane.flipped()).color(options.color && "blue") ]);
|
|
2000
|
+
if (options.addRotationCenter) {
|
|
2001
|
+
var objectSize = size(object);
|
|
2002
|
+
g.add(unitAxis(objectSize.length() + 10, .1, rotationCenter), "rotationCenter");
|
|
2003
|
+
}
|
|
2004
|
+
return g;
|
|
2005
|
+
}
|
|
2006
|
+
function wedge(object, start, end, axis) {
|
|
2007
|
+
var a = slice(object, start, axis);
|
|
2008
|
+
var b = slice(a.parts.positive, end, axis);
|
|
2009
|
+
return Group({
|
|
2010
|
+
body: b.parts.positive.union(a.parts.negative).color("blue"),
|
|
2011
|
+
wedge: b.parts.negative.color("red")
|
|
2012
|
+
});
|
|
2013
|
+
}
|
|
2014
|
+
function stretch(object, axis, distance, offset) {
|
|
2015
|
+
var normal = {
|
|
2016
|
+
x: [ 1, 0, 0 ],
|
|
2017
|
+
y: [ 0, 1, 0 ],
|
|
2018
|
+
z: [ 0, 0, 1 ]
|
|
2019
|
+
};
|
|
2020
|
+
var bounds = object.getBounds();
|
|
2021
|
+
var objectSize = size(object);
|
|
2022
|
+
var cutDelta = getDelta(objectSize, bounds, axis, offset, true);
|
|
2023
|
+
return assertValidCSG$1(object.stretchAtPlane(normal[axis], cutDelta, distance), "stretch");
|
|
2024
|
+
}
|
|
2025
|
+
function poly2solid(top, bottom, height) {
|
|
2026
|
+
if (top.sides.length == 0) {
|
|
2027
|
+
return new CSG$1;
|
|
2028
|
+
}
|
|
2029
|
+
var offsetVector = CSG$1.Vector3D.Create(0, 0, height);
|
|
2030
|
+
var normalVector = CSG$1.Vector3D.Create(0, 1, 0);
|
|
2031
|
+
var polygons = [];
|
|
2032
|
+
polygons = polygons.concat(bottom._toPlanePolygons({
|
|
2033
|
+
translation: [ 0, 0, 0 ],
|
|
2034
|
+
normalVector,
|
|
2035
|
+
flipped: !(offsetVector.z < 0)
|
|
2036
|
+
}));
|
|
2037
|
+
polygons = polygons.concat(top._toPlanePolygons({
|
|
2038
|
+
translation: offsetVector,
|
|
2039
|
+
normalVector,
|
|
2040
|
+
flipped: offsetVector.z < 0
|
|
2041
|
+
}));
|
|
2042
|
+
var c1 = new CSG$1.Connector(offsetVector.times(0), [ 0, 0, offsetVector.z ], normalVector);
|
|
2043
|
+
var c2 = new CSG$1.Connector(offsetVector, [ 0, 0, offsetVector.z ], normalVector);
|
|
2044
|
+
polygons = polygons.concat(bottom._toWallPolygons({
|
|
2045
|
+
cag: top,
|
|
2046
|
+
toConnector1: c1,
|
|
2047
|
+
toConnector2: c2
|
|
2048
|
+
}));
|
|
2049
|
+
return assertValidCSG$1(CSG$1.fromPolygons(polygons), "poly2solid");
|
|
2050
|
+
}
|
|
2051
|
+
function slices2poly(slices, options, axis) {
|
|
2052
|
+
debug$2("slices2poly", slices, options, axis);
|
|
2053
|
+
options = Object.assign({
|
|
2054
|
+
twistangle: 0,
|
|
2055
|
+
twiststeps: 0
|
|
2056
|
+
}, options);
|
|
2057
|
+
var twistangle = options && parseFloat(options.twistangle) || 0;
|
|
2058
|
+
options && parseInt(options.twiststeps) || CSG$1.defaultResolution3D;
|
|
2059
|
+
var normalVector = options.si.normalVector;
|
|
2060
|
+
var polygons = [];
|
|
2061
|
+
var first$1 = first(slices);
|
|
2062
|
+
var last$1 = last(slices);
|
|
2063
|
+
debug$2("slices2poly first", first$1, first$1.offset, "last", last$1);
|
|
2064
|
+
var up = first$1.offset[axis] > last$1.offset[axis];
|
|
2065
|
+
polygons = polygons.concat(first$1.poly._toPlanePolygons({
|
|
2066
|
+
translation: first$1.offset,
|
|
2067
|
+
normalVector,
|
|
2068
|
+
flipped: !up
|
|
2069
|
+
}));
|
|
2070
|
+
var rotateAxis = "rotate" + axis.toUpperCase();
|
|
2071
|
+
polygons = polygons.concat(last$1.poly._toPlanePolygons({
|
|
2072
|
+
translation: last$1.offset,
|
|
2073
|
+
normalVector: normalVector[rotateAxis](twistangle),
|
|
2074
|
+
flipped: up
|
|
2075
|
+
}));
|
|
2076
|
+
var rotate = twistangle === 0 ? function rotateZero(v) {
|
|
2077
|
+
return v;
|
|
2078
|
+
} : function rotate(v, angle, percent) {
|
|
2079
|
+
return v[rotateAxis](angle * percent);
|
|
2080
|
+
};
|
|
2081
|
+
var connectorAxis = last$1.offset.minus(first$1.offset).abs();
|
|
2082
|
+
slices.forEach(function(slice, idx) {
|
|
2083
|
+
if (idx < slices.length - 1) {
|
|
2084
|
+
var nextidx = idx + 1;
|
|
2085
|
+
var top = !up ? slices[nextidx] : slice;
|
|
2086
|
+
var bottom = up ? slices[nextidx] : slice;
|
|
2087
|
+
var c1 = new CSG$1.Connector(bottom.offset, connectorAxis, rotate(normalVector, twistangle, idx / slices.length));
|
|
2088
|
+
var c2 = new CSG$1.Connector(top.offset, connectorAxis, rotate(normalVector, twistangle, nextidx / slices.length));
|
|
2089
|
+
polygons = polygons.concat(bottom.poly._toWallPolygons({
|
|
2090
|
+
cag: top.poly,
|
|
2091
|
+
toConnector1: c1,
|
|
2092
|
+
toConnector2: c2
|
|
2093
|
+
}));
|
|
2094
|
+
}
|
|
2095
|
+
});
|
|
2096
|
+
return assertValidCSG$1(CSG$1.fromPolygons(polygons), "slices2poly");
|
|
2097
|
+
}
|
|
2098
|
+
function normalVector(axis) {
|
|
2099
|
+
var axisInfo = {
|
|
2100
|
+
z: {
|
|
2101
|
+
orthoNormalCartesian: [ "X", "Y" ],
|
|
2102
|
+
normalVector: CSG$1.Vector3D.Create(0, 1, 0)
|
|
2103
|
+
},
|
|
2104
|
+
x: {
|
|
2105
|
+
orthoNormalCartesian: [ "Y", "Z" ],
|
|
2106
|
+
normalVector: CSG$1.Vector3D.Create(0, 0, 1)
|
|
2107
|
+
},
|
|
2108
|
+
y: {
|
|
2109
|
+
orthoNormalCartesian: [ "Z", "X" ],
|
|
2110
|
+
normalVector: CSG$1.Vector3D.Create(0, 0, 1)
|
|
2111
|
+
}
|
|
2112
|
+
};
|
|
2113
|
+
if (!axisInfo[axis]) error("normalVector: invalid axis " + axis);
|
|
2114
|
+
return axisInfo[axis];
|
|
2115
|
+
}
|
|
2116
|
+
function sliceParams(orientation, radius, bounds) {
|
|
2117
|
+
var axis = orientation[0];
|
|
2118
|
+
var direction = orientation[1];
|
|
2119
|
+
var dirInfo = {
|
|
2120
|
+
"dir+": {
|
|
2121
|
+
sizeIdx: 1,
|
|
2122
|
+
sizeDir: -1,
|
|
2123
|
+
moveDir: -1,
|
|
2124
|
+
positive: true
|
|
2125
|
+
},
|
|
2126
|
+
"dir-": {
|
|
2127
|
+
sizeIdx: 0,
|
|
2128
|
+
sizeDir: 1,
|
|
2129
|
+
moveDir: 0,
|
|
2130
|
+
positive: false
|
|
2131
|
+
}
|
|
2132
|
+
};
|
|
2133
|
+
var info = dirInfo["dir" + direction];
|
|
2134
|
+
return Object.assign({
|
|
2135
|
+
axis,
|
|
2136
|
+
cutDelta: axisApply(axis, function(i, a) {
|
|
2137
|
+
return bounds[info.sizeIdx][a] + Math.abs(radius) * info.sizeDir;
|
|
2138
|
+
}),
|
|
2139
|
+
moveDelta: axisApply(axis, function(i, a) {
|
|
2140
|
+
return bounds[info.sizeIdx][a] + Math.abs(radius) * info.moveDir;
|
|
2141
|
+
})
|
|
2142
|
+
}, info, normalVector(axis));
|
|
2143
|
+
}
|
|
2144
|
+
function reShape(object, radius, orientation, options, slicer) {
|
|
2145
|
+
options = options || {};
|
|
2146
|
+
var b = object.getBounds();
|
|
2147
|
+
var absoluteRadius = Math.abs(radius);
|
|
2148
|
+
var si = sliceParams(orientation, radius, b);
|
|
2149
|
+
debug$2("reShape", absoluteRadius, si);
|
|
2150
|
+
if (si.axis !== "z") throw new Error('reShape error: CAG._toPlanePolygons only uses the "z" axis. You must use the "z" axis for now.');
|
|
2151
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(si.orthoNormalCartesian[0], si.orthoNormalCartesian[1]).translate(si.cutDelta);
|
|
2152
|
+
var slice = object.sectionCut(cutplane);
|
|
2153
|
+
var first = axisApply(si.axis, function() {
|
|
2154
|
+
return si.positive ? 0 : absoluteRadius;
|
|
2155
|
+
});
|
|
2156
|
+
var last = axisApply(si.axis, function() {
|
|
2157
|
+
return si.positive ? absoluteRadius : 0;
|
|
2158
|
+
});
|
|
2159
|
+
var plane = si.positive ? cutplane.plane : cutplane.plane.flipped();
|
|
2160
|
+
debug$2("reShape first/last", first, last);
|
|
2161
|
+
var slices = slicer(first, last, slice, radius);
|
|
2162
|
+
var delta = slices2poly(slices, Object.assign(options, {
|
|
2163
|
+
si
|
|
2164
|
+
}), si.axis).color(options.color);
|
|
2165
|
+
var remainder = object.cutByPlane(plane);
|
|
2166
|
+
return assertValidCSG$1(union([ options.unionOriginal ? object : remainder, delta.translate(si.moveDelta) ]), "reShape");
|
|
2167
|
+
}
|
|
2168
|
+
function chamfer(object, radius, orientation, options) {
|
|
2169
|
+
return assertValidCSG$1(reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
2170
|
+
return [ {
|
|
2171
|
+
poly: slice,
|
|
2172
|
+
offset: new CSG$1.Vector3D(first)
|
|
2173
|
+
}, {
|
|
2174
|
+
poly: enlarge(slice, [ -radius * 2, -radius * 2 ]),
|
|
2175
|
+
offset: new CSG$1.Vector3D(last)
|
|
2176
|
+
} ];
|
|
2177
|
+
}), "chamfer");
|
|
2178
|
+
}
|
|
2179
|
+
function fillet(object, radius, orientation, options) {
|
|
2180
|
+
options = options || {};
|
|
2181
|
+
return assertValidCSG$1(reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
2182
|
+
var v1 = new CSG$1.Vector3D(first);
|
|
2183
|
+
var v2 = new CSG$1.Vector3D(last);
|
|
2184
|
+
var res = options.resolution || CSG$1.defaultResolution3D;
|
|
2185
|
+
var slices = range(0, res).map(function(i) {
|
|
2186
|
+
var p = i > 0 ? i / (res - 1) : 0;
|
|
2187
|
+
var v = v1.lerp(v2, p);
|
|
2188
|
+
var size = -radius * 2 - Math.cos(Math.asin(p)) * (-radius * 2);
|
|
2189
|
+
return {
|
|
2190
|
+
poly: enlarge(slice, [ size, size ]),
|
|
2191
|
+
offset: v
|
|
2192
|
+
};
|
|
2193
|
+
});
|
|
2194
|
+
return slices;
|
|
2195
|
+
}), "fillet");
|
|
2196
|
+
}
|
|
2197
|
+
function calcRotate(part, solid, axis) {
|
|
2198
|
+
var axes = {
|
|
2199
|
+
x: [ 1, 0, 0 ],
|
|
2200
|
+
y: [ 0, 1, 0 ],
|
|
2201
|
+
z: [ 0, 0, 1 ]
|
|
2202
|
+
};
|
|
2203
|
+
var rotationCenter = solid.centroid();
|
|
2204
|
+
var rotationAxis = axes[axis];
|
|
2205
|
+
return {
|
|
2206
|
+
rotationCenter,
|
|
2207
|
+
rotationAxis
|
|
2208
|
+
};
|
|
2209
|
+
}
|
|
2210
|
+
function rotateAround(part, solid, axis, angle) {
|
|
2211
|
+
var _calcRotate = calcRotate(part, solid, axis), rotationCenter = _calcRotate.rotationCenter, rotationAxis = _calcRotate.rotationAxis;
|
|
2212
|
+
return assertValidCSG$1("rotateAround")(part.rotate(rotationCenter, rotationAxis, angle));
|
|
2213
|
+
}
|
|
2214
|
+
function cloneProperties(from, to) {
|
|
2215
|
+
return Object.entries(from).reduce(function(props, _ref) {
|
|
2216
|
+
var _ref2 = _slicedToArray(_ref, 2), key = _ref2[0], value = _ref2[1];
|
|
2217
|
+
props[key] = value;
|
|
2218
|
+
return props;
|
|
2219
|
+
}, to);
|
|
2220
|
+
}
|
|
2221
|
+
function clone(o) {
|
|
2222
|
+
var c = CSG$1.fromPolygons(o.toPolygons());
|
|
2223
|
+
cloneProperties(o, c);
|
|
2224
|
+
debug$2("clone", o, c, CSG$1);
|
|
2225
|
+
return assertValidCSG$1(c, "clone");
|
|
2226
|
+
}
|
|
2227
|
+
function addConnector(object, name) {
|
|
2228
|
+
var point = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [ 0, 0, 0 ];
|
|
2229
|
+
var axis = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [ 1, 0, 0 ];
|
|
2230
|
+
var normal = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [ 0, 0, 1 ];
|
|
2231
|
+
object.properties[name] = new CSG$1.Connector(point, axis, normal);
|
|
2232
|
+
return assertValidCSG$1("addConnector")(object);
|
|
2233
|
+
}
|
|
2234
|
+
var debug$1 = Debug("jscadUtils:parts");
|
|
2235
|
+
var assertValidCSG = AssertValidCSG("parts");
|
|
2236
|
+
var parts = {
|
|
2237
|
+
BBox: BBox$1,
|
|
2238
|
+
Cube,
|
|
2239
|
+
RoundedCube,
|
|
2240
|
+
Cylinder,
|
|
2241
|
+
Cone
|
|
2242
|
+
};
|
|
2243
|
+
function BBox$1() {
|
|
2244
|
+
function box(object) {
|
|
2245
|
+
return CSG$1.cube({
|
|
2246
|
+
center: object.centroid(),
|
|
2247
|
+
radius: object.size().dividedBy(2)
|
|
2248
|
+
});
|
|
2249
|
+
}
|
|
2250
|
+
for (var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
2251
|
+
objects[_key] = arguments[_key];
|
|
2252
|
+
}
|
|
2253
|
+
return assertValidCSG(objects.reduce(function(bbox, part) {
|
|
2254
|
+
var object = bbox ? union([ bbox, box(part) ]) : part;
|
|
2255
|
+
return box(object);
|
|
2256
|
+
}, undefined), "BBox");
|
|
2257
|
+
}
|
|
2258
|
+
function Cube(width) {
|
|
2259
|
+
var r = div$1(fromxyz(width), 2);
|
|
2260
|
+
return assertValidCSG(CSG$1.cube({
|
|
2261
|
+
center: r,
|
|
2262
|
+
radius: r
|
|
2263
|
+
}), "Cube");
|
|
2264
|
+
}
|
|
2265
|
+
function RoundedCube(x, y, thickness, corner_radius) {
|
|
2266
|
+
if (x.getBounds) {
|
|
2267
|
+
var size$1 = size(x.getBounds());
|
|
2268
|
+
var r = [ size$1.x / 2, size$1.y / 2 ];
|
|
2269
|
+
thickness = size$1.z;
|
|
2270
|
+
corner_radius = y;
|
|
2271
|
+
} else {
|
|
2272
|
+
var r = [ x / 2, y / 2 ];
|
|
2273
|
+
}
|
|
2274
|
+
debug$1("RoundedCube", size$1, r, thickness, corner_radius);
|
|
2275
|
+
var roundedcube = CAG.roundedRectangle({
|
|
2276
|
+
center: [ r[0], r[1], 0 ],
|
|
2277
|
+
radius: r,
|
|
2278
|
+
roundradius: corner_radius,
|
|
2279
|
+
resolution: CSG$1.defaultResolution2D
|
|
2280
|
+
}).extrude({
|
|
2281
|
+
offset: [ 0, 0, thickness || 1.62 ]
|
|
2282
|
+
});
|
|
2283
|
+
return assertValidCSG(roundedcube, "RoundedCube");
|
|
2284
|
+
}
|
|
2285
|
+
function Cylinder(diameter, height) {
|
|
2286
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
2287
|
+
debug$1("parts.Cylinder", diameter, height, options);
|
|
2288
|
+
options = Object.assign({
|
|
2289
|
+
start: [ 0, 0, 0 ],
|
|
2290
|
+
end: [ 0, 0, height ],
|
|
2291
|
+
radius: diameter / 2,
|
|
2292
|
+
resolution: CSG$1.defaultResolution2D
|
|
2293
|
+
}, options);
|
|
2294
|
+
return assertValidCSG(CSG$1.cylinder(options), "Cylinder");
|
|
2295
|
+
}
|
|
2296
|
+
function Cone(diameter1, diameter2, height) {
|
|
2297
|
+
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
2298
|
+
debug$1("parts.Cone", diameter1, diameter2, height, options);
|
|
2299
|
+
return assertValidCSG(CSG$1.cylinder(Object.assign({
|
|
2300
|
+
start: [ 0, 0, 0 ],
|
|
2301
|
+
end: [ 0, 0, height ],
|
|
2302
|
+
radiusStart: diameter1 / 2,
|
|
2303
|
+
radiusEnd: diameter2 / 2,
|
|
2304
|
+
resolution: CSG$1.defaultResolution2D
|
|
2305
|
+
}, options)), "Cone");
|
|
2306
|
+
}
|
|
2307
|
+
function Hexagon(diameter, height) {
|
|
2308
|
+
debug$1("hexagon", diameter, height);
|
|
2309
|
+
var radius = diameter / 2;
|
|
2310
|
+
var sqrt3 = Math.sqrt(3) / 2;
|
|
2311
|
+
var hex = CAG.fromPoints([ [ radius, 0 ], [ radius / 2, radius * sqrt3 ], [ -radius / 2, radius * sqrt3 ], [ -radius, 0 ], [ -radius / 2, -radius * sqrt3 ], [ radius / 2, -radius * sqrt3 ] ]);
|
|
2312
|
+
return assertValidCSG(hex.extrude({
|
|
2313
|
+
offset: [ 0, 0, height ]
|
|
2314
|
+
}), "Hexagon");
|
|
2315
|
+
}
|
|
2316
|
+
function Triangle(base, height) {
|
|
2317
|
+
var radius = base / 2;
|
|
2318
|
+
var tri = CAG.fromPoints([ [ -radius, 0 ], [ radius, 0 ], [ 0, Math.sin(30) * radius ] ]);
|
|
2319
|
+
return assertValidCSG(tri.extrude({
|
|
2320
|
+
offset: [ 0, 0, height ]
|
|
2321
|
+
}), "Triangle");
|
|
2322
|
+
}
|
|
2323
|
+
function Tube(outsideDiameter, insideDiameter, height, outsideOptions, insideOptions) {
|
|
2324
|
+
return assertValidCSG(Cylinder(outsideDiameter, height, outsideOptions).subtract(Cylinder(insideDiameter, height, insideOptions || outsideOptions)), "Tube");
|
|
2325
|
+
}
|
|
2326
|
+
function Anchor() {
|
|
2327
|
+
var width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
|
|
2328
|
+
var height = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10;
|
|
2329
|
+
var hole = Cylinder(width, height).Center().color("red");
|
|
2330
|
+
var post = Cylinder(height / 2, width * .66).rotateX(90).align(hole, "xz").snap(hole, "y", "inside-").translate([ 0, 0, -height / 6 ]).color("purple");
|
|
2331
|
+
return Group({
|
|
2332
|
+
post,
|
|
2333
|
+
hole
|
|
2334
|
+
});
|
|
2335
|
+
}
|
|
2336
|
+
function Board(width, height, corner_radius, thickness) {
|
|
2337
|
+
var r = divA([ width, height ], 2);
|
|
2338
|
+
var board = CAG.roundedRectangle({
|
|
2339
|
+
center: [ r[0], r[1], 0 ],
|
|
2340
|
+
radius: r,
|
|
2341
|
+
roundradius: corner_radius,
|
|
2342
|
+
resolution: CSG$1.defaultResolution2D
|
|
2343
|
+
}).extrude({
|
|
2344
|
+
offset: [ 0, 0, thickness || 1.62 ]
|
|
2345
|
+
});
|
|
2346
|
+
return assertValidCSG(board, "Board");
|
|
2347
|
+
}
|
|
2348
|
+
var Hardware = {
|
|
2349
|
+
Orientation: {
|
|
2350
|
+
up: {
|
|
2351
|
+
head: "outside-",
|
|
2352
|
+
clear: "inside+"
|
|
2353
|
+
},
|
|
2354
|
+
down: {
|
|
2355
|
+
head: "outside+",
|
|
2356
|
+
clear: "inside-"
|
|
2357
|
+
}
|
|
2358
|
+
},
|
|
2359
|
+
Screw: function Screw(head, thread, headClearSpace, options) {
|
|
2360
|
+
depreciated("Screw", false, "Use the jscad-hardware screw methods instead");
|
|
2361
|
+
options = Object.assign(options, {
|
|
2362
|
+
orientation: "up",
|
|
2363
|
+
clearance: [ 0, 0, 0 ]
|
|
2364
|
+
});
|
|
2365
|
+
var orientation = Hardware.Orientation[options.orientation];
|
|
2366
|
+
var group = Group("head,thread", {
|
|
2367
|
+
head: head.color("gray"),
|
|
2368
|
+
thread: thread.snap(head, "z", orientation.head).color("silver")
|
|
2369
|
+
});
|
|
2370
|
+
if (headClearSpace) {
|
|
2371
|
+
group.add(headClearSpace.enlarge(options.clearance).snap(head, "z", orientation.clear).color("red"), "headClearSpace", true);
|
|
2372
|
+
}
|
|
2373
|
+
return group;
|
|
2374
|
+
},
|
|
2375
|
+
PanHeadScrew: function PanHeadScrew(headDiameter, headLength, diameter, length, clearLength, options) {
|
|
2376
|
+
depreciated("PanHeadScrew", false, "Use the jscad-hardware screw methods instead");
|
|
2377
|
+
var head = Cylinder(headDiameter, headLength);
|
|
2378
|
+
var thread = Cylinder(diameter, length);
|
|
2379
|
+
if (clearLength) {
|
|
2380
|
+
var headClearSpace = Cylinder(headDiameter, clearLength);
|
|
2381
|
+
}
|
|
2382
|
+
return Hardware.Screw(head, thread, headClearSpace, options);
|
|
2383
|
+
},
|
|
2384
|
+
HexHeadScrew: function HexHeadScrew(headDiameter, headLength, diameter, length, clearLength, options) {
|
|
2385
|
+
depreciated("HexHeadScrew", false, "Use the jscad-hardware screw methods instead");
|
|
2386
|
+
var head = Hexagon(headDiameter, headLength);
|
|
2387
|
+
var thread = Cylinder(diameter, length);
|
|
2388
|
+
if (clearLength) {
|
|
2389
|
+
var headClearSpace = Hexagon(headDiameter, clearLength);
|
|
2390
|
+
}
|
|
2391
|
+
return Hardware.Screw(head, thread, headClearSpace, options);
|
|
2392
|
+
},
|
|
2393
|
+
FlatHeadScrew: function FlatHeadScrew(headDiameter, headLength, diameter, length, clearLength, options) {
|
|
2394
|
+
depreciated("FlatHeadScrew", false, "Use the jscad-hardware screw methods instead");
|
|
2395
|
+
var head = Cone(headDiameter, diameter, headLength);
|
|
2396
|
+
var thread = Cylinder(diameter, length);
|
|
2397
|
+
if (clearLength) {
|
|
2398
|
+
var headClearSpace = Cylinder(headDiameter, clearLength);
|
|
2399
|
+
}
|
|
2400
|
+
return Hardware.Screw(head, thread, headClearSpace, options);
|
|
2401
|
+
}
|
|
2402
|
+
};
|
|
2403
|
+
var parts$1 = Object.freeze({
|
|
2404
|
+
__proto__: null,
|
|
2405
|
+
default: parts,
|
|
2406
|
+
BBox: BBox$1,
|
|
2407
|
+
Cube,
|
|
2408
|
+
RoundedCube,
|
|
2409
|
+
Cylinder,
|
|
2410
|
+
Cone,
|
|
2411
|
+
Hexagon,
|
|
2412
|
+
Triangle,
|
|
2413
|
+
Tube,
|
|
2414
|
+
Anchor,
|
|
2415
|
+
Board,
|
|
2416
|
+
Hardware
|
|
2417
|
+
});
|
|
2418
|
+
var debug = Debug("jscadUtils:boxes");
|
|
2419
|
+
function RabbetJoin(box, thickness, cutHeight) {
|
|
2420
|
+
depreciated("RabbetJoin", true, "Use 'Rabbet' instead");
|
|
2421
|
+
return rabbetJoin(box, thickness, cutHeight);
|
|
2422
|
+
}
|
|
2423
|
+
function topMiddleBottom(box, thickness) {
|
|
2424
|
+
debug("TopMiddleBottom", box, thickness);
|
|
2425
|
+
var bottom = box.bisect("z", thickness, {
|
|
2426
|
+
color: true
|
|
2427
|
+
});
|
|
2428
|
+
var top = bottom.parts.positive.bisect("z", -thickness);
|
|
2429
|
+
return Group("top,middle,bottom", [ top.parts.positive, top.parts.negative.color("green"), bottom.parts.negative ]);
|
|
2430
|
+
}
|
|
2431
|
+
function Rabett(box, thickness, gap, height, face) {
|
|
2432
|
+
var options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
|
|
2433
|
+
debug("Rabett", "thickness", thickness, "gap", gap, "height", height, "face", face);
|
|
2434
|
+
gap = gap || .25;
|
|
2435
|
+
var inside = thickness - gap;
|
|
2436
|
+
var outside = -thickness + gap;
|
|
2437
|
+
var boxHeight = box.size().z;
|
|
2438
|
+
if (Math.abs(height) >= boxHeight) {
|
|
2439
|
+
throw new Error("Rabett: height (".concat(height, ") must be less than the object height (").concat(boxHeight, ")"));
|
|
2440
|
+
}
|
|
2441
|
+
debug("inside", inside, "outside", outside);
|
|
2442
|
+
var group = Group();
|
|
2443
|
+
var _box$bisect$parts = box.bisect("z", height, options).parts, top = _box$bisect$parts.positive, lower2_3rd = _box$bisect$parts.negative;
|
|
2444
|
+
var lowerBisectHeight = Math.sign(height) < 0 ? face * Math.sign(height) : height - face;
|
|
2445
|
+
var _lower2_3rd$bisect$pa = lower2_3rd.bisect("z", lowerBisectHeight, options).parts, middle = _lower2_3rd$bisect$pa.positive, bottom = _lower2_3rd$bisect$pa.negative;
|
|
2446
|
+
var middleTop = middle.color("yellow").subtract(middle.color("darkred").enlarge([ outside, outside, 0 ]));
|
|
2447
|
+
group.add(top.union(middleTop), "top");
|
|
2448
|
+
var bottomOutline = middle.color("yellow").subtract(middle.color("orange").enlarge([ outside, outside, 0 ])).enlarge([ outside, outside, 0 ]);
|
|
2449
|
+
group.add(bottomOutline, "middle-top", true);
|
|
2450
|
+
group.add(middle.color("green").subtract(middle.color("pink").enlarge([ inside, inside, 0 ])), "middle-bottom", true);
|
|
2451
|
+
group.add(bottom.color("orange").union(middle.color("green").subtract(middle.color("red").enlarge([ inside, inside, 0 ])).subtract(middleTop)), "bottom");
|
|
2452
|
+
return group;
|
|
2453
|
+
}
|
|
2454
|
+
var RabettTopBottom = function rabbetTMB(box, thickness) {
|
|
2455
|
+
var gap = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : .25;
|
|
2456
|
+
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
2457
|
+
options = Object.assign({
|
|
2458
|
+
removableTop: true,
|
|
2459
|
+
removableBottom: true,
|
|
2460
|
+
topWidth: -thickness,
|
|
2461
|
+
bottomWidth: thickness
|
|
2462
|
+
}, options);
|
|
2463
|
+
debug("RabettTopBottom", box, thickness, gap, options);
|
|
2464
|
+
var group = Group("", {
|
|
2465
|
+
box
|
|
2466
|
+
});
|
|
2467
|
+
var inside = -thickness - gap;
|
|
2468
|
+
var outside = -thickness + gap;
|
|
2469
|
+
if (options.removableTop) {
|
|
2470
|
+
var top = box.bisect("z", options.topWidth, {
|
|
2471
|
+
color: true
|
|
2472
|
+
});
|
|
2473
|
+
group.add(top.parts.positive.enlarge([ inside, inside, 0 ]), "top");
|
|
2474
|
+
if (!options.removableBottom) group.add(box.subtract(top.parts.positive.enlarge([ outside, outside, 0 ])), "bottom");
|
|
2475
|
+
}
|
|
2476
|
+
if (options.removableBottom) {
|
|
2477
|
+
var bottom = box.bisect("z", options.bottomWidth, {
|
|
2478
|
+
color: true
|
|
2479
|
+
});
|
|
2480
|
+
group.add(bottom.parts.negative.enlarge([ outside, outside, 0 ]), "bottomCutout", true);
|
|
2481
|
+
group.add(bottom.parts.negative.enlarge([ inside, inside, 0 ]), "bottom");
|
|
2482
|
+
if (!options.removableTop) group.add(box.subtract(group.parts.bottomCutout), "top");
|
|
2483
|
+
}
|
|
2484
|
+
if (options.removableBottom && options.removableTop) {
|
|
2485
|
+
group.add(box.subtract(union([ bottom.parts.negative.enlarge([ outside, outside, 0 ]), top.parts.positive.enlarge([ outside, outside, 0 ]) ])), "middle");
|
|
2486
|
+
}
|
|
2487
|
+
return group;
|
|
2488
|
+
};
|
|
2489
|
+
var CutOut = function cutOut(o, h, box, plug, gap) {
|
|
2490
|
+
gap = gap || .25;
|
|
2491
|
+
var s = o.size();
|
|
2492
|
+
var cutout = o.intersect(box);
|
|
2493
|
+
var cs = o.size();
|
|
2494
|
+
var clear = Parts.Cube([ s.x, s.y, h ]).align(o, "xy").color("yellow");
|
|
2495
|
+
var top = clear.snap(o, "z", "center+").union(o);
|
|
2496
|
+
var back = Parts.Cube([ cs.x + 6, 2, cs.z + 2.5 ]).align(cutout, "x").snap(cutout, "z", "center+").snap(cutout, "y", "outside-");
|
|
2497
|
+
var clip = Parts.Cube([ cs.x + 2 - gap, 1 - gap, cs.z + 2.5 ]).align(cutout, "x").snap(cutout, "z", "center+").snap(cutout, "y", "outside-");
|
|
2498
|
+
return Group("insert", {
|
|
2499
|
+
top,
|
|
2500
|
+
bottom: clear.snap(o, "z", "center-").union(o),
|
|
2501
|
+
cutout: union([ o, top ]),
|
|
2502
|
+
back: back.subtract(plug).subtract(clip.enlarge(gap, gap, gap)).subtract(clear.translate([ 0, 5, 0 ])),
|
|
2503
|
+
clip: clip.subtract(plug).color("red"),
|
|
2504
|
+
insert: union([ o, top ]).intersect(box).subtract(o).enlarge([ -gap, 0, 0 ]).union(clip.subtract(plug).enlarge(-gap, -gap, 0)).color("blue")
|
|
2505
|
+
});
|
|
2506
|
+
};
|
|
2507
|
+
var Rectangle = function Rectangle(size, thickness, cb) {
|
|
2508
|
+
thickness = thickness || 2;
|
|
2509
|
+
var s = div$1(xyz2array(size), 2);
|
|
2510
|
+
var r = add(s, thickness);
|
|
2511
|
+
var box = CSG$1.cube({
|
|
2512
|
+
center: r,
|
|
2513
|
+
radius: r
|
|
2514
|
+
}).subtract(CSG$1.cube({
|
|
2515
|
+
center: r,
|
|
2516
|
+
radius: s
|
|
2517
|
+
}));
|
|
2518
|
+
if (cb) box = cb(box);
|
|
2519
|
+
return box;
|
|
2520
|
+
};
|
|
2521
|
+
var Hollow = function Hollow(object, thickness, interiorcb, exteriorcb) {
|
|
2522
|
+
thickness = thickness || 2;
|
|
2523
|
+
var size = -thickness * 2;
|
|
2524
|
+
interiorcb = interiorcb || identity;
|
|
2525
|
+
var box = object.subtract(interiorcb(object.enlarge([ size, size, size ])));
|
|
2526
|
+
if (exteriorcb) box = exteriorcb(box);
|
|
2527
|
+
return box;
|
|
2528
|
+
};
|
|
2529
|
+
var BBox = function BBox(o) {
|
|
2530
|
+
depreciated("BBox", true, "Use 'parts.BBox' instead");
|
|
2531
|
+
var s = div$1(xyz2array(o.size()), 2);
|
|
2532
|
+
return CSG$1.cube({
|
|
2533
|
+
center: s,
|
|
2534
|
+
radius: s
|
|
2535
|
+
}).align(o, "xyz");
|
|
2536
|
+
};
|
|
2537
|
+
function getRadius(o) {
|
|
2538
|
+
return div$1(xyz2array(o.size()), 2);
|
|
2539
|
+
}
|
|
2540
|
+
function rabbetJoin(box, thickness) {
|
|
2541
|
+
var gap = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : .25;
|
|
2542
|
+
var r = add(getRadius(box), -thickness / 2);
|
|
2543
|
+
r[2] = thickness / 2;
|
|
2544
|
+
var cutter = CSG$1.cube({
|
|
2545
|
+
center: r,
|
|
2546
|
+
radius: r
|
|
2547
|
+
}).align(box, "xy").color("green");
|
|
2548
|
+
var topCutter = cutter.snap(box, "z", "inside+");
|
|
2549
|
+
var group = Group("", {
|
|
2550
|
+
topCutter,
|
|
2551
|
+
bottomCutter: cutter
|
|
2552
|
+
});
|
|
2553
|
+
group.add(box.subtract(cutter.enlarge([ gap, gap, 0 ])).color("blue"), "top");
|
|
2554
|
+
group.add(box.subtract(topCutter.enlarge([ gap, gap, 0 ])).color("red"), "bottom");
|
|
2555
|
+
return group;
|
|
2556
|
+
}
|
|
2557
|
+
var Boxes = Object.freeze({
|
|
2558
|
+
__proto__: null,
|
|
2559
|
+
RabbetJoin,
|
|
2560
|
+
topMiddleBottom,
|
|
2561
|
+
Rabett,
|
|
2562
|
+
RabettTopBottom,
|
|
2563
|
+
CutOut,
|
|
2564
|
+
Rectangle,
|
|
2565
|
+
Hollow,
|
|
2566
|
+
BBox
|
|
2567
|
+
});
|
|
2568
|
+
var compatV1 = _objectSpread2(_objectSpread2({}, util), {}, {
|
|
2569
|
+
group: Group,
|
|
2570
|
+
init: init$1,
|
|
2571
|
+
triangle: triUtils,
|
|
2572
|
+
array,
|
|
2573
|
+
parts: parts$1,
|
|
2574
|
+
Boxes,
|
|
2575
|
+
Debug
|
|
2576
|
+
});
|
|
2577
|
+
exports.Boxes = Boxes;
|
|
2578
|
+
exports.Debug = Debug;
|
|
2579
|
+
exports.Group = Group;
|
|
2580
|
+
exports.array = array;
|
|
2581
|
+
exports.compatV1 = compatV1;
|
|
2582
|
+
exports.init = init$1;
|
|
2583
|
+
exports.parts = parts$1;
|
|
2584
|
+
exports.triUtils = triUtils;
|
|
2585
|
+
exports.util = util;
|
|
2586
|
+
Object.defineProperty(exports, "__esModule", {
|
|
2587
|
+
value: true
|
|
2588
|
+
});
|
|
2589
|
+
return exports;
|
|
2590
|
+
}({}, jsCadCSG, scadApi);
|
|
2591
|
+
const debug = jscadUtils.Debug("jscadUtils:initJscadutils");
|
|
2592
|
+
util = jscadUtils.compatV1;
|
|
2593
|
+
util.init.default(CSG);
|
|
2594
|
+
debug("initJscadutils:jscadUtils", jscadUtils);
|
|
2595
|
+
Parts = jscadUtils.parts;
|
|
2596
|
+
Boxes = jscadUtils.Boxes;
|
|
2597
|
+
Group = jscadUtils.Group;
|
|
2598
|
+
Debug = jscadUtils.Debug;
|
|
2599
|
+
array = jscadUtils.array;
|
|
2600
|
+
triUtils = jscadUtils.triUtils;
|
|
2601
|
+
return jscadUtils;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
var jscadUtilsPluginInit = [];
|
|
2605
|
+
|
|
2606
|
+
var util = {
|
|
2607
|
+
init: (...a) => {
|
|
2608
|
+
initJscadutils(...a);
|
|
2609
|
+
jscadUtilsPluginInit.forEach(p => {
|
|
2610
|
+
p(...a);
|
|
2611
|
+
});
|
|
2612
|
+
}
|
|
2613
|
+
};
|
|
2614
|
+
// endinject
|