@jwc/jscad-utils 5.2.0 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -5
- package/dist/compat.js +641 -100
- package/dist/examples/bisect.jscad +471 -93
- package/dist/examples/bisect2.jscad +2614 -0
- package/dist/examples/boxes.jscad +481 -102
- package/dist/examples/chamfer.jscad +471 -93
- package/dist/examples/fillet.jscad +471 -93
- package/dist/examples/fit.jscad +471 -93
- package/dist/examples/groups.jscad +471 -93
- package/dist/examples/midlineTo.jscad +471 -93
- package/dist/examples/parts-hexagon.jscad +471 -93
- package/dist/examples/rabett-tb.jscad +471 -93
- package/dist/examples/rabett.jscad +471 -93
- package/dist/examples/rabett2.jscad +471 -93
- package/dist/examples/rabett3.jscad +2614 -0
- package/dist/examples/retraction-test.jscad +471 -93
- package/dist/examples/size.jscad +471 -93
- package/dist/examples/snap.jscad +471 -93
- package/dist/examples/text.jscad +471 -93
- package/dist/examples/wedge.jscad +471 -93
- package/dist/index.js +638 -100
- package/package.json +8 -4
- package/src/add-prototype.js +5 -1
- package/src/boxes.js +11 -3
- package/src/compat.js +3 -0
- package/src/group.js +13 -11
- package/src/parts.js +25 -23
- package/src/util.js +239 -72
- package/src/validate.js +335 -0
|
@@ -99,6 +99,8 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
99
99
|
enabled: [],
|
|
100
100
|
disabled: []
|
|
101
101
|
});
|
|
102
|
+
var jscadUtilsAssertValidCSGWarnings = options.assertValidCSGWarnings || false;
|
|
103
|
+
var jscadUtilsAssertValidCSG = options.assertValidCSG || false;
|
|
102
104
|
var jscadUtils = function(exports, jsCadCSG, scadApi) {
|
|
103
105
|
"use strict";
|
|
104
106
|
function _interopDefaultLegacy(e) {
|
|
@@ -332,6 +334,51 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
332
334
|
function _arrayWithHoles(r) {
|
|
333
335
|
if (Array.isArray(r)) return r;
|
|
334
336
|
}
|
|
337
|
+
function _createForOfIteratorHelper(r, e) {
|
|
338
|
+
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
339
|
+
if (!t) {
|
|
340
|
+
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
|
|
341
|
+
t && (r = t);
|
|
342
|
+
var n = 0, F = function() {};
|
|
343
|
+
return {
|
|
344
|
+
s: F,
|
|
345
|
+
n: function() {
|
|
346
|
+
return n >= r.length ? {
|
|
347
|
+
done: !0
|
|
348
|
+
} : {
|
|
349
|
+
done: !1,
|
|
350
|
+
value: r[n++]
|
|
351
|
+
};
|
|
352
|
+
},
|
|
353
|
+
e: function(r) {
|
|
354
|
+
throw r;
|
|
355
|
+
},
|
|
356
|
+
f: F
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
360
|
+
}
|
|
361
|
+
var o, a = !0, u = !1;
|
|
362
|
+
return {
|
|
363
|
+
s: function() {
|
|
364
|
+
t = t.call(r);
|
|
365
|
+
},
|
|
366
|
+
n: function() {
|
|
367
|
+
var r = t.next();
|
|
368
|
+
return a = r.done, r;
|
|
369
|
+
},
|
|
370
|
+
e: function(r) {
|
|
371
|
+
u = !0, o = r;
|
|
372
|
+
},
|
|
373
|
+
f: function() {
|
|
374
|
+
try {
|
|
375
|
+
a || null == t.return || t.return();
|
|
376
|
+
} finally {
|
|
377
|
+
if (u) throw o;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
}
|
|
335
382
|
function _defineProperty(e, r, t) {
|
|
336
383
|
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
337
384
|
value: t,
|
|
@@ -752,6 +799,219 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
752
799
|
c[3] = g || 1;
|
|
753
800
|
return o.setColor(c);
|
|
754
801
|
}
|
|
802
|
+
function validateCSG(csg, options) {
|
|
803
|
+
var errors = [];
|
|
804
|
+
var warnings = [];
|
|
805
|
+
if (!csg || !csg.polygons || csg.polygons.length === 0) {
|
|
806
|
+
errors.push("Empty mesh: no polygons");
|
|
807
|
+
return {
|
|
808
|
+
ok: false,
|
|
809
|
+
errors,
|
|
810
|
+
warnings
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
var opts = _objectSpread2({
|
|
814
|
+
fixTJunctions: true
|
|
815
|
+
}, options);
|
|
816
|
+
if (opts.fixTJunctions && typeof csg.canonicalized === "function") {
|
|
817
|
+
csg = csg.canonicalized();
|
|
818
|
+
if (typeof csg.reTesselated === "function") {
|
|
819
|
+
csg = csg.reTesselated();
|
|
820
|
+
}
|
|
821
|
+
if (typeof csg.fixTJunctions === "function") {
|
|
822
|
+
csg = csg.fixTJunctions();
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
var AREA_EPS = 1e-10;
|
|
826
|
+
var KEY_EPS = 1e-5;
|
|
827
|
+
var degenerateCount = 0;
|
|
828
|
+
var invalidVertexCount = 0;
|
|
829
|
+
var _iterator = _createForOfIteratorHelper(csg.polygons), _step;
|
|
830
|
+
try {
|
|
831
|
+
for (_iterator.s(); !(_step = _iterator.n()).done; ) {
|
|
832
|
+
var npoly = _step.value;
|
|
833
|
+
var _iterator4 = _createForOfIteratorHelper(npoly.vertices), _step4;
|
|
834
|
+
try {
|
|
835
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done; ) {
|
|
836
|
+
var nvert = _step4.value;
|
|
837
|
+
var np = nvert.pos;
|
|
838
|
+
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)) {
|
|
839
|
+
invalidVertexCount++;
|
|
840
|
+
break;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
} catch (err) {
|
|
844
|
+
_iterator4.e(err);
|
|
845
|
+
} finally {
|
|
846
|
+
_iterator4.f();
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
} catch (err) {
|
|
850
|
+
_iterator.e(err);
|
|
851
|
+
} finally {
|
|
852
|
+
_iterator.f();
|
|
853
|
+
}
|
|
854
|
+
if (invalidVertexCount > 0) {
|
|
855
|
+
errors.push(invalidVertexCount + " polygon(s) with invalid vertex coordinates (NaN or Infinity)");
|
|
856
|
+
}
|
|
857
|
+
function vtxKey(v) {
|
|
858
|
+
var p = v.pos;
|
|
859
|
+
return Math.round(p.x / KEY_EPS) + "," + Math.round(p.y / KEY_EPS) + "," + Math.round(p.z / KEY_EPS);
|
|
860
|
+
}
|
|
861
|
+
var validPolygons = [];
|
|
862
|
+
var _iterator2 = _createForOfIteratorHelper(csg.polygons), _step2;
|
|
863
|
+
try {
|
|
864
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) {
|
|
865
|
+
var poly = _step2.value;
|
|
866
|
+
var verts = poly.vertices;
|
|
867
|
+
var nv = verts.length;
|
|
868
|
+
if (nv < 3) {
|
|
869
|
+
degenerateCount++;
|
|
870
|
+
continue;
|
|
871
|
+
}
|
|
872
|
+
var hasInvalid = false;
|
|
873
|
+
var _iterator5 = _createForOfIteratorHelper(verts), _step5;
|
|
874
|
+
try {
|
|
875
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done; ) {
|
|
876
|
+
var vert = _step5.value;
|
|
877
|
+
var ip = vert.pos;
|
|
878
|
+
if (!Number.isFinite(ip.x) || !Number.isFinite(ip.y) || !Number.isFinite(ip.z)) {
|
|
879
|
+
hasInvalid = true;
|
|
880
|
+
break;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
} catch (err) {
|
|
884
|
+
_iterator5.e(err);
|
|
885
|
+
} finally {
|
|
886
|
+
_iterator5.f();
|
|
887
|
+
}
|
|
888
|
+
if (hasInvalid) continue;
|
|
889
|
+
var area = 0;
|
|
890
|
+
for (var ai = 0; ai < nv - 2; ai++) {
|
|
891
|
+
area += verts[ai + 1].pos.minus(verts[0].pos).cross(verts[ai + 2].pos.minus(verts[ai + 1].pos)).length();
|
|
892
|
+
}
|
|
893
|
+
area *= .5;
|
|
894
|
+
if (area < AREA_EPS) {
|
|
895
|
+
degenerateCount++;
|
|
896
|
+
continue;
|
|
897
|
+
}
|
|
898
|
+
validPolygons.push(poly);
|
|
899
|
+
}
|
|
900
|
+
} catch (err) {
|
|
901
|
+
_iterator2.e(err);
|
|
902
|
+
} finally {
|
|
903
|
+
_iterator2.f();
|
|
904
|
+
}
|
|
905
|
+
if (degenerateCount > 0) {
|
|
906
|
+
warnings.push(degenerateCount + " degenerate polygon(s) (fewer than 3 vertices or near-zero area)");
|
|
907
|
+
if (opts.fixTJunctions && typeof CSG !== "undefined") {
|
|
908
|
+
var cleaned = CSG.fromPolygons(validPolygons);
|
|
909
|
+
cleaned = cleaned.canonicalized();
|
|
910
|
+
if (typeof cleaned.reTesselated === "function") {
|
|
911
|
+
cleaned = cleaned.reTesselated();
|
|
912
|
+
}
|
|
913
|
+
if (typeof cleaned.fixTJunctions === "function") {
|
|
914
|
+
cleaned = cleaned.fixTJunctions();
|
|
915
|
+
}
|
|
916
|
+
validPolygons = [];
|
|
917
|
+
var _iterator3 = _createForOfIteratorHelper(cleaned.polygons), _step3;
|
|
918
|
+
try {
|
|
919
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done; ) {
|
|
920
|
+
var cpoly = _step3.value;
|
|
921
|
+
var cverts = cpoly.vertices;
|
|
922
|
+
var cnv = cverts.length;
|
|
923
|
+
if (cnv < 3) continue;
|
|
924
|
+
var carea = 0;
|
|
925
|
+
for (var cai = 0; cai < cnv - 2; cai++) {
|
|
926
|
+
carea += cverts[cai + 1].pos.minus(cverts[0].pos).cross(cverts[cai + 2].pos.minus(cverts[cai + 1].pos)).length();
|
|
927
|
+
}
|
|
928
|
+
carea *= .5;
|
|
929
|
+
if (carea < AREA_EPS) continue;
|
|
930
|
+
validPolygons.push(cpoly);
|
|
931
|
+
}
|
|
932
|
+
} catch (err) {
|
|
933
|
+
_iterator3.e(err);
|
|
934
|
+
} finally {
|
|
935
|
+
_iterator3.f();
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
var edgeCounts = {};
|
|
940
|
+
for (var _i = 0, _validPolygons = validPolygons; _i < _validPolygons.length; _i++) {
|
|
941
|
+
var vpoly = _validPolygons[_i];
|
|
942
|
+
var vverts = vpoly.vertices;
|
|
943
|
+
var vnv = vverts.length;
|
|
944
|
+
for (var ei = 0; ei < vnv; ei++) {
|
|
945
|
+
var v0 = vverts[ei];
|
|
946
|
+
var v1 = vverts[(ei + 1) % vnv];
|
|
947
|
+
var edgeKey = vtxKey(v0) + "/" + vtxKey(v1);
|
|
948
|
+
edgeCounts[edgeKey] = (edgeCounts[edgeKey] || 0) + 1;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
var unmatchedEdges = 0;
|
|
952
|
+
var nonManifoldEdges = 0;
|
|
953
|
+
var checked = {};
|
|
954
|
+
for (var _i2 = 0, _Object$keys = Object.keys(edgeCounts); _i2 < _Object$keys.length; _i2++) {
|
|
955
|
+
var _edgeKey = _Object$keys[_i2];
|
|
956
|
+
if (checked[_edgeKey]) continue;
|
|
957
|
+
var parts = _edgeKey.split("/");
|
|
958
|
+
var reverseKey = parts[1] + "/" + parts[0];
|
|
959
|
+
var forwardCount = edgeCounts[_edgeKey] || 0;
|
|
960
|
+
var reverseCount = edgeCounts[reverseKey] || 0;
|
|
961
|
+
checked[_edgeKey] = true;
|
|
962
|
+
checked[reverseKey] = true;
|
|
963
|
+
if (forwardCount !== reverseCount) {
|
|
964
|
+
unmatchedEdges += Math.abs(forwardCount - reverseCount);
|
|
965
|
+
}
|
|
966
|
+
if (forwardCount > 1 || reverseCount > 1) {
|
|
967
|
+
nonManifoldEdges++;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
if (unmatchedEdges > 0) {
|
|
971
|
+
errors.push(unmatchedEdges + " unmatched edge(s): mesh is not watertight");
|
|
972
|
+
}
|
|
973
|
+
if (nonManifoldEdges > 0) {
|
|
974
|
+
errors.push(nonManifoldEdges + " non-manifold edge(s): edge shared by more than 2 polygons");
|
|
975
|
+
}
|
|
976
|
+
return {
|
|
977
|
+
ok: errors.length === 0,
|
|
978
|
+
errors,
|
|
979
|
+
warnings
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
function _noOp(csg) {
|
|
983
|
+
return csg;
|
|
984
|
+
}
|
|
985
|
+
function _makeAssertFn(warnEnabled) {
|
|
986
|
+
return function _assert(csg) {
|
|
987
|
+
var functionName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "unknown";
|
|
988
|
+
var moduleName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "unknown";
|
|
989
|
+
if (!csg || csg.polygons === undefined) return csg;
|
|
990
|
+
var result = validateCSG(csg);
|
|
991
|
+
if (!result.ok) {
|
|
992
|
+
throw new Error(moduleName + ":" + functionName + ": " + "invalid CSG: " + result.errors.join(", "));
|
|
993
|
+
}
|
|
994
|
+
if (warnEnabled && result.warnings.length > 0) {
|
|
995
|
+
throw new Error(moduleName + ":" + functionName + ": " + "CSG warnings: " + result.warnings.join(", "));
|
|
996
|
+
}
|
|
997
|
+
return csg;
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
var _assertFn = _noOp;
|
|
1001
|
+
function _resolveFromGlobals() {
|
|
1002
|
+
var enabled = typeof jscadUtilsAssertValidCSG !== "undefined" && !!jscadUtilsAssertValidCSG;
|
|
1003
|
+
var warnEnabled = typeof jscadUtilsAssertValidCSGWarnings !== "undefined" && !!jscadUtilsAssertValidCSGWarnings;
|
|
1004
|
+
return enabled ? _makeAssertFn(warnEnabled) : _noOp;
|
|
1005
|
+
}
|
|
1006
|
+
function AssertValidCSG() {
|
|
1007
|
+
var moduleName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "unknown";
|
|
1008
|
+
{
|
|
1009
|
+
_assertFn = _resolveFromGlobals();
|
|
1010
|
+
}
|
|
1011
|
+
return function(csg, name) {
|
|
1012
|
+
return _assertFn(csg, name, moduleName);
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
755
1015
|
function init(proto) {
|
|
756
1016
|
if (proto.prototype._jscadutilsinit) return;
|
|
757
1017
|
proto.prototype.color = function(r, g, b, a) {
|
|
@@ -845,6 +1105,9 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
845
1105
|
proto.prototype.subtractIf = function subtractIf(object, condition) {
|
|
846
1106
|
return condition ? this.subtract(result(this, object)) : this;
|
|
847
1107
|
};
|
|
1108
|
+
proto.prototype.validate = function validate(options) {
|
|
1109
|
+
return validateCSG(this, options);
|
|
1110
|
+
};
|
|
848
1111
|
proto.prototype._translate = proto.prototype.translate;
|
|
849
1112
|
proto.prototype.translate = function translate() {
|
|
850
1113
|
if (arguments.length === 1) {
|
|
@@ -877,12 +1140,13 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
877
1140
|
__proto__: null,
|
|
878
1141
|
default: init
|
|
879
1142
|
});
|
|
880
|
-
var CSG = jsCadCSG__default["default"].CSG, CAG = jsCadCSG__default["default"].CAG;
|
|
1143
|
+
var CSG$1 = jsCadCSG__default["default"].CSG, CAG = jsCadCSG__default["default"].CAG;
|
|
881
1144
|
var rectangular_extrude = scadApi__default["default"].extrusions.rectangular_extrude;
|
|
882
1145
|
var _scadApi$text = scadApi__default["default"].text, vector_text = _scadApi$text.vector_text, vector_char = _scadApi$text.vector_char;
|
|
883
1146
|
var union = scadApi__default["default"].booleanOps.union;
|
|
884
|
-
init(CSG);
|
|
1147
|
+
init(CSG$1);
|
|
885
1148
|
var debug$3 = Debug("jscadUtils:group");
|
|
1149
|
+
var assertValidCSG$2 = AssertValidCSG("group");
|
|
886
1150
|
function JsCadUtilsGroup() {
|
|
887
1151
|
var names = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
888
1152
|
var parts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
@@ -933,7 +1197,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
933
1197
|
debug$3("combine mapPick", value, key, object);
|
|
934
1198
|
return map ? map(value, key, index, object) : identity(value);
|
|
935
1199
|
}, self.name));
|
|
936
|
-
return g.subtractIf(self.holes && Array.isArray(self.holes) ? union(self.holes) : self.holes, self.holes && !options.noholes);
|
|
1200
|
+
return assertValidCSG$2(g.subtractIf(self.holes && Array.isArray(self.holes) ? union(self.holes) : self.holes, self.holes && !options.noholes), "combine");
|
|
937
1201
|
} catch (err) {
|
|
938
1202
|
debug$3("combine error", this, pieces, options, err);
|
|
939
1203
|
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");
|
|
@@ -974,7 +1238,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
974
1238
|
});
|
|
975
1239
|
if (self.holes) {
|
|
976
1240
|
group.holes = toArray(self.holes).map(function(part) {
|
|
977
|
-
return map(CSG.fromPolygons(part.toPolygons()), "holes");
|
|
1241
|
+
return assertValidCSG$2(map(CSG$1.fromPolygons(part.toPolygons()), "holes"), "clone");
|
|
978
1242
|
});
|
|
979
1243
|
}
|
|
980
1244
|
return group;
|
|
@@ -993,7 +1257,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
993
1257
|
var rotationCenter = solid.centroid();
|
|
994
1258
|
var rotationAxis = axes[axis];
|
|
995
1259
|
self.map(function(part) {
|
|
996
|
-
return part.rotate(rotationCenter, rotationAxis, angle);
|
|
1260
|
+
return assertValidCSG$2(part.rotate(rotationCenter, rotationAxis, angle), "rotate");
|
|
997
1261
|
});
|
|
998
1262
|
return self;
|
|
999
1263
|
};
|
|
@@ -1006,7 +1270,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1006
1270
|
var self = this;
|
|
1007
1271
|
var t = calcSnap(self.combine(part), to, axis, orientation, delta);
|
|
1008
1272
|
self.map(function(part) {
|
|
1009
|
-
return part.translate(t);
|
|
1273
|
+
return assertValidCSG$2(part.translate(t), "snap");
|
|
1010
1274
|
});
|
|
1011
1275
|
return self;
|
|
1012
1276
|
} catch (err) {
|
|
@@ -1021,7 +1285,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1021
1285
|
noholes: true
|
|
1022
1286
|
}), axis, to, delta);
|
|
1023
1287
|
self.map(function(part) {
|
|
1024
|
-
return part.translate(t);
|
|
1288
|
+
return assertValidCSG$2(part.translate(t), "align");
|
|
1025
1289
|
});
|
|
1026
1290
|
return self;
|
|
1027
1291
|
} catch (err) {
|
|
@@ -1053,14 +1317,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1053
1317
|
var myConnector = connectorName.split(".").reduce(function(a, v) {
|
|
1054
1318
|
return a[v];
|
|
1055
1319
|
}, self.parts[partName].properties);
|
|
1056
|
-
debug$3("toConnector", to instanceof CSG.Connector);
|
|
1320
|
+
debug$3("toConnector", to instanceof CSG$1.Connector);
|
|
1057
1321
|
var toConnector = toConnectorName.split(".").reduce(function(a, v) {
|
|
1058
1322
|
return a[v];
|
|
1059
1323
|
}, to.properties);
|
|
1060
1324
|
var matrix = myConnector.getTransformationTo(toConnector, mirror, normalrotation);
|
|
1061
1325
|
debug$3("connectTo", matrix);
|
|
1062
1326
|
self.map(function(part) {
|
|
1063
|
-
return part.transform(matrix);
|
|
1327
|
+
return assertValidCSG$2(part.transform(matrix), "connectTo");
|
|
1064
1328
|
});
|
|
1065
1329
|
return self;
|
|
1066
1330
|
};
|
|
@@ -1071,7 +1335,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1071
1335
|
return to - size[a] / 2;
|
|
1072
1336
|
});
|
|
1073
1337
|
self.map(function(part) {
|
|
1074
|
-
return part.translate(t);
|
|
1338
|
+
return assertValidCSG$2(part.translate(t), "midlineTo");
|
|
1075
1339
|
});
|
|
1076
1340
|
return self;
|
|
1077
1341
|
};
|
|
@@ -1080,7 +1344,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1080
1344
|
var t = Array.isArray(x) ? x : [ x, y, z ];
|
|
1081
1345
|
debug$3("translate", t);
|
|
1082
1346
|
self.map(function(part) {
|
|
1083
|
-
return part.translate(t);
|
|
1347
|
+
return assertValidCSG$2(part.translate(t), "translate");
|
|
1084
1348
|
});
|
|
1085
1349
|
return self;
|
|
1086
1350
|
};
|
|
@@ -1090,7 +1354,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1090
1354
|
if (!map) map = identity;
|
|
1091
1355
|
var g = Group();
|
|
1092
1356
|
p.forEach(function(name) {
|
|
1093
|
-
g.add(map(CSG.fromPolygons(self.parts[name].toPolygons()), name), name);
|
|
1357
|
+
g.add(assertValidCSG$2(map(CSG$1.fromPolygons(self.parts[name].toPolygons()), name), "pick"), name);
|
|
1094
1358
|
});
|
|
1095
1359
|
return g;
|
|
1096
1360
|
};
|
|
@@ -1105,7 +1369,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1105
1369
|
debug$3("array error", _this, parts);
|
|
1106
1370
|
throw error('group::array error "'.concat(name, '" not found.\nthis: ').concat(_this, '\nparts: "').concat(parts, '"\n'), "JSCAD_UTILS_GROUP_ERROR");
|
|
1107
1371
|
}
|
|
1108
|
-
a.push(map(CSG.fromPolygons(self.parts[name].toPolygons()), name));
|
|
1372
|
+
a.push(assertValidCSG$2(map(CSG$1.fromPolygons(self.parts[name].toPolygons()), name), "array"));
|
|
1109
1373
|
});
|
|
1110
1374
|
return a;
|
|
1111
1375
|
};
|
|
@@ -1138,7 +1402,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1138
1402
|
self.names = names && names.length > 0 && names.split(",") || [];
|
|
1139
1403
|
if (Array.isArray(objects)) {
|
|
1140
1404
|
self.parts = zipObject(self.names, objects);
|
|
1141
|
-
} else if (objects instanceof CSG) {
|
|
1405
|
+
} else if (objects instanceof CSG$1) {
|
|
1142
1406
|
self.parts = zipObject(self.names, [ objects ]);
|
|
1143
1407
|
} else {
|
|
1144
1408
|
self.parts = objects || {};
|
|
@@ -1159,6 +1423,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1159
1423
|
return new JsCadUtilsGroup(self.names, self.parts, self.holes);
|
|
1160
1424
|
}
|
|
1161
1425
|
var debug$2 = Debug("jscadUtils:util");
|
|
1426
|
+
var assertValidCSG$1 = AssertValidCSG("util");
|
|
1162
1427
|
var NOZZEL_SIZE = .4;
|
|
1163
1428
|
var nearest = {
|
|
1164
1429
|
under: function under(desired) {
|
|
@@ -1235,12 +1500,12 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1235
1500
|
h: height || 2
|
|
1236
1501
|
}));
|
|
1237
1502
|
});
|
|
1238
|
-
return center(union(o));
|
|
1503
|
+
return assertValidCSG$1(center(union(o)), "label");
|
|
1239
1504
|
}
|
|
1240
1505
|
function text(text) {
|
|
1241
1506
|
var l = vector_char(0, 0, text);
|
|
1242
1507
|
var _char = l.segments.reduce(function(result, segment) {
|
|
1243
|
-
var path = new CSG.Path2D(segment);
|
|
1508
|
+
var path = new CSG$1.Path2D(segment);
|
|
1244
1509
|
var cag = path.expandToCAG(2);
|
|
1245
1510
|
return result ? result.union(cag) : cag;
|
|
1246
1511
|
}, undefined);
|
|
@@ -1248,17 +1513,17 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1248
1513
|
}
|
|
1249
1514
|
function unitCube(length, radius) {
|
|
1250
1515
|
radius = radius || .5;
|
|
1251
|
-
return CSG.cube({
|
|
1516
|
+
return assertValidCSG$1(CSG$1.cube({
|
|
1252
1517
|
center: [ 0, 0, 0 ],
|
|
1253
1518
|
radius: [ radius, radius, length || .5 ]
|
|
1254
|
-
});
|
|
1519
|
+
}), "unitCube");
|
|
1255
1520
|
}
|
|
1256
1521
|
function unitAxis(length, radius, centroid) {
|
|
1257
1522
|
debug$2("unitAxis", length, radius, centroid);
|
|
1258
1523
|
centroid = centroid || [ 0, 0, 0 ];
|
|
1259
1524
|
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) ]);
|
|
1260
|
-
unitaxis.properties.origin = new CSG.Connector([ 0, 0, 0 ], [ 1, 0, 0 ], [ 0, 1, 0 ]);
|
|
1261
|
-
return unitaxis.translate(centroid);
|
|
1525
|
+
unitaxis.properties.origin = new CSG$1.Connector([ 0, 0, 0 ], [ 1, 0, 0 ], [ 0, 1, 0 ]);
|
|
1526
|
+
return assertValidCSG$1(unitaxis.translate(centroid), "unitAxis");
|
|
1262
1527
|
}
|
|
1263
1528
|
function toArray(a) {
|
|
1264
1529
|
return Array.isArray(a) ? a : [ a ];
|
|
@@ -1348,15 +1613,15 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1348
1613
|
}
|
|
1349
1614
|
function center(object, objectSize) {
|
|
1350
1615
|
objectSize = objectSize || size(object.getBounds());
|
|
1351
|
-
return centerY(centerX(object, objectSize), objectSize);
|
|
1616
|
+
return assertValidCSG$1(centerY(centerX(object, objectSize), objectSize), "center");
|
|
1352
1617
|
}
|
|
1353
1618
|
function centerY(object, objectSize) {
|
|
1354
1619
|
objectSize = objectSize || size(object.getBounds());
|
|
1355
|
-
return object.translate([ 0, -objectSize.y / 2, 0 ]);
|
|
1620
|
+
return assertValidCSG$1(object.translate([ 0, -objectSize.y / 2, 0 ]), "centerY");
|
|
1356
1621
|
}
|
|
1357
1622
|
function centerX(object, objectSize) {
|
|
1358
1623
|
objectSize = objectSize || size(object.getBounds());
|
|
1359
|
-
return object.translate([ -objectSize.x / 2, 0, 0 ]);
|
|
1624
|
+
return assertValidCSG$1(object.translate([ -objectSize.x / 2, 0, 0 ]), "centerX");
|
|
1360
1625
|
}
|
|
1361
1626
|
function enlarge(object, x, y, z) {
|
|
1362
1627
|
var a;
|
|
@@ -1374,7 +1639,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1374
1639
|
var new_object = object.scale(t);
|
|
1375
1640
|
var new_centroid = centroid(new_object);
|
|
1376
1641
|
var delta = new_centroid.minus(objectCentroid).times(-1);
|
|
1377
|
-
return new_object.translate(delta);
|
|
1642
|
+
return assertValidCSG$1(new_object.translate(delta), "enlarge");
|
|
1378
1643
|
}
|
|
1379
1644
|
function fit(object, x, y, z, keep_aspect_ratio) {
|
|
1380
1645
|
var a;
|
|
@@ -1394,10 +1659,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1394
1659
|
}
|
|
1395
1660
|
var s = [ scale(objectSize.x, x), scale(objectSize.y, y), scale(objectSize.z, z) ];
|
|
1396
1661
|
var min$1 = min(s);
|
|
1397
|
-
return centerWith(object.scale(s.map(function(d, i) {
|
|
1662
|
+
return assertValidCSG$1(centerWith(object.scale(s.map(function(d, i) {
|
|
1398
1663
|
if (a[i] === 0) return 1;
|
|
1399
1664
|
return keep_aspect_ratio ? min$1 : d;
|
|
1400
|
-
})), "xyz", object);
|
|
1665
|
+
})), "xyz", object), "fit");
|
|
1401
1666
|
}
|
|
1402
1667
|
function shift(object, x, y, z) {
|
|
1403
1668
|
var hsize = this.div(this.size(object.getBounds()), 2);
|
|
@@ -1405,10 +1670,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1405
1670
|
}
|
|
1406
1671
|
function zero(object) {
|
|
1407
1672
|
var bounds = object.getBounds();
|
|
1408
|
-
return object.translate([ 0, 0, -bounds[0].z ]);
|
|
1673
|
+
return assertValidCSG$1(object.translate([ 0, 0, -bounds[0].z ]), "zero");
|
|
1409
1674
|
}
|
|
1410
1675
|
function mirrored4(x) {
|
|
1411
|
-
return x.union([ x.mirroredY(90), x.mirroredX(90), x.mirroredY(90).mirroredX(90) ]);
|
|
1676
|
+
return assertValidCSG$1(x.union([ x.mirroredY(90), x.mirroredX(90), x.mirroredY(90).mirroredX(90) ]), "mirrored4");
|
|
1412
1677
|
}
|
|
1413
1678
|
var flushSide = {
|
|
1414
1679
|
"above-outside": [ 1, 0 ],
|
|
@@ -1469,10 +1734,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1469
1734
|
function snap(moveobj, withobj, axis, orientation, delta) {
|
|
1470
1735
|
debug$2("snap", moveobj, withobj, axis, orientation, delta);
|
|
1471
1736
|
var t = calcSnap(moveobj, withobj, axis, orientation, delta);
|
|
1472
|
-
return moveobj.translate(t);
|
|
1737
|
+
return assertValidCSG$1(moveobj.translate(t), "snap");
|
|
1473
1738
|
}
|
|
1474
1739
|
function flush(moveobj, withobj, axis, mside, wside) {
|
|
1475
|
-
return moveobj.translate(calcFlush(moveobj, withobj, axis, mside, wside));
|
|
1740
|
+
return assertValidCSG$1(moveobj.translate(calcFlush(moveobj, withobj, axis, mside, wside)), "flush");
|
|
1476
1741
|
}
|
|
1477
1742
|
function axisApply(axes, valfun, a) {
|
|
1478
1743
|
debug$2("axisApply", axes, valfun, a);
|
|
@@ -1488,7 +1753,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1488
1753
|
return retval;
|
|
1489
1754
|
}
|
|
1490
1755
|
function axis2array(axes, valfun) {
|
|
1491
|
-
depreciated("axis2array");
|
|
1756
|
+
depreciated("axis2array", false, "Use axisApply instead.");
|
|
1492
1757
|
var a = [ 0, 0, 0 ];
|
|
1493
1758
|
var lookup = {
|
|
1494
1759
|
x: 0,
|
|
@@ -1518,7 +1783,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1518
1783
|
});
|
|
1519
1784
|
}
|
|
1520
1785
|
function midlineTo(o, axis, to) {
|
|
1521
|
-
return o.translate(calcmidlineTo(o, axis, to));
|
|
1786
|
+
return assertValidCSG$1(o.translate(calcmidlineTo(o, axis, to)), "midlineTo");
|
|
1522
1787
|
}
|
|
1523
1788
|
function translator(o, axis, withObj) {
|
|
1524
1789
|
var objectCentroid = centroid(o);
|
|
@@ -1538,7 +1803,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1538
1803
|
return delta ? add(t, delta) : t;
|
|
1539
1804
|
}
|
|
1540
1805
|
function centerWith(o, axis, withObj) {
|
|
1541
|
-
return o.translate(calcCenterWith(o, axis, withObj));
|
|
1806
|
+
return assertValidCSG$1(o.translate(calcCenterWith(o, axis, withObj)), "centerWith");
|
|
1542
1807
|
}
|
|
1543
1808
|
function getDelta(size, bounds, axis, offset, nonzero) {
|
|
1544
1809
|
if (!isEmpty(offset) && nonzero) {
|
|
@@ -1551,6 +1816,95 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1551
1816
|
return bounds[0][a] + (isEmpty(dist) ? size[axis] / 2 : dist);
|
|
1552
1817
|
});
|
|
1553
1818
|
}
|
|
1819
|
+
var EPS = 1e-5;
|
|
1820
|
+
function splitCSGByPlane(csg, plane) {
|
|
1821
|
+
var frontPolys = [];
|
|
1822
|
+
var backPolys = [];
|
|
1823
|
+
csg.polygons.forEach(function(poly) {
|
|
1824
|
+
var vertices = poly.vertices;
|
|
1825
|
+
var numVerts = vertices.length;
|
|
1826
|
+
var hasfront = false;
|
|
1827
|
+
var hasback = false;
|
|
1828
|
+
var vertexIsBack = [];
|
|
1829
|
+
for (var i = 0; i < numVerts; i++) {
|
|
1830
|
+
var t = plane.normal.dot(vertices[i].pos) - plane.w;
|
|
1831
|
+
vertexIsBack.push(t < 0);
|
|
1832
|
+
if (t > EPS) hasfront = true;
|
|
1833
|
+
if (t < -EPS) hasback = true;
|
|
1834
|
+
}
|
|
1835
|
+
if (!hasfront && !hasback) {
|
|
1836
|
+
var d = plane.normal.dot(poly.plane.normal);
|
|
1837
|
+
if (d >= 0) {
|
|
1838
|
+
frontPolys.push(poly);
|
|
1839
|
+
} else {
|
|
1840
|
+
backPolys.push(poly);
|
|
1841
|
+
}
|
|
1842
|
+
} else if (!hasback) {
|
|
1843
|
+
frontPolys.push(poly);
|
|
1844
|
+
} else if (!hasfront) {
|
|
1845
|
+
backPolys.push(poly);
|
|
1846
|
+
} else {
|
|
1847
|
+
var fv = [];
|
|
1848
|
+
var bv = [];
|
|
1849
|
+
for (var vi = 0; vi < numVerts; vi++) {
|
|
1850
|
+
var vertex = vertices[vi];
|
|
1851
|
+
var nextVi = (vi + 1) % numVerts;
|
|
1852
|
+
var isback = vertexIsBack[vi];
|
|
1853
|
+
var nextisback = vertexIsBack[nextVi];
|
|
1854
|
+
if (isback === nextisback) {
|
|
1855
|
+
if (isback) {
|
|
1856
|
+
bv.push(vertex);
|
|
1857
|
+
} else {
|
|
1858
|
+
fv.push(vertex);
|
|
1859
|
+
}
|
|
1860
|
+
} else {
|
|
1861
|
+
var point = vertex.pos;
|
|
1862
|
+
var nextpoint = vertices[nextVi].pos;
|
|
1863
|
+
var ip = plane.splitLineBetweenPoints(point, nextpoint);
|
|
1864
|
+
var iv = new CSG$1.Vertex(ip);
|
|
1865
|
+
if (isback) {
|
|
1866
|
+
bv.push(vertex);
|
|
1867
|
+
bv.push(iv);
|
|
1868
|
+
fv.push(iv);
|
|
1869
|
+
} else {
|
|
1870
|
+
fv.push(vertex);
|
|
1871
|
+
fv.push(iv);
|
|
1872
|
+
bv.push(iv);
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
var EPSEPS = EPS * EPS;
|
|
1877
|
+
if (fv.length >= 3) {
|
|
1878
|
+
var prev = fv[fv.length - 1];
|
|
1879
|
+
for (var fi = 0; fi < fv.length; fi++) {
|
|
1880
|
+
var curr = fv[fi];
|
|
1881
|
+
if (curr.pos.distanceToSquared(prev.pos) < EPSEPS) {
|
|
1882
|
+
fv.splice(fi, 1);
|
|
1883
|
+
fi--;
|
|
1884
|
+
}
|
|
1885
|
+
prev = curr;
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
if (bv.length >= 3) {
|
|
1889
|
+
var prev = bv[bv.length - 1];
|
|
1890
|
+
for (var bi = 0; bi < bv.length; bi++) {
|
|
1891
|
+
var curr = bv[bi];
|
|
1892
|
+
if (curr.pos.distanceToSquared(prev.pos) < EPSEPS) {
|
|
1893
|
+
bv.splice(bi, 1);
|
|
1894
|
+
bi--;
|
|
1895
|
+
}
|
|
1896
|
+
prev = curr;
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
if (fv.length >= 3) frontPolys.push(new CSG$1.Polygon(fv, poly.shared, poly.plane));
|
|
1900
|
+
if (bv.length >= 3) backPolys.push(new CSG$1.Polygon(bv, poly.shared, poly.plane));
|
|
1901
|
+
}
|
|
1902
|
+
});
|
|
1903
|
+
return {
|
|
1904
|
+
front: CSG$1.fromPolygons(frontPolys),
|
|
1905
|
+
back: CSG$1.fromPolygons(backPolys)
|
|
1906
|
+
};
|
|
1907
|
+
}
|
|
1554
1908
|
function bisect() {
|
|
1555
1909
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1556
1910
|
args[_key] = arguments[_key];
|
|
@@ -1612,13 +1966,13 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1612
1966
|
}[[ axis, rotateaxis ].sort().join("")];
|
|
1613
1967
|
var centroid = object.centroid();
|
|
1614
1968
|
var rotateDelta = getDelta(objectSize, bounds, rotateOffsetAxis, rotateoffset);
|
|
1615
|
-
var rotationCenter = options.rotationCenter || new CSG.Vector3D(axisApply("xyz", function(i, a) {
|
|
1969
|
+
var rotationCenter = options.rotationCenter || new CSG$1.Vector3D(axisApply("xyz", function(i, a) {
|
|
1616
1970
|
if (a == axis) return cutDelta[i];
|
|
1617
1971
|
if (a == rotateOffsetAxis) return rotateDelta[i];
|
|
1618
1972
|
return centroid[a];
|
|
1619
1973
|
}));
|
|
1620
1974
|
var theRotationAxis = rotationAxes[rotateaxis];
|
|
1621
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).translate(cutDelta).rotate(rotationCenter, theRotationAxis, angle);
|
|
1975
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).translate(cutDelta).rotate(rotationCenter, theRotationAxis, angle);
|
|
1622
1976
|
debug$2("bisect", debug$2.enabled && {
|
|
1623
1977
|
axis,
|
|
1624
1978
|
offset,
|
|
@@ -1631,7 +1985,26 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1631
1985
|
cutplane,
|
|
1632
1986
|
options
|
|
1633
1987
|
});
|
|
1634
|
-
var
|
|
1988
|
+
var negative = object.cutByPlane(cutplane.plane);
|
|
1989
|
+
var positive = object.cutByPlane(cutplane.plane.flipped());
|
|
1990
|
+
var negSize = size(negative);
|
|
1991
|
+
var posSize = size(positive);
|
|
1992
|
+
if (negSize[axis] >= objectSize[axis] - EPS || posSize[axis] >= objectSize[axis] - EPS) {
|
|
1993
|
+
var halves = splitCSGByPlane(object, cutplane.plane);
|
|
1994
|
+
if (negSize[axis] >= objectSize[axis] - EPS) {
|
|
1995
|
+
negative = halves.back;
|
|
1996
|
+
try {
|
|
1997
|
+
negative = negative.cutByPlane(cutplane.plane);
|
|
1998
|
+
} catch (e) {}
|
|
1999
|
+
}
|
|
2000
|
+
if (posSize[axis] >= objectSize[axis] - EPS) {
|
|
2001
|
+
positive = halves.front;
|
|
2002
|
+
try {
|
|
2003
|
+
positive = positive.cutByPlane(cutplane.plane.flipped());
|
|
2004
|
+
} catch (e) {}
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
var g = Group("negative,positive", [ negative.color(options.color && "red"), positive.color(options.color && "blue") ]);
|
|
1635
2008
|
if (options.addRotationCenter) g.add(unitAxis(objectSize.length() + 10, .1, rotationCenter), "rotationCenter");
|
|
1636
2009
|
return g;
|
|
1637
2010
|
}
|
|
@@ -1644,9 +2017,9 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1644
2017
|
addRotationCenter: true
|
|
1645
2018
|
};
|
|
1646
2019
|
var info = normalVector(axis);
|
|
1647
|
-
var rotationCenter = options.rotationCenter || new CSG.Vector3D(0, 0, 0);
|
|
2020
|
+
var rotationCenter = options.rotationCenter || new CSG$1.Vector3D(0, 0, 0);
|
|
1648
2021
|
var theRotationAxis = rotationAxes[rotateaxis];
|
|
1649
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).rotate(rotationCenter, theRotationAxis, angle);
|
|
2022
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(info.orthoNormalCartesian[0], info.orthoNormalCartesian[1]).rotate(rotationCenter, theRotationAxis, angle);
|
|
1650
2023
|
var g = Group("negative,positive", [ object.cutByPlane(cutplane.plane).color(options.color && "red"), object.cutByPlane(cutplane.plane.flipped()).color(options.color && "blue") ]);
|
|
1651
2024
|
if (options.addRotationCenter) {
|
|
1652
2025
|
var objectSize = size(object);
|
|
@@ -1671,14 +2044,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1671
2044
|
var bounds = object.getBounds();
|
|
1672
2045
|
var objectSize = size(object);
|
|
1673
2046
|
var cutDelta = getDelta(objectSize, bounds, axis, offset, true);
|
|
1674
|
-
return object.stretchAtPlane(normal[axis], cutDelta, distance);
|
|
2047
|
+
return assertValidCSG$1(object.stretchAtPlane(normal[axis], cutDelta, distance), "stretch");
|
|
1675
2048
|
}
|
|
1676
2049
|
function poly2solid(top, bottom, height) {
|
|
1677
2050
|
if (top.sides.length == 0) {
|
|
1678
|
-
return new CSG;
|
|
2051
|
+
return new CSG$1;
|
|
1679
2052
|
}
|
|
1680
|
-
var offsetVector = CSG.Vector3D.Create(0, 0, height);
|
|
1681
|
-
var normalVector = CSG.Vector3D.Create(0, 1, 0);
|
|
2053
|
+
var offsetVector = CSG$1.Vector3D.Create(0, 0, height);
|
|
2054
|
+
var normalVector = CSG$1.Vector3D.Create(0, 1, 0);
|
|
1682
2055
|
var polygons = [];
|
|
1683
2056
|
polygons = polygons.concat(bottom._toPlanePolygons({
|
|
1684
2057
|
translation: [ 0, 0, 0 ],
|
|
@@ -1690,14 +2063,14 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1690
2063
|
normalVector,
|
|
1691
2064
|
flipped: offsetVector.z < 0
|
|
1692
2065
|
}));
|
|
1693
|
-
var c1 = new CSG.Connector(offsetVector.times(0), [ 0, 0, offsetVector.z ], normalVector);
|
|
1694
|
-
var c2 = new CSG.Connector(offsetVector, [ 0, 0, offsetVector.z ], normalVector);
|
|
2066
|
+
var c1 = new CSG$1.Connector(offsetVector.times(0), [ 0, 0, offsetVector.z ], normalVector);
|
|
2067
|
+
var c2 = new CSG$1.Connector(offsetVector, [ 0, 0, offsetVector.z ], normalVector);
|
|
1695
2068
|
polygons = polygons.concat(bottom._toWallPolygons({
|
|
1696
2069
|
cag: top,
|
|
1697
2070
|
toConnector1: c1,
|
|
1698
2071
|
toConnector2: c2
|
|
1699
2072
|
}));
|
|
1700
|
-
return CSG.fromPolygons(polygons);
|
|
2073
|
+
return assertValidCSG$1(CSG$1.fromPolygons(polygons), "poly2solid");
|
|
1701
2074
|
}
|
|
1702
2075
|
function slices2poly(slices, options, axis) {
|
|
1703
2076
|
debug$2("slices2poly", slices, options, axis);
|
|
@@ -1706,7 +2079,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1706
2079
|
twiststeps: 0
|
|
1707
2080
|
}, options);
|
|
1708
2081
|
var twistangle = options && parseFloat(options.twistangle) || 0;
|
|
1709
|
-
options && parseInt(options.twiststeps) || CSG.defaultResolution3D;
|
|
2082
|
+
options && parseInt(options.twiststeps) || CSG$1.defaultResolution3D;
|
|
1710
2083
|
var normalVector = options.si.normalVector;
|
|
1711
2084
|
var polygons = [];
|
|
1712
2085
|
var first$1 = first(slices);
|
|
@@ -1735,8 +2108,8 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1735
2108
|
var nextidx = idx + 1;
|
|
1736
2109
|
var top = !up ? slices[nextidx] : slice;
|
|
1737
2110
|
var bottom = up ? slices[nextidx] : slice;
|
|
1738
|
-
var c1 = new CSG.Connector(bottom.offset, connectorAxis, rotate(normalVector, twistangle, idx / slices.length));
|
|
1739
|
-
var c2 = new CSG.Connector(top.offset, connectorAxis, rotate(normalVector, twistangle, nextidx / slices.length));
|
|
2111
|
+
var c1 = new CSG$1.Connector(bottom.offset, connectorAxis, rotate(normalVector, twistangle, idx / slices.length));
|
|
2112
|
+
var c2 = new CSG$1.Connector(top.offset, connectorAxis, rotate(normalVector, twistangle, nextidx / slices.length));
|
|
1740
2113
|
polygons = polygons.concat(bottom.poly._toWallPolygons({
|
|
1741
2114
|
cag: top.poly,
|
|
1742
2115
|
toConnector1: c1,
|
|
@@ -1744,21 +2117,21 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1744
2117
|
}));
|
|
1745
2118
|
}
|
|
1746
2119
|
});
|
|
1747
|
-
return CSG.fromPolygons(polygons);
|
|
2120
|
+
return assertValidCSG$1(CSG$1.fromPolygons(polygons), "slices2poly");
|
|
1748
2121
|
}
|
|
1749
2122
|
function normalVector(axis) {
|
|
1750
2123
|
var axisInfo = {
|
|
1751
2124
|
z: {
|
|
1752
2125
|
orthoNormalCartesian: [ "X", "Y" ],
|
|
1753
|
-
normalVector: CSG.Vector3D.Create(0, 1, 0)
|
|
2126
|
+
normalVector: CSG$1.Vector3D.Create(0, 1, 0)
|
|
1754
2127
|
},
|
|
1755
2128
|
x: {
|
|
1756
2129
|
orthoNormalCartesian: [ "Y", "Z" ],
|
|
1757
|
-
normalVector: CSG.Vector3D.Create(0, 0, 1)
|
|
2130
|
+
normalVector: CSG$1.Vector3D.Create(0, 0, 1)
|
|
1758
2131
|
},
|
|
1759
2132
|
y: {
|
|
1760
|
-
orthoNormalCartesian: [ "
|
|
1761
|
-
normalVector: CSG.Vector3D.Create(0, 0, 1)
|
|
2133
|
+
orthoNormalCartesian: [ "Z", "X" ],
|
|
2134
|
+
normalVector: CSG$1.Vector3D.Create(0, 0, 1)
|
|
1762
2135
|
}
|
|
1763
2136
|
};
|
|
1764
2137
|
if (!axisInfo[axis]) error("normalVector: invalid axis " + axis);
|
|
@@ -1799,7 +2172,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1799
2172
|
var si = sliceParams(orientation, radius, b);
|
|
1800
2173
|
debug$2("reShape", absoluteRadius, si);
|
|
1801
2174
|
if (si.axis !== "z") throw new Error('reShape error: CAG._toPlanePolygons only uses the "z" axis. You must use the "z" axis for now.');
|
|
1802
|
-
var cutplane = CSG.OrthoNormalBasis.GetCartesian(si.orthoNormalCartesian[0], si.orthoNormalCartesian[1]).translate(si.cutDelta);
|
|
2175
|
+
var cutplane = CSG$1.OrthoNormalBasis.GetCartesian(si.orthoNormalCartesian[0], si.orthoNormalCartesian[1]).translate(si.cutDelta);
|
|
1803
2176
|
var slice = object.sectionCut(cutplane);
|
|
1804
2177
|
var first = axisApply(si.axis, function() {
|
|
1805
2178
|
return si.positive ? 0 : absoluteRadius;
|
|
@@ -1814,25 +2187,25 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1814
2187
|
si
|
|
1815
2188
|
}), si.axis).color(options.color);
|
|
1816
2189
|
var remainder = object.cutByPlane(plane);
|
|
1817
|
-
return union([ options.unionOriginal ? object : remainder, delta.translate(si.moveDelta) ]);
|
|
2190
|
+
return assertValidCSG$1(union([ options.unionOriginal ? object : remainder, delta.translate(si.moveDelta) ]), "reShape");
|
|
1818
2191
|
}
|
|
1819
2192
|
function chamfer(object, radius, orientation, options) {
|
|
1820
|
-
return reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
2193
|
+
return assertValidCSG$1(reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
1821
2194
|
return [ {
|
|
1822
2195
|
poly: slice,
|
|
1823
|
-
offset: new CSG.Vector3D(first)
|
|
2196
|
+
offset: new CSG$1.Vector3D(first)
|
|
1824
2197
|
}, {
|
|
1825
2198
|
poly: enlarge(slice, [ -radius * 2, -radius * 2 ]),
|
|
1826
|
-
offset: new CSG.Vector3D(last)
|
|
2199
|
+
offset: new CSG$1.Vector3D(last)
|
|
1827
2200
|
} ];
|
|
1828
|
-
});
|
|
2201
|
+
}), "chamfer");
|
|
1829
2202
|
}
|
|
1830
2203
|
function fillet(object, radius, orientation, options) {
|
|
1831
2204
|
options = options || {};
|
|
1832
|
-
return reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
1833
|
-
var v1 = new CSG.Vector3D(first);
|
|
1834
|
-
var v2 = new CSG.Vector3D(last);
|
|
1835
|
-
var res = options.resolution || CSG.defaultResolution3D;
|
|
2205
|
+
return assertValidCSG$1(reShape(object, radius, orientation, options, function(first, last, slice) {
|
|
2206
|
+
var v1 = new CSG$1.Vector3D(first);
|
|
2207
|
+
var v2 = new CSG$1.Vector3D(last);
|
|
2208
|
+
var res = options.resolution || CSG$1.defaultResolution3D;
|
|
1836
2209
|
var slices = range(0, res).map(function(i) {
|
|
1837
2210
|
var p = i > 0 ? i / (res - 1) : 0;
|
|
1838
2211
|
var v = v1.lerp(v2, p);
|
|
@@ -1843,7 +2216,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1843
2216
|
};
|
|
1844
2217
|
});
|
|
1845
2218
|
return slices;
|
|
1846
|
-
});
|
|
2219
|
+
}), "fillet");
|
|
1847
2220
|
}
|
|
1848
2221
|
function calcRotate(part, solid, axis) {
|
|
1849
2222
|
var axes = {
|
|
@@ -1860,7 +2233,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1860
2233
|
}
|
|
1861
2234
|
function rotateAround(part, solid, axis, angle) {
|
|
1862
2235
|
var _calcRotate = calcRotate(part, solid, axis), rotationCenter = _calcRotate.rotationCenter, rotationAxis = _calcRotate.rotationAxis;
|
|
1863
|
-
return part.rotate(rotationCenter, rotationAxis, angle);
|
|
2236
|
+
return assertValidCSG$1("rotateAround")(part.rotate(rotationCenter, rotationAxis, angle));
|
|
1864
2237
|
}
|
|
1865
2238
|
function cloneProperties(from, to) {
|
|
1866
2239
|
return Object.entries(from).reduce(function(props, _ref) {
|
|
@@ -1870,19 +2243,20 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1870
2243
|
}, to);
|
|
1871
2244
|
}
|
|
1872
2245
|
function clone(o) {
|
|
1873
|
-
var c = CSG.fromPolygons(o.toPolygons());
|
|
2246
|
+
var c = CSG$1.fromPolygons(o.toPolygons());
|
|
1874
2247
|
cloneProperties(o, c);
|
|
1875
|
-
debug$2("clone", o, c, CSG);
|
|
1876
|
-
return c;
|
|
2248
|
+
debug$2("clone", o, c, CSG$1);
|
|
2249
|
+
return assertValidCSG$1(c, "clone");
|
|
1877
2250
|
}
|
|
1878
2251
|
function addConnector(object, name) {
|
|
1879
2252
|
var point = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [ 0, 0, 0 ];
|
|
1880
2253
|
var axis = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [ 1, 0, 0 ];
|
|
1881
2254
|
var normal = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [ 0, 0, 1 ];
|
|
1882
|
-
object.properties[name] = new CSG.Connector(point, axis, normal);
|
|
1883
|
-
return object;
|
|
2255
|
+
object.properties[name] = new CSG$1.Connector(point, axis, normal);
|
|
2256
|
+
return assertValidCSG$1("addConnector")(object);
|
|
1884
2257
|
}
|
|
1885
2258
|
var debug$1 = Debug("jscadUtils:parts");
|
|
2259
|
+
var assertValidCSG = AssertValidCSG("parts");
|
|
1886
2260
|
var parts = {
|
|
1887
2261
|
BBox: BBox$1,
|
|
1888
2262
|
Cube,
|
|
@@ -1892,7 +2266,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1892
2266
|
};
|
|
1893
2267
|
function BBox$1() {
|
|
1894
2268
|
function box(object) {
|
|
1895
|
-
return CSG.cube({
|
|
2269
|
+
return CSG$1.cube({
|
|
1896
2270
|
center: object.centroid(),
|
|
1897
2271
|
radius: object.size().dividedBy(2)
|
|
1898
2272
|
});
|
|
@@ -1900,17 +2274,17 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1900
2274
|
for (var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1901
2275
|
objects[_key] = arguments[_key];
|
|
1902
2276
|
}
|
|
1903
|
-
return objects.reduce(function(bbox, part) {
|
|
2277
|
+
return assertValidCSG(objects.reduce(function(bbox, part) {
|
|
1904
2278
|
var object = bbox ? union([ bbox, box(part) ]) : part;
|
|
1905
2279
|
return box(object);
|
|
1906
|
-
}, undefined);
|
|
2280
|
+
}, undefined), "BBox");
|
|
1907
2281
|
}
|
|
1908
2282
|
function Cube(width) {
|
|
1909
2283
|
var r = div$1(fromxyz(width), 2);
|
|
1910
|
-
return CSG.cube({
|
|
2284
|
+
return assertValidCSG(CSG$1.cube({
|
|
1911
2285
|
center: r,
|
|
1912
2286
|
radius: r
|
|
1913
|
-
});
|
|
2287
|
+
}), "Cube");
|
|
1914
2288
|
}
|
|
1915
2289
|
function RoundedCube(x, y, thickness, corner_radius) {
|
|
1916
2290
|
if (x.getBounds) {
|
|
@@ -1926,11 +2300,11 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1926
2300
|
center: [ r[0], r[1], 0 ],
|
|
1927
2301
|
radius: r,
|
|
1928
2302
|
roundradius: corner_radius,
|
|
1929
|
-
resolution: CSG.defaultResolution2D
|
|
2303
|
+
resolution: CSG$1.defaultResolution2D
|
|
1930
2304
|
}).extrude({
|
|
1931
2305
|
offset: [ 0, 0, thickness || 1.62 ]
|
|
1932
2306
|
});
|
|
1933
|
-
return roundedcube;
|
|
2307
|
+
return assertValidCSG(roundedcube, "RoundedCube");
|
|
1934
2308
|
}
|
|
1935
2309
|
function Cylinder(diameter, height) {
|
|
1936
2310
|
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
@@ -1939,39 +2313,39 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1939
2313
|
start: [ 0, 0, 0 ],
|
|
1940
2314
|
end: [ 0, 0, height ],
|
|
1941
2315
|
radius: diameter / 2,
|
|
1942
|
-
resolution: CSG.defaultResolution2D
|
|
2316
|
+
resolution: CSG$1.defaultResolution2D
|
|
1943
2317
|
}, options);
|
|
1944
|
-
return CSG.cylinder(options);
|
|
2318
|
+
return assertValidCSG(CSG$1.cylinder(options), "Cylinder");
|
|
1945
2319
|
}
|
|
1946
2320
|
function Cone(diameter1, diameter2, height) {
|
|
1947
2321
|
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
1948
2322
|
debug$1("parts.Cone", diameter1, diameter2, height, options);
|
|
1949
|
-
return CSG.cylinder(Object.assign({
|
|
2323
|
+
return assertValidCSG(CSG$1.cylinder(Object.assign({
|
|
1950
2324
|
start: [ 0, 0, 0 ],
|
|
1951
2325
|
end: [ 0, 0, height ],
|
|
1952
2326
|
radiusStart: diameter1 / 2,
|
|
1953
2327
|
radiusEnd: diameter2 / 2,
|
|
1954
|
-
resolution: CSG.defaultResolution2D
|
|
1955
|
-
}, options));
|
|
2328
|
+
resolution: CSG$1.defaultResolution2D
|
|
2329
|
+
}, options)), "Cone");
|
|
1956
2330
|
}
|
|
1957
2331
|
function Hexagon(diameter, height) {
|
|
1958
2332
|
debug$1("hexagon", diameter, height);
|
|
1959
2333
|
var radius = diameter / 2;
|
|
1960
2334
|
var sqrt3 = Math.sqrt(3) / 2;
|
|
1961
2335
|
var hex = CAG.fromPoints([ [ radius, 0 ], [ radius / 2, radius * sqrt3 ], [ -radius / 2, radius * sqrt3 ], [ -radius, 0 ], [ -radius / 2, -radius * sqrt3 ], [ radius / 2, -radius * sqrt3 ] ]);
|
|
1962
|
-
return hex.extrude({
|
|
2336
|
+
return assertValidCSG(hex.extrude({
|
|
1963
2337
|
offset: [ 0, 0, height ]
|
|
1964
|
-
});
|
|
2338
|
+
}), "Hexagon");
|
|
1965
2339
|
}
|
|
1966
2340
|
function Triangle(base, height) {
|
|
1967
2341
|
var radius = base / 2;
|
|
1968
2342
|
var tri = CAG.fromPoints([ [ -radius, 0 ], [ radius, 0 ], [ 0, Math.sin(30) * radius ] ]);
|
|
1969
|
-
return tri.extrude({
|
|
2343
|
+
return assertValidCSG(tri.extrude({
|
|
1970
2344
|
offset: [ 0, 0, height ]
|
|
1971
|
-
});
|
|
2345
|
+
}), "Triangle");
|
|
1972
2346
|
}
|
|
1973
2347
|
function Tube(outsideDiameter, insideDiameter, height, outsideOptions, insideOptions) {
|
|
1974
|
-
return Cylinder(outsideDiameter, height, outsideOptions).subtract(Cylinder(insideDiameter, height, insideOptions || outsideOptions));
|
|
2348
|
+
return assertValidCSG(Cylinder(outsideDiameter, height, outsideOptions).subtract(Cylinder(insideDiameter, height, insideOptions || outsideOptions)), "Tube");
|
|
1975
2349
|
}
|
|
1976
2350
|
function Anchor() {
|
|
1977
2351
|
var width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
|
|
@@ -1989,11 +2363,11 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
1989
2363
|
center: [ r[0], r[1], 0 ],
|
|
1990
2364
|
radius: r,
|
|
1991
2365
|
roundradius: corner_radius,
|
|
1992
|
-
resolution: CSG.defaultResolution2D
|
|
2366
|
+
resolution: CSG$1.defaultResolution2D
|
|
1993
2367
|
}).extrude({
|
|
1994
2368
|
offset: [ 0, 0, thickness || 1.62 ]
|
|
1995
2369
|
});
|
|
1996
|
-
return board;
|
|
2370
|
+
return assertValidCSG(board, "Board");
|
|
1997
2371
|
}
|
|
1998
2372
|
var Hardware = {
|
|
1999
2373
|
Orientation: {
|
|
@@ -2084,6 +2458,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2084
2458
|
gap = gap || .25;
|
|
2085
2459
|
var inside = thickness - gap;
|
|
2086
2460
|
var outside = -thickness + gap;
|
|
2461
|
+
var boxHeight = box.size().z;
|
|
2462
|
+
if (Math.abs(height) >= boxHeight) {
|
|
2463
|
+
throw new Error("Rabett: height (".concat(height, ") must be less than the object height (").concat(boxHeight, ")"));
|
|
2464
|
+
}
|
|
2087
2465
|
debug("inside", inside, "outside", outside);
|
|
2088
2466
|
var group = Group();
|
|
2089
2467
|
var _box$bisect$parts = box.bisect("z", height, options).parts, top = _box$bisect$parts.positive, lower2_3rd = _box$bisect$parts.negative;
|
|
@@ -2154,10 +2532,10 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2154
2532
|
thickness = thickness || 2;
|
|
2155
2533
|
var s = div$1(xyz2array(size), 2);
|
|
2156
2534
|
var r = add(s, thickness);
|
|
2157
|
-
var box = CSG.cube({
|
|
2535
|
+
var box = CSG$1.cube({
|
|
2158
2536
|
center: r,
|
|
2159
2537
|
radius: r
|
|
2160
|
-
}).subtract(CSG.cube({
|
|
2538
|
+
}).subtract(CSG$1.cube({
|
|
2161
2539
|
center: r,
|
|
2162
2540
|
radius: s
|
|
2163
2541
|
}));
|
|
@@ -2175,7 +2553,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2175
2553
|
var BBox = function BBox(o) {
|
|
2176
2554
|
depreciated("BBox", true, "Use 'parts.BBox' instead");
|
|
2177
2555
|
var s = div$1(xyz2array(o.size()), 2);
|
|
2178
|
-
return CSG.cube({
|
|
2556
|
+
return CSG$1.cube({
|
|
2179
2557
|
center: s,
|
|
2180
2558
|
radius: s
|
|
2181
2559
|
}).align(o, "xyz");
|
|
@@ -2187,7 +2565,7 @@ function initJscadutils(_CSG, options = {}) {
|
|
|
2187
2565
|
var gap = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : .25;
|
|
2188
2566
|
var r = add(getRadius(box), -thickness / 2);
|
|
2189
2567
|
r[2] = thickness / 2;
|
|
2190
|
-
var cutter = CSG.cube({
|
|
2568
|
+
var cutter = CSG$1.cube({
|
|
2191
2569
|
center: r,
|
|
2192
2570
|
radius: r
|
|
2193
2571
|
}).align(box, "xy").color("green");
|