@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
|
@@ -67,6 +67,8 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
67
67
|
enabled: [],
|
|
68
68
|
disabled: []
|
|
69
69
|
});
|
|
70
|
+
var jscadUtilsAssertValidCSGWarnings = options.assertValidCSGWarnings || false;
|
|
71
|
+
var jscadUtilsAssertValidCSG = options.assertValidCSG || false;
|
|
70
72
|
var jscadUtils = function(exports, jsCadCSG, scadApi) {
|
|
71
73
|
"use strict";
|
|
72
74
|
function _interopDefaultLegacy(e) {
|
|
@@ -300,6 +302,51 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
300
302
|
function _arrayWithHoles(r) {
|
|
301
303
|
if (Array.isArray(r)) return r;
|
|
302
304
|
}
|
|
305
|
+
function _createForOfIteratorHelper(r, e) {
|
|
306
|
+
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
307
|
+
if (!t) {
|
|
308
|
+
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
|
|
309
|
+
t && (r = t);
|
|
310
|
+
var n = 0, F = function() {};
|
|
311
|
+
return {
|
|
312
|
+
s: F,
|
|
313
|
+
n: function() {
|
|
314
|
+
return n >= r.length ? {
|
|
315
|
+
done: !0
|
|
316
|
+
} : {
|
|
317
|
+
done: !1,
|
|
318
|
+
value: r[n++]
|
|
319
|
+
};
|
|
320
|
+
},
|
|
321
|
+
e: function(r) {
|
|
322
|
+
throw r;
|
|
323
|
+
},
|
|
324
|
+
f: F
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
328
|
+
}
|
|
329
|
+
var o, a = !0, u = !1;
|
|
330
|
+
return {
|
|
331
|
+
s: function() {
|
|
332
|
+
t = t.call(r);
|
|
333
|
+
},
|
|
334
|
+
n: function() {
|
|
335
|
+
var r = t.next();
|
|
336
|
+
return a = r.done, r;
|
|
337
|
+
},
|
|
338
|
+
e: function(r) {
|
|
339
|
+
u = !0, o = r;
|
|
340
|
+
},
|
|
341
|
+
f: function() {
|
|
342
|
+
try {
|
|
343
|
+
a || null == t.return || t.return();
|
|
344
|
+
} finally {
|
|
345
|
+
if (u) throw o;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
}
|
|
303
350
|
function _defineProperty(e, r, t) {
|
|
304
351
|
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
305
352
|
value: t,
|
|
@@ -720,6 +767,219 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
720
767
|
c[3] = g || 1;
|
|
721
768
|
return o.setColor(c);
|
|
722
769
|
}
|
|
770
|
+
function validateCSG(csg, options) {
|
|
771
|
+
var errors = [];
|
|
772
|
+
var warnings = [];
|
|
773
|
+
if (!csg || !csg.polygons || csg.polygons.length === 0) {
|
|
774
|
+
errors.push("Empty mesh: no polygons");
|
|
775
|
+
return {
|
|
776
|
+
ok: false,
|
|
777
|
+
errors,
|
|
778
|
+
warnings
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
var opts = _objectSpread2({
|
|
782
|
+
fixTJunctions: true
|
|
783
|
+
}, options);
|
|
784
|
+
if (opts.fixTJunctions && typeof csg.canonicalized === "function") {
|
|
785
|
+
csg = csg.canonicalized();
|
|
786
|
+
if (typeof csg.reTesselated === "function") {
|
|
787
|
+
csg = csg.reTesselated();
|
|
788
|
+
}
|
|
789
|
+
if (typeof csg.fixTJunctions === "function") {
|
|
790
|
+
csg = csg.fixTJunctions();
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
var AREA_EPS = 1e-10;
|
|
794
|
+
var KEY_EPS = 1e-5;
|
|
795
|
+
var degenerateCount = 0;
|
|
796
|
+
var invalidVertexCount = 0;
|
|
797
|
+
var _iterator = _createForOfIteratorHelper(csg.polygons), _step;
|
|
798
|
+
try {
|
|
799
|
+
for (_iterator.s(); !(_step = _iterator.n()).done; ) {
|
|
800
|
+
var npoly = _step.value;
|
|
801
|
+
var _iterator4 = _createForOfIteratorHelper(npoly.vertices), _step4;
|
|
802
|
+
try {
|
|
803
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done; ) {
|
|
804
|
+
var nvert = _step4.value;
|
|
805
|
+
var np = nvert.pos;
|
|
806
|
+
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)) {
|
|
807
|
+
invalidVertexCount++;
|
|
808
|
+
break;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
} catch (err) {
|
|
812
|
+
_iterator4.e(err);
|
|
813
|
+
} finally {
|
|
814
|
+
_iterator4.f();
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
} catch (err) {
|
|
818
|
+
_iterator.e(err);
|
|
819
|
+
} finally {
|
|
820
|
+
_iterator.f();
|
|
821
|
+
}
|
|
822
|
+
if (invalidVertexCount > 0) {
|
|
823
|
+
errors.push(invalidVertexCount + " polygon(s) with invalid vertex coordinates (NaN or Infinity)");
|
|
824
|
+
}
|
|
825
|
+
function vtxKey(v) {
|
|
826
|
+
var p = v.pos;
|
|
827
|
+
return Math.round(p.x / KEY_EPS) + "," + Math.round(p.y / KEY_EPS) + "," + Math.round(p.z / KEY_EPS);
|
|
828
|
+
}
|
|
829
|
+
var validPolygons = [];
|
|
830
|
+
var _iterator2 = _createForOfIteratorHelper(csg.polygons), _step2;
|
|
831
|
+
try {
|
|
832
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) {
|
|
833
|
+
var poly = _step2.value;
|
|
834
|
+
var verts = poly.vertices;
|
|
835
|
+
var nv = verts.length;
|
|
836
|
+
if (nv < 3) {
|
|
837
|
+
degenerateCount++;
|
|
838
|
+
continue;
|
|
839
|
+
}
|
|
840
|
+
var hasInvalid = false;
|
|
841
|
+
var _iterator5 = _createForOfIteratorHelper(verts), _step5;
|
|
842
|
+
try {
|
|
843
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done; ) {
|
|
844
|
+
var vert = _step5.value;
|
|
845
|
+
var ip = vert.pos;
|
|
846
|
+
if (!Number.isFinite(ip.x) || !Number.isFinite(ip.y) || !Number.isFinite(ip.z)) {
|
|
847
|
+
hasInvalid = true;
|
|
848
|
+
break;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
} catch (err) {
|
|
852
|
+
_iterator5.e(err);
|
|
853
|
+
} finally {
|
|
854
|
+
_iterator5.f();
|
|
855
|
+
}
|
|
856
|
+
if (hasInvalid) continue;
|
|
857
|
+
var area = 0;
|
|
858
|
+
for (var ai = 0; ai < nv - 2; ai++) {
|
|
859
|
+
area += verts[ai + 1].pos.minus(verts[0].pos).cross(verts[ai + 2].pos.minus(verts[ai + 1].pos)).length();
|
|
860
|
+
}
|
|
861
|
+
area *= .5;
|
|
862
|
+
if (area < AREA_EPS) {
|
|
863
|
+
degenerateCount++;
|
|
864
|
+
continue;
|
|
865
|
+
}
|
|
866
|
+
validPolygons.push(poly);
|
|
867
|
+
}
|
|
868
|
+
} catch (err) {
|
|
869
|
+
_iterator2.e(err);
|
|
870
|
+
} finally {
|
|
871
|
+
_iterator2.f();
|
|
872
|
+
}
|
|
873
|
+
if (degenerateCount > 0) {
|
|
874
|
+
warnings.push(degenerateCount + " degenerate polygon(s) (fewer than 3 vertices or near-zero area)");
|
|
875
|
+
if (opts.fixTJunctions && typeof CSG !== "undefined") {
|
|
876
|
+
var cleaned = CSG.fromPolygons(validPolygons);
|
|
877
|
+
cleaned = cleaned.canonicalized();
|
|
878
|
+
if (typeof cleaned.reTesselated === "function") {
|
|
879
|
+
cleaned = cleaned.reTesselated();
|
|
880
|
+
}
|
|
881
|
+
if (typeof cleaned.fixTJunctions === "function") {
|
|
882
|
+
cleaned = cleaned.fixTJunctions();
|
|
883
|
+
}
|
|
884
|
+
validPolygons = [];
|
|
885
|
+
var _iterator3 = _createForOfIteratorHelper(cleaned.polygons), _step3;
|
|
886
|
+
try {
|
|
887
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done; ) {
|
|
888
|
+
var cpoly = _step3.value;
|
|
889
|
+
var cverts = cpoly.vertices;
|
|
890
|
+
var cnv = cverts.length;
|
|
891
|
+
if (cnv < 3) continue;
|
|
892
|
+
var carea = 0;
|
|
893
|
+
for (var cai = 0; cai < cnv - 2; cai++) {
|
|
894
|
+
carea += cverts[cai + 1].pos.minus(cverts[0].pos).cross(cverts[cai + 2].pos.minus(cverts[cai + 1].pos)).length();
|
|
895
|
+
}
|
|
896
|
+
carea *= .5;
|
|
897
|
+
if (carea < AREA_EPS) continue;
|
|
898
|
+
validPolygons.push(cpoly);
|
|
899
|
+
}
|
|
900
|
+
} catch (err) {
|
|
901
|
+
_iterator3.e(err);
|
|
902
|
+
} finally {
|
|
903
|
+
_iterator3.f();
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
var edgeCounts = {};
|
|
908
|
+
for (var _i = 0, _validPolygons = validPolygons; _i < _validPolygons.length; _i++) {
|
|
909
|
+
var vpoly = _validPolygons[_i];
|
|
910
|
+
var vverts = vpoly.vertices;
|
|
911
|
+
var vnv = vverts.length;
|
|
912
|
+
for (var ei = 0; ei < vnv; ei++) {
|
|
913
|
+
var v0 = vverts[ei];
|
|
914
|
+
var v1 = vverts[(ei + 1) % vnv];
|
|
915
|
+
var edgeKey = vtxKey(v0) + "/" + vtxKey(v1);
|
|
916
|
+
edgeCounts[edgeKey] = (edgeCounts[edgeKey] || 0) + 1;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
var unmatchedEdges = 0;
|
|
920
|
+
var nonManifoldEdges = 0;
|
|
921
|
+
var checked = {};
|
|
922
|
+
for (var _i2 = 0, _Object$keys = Object.keys(edgeCounts); _i2 < _Object$keys.length; _i2++) {
|
|
923
|
+
var _edgeKey = _Object$keys[_i2];
|
|
924
|
+
if (checked[_edgeKey]) continue;
|
|
925
|
+
var parts = _edgeKey.split("/");
|
|
926
|
+
var reverseKey = parts[1] + "/" + parts[0];
|
|
927
|
+
var forwardCount = edgeCounts[_edgeKey] || 0;
|
|
928
|
+
var reverseCount = edgeCounts[reverseKey] || 0;
|
|
929
|
+
checked[_edgeKey] = true;
|
|
930
|
+
checked[reverseKey] = true;
|
|
931
|
+
if (forwardCount !== reverseCount) {
|
|
932
|
+
unmatchedEdges += Math.abs(forwardCount - reverseCount);
|
|
933
|
+
}
|
|
934
|
+
if (forwardCount > 1 || reverseCount > 1) {
|
|
935
|
+
nonManifoldEdges++;
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
if (unmatchedEdges > 0) {
|
|
939
|
+
errors.push(unmatchedEdges + " unmatched edge(s): mesh is not watertight");
|
|
940
|
+
}
|
|
941
|
+
if (nonManifoldEdges > 0) {
|
|
942
|
+
errors.push(nonManifoldEdges + " non-manifold edge(s): edge shared by more than 2 polygons");
|
|
943
|
+
}
|
|
944
|
+
return {
|
|
945
|
+
ok: errors.length === 0,
|
|
946
|
+
errors,
|
|
947
|
+
warnings
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
function _noOp(csg) {
|
|
951
|
+
return csg;
|
|
952
|
+
}
|
|
953
|
+
function _makeAssertFn(warnEnabled) {
|
|
954
|
+
return function _assert(csg) {
|
|
955
|
+
var functionName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "unknown";
|
|
956
|
+
var moduleName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "unknown";
|
|
957
|
+
if (!csg || csg.polygons === undefined) return csg;
|
|
958
|
+
var result = validateCSG(csg);
|
|
959
|
+
if (!result.ok) {
|
|
960
|
+
throw new Error(moduleName + ":" + functionName + ": " + "invalid CSG: " + result.errors.join(", "));
|
|
961
|
+
}
|
|
962
|
+
if (warnEnabled && result.warnings.length > 0) {
|
|
963
|
+
throw new Error(moduleName + ":" + functionName + ": " + "CSG warnings: " + result.warnings.join(", "));
|
|
964
|
+
}
|
|
965
|
+
return csg;
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
var _assertFn = _noOp;
|
|
969
|
+
function _resolveFromGlobals() {
|
|
970
|
+
var enabled = typeof jscadUtilsAssertValidCSG !== "undefined" && !!jscadUtilsAssertValidCSG;
|
|
971
|
+
var warnEnabled = typeof jscadUtilsAssertValidCSGWarnings !== "undefined" && !!jscadUtilsAssertValidCSGWarnings;
|
|
972
|
+
return enabled ? _makeAssertFn(warnEnabled) : _noOp;
|
|
973
|
+
}
|
|
974
|
+
function AssertValidCSG() {
|
|
975
|
+
var moduleName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "unknown";
|
|
976
|
+
{
|
|
977
|
+
_assertFn = _resolveFromGlobals();
|
|
978
|
+
}
|
|
979
|
+
return function(csg, name) {
|
|
980
|
+
return _assertFn(csg, name, moduleName);
|
|
981
|
+
};
|
|
982
|
+
}
|
|
723
983
|
function init(proto) {
|
|
724
984
|
if (proto.prototype._jscadutilsinit) return;
|
|
725
985
|
proto.prototype.color = function(r, g, b, a) {
|
|
@@ -813,6 +1073,9 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
813
1073
|
proto.prototype.subtractIf = function subtractIf(object, condition) {
|
|
814
1074
|
return condition ? this.subtract(result(this, object)) : this;
|
|
815
1075
|
};
|
|
1076
|
+
proto.prototype.validate = function validate(options) {
|
|
1077
|
+
return validateCSG(this, options);
|
|
1078
|
+
};
|
|
816
1079
|
proto.prototype._translate = proto.prototype.translate;
|
|
817
1080
|
proto.prototype.translate = function translate() {
|
|
818
1081
|
if (arguments.length === 1) {
|
|
@@ -845,12 +1108,13 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
845
1108
|
__proto__: null,
|
|
846
1109
|
default: init
|
|
847
1110
|
});
|
|
848
|
-
var CSG = jsCadCSG__default["default"].CSG, CAG = jsCadCSG__default["default"].CAG;
|
|
1111
|
+
var CSG$1 = jsCadCSG__default["default"].CSG, CAG = jsCadCSG__default["default"].CAG;
|
|
849
1112
|
var rectangular_extrude = scadApi__default["default"].extrusions.rectangular_extrude;
|
|
850
1113
|
var _scadApi$text = scadApi__default["default"].text, vector_text = _scadApi$text.vector_text, vector_char = _scadApi$text.vector_char;
|
|
851
1114
|
var union = scadApi__default["default"].booleanOps.union;
|
|
852
|
-
init(CSG);
|
|
1115
|
+
init(CSG$1);
|
|
853
1116
|
var debug$3 = Debug("jscadUtils:group");
|
|
1117
|
+
var assertValidCSG$2 = AssertValidCSG("group");
|
|
854
1118
|
function JsCadUtilsGroup() {
|
|
855
1119
|
var names = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
856
1120
|
var parts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
@@ -901,7 +1165,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
901
1165
|
debug$3("combine mapPick", value, key, object);
|
|
902
1166
|
return map ? map(value, key, index, object) : identity(value);
|
|
903
1167
|
}, self.name));
|
|
904
|
-
return g.subtractIf(self.holes && Array.isArray(self.holes) ? union(self.holes) : self.holes, self.holes && !options.noholes);
|
|
1168
|
+
return assertValidCSG$2(g.subtractIf(self.holes && Array.isArray(self.holes) ? union(self.holes) : self.holes, self.holes && !options.noholes), "combine");
|
|
905
1169
|
} catch (err) {
|
|
906
1170
|
debug$3("combine error", this, pieces, options, err);
|
|
907
1171
|
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");
|
|
@@ -942,7 +1206,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
942
1206
|
});
|
|
943
1207
|
if (self.holes) {
|
|
944
1208
|
group.holes = toArray(self.holes).map(function(part) {
|
|
945
|
-
return map(CSG.fromPolygons(part.toPolygons()), "holes");
|
|
1209
|
+
return assertValidCSG$2(map(CSG$1.fromPolygons(part.toPolygons()), "holes"), "clone");
|
|
946
1210
|
});
|
|
947
1211
|
}
|
|
948
1212
|
return group;
|
|
@@ -961,7 +1225,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
961
1225
|
var rotationCenter = solid.centroid();
|
|
962
1226
|
var rotationAxis = axes[axis];
|
|
963
1227
|
self.map(function(part) {
|
|
964
|
-
return part.rotate(rotationCenter, rotationAxis, angle);
|
|
1228
|
+
return assertValidCSG$2(part.rotate(rotationCenter, rotationAxis, angle), "rotate");
|
|
965
1229
|
});
|
|
966
1230
|
return self;
|
|
967
1231
|
};
|
|
@@ -974,7 +1238,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
974
1238
|
var self = this;
|
|
975
1239
|
var t = calcSnap(self.combine(part), to, axis, orientation, delta);
|
|
976
1240
|
self.map(function(part) {
|
|
977
|
-
return part.translate(t);
|
|
1241
|
+
return assertValidCSG$2(part.translate(t), "snap");
|
|
978
1242
|
});
|
|
979
1243
|
return self;
|
|
980
1244
|
} catch (err) {
|
|
@@ -989,7 +1253,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
989
1253
|
noholes: true
|
|
990
1254
|
}), axis, to, delta);
|
|
991
1255
|
self.map(function(part) {
|
|
992
|
-
return part.translate(t);
|
|
1256
|
+
return assertValidCSG$2(part.translate(t), "align");
|
|
993
1257
|
});
|
|
994
1258
|
return self;
|
|
995
1259
|
} catch (err) {
|
|
@@ -1021,14 +1285,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1021
1285
|
var myConnector = connectorName.split(".").reduce(function(a, v) {
|
|
1022
1286
|
return a[v];
|
|
1023
1287
|
}, self.parts[partName].properties);
|
|
1024
|
-
debug$3("toConnector", to instanceof CSG.Connector);
|
|
1288
|
+
debug$3("toConnector", to instanceof CSG$1.Connector);
|
|
1025
1289
|
var toConnector = toConnectorName.split(".").reduce(function(a, v) {
|
|
1026
1290
|
return a[v];
|
|
1027
1291
|
}, to.properties);
|
|
1028
1292
|
var matrix = myConnector.getTransformationTo(toConnector, mirror, normalrotation);
|
|
1029
1293
|
debug$3("connectTo", matrix);
|
|
1030
1294
|
self.map(function(part) {
|
|
1031
|
-
return part.transform(matrix);
|
|
1295
|
+
return assertValidCSG$2(part.transform(matrix), "connectTo");
|
|
1032
1296
|
});
|
|
1033
1297
|
return self;
|
|
1034
1298
|
};
|
|
@@ -1039,7 +1303,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1039
1303
|
return to - size[a] / 2;
|
|
1040
1304
|
});
|
|
1041
1305
|
self.map(function(part) {
|
|
1042
|
-
return part.translate(t);
|
|
1306
|
+
return assertValidCSG$2(part.translate(t), "midlineTo");
|
|
1043
1307
|
});
|
|
1044
1308
|
return self;
|
|
1045
1309
|
};
|
|
@@ -1048,7 +1312,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1048
1312
|
var t = Array.isArray(x) ? x : [ x, y, z ];
|
|
1049
1313
|
debug$3("translate", t);
|
|
1050
1314
|
self.map(function(part) {
|
|
1051
|
-
return part.translate(t);
|
|
1315
|
+
return assertValidCSG$2(part.translate(t), "translate");
|
|
1052
1316
|
});
|
|
1053
1317
|
return self;
|
|
1054
1318
|
};
|
|
@@ -1058,7 +1322,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1058
1322
|
if (!map) map = identity;
|
|
1059
1323
|
var g = Group();
|
|
1060
1324
|
p.forEach(function(name) {
|
|
1061
|
-
g.add(map(CSG.fromPolygons(self.parts[name].toPolygons()), name), name);
|
|
1325
|
+
g.add(assertValidCSG$2(map(CSG$1.fromPolygons(self.parts[name].toPolygons()), name), "pick"), name);
|
|
1062
1326
|
});
|
|
1063
1327
|
return g;
|
|
1064
1328
|
};
|
|
@@ -1073,7 +1337,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1073
1337
|
debug$3("array error", _this, parts);
|
|
1074
1338
|
throw error('group::array error "'.concat(name, '" not found.\nthis: ').concat(_this, '\nparts: "').concat(parts, '"\n'), "JSCAD_UTILS_GROUP_ERROR");
|
|
1075
1339
|
}
|
|
1076
|
-
a.push(map(CSG.fromPolygons(self.parts[name].toPolygons()), name));
|
|
1340
|
+
a.push(assertValidCSG$2(map(CSG$1.fromPolygons(self.parts[name].toPolygons()), name), "array"));
|
|
1077
1341
|
});
|
|
1078
1342
|
return a;
|
|
1079
1343
|
};
|
|
@@ -1106,7 +1370,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1106
1370
|
self.names = names && names.length > 0 && names.split(",") || [];
|
|
1107
1371
|
if (Array.isArray(objects)) {
|
|
1108
1372
|
self.parts = zipObject(self.names, objects);
|
|
1109
|
-
} else if (objects instanceof CSG) {
|
|
1373
|
+
} else if (objects instanceof CSG$1) {
|
|
1110
1374
|
self.parts = zipObject(self.names, [ objects ]);
|
|
1111
1375
|
} else {
|
|
1112
1376
|
self.parts = objects || {};
|
|
@@ -1127,6 +1391,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1127
1391
|
return new JsCadUtilsGroup(self.names, self.parts, self.holes);
|
|
1128
1392
|
}
|
|
1129
1393
|
var debug$2 = Debug("jscadUtils:util");
|
|
1394
|
+
var assertValidCSG$1 = AssertValidCSG("util");
|
|
1130
1395
|
var NOZZEL_SIZE = .4;
|
|
1131
1396
|
var nearest = {
|
|
1132
1397
|
under: function under(desired) {
|
|
@@ -1203,12 +1468,12 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1203
1468
|
h: height || 2
|
|
1204
1469
|
}));
|
|
1205
1470
|
});
|
|
1206
|
-
return center(union(o));
|
|
1471
|
+
return assertValidCSG$1(center(union(o)), "label");
|
|
1207
1472
|
}
|
|
1208
1473
|
function text(text) {
|
|
1209
1474
|
var l = vector_char(0, 0, text);
|
|
1210
1475
|
var _char = l.segments.reduce(function(result, segment) {
|
|
1211
|
-
var path = new CSG.Path2D(segment);
|
|
1476
|
+
var path = new CSG$1.Path2D(segment);
|
|
1212
1477
|
var cag = path.expandToCAG(2);
|
|
1213
1478
|
return result ? result.union(cag) : cag;
|
|
1214
1479
|
}, undefined);
|
|
@@ -1216,17 +1481,17 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1216
1481
|
}
|
|
1217
1482
|
function unitCube(length, radius) {
|
|
1218
1483
|
radius = radius || .5;
|
|
1219
|
-
return CSG.cube({
|
|
1484
|
+
return assertValidCSG$1(CSG$1.cube({
|
|
1220
1485
|
center: [ 0, 0, 0 ],
|
|
1221
1486
|
radius: [ radius, radius, length || .5 ]
|
|
1222
|
-
});
|
|
1487
|
+
}), "unitCube");
|
|
1223
1488
|
}
|
|
1224
1489
|
function unitAxis(length, radius, centroid) {
|
|
1225
1490
|
debug$2("unitAxis", length, radius, centroid);
|
|
1226
1491
|
centroid = centroid || [ 0, 0, 0 ];
|
|
1227
1492
|
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) ]);
|
|
1228
|
-
unitaxis.properties.origin = new CSG.Connector([ 0, 0, 0 ], [ 1, 0, 0 ], [ 0, 1, 0 ]);
|
|
1229
|
-
return unitaxis.translate(centroid);
|
|
1493
|
+
unitaxis.properties.origin = new CSG$1.Connector([ 0, 0, 0 ], [ 1, 0, 0 ], [ 0, 1, 0 ]);
|
|
1494
|
+
return assertValidCSG$1(unitaxis.translate(centroid), "unitAxis");
|
|
1230
1495
|
}
|
|
1231
1496
|
function toArray(a) {
|
|
1232
1497
|
return Array.isArray(a) ? a : [ a ];
|
|
@@ -1316,15 +1581,15 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1316
1581
|
}
|
|
1317
1582
|
function center(object, objectSize) {
|
|
1318
1583
|
objectSize = objectSize || size(object.getBounds());
|
|
1319
|
-
return centerY(centerX(object, objectSize), objectSize);
|
|
1584
|
+
return assertValidCSG$1(centerY(centerX(object, objectSize), objectSize), "center");
|
|
1320
1585
|
}
|
|
1321
1586
|
function centerY(object, objectSize) {
|
|
1322
1587
|
objectSize = objectSize || size(object.getBounds());
|
|
1323
|
-
return object.translate([ 0, -objectSize.y / 2, 0 ]);
|
|
1588
|
+
return assertValidCSG$1(object.translate([ 0, -objectSize.y / 2, 0 ]), "centerY");
|
|
1324
1589
|
}
|
|
1325
1590
|
function centerX(object, objectSize) {
|
|
1326
1591
|
objectSize = objectSize || size(object.getBounds());
|
|
1327
|
-
return object.translate([ -objectSize.x / 2, 0, 0 ]);
|
|
1592
|
+
return assertValidCSG$1(object.translate([ -objectSize.x / 2, 0, 0 ]), "centerX");
|
|
1328
1593
|
}
|
|
1329
1594
|
function enlarge(object, x, y, z) {
|
|
1330
1595
|
var a;
|
|
@@ -1342,7 +1607,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1342
1607
|
var new_object = object.scale(t);
|
|
1343
1608
|
var new_centroid = centroid(new_object);
|
|
1344
1609
|
var delta = new_centroid.minus(objectCentroid).times(-1);
|
|
1345
|
-
return new_object.translate(delta);
|
|
1610
|
+
return assertValidCSG$1(new_object.translate(delta), "enlarge");
|
|
1346
1611
|
}
|
|
1347
1612
|
function fit(object, x, y, z, keep_aspect_ratio) {
|
|
1348
1613
|
var a;
|
|
@@ -1362,10 +1627,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1362
1627
|
}
|
|
1363
1628
|
var s = [ scale(objectSize.x, x), scale(objectSize.y, y), scale(objectSize.z, z) ];
|
|
1364
1629
|
var min$1 = min(s);
|
|
1365
|
-
return centerWith(object.scale(s.map(function(d, i) {
|
|
1630
|
+
return assertValidCSG$1(centerWith(object.scale(s.map(function(d, i) {
|
|
1366
1631
|
if (a[i] === 0) return 1;
|
|
1367
1632
|
return keep_aspect_ratio ? min$1 : d;
|
|
1368
|
-
})), "xyz", object);
|
|
1633
|
+
})), "xyz", object), "fit");
|
|
1369
1634
|
}
|
|
1370
1635
|
function shift(object, x, y, z) {
|
|
1371
1636
|
var hsize = this.div(this.size(object.getBounds()), 2);
|
|
@@ -1373,10 +1638,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1373
1638
|
}
|
|
1374
1639
|
function zero(object) {
|
|
1375
1640
|
var bounds = object.getBounds();
|
|
1376
|
-
return object.translate([ 0, 0, -bounds[0].z ]);
|
|
1641
|
+
return assertValidCSG$1(object.translate([ 0, 0, -bounds[0].z ]), "zero");
|
|
1377
1642
|
}
|
|
1378
1643
|
function mirrored4(x) {
|
|
1379
|
-
return x.union([ x.mirroredY(90), x.mirroredX(90), x.mirroredY(90).mirroredX(90) ]);
|
|
1644
|
+
return assertValidCSG$1(x.union([ x.mirroredY(90), x.mirroredX(90), x.mirroredY(90).mirroredX(90) ]), "mirrored4");
|
|
1380
1645
|
}
|
|
1381
1646
|
var flushSide = {
|
|
1382
1647
|
"above-outside": [ 1, 0 ],
|
|
@@ -1437,10 +1702,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1437
1702
|
function snap(moveobj, withobj, axis, orientation, delta) {
|
|
1438
1703
|
debug$2("snap", moveobj, withobj, axis, orientation, delta);
|
|
1439
1704
|
var t = calcSnap(moveobj, withobj, axis, orientation, delta);
|
|
1440
|
-
return moveobj.translate(t);
|
|
1705
|
+
return assertValidCSG$1(moveobj.translate(t), "snap");
|
|
1441
1706
|
}
|
|
1442
1707
|
function flush(moveobj, withobj, axis, mside, wside) {
|
|
1443
|
-
return moveobj.translate(calcFlush(moveobj, withobj, axis, mside, wside));
|
|
1708
|
+
return assertValidCSG$1(moveobj.translate(calcFlush(moveobj, withobj, axis, mside, wside)), "flush");
|
|
1444
1709
|
}
|
|
1445
1710
|
function axisApply(axes, valfun, a) {
|
|
1446
1711
|
debug$2("axisApply", axes, valfun, a);
|
|
@@ -1456,7 +1721,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1456
1721
|
return retval;
|
|
1457
1722
|
}
|
|
1458
1723
|
function axis2array(axes, valfun) {
|
|
1459
|
-
depreciated("axis2array");
|
|
1724
|
+
depreciated("axis2array", false, "Use axisApply instead.");
|
|
1460
1725
|
var a = [ 0, 0, 0 ];
|
|
1461
1726
|
var lookup = {
|
|
1462
1727
|
x: 0,
|
|
@@ -1486,7 +1751,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1486
1751
|
});
|
|
1487
1752
|
}
|
|
1488
1753
|
function midlineTo(o, axis, to) {
|
|
1489
|
-
return o.translate(calcmidlineTo(o, axis, to));
|
|
1754
|
+
return assertValidCSG$1(o.translate(calcmidlineTo(o, axis, to)), "midlineTo");
|
|
1490
1755
|
}
|
|
1491
1756
|
function translator(o, axis, withObj) {
|
|
1492
1757
|
var objectCentroid = centroid(o);
|
|
@@ -1506,7 +1771,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1506
1771
|
return delta ? add(t, delta) : t;
|
|
1507
1772
|
}
|
|
1508
1773
|
function centerWith(o, axis, withObj) {
|
|
1509
|
-
return o.translate(calcCenterWith(o, axis, withObj));
|
|
1774
|
+
return assertValidCSG$1(o.translate(calcCenterWith(o, axis, withObj)), "centerWith");
|
|
1510
1775
|
}
|
|
1511
1776
|
function getDelta(size, bounds, axis, offset, nonzero) {
|
|
1512
1777
|
if (!isEmpty(offset) && nonzero) {
|
|
@@ -1519,6 +1784,95 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1519
1784
|
return bounds[0][a] + (isEmpty(dist) ? size[axis] / 2 : dist);
|
|
1520
1785
|
});
|
|
1521
1786
|
}
|
|
1787
|
+
var EPS = 1e-5;
|
|
1788
|
+
function splitCSGByPlane(csg, plane) {
|
|
1789
|
+
var frontPolys = [];
|
|
1790
|
+
var backPolys = [];
|
|
1791
|
+
csg.polygons.forEach(function(poly) {
|
|
1792
|
+
var vertices = poly.vertices;
|
|
1793
|
+
var numVerts = vertices.length;
|
|
1794
|
+
var hasfront = false;
|
|
1795
|
+
var hasback = false;
|
|
1796
|
+
var vertexIsBack = [];
|
|
1797
|
+
for (var i = 0; i < numVerts; i++) {
|
|
1798
|
+
var t = plane.normal.dot(vertices[i].pos) - plane.w;
|
|
1799
|
+
vertexIsBack.push(t < 0);
|
|
1800
|
+
if (t > EPS) hasfront = true;
|
|
1801
|
+
if (t < -EPS) hasback = true;
|
|
1802
|
+
}
|
|
1803
|
+
if (!hasfront && !hasback) {
|
|
1804
|
+
var d = plane.normal.dot(poly.plane.normal);
|
|
1805
|
+
if (d >= 0) {
|
|
1806
|
+
frontPolys.push(poly);
|
|
1807
|
+
} else {
|
|
1808
|
+
backPolys.push(poly);
|
|
1809
|
+
}
|
|
1810
|
+
} else if (!hasback) {
|
|
1811
|
+
frontPolys.push(poly);
|
|
1812
|
+
} else if (!hasfront) {
|
|
1813
|
+
backPolys.push(poly);
|
|
1814
|
+
} else {
|
|
1815
|
+
var fv = [];
|
|
1816
|
+
var bv = [];
|
|
1817
|
+
for (var vi = 0; vi < numVerts; vi++) {
|
|
1818
|
+
var vertex = vertices[vi];
|
|
1819
|
+
var nextVi = (vi + 1) % numVerts;
|
|
1820
|
+
var isback = vertexIsBack[vi];
|
|
1821
|
+
var nextisback = vertexIsBack[nextVi];
|
|
1822
|
+
if (isback === nextisback) {
|
|
1823
|
+
if (isback) {
|
|
1824
|
+
bv.push(vertex);
|
|
1825
|
+
} else {
|
|
1826
|
+
fv.push(vertex);
|
|
1827
|
+
}
|
|
1828
|
+
} else {
|
|
1829
|
+
var point = vertex.pos;
|
|
1830
|
+
var nextpoint = vertices[nextVi].pos;
|
|
1831
|
+
var ip = plane.splitLineBetweenPoints(point, nextpoint);
|
|
1832
|
+
var iv = new CSG$1.Vertex(ip);
|
|
1833
|
+
if (isback) {
|
|
1834
|
+
bv.push(vertex);
|
|
1835
|
+
bv.push(iv);
|
|
1836
|
+
fv.push(iv);
|
|
1837
|
+
} else {
|
|
1838
|
+
fv.push(vertex);
|
|
1839
|
+
fv.push(iv);
|
|
1840
|
+
bv.push(iv);
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
var EPSEPS = EPS * EPS;
|
|
1845
|
+
if (fv.length >= 3) {
|
|
1846
|
+
var prev = fv[fv.length - 1];
|
|
1847
|
+
for (var fi = 0; fi < fv.length; fi++) {
|
|
1848
|
+
var curr = fv[fi];
|
|
1849
|
+
if (curr.pos.distanceToSquared(prev.pos) < EPSEPS) {
|
|
1850
|
+
fv.splice(fi, 1);
|
|
1851
|
+
fi--;
|
|
1852
|
+
}
|
|
1853
|
+
prev = curr;
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
if (bv.length >= 3) {
|
|
1857
|
+
var prev = bv[bv.length - 1];
|
|
1858
|
+
for (var bi = 0; bi < bv.length; bi++) {
|
|
1859
|
+
var curr = bv[bi];
|
|
1860
|
+
if (curr.pos.distanceToSquared(prev.pos) < EPSEPS) {
|
|
1861
|
+
bv.splice(bi, 1);
|
|
1862
|
+
bi--;
|
|
1863
|
+
}
|
|
1864
|
+
prev = curr;
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
if (fv.length >= 3) frontPolys.push(new CSG$1.Polygon(fv, poly.shared, poly.plane));
|
|
1868
|
+
if (bv.length >= 3) backPolys.push(new CSG$1.Polygon(bv, poly.shared, poly.plane));
|
|
1869
|
+
}
|
|
1870
|
+
});
|
|
1871
|
+
return {
|
|
1872
|
+
front: CSG$1.fromPolygons(frontPolys),
|
|
1873
|
+
back: CSG$1.fromPolygons(backPolys)
|
|
1874
|
+
};
|
|
1875
|
+
}
|
|
1522
1876
|
function bisect() {
|
|
1523
1877
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1524
1878
|
args[_key] = arguments[_key];
|
|
@@ -1580,13 +1934,13 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1580
1934
|
}[[ axis, rotateaxis ].sort().join("")];
|
|
1581
1935
|
var centroid = object.centroid();
|
|
1582
1936
|
var rotateDelta = getDelta(objectSize, bounds, rotateOffsetAxis, rotateoffset);
|
|
1583
|
-
var rotationCenter = options.rotationCenter || new CSG.Vector3D(axisApply("xyz", function(i, a) {
|
|
1937
|
+
var rotationCenter = options.rotationCenter || new CSG$1.Vector3D(axisApply("xyz", function(i, a) {
|
|
1584
1938
|
if (a == axis) return cutDelta[i];
|
|
1585
1939
|
if (a == rotateOffsetAxis) return rotateDelta[i];
|
|
1586
1940
|
return centroid[a];
|
|
1587
1941
|
}));
|
|
1588
1942
|
var theRotationAxis = rotationAxes[rotateaxis];
|
|
1589
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).translate(cutDelta).rotate(rotationCenter, theRotationAxis, angle);
|
|
1943
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).translate(cutDelta).rotate(rotationCenter, theRotationAxis, angle);
|
|
1590
1944
|
debug$2("bisect", debug$2.enabled && {
|
|
1591
1945
|
axis,
|
|
1592
1946
|
offset,
|
|
@@ -1599,7 +1953,26 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1599
1953
|
cutplane,
|
|
1600
1954
|
options
|
|
1601
1955
|
});
|
|
1602
|
-
var
|
|
1956
|
+
var negative = object.cutByPlane(cutplane.plane);
|
|
1957
|
+
var positive = object.cutByPlane(cutplane.plane.flipped());
|
|
1958
|
+
var negSize = size(negative);
|
|
1959
|
+
var posSize = size(positive);
|
|
1960
|
+
if (negSize[axis] >= objectSize[axis] - EPS || posSize[axis] >= objectSize[axis] - EPS) {
|
|
1961
|
+
var halves = splitCSGByPlane(object, cutplane.plane);
|
|
1962
|
+
if (negSize[axis] >= objectSize[axis] - EPS) {
|
|
1963
|
+
negative = halves.back;
|
|
1964
|
+
try {
|
|
1965
|
+
negative = negative.cutByPlane(cutplane.plane);
|
|
1966
|
+
} catch (e) {}
|
|
1967
|
+
}
|
|
1968
|
+
if (posSize[axis] >= objectSize[axis] - EPS) {
|
|
1969
|
+
positive = halves.front;
|
|
1970
|
+
try {
|
|
1971
|
+
positive = positive.cutByPlane(cutplane.plane.flipped());
|
|
1972
|
+
} catch (e) {}
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
var g = Group("negative,positive", [ negative.color(options.color && "red"), positive.color(options.color && "blue") ]);
|
|
1603
1976
|
if (options.addRotationCenter) g.add(unitAxis(objectSize.length() + 10, .1, rotationCenter), "rotationCenter");
|
|
1604
1977
|
return g;
|
|
1605
1978
|
}
|
|
@@ -1612,9 +1985,9 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1612
1985
|
addRotationCenter: true
|
|
1613
1986
|
};
|
|
1614
1987
|
var info = normalVector(axis);
|
|
1615
|
-
var rotationCenter = options.rotationCenter || new CSG.Vector3D(0, 0, 0);
|
|
1988
|
+
var rotationCenter = options.rotationCenter || new CSG$1.Vector3D(0, 0, 0);
|
|
1616
1989
|
var theRotationAxis = rotationAxes[rotateaxis];
|
|
1617
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).rotate(rotationCenter, theRotationAxis, angle);
|
|
1990
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).rotate(rotationCenter, theRotationAxis, angle);
|
|
1618
1991
|
var g = Group("negative,positive", [ object.cutByPlane(cutplane.plane).color(options.color && "red"), object.cutByPlane(cutplane.plane.flipped()).color(options.color && "blue") ]);
|
|
1619
1992
|
if (options.addRotationCenter) {
|
|
1620
1993
|
var objectSize = size(object);
|
|
@@ -1639,14 +2012,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1639
2012
|
var bounds = object.getBounds();
|
|
1640
2013
|
var objectSize = size(object);
|
|
1641
2014
|
var cutDelta = getDelta(objectSize, bounds, axis, offset, true);
|
|
1642
|
-
return object.stretchAtPlane(normal[axis], cutDelta, distance);
|
|
2015
|
+
return assertValidCSG$1(object.stretchAtPlane(normal[axis], cutDelta, distance), "stretch");
|
|
1643
2016
|
}
|
|
1644
2017
|
function poly2solid(top, bottom, height) {
|
|
1645
2018
|
if (top.sides.length == 0) {
|
|
1646
|
-
return new CSG;
|
|
2019
|
+
return new CSG$1;
|
|
1647
2020
|
}
|
|
1648
|
-
var offsetVector = CSG.Vector3D.Create(0, 0, height);
|
|
1649
|
-
var normalVector = CSG.Vector3D.Create(0, 1, 0);
|
|
2021
|
+
var offsetVector = CSG$1.Vector3D.Create(0, 0, height);
|
|
2022
|
+
var normalVector = CSG$1.Vector3D.Create(0, 1, 0);
|
|
1650
2023
|
var polygons = [];
|
|
1651
2024
|
polygons = polygons.concat(bottom._toPlanePolygons({
|
|
1652
2025
|
translation: [ 0, 0, 0 ],
|
|
@@ -1658,14 +2031,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1658
2031
|
normalVector,
|
|
1659
2032
|
flipped: offsetVector.z < 0
|
|
1660
2033
|
}));
|
|
1661
|
-
var c1 = new CSG.Connector(offsetVector.times(0), [ 0, 0, offsetVector.z ], normalVector);
|
|
1662
|
-
var c2 = new CSG.Connector(offsetVector, [ 0, 0, offsetVector.z ], normalVector);
|
|
2034
|
+
var c1 = new CSG$1.Connector(offsetVector.times(0), [ 0, 0, offsetVector.z ], normalVector);
|
|
2035
|
+
var c2 = new CSG$1.Connector(offsetVector, [ 0, 0, offsetVector.z ], normalVector);
|
|
1663
2036
|
polygons = polygons.concat(bottom._toWallPolygons({
|
|
1664
2037
|
cag: top,
|
|
1665
2038
|
toConnector1: c1,
|
|
1666
2039
|
toConnector2: c2
|
|
1667
2040
|
}));
|
|
1668
|
-
return CSG.fromPolygons(polygons);
|
|
2041
|
+
return assertValidCSG$1(CSG$1.fromPolygons(polygons), "poly2solid");
|
|
1669
2042
|
}
|
|
1670
2043
|
function slices2poly(slices, options, axis) {
|
|
1671
2044
|
debug$2("slices2poly", slices, options, axis);
|
|
@@ -1674,7 +2047,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1674
2047
|
twiststeps: 0
|
|
1675
2048
|
}, options);
|
|
1676
2049
|
var twistangle = options && parseFloat(options.twistangle) || 0;
|
|
1677
|
-
options && parseInt(options.twiststeps) || CSG.defaultResolution3D;
|
|
2050
|
+
options && parseInt(options.twiststeps) || CSG$1.defaultResolution3D;
|
|
1678
2051
|
var normalVector = options.si.normalVector;
|
|
1679
2052
|
var polygons = [];
|
|
1680
2053
|
var first$1 = first(slices);
|
|
@@ -1703,8 +2076,8 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1703
2076
|
var nextidx = idx + 1;
|
|
1704
2077
|
var top = !up ? slices[nextidx] : slice;
|
|
1705
2078
|
var bottom = up ? slices[nextidx] : slice;
|
|
1706
|
-
var c1 = new CSG.Connector(bottom.offset, connectorAxis, rotate(normalVector, twistangle, idx / slices.length));
|
|
1707
|
-
var c2 = new CSG.Connector(top.offset, connectorAxis, rotate(normalVector, twistangle, nextidx / slices.length));
|
|
2079
|
+
var c1 = new CSG$1.Connector(bottom.offset, connectorAxis, rotate(normalVector, twistangle, idx / slices.length));
|
|
2080
|
+
var c2 = new CSG$1.Connector(top.offset, connectorAxis, rotate(normalVector, twistangle, nextidx / slices.length));
|
|
1708
2081
|
polygons = polygons.concat(bottom.poly._toWallPolygons({
|
|
1709
2082
|
cag: top.poly,
|
|
1710
2083
|
toConnector1: c1,
|
|
@@ -1712,21 +2085,21 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1712
2085
|
}));
|
|
1713
2086
|
}
|
|
1714
2087
|
});
|
|
1715
|
-
return CSG.fromPolygons(polygons);
|
|
2088
|
+
return assertValidCSG$1(CSG$1.fromPolygons(polygons), "slices2poly");
|
|
1716
2089
|
}
|
|
1717
2090
|
function normalVector(axis) {
|
|
1718
2091
|
var axisInfo = {
|
|
1719
2092
|
z: {
|
|
1720
2093
|
orthoNormalCartesian: [ "X", "Y" ],
|
|
1721
|
-
normalVector: CSG.Vector3D.Create(0, 1, 0)
|
|
2094
|
+
normalVector: CSG$1.Vector3D.Create(0, 1, 0)
|
|
1722
2095
|
},
|
|
1723
2096
|
x: {
|
|
1724
2097
|
orthoNormalCartesian: [ "Y", "Z" ],
|
|
1725
|
-
normalVector: CSG.Vector3D.Create(0, 0, 1)
|
|
2098
|
+
normalVector: CSG$1.Vector3D.Create(0, 0, 1)
|
|
1726
2099
|
},
|
|
1727
2100
|
y: {
|
|
1728
|
-
orthoNormalCartesian: [ "
|
|
1729
|
-
normalVector: CSG.Vector3D.Create(0, 0, 1)
|
|
2101
|
+
orthoNormalCartesian: [ "Z", "X" ],
|
|
2102
|
+
normalVector: CSG$1.Vector3D.Create(0, 0, 1)
|
|
1730
2103
|
}
|
|
1731
2104
|
};
|
|
1732
2105
|
if (!axisInfo[axis]) error("normalVector: invalid axis " + axis);
|
|
@@ -1767,7 +2140,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1767
2140
|
var si = sliceParams(orientation, radius, b);
|
|
1768
2141
|
debug$2("reShape", absoluteRadius, si);
|
|
1769
2142
|
if (si.axis !== "z") throw new Error('reShape error: CAG._toPlanePolygons only uses the "z" axis. You must use the "z" axis for now.');
|
|
1770
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(si.orthoNormalCartesian[0], si.orthoNormalCartesian[1]).translate(si.cutDelta);
|
|
2143
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(si.orthoNormalCartesian[0], si.orthoNormalCartesian[1]).translate(si.cutDelta);
|
|
1771
2144
|
var slice = object.sectionCut(cutplane);
|
|
1772
2145
|
var first = axisApply(si.axis, function() {
|
|
1773
2146
|
return si.positive ? 0 : absoluteRadius;
|
|
@@ -1782,25 +2155,25 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1782
2155
|
si
|
|
1783
2156
|
}), si.axis).color(options.color);
|
|
1784
2157
|
var remainder = object.cutByPlane(plane);
|
|
1785
|
-
return union([ options.unionOriginal ? object : remainder, delta.translate(si.moveDelta) ]);
|
|
2158
|
+
return assertValidCSG$1(union([ options.unionOriginal ? object : remainder, delta.translate(si.moveDelta) ]), "reShape");
|
|
1786
2159
|
}
|
|
1787
2160
|
function chamfer(object, radius, orientation, options) {
|
|
1788
|
-
return reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
2161
|
+
return assertValidCSG$1(reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
1789
2162
|
return [ {
|
|
1790
2163
|
poly: slice,
|
|
1791
|
-
offset: new CSG.Vector3D(first)
|
|
2164
|
+
offset: new CSG$1.Vector3D(first)
|
|
1792
2165
|
}, {
|
|
1793
2166
|
poly: enlarge(slice, [ -radius * 2, -radius * 2 ]),
|
|
1794
|
-
offset: new CSG.Vector3D(last)
|
|
2167
|
+
offset: new CSG$1.Vector3D(last)
|
|
1795
2168
|
} ];
|
|
1796
|
-
});
|
|
2169
|
+
}), "chamfer");
|
|
1797
2170
|
}
|
|
1798
2171
|
function fillet(object, radius, orientation, options) {
|
|
1799
2172
|
options = options || {};
|
|
1800
|
-
return reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
1801
|
-
var v1 = new CSG.Vector3D(first);
|
|
1802
|
-
var v2 = new CSG.Vector3D(last);
|
|
1803
|
-
var res = options.resolution || CSG.defaultResolution3D;
|
|
2173
|
+
return assertValidCSG$1(reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
2174
|
+
var v1 = new CSG$1.Vector3D(first);
|
|
2175
|
+
var v2 = new CSG$1.Vector3D(last);
|
|
2176
|
+
var res = options.resolution || CSG$1.defaultResolution3D;
|
|
1804
2177
|
var slices = range(0, res).map(function(i) {
|
|
1805
2178
|
var p = i > 0 ? i / (res - 1) : 0;
|
|
1806
2179
|
var v = v1.lerp(v2, p);
|
|
@@ -1811,7 +2184,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1811
2184
|
};
|
|
1812
2185
|
});
|
|
1813
2186
|
return slices;
|
|
1814
|
-
});
|
|
2187
|
+
}), "fillet");
|
|
1815
2188
|
}
|
|
1816
2189
|
function calcRotate(part, solid, axis) {
|
|
1817
2190
|
var axes = {
|
|
@@ -1828,7 +2201,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1828
2201
|
}
|
|
1829
2202
|
function rotateAround(part, solid, axis, angle) {
|
|
1830
2203
|
var _calcRotate = calcRotate(part, solid, axis), rotationCenter = _calcRotate.rotationCenter, rotationAxis = _calcRotate.rotationAxis;
|
|
1831
|
-
return part.rotate(rotationCenter, rotationAxis, angle);
|
|
2204
|
+
return assertValidCSG$1("rotateAround")(part.rotate(rotationCenter, rotationAxis, angle));
|
|
1832
2205
|
}
|
|
1833
2206
|
function cloneProperties(from, to) {
|
|
1834
2207
|
return Object.entries(from).reduce(function(props, _ref) {
|
|
@@ -1838,19 +2211,20 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1838
2211
|
}, to);
|
|
1839
2212
|
}
|
|
1840
2213
|
function clone(o) {
|
|
1841
|
-
var c = CSG.fromPolygons(o.toPolygons());
|
|
2214
|
+
var c = CSG$1.fromPolygons(o.toPolygons());
|
|
1842
2215
|
cloneProperties(o, c);
|
|
1843
|
-
debug$2("clone", o, c, CSG);
|
|
1844
|
-
return c;
|
|
2216
|
+
debug$2("clone", o, c, CSG$1);
|
|
2217
|
+
return assertValidCSG$1(c, "clone");
|
|
1845
2218
|
}
|
|
1846
2219
|
function addConnector(object, name) {
|
|
1847
2220
|
var point = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [ 0, 0, 0 ];
|
|
1848
2221
|
var axis = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [ 1, 0, 0 ];
|
|
1849
2222
|
var normal = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [ 0, 0, 1 ];
|
|
1850
|
-
object.properties[name] = new CSG.Connector(point, axis, normal);
|
|
1851
|
-
return object;
|
|
2223
|
+
object.properties[name] = new CSG$1.Connector(point, axis, normal);
|
|
2224
|
+
return assertValidCSG$1("addConnector")(object);
|
|
1852
2225
|
}
|
|
1853
2226
|
var debug$1 = Debug("jscadUtils:parts");
|
|
2227
|
+
var assertValidCSG = AssertValidCSG("parts");
|
|
1854
2228
|
var parts = {
|
|
1855
2229
|
BBox: BBox$1,
|
|
1856
2230
|
Cube,
|
|
@@ -1860,7 +2234,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1860
2234
|
};
|
|
1861
2235
|
function BBox$1() {
|
|
1862
2236
|
function box(object) {
|
|
1863
|
-
return CSG.cube({
|
|
2237
|
+
return CSG$1.cube({
|
|
1864
2238
|
center: object.centroid(),
|
|
1865
2239
|
radius: object.size().dividedBy(2)
|
|
1866
2240
|
});
|
|
@@ -1868,17 +2242,17 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1868
2242
|
for (var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1869
2243
|
objects[_key] = arguments[_key];
|
|
1870
2244
|
}
|
|
1871
|
-
return objects.reduce(function(bbox, part) {
|
|
2245
|
+
return assertValidCSG(objects.reduce(function(bbox, part) {
|
|
1872
2246
|
var object = bbox ? union([ bbox, box(part) ]) : part;
|
|
1873
2247
|
return box(object);
|
|
1874
|
-
}, undefined);
|
|
2248
|
+
}, undefined), "BBox");
|
|
1875
2249
|
}
|
|
1876
2250
|
function Cube(width) {
|
|
1877
2251
|
var r = div$1(fromxyz(width), 2);
|
|
1878
|
-
return CSG.cube({
|
|
2252
|
+
return assertValidCSG(CSG$1.cube({
|
|
1879
2253
|
center: r,
|
|
1880
2254
|
radius: r
|
|
1881
|
-
});
|
|
2255
|
+
}), "Cube");
|
|
1882
2256
|
}
|
|
1883
2257
|
function RoundedCube(x, y, thickness, corner_radius) {
|
|
1884
2258
|
if (x.getBounds) {
|
|
@@ -1894,11 +2268,11 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1894
2268
|
center: [ r[0], r[1], 0 ],
|
|
1895
2269
|
radius: r,
|
|
1896
2270
|
roundradius: corner_radius,
|
|
1897
|
-
resolution: CSG.defaultResolution2D
|
|
2271
|
+
resolution: CSG$1.defaultResolution2D
|
|
1898
2272
|
}).extrude({
|
|
1899
2273
|
offset: [ 0, 0, thickness || 1.62 ]
|
|
1900
2274
|
});
|
|
1901
|
-
return roundedcube;
|
|
2275
|
+
return assertValidCSG(roundedcube, "RoundedCube");
|
|
1902
2276
|
}
|
|
1903
2277
|
function Cylinder(diameter, height) {
|
|
1904
2278
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
@@ -1907,39 +2281,39 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1907
2281
|
start: [ 0, 0, 0 ],
|
|
1908
2282
|
end: [ 0, 0, height ],
|
|
1909
2283
|
radius: diameter / 2,
|
|
1910
|
-
resolution: CSG.defaultResolution2D
|
|
2284
|
+
resolution: CSG$1.defaultResolution2D
|
|
1911
2285
|
}, options);
|
|
1912
|
-
return CSG.cylinder(options);
|
|
2286
|
+
return assertValidCSG(CSG$1.cylinder(options), "Cylinder");
|
|
1913
2287
|
}
|
|
1914
2288
|
function Cone(diameter1, diameter2, height) {
|
|
1915
2289
|
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
1916
2290
|
debug$1("parts.Cone", diameter1, diameter2, height, options);
|
|
1917
|
-
return CSG.cylinder(Object.assign({
|
|
2291
|
+
return assertValidCSG(CSG$1.cylinder(Object.assign({
|
|
1918
2292
|
start: [ 0, 0, 0 ],
|
|
1919
2293
|
end: [ 0, 0, height ],
|
|
1920
2294
|
radiusStart: diameter1 / 2,
|
|
1921
2295
|
radiusEnd: diameter2 / 2,
|
|
1922
|
-
resolution: CSG.defaultResolution2D
|
|
1923
|
-
}, options));
|
|
2296
|
+
resolution: CSG$1.defaultResolution2D
|
|
2297
|
+
}, options)), "Cone");
|
|
1924
2298
|
}
|
|
1925
2299
|
function Hexagon(diameter, height) {
|
|
1926
2300
|
debug$1("hexagon", diameter, height);
|
|
1927
2301
|
var radius = diameter / 2;
|
|
1928
2302
|
var sqrt3 = Math.sqrt(3) / 2;
|
|
1929
2303
|
var hex = CAG.fromPoints([ [ radius, 0 ], [ radius / 2, radius * sqrt3 ], [ -radius / 2, radius * sqrt3 ], [ -radius, 0 ], [ -radius / 2, -radius * sqrt3 ], [ radius / 2, -radius * sqrt3 ] ]);
|
|
1930
|
-
return hex.extrude({
|
|
2304
|
+
return assertValidCSG(hex.extrude({
|
|
1931
2305
|
offset: [ 0, 0, height ]
|
|
1932
|
-
});
|
|
2306
|
+
}), "Hexagon");
|
|
1933
2307
|
}
|
|
1934
2308
|
function Triangle(base, height) {
|
|
1935
2309
|
var radius = base / 2;
|
|
1936
2310
|
var tri = CAG.fromPoints([ [ -radius, 0 ], [ radius, 0 ], [ 0, Math.sin(30) * radius ] ]);
|
|
1937
|
-
return tri.extrude({
|
|
2311
|
+
return assertValidCSG(tri.extrude({
|
|
1938
2312
|
offset: [ 0, 0, height ]
|
|
1939
|
-
});
|
|
2313
|
+
}), "Triangle");
|
|
1940
2314
|
}
|
|
1941
2315
|
function Tube(outsideDiameter, insideDiameter, height, outsideOptions, insideOptions) {
|
|
1942
|
-
return Cylinder(outsideDiameter, height, outsideOptions).subtract(Cylinder(insideDiameter, height, insideOptions || outsideOptions));
|
|
2316
|
+
return assertValidCSG(Cylinder(outsideDiameter, height, outsideOptions).subtract(Cylinder(insideDiameter, height, insideOptions || outsideOptions)), "Tube");
|
|
1943
2317
|
}
|
|
1944
2318
|
function Anchor() {
|
|
1945
2319
|
var width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
|
|
@@ -1957,11 +2331,11 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1957
2331
|
center: [ r[0], r[1], 0 ],
|
|
1958
2332
|
radius: r,
|
|
1959
2333
|
roundradius: corner_radius,
|
|
1960
|
-
resolution: CSG.defaultResolution2D
|
|
2334
|
+
resolution: CSG$1.defaultResolution2D
|
|
1961
2335
|
}).extrude({
|
|
1962
2336
|
offset: [ 0, 0, thickness || 1.62 ]
|
|
1963
2337
|
});
|
|
1964
|
-
return board;
|
|
2338
|
+
return assertValidCSG(board, "Board");
|
|
1965
2339
|
}
|
|
1966
2340
|
var Hardware = {
|
|
1967
2341
|
Orientation: {
|
|
@@ -2052,6 +2426,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2052
2426
|
gap = gap || .25;
|
|
2053
2427
|
var inside = thickness - gap;
|
|
2054
2428
|
var outside = -thickness + gap;
|
|
2429
|
+
var boxHeight = box.size().z;
|
|
2430
|
+
if (Math.abs(height) >= boxHeight) {
|
|
2431
|
+
throw new Error("Rabett: height (".concat(height, ") must be less than the object height (").concat(boxHeight, ")"));
|
|
2432
|
+
}
|
|
2055
2433
|
debug("inside", inside, "outside", outside);
|
|
2056
2434
|
var group = Group();
|
|
2057
2435
|
var _box$bisect$parts = box.bisect("z", height, options).parts, top = _box$bisect$parts.positive, lower2_3rd = _box$bisect$parts.negative;
|
|
@@ -2122,10 +2500,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2122
2500
|
thickness = thickness || 2;
|
|
2123
2501
|
var s = div$1(xyz2array(size), 2);
|
|
2124
2502
|
var r = add(s, thickness);
|
|
2125
|
-
var box = CSG.cube({
|
|
2503
|
+
var box = CSG$1.cube({
|
|
2126
2504
|
center: r,
|
|
2127
2505
|
radius: r
|
|
2128
|
-
}).subtract(CSG.cube({
|
|
2506
|
+
}).subtract(CSG$1.cube({
|
|
2129
2507
|
center: r,
|
|
2130
2508
|
radius: s
|
|
2131
2509
|
}));
|
|
@@ -2143,7 +2521,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2143
2521
|
var BBox = function BBox(o) {
|
|
2144
2522
|
depreciated("BBox", true, "Use 'parts.BBox' instead");
|
|
2145
2523
|
var s = div$1(xyz2array(o.size()), 2);
|
|
2146
|
-
return CSG.cube({
|
|
2524
|
+
return CSG$1.cube({
|
|
2147
2525
|
center: s,
|
|
2148
2526
|
radius: s
|
|
2149
2527
|
}).align(o, "xyz");
|
|
@@ -2155,7 +2533,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2155
2533
|
var gap = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : .25;
|
|
2156
2534
|
var r = add(getRadius(box), -thickness / 2);
|
|
2157
2535
|
r[2] = thickness / 2;
|
|
2158
|
-
var cutter = CSG.cube({
|
|
2536
|
+
var cutter = CSG$1.cube({
|
|
2159
2537
|
center: r,
|
|
2160
2538
|
radius: r
|
|
2161
2539
|
}).align(box, "xy").color("green");
|