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