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