@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
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
function main() {
|
|
2
|
-
|
|
2
|
+
util.init(CSG, { debug: 'jscadUtils:boxes' });
|
|
3
|
+
|
|
4
|
+
var cyl = Parts.Cylinder(20, 20)
|
|
5
|
+
var cbox = Boxes.Hollow(cyl, 3, function (box) {
|
|
6
|
+
return box
|
|
7
|
+
.fillet(2, 'z+')
|
|
8
|
+
.fillet(2, 'z-');
|
|
9
|
+
});
|
|
10
|
+
var box = Boxes.Rabett(cbox, 3, 0.5, 11, 2)
|
|
11
|
+
return box.parts.top.translate([0, 0, 10]).union(box.parts.bottom);
|
|
3
12
|
|
|
4
|
-
var cyl = Parts.Cylinder(20, 20)
|
|
5
|
-
var cbox = Boxes.Hollow(cyl, 3, function (box) {
|
|
6
|
-
return box
|
|
7
|
-
.fillet(2, 'z+')
|
|
8
|
-
.fillet(2, 'z-');
|
|
9
|
-
});
|
|
10
|
-
var box = Boxes.Rabett(cbox, 3, 0.5, 11, 2)
|
|
11
|
-
return box.parts.top.translate([0, 0, 10]).union(box.parts.bottom);
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
// include:js
|
|
@@ -54,6 +55,8 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
54
55
|
enabled: [],
|
|
55
56
|
disabled: []
|
|
56
57
|
});
|
|
58
|
+
var jscadUtilsAssertValidCSGWarnings = options.assertValidCSGWarnings || false;
|
|
59
|
+
var jscadUtilsAssertValidCSG = options.assertValidCSG || false;
|
|
57
60
|
var jscadUtils = function(exports, jsCadCSG, scadApi) {
|
|
58
61
|
"use strict";
|
|
59
62
|
function _interopDefaultLegacy(e) {
|
|
@@ -287,6 +290,51 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
287
290
|
function _arrayWithHoles(r) {
|
|
288
291
|
if (Array.isArray(r)) return r;
|
|
289
292
|
}
|
|
293
|
+
function _createForOfIteratorHelper(r, e) {
|
|
294
|
+
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
295
|
+
if (!t) {
|
|
296
|
+
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
|
|
297
|
+
t && (r = t);
|
|
298
|
+
var n = 0, F = function() {};
|
|
299
|
+
return {
|
|
300
|
+
s: F,
|
|
301
|
+
n: function() {
|
|
302
|
+
return n >= r.length ? {
|
|
303
|
+
done: !0
|
|
304
|
+
} : {
|
|
305
|
+
done: !1,
|
|
306
|
+
value: r[n++]
|
|
307
|
+
};
|
|
308
|
+
},
|
|
309
|
+
e: function(r) {
|
|
310
|
+
throw r;
|
|
311
|
+
},
|
|
312
|
+
f: F
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
316
|
+
}
|
|
317
|
+
var o, a = !0, u = !1;
|
|
318
|
+
return {
|
|
319
|
+
s: function() {
|
|
320
|
+
t = t.call(r);
|
|
321
|
+
},
|
|
322
|
+
n: function() {
|
|
323
|
+
var r = t.next();
|
|
324
|
+
return a = r.done, r;
|
|
325
|
+
},
|
|
326
|
+
e: function(r) {
|
|
327
|
+
u = !0, o = r;
|
|
328
|
+
},
|
|
329
|
+
f: function() {
|
|
330
|
+
try {
|
|
331
|
+
a || null == t.return || t.return();
|
|
332
|
+
} finally {
|
|
333
|
+
if (u) throw o;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
}
|
|
290
338
|
function _defineProperty(e, r, t) {
|
|
291
339
|
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
292
340
|
value: t,
|
|
@@ -707,6 +755,219 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
707
755
|
c[3] = g || 1;
|
|
708
756
|
return o.setColor(c);
|
|
709
757
|
}
|
|
758
|
+
function validateCSG(csg, options) {
|
|
759
|
+
var errors = [];
|
|
760
|
+
var warnings = [];
|
|
761
|
+
if (!csg || !csg.polygons || csg.polygons.length === 0) {
|
|
762
|
+
errors.push("Empty mesh: no polygons");
|
|
763
|
+
return {
|
|
764
|
+
ok: false,
|
|
765
|
+
errors,
|
|
766
|
+
warnings
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
var opts = _objectSpread2({
|
|
770
|
+
fixTJunctions: true
|
|
771
|
+
}, options);
|
|
772
|
+
if (opts.fixTJunctions && typeof csg.canonicalized === "function") {
|
|
773
|
+
csg = csg.canonicalized();
|
|
774
|
+
if (typeof csg.reTesselated === "function") {
|
|
775
|
+
csg = csg.reTesselated();
|
|
776
|
+
}
|
|
777
|
+
if (typeof csg.fixTJunctions === "function") {
|
|
778
|
+
csg = csg.fixTJunctions();
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
var AREA_EPS = 1e-10;
|
|
782
|
+
var KEY_EPS = 1e-5;
|
|
783
|
+
var degenerateCount = 0;
|
|
784
|
+
var invalidVertexCount = 0;
|
|
785
|
+
var _iterator = _createForOfIteratorHelper(csg.polygons), _step;
|
|
786
|
+
try {
|
|
787
|
+
for (_iterator.s(); !(_step = _iterator.n()).done; ) {
|
|
788
|
+
var npoly = _step.value;
|
|
789
|
+
var _iterator4 = _createForOfIteratorHelper(npoly.vertices), _step4;
|
|
790
|
+
try {
|
|
791
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done; ) {
|
|
792
|
+
var nvert = _step4.value;
|
|
793
|
+
var np = nvert.pos;
|
|
794
|
+
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)) {
|
|
795
|
+
invalidVertexCount++;
|
|
796
|
+
break;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
} catch (err) {
|
|
800
|
+
_iterator4.e(err);
|
|
801
|
+
} finally {
|
|
802
|
+
_iterator4.f();
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
} catch (err) {
|
|
806
|
+
_iterator.e(err);
|
|
807
|
+
} finally {
|
|
808
|
+
_iterator.f();
|
|
809
|
+
}
|
|
810
|
+
if (invalidVertexCount > 0) {
|
|
811
|
+
errors.push(invalidVertexCount + " polygon(s) with invalid vertex coordinates (NaN or Infinity)");
|
|
812
|
+
}
|
|
813
|
+
function vtxKey(v) {
|
|
814
|
+
var p = v.pos;
|
|
815
|
+
return Math.round(p.x / KEY_EPS) + "," + Math.round(p.y / KEY_EPS) + "," + Math.round(p.z / KEY_EPS);
|
|
816
|
+
}
|
|
817
|
+
var validPolygons = [];
|
|
818
|
+
var _iterator2 = _createForOfIteratorHelper(csg.polygons), _step2;
|
|
819
|
+
try {
|
|
820
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) {
|
|
821
|
+
var poly = _step2.value;
|
|
822
|
+
var verts = poly.vertices;
|
|
823
|
+
var nv = verts.length;
|
|
824
|
+
if (nv < 3) {
|
|
825
|
+
degenerateCount++;
|
|
826
|
+
continue;
|
|
827
|
+
}
|
|
828
|
+
var hasInvalid = false;
|
|
829
|
+
var _iterator5 = _createForOfIteratorHelper(verts), _step5;
|
|
830
|
+
try {
|
|
831
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done; ) {
|
|
832
|
+
var vert = _step5.value;
|
|
833
|
+
var ip = vert.pos;
|
|
834
|
+
if (!Number.isFinite(ip.x) || !Number.isFinite(ip.y) || !Number.isFinite(ip.z)) {
|
|
835
|
+
hasInvalid = true;
|
|
836
|
+
break;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
} catch (err) {
|
|
840
|
+
_iterator5.e(err);
|
|
841
|
+
} finally {
|
|
842
|
+
_iterator5.f();
|
|
843
|
+
}
|
|
844
|
+
if (hasInvalid) continue;
|
|
845
|
+
var area = 0;
|
|
846
|
+
for (var ai = 0; ai < nv - 2; ai++) {
|
|
847
|
+
area += verts[ai + 1].pos.minus(verts[0].pos).cross(verts[ai + 2].pos.minus(verts[ai + 1].pos)).length();
|
|
848
|
+
}
|
|
849
|
+
area *= .5;
|
|
850
|
+
if (area < AREA_EPS) {
|
|
851
|
+
degenerateCount++;
|
|
852
|
+
continue;
|
|
853
|
+
}
|
|
854
|
+
validPolygons.push(poly);
|
|
855
|
+
}
|
|
856
|
+
} catch (err) {
|
|
857
|
+
_iterator2.e(err);
|
|
858
|
+
} finally {
|
|
859
|
+
_iterator2.f();
|
|
860
|
+
}
|
|
861
|
+
if (degenerateCount > 0) {
|
|
862
|
+
warnings.push(degenerateCount + " degenerate polygon(s) (fewer than 3 vertices or near-zero area)");
|
|
863
|
+
if (opts.fixTJunctions && typeof CSG !== "undefined") {
|
|
864
|
+
var cleaned = CSG.fromPolygons(validPolygons);
|
|
865
|
+
cleaned = cleaned.canonicalized();
|
|
866
|
+
if (typeof cleaned.reTesselated === "function") {
|
|
867
|
+
cleaned = cleaned.reTesselated();
|
|
868
|
+
}
|
|
869
|
+
if (typeof cleaned.fixTJunctions === "function") {
|
|
870
|
+
cleaned = cleaned.fixTJunctions();
|
|
871
|
+
}
|
|
872
|
+
validPolygons = [];
|
|
873
|
+
var _iterator3 = _createForOfIteratorHelper(cleaned.polygons), _step3;
|
|
874
|
+
try {
|
|
875
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done; ) {
|
|
876
|
+
var cpoly = _step3.value;
|
|
877
|
+
var cverts = cpoly.vertices;
|
|
878
|
+
var cnv = cverts.length;
|
|
879
|
+
if (cnv < 3) continue;
|
|
880
|
+
var carea = 0;
|
|
881
|
+
for (var cai = 0; cai < cnv - 2; cai++) {
|
|
882
|
+
carea += cverts[cai + 1].pos.minus(cverts[0].pos).cross(cverts[cai + 2].pos.minus(cverts[cai + 1].pos)).length();
|
|
883
|
+
}
|
|
884
|
+
carea *= .5;
|
|
885
|
+
if (carea < AREA_EPS) continue;
|
|
886
|
+
validPolygons.push(cpoly);
|
|
887
|
+
}
|
|
888
|
+
} catch (err) {
|
|
889
|
+
_iterator3.e(err);
|
|
890
|
+
} finally {
|
|
891
|
+
_iterator3.f();
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
var edgeCounts = {};
|
|
896
|
+
for (var _i = 0, _validPolygons = validPolygons; _i < _validPolygons.length; _i++) {
|
|
897
|
+
var vpoly = _validPolygons[_i];
|
|
898
|
+
var vverts = vpoly.vertices;
|
|
899
|
+
var vnv = vverts.length;
|
|
900
|
+
for (var ei = 0; ei < vnv; ei++) {
|
|
901
|
+
var v0 = vverts[ei];
|
|
902
|
+
var v1 = vverts[(ei + 1) % vnv];
|
|
903
|
+
var edgeKey = vtxKey(v0) + "/" + vtxKey(v1);
|
|
904
|
+
edgeCounts[edgeKey] = (edgeCounts[edgeKey] || 0) + 1;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
var unmatchedEdges = 0;
|
|
908
|
+
var nonManifoldEdges = 0;
|
|
909
|
+
var checked = {};
|
|
910
|
+
for (var _i2 = 0, _Object$keys = Object.keys(edgeCounts); _i2 < _Object$keys.length; _i2++) {
|
|
911
|
+
var _edgeKey = _Object$keys[_i2];
|
|
912
|
+
if (checked[_edgeKey]) continue;
|
|
913
|
+
var parts = _edgeKey.split("/");
|
|
914
|
+
var reverseKey = parts[1] + "/" + parts[0];
|
|
915
|
+
var forwardCount = edgeCounts[_edgeKey] || 0;
|
|
916
|
+
var reverseCount = edgeCounts[reverseKey] || 0;
|
|
917
|
+
checked[_edgeKey] = true;
|
|
918
|
+
checked[reverseKey] = true;
|
|
919
|
+
if (forwardCount !== reverseCount) {
|
|
920
|
+
unmatchedEdges += Math.abs(forwardCount - reverseCount);
|
|
921
|
+
}
|
|
922
|
+
if (forwardCount > 1 || reverseCount > 1) {
|
|
923
|
+
nonManifoldEdges++;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
if (unmatchedEdges > 0) {
|
|
927
|
+
errors.push(unmatchedEdges + " unmatched edge(s): mesh is not watertight");
|
|
928
|
+
}
|
|
929
|
+
if (nonManifoldEdges > 0) {
|
|
930
|
+
errors.push(nonManifoldEdges + " non-manifold edge(s): edge shared by more than 2 polygons");
|
|
931
|
+
}
|
|
932
|
+
return {
|
|
933
|
+
ok: errors.length === 0,
|
|
934
|
+
errors,
|
|
935
|
+
warnings
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
function _noOp(csg) {
|
|
939
|
+
return csg;
|
|
940
|
+
}
|
|
941
|
+
function _makeAssertFn(warnEnabled) {
|
|
942
|
+
return function _assert(csg) {
|
|
943
|
+
var functionName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "unknown";
|
|
944
|
+
var moduleName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "unknown";
|
|
945
|
+
if (!csg || csg.polygons === undefined) return csg;
|
|
946
|
+
var result = validateCSG(csg);
|
|
947
|
+
if (!result.ok) {
|
|
948
|
+
throw new Error(moduleName + ":" + functionName + ": " + "invalid CSG: " + result.errors.join(", "));
|
|
949
|
+
}
|
|
950
|
+
if (warnEnabled && result.warnings.length > 0) {
|
|
951
|
+
throw new Error(moduleName + ":" + functionName + ": " + "CSG warnings: " + result.warnings.join(", "));
|
|
952
|
+
}
|
|
953
|
+
return csg;
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
var _assertFn = _noOp;
|
|
957
|
+
function _resolveFromGlobals() {
|
|
958
|
+
var enabled = typeof jscadUtilsAssertValidCSG !== "undefined" && !!jscadUtilsAssertValidCSG;
|
|
959
|
+
var warnEnabled = typeof jscadUtilsAssertValidCSGWarnings !== "undefined" && !!jscadUtilsAssertValidCSGWarnings;
|
|
960
|
+
return enabled ? _makeAssertFn(warnEnabled) : _noOp;
|
|
961
|
+
}
|
|
962
|
+
function AssertValidCSG() {
|
|
963
|
+
var moduleName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "unknown";
|
|
964
|
+
{
|
|
965
|
+
_assertFn = _resolveFromGlobals();
|
|
966
|
+
}
|
|
967
|
+
return function(csg, name) {
|
|
968
|
+
return _assertFn(csg, name, moduleName);
|
|
969
|
+
};
|
|
970
|
+
}
|
|
710
971
|
function init(proto) {
|
|
711
972
|
if (proto.prototype._jscadutilsinit) return;
|
|
712
973
|
proto.prototype.color = function(r, g, b, a) {
|
|
@@ -800,6 +1061,9 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
800
1061
|
proto.prototype.subtractIf = function subtractIf(object, condition) {
|
|
801
1062
|
return condition ? this.subtract(result(this, object)) : this;
|
|
802
1063
|
};
|
|
1064
|
+
proto.prototype.validate = function validate(options) {
|
|
1065
|
+
return validateCSG(this, options);
|
|
1066
|
+
};
|
|
803
1067
|
proto.prototype._translate = proto.prototype.translate;
|
|
804
1068
|
proto.prototype.translate = function translate() {
|
|
805
1069
|
if (arguments.length === 1) {
|
|
@@ -832,12 +1096,13 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
832
1096
|
__proto__: null,
|
|
833
1097
|
default: init
|
|
834
1098
|
});
|
|
835
|
-
var CSG = jsCadCSG__default["default"].CSG, CAG = jsCadCSG__default["default"].CAG;
|
|
1099
|
+
var CSG$1 = jsCadCSG__default["default"].CSG, CAG = jsCadCSG__default["default"].CAG;
|
|
836
1100
|
var rectangular_extrude = scadApi__default["default"].extrusions.rectangular_extrude;
|
|
837
1101
|
var _scadApi$text = scadApi__default["default"].text, vector_text = _scadApi$text.vector_text, vector_char = _scadApi$text.vector_char;
|
|
838
1102
|
var union = scadApi__default["default"].booleanOps.union;
|
|
839
|
-
init(CSG);
|
|
1103
|
+
init(CSG$1);
|
|
840
1104
|
var debug$3 = Debug("jscadUtils:group");
|
|
1105
|
+
var assertValidCSG$2 = AssertValidCSG("group");
|
|
841
1106
|
function JsCadUtilsGroup() {
|
|
842
1107
|
var names = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
843
1108
|
var parts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
@@ -888,7 +1153,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
888
1153
|
debug$3("combine mapPick", value, key, object);
|
|
889
1154
|
return map ? map(value, key, index, object) : identity(value);
|
|
890
1155
|
}, self.name));
|
|
891
|
-
return g.subtractIf(self.holes && Array.isArray(self.holes) ? union(self.holes) : self.holes, self.holes && !options.noholes);
|
|
1156
|
+
return assertValidCSG$2(g.subtractIf(self.holes && Array.isArray(self.holes) ? union(self.holes) : self.holes, self.holes && !options.noholes), "combine");
|
|
892
1157
|
} catch (err) {
|
|
893
1158
|
debug$3("combine error", this, pieces, options, err);
|
|
894
1159
|
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");
|
|
@@ -929,7 +1194,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
929
1194
|
});
|
|
930
1195
|
if (self.holes) {
|
|
931
1196
|
group.holes = toArray(self.holes).map(function(part) {
|
|
932
|
-
return map(CSG.fromPolygons(part.toPolygons()), "holes");
|
|
1197
|
+
return assertValidCSG$2(map(CSG$1.fromPolygons(part.toPolygons()), "holes"), "clone");
|
|
933
1198
|
});
|
|
934
1199
|
}
|
|
935
1200
|
return group;
|
|
@@ -948,7 +1213,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
948
1213
|
var rotationCenter = solid.centroid();
|
|
949
1214
|
var rotationAxis = axes[axis];
|
|
950
1215
|
self.map(function(part) {
|
|
951
|
-
return part.rotate(rotationCenter, rotationAxis, angle);
|
|
1216
|
+
return assertValidCSG$2(part.rotate(rotationCenter, rotationAxis, angle), "rotate");
|
|
952
1217
|
});
|
|
953
1218
|
return self;
|
|
954
1219
|
};
|
|
@@ -961,7 +1226,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
961
1226
|
var self = this;
|
|
962
1227
|
var t = calcSnap(self.combine(part), to, axis, orientation, delta);
|
|
963
1228
|
self.map(function(part) {
|
|
964
|
-
return part.translate(t);
|
|
1229
|
+
return assertValidCSG$2(part.translate(t), "snap");
|
|
965
1230
|
});
|
|
966
1231
|
return self;
|
|
967
1232
|
} catch (err) {
|
|
@@ -976,7 +1241,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
976
1241
|
noholes: true
|
|
977
1242
|
}), axis, to, delta);
|
|
978
1243
|
self.map(function(part) {
|
|
979
|
-
return part.translate(t);
|
|
1244
|
+
return assertValidCSG$2(part.translate(t), "align");
|
|
980
1245
|
});
|
|
981
1246
|
return self;
|
|
982
1247
|
} catch (err) {
|
|
@@ -1008,14 +1273,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1008
1273
|
var myConnector = connectorName.split(".").reduce(function(a, v) {
|
|
1009
1274
|
return a[v];
|
|
1010
1275
|
}, self.parts[partName].properties);
|
|
1011
|
-
debug$3("toConnector", to instanceof CSG.Connector);
|
|
1276
|
+
debug$3("toConnector", to instanceof CSG$1.Connector);
|
|
1012
1277
|
var toConnector = toConnectorName.split(".").reduce(function(a, v) {
|
|
1013
1278
|
return a[v];
|
|
1014
1279
|
}, to.properties);
|
|
1015
1280
|
var matrix = myConnector.getTransformationTo(toConnector, mirror, normalrotation);
|
|
1016
1281
|
debug$3("connectTo", matrix);
|
|
1017
1282
|
self.map(function(part) {
|
|
1018
|
-
return part.transform(matrix);
|
|
1283
|
+
return assertValidCSG$2(part.transform(matrix), "connectTo");
|
|
1019
1284
|
});
|
|
1020
1285
|
return self;
|
|
1021
1286
|
};
|
|
@@ -1026,7 +1291,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1026
1291
|
return to - size[a] / 2;
|
|
1027
1292
|
});
|
|
1028
1293
|
self.map(function(part) {
|
|
1029
|
-
return part.translate(t);
|
|
1294
|
+
return assertValidCSG$2(part.translate(t), "midlineTo");
|
|
1030
1295
|
});
|
|
1031
1296
|
return self;
|
|
1032
1297
|
};
|
|
@@ -1035,7 +1300,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1035
1300
|
var t = Array.isArray(x) ? x : [ x, y, z ];
|
|
1036
1301
|
debug$3("translate", t);
|
|
1037
1302
|
self.map(function(part) {
|
|
1038
|
-
return part.translate(t);
|
|
1303
|
+
return assertValidCSG$2(part.translate(t), "translate");
|
|
1039
1304
|
});
|
|
1040
1305
|
return self;
|
|
1041
1306
|
};
|
|
@@ -1045,7 +1310,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1045
1310
|
if (!map) map = identity;
|
|
1046
1311
|
var g = Group();
|
|
1047
1312
|
p.forEach(function(name) {
|
|
1048
|
-
g.add(map(CSG.fromPolygons(self.parts[name].toPolygons()), name), name);
|
|
1313
|
+
g.add(assertValidCSG$2(map(CSG$1.fromPolygons(self.parts[name].toPolygons()), name), "pick"), name);
|
|
1049
1314
|
});
|
|
1050
1315
|
return g;
|
|
1051
1316
|
};
|
|
@@ -1060,7 +1325,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1060
1325
|
debug$3("array error", _this, parts);
|
|
1061
1326
|
throw error('group::array error "'.concat(name, '" not found.\nthis: ').concat(_this, '\nparts: "').concat(parts, '"\n'), "JSCAD_UTILS_GROUP_ERROR");
|
|
1062
1327
|
}
|
|
1063
|
-
a.push(map(CSG.fromPolygons(self.parts[name].toPolygons()), name));
|
|
1328
|
+
a.push(assertValidCSG$2(map(CSG$1.fromPolygons(self.parts[name].toPolygons()), name), "array"));
|
|
1064
1329
|
});
|
|
1065
1330
|
return a;
|
|
1066
1331
|
};
|
|
@@ -1093,7 +1358,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1093
1358
|
self.names = names && names.length > 0 && names.split(",") || [];
|
|
1094
1359
|
if (Array.isArray(objects)) {
|
|
1095
1360
|
self.parts = zipObject(self.names, objects);
|
|
1096
|
-
} else if (objects instanceof CSG) {
|
|
1361
|
+
} else if (objects instanceof CSG$1) {
|
|
1097
1362
|
self.parts = zipObject(self.names, [ objects ]);
|
|
1098
1363
|
} else {
|
|
1099
1364
|
self.parts = objects || {};
|
|
@@ -1114,6 +1379,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1114
1379
|
return new JsCadUtilsGroup(self.names, self.parts, self.holes);
|
|
1115
1380
|
}
|
|
1116
1381
|
var debug$2 = Debug("jscadUtils:util");
|
|
1382
|
+
var assertValidCSG$1 = AssertValidCSG("util");
|
|
1117
1383
|
var NOZZEL_SIZE = .4;
|
|
1118
1384
|
var nearest = {
|
|
1119
1385
|
under: function under(desired) {
|
|
@@ -1190,12 +1456,12 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1190
1456
|
h: height || 2
|
|
1191
1457
|
}));
|
|
1192
1458
|
});
|
|
1193
|
-
return center(union(o));
|
|
1459
|
+
return assertValidCSG$1(center(union(o)), "label");
|
|
1194
1460
|
}
|
|
1195
1461
|
function text(text) {
|
|
1196
1462
|
var l = vector_char(0, 0, text);
|
|
1197
1463
|
var _char = l.segments.reduce(function(result, segment) {
|
|
1198
|
-
var path = new CSG.Path2D(segment);
|
|
1464
|
+
var path = new CSG$1.Path2D(segment);
|
|
1199
1465
|
var cag = path.expandToCAG(2);
|
|
1200
1466
|
return result ? result.union(cag) : cag;
|
|
1201
1467
|
}, undefined);
|
|
@@ -1203,17 +1469,17 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1203
1469
|
}
|
|
1204
1470
|
function unitCube(length, radius) {
|
|
1205
1471
|
radius = radius || .5;
|
|
1206
|
-
return CSG.cube({
|
|
1472
|
+
return assertValidCSG$1(CSG$1.cube({
|
|
1207
1473
|
center: [ 0, 0, 0 ],
|
|
1208
1474
|
radius: [ radius, radius, length || .5 ]
|
|
1209
|
-
});
|
|
1475
|
+
}), "unitCube");
|
|
1210
1476
|
}
|
|
1211
1477
|
function unitAxis(length, radius, centroid) {
|
|
1212
1478
|
debug$2("unitAxis", length, radius, centroid);
|
|
1213
1479
|
centroid = centroid || [ 0, 0, 0 ];
|
|
1214
1480
|
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) ]);
|
|
1215
|
-
unitaxis.properties.origin = new CSG.Connector([ 0, 0, 0 ], [ 1, 0, 0 ], [ 0, 1, 0 ]);
|
|
1216
|
-
return unitaxis.translate(centroid);
|
|
1481
|
+
unitaxis.properties.origin = new CSG$1.Connector([ 0, 0, 0 ], [ 1, 0, 0 ], [ 0, 1, 0 ]);
|
|
1482
|
+
return assertValidCSG$1(unitaxis.translate(centroid), "unitAxis");
|
|
1217
1483
|
}
|
|
1218
1484
|
function toArray(a) {
|
|
1219
1485
|
return Array.isArray(a) ? a : [ a ];
|
|
@@ -1303,15 +1569,15 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1303
1569
|
}
|
|
1304
1570
|
function center(object, objectSize) {
|
|
1305
1571
|
objectSize = objectSize || size(object.getBounds());
|
|
1306
|
-
return centerY(centerX(object, objectSize), objectSize);
|
|
1572
|
+
return assertValidCSG$1(centerY(centerX(object, objectSize), objectSize), "center");
|
|
1307
1573
|
}
|
|
1308
1574
|
function centerY(object, objectSize) {
|
|
1309
1575
|
objectSize = objectSize || size(object.getBounds());
|
|
1310
|
-
return object.translate([ 0, -objectSize.y / 2, 0 ]);
|
|
1576
|
+
return assertValidCSG$1(object.translate([ 0, -objectSize.y / 2, 0 ]), "centerY");
|
|
1311
1577
|
}
|
|
1312
1578
|
function centerX(object, objectSize) {
|
|
1313
1579
|
objectSize = objectSize || size(object.getBounds());
|
|
1314
|
-
return object.translate([ -objectSize.x / 2, 0, 0 ]);
|
|
1580
|
+
return assertValidCSG$1(object.translate([ -objectSize.x / 2, 0, 0 ]), "centerX");
|
|
1315
1581
|
}
|
|
1316
1582
|
function enlarge(object, x, y, z) {
|
|
1317
1583
|
var a;
|
|
@@ -1329,7 +1595,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1329
1595
|
var new_object = object.scale(t);
|
|
1330
1596
|
var new_centroid = centroid(new_object);
|
|
1331
1597
|
var delta = new_centroid.minus(objectCentroid).times(-1);
|
|
1332
|
-
return new_object.translate(delta);
|
|
1598
|
+
return assertValidCSG$1(new_object.translate(delta), "enlarge");
|
|
1333
1599
|
}
|
|
1334
1600
|
function fit(object, x, y, z, keep_aspect_ratio) {
|
|
1335
1601
|
var a;
|
|
@@ -1349,10 +1615,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1349
1615
|
}
|
|
1350
1616
|
var s = [ scale(objectSize.x, x), scale(objectSize.y, y), scale(objectSize.z, z) ];
|
|
1351
1617
|
var min$1 = min(s);
|
|
1352
|
-
return centerWith(object.scale(s.map(function(d, i) {
|
|
1618
|
+
return assertValidCSG$1(centerWith(object.scale(s.map(function(d, i) {
|
|
1353
1619
|
if (a[i] === 0) return 1;
|
|
1354
1620
|
return keep_aspect_ratio ? min$1 : d;
|
|
1355
|
-
})), "xyz", object);
|
|
1621
|
+
})), "xyz", object), "fit");
|
|
1356
1622
|
}
|
|
1357
1623
|
function shift(object, x, y, z) {
|
|
1358
1624
|
var hsize = this.div(this.size(object.getBounds()), 2);
|
|
@@ -1360,10 +1626,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1360
1626
|
}
|
|
1361
1627
|
function zero(object) {
|
|
1362
1628
|
var bounds = object.getBounds();
|
|
1363
|
-
return object.translate([ 0, 0, -bounds[0].z ]);
|
|
1629
|
+
return assertValidCSG$1(object.translate([ 0, 0, -bounds[0].z ]), "zero");
|
|
1364
1630
|
}
|
|
1365
1631
|
function mirrored4(x) {
|
|
1366
|
-
return x.union([ x.mirroredY(90), x.mirroredX(90), x.mirroredY(90).mirroredX(90) ]);
|
|
1632
|
+
return assertValidCSG$1(x.union([ x.mirroredY(90), x.mirroredX(90), x.mirroredY(90).mirroredX(90) ]), "mirrored4");
|
|
1367
1633
|
}
|
|
1368
1634
|
var flushSide = {
|
|
1369
1635
|
"above-outside": [ 1, 0 ],
|
|
@@ -1424,10 +1690,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1424
1690
|
function snap(moveobj, withobj, axis, orientation, delta) {
|
|
1425
1691
|
debug$2("snap", moveobj, withobj, axis, orientation, delta);
|
|
1426
1692
|
var t = calcSnap(moveobj, withobj, axis, orientation, delta);
|
|
1427
|
-
return moveobj.translate(t);
|
|
1693
|
+
return assertValidCSG$1(moveobj.translate(t), "snap");
|
|
1428
1694
|
}
|
|
1429
1695
|
function flush(moveobj, withobj, axis, mside, wside) {
|
|
1430
|
-
return moveobj.translate(calcFlush(moveobj, withobj, axis, mside, wside));
|
|
1696
|
+
return assertValidCSG$1(moveobj.translate(calcFlush(moveobj, withobj, axis, mside, wside)), "flush");
|
|
1431
1697
|
}
|
|
1432
1698
|
function axisApply(axes, valfun, a) {
|
|
1433
1699
|
debug$2("axisApply", axes, valfun, a);
|
|
@@ -1443,7 +1709,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1443
1709
|
return retval;
|
|
1444
1710
|
}
|
|
1445
1711
|
function axis2array(axes, valfun) {
|
|
1446
|
-
depreciated("axis2array");
|
|
1712
|
+
depreciated("axis2array", false, "Use axisApply instead.");
|
|
1447
1713
|
var a = [ 0, 0, 0 ];
|
|
1448
1714
|
var lookup = {
|
|
1449
1715
|
x: 0,
|
|
@@ -1473,7 +1739,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1473
1739
|
});
|
|
1474
1740
|
}
|
|
1475
1741
|
function midlineTo(o, axis, to) {
|
|
1476
|
-
return o.translate(calcmidlineTo(o, axis, to));
|
|
1742
|
+
return assertValidCSG$1(o.translate(calcmidlineTo(o, axis, to)), "midlineTo");
|
|
1477
1743
|
}
|
|
1478
1744
|
function translator(o, axis, withObj) {
|
|
1479
1745
|
var objectCentroid = centroid(o);
|
|
@@ -1493,7 +1759,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1493
1759
|
return delta ? add(t, delta) : t;
|
|
1494
1760
|
}
|
|
1495
1761
|
function centerWith(o, axis, withObj) {
|
|
1496
|
-
return o.translate(calcCenterWith(o, axis, withObj));
|
|
1762
|
+
return assertValidCSG$1(o.translate(calcCenterWith(o, axis, withObj)), "centerWith");
|
|
1497
1763
|
}
|
|
1498
1764
|
function getDelta(size, bounds, axis, offset, nonzero) {
|
|
1499
1765
|
if (!isEmpty(offset) && nonzero) {
|
|
@@ -1506,6 +1772,95 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1506
1772
|
return bounds[0][a] + (isEmpty(dist) ? size[axis] / 2 : dist);
|
|
1507
1773
|
});
|
|
1508
1774
|
}
|
|
1775
|
+
var EPS = 1e-5;
|
|
1776
|
+
function splitCSGByPlane(csg, plane) {
|
|
1777
|
+
var frontPolys = [];
|
|
1778
|
+
var backPolys = [];
|
|
1779
|
+
csg.polygons.forEach(function(poly) {
|
|
1780
|
+
var vertices = poly.vertices;
|
|
1781
|
+
var numVerts = vertices.length;
|
|
1782
|
+
var hasfront = false;
|
|
1783
|
+
var hasback = false;
|
|
1784
|
+
var vertexIsBack = [];
|
|
1785
|
+
for (var i = 0; i < numVerts; i++) {
|
|
1786
|
+
var t = plane.normal.dot(vertices[i].pos) - plane.w;
|
|
1787
|
+
vertexIsBack.push(t < 0);
|
|
1788
|
+
if (t > EPS) hasfront = true;
|
|
1789
|
+
if (t < -EPS) hasback = true;
|
|
1790
|
+
}
|
|
1791
|
+
if (!hasfront && !hasback) {
|
|
1792
|
+
var d = plane.normal.dot(poly.plane.normal);
|
|
1793
|
+
if (d >= 0) {
|
|
1794
|
+
frontPolys.push(poly);
|
|
1795
|
+
} else {
|
|
1796
|
+
backPolys.push(poly);
|
|
1797
|
+
}
|
|
1798
|
+
} else if (!hasback) {
|
|
1799
|
+
frontPolys.push(poly);
|
|
1800
|
+
} else if (!hasfront) {
|
|
1801
|
+
backPolys.push(poly);
|
|
1802
|
+
} else {
|
|
1803
|
+
var fv = [];
|
|
1804
|
+
var bv = [];
|
|
1805
|
+
for (var vi = 0; vi < numVerts; vi++) {
|
|
1806
|
+
var vertex = vertices[vi];
|
|
1807
|
+
var nextVi = (vi + 1) % numVerts;
|
|
1808
|
+
var isback = vertexIsBack[vi];
|
|
1809
|
+
var nextisback = vertexIsBack[nextVi];
|
|
1810
|
+
if (isback === nextisback) {
|
|
1811
|
+
if (isback) {
|
|
1812
|
+
bv.push(vertex);
|
|
1813
|
+
} else {
|
|
1814
|
+
fv.push(vertex);
|
|
1815
|
+
}
|
|
1816
|
+
} else {
|
|
1817
|
+
var point = vertex.pos;
|
|
1818
|
+
var nextpoint = vertices[nextVi].pos;
|
|
1819
|
+
var ip = plane.splitLineBetweenPoints(point, nextpoint);
|
|
1820
|
+
var iv = new CSG$1.Vertex(ip);
|
|
1821
|
+
if (isback) {
|
|
1822
|
+
bv.push(vertex);
|
|
1823
|
+
bv.push(iv);
|
|
1824
|
+
fv.push(iv);
|
|
1825
|
+
} else {
|
|
1826
|
+
fv.push(vertex);
|
|
1827
|
+
fv.push(iv);
|
|
1828
|
+
bv.push(iv);
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
var EPSEPS = EPS * EPS;
|
|
1833
|
+
if (fv.length >= 3) {
|
|
1834
|
+
var prev = fv[fv.length - 1];
|
|
1835
|
+
for (var fi = 0; fi < fv.length; fi++) {
|
|
1836
|
+
var curr = fv[fi];
|
|
1837
|
+
if (curr.pos.distanceToSquared(prev.pos) < EPSEPS) {
|
|
1838
|
+
fv.splice(fi, 1);
|
|
1839
|
+
fi--;
|
|
1840
|
+
}
|
|
1841
|
+
prev = curr;
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
if (bv.length >= 3) {
|
|
1845
|
+
var prev = bv[bv.length - 1];
|
|
1846
|
+
for (var bi = 0; bi < bv.length; bi++) {
|
|
1847
|
+
var curr = bv[bi];
|
|
1848
|
+
if (curr.pos.distanceToSquared(prev.pos) < EPSEPS) {
|
|
1849
|
+
bv.splice(bi, 1);
|
|
1850
|
+
bi--;
|
|
1851
|
+
}
|
|
1852
|
+
prev = curr;
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
if (fv.length >= 3) frontPolys.push(new CSG$1.Polygon(fv, poly.shared, poly.plane));
|
|
1856
|
+
if (bv.length >= 3) backPolys.push(new CSG$1.Polygon(bv, poly.shared, poly.plane));
|
|
1857
|
+
}
|
|
1858
|
+
});
|
|
1859
|
+
return {
|
|
1860
|
+
front: CSG$1.fromPolygons(frontPolys),
|
|
1861
|
+
back: CSG$1.fromPolygons(backPolys)
|
|
1862
|
+
};
|
|
1863
|
+
}
|
|
1509
1864
|
function bisect() {
|
|
1510
1865
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1511
1866
|
args[_key] = arguments[_key];
|
|
@@ -1567,13 +1922,13 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1567
1922
|
}[[ axis, rotateaxis ].sort().join("")];
|
|
1568
1923
|
var centroid = object.centroid();
|
|
1569
1924
|
var rotateDelta = getDelta(objectSize, bounds, rotateOffsetAxis, rotateoffset);
|
|
1570
|
-
var rotationCenter = options.rotationCenter || new CSG.Vector3D(axisApply("xyz", function(i, a) {
|
|
1925
|
+
var rotationCenter = options.rotationCenter || new CSG$1.Vector3D(axisApply("xyz", function(i, a) {
|
|
1571
1926
|
if (a == axis) return cutDelta[i];
|
|
1572
1927
|
if (a == rotateOffsetAxis) return rotateDelta[i];
|
|
1573
1928
|
return centroid[a];
|
|
1574
1929
|
}));
|
|
1575
1930
|
var theRotationAxis = rotationAxes[rotateaxis];
|
|
1576
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).translate(cutDelta).rotate(rotationCenter, theRotationAxis, angle);
|
|
1931
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).translate(cutDelta).rotate(rotationCenter, theRotationAxis, angle);
|
|
1577
1932
|
debug$2("bisect", debug$2.enabled && {
|
|
1578
1933
|
axis,
|
|
1579
1934
|
offset,
|
|
@@ -1586,7 +1941,26 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1586
1941
|
cutplane,
|
|
1587
1942
|
options
|
|
1588
1943
|
});
|
|
1589
|
-
var
|
|
1944
|
+
var negative = object.cutByPlane(cutplane.plane);
|
|
1945
|
+
var positive = object.cutByPlane(cutplane.plane.flipped());
|
|
1946
|
+
var negSize = size(negative);
|
|
1947
|
+
var posSize = size(positive);
|
|
1948
|
+
if (negSize[axis] >= objectSize[axis] - EPS || posSize[axis] >= objectSize[axis] - EPS) {
|
|
1949
|
+
var halves = splitCSGByPlane(object, cutplane.plane);
|
|
1950
|
+
if (negSize[axis] >= objectSize[axis] - EPS) {
|
|
1951
|
+
negative = halves.back;
|
|
1952
|
+
try {
|
|
1953
|
+
negative = negative.cutByPlane(cutplane.plane);
|
|
1954
|
+
} catch (e) {}
|
|
1955
|
+
}
|
|
1956
|
+
if (posSize[axis] >= objectSize[axis] - EPS) {
|
|
1957
|
+
positive = halves.front;
|
|
1958
|
+
try {
|
|
1959
|
+
positive = positive.cutByPlane(cutplane.plane.flipped());
|
|
1960
|
+
} catch (e) {}
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
var g = Group("negative,positive", [ negative.color(options.color && "red"), positive.color(options.color && "blue") ]);
|
|
1590
1964
|
if (options.addRotationCenter) g.add(unitAxis(objectSize.length() + 10, .1, rotationCenter), "rotationCenter");
|
|
1591
1965
|
return g;
|
|
1592
1966
|
}
|
|
@@ -1599,9 +1973,9 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1599
1973
|
addRotationCenter: true
|
|
1600
1974
|
};
|
|
1601
1975
|
var info = normalVector(axis);
|
|
1602
|
-
var rotationCenter = options.rotationCenter || new CSG.Vector3D(0, 0, 0);
|
|
1976
|
+
var rotationCenter = options.rotationCenter || new CSG$1.Vector3D(0, 0, 0);
|
|
1603
1977
|
var theRotationAxis = rotationAxes[rotateaxis];
|
|
1604
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).rotate(rotationCenter, theRotationAxis, angle);
|
|
1978
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).rotate(rotationCenter, theRotationAxis, angle);
|
|
1605
1979
|
var g = Group("negative,positive", [ object.cutByPlane(cutplane.plane).color(options.color && "red"), object.cutByPlane(cutplane.plane.flipped()).color(options.color && "blue") ]);
|
|
1606
1980
|
if (options.addRotationCenter) {
|
|
1607
1981
|
var objectSize = size(object);
|
|
@@ -1626,14 +2000,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1626
2000
|
var bounds = object.getBounds();
|
|
1627
2001
|
var objectSize = size(object);
|
|
1628
2002
|
var cutDelta = getDelta(objectSize, bounds, axis, offset, true);
|
|
1629
|
-
return object.stretchAtPlane(normal[axis], cutDelta, distance);
|
|
2003
|
+
return assertValidCSG$1(object.stretchAtPlane(normal[axis], cutDelta, distance), "stretch");
|
|
1630
2004
|
}
|
|
1631
2005
|
function poly2solid(top, bottom, height) {
|
|
1632
2006
|
if (top.sides.length == 0) {
|
|
1633
|
-
return new CSG;
|
|
2007
|
+
return new CSG$1;
|
|
1634
2008
|
}
|
|
1635
|
-
var offsetVector = CSG.Vector3D.Create(0, 0, height);
|
|
1636
|
-
var normalVector = CSG.Vector3D.Create(0, 1, 0);
|
|
2009
|
+
var offsetVector = CSG$1.Vector3D.Create(0, 0, height);
|
|
2010
|
+
var normalVector = CSG$1.Vector3D.Create(0, 1, 0);
|
|
1637
2011
|
var polygons = [];
|
|
1638
2012
|
polygons = polygons.concat(bottom._toPlanePolygons({
|
|
1639
2013
|
translation: [ 0, 0, 0 ],
|
|
@@ -1645,14 +2019,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1645
2019
|
normalVector,
|
|
1646
2020
|
flipped: offsetVector.z < 0
|
|
1647
2021
|
}));
|
|
1648
|
-
var c1 = new CSG.Connector(offsetVector.times(0), [ 0, 0, offsetVector.z ], normalVector);
|
|
1649
|
-
var c2 = new CSG.Connector(offsetVector, [ 0, 0, offsetVector.z ], normalVector);
|
|
2022
|
+
var c1 = new CSG$1.Connector(offsetVector.times(0), [ 0, 0, offsetVector.z ], normalVector);
|
|
2023
|
+
var c2 = new CSG$1.Connector(offsetVector, [ 0, 0, offsetVector.z ], normalVector);
|
|
1650
2024
|
polygons = polygons.concat(bottom._toWallPolygons({
|
|
1651
2025
|
cag: top,
|
|
1652
2026
|
toConnector1: c1,
|
|
1653
2027
|
toConnector2: c2
|
|
1654
2028
|
}));
|
|
1655
|
-
return CSG.fromPolygons(polygons);
|
|
2029
|
+
return assertValidCSG$1(CSG$1.fromPolygons(polygons), "poly2solid");
|
|
1656
2030
|
}
|
|
1657
2031
|
function slices2poly(slices, options, axis) {
|
|
1658
2032
|
debug$2("slices2poly", slices, options, axis);
|
|
@@ -1661,7 +2035,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1661
2035
|
twiststeps: 0
|
|
1662
2036
|
}, options);
|
|
1663
2037
|
var twistangle = options && parseFloat(options.twistangle) || 0;
|
|
1664
|
-
options && parseInt(options.twiststeps) || CSG.defaultResolution3D;
|
|
2038
|
+
options && parseInt(options.twiststeps) || CSG$1.defaultResolution3D;
|
|
1665
2039
|
var normalVector = options.si.normalVector;
|
|
1666
2040
|
var polygons = [];
|
|
1667
2041
|
var first$1 = first(slices);
|
|
@@ -1690,8 +2064,8 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1690
2064
|
var nextidx = idx + 1;
|
|
1691
2065
|
var top = !up ? slices[nextidx] : slice;
|
|
1692
2066
|
var bottom = up ? slices[nextidx] : slice;
|
|
1693
|
-
var c1 = new CSG.Connector(bottom.offset, connectorAxis, rotate(normalVector, twistangle, idx / slices.length));
|
|
1694
|
-
var c2 = new CSG.Connector(top.offset, connectorAxis, rotate(normalVector, twistangle, nextidx / slices.length));
|
|
2067
|
+
var c1 = new CSG$1.Connector(bottom.offset, connectorAxis, rotate(normalVector, twistangle, idx / slices.length));
|
|
2068
|
+
var c2 = new CSG$1.Connector(top.offset, connectorAxis, rotate(normalVector, twistangle, nextidx / slices.length));
|
|
1695
2069
|
polygons = polygons.concat(bottom.poly._toWallPolygons({
|
|
1696
2070
|
cag: top.poly,
|
|
1697
2071
|
toConnector1: c1,
|
|
@@ -1699,21 +2073,21 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1699
2073
|
}));
|
|
1700
2074
|
}
|
|
1701
2075
|
});
|
|
1702
|
-
return CSG.fromPolygons(polygons);
|
|
2076
|
+
return assertValidCSG$1(CSG$1.fromPolygons(polygons), "slices2poly");
|
|
1703
2077
|
}
|
|
1704
2078
|
function normalVector(axis) {
|
|
1705
2079
|
var axisInfo = {
|
|
1706
2080
|
z: {
|
|
1707
2081
|
orthoNormalCartesian: [ "X", "Y" ],
|
|
1708
|
-
normalVector: CSG.Vector3D.Create(0, 1, 0)
|
|
2082
|
+
normalVector: CSG$1.Vector3D.Create(0, 1, 0)
|
|
1709
2083
|
},
|
|
1710
2084
|
x: {
|
|
1711
2085
|
orthoNormalCartesian: [ "Y", "Z" ],
|
|
1712
|
-
normalVector: CSG.Vector3D.Create(0, 0, 1)
|
|
2086
|
+
normalVector: CSG$1.Vector3D.Create(0, 0, 1)
|
|
1713
2087
|
},
|
|
1714
2088
|
y: {
|
|
1715
|
-
orthoNormalCartesian: [ "
|
|
1716
|
-
normalVector: CSG.Vector3D.Create(0, 0, 1)
|
|
2089
|
+
orthoNormalCartesian: [ "Z", "X" ],
|
|
2090
|
+
normalVector: CSG$1.Vector3D.Create(0, 0, 1)
|
|
1717
2091
|
}
|
|
1718
2092
|
};
|
|
1719
2093
|
if (!axisInfo[axis]) error("normalVector: invalid axis " + axis);
|
|
@@ -1754,7 +2128,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1754
2128
|
var si = sliceParams(orientation, radius, b);
|
|
1755
2129
|
debug$2("reShape", absoluteRadius, si);
|
|
1756
2130
|
if (si.axis !== "z") throw new Error('reShape error: CAG._toPlanePolygons only uses the "z" axis. You must use the "z" axis for now.');
|
|
1757
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(si.orthoNormalCartesian[0], si.orthoNormalCartesian[1]).translate(si.cutDelta);
|
|
2131
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(si.orthoNormalCartesian[0], si.orthoNormalCartesian[1]).translate(si.cutDelta);
|
|
1758
2132
|
var slice = object.sectionCut(cutplane);
|
|
1759
2133
|
var first = axisApply(si.axis, function() {
|
|
1760
2134
|
return si.positive ? 0 : absoluteRadius;
|
|
@@ -1769,25 +2143,25 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1769
2143
|
si
|
|
1770
2144
|
}), si.axis).color(options.color);
|
|
1771
2145
|
var remainder = object.cutByPlane(plane);
|
|
1772
|
-
return union([ options.unionOriginal ? object : remainder, delta.translate(si.moveDelta) ]);
|
|
2146
|
+
return assertValidCSG$1(union([ options.unionOriginal ? object : remainder, delta.translate(si.moveDelta) ]), "reShape");
|
|
1773
2147
|
}
|
|
1774
2148
|
function chamfer(object, radius, orientation, options) {
|
|
1775
|
-
return reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
2149
|
+
return assertValidCSG$1(reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
1776
2150
|
return [ {
|
|
1777
2151
|
poly: slice,
|
|
1778
|
-
offset: new CSG.Vector3D(first)
|
|
2152
|
+
offset: new CSG$1.Vector3D(first)
|
|
1779
2153
|
}, {
|
|
1780
2154
|
poly: enlarge(slice, [ -radius * 2, -radius * 2 ]),
|
|
1781
|
-
offset: new CSG.Vector3D(last)
|
|
2155
|
+
offset: new CSG$1.Vector3D(last)
|
|
1782
2156
|
} ];
|
|
1783
|
-
});
|
|
2157
|
+
}), "chamfer");
|
|
1784
2158
|
}
|
|
1785
2159
|
function fillet(object, radius, orientation, options) {
|
|
1786
2160
|
options = options || {};
|
|
1787
|
-
return reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
1788
|
-
var v1 = new CSG.Vector3D(first);
|
|
1789
|
-
var v2 = new CSG.Vector3D(last);
|
|
1790
|
-
var res = options.resolution || CSG.defaultResolution3D;
|
|
2161
|
+
return assertValidCSG$1(reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
2162
|
+
var v1 = new CSG$1.Vector3D(first);
|
|
2163
|
+
var v2 = new CSG$1.Vector3D(last);
|
|
2164
|
+
var res = options.resolution || CSG$1.defaultResolution3D;
|
|
1791
2165
|
var slices = range(0, res).map(function(i) {
|
|
1792
2166
|
var p = i > 0 ? i / (res - 1) : 0;
|
|
1793
2167
|
var v = v1.lerp(v2, p);
|
|
@@ -1798,7 +2172,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1798
2172
|
};
|
|
1799
2173
|
});
|
|
1800
2174
|
return slices;
|
|
1801
|
-
});
|
|
2175
|
+
}), "fillet");
|
|
1802
2176
|
}
|
|
1803
2177
|
function calcRotate(part, solid, axis) {
|
|
1804
2178
|
var axes = {
|
|
@@ -1815,7 +2189,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1815
2189
|
}
|
|
1816
2190
|
function rotateAround(part, solid, axis, angle) {
|
|
1817
2191
|
var _calcRotate = calcRotate(part, solid, axis), rotationCenter = _calcRotate.rotationCenter, rotationAxis = _calcRotate.rotationAxis;
|
|
1818
|
-
return part.rotate(rotationCenter, rotationAxis, angle);
|
|
2192
|
+
return assertValidCSG$1("rotateAround")(part.rotate(rotationCenter, rotationAxis, angle));
|
|
1819
2193
|
}
|
|
1820
2194
|
function cloneProperties(from, to) {
|
|
1821
2195
|
return Object.entries(from).reduce(function(props, _ref) {
|
|
@@ -1825,19 +2199,20 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1825
2199
|
}, to);
|
|
1826
2200
|
}
|
|
1827
2201
|
function clone(o) {
|
|
1828
|
-
var c = CSG.fromPolygons(o.toPolygons());
|
|
2202
|
+
var c = CSG$1.fromPolygons(o.toPolygons());
|
|
1829
2203
|
cloneProperties(o, c);
|
|
1830
|
-
debug$2("clone", o, c, CSG);
|
|
1831
|
-
return c;
|
|
2204
|
+
debug$2("clone", o, c, CSG$1);
|
|
2205
|
+
return assertValidCSG$1(c, "clone");
|
|
1832
2206
|
}
|
|
1833
2207
|
function addConnector(object, name) {
|
|
1834
2208
|
var point = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [ 0, 0, 0 ];
|
|
1835
2209
|
var axis = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [ 1, 0, 0 ];
|
|
1836
2210
|
var normal = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [ 0, 0, 1 ];
|
|
1837
|
-
object.properties[name] = new CSG.Connector(point, axis, normal);
|
|
1838
|
-
return object;
|
|
2211
|
+
object.properties[name] = new CSG$1.Connector(point, axis, normal);
|
|
2212
|
+
return assertValidCSG$1("addConnector")(object);
|
|
1839
2213
|
}
|
|
1840
2214
|
var debug$1 = Debug("jscadUtils:parts");
|
|
2215
|
+
var assertValidCSG = AssertValidCSG("parts");
|
|
1841
2216
|
var parts = {
|
|
1842
2217
|
BBox: BBox$1,
|
|
1843
2218
|
Cube,
|
|
@@ -1847,7 +2222,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1847
2222
|
};
|
|
1848
2223
|
function BBox$1() {
|
|
1849
2224
|
function box(object) {
|
|
1850
|
-
return CSG.cube({
|
|
2225
|
+
return CSG$1.cube({
|
|
1851
2226
|
center: object.centroid(),
|
|
1852
2227
|
radius: object.size().dividedBy(2)
|
|
1853
2228
|
});
|
|
@@ -1855,17 +2230,17 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1855
2230
|
for (var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1856
2231
|
objects[_key] = arguments[_key];
|
|
1857
2232
|
}
|
|
1858
|
-
return objects.reduce(function(bbox, part) {
|
|
2233
|
+
return assertValidCSG(objects.reduce(function(bbox, part) {
|
|
1859
2234
|
var object = bbox ? union([ bbox, box(part) ]) : part;
|
|
1860
2235
|
return box(object);
|
|
1861
|
-
}, undefined);
|
|
2236
|
+
}, undefined), "BBox");
|
|
1862
2237
|
}
|
|
1863
2238
|
function Cube(width) {
|
|
1864
2239
|
var r = div$1(fromxyz(width), 2);
|
|
1865
|
-
return CSG.cube({
|
|
2240
|
+
return assertValidCSG(CSG$1.cube({
|
|
1866
2241
|
center: r,
|
|
1867
2242
|
radius: r
|
|
1868
|
-
});
|
|
2243
|
+
}), "Cube");
|
|
1869
2244
|
}
|
|
1870
2245
|
function RoundedCube(x, y, thickness, corner_radius) {
|
|
1871
2246
|
if (x.getBounds) {
|
|
@@ -1881,11 +2256,11 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1881
2256
|
center: [ r[0], r[1], 0 ],
|
|
1882
2257
|
radius: r,
|
|
1883
2258
|
roundradius: corner_radius,
|
|
1884
|
-
resolution: CSG.defaultResolution2D
|
|
2259
|
+
resolution: CSG$1.defaultResolution2D
|
|
1885
2260
|
}).extrude({
|
|
1886
2261
|
offset: [ 0, 0, thickness || 1.62 ]
|
|
1887
2262
|
});
|
|
1888
|
-
return roundedcube;
|
|
2263
|
+
return assertValidCSG(roundedcube, "RoundedCube");
|
|
1889
2264
|
}
|
|
1890
2265
|
function Cylinder(diameter, height) {
|
|
1891
2266
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
@@ -1894,39 +2269,39 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1894
2269
|
start: [ 0, 0, 0 ],
|
|
1895
2270
|
end: [ 0, 0, height ],
|
|
1896
2271
|
radius: diameter / 2,
|
|
1897
|
-
resolution: CSG.defaultResolution2D
|
|
2272
|
+
resolution: CSG$1.defaultResolution2D
|
|
1898
2273
|
}, options);
|
|
1899
|
-
return CSG.cylinder(options);
|
|
2274
|
+
return assertValidCSG(CSG$1.cylinder(options), "Cylinder");
|
|
1900
2275
|
}
|
|
1901
2276
|
function Cone(diameter1, diameter2, height) {
|
|
1902
2277
|
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
1903
2278
|
debug$1("parts.Cone", diameter1, diameter2, height, options);
|
|
1904
|
-
return CSG.cylinder(Object.assign({
|
|
2279
|
+
return assertValidCSG(CSG$1.cylinder(Object.assign({
|
|
1905
2280
|
start: [ 0, 0, 0 ],
|
|
1906
2281
|
end: [ 0, 0, height ],
|
|
1907
2282
|
radiusStart: diameter1 / 2,
|
|
1908
2283
|
radiusEnd: diameter2 / 2,
|
|
1909
|
-
resolution: CSG.defaultResolution2D
|
|
1910
|
-
}, options));
|
|
2284
|
+
resolution: CSG$1.defaultResolution2D
|
|
2285
|
+
}, options)), "Cone");
|
|
1911
2286
|
}
|
|
1912
2287
|
function Hexagon(diameter, height) {
|
|
1913
2288
|
debug$1("hexagon", diameter, height);
|
|
1914
2289
|
var radius = diameter / 2;
|
|
1915
2290
|
var sqrt3 = Math.sqrt(3) / 2;
|
|
1916
2291
|
var hex = CAG.fromPoints([ [ radius, 0 ], [ radius / 2, radius * sqrt3 ], [ -radius / 2, radius * sqrt3 ], [ -radius, 0 ], [ -radius / 2, -radius * sqrt3 ], [ radius / 2, -radius * sqrt3 ] ]);
|
|
1917
|
-
return hex.extrude({
|
|
2292
|
+
return assertValidCSG(hex.extrude({
|
|
1918
2293
|
offset: [ 0, 0, height ]
|
|
1919
|
-
});
|
|
2294
|
+
}), "Hexagon");
|
|
1920
2295
|
}
|
|
1921
2296
|
function Triangle(base, height) {
|
|
1922
2297
|
var radius = base / 2;
|
|
1923
2298
|
var tri = CAG.fromPoints([ [ -radius, 0 ], [ radius, 0 ], [ 0, Math.sin(30) * radius ] ]);
|
|
1924
|
-
return tri.extrude({
|
|
2299
|
+
return assertValidCSG(tri.extrude({
|
|
1925
2300
|
offset: [ 0, 0, height ]
|
|
1926
|
-
});
|
|
2301
|
+
}), "Triangle");
|
|
1927
2302
|
}
|
|
1928
2303
|
function Tube(outsideDiameter, insideDiameter, height, outsideOptions, insideOptions) {
|
|
1929
|
-
return Cylinder(outsideDiameter, height, outsideOptions).subtract(Cylinder(insideDiameter, height, insideOptions || outsideOptions));
|
|
2304
|
+
return assertValidCSG(Cylinder(outsideDiameter, height, outsideOptions).subtract(Cylinder(insideDiameter, height, insideOptions || outsideOptions)), "Tube");
|
|
1930
2305
|
}
|
|
1931
2306
|
function Anchor() {
|
|
1932
2307
|
var width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
|
|
@@ -1944,11 +2319,11 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1944
2319
|
center: [ r[0], r[1], 0 ],
|
|
1945
2320
|
radius: r,
|
|
1946
2321
|
roundradius: corner_radius,
|
|
1947
|
-
resolution: CSG.defaultResolution2D
|
|
2322
|
+
resolution: CSG$1.defaultResolution2D
|
|
1948
2323
|
}).extrude({
|
|
1949
2324
|
offset: [ 0, 0, thickness || 1.62 ]
|
|
1950
2325
|
});
|
|
1951
|
-
return board;
|
|
2326
|
+
return assertValidCSG(board, "Board");
|
|
1952
2327
|
}
|
|
1953
2328
|
var Hardware = {
|
|
1954
2329
|
Orientation: {
|
|
@@ -2039,6 +2414,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2039
2414
|
gap = gap || .25;
|
|
2040
2415
|
var inside = thickness - gap;
|
|
2041
2416
|
var outside = -thickness + gap;
|
|
2417
|
+
var boxHeight = box.size().z;
|
|
2418
|
+
if (Math.abs(height) >= boxHeight) {
|
|
2419
|
+
throw new Error("Rabett: height (".concat(height, ") must be less than the object height (").concat(boxHeight, ")"));
|
|
2420
|
+
}
|
|
2042
2421
|
debug("inside", inside, "outside", outside);
|
|
2043
2422
|
var group = Group();
|
|
2044
2423
|
var _box$bisect$parts = box.bisect("z", height, options).parts, top = _box$bisect$parts.positive, lower2_3rd = _box$bisect$parts.negative;
|
|
@@ -2109,10 +2488,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2109
2488
|
thickness = thickness || 2;
|
|
2110
2489
|
var s = div$1(xyz2array(size), 2);
|
|
2111
2490
|
var r = add(s, thickness);
|
|
2112
|
-
var box = CSG.cube({
|
|
2491
|
+
var box = CSG$1.cube({
|
|
2113
2492
|
center: r,
|
|
2114
2493
|
radius: r
|
|
2115
|
-
}).subtract(CSG.cube({
|
|
2494
|
+
}).subtract(CSG$1.cube({
|
|
2116
2495
|
center: r,
|
|
2117
2496
|
radius: s
|
|
2118
2497
|
}));
|
|
@@ -2130,7 +2509,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2130
2509
|
var BBox = function BBox(o) {
|
|
2131
2510
|
depreciated("BBox", true, "Use 'parts.BBox' instead");
|
|
2132
2511
|
var s = div$1(xyz2array(o.size()), 2);
|
|
2133
|
-
return CSG.cube({
|
|
2512
|
+
return CSG$1.cube({
|
|
2134
2513
|
center: s,
|
|
2135
2514
|
radius: s
|
|
2136
2515
|
}).align(o, "xyz");
|
|
@@ -2142,7 +2521,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2142
2521
|
var gap = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : .25;
|
|
2143
2522
|
var r = add(getRadius(box), -thickness / 2);
|
|
2144
2523
|
r[2] = thickness / 2;
|
|
2145
|
-
var cutter = CSG.cube({
|
|
2524
|
+
var cutter = CSG$1.cube({
|
|
2146
2525
|
center: r,
|
|
2147
2526
|
radius: r
|
|
2148
2527
|
}).align(box, "xy").color("green");
|