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