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