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