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