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