@jwc/jscad-utils 5.2.0 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -5
- package/dist/compat.js +641 -100
- package/dist/examples/bisect.jscad +471 -93
- package/dist/examples/bisect2.jscad +2614 -0
- package/dist/examples/boxes.jscad +481 -102
- package/dist/examples/chamfer.jscad +471 -93
- package/dist/examples/fillet.jscad +471 -93
- package/dist/examples/fit.jscad +471 -93
- package/dist/examples/groups.jscad +471 -93
- package/dist/examples/midlineTo.jscad +471 -93
- package/dist/examples/parts-hexagon.jscad +471 -93
- package/dist/examples/rabett-tb.jscad +471 -93
- package/dist/examples/rabett.jscad +471 -93
- package/dist/examples/rabett2.jscad +471 -93
- package/dist/examples/rabett3.jscad +2614 -0
- package/dist/examples/retraction-test.jscad +471 -93
- package/dist/examples/size.jscad +471 -93
- package/dist/examples/snap.jscad +471 -93
- package/dist/examples/text.jscad +471 -93
- package/dist/examples/wedge.jscad +471 -93
- package/dist/index.js +638 -100
- package/package.json +8 -4
- package/src/add-prototype.js +5 -1
- package/src/boxes.js +11 -3
- package/src/compat.js +3 -0
- package/src/group.js +13 -11
- package/src/parts.js +25 -23
- package/src/util.js +239 -72
- package/src/validate.js +335 -0
package/dist/examples/text.jscad
CHANGED
|
@@ -52,6 +52,8 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
52
52
|
enabled: [],
|
|
53
53
|
disabled: []
|
|
54
54
|
});
|
|
55
|
+
var jscadUtilsAssertValidCSGWarnings = options.assertValidCSGWarnings || false;
|
|
56
|
+
var jscadUtilsAssertValidCSG = options.assertValidCSG || false;
|
|
55
57
|
var jscadUtils = function(exports, jsCadCSG, scadApi) {
|
|
56
58
|
"use strict";
|
|
57
59
|
function _interopDefaultLegacy(e) {
|
|
@@ -285,6 +287,51 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
285
287
|
function _arrayWithHoles(r) {
|
|
286
288
|
if (Array.isArray(r)) return r;
|
|
287
289
|
}
|
|
290
|
+
function _createForOfIteratorHelper(r, e) {
|
|
291
|
+
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
292
|
+
if (!t) {
|
|
293
|
+
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
|
|
294
|
+
t && (r = t);
|
|
295
|
+
var n = 0, F = function() {};
|
|
296
|
+
return {
|
|
297
|
+
s: F,
|
|
298
|
+
n: function() {
|
|
299
|
+
return n >= r.length ? {
|
|
300
|
+
done: !0
|
|
301
|
+
} : {
|
|
302
|
+
done: !1,
|
|
303
|
+
value: r[n++]
|
|
304
|
+
};
|
|
305
|
+
},
|
|
306
|
+
e: function(r) {
|
|
307
|
+
throw r;
|
|
308
|
+
},
|
|
309
|
+
f: F
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
313
|
+
}
|
|
314
|
+
var o, a = !0, u = !1;
|
|
315
|
+
return {
|
|
316
|
+
s: function() {
|
|
317
|
+
t = t.call(r);
|
|
318
|
+
},
|
|
319
|
+
n: function() {
|
|
320
|
+
var r = t.next();
|
|
321
|
+
return a = r.done, r;
|
|
322
|
+
},
|
|
323
|
+
e: function(r) {
|
|
324
|
+
u = !0, o = r;
|
|
325
|
+
},
|
|
326
|
+
f: function() {
|
|
327
|
+
try {
|
|
328
|
+
a || null == t.return || t.return();
|
|
329
|
+
} finally {
|
|
330
|
+
if (u) throw o;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
}
|
|
288
335
|
function _defineProperty(e, r, t) {
|
|
289
336
|
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
290
337
|
value: t,
|
|
@@ -705,6 +752,219 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
705
752
|
c[3] = g || 1;
|
|
706
753
|
return o.setColor(c);
|
|
707
754
|
}
|
|
755
|
+
function validateCSG(csg, options) {
|
|
756
|
+
var errors = [];
|
|
757
|
+
var warnings = [];
|
|
758
|
+
if (!csg || !csg.polygons || csg.polygons.length === 0) {
|
|
759
|
+
errors.push("Empty mesh: no polygons");
|
|
760
|
+
return {
|
|
761
|
+
ok: false,
|
|
762
|
+
errors,
|
|
763
|
+
warnings
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
var opts = _objectSpread2({
|
|
767
|
+
fixTJunctions: true
|
|
768
|
+
}, options);
|
|
769
|
+
if (opts.fixTJunctions && typeof csg.canonicalized === "function") {
|
|
770
|
+
csg = csg.canonicalized();
|
|
771
|
+
if (typeof csg.reTesselated === "function") {
|
|
772
|
+
csg = csg.reTesselated();
|
|
773
|
+
}
|
|
774
|
+
if (typeof csg.fixTJunctions === "function") {
|
|
775
|
+
csg = csg.fixTJunctions();
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
var AREA_EPS = 1e-10;
|
|
779
|
+
var KEY_EPS = 1e-5;
|
|
780
|
+
var degenerateCount = 0;
|
|
781
|
+
var invalidVertexCount = 0;
|
|
782
|
+
var _iterator = _createForOfIteratorHelper(csg.polygons), _step;
|
|
783
|
+
try {
|
|
784
|
+
for (_iterator.s(); !(_step = _iterator.n()).done; ) {
|
|
785
|
+
var npoly = _step.value;
|
|
786
|
+
var _iterator4 = _createForOfIteratorHelper(npoly.vertices), _step4;
|
|
787
|
+
try {
|
|
788
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done; ) {
|
|
789
|
+
var nvert = _step4.value;
|
|
790
|
+
var np = nvert.pos;
|
|
791
|
+
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)) {
|
|
792
|
+
invalidVertexCount++;
|
|
793
|
+
break;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
} catch (err) {
|
|
797
|
+
_iterator4.e(err);
|
|
798
|
+
} finally {
|
|
799
|
+
_iterator4.f();
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
} catch (err) {
|
|
803
|
+
_iterator.e(err);
|
|
804
|
+
} finally {
|
|
805
|
+
_iterator.f();
|
|
806
|
+
}
|
|
807
|
+
if (invalidVertexCount > 0) {
|
|
808
|
+
errors.push(invalidVertexCount + " polygon(s) with invalid vertex coordinates (NaN or Infinity)");
|
|
809
|
+
}
|
|
810
|
+
function vtxKey(v) {
|
|
811
|
+
var p = v.pos;
|
|
812
|
+
return Math.round(p.x / KEY_EPS) + "," + Math.round(p.y / KEY_EPS) + "," + Math.round(p.z / KEY_EPS);
|
|
813
|
+
}
|
|
814
|
+
var validPolygons = [];
|
|
815
|
+
var _iterator2 = _createForOfIteratorHelper(csg.polygons), _step2;
|
|
816
|
+
try {
|
|
817
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) {
|
|
818
|
+
var poly = _step2.value;
|
|
819
|
+
var verts = poly.vertices;
|
|
820
|
+
var nv = verts.length;
|
|
821
|
+
if (nv < 3) {
|
|
822
|
+
degenerateCount++;
|
|
823
|
+
continue;
|
|
824
|
+
}
|
|
825
|
+
var hasInvalid = false;
|
|
826
|
+
var _iterator5 = _createForOfIteratorHelper(verts), _step5;
|
|
827
|
+
try {
|
|
828
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done; ) {
|
|
829
|
+
var vert = _step5.value;
|
|
830
|
+
var ip = vert.pos;
|
|
831
|
+
if (!Number.isFinite(ip.x) || !Number.isFinite(ip.y) || !Number.isFinite(ip.z)) {
|
|
832
|
+
hasInvalid = true;
|
|
833
|
+
break;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
} catch (err) {
|
|
837
|
+
_iterator5.e(err);
|
|
838
|
+
} finally {
|
|
839
|
+
_iterator5.f();
|
|
840
|
+
}
|
|
841
|
+
if (hasInvalid) continue;
|
|
842
|
+
var area = 0;
|
|
843
|
+
for (var ai = 0; ai < nv - 2; ai++) {
|
|
844
|
+
area += verts[ai + 1].pos.minus(verts[0].pos).cross(verts[ai + 2].pos.minus(verts[ai + 1].pos)).length();
|
|
845
|
+
}
|
|
846
|
+
area *= .5;
|
|
847
|
+
if (area < AREA_EPS) {
|
|
848
|
+
degenerateCount++;
|
|
849
|
+
continue;
|
|
850
|
+
}
|
|
851
|
+
validPolygons.push(poly);
|
|
852
|
+
}
|
|
853
|
+
} catch (err) {
|
|
854
|
+
_iterator2.e(err);
|
|
855
|
+
} finally {
|
|
856
|
+
_iterator2.f();
|
|
857
|
+
}
|
|
858
|
+
if (degenerateCount > 0) {
|
|
859
|
+
warnings.push(degenerateCount + " degenerate polygon(s) (fewer than 3 vertices or near-zero area)");
|
|
860
|
+
if (opts.fixTJunctions && typeof CSG !== "undefined") {
|
|
861
|
+
var cleaned = CSG.fromPolygons(validPolygons);
|
|
862
|
+
cleaned = cleaned.canonicalized();
|
|
863
|
+
if (typeof cleaned.reTesselated === "function") {
|
|
864
|
+
cleaned = cleaned.reTesselated();
|
|
865
|
+
}
|
|
866
|
+
if (typeof cleaned.fixTJunctions === "function") {
|
|
867
|
+
cleaned = cleaned.fixTJunctions();
|
|
868
|
+
}
|
|
869
|
+
validPolygons = [];
|
|
870
|
+
var _iterator3 = _createForOfIteratorHelper(cleaned.polygons), _step3;
|
|
871
|
+
try {
|
|
872
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done; ) {
|
|
873
|
+
var cpoly = _step3.value;
|
|
874
|
+
var cverts = cpoly.vertices;
|
|
875
|
+
var cnv = cverts.length;
|
|
876
|
+
if (cnv < 3) continue;
|
|
877
|
+
var carea = 0;
|
|
878
|
+
for (var cai = 0; cai < cnv - 2; cai++) {
|
|
879
|
+
carea += cverts[cai + 1].pos.minus(cverts[0].pos).cross(cverts[cai + 2].pos.minus(cverts[cai + 1].pos)).length();
|
|
880
|
+
}
|
|
881
|
+
carea *= .5;
|
|
882
|
+
if (carea < AREA_EPS) continue;
|
|
883
|
+
validPolygons.push(cpoly);
|
|
884
|
+
}
|
|
885
|
+
} catch (err) {
|
|
886
|
+
_iterator3.e(err);
|
|
887
|
+
} finally {
|
|
888
|
+
_iterator3.f();
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
var edgeCounts = {};
|
|
893
|
+
for (var _i = 0, _validPolygons = validPolygons; _i < _validPolygons.length; _i++) {
|
|
894
|
+
var vpoly = _validPolygons[_i];
|
|
895
|
+
var vverts = vpoly.vertices;
|
|
896
|
+
var vnv = vverts.length;
|
|
897
|
+
for (var ei = 0; ei < vnv; ei++) {
|
|
898
|
+
var v0 = vverts[ei];
|
|
899
|
+
var v1 = vverts[(ei + 1) % vnv];
|
|
900
|
+
var edgeKey = vtxKey(v0) + "/" + vtxKey(v1);
|
|
901
|
+
edgeCounts[edgeKey] = (edgeCounts[edgeKey] || 0) + 1;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
var unmatchedEdges = 0;
|
|
905
|
+
var nonManifoldEdges = 0;
|
|
906
|
+
var checked = {};
|
|
907
|
+
for (var _i2 = 0, _Object$keys = Object.keys(edgeCounts); _i2 < _Object$keys.length; _i2++) {
|
|
908
|
+
var _edgeKey = _Object$keys[_i2];
|
|
909
|
+
if (checked[_edgeKey]) continue;
|
|
910
|
+
var parts = _edgeKey.split("/");
|
|
911
|
+
var reverseKey = parts[1] + "/" + parts[0];
|
|
912
|
+
var forwardCount = edgeCounts[_edgeKey] || 0;
|
|
913
|
+
var reverseCount = edgeCounts[reverseKey] || 0;
|
|
914
|
+
checked[_edgeKey] = true;
|
|
915
|
+
checked[reverseKey] = true;
|
|
916
|
+
if (forwardCount !== reverseCount) {
|
|
917
|
+
unmatchedEdges += Math.abs(forwardCount - reverseCount);
|
|
918
|
+
}
|
|
919
|
+
if (forwardCount > 1 || reverseCount > 1) {
|
|
920
|
+
nonManifoldEdges++;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
if (unmatchedEdges > 0) {
|
|
924
|
+
errors.push(unmatchedEdges + " unmatched edge(s): mesh is not watertight");
|
|
925
|
+
}
|
|
926
|
+
if (nonManifoldEdges > 0) {
|
|
927
|
+
errors.push(nonManifoldEdges + " non-manifold edge(s): edge shared by more than 2 polygons");
|
|
928
|
+
}
|
|
929
|
+
return {
|
|
930
|
+
ok: errors.length === 0,
|
|
931
|
+
errors,
|
|
932
|
+
warnings
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
function _noOp(csg) {
|
|
936
|
+
return csg;
|
|
937
|
+
}
|
|
938
|
+
function _makeAssertFn(warnEnabled) {
|
|
939
|
+
return function _assert(csg) {
|
|
940
|
+
var functionName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "unknown";
|
|
941
|
+
var moduleName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "unknown";
|
|
942
|
+
if (!csg || csg.polygons === undefined) return csg;
|
|
943
|
+
var result = validateCSG(csg);
|
|
944
|
+
if (!result.ok) {
|
|
945
|
+
throw new Error(moduleName + ":" + functionName + ": " + "invalid CSG: " + result.errors.join(", "));
|
|
946
|
+
}
|
|
947
|
+
if (warnEnabled && result.warnings.length > 0) {
|
|
948
|
+
throw new Error(moduleName + ":" + functionName + ": " + "CSG warnings: " + result.warnings.join(", "));
|
|
949
|
+
}
|
|
950
|
+
return csg;
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
var _assertFn = _noOp;
|
|
954
|
+
function _resolveFromGlobals() {
|
|
955
|
+
var enabled = typeof jscadUtilsAssertValidCSG !== "undefined" && !!jscadUtilsAssertValidCSG;
|
|
956
|
+
var warnEnabled = typeof jscadUtilsAssertValidCSGWarnings !== "undefined" && !!jscadUtilsAssertValidCSGWarnings;
|
|
957
|
+
return enabled ? _makeAssertFn(warnEnabled) : _noOp;
|
|
958
|
+
}
|
|
959
|
+
function AssertValidCSG() {
|
|
960
|
+
var moduleName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "unknown";
|
|
961
|
+
{
|
|
962
|
+
_assertFn = _resolveFromGlobals();
|
|
963
|
+
}
|
|
964
|
+
return function(csg, name) {
|
|
965
|
+
return _assertFn(csg, name, moduleName);
|
|
966
|
+
};
|
|
967
|
+
}
|
|
708
968
|
function init(proto) {
|
|
709
969
|
if (proto.prototype._jscadutilsinit) return;
|
|
710
970
|
proto.prototype.color = function(r, g, b, a) {
|
|
@@ -798,6 +1058,9 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
798
1058
|
proto.prototype.subtractIf = function subtractIf(object, condition) {
|
|
799
1059
|
return condition ? this.subtract(result(this, object)) : this;
|
|
800
1060
|
};
|
|
1061
|
+
proto.prototype.validate = function validate(options) {
|
|
1062
|
+
return validateCSG(this, options);
|
|
1063
|
+
};
|
|
801
1064
|
proto.prototype._translate = proto.prototype.translate;
|
|
802
1065
|
proto.prototype.translate = function translate() {
|
|
803
1066
|
if (arguments.length === 1) {
|
|
@@ -830,12 +1093,13 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
830
1093
|
__proto__: null,
|
|
831
1094
|
default: init
|
|
832
1095
|
});
|
|
833
|
-
var CSG = jsCadCSG__default["default"].CSG, CAG = jsCadCSG__default["default"].CAG;
|
|
1096
|
+
var CSG$1 = jsCadCSG__default["default"].CSG, CAG = jsCadCSG__default["default"].CAG;
|
|
834
1097
|
var rectangular_extrude = scadApi__default["default"].extrusions.rectangular_extrude;
|
|
835
1098
|
var _scadApi$text = scadApi__default["default"].text, vector_text = _scadApi$text.vector_text, vector_char = _scadApi$text.vector_char;
|
|
836
1099
|
var union = scadApi__default["default"].booleanOps.union;
|
|
837
|
-
init(CSG);
|
|
1100
|
+
init(CSG$1);
|
|
838
1101
|
var debug$3 = Debug("jscadUtils:group");
|
|
1102
|
+
var assertValidCSG$2 = AssertValidCSG("group");
|
|
839
1103
|
function JsCadUtilsGroup() {
|
|
840
1104
|
var names = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
841
1105
|
var parts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
@@ -886,7 +1150,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
886
1150
|
debug$3("combine mapPick", value, key, object);
|
|
887
1151
|
return map ? map(value, key, index, object) : identity(value);
|
|
888
1152
|
}, self.name));
|
|
889
|
-
return g.subtractIf(self.holes && Array.isArray(self.holes) ? union(self.holes) : self.holes, self.holes && !options.noholes);
|
|
1153
|
+
return assertValidCSG$2(g.subtractIf(self.holes && Array.isArray(self.holes) ? union(self.holes) : self.holes, self.holes && !options.noholes), "combine");
|
|
890
1154
|
} catch (err) {
|
|
891
1155
|
debug$3("combine error", this, pieces, options, err);
|
|
892
1156
|
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");
|
|
@@ -927,7 +1191,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
927
1191
|
});
|
|
928
1192
|
if (self.holes) {
|
|
929
1193
|
group.holes = toArray(self.holes).map(function(part) {
|
|
930
|
-
return map(CSG.fromPolygons(part.toPolygons()), "holes");
|
|
1194
|
+
return assertValidCSG$2(map(CSG$1.fromPolygons(part.toPolygons()), "holes"), "clone");
|
|
931
1195
|
});
|
|
932
1196
|
}
|
|
933
1197
|
return group;
|
|
@@ -946,7 +1210,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
946
1210
|
var rotationCenter = solid.centroid();
|
|
947
1211
|
var rotationAxis = axes[axis];
|
|
948
1212
|
self.map(function(part) {
|
|
949
|
-
return part.rotate(rotationCenter, rotationAxis, angle);
|
|
1213
|
+
return assertValidCSG$2(part.rotate(rotationCenter, rotationAxis, angle), "rotate");
|
|
950
1214
|
});
|
|
951
1215
|
return self;
|
|
952
1216
|
};
|
|
@@ -959,7 +1223,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
959
1223
|
var self = this;
|
|
960
1224
|
var t = calcSnap(self.combine(part), to, axis, orientation, delta);
|
|
961
1225
|
self.map(function(part) {
|
|
962
|
-
return part.translate(t);
|
|
1226
|
+
return assertValidCSG$2(part.translate(t), "snap");
|
|
963
1227
|
});
|
|
964
1228
|
return self;
|
|
965
1229
|
} catch (err) {
|
|
@@ -974,7 +1238,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
974
1238
|
noholes: true
|
|
975
1239
|
}), axis, to, delta);
|
|
976
1240
|
self.map(function(part) {
|
|
977
|
-
return part.translate(t);
|
|
1241
|
+
return assertValidCSG$2(part.translate(t), "align");
|
|
978
1242
|
});
|
|
979
1243
|
return self;
|
|
980
1244
|
} catch (err) {
|
|
@@ -1006,14 +1270,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1006
1270
|
var myConnector = connectorName.split(".").reduce(function(a, v) {
|
|
1007
1271
|
return a[v];
|
|
1008
1272
|
}, self.parts[partName].properties);
|
|
1009
|
-
debug$3("toConnector", to instanceof CSG.Connector);
|
|
1273
|
+
debug$3("toConnector", to instanceof CSG$1.Connector);
|
|
1010
1274
|
var toConnector = toConnectorName.split(".").reduce(function(a, v) {
|
|
1011
1275
|
return a[v];
|
|
1012
1276
|
}, to.properties);
|
|
1013
1277
|
var matrix = myConnector.getTransformationTo(toConnector, mirror, normalrotation);
|
|
1014
1278
|
debug$3("connectTo", matrix);
|
|
1015
1279
|
self.map(function(part) {
|
|
1016
|
-
return part.transform(matrix);
|
|
1280
|
+
return assertValidCSG$2(part.transform(matrix), "connectTo");
|
|
1017
1281
|
});
|
|
1018
1282
|
return self;
|
|
1019
1283
|
};
|
|
@@ -1024,7 +1288,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1024
1288
|
return to - size[a] / 2;
|
|
1025
1289
|
});
|
|
1026
1290
|
self.map(function(part) {
|
|
1027
|
-
return part.translate(t);
|
|
1291
|
+
return assertValidCSG$2(part.translate(t), "midlineTo");
|
|
1028
1292
|
});
|
|
1029
1293
|
return self;
|
|
1030
1294
|
};
|
|
@@ -1033,7 +1297,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1033
1297
|
var t = Array.isArray(x) ? x : [ x, y, z ];
|
|
1034
1298
|
debug$3("translate", t);
|
|
1035
1299
|
self.map(function(part) {
|
|
1036
|
-
return part.translate(t);
|
|
1300
|
+
return assertValidCSG$2(part.translate(t), "translate");
|
|
1037
1301
|
});
|
|
1038
1302
|
return self;
|
|
1039
1303
|
};
|
|
@@ -1043,7 +1307,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1043
1307
|
if (!map) map = identity;
|
|
1044
1308
|
var g = Group();
|
|
1045
1309
|
p.forEach(function(name) {
|
|
1046
|
-
g.add(map(CSG.fromPolygons(self.parts[name].toPolygons()), name), name);
|
|
1310
|
+
g.add(assertValidCSG$2(map(CSG$1.fromPolygons(self.parts[name].toPolygons()), name), "pick"), name);
|
|
1047
1311
|
});
|
|
1048
1312
|
return g;
|
|
1049
1313
|
};
|
|
@@ -1058,7 +1322,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1058
1322
|
debug$3("array error", _this, parts);
|
|
1059
1323
|
throw error('group::array error "'.concat(name, '" not found.\nthis: ').concat(_this, '\nparts: "').concat(parts, '"\n'), "JSCAD_UTILS_GROUP_ERROR");
|
|
1060
1324
|
}
|
|
1061
|
-
a.push(map(CSG.fromPolygons(self.parts[name].toPolygons()), name));
|
|
1325
|
+
a.push(assertValidCSG$2(map(CSG$1.fromPolygons(self.parts[name].toPolygons()), name), "array"));
|
|
1062
1326
|
});
|
|
1063
1327
|
return a;
|
|
1064
1328
|
};
|
|
@@ -1091,7 +1355,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1091
1355
|
self.names = names && names.length > 0 && names.split(",") || [];
|
|
1092
1356
|
if (Array.isArray(objects)) {
|
|
1093
1357
|
self.parts = zipObject(self.names, objects);
|
|
1094
|
-
} else if (objects instanceof CSG) {
|
|
1358
|
+
} else if (objects instanceof CSG$1) {
|
|
1095
1359
|
self.parts = zipObject(self.names, [ objects ]);
|
|
1096
1360
|
} else {
|
|
1097
1361
|
self.parts = objects || {};
|
|
@@ -1112,6 +1376,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1112
1376
|
return new JsCadUtilsGroup(self.names, self.parts, self.holes);
|
|
1113
1377
|
}
|
|
1114
1378
|
var debug$2 = Debug("jscadUtils:util");
|
|
1379
|
+
var assertValidCSG$1 = AssertValidCSG("util");
|
|
1115
1380
|
var NOZZEL_SIZE = .4;
|
|
1116
1381
|
var nearest = {
|
|
1117
1382
|
under: function under(desired) {
|
|
@@ -1188,12 +1453,12 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1188
1453
|
h: height || 2
|
|
1189
1454
|
}));
|
|
1190
1455
|
});
|
|
1191
|
-
return center(union(o));
|
|
1456
|
+
return assertValidCSG$1(center(union(o)), "label");
|
|
1192
1457
|
}
|
|
1193
1458
|
function text(text) {
|
|
1194
1459
|
var l = vector_char(0, 0, text);
|
|
1195
1460
|
var _char = l.segments.reduce(function(result, segment) {
|
|
1196
|
-
var path = new CSG.Path2D(segment);
|
|
1461
|
+
var path = new CSG$1.Path2D(segment);
|
|
1197
1462
|
var cag = path.expandToCAG(2);
|
|
1198
1463
|
return result ? result.union(cag) : cag;
|
|
1199
1464
|
}, undefined);
|
|
@@ -1201,17 +1466,17 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1201
1466
|
}
|
|
1202
1467
|
function unitCube(length, radius) {
|
|
1203
1468
|
radius = radius || .5;
|
|
1204
|
-
return CSG.cube({
|
|
1469
|
+
return assertValidCSG$1(CSG$1.cube({
|
|
1205
1470
|
center: [ 0, 0, 0 ],
|
|
1206
1471
|
radius: [ radius, radius, length || .5 ]
|
|
1207
|
-
});
|
|
1472
|
+
}), "unitCube");
|
|
1208
1473
|
}
|
|
1209
1474
|
function unitAxis(length, radius, centroid) {
|
|
1210
1475
|
debug$2("unitAxis", length, radius, centroid);
|
|
1211
1476
|
centroid = centroid || [ 0, 0, 0 ];
|
|
1212
1477
|
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) ]);
|
|
1213
|
-
unitaxis.properties.origin = new CSG.Connector([ 0, 0, 0 ], [ 1, 0, 0 ], [ 0, 1, 0 ]);
|
|
1214
|
-
return unitaxis.translate(centroid);
|
|
1478
|
+
unitaxis.properties.origin = new CSG$1.Connector([ 0, 0, 0 ], [ 1, 0, 0 ], [ 0, 1, 0 ]);
|
|
1479
|
+
return assertValidCSG$1(unitaxis.translate(centroid), "unitAxis");
|
|
1215
1480
|
}
|
|
1216
1481
|
function toArray(a) {
|
|
1217
1482
|
return Array.isArray(a) ? a : [ a ];
|
|
@@ -1301,15 +1566,15 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1301
1566
|
}
|
|
1302
1567
|
function center(object, objectSize) {
|
|
1303
1568
|
objectSize = objectSize || size(object.getBounds());
|
|
1304
|
-
return centerY(centerX(object, objectSize), objectSize);
|
|
1569
|
+
return assertValidCSG$1(centerY(centerX(object, objectSize), objectSize), "center");
|
|
1305
1570
|
}
|
|
1306
1571
|
function centerY(object, objectSize) {
|
|
1307
1572
|
objectSize = objectSize || size(object.getBounds());
|
|
1308
|
-
return object.translate([ 0, -objectSize.y / 2, 0 ]);
|
|
1573
|
+
return assertValidCSG$1(object.translate([ 0, -objectSize.y / 2, 0 ]), "centerY");
|
|
1309
1574
|
}
|
|
1310
1575
|
function centerX(object, objectSize) {
|
|
1311
1576
|
objectSize = objectSize || size(object.getBounds());
|
|
1312
|
-
return object.translate([ -objectSize.x / 2, 0, 0 ]);
|
|
1577
|
+
return assertValidCSG$1(object.translate([ -objectSize.x / 2, 0, 0 ]), "centerX");
|
|
1313
1578
|
}
|
|
1314
1579
|
function enlarge(object, x, y, z) {
|
|
1315
1580
|
var a;
|
|
@@ -1327,7 +1592,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1327
1592
|
var new_object = object.scale(t);
|
|
1328
1593
|
var new_centroid = centroid(new_object);
|
|
1329
1594
|
var delta = new_centroid.minus(objectCentroid).times(-1);
|
|
1330
|
-
return new_object.translate(delta);
|
|
1595
|
+
return assertValidCSG$1(new_object.translate(delta), "enlarge");
|
|
1331
1596
|
}
|
|
1332
1597
|
function fit(object, x, y, z, keep_aspect_ratio) {
|
|
1333
1598
|
var a;
|
|
@@ -1347,10 +1612,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1347
1612
|
}
|
|
1348
1613
|
var s = [ scale(objectSize.x, x), scale(objectSize.y, y), scale(objectSize.z, z) ];
|
|
1349
1614
|
var min$1 = min(s);
|
|
1350
|
-
return centerWith(object.scale(s.map(function(d, i) {
|
|
1615
|
+
return assertValidCSG$1(centerWith(object.scale(s.map(function(d, i) {
|
|
1351
1616
|
if (a[i] === 0) return 1;
|
|
1352
1617
|
return keep_aspect_ratio ? min$1 : d;
|
|
1353
|
-
})), "xyz", object);
|
|
1618
|
+
})), "xyz", object), "fit");
|
|
1354
1619
|
}
|
|
1355
1620
|
function shift(object, x, y, z) {
|
|
1356
1621
|
var hsize = this.div(this.size(object.getBounds()), 2);
|
|
@@ -1358,10 +1623,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1358
1623
|
}
|
|
1359
1624
|
function zero(object) {
|
|
1360
1625
|
var bounds = object.getBounds();
|
|
1361
|
-
return object.translate([ 0, 0, -bounds[0].z ]);
|
|
1626
|
+
return assertValidCSG$1(object.translate([ 0, 0, -bounds[0].z ]), "zero");
|
|
1362
1627
|
}
|
|
1363
1628
|
function mirrored4(x) {
|
|
1364
|
-
return x.union([ x.mirroredY(90), x.mirroredX(90), x.mirroredY(90).mirroredX(90) ]);
|
|
1629
|
+
return assertValidCSG$1(x.union([ x.mirroredY(90), x.mirroredX(90), x.mirroredY(90).mirroredX(90) ]), "mirrored4");
|
|
1365
1630
|
}
|
|
1366
1631
|
var flushSide = {
|
|
1367
1632
|
"above-outside": [ 1, 0 ],
|
|
@@ -1422,10 +1687,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1422
1687
|
function snap(moveobj, withobj, axis, orientation, delta) {
|
|
1423
1688
|
debug$2("snap", moveobj, withobj, axis, orientation, delta);
|
|
1424
1689
|
var t = calcSnap(moveobj, withobj, axis, orientation, delta);
|
|
1425
|
-
return moveobj.translate(t);
|
|
1690
|
+
return assertValidCSG$1(moveobj.translate(t), "snap");
|
|
1426
1691
|
}
|
|
1427
1692
|
function flush(moveobj, withobj, axis, mside, wside) {
|
|
1428
|
-
return moveobj.translate(calcFlush(moveobj, withobj, axis, mside, wside));
|
|
1693
|
+
return assertValidCSG$1(moveobj.translate(calcFlush(moveobj, withobj, axis, mside, wside)), "flush");
|
|
1429
1694
|
}
|
|
1430
1695
|
function axisApply(axes, valfun, a) {
|
|
1431
1696
|
debug$2("axisApply", axes, valfun, a);
|
|
@@ -1441,7 +1706,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1441
1706
|
return retval;
|
|
1442
1707
|
}
|
|
1443
1708
|
function axis2array(axes, valfun) {
|
|
1444
|
-
depreciated("axis2array");
|
|
1709
|
+
depreciated("axis2array", false, "Use axisApply instead.");
|
|
1445
1710
|
var a = [ 0, 0, 0 ];
|
|
1446
1711
|
var lookup = {
|
|
1447
1712
|
x: 0,
|
|
@@ -1471,7 +1736,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1471
1736
|
});
|
|
1472
1737
|
}
|
|
1473
1738
|
function midlineTo(o, axis, to) {
|
|
1474
|
-
return o.translate(calcmidlineTo(o, axis, to));
|
|
1739
|
+
return assertValidCSG$1(o.translate(calcmidlineTo(o, axis, to)), "midlineTo");
|
|
1475
1740
|
}
|
|
1476
1741
|
function translator(o, axis, withObj) {
|
|
1477
1742
|
var objectCentroid = centroid(o);
|
|
@@ -1491,7 +1756,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1491
1756
|
return delta ? add(t, delta) : t;
|
|
1492
1757
|
}
|
|
1493
1758
|
function centerWith(o, axis, withObj) {
|
|
1494
|
-
return o.translate(calcCenterWith(o, axis, withObj));
|
|
1759
|
+
return assertValidCSG$1(o.translate(calcCenterWith(o, axis, withObj)), "centerWith");
|
|
1495
1760
|
}
|
|
1496
1761
|
function getDelta(size, bounds, axis, offset, nonzero) {
|
|
1497
1762
|
if (!isEmpty(offset) && nonzero) {
|
|
@@ -1504,6 +1769,95 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1504
1769
|
return bounds[0][a] + (isEmpty(dist) ? size[axis] / 2 : dist);
|
|
1505
1770
|
});
|
|
1506
1771
|
}
|
|
1772
|
+
var EPS = 1e-5;
|
|
1773
|
+
function splitCSGByPlane(csg, plane) {
|
|
1774
|
+
var frontPolys = [];
|
|
1775
|
+
var backPolys = [];
|
|
1776
|
+
csg.polygons.forEach(function(poly) {
|
|
1777
|
+
var vertices = poly.vertices;
|
|
1778
|
+
var numVerts = vertices.length;
|
|
1779
|
+
var hasfront = false;
|
|
1780
|
+
var hasback = false;
|
|
1781
|
+
var vertexIsBack = [];
|
|
1782
|
+
for (var i = 0; i < numVerts; i++) {
|
|
1783
|
+
var t = plane.normal.dot(vertices[i].pos) - plane.w;
|
|
1784
|
+
vertexIsBack.push(t < 0);
|
|
1785
|
+
if (t > EPS) hasfront = true;
|
|
1786
|
+
if (t < -EPS) hasback = true;
|
|
1787
|
+
}
|
|
1788
|
+
if (!hasfront && !hasback) {
|
|
1789
|
+
var d = plane.normal.dot(poly.plane.normal);
|
|
1790
|
+
if (d >= 0) {
|
|
1791
|
+
frontPolys.push(poly);
|
|
1792
|
+
} else {
|
|
1793
|
+
backPolys.push(poly);
|
|
1794
|
+
}
|
|
1795
|
+
} else if (!hasback) {
|
|
1796
|
+
frontPolys.push(poly);
|
|
1797
|
+
} else if (!hasfront) {
|
|
1798
|
+
backPolys.push(poly);
|
|
1799
|
+
} else {
|
|
1800
|
+
var fv = [];
|
|
1801
|
+
var bv = [];
|
|
1802
|
+
for (var vi = 0; vi < numVerts; vi++) {
|
|
1803
|
+
var vertex = vertices[vi];
|
|
1804
|
+
var nextVi = (vi + 1) % numVerts;
|
|
1805
|
+
var isback = vertexIsBack[vi];
|
|
1806
|
+
var nextisback = vertexIsBack[nextVi];
|
|
1807
|
+
if (isback === nextisback) {
|
|
1808
|
+
if (isback) {
|
|
1809
|
+
bv.push(vertex);
|
|
1810
|
+
} else {
|
|
1811
|
+
fv.push(vertex);
|
|
1812
|
+
}
|
|
1813
|
+
} else {
|
|
1814
|
+
var point = vertex.pos;
|
|
1815
|
+
var nextpoint = vertices[nextVi].pos;
|
|
1816
|
+
var ip = plane.splitLineBetweenPoints(point, nextpoint);
|
|
1817
|
+
var iv = new CSG$1.Vertex(ip);
|
|
1818
|
+
if (isback) {
|
|
1819
|
+
bv.push(vertex);
|
|
1820
|
+
bv.push(iv);
|
|
1821
|
+
fv.push(iv);
|
|
1822
|
+
} else {
|
|
1823
|
+
fv.push(vertex);
|
|
1824
|
+
fv.push(iv);
|
|
1825
|
+
bv.push(iv);
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
var EPSEPS = EPS * EPS;
|
|
1830
|
+
if (fv.length >= 3) {
|
|
1831
|
+
var prev = fv[fv.length - 1];
|
|
1832
|
+
for (var fi = 0; fi < fv.length; fi++) {
|
|
1833
|
+
var curr = fv[fi];
|
|
1834
|
+
if (curr.pos.distanceToSquared(prev.pos) < EPSEPS) {
|
|
1835
|
+
fv.splice(fi, 1);
|
|
1836
|
+
fi--;
|
|
1837
|
+
}
|
|
1838
|
+
prev = curr;
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
if (bv.length >= 3) {
|
|
1842
|
+
var prev = bv[bv.length - 1];
|
|
1843
|
+
for (var bi = 0; bi < bv.length; bi++) {
|
|
1844
|
+
var curr = bv[bi];
|
|
1845
|
+
if (curr.pos.distanceToSquared(prev.pos) < EPSEPS) {
|
|
1846
|
+
bv.splice(bi, 1);
|
|
1847
|
+
bi--;
|
|
1848
|
+
}
|
|
1849
|
+
prev = curr;
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
if (fv.length >= 3) frontPolys.push(new CSG$1.Polygon(fv, poly.shared, poly.plane));
|
|
1853
|
+
if (bv.length >= 3) backPolys.push(new CSG$1.Polygon(bv, poly.shared, poly.plane));
|
|
1854
|
+
}
|
|
1855
|
+
});
|
|
1856
|
+
return {
|
|
1857
|
+
front: CSG$1.fromPolygons(frontPolys),
|
|
1858
|
+
back: CSG$1.fromPolygons(backPolys)
|
|
1859
|
+
};
|
|
1860
|
+
}
|
|
1507
1861
|
function bisect() {
|
|
1508
1862
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1509
1863
|
args[_key] = arguments[_key];
|
|
@@ -1565,13 +1919,13 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1565
1919
|
}[[ axis, rotateaxis ].sort().join("")];
|
|
1566
1920
|
var centroid = object.centroid();
|
|
1567
1921
|
var rotateDelta = getDelta(objectSize, bounds, rotateOffsetAxis, rotateoffset);
|
|
1568
|
-
var rotationCenter = options.rotationCenter || new CSG.Vector3D(axisApply("xyz", function(i, a) {
|
|
1922
|
+
var rotationCenter = options.rotationCenter || new CSG$1.Vector3D(axisApply("xyz", function(i, a) {
|
|
1569
1923
|
if (a == axis) return cutDelta[i];
|
|
1570
1924
|
if (a == rotateOffsetAxis) return rotateDelta[i];
|
|
1571
1925
|
return centroid[a];
|
|
1572
1926
|
}));
|
|
1573
1927
|
var theRotationAxis = rotationAxes[rotateaxis];
|
|
1574
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).translate(cutDelta).rotate(rotationCenter, theRotationAxis, angle);
|
|
1928
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).translate(cutDelta).rotate(rotationCenter, theRotationAxis, angle);
|
|
1575
1929
|
debug$2("bisect", debug$2.enabled && {
|
|
1576
1930
|
axis,
|
|
1577
1931
|
offset,
|
|
@@ -1584,7 +1938,26 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1584
1938
|
cutplane,
|
|
1585
1939
|
options
|
|
1586
1940
|
});
|
|
1587
|
-
var
|
|
1941
|
+
var negative = object.cutByPlane(cutplane.plane);
|
|
1942
|
+
var positive = object.cutByPlane(cutplane.plane.flipped());
|
|
1943
|
+
var negSize = size(negative);
|
|
1944
|
+
var posSize = size(positive);
|
|
1945
|
+
if (negSize[axis] >= objectSize[axis] - EPS || posSize[axis] >= objectSize[axis] - EPS) {
|
|
1946
|
+
var halves = splitCSGByPlane(object, cutplane.plane);
|
|
1947
|
+
if (negSize[axis] >= objectSize[axis] - EPS) {
|
|
1948
|
+
negative = halves.back;
|
|
1949
|
+
try {
|
|
1950
|
+
negative = negative.cutByPlane(cutplane.plane);
|
|
1951
|
+
} catch (e) {}
|
|
1952
|
+
}
|
|
1953
|
+
if (posSize[axis] >= objectSize[axis] - EPS) {
|
|
1954
|
+
positive = halves.front;
|
|
1955
|
+
try {
|
|
1956
|
+
positive = positive.cutByPlane(cutplane.plane.flipped());
|
|
1957
|
+
} catch (e) {}
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
var g = Group("negative,positive", [ negative.color(options.color && "red"), positive.color(options.color && "blue") ]);
|
|
1588
1961
|
if (options.addRotationCenter) g.add(unitAxis(objectSize.length() + 10, .1, rotationCenter), "rotationCenter");
|
|
1589
1962
|
return g;
|
|
1590
1963
|
}
|
|
@@ -1597,9 +1970,9 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1597
1970
|
addRotationCenter: true
|
|
1598
1971
|
};
|
|
1599
1972
|
var info = normalVector(axis);
|
|
1600
|
-
var rotationCenter = options.rotationCenter || new CSG.Vector3D(0, 0, 0);
|
|
1973
|
+
var rotationCenter = options.rotationCenter || new CSG$1.Vector3D(0, 0, 0);
|
|
1601
1974
|
var theRotationAxis = rotationAxes[rotateaxis];
|
|
1602
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).rotate(rotationCenter, theRotationAxis, angle);
|
|
1975
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).rotate(rotationCenter, theRotationAxis, angle);
|
|
1603
1976
|
var g = Group("negative,positive", [ object.cutByPlane(cutplane.plane).color(options.color && "red"), object.cutByPlane(cutplane.plane.flipped()).color(options.color && "blue") ]);
|
|
1604
1977
|
if (options.addRotationCenter) {
|
|
1605
1978
|
var objectSize = size(object);
|
|
@@ -1624,14 +1997,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1624
1997
|
var bounds = object.getBounds();
|
|
1625
1998
|
var objectSize = size(object);
|
|
1626
1999
|
var cutDelta = getDelta(objectSize, bounds, axis, offset, true);
|
|
1627
|
-
return object.stretchAtPlane(normal[axis], cutDelta, distance);
|
|
2000
|
+
return assertValidCSG$1(object.stretchAtPlane(normal[axis], cutDelta, distance), "stretch");
|
|
1628
2001
|
}
|
|
1629
2002
|
function poly2solid(top, bottom, height) {
|
|
1630
2003
|
if (top.sides.length == 0) {
|
|
1631
|
-
return new CSG;
|
|
2004
|
+
return new CSG$1;
|
|
1632
2005
|
}
|
|
1633
|
-
var offsetVector = CSG.Vector3D.Create(0, 0, height);
|
|
1634
|
-
var normalVector = CSG.Vector3D.Create(0, 1, 0);
|
|
2006
|
+
var offsetVector = CSG$1.Vector3D.Create(0, 0, height);
|
|
2007
|
+
var normalVector = CSG$1.Vector3D.Create(0, 1, 0);
|
|
1635
2008
|
var polygons = [];
|
|
1636
2009
|
polygons = polygons.concat(bottom._toPlanePolygons({
|
|
1637
2010
|
translation: [ 0, 0, 0 ],
|
|
@@ -1643,14 +2016,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1643
2016
|
normalVector,
|
|
1644
2017
|
flipped: offsetVector.z < 0
|
|
1645
2018
|
}));
|
|
1646
|
-
var c1 = new CSG.Connector(offsetVector.times(0), [ 0, 0, offsetVector.z ], normalVector);
|
|
1647
|
-
var c2 = new CSG.Connector(offsetVector, [ 0, 0, offsetVector.z ], normalVector);
|
|
2019
|
+
var c1 = new CSG$1.Connector(offsetVector.times(0), [ 0, 0, offsetVector.z ], normalVector);
|
|
2020
|
+
var c2 = new CSG$1.Connector(offsetVector, [ 0, 0, offsetVector.z ], normalVector);
|
|
1648
2021
|
polygons = polygons.concat(bottom._toWallPolygons({
|
|
1649
2022
|
cag: top,
|
|
1650
2023
|
toConnector1: c1,
|
|
1651
2024
|
toConnector2: c2
|
|
1652
2025
|
}));
|
|
1653
|
-
return CSG.fromPolygons(polygons);
|
|
2026
|
+
return assertValidCSG$1(CSG$1.fromPolygons(polygons), "poly2solid");
|
|
1654
2027
|
}
|
|
1655
2028
|
function slices2poly(slices, options, axis) {
|
|
1656
2029
|
debug$2("slices2poly", slices, options, axis);
|
|
@@ -1659,7 +2032,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1659
2032
|
twiststeps: 0
|
|
1660
2033
|
}, options);
|
|
1661
2034
|
var twistangle = options && parseFloat(options.twistangle) || 0;
|
|
1662
|
-
options && parseInt(options.twiststeps) || CSG.defaultResolution3D;
|
|
2035
|
+
options && parseInt(options.twiststeps) || CSG$1.defaultResolution3D;
|
|
1663
2036
|
var normalVector = options.si.normalVector;
|
|
1664
2037
|
var polygons = [];
|
|
1665
2038
|
var first$1 = first(slices);
|
|
@@ -1688,8 +2061,8 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1688
2061
|
var nextidx = idx + 1;
|
|
1689
2062
|
var top = !up ? slices[nextidx] : slice;
|
|
1690
2063
|
var bottom = up ? slices[nextidx] : slice;
|
|
1691
|
-
var c1 = new CSG.Connector(bottom.offset, connectorAxis, rotate(normalVector, twistangle, idx / slices.length));
|
|
1692
|
-
var c2 = new CSG.Connector(top.offset, connectorAxis, rotate(normalVector, twistangle, nextidx / slices.length));
|
|
2064
|
+
var c1 = new CSG$1.Connector(bottom.offset, connectorAxis, rotate(normalVector, twistangle, idx / slices.length));
|
|
2065
|
+
var c2 = new CSG$1.Connector(top.offset, connectorAxis, rotate(normalVector, twistangle, nextidx / slices.length));
|
|
1693
2066
|
polygons = polygons.concat(bottom.poly._toWallPolygons({
|
|
1694
2067
|
cag: top.poly,
|
|
1695
2068
|
toConnector1: c1,
|
|
@@ -1697,21 +2070,21 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1697
2070
|
}));
|
|
1698
2071
|
}
|
|
1699
2072
|
});
|
|
1700
|
-
return CSG.fromPolygons(polygons);
|
|
2073
|
+
return assertValidCSG$1(CSG$1.fromPolygons(polygons), "slices2poly");
|
|
1701
2074
|
}
|
|
1702
2075
|
function normalVector(axis) {
|
|
1703
2076
|
var axisInfo = {
|
|
1704
2077
|
z: {
|
|
1705
2078
|
orthoNormalCartesian: [ "X", "Y" ],
|
|
1706
|
-
normalVector: CSG.Vector3D.Create(0, 1, 0)
|
|
2079
|
+
normalVector: CSG$1.Vector3D.Create(0, 1, 0)
|
|
1707
2080
|
},
|
|
1708
2081
|
x: {
|
|
1709
2082
|
orthoNormalCartesian: [ "Y", "Z" ],
|
|
1710
|
-
normalVector: CSG.Vector3D.Create(0, 0, 1)
|
|
2083
|
+
normalVector: CSG$1.Vector3D.Create(0, 0, 1)
|
|
1711
2084
|
},
|
|
1712
2085
|
y: {
|
|
1713
|
-
orthoNormalCartesian: [ "
|
|
1714
|
-
normalVector: CSG.Vector3D.Create(0, 0, 1)
|
|
2086
|
+
orthoNormalCartesian: [ "Z", "X" ],
|
|
2087
|
+
normalVector: CSG$1.Vector3D.Create(0, 0, 1)
|
|
1715
2088
|
}
|
|
1716
2089
|
};
|
|
1717
2090
|
if (!axisInfo[axis]) error("normalVector: invalid axis " + axis);
|
|
@@ -1752,7 +2125,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1752
2125
|
var si = sliceParams(orientation, radius, b);
|
|
1753
2126
|
debug$2("reShape", absoluteRadius, si);
|
|
1754
2127
|
if (si.axis !== "z") throw new Error('reShape error: CAG._toPlanePolygons only uses the "z" axis. You must use the "z" axis for now.');
|
|
1755
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(si.orthoNormalCartesian[0], si.orthoNormalCartesian[1]).translate(si.cutDelta);
|
|
2128
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(si.orthoNormalCartesian[0], si.orthoNormalCartesian[1]).translate(si.cutDelta);
|
|
1756
2129
|
var slice = object.sectionCut(cutplane);
|
|
1757
2130
|
var first = axisApply(si.axis, function() {
|
|
1758
2131
|
return si.positive ? 0 : absoluteRadius;
|
|
@@ -1767,25 +2140,25 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1767
2140
|
si
|
|
1768
2141
|
}), si.axis).color(options.color);
|
|
1769
2142
|
var remainder = object.cutByPlane(plane);
|
|
1770
|
-
return union([ options.unionOriginal ? object : remainder, delta.translate(si.moveDelta) ]);
|
|
2143
|
+
return assertValidCSG$1(union([ options.unionOriginal ? object : remainder, delta.translate(si.moveDelta) ]), "reShape");
|
|
1771
2144
|
}
|
|
1772
2145
|
function chamfer(object, radius, orientation, options) {
|
|
1773
|
-
return reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
2146
|
+
return assertValidCSG$1(reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
1774
2147
|
return [ {
|
|
1775
2148
|
poly: slice,
|
|
1776
|
-
offset: new CSG.Vector3D(first)
|
|
2149
|
+
offset: new CSG$1.Vector3D(first)
|
|
1777
2150
|
}, {
|
|
1778
2151
|
poly: enlarge(slice, [ -radius * 2, -radius * 2 ]),
|
|
1779
|
-
offset: new CSG.Vector3D(last)
|
|
2152
|
+
offset: new CSG$1.Vector3D(last)
|
|
1780
2153
|
} ];
|
|
1781
|
-
});
|
|
2154
|
+
}), "chamfer");
|
|
1782
2155
|
}
|
|
1783
2156
|
function fillet(object, radius, orientation, options) {
|
|
1784
2157
|
options = options || {};
|
|
1785
|
-
return reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
1786
|
-
var v1 = new CSG.Vector3D(first);
|
|
1787
|
-
var v2 = new CSG.Vector3D(last);
|
|
1788
|
-
var res = options.resolution || CSG.defaultResolution3D;
|
|
2158
|
+
return assertValidCSG$1(reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
2159
|
+
var v1 = new CSG$1.Vector3D(first);
|
|
2160
|
+
var v2 = new CSG$1.Vector3D(last);
|
|
2161
|
+
var res = options.resolution || CSG$1.defaultResolution3D;
|
|
1789
2162
|
var slices = range(0, res).map(function(i) {
|
|
1790
2163
|
var p = i > 0 ? i / (res - 1) : 0;
|
|
1791
2164
|
var v = v1.lerp(v2, p);
|
|
@@ -1796,7 +2169,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1796
2169
|
};
|
|
1797
2170
|
});
|
|
1798
2171
|
return slices;
|
|
1799
|
-
});
|
|
2172
|
+
}), "fillet");
|
|
1800
2173
|
}
|
|
1801
2174
|
function calcRotate(part, solid, axis) {
|
|
1802
2175
|
var axes = {
|
|
@@ -1813,7 +2186,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1813
2186
|
}
|
|
1814
2187
|
function rotateAround(part, solid, axis, angle) {
|
|
1815
2188
|
var _calcRotate = calcRotate(part, solid, axis), rotationCenter = _calcRotate.rotationCenter, rotationAxis = _calcRotate.rotationAxis;
|
|
1816
|
-
return part.rotate(rotationCenter, rotationAxis, angle);
|
|
2189
|
+
return assertValidCSG$1("rotateAround")(part.rotate(rotationCenter, rotationAxis, angle));
|
|
1817
2190
|
}
|
|
1818
2191
|
function cloneProperties(from, to) {
|
|
1819
2192
|
return Object.entries(from).reduce(function(props, _ref) {
|
|
@@ -1823,19 +2196,20 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1823
2196
|
}, to);
|
|
1824
2197
|
}
|
|
1825
2198
|
function clone(o) {
|
|
1826
|
-
var c = CSG.fromPolygons(o.toPolygons());
|
|
2199
|
+
var c = CSG$1.fromPolygons(o.toPolygons());
|
|
1827
2200
|
cloneProperties(o, c);
|
|
1828
|
-
debug$2("clone", o, c, CSG);
|
|
1829
|
-
return c;
|
|
2201
|
+
debug$2("clone", o, c, CSG$1);
|
|
2202
|
+
return assertValidCSG$1(c, "clone");
|
|
1830
2203
|
}
|
|
1831
2204
|
function addConnector(object, name) {
|
|
1832
2205
|
var point = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [ 0, 0, 0 ];
|
|
1833
2206
|
var axis = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [ 1, 0, 0 ];
|
|
1834
2207
|
var normal = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [ 0, 0, 1 ];
|
|
1835
|
-
object.properties[name] = new CSG.Connector(point, axis, normal);
|
|
1836
|
-
return object;
|
|
2208
|
+
object.properties[name] = new CSG$1.Connector(point, axis, normal);
|
|
2209
|
+
return assertValidCSG$1("addConnector")(object);
|
|
1837
2210
|
}
|
|
1838
2211
|
var debug$1 = Debug("jscadUtils:parts");
|
|
2212
|
+
var assertValidCSG = AssertValidCSG("parts");
|
|
1839
2213
|
var parts = {
|
|
1840
2214
|
BBox: BBox$1,
|
|
1841
2215
|
Cube,
|
|
@@ -1845,7 +2219,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1845
2219
|
};
|
|
1846
2220
|
function BBox$1() {
|
|
1847
2221
|
function box(object) {
|
|
1848
|
-
return CSG.cube({
|
|
2222
|
+
return CSG$1.cube({
|
|
1849
2223
|
center: object.centroid(),
|
|
1850
2224
|
radius: object.size().dividedBy(2)
|
|
1851
2225
|
});
|
|
@@ -1853,17 +2227,17 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1853
2227
|
for (var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1854
2228
|
objects[_key] = arguments[_key];
|
|
1855
2229
|
}
|
|
1856
|
-
return objects.reduce(function(bbox, part) {
|
|
2230
|
+
return assertValidCSG(objects.reduce(function(bbox, part) {
|
|
1857
2231
|
var object = bbox ? union([ bbox, box(part) ]) : part;
|
|
1858
2232
|
return box(object);
|
|
1859
|
-
}, undefined);
|
|
2233
|
+
}, undefined), "BBox");
|
|
1860
2234
|
}
|
|
1861
2235
|
function Cube(width) {
|
|
1862
2236
|
var r = div$1(fromxyz(width), 2);
|
|
1863
|
-
return CSG.cube({
|
|
2237
|
+
return assertValidCSG(CSG$1.cube({
|
|
1864
2238
|
center: r,
|
|
1865
2239
|
radius: r
|
|
1866
|
-
});
|
|
2240
|
+
}), "Cube");
|
|
1867
2241
|
}
|
|
1868
2242
|
function RoundedCube(x, y, thickness, corner_radius) {
|
|
1869
2243
|
if (x.getBounds) {
|
|
@@ -1879,11 +2253,11 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1879
2253
|
center: [ r[0], r[1], 0 ],
|
|
1880
2254
|
radius: r,
|
|
1881
2255
|
roundradius: corner_radius,
|
|
1882
|
-
resolution: CSG.defaultResolution2D
|
|
2256
|
+
resolution: CSG$1.defaultResolution2D
|
|
1883
2257
|
}).extrude({
|
|
1884
2258
|
offset: [ 0, 0, thickness || 1.62 ]
|
|
1885
2259
|
});
|
|
1886
|
-
return roundedcube;
|
|
2260
|
+
return assertValidCSG(roundedcube, "RoundedCube");
|
|
1887
2261
|
}
|
|
1888
2262
|
function Cylinder(diameter, height) {
|
|
1889
2263
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
@@ -1892,39 +2266,39 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1892
2266
|
start: [ 0, 0, 0 ],
|
|
1893
2267
|
end: [ 0, 0, height ],
|
|
1894
2268
|
radius: diameter / 2,
|
|
1895
|
-
resolution: CSG.defaultResolution2D
|
|
2269
|
+
resolution: CSG$1.defaultResolution2D
|
|
1896
2270
|
}, options);
|
|
1897
|
-
return CSG.cylinder(options);
|
|
2271
|
+
return assertValidCSG(CSG$1.cylinder(options), "Cylinder");
|
|
1898
2272
|
}
|
|
1899
2273
|
function Cone(diameter1, diameter2, height) {
|
|
1900
2274
|
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
1901
2275
|
debug$1("parts.Cone", diameter1, diameter2, height, options);
|
|
1902
|
-
return CSG.cylinder(Object.assign({
|
|
2276
|
+
return assertValidCSG(CSG$1.cylinder(Object.assign({
|
|
1903
2277
|
start: [ 0, 0, 0 ],
|
|
1904
2278
|
end: [ 0, 0, height ],
|
|
1905
2279
|
radiusStart: diameter1 / 2,
|
|
1906
2280
|
radiusEnd: diameter2 / 2,
|
|
1907
|
-
resolution: CSG.defaultResolution2D
|
|
1908
|
-
}, options));
|
|
2281
|
+
resolution: CSG$1.defaultResolution2D
|
|
2282
|
+
}, options)), "Cone");
|
|
1909
2283
|
}
|
|
1910
2284
|
function Hexagon(diameter, height) {
|
|
1911
2285
|
debug$1("hexagon", diameter, height);
|
|
1912
2286
|
var radius = diameter / 2;
|
|
1913
2287
|
var sqrt3 = Math.sqrt(3) / 2;
|
|
1914
2288
|
var hex = CAG.fromPoints([ [ radius, 0 ], [ radius / 2, radius * sqrt3 ], [ -radius / 2, radius * sqrt3 ], [ -radius, 0 ], [ -radius / 2, -radius * sqrt3 ], [ radius / 2, -radius * sqrt3 ] ]);
|
|
1915
|
-
return hex.extrude({
|
|
2289
|
+
return assertValidCSG(hex.extrude({
|
|
1916
2290
|
offset: [ 0, 0, height ]
|
|
1917
|
-
});
|
|
2291
|
+
}), "Hexagon");
|
|
1918
2292
|
}
|
|
1919
2293
|
function Triangle(base, height) {
|
|
1920
2294
|
var radius = base / 2;
|
|
1921
2295
|
var tri = CAG.fromPoints([ [ -radius, 0 ], [ radius, 0 ], [ 0, Math.sin(30) * radius ] ]);
|
|
1922
|
-
return tri.extrude({
|
|
2296
|
+
return assertValidCSG(tri.extrude({
|
|
1923
2297
|
offset: [ 0, 0, height ]
|
|
1924
|
-
});
|
|
2298
|
+
}), "Triangle");
|
|
1925
2299
|
}
|
|
1926
2300
|
function Tube(outsideDiameter, insideDiameter, height, outsideOptions, insideOptions) {
|
|
1927
|
-
return Cylinder(outsideDiameter, height, outsideOptions).subtract(Cylinder(insideDiameter, height, insideOptions || outsideOptions));
|
|
2301
|
+
return assertValidCSG(Cylinder(outsideDiameter, height, outsideOptions).subtract(Cylinder(insideDiameter, height, insideOptions || outsideOptions)), "Tube");
|
|
1928
2302
|
}
|
|
1929
2303
|
function Anchor() {
|
|
1930
2304
|
var width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
|
|
@@ -1942,11 +2316,11 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1942
2316
|
center: [ r[0], r[1], 0 ],
|
|
1943
2317
|
radius: r,
|
|
1944
2318
|
roundradius: corner_radius,
|
|
1945
|
-
resolution: CSG.defaultResolution2D
|
|
2319
|
+
resolution: CSG$1.defaultResolution2D
|
|
1946
2320
|
}).extrude({
|
|
1947
2321
|
offset: [ 0, 0, thickness || 1.62 ]
|
|
1948
2322
|
});
|
|
1949
|
-
return board;
|
|
2323
|
+
return assertValidCSG(board, "Board");
|
|
1950
2324
|
}
|
|
1951
2325
|
var Hardware = {
|
|
1952
2326
|
Orientation: {
|
|
@@ -2037,6 +2411,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2037
2411
|
gap = gap || .25;
|
|
2038
2412
|
var inside = thickness - gap;
|
|
2039
2413
|
var outside = -thickness + gap;
|
|
2414
|
+
var boxHeight = box.size().z;
|
|
2415
|
+
if (Math.abs(height) >= boxHeight) {
|
|
2416
|
+
throw new Error("Rabett: height (".concat(height, ") must be less than the object height (").concat(boxHeight, ")"));
|
|
2417
|
+
}
|
|
2040
2418
|
debug("inside", inside, "outside", outside);
|
|
2041
2419
|
var group = Group();
|
|
2042
2420
|
var _box$bisect$parts = box.bisect("z", height, options).parts, top = _box$bisect$parts.positive, lower2_3rd = _box$bisect$parts.negative;
|
|
@@ -2107,10 +2485,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2107
2485
|
thickness = thickness || 2;
|
|
2108
2486
|
var s = div$1(xyz2array(size), 2);
|
|
2109
2487
|
var r = add(s, thickness);
|
|
2110
|
-
var box = CSG.cube({
|
|
2488
|
+
var box = CSG$1.cube({
|
|
2111
2489
|
center: r,
|
|
2112
2490
|
radius: r
|
|
2113
|
-
}).subtract(CSG.cube({
|
|
2491
|
+
}).subtract(CSG$1.cube({
|
|
2114
2492
|
center: r,
|
|
2115
2493
|
radius: s
|
|
2116
2494
|
}));
|
|
@@ -2128,7 +2506,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2128
2506
|
var BBox = function BBox(o) {
|
|
2129
2507
|
depreciated("BBox", true, "Use 'parts.BBox' instead");
|
|
2130
2508
|
var s = div$1(xyz2array(o.size()), 2);
|
|
2131
|
-
return CSG.cube({
|
|
2509
|
+
return CSG$1.cube({
|
|
2132
2510
|
center: s,
|
|
2133
2511
|
radius: s
|
|
2134
2512
|
}).align(o, "xyz");
|
|
@@ -2140,7 +2518,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2140
2518
|
var gap = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : .25;
|
|
2141
2519
|
var r = add(getRadius(box), -thickness / 2);
|
|
2142
2520
|
r[2] = thickness / 2;
|
|
2143
|
-
var cutter = CSG.cube({
|
|
2521
|
+
var cutter = CSG$1.cube({
|
|
2144
2522
|
center: r,
|
|
2145
2523
|
radius: r
|
|
2146
2524
|
}).align(box, "xy").color("green");
|