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