@jwc/jscad-utils 5.1.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 -7
- 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
|
@@ -72,6 +72,8 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
72
72
|
enabled: [],
|
|
73
73
|
disabled: []
|
|
74
74
|
});
|
|
75
|
+
var jscadUtilsAssertValidCSGWarnings = options.assertValidCSGWarnings || false;
|
|
76
|
+
var jscadUtilsAssertValidCSG = options.assertValidCSG || false;
|
|
75
77
|
var jscadUtils = function(exports, jsCadCSG, scadApi) {
|
|
76
78
|
"use strict";
|
|
77
79
|
function _interopDefaultLegacy(e) {
|
|
@@ -305,6 +307,51 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
305
307
|
function _arrayWithHoles(r) {
|
|
306
308
|
if (Array.isArray(r)) return r;
|
|
307
309
|
}
|
|
310
|
+
function _createForOfIteratorHelper(r, e) {
|
|
311
|
+
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
312
|
+
if (!t) {
|
|
313
|
+
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
|
|
314
|
+
t && (r = t);
|
|
315
|
+
var n = 0, F = function() {};
|
|
316
|
+
return {
|
|
317
|
+
s: F,
|
|
318
|
+
n: function() {
|
|
319
|
+
return n >= r.length ? {
|
|
320
|
+
done: !0
|
|
321
|
+
} : {
|
|
322
|
+
done: !1,
|
|
323
|
+
value: r[n++]
|
|
324
|
+
};
|
|
325
|
+
},
|
|
326
|
+
e: function(r) {
|
|
327
|
+
throw r;
|
|
328
|
+
},
|
|
329
|
+
f: F
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
333
|
+
}
|
|
334
|
+
var o, a = !0, u = !1;
|
|
335
|
+
return {
|
|
336
|
+
s: function() {
|
|
337
|
+
t = t.call(r);
|
|
338
|
+
},
|
|
339
|
+
n: function() {
|
|
340
|
+
var r = t.next();
|
|
341
|
+
return a = r.done, r;
|
|
342
|
+
},
|
|
343
|
+
e: function(r) {
|
|
344
|
+
u = !0, o = r;
|
|
345
|
+
},
|
|
346
|
+
f: function() {
|
|
347
|
+
try {
|
|
348
|
+
a || null == t.return || t.return();
|
|
349
|
+
} finally {
|
|
350
|
+
if (u) throw o;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
}
|
|
308
355
|
function _defineProperty(e, r, t) {
|
|
309
356
|
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
310
357
|
value: t,
|
|
@@ -725,6 +772,219 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
725
772
|
c[3] = g || 1;
|
|
726
773
|
return o.setColor(c);
|
|
727
774
|
}
|
|
775
|
+
function validateCSG(csg, options) {
|
|
776
|
+
var errors = [];
|
|
777
|
+
var warnings = [];
|
|
778
|
+
if (!csg || !csg.polygons || csg.polygons.length === 0) {
|
|
779
|
+
errors.push("Empty mesh: no polygons");
|
|
780
|
+
return {
|
|
781
|
+
ok: false,
|
|
782
|
+
errors,
|
|
783
|
+
warnings
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
var opts = _objectSpread2({
|
|
787
|
+
fixTJunctions: true
|
|
788
|
+
}, options);
|
|
789
|
+
if (opts.fixTJunctions && typeof csg.canonicalized === "function") {
|
|
790
|
+
csg = csg.canonicalized();
|
|
791
|
+
if (typeof csg.reTesselated === "function") {
|
|
792
|
+
csg = csg.reTesselated();
|
|
793
|
+
}
|
|
794
|
+
if (typeof csg.fixTJunctions === "function") {
|
|
795
|
+
csg = csg.fixTJunctions();
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
var AREA_EPS = 1e-10;
|
|
799
|
+
var KEY_EPS = 1e-5;
|
|
800
|
+
var degenerateCount = 0;
|
|
801
|
+
var invalidVertexCount = 0;
|
|
802
|
+
var _iterator = _createForOfIteratorHelper(csg.polygons), _step;
|
|
803
|
+
try {
|
|
804
|
+
for (_iterator.s(); !(_step = _iterator.n()).done; ) {
|
|
805
|
+
var npoly = _step.value;
|
|
806
|
+
var _iterator4 = _createForOfIteratorHelper(npoly.vertices), _step4;
|
|
807
|
+
try {
|
|
808
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done; ) {
|
|
809
|
+
var nvert = _step4.value;
|
|
810
|
+
var np = nvert.pos;
|
|
811
|
+
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)) {
|
|
812
|
+
invalidVertexCount++;
|
|
813
|
+
break;
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
} catch (err) {
|
|
817
|
+
_iterator4.e(err);
|
|
818
|
+
} finally {
|
|
819
|
+
_iterator4.f();
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
} catch (err) {
|
|
823
|
+
_iterator.e(err);
|
|
824
|
+
} finally {
|
|
825
|
+
_iterator.f();
|
|
826
|
+
}
|
|
827
|
+
if (invalidVertexCount > 0) {
|
|
828
|
+
errors.push(invalidVertexCount + " polygon(s) with invalid vertex coordinates (NaN or Infinity)");
|
|
829
|
+
}
|
|
830
|
+
function vtxKey(v) {
|
|
831
|
+
var p = v.pos;
|
|
832
|
+
return Math.round(p.x / KEY_EPS) + "," + Math.round(p.y / KEY_EPS) + "," + Math.round(p.z / KEY_EPS);
|
|
833
|
+
}
|
|
834
|
+
var validPolygons = [];
|
|
835
|
+
var _iterator2 = _createForOfIteratorHelper(csg.polygons), _step2;
|
|
836
|
+
try {
|
|
837
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) {
|
|
838
|
+
var poly = _step2.value;
|
|
839
|
+
var verts = poly.vertices;
|
|
840
|
+
var nv = verts.length;
|
|
841
|
+
if (nv < 3) {
|
|
842
|
+
degenerateCount++;
|
|
843
|
+
continue;
|
|
844
|
+
}
|
|
845
|
+
var hasInvalid = false;
|
|
846
|
+
var _iterator5 = _createForOfIteratorHelper(verts), _step5;
|
|
847
|
+
try {
|
|
848
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done; ) {
|
|
849
|
+
var vert = _step5.value;
|
|
850
|
+
var ip = vert.pos;
|
|
851
|
+
if (!Number.isFinite(ip.x) || !Number.isFinite(ip.y) || !Number.isFinite(ip.z)) {
|
|
852
|
+
hasInvalid = true;
|
|
853
|
+
break;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
} catch (err) {
|
|
857
|
+
_iterator5.e(err);
|
|
858
|
+
} finally {
|
|
859
|
+
_iterator5.f();
|
|
860
|
+
}
|
|
861
|
+
if (hasInvalid) continue;
|
|
862
|
+
var area = 0;
|
|
863
|
+
for (var ai = 0; ai < nv - 2; ai++) {
|
|
864
|
+
area += verts[ai + 1].pos.minus(verts[0].pos).cross(verts[ai + 2].pos.minus(verts[ai + 1].pos)).length();
|
|
865
|
+
}
|
|
866
|
+
area *= .5;
|
|
867
|
+
if (area < AREA_EPS) {
|
|
868
|
+
degenerateCount++;
|
|
869
|
+
continue;
|
|
870
|
+
}
|
|
871
|
+
validPolygons.push(poly);
|
|
872
|
+
}
|
|
873
|
+
} catch (err) {
|
|
874
|
+
_iterator2.e(err);
|
|
875
|
+
} finally {
|
|
876
|
+
_iterator2.f();
|
|
877
|
+
}
|
|
878
|
+
if (degenerateCount > 0) {
|
|
879
|
+
warnings.push(degenerateCount + " degenerate polygon(s) (fewer than 3 vertices or near-zero area)");
|
|
880
|
+
if (opts.fixTJunctions && typeof CSG !== "undefined") {
|
|
881
|
+
var cleaned = CSG.fromPolygons(validPolygons);
|
|
882
|
+
cleaned = cleaned.canonicalized();
|
|
883
|
+
if (typeof cleaned.reTesselated === "function") {
|
|
884
|
+
cleaned = cleaned.reTesselated();
|
|
885
|
+
}
|
|
886
|
+
if (typeof cleaned.fixTJunctions === "function") {
|
|
887
|
+
cleaned = cleaned.fixTJunctions();
|
|
888
|
+
}
|
|
889
|
+
validPolygons = [];
|
|
890
|
+
var _iterator3 = _createForOfIteratorHelper(cleaned.polygons), _step3;
|
|
891
|
+
try {
|
|
892
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done; ) {
|
|
893
|
+
var cpoly = _step3.value;
|
|
894
|
+
var cverts = cpoly.vertices;
|
|
895
|
+
var cnv = cverts.length;
|
|
896
|
+
if (cnv < 3) continue;
|
|
897
|
+
var carea = 0;
|
|
898
|
+
for (var cai = 0; cai < cnv - 2; cai++) {
|
|
899
|
+
carea += cverts[cai + 1].pos.minus(cverts[0].pos).cross(cverts[cai + 2].pos.minus(cverts[cai + 1].pos)).length();
|
|
900
|
+
}
|
|
901
|
+
carea *= .5;
|
|
902
|
+
if (carea < AREA_EPS) continue;
|
|
903
|
+
validPolygons.push(cpoly);
|
|
904
|
+
}
|
|
905
|
+
} catch (err) {
|
|
906
|
+
_iterator3.e(err);
|
|
907
|
+
} finally {
|
|
908
|
+
_iterator3.f();
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
var edgeCounts = {};
|
|
913
|
+
for (var _i = 0, _validPolygons = validPolygons; _i < _validPolygons.length; _i++) {
|
|
914
|
+
var vpoly = _validPolygons[_i];
|
|
915
|
+
var vverts = vpoly.vertices;
|
|
916
|
+
var vnv = vverts.length;
|
|
917
|
+
for (var ei = 0; ei < vnv; ei++) {
|
|
918
|
+
var v0 = vverts[ei];
|
|
919
|
+
var v1 = vverts[(ei + 1) % vnv];
|
|
920
|
+
var edgeKey = vtxKey(v0) + "/" + vtxKey(v1);
|
|
921
|
+
edgeCounts[edgeKey] = (edgeCounts[edgeKey] || 0) + 1;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
var unmatchedEdges = 0;
|
|
925
|
+
var nonManifoldEdges = 0;
|
|
926
|
+
var checked = {};
|
|
927
|
+
for (var _i2 = 0, _Object$keys = Object.keys(edgeCounts); _i2 < _Object$keys.length; _i2++) {
|
|
928
|
+
var _edgeKey = _Object$keys[_i2];
|
|
929
|
+
if (checked[_edgeKey]) continue;
|
|
930
|
+
var parts = _edgeKey.split("/");
|
|
931
|
+
var reverseKey = parts[1] + "/" + parts[0];
|
|
932
|
+
var forwardCount = edgeCounts[_edgeKey] || 0;
|
|
933
|
+
var reverseCount = edgeCounts[reverseKey] || 0;
|
|
934
|
+
checked[_edgeKey] = true;
|
|
935
|
+
checked[reverseKey] = true;
|
|
936
|
+
if (forwardCount !== reverseCount) {
|
|
937
|
+
unmatchedEdges += Math.abs(forwardCount - reverseCount);
|
|
938
|
+
}
|
|
939
|
+
if (forwardCount > 1 || reverseCount > 1) {
|
|
940
|
+
nonManifoldEdges++;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
if (unmatchedEdges > 0) {
|
|
944
|
+
errors.push(unmatchedEdges + " unmatched edge(s): mesh is not watertight");
|
|
945
|
+
}
|
|
946
|
+
if (nonManifoldEdges > 0) {
|
|
947
|
+
errors.push(nonManifoldEdges + " non-manifold edge(s): edge shared by more than 2 polygons");
|
|
948
|
+
}
|
|
949
|
+
return {
|
|
950
|
+
ok: errors.length === 0,
|
|
951
|
+
errors,
|
|
952
|
+
warnings
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
function _noOp(csg) {
|
|
956
|
+
return csg;
|
|
957
|
+
}
|
|
958
|
+
function _makeAssertFn(warnEnabled) {
|
|
959
|
+
return function _assert(csg) {
|
|
960
|
+
var functionName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "unknown";
|
|
961
|
+
var moduleName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "unknown";
|
|
962
|
+
if (!csg || csg.polygons === undefined) return csg;
|
|
963
|
+
var result = validateCSG(csg);
|
|
964
|
+
if (!result.ok) {
|
|
965
|
+
throw new Error(moduleName + ":" + functionName + ": " + "invalid CSG: " + result.errors.join(", "));
|
|
966
|
+
}
|
|
967
|
+
if (warnEnabled && result.warnings.length > 0) {
|
|
968
|
+
throw new Error(moduleName + ":" + functionName + ": " + "CSG warnings: " + result.warnings.join(", "));
|
|
969
|
+
}
|
|
970
|
+
return csg;
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
var _assertFn = _noOp;
|
|
974
|
+
function _resolveFromGlobals() {
|
|
975
|
+
var enabled = typeof jscadUtilsAssertValidCSG !== "undefined" && !!jscadUtilsAssertValidCSG;
|
|
976
|
+
var warnEnabled = typeof jscadUtilsAssertValidCSGWarnings !== "undefined" && !!jscadUtilsAssertValidCSGWarnings;
|
|
977
|
+
return enabled ? _makeAssertFn(warnEnabled) : _noOp;
|
|
978
|
+
}
|
|
979
|
+
function AssertValidCSG() {
|
|
980
|
+
var moduleName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "unknown";
|
|
981
|
+
{
|
|
982
|
+
_assertFn = _resolveFromGlobals();
|
|
983
|
+
}
|
|
984
|
+
return function(csg, name) {
|
|
985
|
+
return _assertFn(csg, name, moduleName);
|
|
986
|
+
};
|
|
987
|
+
}
|
|
728
988
|
function init(proto) {
|
|
729
989
|
if (proto.prototype._jscadutilsinit) return;
|
|
730
990
|
proto.prototype.color = function(r, g, b, a) {
|
|
@@ -818,6 +1078,9 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
818
1078
|
proto.prototype.subtractIf = function subtractIf(object, condition) {
|
|
819
1079
|
return condition ? this.subtract(result(this, object)) : this;
|
|
820
1080
|
};
|
|
1081
|
+
proto.prototype.validate = function validate(options) {
|
|
1082
|
+
return validateCSG(this, options);
|
|
1083
|
+
};
|
|
821
1084
|
proto.prototype._translate = proto.prototype.translate;
|
|
822
1085
|
proto.prototype.translate = function translate() {
|
|
823
1086
|
if (arguments.length === 1) {
|
|
@@ -850,12 +1113,13 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
850
1113
|
__proto__: null,
|
|
851
1114
|
default: init
|
|
852
1115
|
});
|
|
853
|
-
var CSG = jsCadCSG__default["default"].CSG, CAG = jsCadCSG__default["default"].CAG;
|
|
1116
|
+
var CSG$1 = jsCadCSG__default["default"].CSG, CAG = jsCadCSG__default["default"].CAG;
|
|
854
1117
|
var rectangular_extrude = scadApi__default["default"].extrusions.rectangular_extrude;
|
|
855
1118
|
var _scadApi$text = scadApi__default["default"].text, vector_text = _scadApi$text.vector_text, vector_char = _scadApi$text.vector_char;
|
|
856
1119
|
var union = scadApi__default["default"].booleanOps.union;
|
|
857
|
-
init(CSG);
|
|
1120
|
+
init(CSG$1);
|
|
858
1121
|
var debug$3 = Debug("jscadUtils:group");
|
|
1122
|
+
var assertValidCSG$2 = AssertValidCSG("group");
|
|
859
1123
|
function JsCadUtilsGroup() {
|
|
860
1124
|
var names = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
861
1125
|
var parts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
@@ -906,7 +1170,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
906
1170
|
debug$3("combine mapPick", value, key, object);
|
|
907
1171
|
return map ? map(value, key, index, object) : identity(value);
|
|
908
1172
|
}, self.name));
|
|
909
|
-
return g.subtractIf(self.holes && Array.isArray(self.holes) ? union(self.holes) : self.holes, self.holes && !options.noholes);
|
|
1173
|
+
return assertValidCSG$2(g.subtractIf(self.holes && Array.isArray(self.holes) ? union(self.holes) : self.holes, self.holes && !options.noholes), "combine");
|
|
910
1174
|
} catch (err) {
|
|
911
1175
|
debug$3("combine error", this, pieces, options, err);
|
|
912
1176
|
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");
|
|
@@ -947,7 +1211,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
947
1211
|
});
|
|
948
1212
|
if (self.holes) {
|
|
949
1213
|
group.holes = toArray(self.holes).map(function(part) {
|
|
950
|
-
return map(CSG.fromPolygons(part.toPolygons()), "holes");
|
|
1214
|
+
return assertValidCSG$2(map(CSG$1.fromPolygons(part.toPolygons()), "holes"), "clone");
|
|
951
1215
|
});
|
|
952
1216
|
}
|
|
953
1217
|
return group;
|
|
@@ -966,7 +1230,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
966
1230
|
var rotationCenter = solid.centroid();
|
|
967
1231
|
var rotationAxis = axes[axis];
|
|
968
1232
|
self.map(function(part) {
|
|
969
|
-
return part.rotate(rotationCenter, rotationAxis, angle);
|
|
1233
|
+
return assertValidCSG$2(part.rotate(rotationCenter, rotationAxis, angle), "rotate");
|
|
970
1234
|
});
|
|
971
1235
|
return self;
|
|
972
1236
|
};
|
|
@@ -979,7 +1243,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
979
1243
|
var self = this;
|
|
980
1244
|
var t = calcSnap(self.combine(part), to, axis, orientation, delta);
|
|
981
1245
|
self.map(function(part) {
|
|
982
|
-
return part.translate(t);
|
|
1246
|
+
return assertValidCSG$2(part.translate(t), "snap");
|
|
983
1247
|
});
|
|
984
1248
|
return self;
|
|
985
1249
|
} catch (err) {
|
|
@@ -994,7 +1258,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
994
1258
|
noholes: true
|
|
995
1259
|
}), axis, to, delta);
|
|
996
1260
|
self.map(function(part) {
|
|
997
|
-
return part.translate(t);
|
|
1261
|
+
return assertValidCSG$2(part.translate(t), "align");
|
|
998
1262
|
});
|
|
999
1263
|
return self;
|
|
1000
1264
|
} catch (err) {
|
|
@@ -1026,14 +1290,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1026
1290
|
var myConnector = connectorName.split(".").reduce(function(a, v) {
|
|
1027
1291
|
return a[v];
|
|
1028
1292
|
}, self.parts[partName].properties);
|
|
1029
|
-
debug$3("toConnector", to instanceof CSG.Connector);
|
|
1293
|
+
debug$3("toConnector", to instanceof CSG$1.Connector);
|
|
1030
1294
|
var toConnector = toConnectorName.split(".").reduce(function(a, v) {
|
|
1031
1295
|
return a[v];
|
|
1032
1296
|
}, to.properties);
|
|
1033
1297
|
var matrix = myConnector.getTransformationTo(toConnector, mirror, normalrotation);
|
|
1034
1298
|
debug$3("connectTo", matrix);
|
|
1035
1299
|
self.map(function(part) {
|
|
1036
|
-
return part.transform(matrix);
|
|
1300
|
+
return assertValidCSG$2(part.transform(matrix), "connectTo");
|
|
1037
1301
|
});
|
|
1038
1302
|
return self;
|
|
1039
1303
|
};
|
|
@@ -1044,7 +1308,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1044
1308
|
return to - size[a] / 2;
|
|
1045
1309
|
});
|
|
1046
1310
|
self.map(function(part) {
|
|
1047
|
-
return part.translate(t);
|
|
1311
|
+
return assertValidCSG$2(part.translate(t), "midlineTo");
|
|
1048
1312
|
});
|
|
1049
1313
|
return self;
|
|
1050
1314
|
};
|
|
@@ -1053,7 +1317,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1053
1317
|
var t = Array.isArray(x) ? x : [ x, y, z ];
|
|
1054
1318
|
debug$3("translate", t);
|
|
1055
1319
|
self.map(function(part) {
|
|
1056
|
-
return part.translate(t);
|
|
1320
|
+
return assertValidCSG$2(part.translate(t), "translate");
|
|
1057
1321
|
});
|
|
1058
1322
|
return self;
|
|
1059
1323
|
};
|
|
@@ -1063,7 +1327,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1063
1327
|
if (!map) map = identity;
|
|
1064
1328
|
var g = Group();
|
|
1065
1329
|
p.forEach(function(name) {
|
|
1066
|
-
g.add(map(CSG.fromPolygons(self.parts[name].toPolygons()), name), name);
|
|
1330
|
+
g.add(assertValidCSG$2(map(CSG$1.fromPolygons(self.parts[name].toPolygons()), name), "pick"), name);
|
|
1067
1331
|
});
|
|
1068
1332
|
return g;
|
|
1069
1333
|
};
|
|
@@ -1078,7 +1342,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1078
1342
|
debug$3("array error", _this, parts);
|
|
1079
1343
|
throw error('group::array error "'.concat(name, '" not found.\nthis: ').concat(_this, '\nparts: "').concat(parts, '"\n'), "JSCAD_UTILS_GROUP_ERROR");
|
|
1080
1344
|
}
|
|
1081
|
-
a.push(map(CSG.fromPolygons(self.parts[name].toPolygons()), name));
|
|
1345
|
+
a.push(assertValidCSG$2(map(CSG$1.fromPolygons(self.parts[name].toPolygons()), name), "array"));
|
|
1082
1346
|
});
|
|
1083
1347
|
return a;
|
|
1084
1348
|
};
|
|
@@ -1111,7 +1375,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1111
1375
|
self.names = names && names.length > 0 && names.split(",") || [];
|
|
1112
1376
|
if (Array.isArray(objects)) {
|
|
1113
1377
|
self.parts = zipObject(self.names, objects);
|
|
1114
|
-
} else if (objects instanceof CSG) {
|
|
1378
|
+
} else if (objects instanceof CSG$1) {
|
|
1115
1379
|
self.parts = zipObject(self.names, [ objects ]);
|
|
1116
1380
|
} else {
|
|
1117
1381
|
self.parts = objects || {};
|
|
@@ -1132,6 +1396,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1132
1396
|
return new JsCadUtilsGroup(self.names, self.parts, self.holes);
|
|
1133
1397
|
}
|
|
1134
1398
|
var debug$2 = Debug("jscadUtils:util");
|
|
1399
|
+
var assertValidCSG$1 = AssertValidCSG("util");
|
|
1135
1400
|
var NOZZEL_SIZE = .4;
|
|
1136
1401
|
var nearest = {
|
|
1137
1402
|
under: function under(desired) {
|
|
@@ -1208,12 +1473,12 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1208
1473
|
h: height || 2
|
|
1209
1474
|
}));
|
|
1210
1475
|
});
|
|
1211
|
-
return center(union(o));
|
|
1476
|
+
return assertValidCSG$1(center(union(o)), "label");
|
|
1212
1477
|
}
|
|
1213
1478
|
function text(text) {
|
|
1214
1479
|
var l = vector_char(0, 0, text);
|
|
1215
1480
|
var _char = l.segments.reduce(function(result, segment) {
|
|
1216
|
-
var path = new CSG.Path2D(segment);
|
|
1481
|
+
var path = new CSG$1.Path2D(segment);
|
|
1217
1482
|
var cag = path.expandToCAG(2);
|
|
1218
1483
|
return result ? result.union(cag) : cag;
|
|
1219
1484
|
}, undefined);
|
|
@@ -1221,17 +1486,17 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1221
1486
|
}
|
|
1222
1487
|
function unitCube(length, radius) {
|
|
1223
1488
|
radius = radius || .5;
|
|
1224
|
-
return CSG.cube({
|
|
1489
|
+
return assertValidCSG$1(CSG$1.cube({
|
|
1225
1490
|
center: [ 0, 0, 0 ],
|
|
1226
1491
|
radius: [ radius, radius, length || .5 ]
|
|
1227
|
-
});
|
|
1492
|
+
}), "unitCube");
|
|
1228
1493
|
}
|
|
1229
1494
|
function unitAxis(length, radius, centroid) {
|
|
1230
1495
|
debug$2("unitAxis", length, radius, centroid);
|
|
1231
1496
|
centroid = centroid || [ 0, 0, 0 ];
|
|
1232
1497
|
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) ]);
|
|
1233
|
-
unitaxis.properties.origin = new CSG.Connector([ 0, 0, 0 ], [ 1, 0, 0 ], [ 0, 1, 0 ]);
|
|
1234
|
-
return unitaxis.translate(centroid);
|
|
1498
|
+
unitaxis.properties.origin = new CSG$1.Connector([ 0, 0, 0 ], [ 1, 0, 0 ], [ 0, 1, 0 ]);
|
|
1499
|
+
return assertValidCSG$1(unitaxis.translate(centroid), "unitAxis");
|
|
1235
1500
|
}
|
|
1236
1501
|
function toArray(a) {
|
|
1237
1502
|
return Array.isArray(a) ? a : [ a ];
|
|
@@ -1321,15 +1586,15 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1321
1586
|
}
|
|
1322
1587
|
function center(object, objectSize) {
|
|
1323
1588
|
objectSize = objectSize || size(object.getBounds());
|
|
1324
|
-
return centerY(centerX(object, objectSize), objectSize);
|
|
1589
|
+
return assertValidCSG$1(centerY(centerX(object, objectSize), objectSize), "center");
|
|
1325
1590
|
}
|
|
1326
1591
|
function centerY(object, objectSize) {
|
|
1327
1592
|
objectSize = objectSize || size(object.getBounds());
|
|
1328
|
-
return object.translate([ 0, -objectSize.y / 2, 0 ]);
|
|
1593
|
+
return assertValidCSG$1(object.translate([ 0, -objectSize.y / 2, 0 ]), "centerY");
|
|
1329
1594
|
}
|
|
1330
1595
|
function centerX(object, objectSize) {
|
|
1331
1596
|
objectSize = objectSize || size(object.getBounds());
|
|
1332
|
-
return object.translate([ -objectSize.x / 2, 0, 0 ]);
|
|
1597
|
+
return assertValidCSG$1(object.translate([ -objectSize.x / 2, 0, 0 ]), "centerX");
|
|
1333
1598
|
}
|
|
1334
1599
|
function enlarge(object, x, y, z) {
|
|
1335
1600
|
var a;
|
|
@@ -1347,7 +1612,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1347
1612
|
var new_object = object.scale(t);
|
|
1348
1613
|
var new_centroid = centroid(new_object);
|
|
1349
1614
|
var delta = new_centroid.minus(objectCentroid).times(-1);
|
|
1350
|
-
return new_object.translate(delta);
|
|
1615
|
+
return assertValidCSG$1(new_object.translate(delta), "enlarge");
|
|
1351
1616
|
}
|
|
1352
1617
|
function fit(object, x, y, z, keep_aspect_ratio) {
|
|
1353
1618
|
var a;
|
|
@@ -1367,10 +1632,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1367
1632
|
}
|
|
1368
1633
|
var s = [ scale(objectSize.x, x), scale(objectSize.y, y), scale(objectSize.z, z) ];
|
|
1369
1634
|
var min$1 = min(s);
|
|
1370
|
-
return centerWith(object.scale(s.map(function(d, i) {
|
|
1635
|
+
return assertValidCSG$1(centerWith(object.scale(s.map(function(d, i) {
|
|
1371
1636
|
if (a[i] === 0) return 1;
|
|
1372
1637
|
return keep_aspect_ratio ? min$1 : d;
|
|
1373
|
-
})), "xyz", object);
|
|
1638
|
+
})), "xyz", object), "fit");
|
|
1374
1639
|
}
|
|
1375
1640
|
function shift(object, x, y, z) {
|
|
1376
1641
|
var hsize = this.div(this.size(object.getBounds()), 2);
|
|
@@ -1378,10 +1643,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1378
1643
|
}
|
|
1379
1644
|
function zero(object) {
|
|
1380
1645
|
var bounds = object.getBounds();
|
|
1381
|
-
return object.translate([ 0, 0, -bounds[0].z ]);
|
|
1646
|
+
return assertValidCSG$1(object.translate([ 0, 0, -bounds[0].z ]), "zero");
|
|
1382
1647
|
}
|
|
1383
1648
|
function mirrored4(x) {
|
|
1384
|
-
return x.union([ x.mirroredY(90), x.mirroredX(90), x.mirroredY(90).mirroredX(90) ]);
|
|
1649
|
+
return assertValidCSG$1(x.union([ x.mirroredY(90), x.mirroredX(90), x.mirroredY(90).mirroredX(90) ]), "mirrored4");
|
|
1385
1650
|
}
|
|
1386
1651
|
var flushSide = {
|
|
1387
1652
|
"above-outside": [ 1, 0 ],
|
|
@@ -1442,10 +1707,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1442
1707
|
function snap(moveobj, withobj, axis, orientation, delta) {
|
|
1443
1708
|
debug$2("snap", moveobj, withobj, axis, orientation, delta);
|
|
1444
1709
|
var t = calcSnap(moveobj, withobj, axis, orientation, delta);
|
|
1445
|
-
return moveobj.translate(t);
|
|
1710
|
+
return assertValidCSG$1(moveobj.translate(t), "snap");
|
|
1446
1711
|
}
|
|
1447
1712
|
function flush(moveobj, withobj, axis, mside, wside) {
|
|
1448
|
-
return moveobj.translate(calcFlush(moveobj, withobj, axis, mside, wside));
|
|
1713
|
+
return assertValidCSG$1(moveobj.translate(calcFlush(moveobj, withobj, axis, mside, wside)), "flush");
|
|
1449
1714
|
}
|
|
1450
1715
|
function axisApply(axes, valfun, a) {
|
|
1451
1716
|
debug$2("axisApply", axes, valfun, a);
|
|
@@ -1461,7 +1726,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1461
1726
|
return retval;
|
|
1462
1727
|
}
|
|
1463
1728
|
function axis2array(axes, valfun) {
|
|
1464
|
-
depreciated("axis2array");
|
|
1729
|
+
depreciated("axis2array", false, "Use axisApply instead.");
|
|
1465
1730
|
var a = [ 0, 0, 0 ];
|
|
1466
1731
|
var lookup = {
|
|
1467
1732
|
x: 0,
|
|
@@ -1491,7 +1756,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1491
1756
|
});
|
|
1492
1757
|
}
|
|
1493
1758
|
function midlineTo(o, axis, to) {
|
|
1494
|
-
return o.translate(calcmidlineTo(o, axis, to));
|
|
1759
|
+
return assertValidCSG$1(o.translate(calcmidlineTo(o, axis, to)), "midlineTo");
|
|
1495
1760
|
}
|
|
1496
1761
|
function translator(o, axis, withObj) {
|
|
1497
1762
|
var objectCentroid = centroid(o);
|
|
@@ -1511,7 +1776,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1511
1776
|
return delta ? add(t, delta) : t;
|
|
1512
1777
|
}
|
|
1513
1778
|
function centerWith(o, axis, withObj) {
|
|
1514
|
-
return o.translate(calcCenterWith(o, axis, withObj));
|
|
1779
|
+
return assertValidCSG$1(o.translate(calcCenterWith(o, axis, withObj)), "centerWith");
|
|
1515
1780
|
}
|
|
1516
1781
|
function getDelta(size, bounds, axis, offset, nonzero) {
|
|
1517
1782
|
if (!isEmpty(offset) && nonzero) {
|
|
@@ -1524,6 +1789,95 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1524
1789
|
return bounds[0][a] + (isEmpty(dist) ? size[axis] / 2 : dist);
|
|
1525
1790
|
});
|
|
1526
1791
|
}
|
|
1792
|
+
var EPS = 1e-5;
|
|
1793
|
+
function splitCSGByPlane(csg, plane) {
|
|
1794
|
+
var frontPolys = [];
|
|
1795
|
+
var backPolys = [];
|
|
1796
|
+
csg.polygons.forEach(function(poly) {
|
|
1797
|
+
var vertices = poly.vertices;
|
|
1798
|
+
var numVerts = vertices.length;
|
|
1799
|
+
var hasfront = false;
|
|
1800
|
+
var hasback = false;
|
|
1801
|
+
var vertexIsBack = [];
|
|
1802
|
+
for (var i = 0; i < numVerts; i++) {
|
|
1803
|
+
var t = plane.normal.dot(vertices[i].pos) - plane.w;
|
|
1804
|
+
vertexIsBack.push(t < 0);
|
|
1805
|
+
if (t > EPS) hasfront = true;
|
|
1806
|
+
if (t < -EPS) hasback = true;
|
|
1807
|
+
}
|
|
1808
|
+
if (!hasfront && !hasback) {
|
|
1809
|
+
var d = plane.normal.dot(poly.plane.normal);
|
|
1810
|
+
if (d >= 0) {
|
|
1811
|
+
frontPolys.push(poly);
|
|
1812
|
+
} else {
|
|
1813
|
+
backPolys.push(poly);
|
|
1814
|
+
}
|
|
1815
|
+
} else if (!hasback) {
|
|
1816
|
+
frontPolys.push(poly);
|
|
1817
|
+
} else if (!hasfront) {
|
|
1818
|
+
backPolys.push(poly);
|
|
1819
|
+
} else {
|
|
1820
|
+
var fv = [];
|
|
1821
|
+
var bv = [];
|
|
1822
|
+
for (var vi = 0; vi < numVerts; vi++) {
|
|
1823
|
+
var vertex = vertices[vi];
|
|
1824
|
+
var nextVi = (vi + 1) % numVerts;
|
|
1825
|
+
var isback = vertexIsBack[vi];
|
|
1826
|
+
var nextisback = vertexIsBack[nextVi];
|
|
1827
|
+
if (isback === nextisback) {
|
|
1828
|
+
if (isback) {
|
|
1829
|
+
bv.push(vertex);
|
|
1830
|
+
} else {
|
|
1831
|
+
fv.push(vertex);
|
|
1832
|
+
}
|
|
1833
|
+
} else {
|
|
1834
|
+
var point = vertex.pos;
|
|
1835
|
+
var nextpoint = vertices[nextVi].pos;
|
|
1836
|
+
var ip = plane.splitLineBetweenPoints(point, nextpoint);
|
|
1837
|
+
var iv = new CSG$1.Vertex(ip);
|
|
1838
|
+
if (isback) {
|
|
1839
|
+
bv.push(vertex);
|
|
1840
|
+
bv.push(iv);
|
|
1841
|
+
fv.push(iv);
|
|
1842
|
+
} else {
|
|
1843
|
+
fv.push(vertex);
|
|
1844
|
+
fv.push(iv);
|
|
1845
|
+
bv.push(iv);
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
var EPSEPS = EPS * EPS;
|
|
1850
|
+
if (fv.length >= 3) {
|
|
1851
|
+
var prev = fv[fv.length - 1];
|
|
1852
|
+
for (var fi = 0; fi < fv.length; fi++) {
|
|
1853
|
+
var curr = fv[fi];
|
|
1854
|
+
if (curr.pos.distanceToSquared(prev.pos) < EPSEPS) {
|
|
1855
|
+
fv.splice(fi, 1);
|
|
1856
|
+
fi--;
|
|
1857
|
+
}
|
|
1858
|
+
prev = curr;
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
if (bv.length >= 3) {
|
|
1862
|
+
var prev = bv[bv.length - 1];
|
|
1863
|
+
for (var bi = 0; bi < bv.length; bi++) {
|
|
1864
|
+
var curr = bv[bi];
|
|
1865
|
+
if (curr.pos.distanceToSquared(prev.pos) < EPSEPS) {
|
|
1866
|
+
bv.splice(bi, 1);
|
|
1867
|
+
bi--;
|
|
1868
|
+
}
|
|
1869
|
+
prev = curr;
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
if (fv.length >= 3) frontPolys.push(new CSG$1.Polygon(fv, poly.shared, poly.plane));
|
|
1873
|
+
if (bv.length >= 3) backPolys.push(new CSG$1.Polygon(bv, poly.shared, poly.plane));
|
|
1874
|
+
}
|
|
1875
|
+
});
|
|
1876
|
+
return {
|
|
1877
|
+
front: CSG$1.fromPolygons(frontPolys),
|
|
1878
|
+
back: CSG$1.fromPolygons(backPolys)
|
|
1879
|
+
};
|
|
1880
|
+
}
|
|
1527
1881
|
function bisect() {
|
|
1528
1882
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1529
1883
|
args[_key] = arguments[_key];
|
|
@@ -1585,13 +1939,13 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1585
1939
|
}[[ axis, rotateaxis ].sort().join("")];
|
|
1586
1940
|
var centroid = object.centroid();
|
|
1587
1941
|
var rotateDelta = getDelta(objectSize, bounds, rotateOffsetAxis, rotateoffset);
|
|
1588
|
-
var rotationCenter = options.rotationCenter || new CSG.Vector3D(axisApply("xyz", function(i, a) {
|
|
1942
|
+
var rotationCenter = options.rotationCenter || new CSG$1.Vector3D(axisApply("xyz", function(i, a) {
|
|
1589
1943
|
if (a == axis) return cutDelta[i];
|
|
1590
1944
|
if (a == rotateOffsetAxis) return rotateDelta[i];
|
|
1591
1945
|
return centroid[a];
|
|
1592
1946
|
}));
|
|
1593
1947
|
var theRotationAxis = rotationAxes[rotateaxis];
|
|
1594
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).translate(cutDelta).rotate(rotationCenter, theRotationAxis, angle);
|
|
1948
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).translate(cutDelta).rotate(rotationCenter, theRotationAxis, angle);
|
|
1595
1949
|
debug$2("bisect", debug$2.enabled && {
|
|
1596
1950
|
axis,
|
|
1597
1951
|
offset,
|
|
@@ -1604,7 +1958,26 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1604
1958
|
cutplane,
|
|
1605
1959
|
options
|
|
1606
1960
|
});
|
|
1607
|
-
var
|
|
1961
|
+
var negative = object.cutByPlane(cutplane.plane);
|
|
1962
|
+
var positive = object.cutByPlane(cutplane.plane.flipped());
|
|
1963
|
+
var negSize = size(negative);
|
|
1964
|
+
var posSize = size(positive);
|
|
1965
|
+
if (negSize[axis] >= objectSize[axis] - EPS || posSize[axis] >= objectSize[axis] - EPS) {
|
|
1966
|
+
var halves = splitCSGByPlane(object, cutplane.plane);
|
|
1967
|
+
if (negSize[axis] >= objectSize[axis] - EPS) {
|
|
1968
|
+
negative = halves.back;
|
|
1969
|
+
try {
|
|
1970
|
+
negative = negative.cutByPlane(cutplane.plane);
|
|
1971
|
+
} catch (e) {}
|
|
1972
|
+
}
|
|
1973
|
+
if (posSize[axis] >= objectSize[axis] - EPS) {
|
|
1974
|
+
positive = halves.front;
|
|
1975
|
+
try {
|
|
1976
|
+
positive = positive.cutByPlane(cutplane.plane.flipped());
|
|
1977
|
+
} catch (e) {}
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
var g = Group("negative,positive", [ negative.color(options.color && "red"), positive.color(options.color && "blue") ]);
|
|
1608
1981
|
if (options.addRotationCenter) g.add(unitAxis(objectSize.length() + 10, .1, rotationCenter), "rotationCenter");
|
|
1609
1982
|
return g;
|
|
1610
1983
|
}
|
|
@@ -1617,9 +1990,9 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1617
1990
|
addRotationCenter: true
|
|
1618
1991
|
};
|
|
1619
1992
|
var info = normalVector(axis);
|
|
1620
|
-
var rotationCenter = options.rotationCenter || new CSG.Vector3D(0, 0, 0);
|
|
1993
|
+
var rotationCenter = options.rotationCenter || new CSG$1.Vector3D(0, 0, 0);
|
|
1621
1994
|
var theRotationAxis = rotationAxes[rotateaxis];
|
|
1622
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).rotate(rotationCenter, theRotationAxis, angle);
|
|
1995
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).rotate(rotationCenter, theRotationAxis, angle);
|
|
1623
1996
|
var g = Group("negative,positive", [ object.cutByPlane(cutplane.plane).color(options.color && "red"), object.cutByPlane(cutplane.plane.flipped()).color(options.color && "blue") ]);
|
|
1624
1997
|
if (options.addRotationCenter) {
|
|
1625
1998
|
var objectSize = size(object);
|
|
@@ -1644,14 +2017,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1644
2017
|
var bounds = object.getBounds();
|
|
1645
2018
|
var objectSize = size(object);
|
|
1646
2019
|
var cutDelta = getDelta(objectSize, bounds, axis, offset, true);
|
|
1647
|
-
return object.stretchAtPlane(normal[axis], cutDelta, distance);
|
|
2020
|
+
return assertValidCSG$1(object.stretchAtPlane(normal[axis], cutDelta, distance), "stretch");
|
|
1648
2021
|
}
|
|
1649
2022
|
function poly2solid(top, bottom, height) {
|
|
1650
2023
|
if (top.sides.length == 0) {
|
|
1651
|
-
return new CSG;
|
|
2024
|
+
return new CSG$1;
|
|
1652
2025
|
}
|
|
1653
|
-
var offsetVector = CSG.Vector3D.Create(0, 0, height);
|
|
1654
|
-
var normalVector = CSG.Vector3D.Create(0, 1, 0);
|
|
2026
|
+
var offsetVector = CSG$1.Vector3D.Create(0, 0, height);
|
|
2027
|
+
var normalVector = CSG$1.Vector3D.Create(0, 1, 0);
|
|
1655
2028
|
var polygons = [];
|
|
1656
2029
|
polygons = polygons.concat(bottom._toPlanePolygons({
|
|
1657
2030
|
translation: [ 0, 0, 0 ],
|
|
@@ -1663,14 +2036,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1663
2036
|
normalVector,
|
|
1664
2037
|
flipped: offsetVector.z < 0
|
|
1665
2038
|
}));
|
|
1666
|
-
var c1 = new CSG.Connector(offsetVector.times(0), [ 0, 0, offsetVector.z ], normalVector);
|
|
1667
|
-
var c2 = new CSG.Connector(offsetVector, [ 0, 0, offsetVector.z ], normalVector);
|
|
2039
|
+
var c1 = new CSG$1.Connector(offsetVector.times(0), [ 0, 0, offsetVector.z ], normalVector);
|
|
2040
|
+
var c2 = new CSG$1.Connector(offsetVector, [ 0, 0, offsetVector.z ], normalVector);
|
|
1668
2041
|
polygons = polygons.concat(bottom._toWallPolygons({
|
|
1669
2042
|
cag: top,
|
|
1670
2043
|
toConnector1: c1,
|
|
1671
2044
|
toConnector2: c2
|
|
1672
2045
|
}));
|
|
1673
|
-
return CSG.fromPolygons(polygons);
|
|
2046
|
+
return assertValidCSG$1(CSG$1.fromPolygons(polygons), "poly2solid");
|
|
1674
2047
|
}
|
|
1675
2048
|
function slices2poly(slices, options, axis) {
|
|
1676
2049
|
debug$2("slices2poly", slices, options, axis);
|
|
@@ -1679,7 +2052,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1679
2052
|
twiststeps: 0
|
|
1680
2053
|
}, options);
|
|
1681
2054
|
var twistangle = options && parseFloat(options.twistangle) || 0;
|
|
1682
|
-
options && parseInt(options.twiststeps) || CSG.defaultResolution3D;
|
|
2055
|
+
options && parseInt(options.twiststeps) || CSG$1.defaultResolution3D;
|
|
1683
2056
|
var normalVector = options.si.normalVector;
|
|
1684
2057
|
var polygons = [];
|
|
1685
2058
|
var first$1 = first(slices);
|
|
@@ -1708,8 +2081,8 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1708
2081
|
var nextidx = idx + 1;
|
|
1709
2082
|
var top = !up ? slices[nextidx] : slice;
|
|
1710
2083
|
var bottom = up ? slices[nextidx] : slice;
|
|
1711
|
-
var c1 = new CSG.Connector(bottom.offset, connectorAxis, rotate(normalVector, twistangle, idx / slices.length));
|
|
1712
|
-
var c2 = new CSG.Connector(top.offset, connectorAxis, rotate(normalVector, twistangle, nextidx / slices.length));
|
|
2084
|
+
var c1 = new CSG$1.Connector(bottom.offset, connectorAxis, rotate(normalVector, twistangle, idx / slices.length));
|
|
2085
|
+
var c2 = new CSG$1.Connector(top.offset, connectorAxis, rotate(normalVector, twistangle, nextidx / slices.length));
|
|
1713
2086
|
polygons = polygons.concat(bottom.poly._toWallPolygons({
|
|
1714
2087
|
cag: top.poly,
|
|
1715
2088
|
toConnector1: c1,
|
|
@@ -1717,21 +2090,21 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1717
2090
|
}));
|
|
1718
2091
|
}
|
|
1719
2092
|
});
|
|
1720
|
-
return CSG.fromPolygons(polygons);
|
|
2093
|
+
return assertValidCSG$1(CSG$1.fromPolygons(polygons), "slices2poly");
|
|
1721
2094
|
}
|
|
1722
2095
|
function normalVector(axis) {
|
|
1723
2096
|
var axisInfo = {
|
|
1724
2097
|
z: {
|
|
1725
2098
|
orthoNormalCartesian: [ "X", "Y" ],
|
|
1726
|
-
normalVector: CSG.Vector3D.Create(0, 1, 0)
|
|
2099
|
+
normalVector: CSG$1.Vector3D.Create(0, 1, 0)
|
|
1727
2100
|
},
|
|
1728
2101
|
x: {
|
|
1729
2102
|
orthoNormalCartesian: [ "Y", "Z" ],
|
|
1730
|
-
normalVector: CSG.Vector3D.Create(0, 0, 1)
|
|
2103
|
+
normalVector: CSG$1.Vector3D.Create(0, 0, 1)
|
|
1731
2104
|
},
|
|
1732
2105
|
y: {
|
|
1733
|
-
orthoNormalCartesian: [ "
|
|
1734
|
-
normalVector: CSG.Vector3D.Create(0, 0, 1)
|
|
2106
|
+
orthoNormalCartesian: [ "Z", "X" ],
|
|
2107
|
+
normalVector: CSG$1.Vector3D.Create(0, 0, 1)
|
|
1735
2108
|
}
|
|
1736
2109
|
};
|
|
1737
2110
|
if (!axisInfo[axis]) error("normalVector: invalid axis " + axis);
|
|
@@ -1772,7 +2145,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1772
2145
|
var si = sliceParams(orientation, radius, b);
|
|
1773
2146
|
debug$2("reShape", absoluteRadius, si);
|
|
1774
2147
|
if (si.axis !== "z") throw new Error('reShape error: CAG._toPlanePolygons only uses the "z" axis. You must use the "z" axis for now.');
|
|
1775
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(si.orthoNormalCartesian[0], si.orthoNormalCartesian[1]).translate(si.cutDelta);
|
|
2148
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(si.orthoNormalCartesian[0], si.orthoNormalCartesian[1]).translate(si.cutDelta);
|
|
1776
2149
|
var slice = object.sectionCut(cutplane);
|
|
1777
2150
|
var first = axisApply(si.axis, function() {
|
|
1778
2151
|
return si.positive ? 0 : absoluteRadius;
|
|
@@ -1787,25 +2160,25 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1787
2160
|
si
|
|
1788
2161
|
}), si.axis).color(options.color);
|
|
1789
2162
|
var remainder = object.cutByPlane(plane);
|
|
1790
|
-
return union([ options.unionOriginal ? object : remainder, delta.translate(si.moveDelta) ]);
|
|
2163
|
+
return assertValidCSG$1(union([ options.unionOriginal ? object : remainder, delta.translate(si.moveDelta) ]), "reShape");
|
|
1791
2164
|
}
|
|
1792
2165
|
function chamfer(object, radius, orientation, options) {
|
|
1793
|
-
return reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
2166
|
+
return assertValidCSG$1(reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
1794
2167
|
return [ {
|
|
1795
2168
|
poly: slice,
|
|
1796
|
-
offset: new CSG.Vector3D(first)
|
|
2169
|
+
offset: new CSG$1.Vector3D(first)
|
|
1797
2170
|
}, {
|
|
1798
2171
|
poly: enlarge(slice, [ -radius * 2, -radius * 2 ]),
|
|
1799
|
-
offset: new CSG.Vector3D(last)
|
|
2172
|
+
offset: new CSG$1.Vector3D(last)
|
|
1800
2173
|
} ];
|
|
1801
|
-
});
|
|
2174
|
+
}), "chamfer");
|
|
1802
2175
|
}
|
|
1803
2176
|
function fillet(object, radius, orientation, options) {
|
|
1804
2177
|
options = options || {};
|
|
1805
|
-
return reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
1806
|
-
var v1 = new CSG.Vector3D(first);
|
|
1807
|
-
var v2 = new CSG.Vector3D(last);
|
|
1808
|
-
var res = options.resolution || CSG.defaultResolution3D;
|
|
2178
|
+
return assertValidCSG$1(reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
2179
|
+
var v1 = new CSG$1.Vector3D(first);
|
|
2180
|
+
var v2 = new CSG$1.Vector3D(last);
|
|
2181
|
+
var res = options.resolution || CSG$1.defaultResolution3D;
|
|
1809
2182
|
var slices = range(0, res).map(function(i) {
|
|
1810
2183
|
var p = i > 0 ? i / (res - 1) : 0;
|
|
1811
2184
|
var v = v1.lerp(v2, p);
|
|
@@ -1816,7 +2189,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1816
2189
|
};
|
|
1817
2190
|
});
|
|
1818
2191
|
return slices;
|
|
1819
|
-
});
|
|
2192
|
+
}), "fillet");
|
|
1820
2193
|
}
|
|
1821
2194
|
function calcRotate(part, solid, axis) {
|
|
1822
2195
|
var axes = {
|
|
@@ -1833,7 +2206,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1833
2206
|
}
|
|
1834
2207
|
function rotateAround(part, solid, axis, angle) {
|
|
1835
2208
|
var _calcRotate = calcRotate(part, solid, axis), rotationCenter = _calcRotate.rotationCenter, rotationAxis = _calcRotate.rotationAxis;
|
|
1836
|
-
return part.rotate(rotationCenter, rotationAxis, angle);
|
|
2209
|
+
return assertValidCSG$1("rotateAround")(part.rotate(rotationCenter, rotationAxis, angle));
|
|
1837
2210
|
}
|
|
1838
2211
|
function cloneProperties(from, to) {
|
|
1839
2212
|
return Object.entries(from).reduce(function(props, _ref) {
|
|
@@ -1843,19 +2216,20 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1843
2216
|
}, to);
|
|
1844
2217
|
}
|
|
1845
2218
|
function clone(o) {
|
|
1846
|
-
var c = CSG.fromPolygons(o.toPolygons());
|
|
2219
|
+
var c = CSG$1.fromPolygons(o.toPolygons());
|
|
1847
2220
|
cloneProperties(o, c);
|
|
1848
|
-
debug$2("clone", o, c, CSG);
|
|
1849
|
-
return c;
|
|
2221
|
+
debug$2("clone", o, c, CSG$1);
|
|
2222
|
+
return assertValidCSG$1(c, "clone");
|
|
1850
2223
|
}
|
|
1851
2224
|
function addConnector(object, name) {
|
|
1852
2225
|
var point = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [ 0, 0, 0 ];
|
|
1853
2226
|
var axis = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [ 1, 0, 0 ];
|
|
1854
2227
|
var normal = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [ 0, 0, 1 ];
|
|
1855
|
-
object.properties[name] = new CSG.Connector(point, axis, normal);
|
|
1856
|
-
return object;
|
|
2228
|
+
object.properties[name] = new CSG$1.Connector(point, axis, normal);
|
|
2229
|
+
return assertValidCSG$1("addConnector")(object);
|
|
1857
2230
|
}
|
|
1858
2231
|
var debug$1 = Debug("jscadUtils:parts");
|
|
2232
|
+
var assertValidCSG = AssertValidCSG("parts");
|
|
1859
2233
|
var parts = {
|
|
1860
2234
|
BBox: BBox$1,
|
|
1861
2235
|
Cube,
|
|
@@ -1865,7 +2239,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1865
2239
|
};
|
|
1866
2240
|
function BBox$1() {
|
|
1867
2241
|
function box(object) {
|
|
1868
|
-
return CSG.cube({
|
|
2242
|
+
return CSG$1.cube({
|
|
1869
2243
|
center: object.centroid(),
|
|
1870
2244
|
radius: object.size().dividedBy(2)
|
|
1871
2245
|
});
|
|
@@ -1873,17 +2247,17 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1873
2247
|
for (var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1874
2248
|
objects[_key] = arguments[_key];
|
|
1875
2249
|
}
|
|
1876
|
-
return objects.reduce(function(bbox, part) {
|
|
2250
|
+
return assertValidCSG(objects.reduce(function(bbox, part) {
|
|
1877
2251
|
var object = bbox ? union([ bbox, box(part) ]) : part;
|
|
1878
2252
|
return box(object);
|
|
1879
|
-
}, undefined);
|
|
2253
|
+
}, undefined), "BBox");
|
|
1880
2254
|
}
|
|
1881
2255
|
function Cube(width) {
|
|
1882
2256
|
var r = div$1(fromxyz(width), 2);
|
|
1883
|
-
return CSG.cube({
|
|
2257
|
+
return assertValidCSG(CSG$1.cube({
|
|
1884
2258
|
center: r,
|
|
1885
2259
|
radius: r
|
|
1886
|
-
});
|
|
2260
|
+
}), "Cube");
|
|
1887
2261
|
}
|
|
1888
2262
|
function RoundedCube(x, y, thickness, corner_radius) {
|
|
1889
2263
|
if (x.getBounds) {
|
|
@@ -1899,11 +2273,11 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1899
2273
|
center: [ r[0], r[1], 0 ],
|
|
1900
2274
|
radius: r,
|
|
1901
2275
|
roundradius: corner_radius,
|
|
1902
|
-
resolution: CSG.defaultResolution2D
|
|
2276
|
+
resolution: CSG$1.defaultResolution2D
|
|
1903
2277
|
}).extrude({
|
|
1904
2278
|
offset: [ 0, 0, thickness || 1.62 ]
|
|
1905
2279
|
});
|
|
1906
|
-
return roundedcube;
|
|
2280
|
+
return assertValidCSG(roundedcube, "RoundedCube");
|
|
1907
2281
|
}
|
|
1908
2282
|
function Cylinder(diameter, height) {
|
|
1909
2283
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
@@ -1912,39 +2286,39 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1912
2286
|
start: [ 0, 0, 0 ],
|
|
1913
2287
|
end: [ 0, 0, height ],
|
|
1914
2288
|
radius: diameter / 2,
|
|
1915
|
-
resolution: CSG.defaultResolution2D
|
|
2289
|
+
resolution: CSG$1.defaultResolution2D
|
|
1916
2290
|
}, options);
|
|
1917
|
-
return CSG.cylinder(options);
|
|
2291
|
+
return assertValidCSG(CSG$1.cylinder(options), "Cylinder");
|
|
1918
2292
|
}
|
|
1919
2293
|
function Cone(diameter1, diameter2, height) {
|
|
1920
2294
|
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
1921
2295
|
debug$1("parts.Cone", diameter1, diameter2, height, options);
|
|
1922
|
-
return CSG.cylinder(Object.assign({
|
|
2296
|
+
return assertValidCSG(CSG$1.cylinder(Object.assign({
|
|
1923
2297
|
start: [ 0, 0, 0 ],
|
|
1924
2298
|
end: [ 0, 0, height ],
|
|
1925
2299
|
radiusStart: diameter1 / 2,
|
|
1926
2300
|
radiusEnd: diameter2 / 2,
|
|
1927
|
-
resolution: CSG.defaultResolution2D
|
|
1928
|
-
}, options));
|
|
2301
|
+
resolution: CSG$1.defaultResolution2D
|
|
2302
|
+
}, options)), "Cone");
|
|
1929
2303
|
}
|
|
1930
2304
|
function Hexagon(diameter, height) {
|
|
1931
2305
|
debug$1("hexagon", diameter, height);
|
|
1932
2306
|
var radius = diameter / 2;
|
|
1933
2307
|
var sqrt3 = Math.sqrt(3) / 2;
|
|
1934
2308
|
var hex = CAG.fromPoints([ [ radius, 0 ], [ radius / 2, radius * sqrt3 ], [ -radius / 2, radius * sqrt3 ], [ -radius, 0 ], [ -radius / 2, -radius * sqrt3 ], [ radius / 2, -radius * sqrt3 ] ]);
|
|
1935
|
-
return hex.extrude({
|
|
2309
|
+
return assertValidCSG(hex.extrude({
|
|
1936
2310
|
offset: [ 0, 0, height ]
|
|
1937
|
-
});
|
|
2311
|
+
}), "Hexagon");
|
|
1938
2312
|
}
|
|
1939
2313
|
function Triangle(base, height) {
|
|
1940
2314
|
var radius = base / 2;
|
|
1941
2315
|
var tri = CAG.fromPoints([ [ -radius, 0 ], [ radius, 0 ], [ 0, Math.sin(30) * radius ] ]);
|
|
1942
|
-
return tri.extrude({
|
|
2316
|
+
return assertValidCSG(tri.extrude({
|
|
1943
2317
|
offset: [ 0, 0, height ]
|
|
1944
|
-
});
|
|
2318
|
+
}), "Triangle");
|
|
1945
2319
|
}
|
|
1946
2320
|
function Tube(outsideDiameter, insideDiameter, height, outsideOptions, insideOptions) {
|
|
1947
|
-
return Cylinder(outsideDiameter, height, outsideOptions).subtract(Cylinder(insideDiameter, height, insideOptions || outsideOptions));
|
|
2321
|
+
return assertValidCSG(Cylinder(outsideDiameter, height, outsideOptions).subtract(Cylinder(insideDiameter, height, insideOptions || outsideOptions)), "Tube");
|
|
1948
2322
|
}
|
|
1949
2323
|
function Anchor() {
|
|
1950
2324
|
var width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
|
|
@@ -1962,11 +2336,11 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1962
2336
|
center: [ r[0], r[1], 0 ],
|
|
1963
2337
|
radius: r,
|
|
1964
2338
|
roundradius: corner_radius,
|
|
1965
|
-
resolution: CSG.defaultResolution2D
|
|
2339
|
+
resolution: CSG$1.defaultResolution2D
|
|
1966
2340
|
}).extrude({
|
|
1967
2341
|
offset: [ 0, 0, thickness || 1.62 ]
|
|
1968
2342
|
});
|
|
1969
|
-
return board;
|
|
2343
|
+
return assertValidCSG(board, "Board");
|
|
1970
2344
|
}
|
|
1971
2345
|
var Hardware = {
|
|
1972
2346
|
Orientation: {
|
|
@@ -2057,6 +2431,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2057
2431
|
gap = gap || .25;
|
|
2058
2432
|
var inside = thickness - gap;
|
|
2059
2433
|
var outside = -thickness + gap;
|
|
2434
|
+
var boxHeight = box.size().z;
|
|
2435
|
+
if (Math.abs(height) >= boxHeight) {
|
|
2436
|
+
throw new Error("Rabett: height (".concat(height, ") must be less than the object height (").concat(boxHeight, ")"));
|
|
2437
|
+
}
|
|
2060
2438
|
debug("inside", inside, "outside", outside);
|
|
2061
2439
|
var group = Group();
|
|
2062
2440
|
var _box$bisect$parts = box.bisect("z", height, options).parts, top = _box$bisect$parts.positive, lower2_3rd = _box$bisect$parts.negative;
|
|
@@ -2127,10 +2505,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2127
2505
|
thickness = thickness || 2;
|
|
2128
2506
|
var s = div$1(xyz2array(size), 2);
|
|
2129
2507
|
var r = add(s, thickness);
|
|
2130
|
-
var box = CSG.cube({
|
|
2508
|
+
var box = CSG$1.cube({
|
|
2131
2509
|
center: r,
|
|
2132
2510
|
radius: r
|
|
2133
|
-
}).subtract(CSG.cube({
|
|
2511
|
+
}).subtract(CSG$1.cube({
|
|
2134
2512
|
center: r,
|
|
2135
2513
|
radius: s
|
|
2136
2514
|
}));
|
|
@@ -2148,7 +2526,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2148
2526
|
var BBox = function BBox(o) {
|
|
2149
2527
|
depreciated("BBox", true, "Use 'parts.BBox' instead");
|
|
2150
2528
|
var s = div$1(xyz2array(o.size()), 2);
|
|
2151
|
-
return CSG.cube({
|
|
2529
|
+
return CSG$1.cube({
|
|
2152
2530
|
center: s,
|
|
2153
2531
|
radius: s
|
|
2154
2532
|
}).align(o, "xyz");
|
|
@@ -2160,7 +2538,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2160
2538
|
var gap = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : .25;
|
|
2161
2539
|
var r = add(getRadius(box), -thickness / 2);
|
|
2162
2540
|
r[2] = thickness / 2;
|
|
2163
|
-
var cutter = CSG.cube({
|
|
2541
|
+
var cutter = CSG$1.cube({
|
|
2164
2542
|
center: r,
|
|
2165
2543
|
radius: r
|
|
2166
2544
|
}).align(box, "xy").color("green");
|