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