@jscad/modeling 2.7.1 → 2.9.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/CHANGELOG.md +46 -0
- package/dist/jscad-modeling.min.js +174 -144
- package/package.json +2 -2
- package/src/colors/hslToRgb.js +1 -1
- package/src/colors/hueToColorComponent.js +1 -0
- package/src/curves/bezier/tangentAt.js +2 -2
- package/src/curves/bezier/tangentAt.test.js +1 -1
- package/src/curves/bezier/valueAt.test.js +1 -1
- package/src/geometries/geom2/index.js +10 -0
- package/src/geometries/geom2/isA.js +2 -2
- package/src/geometries/geom2/toCompactBinary.js +4 -4
- package/src/geometries/geom2/toOutlines.js +6 -11
- package/src/geometries/geom2/toString.js +1 -1
- package/src/geometries/geom2/transform.test.js +1 -1
- package/src/geometries/geom3/fromCompactBinary.js +1 -1
- package/src/geometries/geom3/index.js +17 -0
- package/src/geometries/geom3/invert.js +2 -2
- package/src/geometries/geom3/isA.js +2 -2
- package/src/geometries/geom3/toCompactBinary.js +4 -4
- package/src/geometries/geom3/toPoints.js +1 -0
- package/src/geometries/geom3/toString.js +1 -1
- package/src/geometries/geom3/transform.test.js +1 -1
- package/src/geometries/index.js +8 -1
- package/src/geometries/path2/eachPoint.js +3 -3
- package/src/geometries/path2/index.js +11 -0
- package/src/geometries/path2/isA.js +2 -2
- package/src/geometries/path2/reverse.js +4 -4
- package/src/geometries/path2/toCompactBinary.js +6 -6
- package/src/geometries/path2/toString.js +1 -1
- package/src/geometries/path2/transform.test.js +1 -1
- package/src/geometries/poly2/arePointsInside.test.js +1 -1
- package/src/geometries/poly2/index.js +6 -0
- package/src/geometries/poly3/index.js +7 -1
- package/src/geometries/poly3/invert.js +7 -1
- package/src/geometries/poly3/isA.js +2 -2
- package/src/geometries/poly3/isConvex.js +2 -2
- package/src/geometries/poly3/measureArea.js +4 -4
- package/src/geometries/poly3/measureBoundingBox.js +2 -2
- package/src/geometries/poly3/measureBoundingSphere.js +2 -2
- package/src/geometries/poly3/measureSignedVolume.js +4 -4
- package/src/geometries/poly3/toPoints.js +2 -2
- package/src/geometries/poly3/toString.js +2 -2
- package/src/geometries/poly3/transform.js +2 -2
- package/src/maths/index.js +1 -1
- package/src/maths/line2/equals.js +2 -2
- package/src/maths/line2/fromValues.js +2 -2
- package/src/maths/line2/intersectPointOfLines.js +1 -1
- package/src/maths/line2/intersectPointOfLines.test.js +1 -1
- package/src/maths/line2/reverse.test.js +1 -1
- package/src/maths/line2/transform.test.js +1 -1
- package/src/maths/line3/equals.js +2 -2
- package/src/maths/line3/reverse.test.js +1 -1
- package/src/maths/line3/transform.test.js +1 -1
- package/src/maths/mat4/fromRotation.js +1 -1
- package/src/maths/mat4/fromVectorRotation.js +1 -1
- package/src/maths/mat4/fromVectorRotation.test.js +1 -1
- package/src/maths/mat4/identity.test.js +1 -1
- package/src/maths/mat4/invert.js +18 -18
- package/src/maths/mat4/isIdentity.js +1 -1
- package/src/maths/mat4/isIdentity.test.js +0 -2
- package/src/maths/mat4/isMirroring.js +4 -4
- package/src/maths/mat4/isMirroring.test.js +1 -1
- package/src/maths/mat4/leftMultiplyVec3.js +2 -2
- package/src/maths/mat4/rotate.js +1 -1
- package/src/maths/mat4/toString.js +2 -2
- package/src/maths/mat4/translate.test.js +1 -1
- package/src/maths/plane/flip.test.js +1 -1
- package/src/maths/plane/fromPoints.d.ts +1 -1
- package/src/maths/plane/fromPoints.js +1 -3
- package/src/maths/plane/signedDistanceToPoint.js +1 -1
- package/src/maths/plane/transform.test.js +1 -1
- package/src/maths/utils/aboutEqualNormals.js +2 -2
- package/src/maths/vec2/abs.d.ts +1 -1
- package/src/maths/vec2/add.test.js +1 -1
- package/src/maths/vec2/angleDegrees.d.ts +1 -1
- package/src/maths/vec2/angleRadians.d.ts +1 -1
- package/src/maths/vec2/create.js +1 -1
- package/src/maths/vec2/cross.test.js +1 -1
- package/src/maths/vec2/divide.test.js +1 -1
- package/src/maths/vec2/fromAngleDegrees.js +1 -1
- package/src/maths/vec2/fromScalar.js +1 -1
- package/src/maths/vec2/length.d.ts +1 -1
- package/src/maths/vec2/length.js +1 -1
- package/src/maths/vec2/length.test.js +10 -0
- package/src/maths/vec2/lerp.test.js +1 -1
- package/src/maths/vec2/multiply.test.js +1 -1
- package/src/maths/vec2/negate.test.js +1 -1
- package/src/maths/vec2/normal.js +1 -1
- package/src/maths/vec2/normalize.d.ts +1 -1
- package/src/maths/vec2/normalize.test.js +1 -1
- package/src/maths/vec2/rotate.test.js +1 -1
- package/src/maths/vec2/squaredLength.d.ts +1 -1
- package/src/maths/vec2/squaredLength.js +3 -3
- package/src/maths/vec2/subtract.test.js +1 -1
- package/src/maths/vec2/toString.js +1 -1
- package/src/maths/vec2/transform.test.js +1 -1
- package/src/maths/vec3/abs.d.ts +1 -1
- package/src/maths/vec3/add.test.js +1 -1
- package/src/maths/vec3/angle.js +2 -2
- package/src/maths/vec3/angle.test.js +17 -0
- package/src/maths/vec3/cross.test.js +1 -1
- package/src/maths/vec3/divide.test.js +1 -1
- package/src/maths/vec3/fromScalar.js +1 -1
- package/src/maths/vec3/fromVec2.d.ts +1 -1
- package/src/maths/vec3/fromVec2.js +3 -3
- package/src/maths/vec3/length.d.ts +1 -1
- package/src/maths/vec3/length.js +4 -4
- package/src/maths/vec3/length.test.js +10 -0
- package/src/maths/vec3/lerp.test.js +1 -1
- package/src/maths/vec3/multiply.test.js +1 -1
- package/src/maths/vec3/negate.d.ts +1 -1
- package/src/maths/vec3/negate.test.js +1 -1
- package/src/maths/vec3/normalize.d.ts +1 -1
- package/src/maths/vec3/normalize.test.js +1 -1
- package/src/maths/vec3/rotateX.test.js +1 -1
- package/src/maths/vec3/rotateY.test.js +1 -1
- package/src/maths/vec3/rotateZ.test.js +1 -1
- package/src/maths/vec3/scale.test.js +1 -1
- package/src/maths/vec3/squaredLength.d.ts +1 -1
- package/src/maths/vec3/squaredLength.js +4 -4
- package/src/maths/vec3/subtract.test.js +1 -1
- package/src/maths/vec3/toString.js +1 -1
- package/src/maths/vec3/transform.test.js +1 -1
- package/src/maths/vec4/toString.js +1 -1
- package/src/maths/vec4/transform.test.js +1 -1
- package/src/measurements/measureBoundingSphere.js +4 -4
- package/src/measurements/measureCenterOfMass.js +1 -1
- package/src/operations/booleans/mayOverlap.js +3 -3
- package/src/operations/booleans/retessellate.js +3 -5
- package/src/operations/booleans/scission.js +1 -1
- package/src/operations/booleans/subtract.js +1 -1
- package/src/operations/booleans/union.test.js +1 -1
- package/src/operations/booleans/unionGeom3Sub.js +1 -1
- package/src/operations/expansions/expand.js +2 -2
- package/src/operations/expansions/expand.test.js +3 -35
- package/src/operations/expansions/expandShell.js +24 -18
- package/src/operations/expansions/offset.js +1 -1
- package/src/operations/expansions/offset.test.js +25 -89
- package/src/operations/expansions/offsetFromPoints.js +11 -6
- package/src/operations/extrusions/earcut/assignHoles.js +87 -0
- package/src/operations/extrusions/earcut/assignHoles.test.js +28 -0
- package/src/operations/extrusions/earcut/eliminateHoles.js +131 -0
- package/src/operations/extrusions/earcut/index.js +252 -0
- package/src/operations/extrusions/earcut/linkedList.js +58 -0
- package/src/operations/extrusions/earcut/linkedListSort.js +54 -0
- package/src/operations/extrusions/earcut/linkedPolygon.js +197 -0
- package/src/operations/extrusions/earcut/polygonHierarchy.js +64 -0
- package/src/operations/extrusions/earcut/triangle.js +16 -0
- package/src/operations/extrusions/extrudeFromSlices.js +10 -3
- package/src/operations/extrusions/extrudeFromSlices.test.js +33 -23
- package/src/operations/extrusions/extrudeLinear.js +11 -6
- package/src/operations/extrusions/extrudeLinear.test.js +77 -27
- package/src/operations/extrusions/extrudeLinearGeom2.js +5 -2
- package/src/operations/extrusions/extrudeLinearPath2.js +24 -0
- package/src/operations/extrusions/extrudeRectangular.js +1 -1
- package/src/operations/extrusions/extrudeRectangular.test.js +7 -7
- package/src/operations/extrusions/extrudeRotate.test.js +19 -27
- package/src/operations/extrusions/project.js +1 -1
- package/src/operations/extrusions/slice/calculatePlane.js +7 -4
- package/src/operations/extrusions/slice/isA.js +2 -2
- package/src/operations/extrusions/slice/repairSlice.js +47 -0
- package/src/operations/extrusions/slice/toPolygons.js +24 -60
- package/src/operations/hulls/hull.test.js +1 -1
- package/src/operations/hulls/hullChain.js +1 -1
- package/src/operations/hulls/hullGeom2.js +1 -1
- package/src/operations/hulls/hullPath2.js +6 -4
- package/src/operations/hulls/hullPath2.test.js +16 -0
- package/src/operations/hulls/hullPoints2.test.js +1 -1
- package/src/operations/hulls/quickhull/QuickHull.js +2 -2
- package/src/operations/modifiers/edges.js +2 -4
- package/src/operations/modifiers/generalize.js +4 -7
- package/src/operations/modifiers/snap.test.js +3 -3
- package/src/operations/transforms/align.d.ts +1 -1
- package/src/operations/transforms/center.js +17 -17
- package/src/operations/transforms/mirror.js +11 -11
- package/src/operations/transforms/rotate.js +12 -12
- package/src/operations/transforms/scale.js +19 -19
- package/src/operations/transforms/transform.js +3 -3
- package/src/operations/transforms/translate.js +14 -14
- package/src/primitives/arc.js +1 -1
- package/src/primitives/cylinderElliptic.test.js +0 -2
- package/src/primitives/ellipsoid.js +1 -1
- package/src/primitives/ellipsoid.test.js +0 -2
- package/src/primitives/geodesicSphere.d.ts +0 -1
- package/src/primitives/geodesicSphere.js +2 -2
- package/src/primitives/polyhedron.js +1 -1
- package/src/primitives/roundedCylinder.js +1 -1
- package/src/primitives/torus.d.ts +0 -1
- package/src/primitives/torus.test.js +1 -1
- package/src/primitives/triangle.js +1 -1
- package/src/text/vectorText.js +2 -2
- package/src/utils/padArrayToLength.js +1 -1
- package/test/helpers/comparePolygons.js +1 -3
- package/test/helpers/nearlyEqual.js +2 -6
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* @returns {vec3} out
|
|
8
8
|
* @alias module:modeling/maths/vec3.fromVec2
|
|
9
9
|
*/
|
|
10
|
-
const fromVector2 = (out,
|
|
11
|
-
out[0] =
|
|
12
|
-
out[1] =
|
|
10
|
+
const fromVector2 = (out, vector, z = 0) => {
|
|
11
|
+
out[0] = vector[0]
|
|
12
|
+
out[1] = vector[1]
|
|
13
13
|
out[2] = z
|
|
14
14
|
return out
|
|
15
15
|
}
|
package/src/maths/vec3/length.js
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* @returns {Number} length
|
|
6
6
|
* @alias module:modeling/maths/vec3.length
|
|
7
7
|
*/
|
|
8
|
-
const length = (
|
|
9
|
-
const x =
|
|
10
|
-
const y =
|
|
11
|
-
const z =
|
|
8
|
+
const length = (vector) => {
|
|
9
|
+
const x = vector[0]
|
|
10
|
+
const y = vector[1]
|
|
11
|
+
const z = vector[2]
|
|
12
12
|
return Math.hypot(x, y, z)
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -41,5 +41,15 @@ test('vec3: length() should return correct values', (t) => {
|
|
|
41
41
|
const length9 = length(vec9)
|
|
42
42
|
nearlyEqual(t, length9, 3.74165, EPS)
|
|
43
43
|
|
|
44
|
+
// huge vector
|
|
45
|
+
const vec10 = fromValues(1e200, 0, 1e200)
|
|
46
|
+
const length10 = length(vec10)
|
|
47
|
+
nearlyEqual(t, length10, Math.SQRT2 * 1e200, EPS)
|
|
48
|
+
|
|
49
|
+
// tiny vector
|
|
50
|
+
const vec11 = fromValues(1e-200, 0, 1e-200)
|
|
51
|
+
const length11 = length(vec11)
|
|
52
|
+
nearlyEqual(t, length11, Math.SQRT2 * 1e-200, EPS)
|
|
53
|
+
|
|
44
54
|
t.true(true)
|
|
45
55
|
})
|
|
@@ -3,7 +3,7 @@ const { lerp, fromValues } = require('./index')
|
|
|
3
3
|
|
|
4
4
|
const { compareVectors } = require('../../../test/helpers/index')
|
|
5
5
|
|
|
6
|
-
test('vec3: lerp() called with three
|
|
6
|
+
test('vec3: lerp() called with three parameters should update a vec3 with correct values', (t) => {
|
|
7
7
|
const obs1 = fromValues(0, 0, 0)
|
|
8
8
|
const ret1 = lerp(obs1, [0, 0, 0], [0, 0, 0], 0)
|
|
9
9
|
t.true(compareVectors(obs1, [0, 0, 0]))
|
|
@@ -3,7 +3,7 @@ const { multiply, fromValues } = require('./index')
|
|
|
3
3
|
|
|
4
4
|
const { compareVectors } = require('../../../test/helpers/index')
|
|
5
5
|
|
|
6
|
-
test('vec3: multiply() called with three
|
|
6
|
+
test('vec3: multiply() called with three parameters should update a vec3 with correct values', (t) => {
|
|
7
7
|
const obs1 = fromValues(0, 0, 0)
|
|
8
8
|
const ret1 = multiply(obs1, [0, 0, 0], [0, 0, 0])
|
|
9
9
|
t.true(compareVectors(obs1, [0, 0, 0]))
|
|
@@ -3,7 +3,7 @@ const { negate, fromValues } = require('./index')
|
|
|
3
3
|
|
|
4
4
|
const { compareVectors } = require('../../../test/helpers/index')
|
|
5
5
|
|
|
6
|
-
test('vec3: negate() called with two
|
|
6
|
+
test('vec3: negate() called with two parameters should update a vec3 with correct values', (t) => {
|
|
7
7
|
const obs1 = fromValues(0, 0, 0)
|
|
8
8
|
const ret1 = negate(obs1, [0, 0, 0])
|
|
9
9
|
t.true(compareVectors(obs1, [-0, -0, -0]))
|
|
@@ -3,7 +3,7 @@ const { normalize, fromValues } = require('./index')
|
|
|
3
3
|
|
|
4
4
|
const { compareVectors } = require('../../../test/helpers/index')
|
|
5
5
|
|
|
6
|
-
test('vec3: normalize() called with two
|
|
6
|
+
test('vec3: normalize() called with two parameters should update a vec3 with correct values', (t) => {
|
|
7
7
|
const obs1 = fromValues(0, 0, 0)
|
|
8
8
|
const ret1 = normalize(obs1, [0, 0, 0])
|
|
9
9
|
t.true(compareVectors(obs1, [0, 0, 0]))
|
|
@@ -3,7 +3,7 @@ const { rotateX, fromValues } = require('./index')
|
|
|
3
3
|
|
|
4
4
|
const { compareVectors } = require('../../../test/helpers/index')
|
|
5
5
|
|
|
6
|
-
test('vec3: rotateX() called with four
|
|
6
|
+
test('vec3: rotateX() called with four parameters should update a vec3 with correct values', (t) => {
|
|
7
7
|
const radians = 90 * Math.PI / 180
|
|
8
8
|
|
|
9
9
|
const obs1 = fromValues(0, 0, 0)
|
|
@@ -3,7 +3,7 @@ const { rotateY, fromValues } = require('./index')
|
|
|
3
3
|
|
|
4
4
|
const { compareVectors } = require('../../../test/helpers/index')
|
|
5
5
|
|
|
6
|
-
test('vec3: rotateY() called with three
|
|
6
|
+
test('vec3: rotateY() called with three parameters should update a vec3 with correct values', (t) => {
|
|
7
7
|
const radians = 90 * Math.PI / 180
|
|
8
8
|
|
|
9
9
|
const obs1 = fromValues(0, 0, 0)
|
|
@@ -3,7 +3,7 @@ const { rotateZ, fromValues } = require('./index')
|
|
|
3
3
|
|
|
4
4
|
const { compareVectors } = require('../../../test/helpers/index')
|
|
5
5
|
|
|
6
|
-
test('vec3: rotateZ() called with four
|
|
6
|
+
test('vec3: rotateZ() called with four parameters should update a vec3 with correct values', (t) => {
|
|
7
7
|
const radians = 90 * Math.PI / 180
|
|
8
8
|
|
|
9
9
|
const obs1 = fromValues(0, 0, 0)
|
|
@@ -3,7 +3,7 @@ const { scale, fromValues } = require('./index')
|
|
|
3
3
|
|
|
4
4
|
const { compareVectors } = require('../../../test/helpers/index')
|
|
5
5
|
|
|
6
|
-
test('vec3: scale() called with three
|
|
6
|
+
test('vec3: scale() called with three parameters should update a vec3 with correct values', (t) => {
|
|
7
7
|
const obs1 = fromValues(0, 0, 0)
|
|
8
8
|
const ret1 = scale(obs1, [0, 0, 0], 0)
|
|
9
9
|
t.true(compareVectors(obs1, [0, 0, 0]))
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* @returns {Number} squared length
|
|
6
6
|
* @alias module:modeling/maths/vec3.squaredLength
|
|
7
7
|
*/
|
|
8
|
-
const squaredLength = (
|
|
9
|
-
const x =
|
|
10
|
-
const y =
|
|
11
|
-
const z =
|
|
8
|
+
const squaredLength = (vector) => {
|
|
9
|
+
const x = vector[0]
|
|
10
|
+
const y = vector[1]
|
|
11
|
+
const z = vector[2]
|
|
12
12
|
return x * x + y * y + z * z
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -3,7 +3,7 @@ const { subtract, fromValues } = require('./index')
|
|
|
3
3
|
|
|
4
4
|
const { compareVectors } = require('../../../test/helpers/index')
|
|
5
5
|
|
|
6
|
-
test('vec3: subtract() called with three
|
|
6
|
+
test('vec3: subtract() called with three parameters should update a vec3 with correct values', (t) => {
|
|
7
7
|
const obs1 = fromValues(0, 0, 0)
|
|
8
8
|
const ret1 = subtract(obs1, [0, 0, 0], [0, 0, 0])
|
|
9
9
|
t.true(compareVectors(obs1, [0, 0, 0]))
|
|
@@ -3,7 +3,7 @@ const { transform, fromValues } = require('./index')
|
|
|
3
3
|
|
|
4
4
|
const { compareVectors } = require('../../../test/helpers/index')
|
|
5
5
|
|
|
6
|
-
test('vec3: transform() called with three
|
|
6
|
+
test('vec3: transform() called with three parameters should update a vec3 with correct values', (t) => {
|
|
7
7
|
const identityMatrix = [
|
|
8
8
|
1, 0, 0, 0,
|
|
9
9
|
0, 1, 0, 0,
|
|
@@ -3,7 +3,7 @@ const { transform, fromValues } = require('./index')
|
|
|
3
3
|
|
|
4
4
|
const { compareVectors } = require('../../../test/helpers/index')
|
|
5
5
|
|
|
6
|
-
test('vec4: transform() called with three
|
|
6
|
+
test('vec4: transform() called with three parameters should update a vec4 with correct values', (t) => {
|
|
7
7
|
const identityMatrix = [
|
|
8
8
|
1, 0, 0, 0,
|
|
9
9
|
0, 1, 0, 0,
|
|
@@ -24,7 +24,7 @@ const measureBoundingSphereOfPath2 = (geometry) => {
|
|
|
24
24
|
const points = path2.toPoints(geometry)
|
|
25
25
|
|
|
26
26
|
if (points.length > 0) {
|
|
27
|
-
// calculate the
|
|
27
|
+
// calculate the centroid of the geometry
|
|
28
28
|
let numPoints = 0
|
|
29
29
|
const temp = vec3.create()
|
|
30
30
|
points.forEach((point) => {
|
|
@@ -60,7 +60,7 @@ const measureBoundingSphereOfGeom2 = (geometry) => {
|
|
|
60
60
|
const sides = geom2.toSides(geometry)
|
|
61
61
|
|
|
62
62
|
if (sides.length > 0) {
|
|
63
|
-
// calculate the
|
|
63
|
+
// calculate the centroid of the geometry
|
|
64
64
|
let numPoints = 0
|
|
65
65
|
const temp = vec3.create()
|
|
66
66
|
sides.forEach((side) => {
|
|
@@ -96,7 +96,7 @@ const measureBoundingSphereOfGeom3 = (geometry) => {
|
|
|
96
96
|
const polygons = geom3.toPolygons(geometry)
|
|
97
97
|
|
|
98
98
|
if (polygons.length > 0) {
|
|
99
|
-
// calculate the
|
|
99
|
+
// calculate the centroid of the geometry
|
|
100
100
|
let numPoints = 0
|
|
101
101
|
polygons.forEach((polygon) => {
|
|
102
102
|
poly3.toPoints(polygon).forEach((point) => {
|
|
@@ -122,7 +122,7 @@ const measureBoundingSphereOfGeom3 = (geometry) => {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
/**
|
|
125
|
-
* Measure the (
|
|
125
|
+
* Measure the (approximate) bounding sphere of the given geometries.
|
|
126
126
|
* @see https://en.wikipedia.org/wiki/Bounding_sphere
|
|
127
127
|
* @param {...Object} geometries - the geometries to measure
|
|
128
128
|
* @return {Array} the bounding sphere for each geometry, i.e. [centroid, radius]
|
|
@@ -61,7 +61,7 @@ const measureCenterOfMassGeom3 = (geometry) => {
|
|
|
61
61
|
let totalVolume = 0
|
|
62
62
|
const vector = vec3.create() // for speed
|
|
63
63
|
polygons.forEach((polygon) => {
|
|
64
|
-
// calculate volume and center of each
|
|
64
|
+
// calculate volume and center of each tetrahedron
|
|
65
65
|
const vertices = polygon.vertices
|
|
66
66
|
for (let i = 0; i < vertices.length - 2; i++) {
|
|
67
67
|
vec3.cross(vector, vertices[i + 1], vertices[i + 2])
|
|
@@ -4,9 +4,9 @@ const measureBoundingBox = require('../../measurements/measureBoundingBox')
|
|
|
4
4
|
|
|
5
5
|
/*
|
|
6
6
|
* Determine if the given geometries overlap by comparing min and max bounds.
|
|
7
|
-
* NOTE: This is used in union for
|
|
8
|
-
* @param {geom3} geometry1 - geometry for
|
|
9
|
-
* @param {geom3} geometry2 - geometry for
|
|
7
|
+
* NOTE: This is used in union for performance gains.
|
|
8
|
+
* @param {geom3} geometry1 - geometry for comparison
|
|
9
|
+
* @param {geom3} geometry2 - geometry for comparison
|
|
10
10
|
* @returns {boolean} true if the geometries overlap
|
|
11
11
|
*/
|
|
12
12
|
const mayOverlap = (geometry1, geometry2) => {
|
|
@@ -3,16 +3,14 @@ const poly3 = require('../../geometries/poly3')
|
|
|
3
3
|
|
|
4
4
|
const reTesselateCoplanarPolygons = require('./reTesselateCoplanarPolygons')
|
|
5
5
|
|
|
6
|
-
// Normals are directional vectors with component values from 0 to 1.0, requiring specialized
|
|
7
|
-
// This EPS is derived from a
|
|
6
|
+
// Normals are directional vectors with component values from 0 to 1.0, requiring specialized comparison
|
|
7
|
+
// This EPS is derived from a series of tests to determine the optimal precision for comparing coplanar polygons,
|
|
8
8
|
// as provided by the sphere primitive at high segmentation
|
|
9
9
|
// This EPS is for 64 bit Number values
|
|
10
10
|
const NEPS = 1e-13
|
|
11
11
|
|
|
12
12
|
// Compare two normals (unit vectors) for equality.
|
|
13
|
-
const aboutEqualNormals = (a, b) =>
|
|
14
|
-
return (Math.abs(a[0] - b[0]) <= NEPS && Math.abs(a[1] - b[1]) <= NEPS && Math.abs(a[2] - b[2]) <= NEPS)
|
|
15
|
-
}
|
|
13
|
+
const aboutEqualNormals = (a, b) => (Math.abs(a[0] - b[0]) <= NEPS && Math.abs(a[1] - b[1]) <= NEPS && Math.abs(a[2] - b[2]) <= NEPS)
|
|
16
14
|
|
|
17
15
|
const coplanar = (plane1, plane2) => {
|
|
18
16
|
// expect the same distance from the origin, within tolerance
|
|
@@ -9,7 +9,7 @@ const scissionGeom3 = require('./scissionGeom3')
|
|
|
9
9
|
/**
|
|
10
10
|
* Scission (divide) the given geometry into the component pieces.
|
|
11
11
|
*
|
|
12
|
-
* @param {...Object}
|
|
12
|
+
* @param {...Object} objects - list of geometries
|
|
13
13
|
* @returns {Array} list of pieces from each geometry
|
|
14
14
|
* @alias module:modeling/booleans.scission
|
|
15
15
|
*
|
|
@@ -17,7 +17,7 @@ const subtractGeom3 = require('./subtractGeom3')
|
|
|
17
17
|
* @alias module:modeling/booleans.subtract
|
|
18
18
|
*
|
|
19
19
|
* @example
|
|
20
|
-
* let myshape = subtract(
|
|
20
|
+
* let myshape = subtract(cuboid({size: [5,5,5]}), cuboid({size: [5,5,5], center: [5,5,5]}))
|
|
21
21
|
*
|
|
22
22
|
* @example
|
|
23
23
|
* +-------+ +-------+
|
|
@@ -198,7 +198,7 @@ test('union of one or more geom3 objects produces expected geometry', (t) => {
|
|
|
198
198
|
|
|
199
199
|
test('union of geom3 with rounding issues #137', (t) => {
|
|
200
200
|
const geometry1 = center({ relativeTo: [0, 0, -1] }, cuboid({ size: [44, 26, 5] }))
|
|
201
|
-
const geometry2 = center({ relativeTo: [0, 0, -4.400001] }, cuboid({ size: [44, 26, 1.8] })) // introduce
|
|
201
|
+
const geometry2 = center({ relativeTo: [0, 0, -4.400001] }, cuboid({ size: [44, 26, 1.8] })) // introduce precision error
|
|
202
202
|
|
|
203
203
|
const obs = union(geometry1, geometry2)
|
|
204
204
|
const pts = geom3.toPoints(obs)
|
|
@@ -7,7 +7,7 @@ const { Tree } = require('./trees')
|
|
|
7
7
|
* Return a new 3D geometry representing the space in the given geometries.
|
|
8
8
|
* @param {geom3} geometry1 - geometry to union
|
|
9
9
|
* @param {geom3} geometry2 - geometry to union
|
|
10
|
-
* @returns {
|
|
10
|
+
* @returns {geom3} new 3D geometry
|
|
11
11
|
*/
|
|
12
12
|
const unionSub = (geometry1, geometry2) => {
|
|
13
13
|
if (!mayOverlap(geometry1, geometry2)) {
|
|
@@ -10,14 +10,14 @@ const expandPath2 = require('./expandPath2')
|
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Expand the given geometry using the given options.
|
|
13
|
-
* Both
|
|
13
|
+
* Both internal and external space is expanded for 2D and 3D shapes.
|
|
14
14
|
*
|
|
15
15
|
* Note: Contract is expand using a negative delta.
|
|
16
16
|
* @param {Object} options - options for expand
|
|
17
17
|
* @param {Number} [options.delta=1] - delta (+/-) of expansion
|
|
18
18
|
* @param {String} [options.corners='edge'] - type of corner to create after expanding; edge, chamfer, round
|
|
19
19
|
* @param {Integer} [options.segments=16] - number of segments when creating round corners
|
|
20
|
-
* @param {...Objects}
|
|
20
|
+
* @param {...Objects} objects - the geometries to expand
|
|
21
21
|
* @return {Object|Array} new geometry, or list of new geometries
|
|
22
22
|
* @alias module:modeling/expansions.expand
|
|
23
23
|
*
|
|
@@ -120,7 +120,7 @@ test('expand: expanding of a geom3 produces expected changes to polygons', (t) =
|
|
|
120
120
|
const geometry2 = sphere({ radius: 5, segments: 8 })
|
|
121
121
|
const obs2 = expand({ delta: 5 }, geometry2)
|
|
122
122
|
const pts2 = geom3.toPoints(obs2)
|
|
123
|
-
t.is(pts2.length,
|
|
123
|
+
t.is(pts2.length, 1588)
|
|
124
124
|
})
|
|
125
125
|
|
|
126
126
|
test('expand (options): offsetting of a complex geom2 produces expected offset geom2', (t) => {
|
|
@@ -151,59 +151,27 @@ test('expand (options): offsetting of a complex geom2 produces expected offset g
|
|
|
151
151
|
const obs = expand({ delta: 2, corners: 'edge' }, geometry)
|
|
152
152
|
const pts = geom2.toPoints(obs)
|
|
153
153
|
const exp = [
|
|
154
|
-
[-77, -77],
|
|
155
|
-
[-75, -77],
|
|
156
|
-
[75, -77],
|
|
157
154
|
[77, -77],
|
|
158
|
-
[77, -75],
|
|
159
|
-
[77, 75],
|
|
160
155
|
[77, 77],
|
|
161
|
-
[75, 77],
|
|
162
|
-
[40, 77],
|
|
163
156
|
[38, 77],
|
|
164
|
-
[38, 75],
|
|
165
157
|
[38, 2],
|
|
166
158
|
[-38, 2],
|
|
167
|
-
[-38, 75],
|
|
168
159
|
[-37.99999999999999, 77],
|
|
169
|
-
[-40, 77],
|
|
170
|
-
[-75, 77],
|
|
171
160
|
[-77, 77],
|
|
172
|
-
[-77, 75],
|
|
173
|
-
[17, -40],
|
|
174
161
|
[16.999999999999996, -42],
|
|
175
|
-
[15, -42],
|
|
176
|
-
[8, -42],
|
|
177
162
|
[6, -42],
|
|
178
|
-
[6, -40],
|
|
179
163
|
[6, -27],
|
|
180
164
|
[-6, -27],
|
|
181
|
-
[-6, -40],
|
|
182
165
|
[-6.000000000000001, -42],
|
|
183
|
-
[-8, -42],
|
|
184
|
-
[-15, -42],
|
|
185
166
|
[-17, -42],
|
|
186
|
-
[-17, -40],
|
|
187
|
-
[-17, -10],
|
|
188
167
|
[-16.999999999999996, -8],
|
|
189
|
-
[-15, -8],
|
|
190
|
-
[15, -8],
|
|
191
168
|
[17, -8.000000000000004],
|
|
192
|
-
[17, -10],
|
|
193
|
-
[-4, -19],
|
|
194
169
|
[-4, -21],
|
|
195
|
-
[-2, -21],
|
|
196
|
-
[1.9999999999999998, -21],
|
|
197
170
|
[3.9999999999999996, -21],
|
|
198
|
-
[4, -19],
|
|
199
|
-
[4, -15],
|
|
200
171
|
[4, -13],
|
|
201
|
-
[2, -13],
|
|
202
|
-
[-1.9999999999999998, -13],
|
|
203
172
|
[-4, -13],
|
|
204
|
-
[-
|
|
205
|
-
[-77, -75]
|
|
173
|
+
[-77, -77]
|
|
206
174
|
]
|
|
207
|
-
t.is(pts.length,
|
|
175
|
+
t.is(pts.length, 20)
|
|
208
176
|
t.true(comparePoints(pts, exp))
|
|
209
177
|
})
|
|
@@ -15,37 +15,43 @@ const unionGeom3Sub = require('../booleans/unionGeom3Sub')
|
|
|
15
15
|
|
|
16
16
|
const extrudePolygon = require('./extrudePolygon')
|
|
17
17
|
|
|
18
|
+
/*
|
|
19
|
+
* Collect all planes adjacent to each vertex
|
|
20
|
+
*/
|
|
18
21
|
const mapPlaneToVertex = (map, vertex, plane) => {
|
|
19
|
-
const
|
|
20
|
-
if (
|
|
22
|
+
const key = vertex.toString()
|
|
23
|
+
if (!map.has(key)) {
|
|
21
24
|
const entry = [vertex, [plane]]
|
|
22
|
-
map.
|
|
23
|
-
|
|
25
|
+
map.set(key, entry)
|
|
26
|
+
} else {
|
|
27
|
+
const planes = map.get(key)[1]
|
|
28
|
+
planes.push(plane)
|
|
24
29
|
}
|
|
25
|
-
const planes = map[i][1]
|
|
26
|
-
planes.push(plane)
|
|
27
|
-
return i
|
|
28
30
|
}
|
|
29
31
|
|
|
32
|
+
/*
|
|
33
|
+
* Collect all planes adjacent to each edge.
|
|
34
|
+
* Combine undirected edges, no need for duplicate cylinders.
|
|
35
|
+
*/
|
|
30
36
|
const mapPlaneToEdge = (map, edge, plane) => {
|
|
31
|
-
const
|
|
32
|
-
|
|
37
|
+
const key0 = edge[0].toString()
|
|
38
|
+
const key1 = edge[1].toString()
|
|
39
|
+
// Sort keys to make edges undirected
|
|
40
|
+
const key = key0 < key1 ? `${key0},${key1}` : `${key1},${key0}`
|
|
41
|
+
if (!map.has(key)) {
|
|
33
42
|
const entry = [edge, [plane]]
|
|
34
|
-
map.
|
|
35
|
-
|
|
43
|
+
map.set(key, entry)
|
|
44
|
+
} else {
|
|
45
|
+
const planes = map.get(key)[1]
|
|
46
|
+
planes.push(plane)
|
|
36
47
|
}
|
|
37
|
-
const planes = map[i][1]
|
|
38
|
-
planes.push(plane)
|
|
39
|
-
return i
|
|
40
48
|
}
|
|
41
49
|
|
|
42
50
|
const addUniqueAngle = (map, angle) => {
|
|
43
51
|
const i = map.findIndex((item) => item === angle)
|
|
44
52
|
if (i < 0) {
|
|
45
53
|
map.push(angle)
|
|
46
|
-
return map.length
|
|
47
54
|
}
|
|
48
|
-
return i
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
/*
|
|
@@ -65,8 +71,8 @@ const expandShell = (options, geometry) => {
|
|
|
65
71
|
const { delta, segments } = Object.assign({ }, defaults, options)
|
|
66
72
|
|
|
67
73
|
let result = geom3.create()
|
|
68
|
-
const vertices2planes =
|
|
69
|
-
const edges2planes =
|
|
74
|
+
const vertices2planes = new Map() // {vertex: [vertex, [plane, ...]]}
|
|
75
|
+
const edges2planes = new Map() // {edge: [[vertex, vertex], [plane, ...]]}
|
|
70
76
|
|
|
71
77
|
const v1 = vec3.create()
|
|
72
78
|
const v2 = vec3.create()
|
|
@@ -13,7 +13,7 @@ const offsetPath2 = require('./offsetPath2')
|
|
|
13
13
|
* @param {Float} [options.delta=1] - delta of offset (+ to exterior, - from interior)
|
|
14
14
|
* @param {String} [options.corners='edge'] - type of corner to create after offseting; edge, chamfer, round
|
|
15
15
|
* @param {Integer} [options.segments=16] - number of segments when creating round corners
|
|
16
|
-
* @param {...Object}
|
|
16
|
+
* @param {...Object} objects - the geometries to offset
|
|
17
17
|
* @return {Object|Array} new geometry, or list of new geometries
|
|
18
18
|
* @alias module:modeling/expansions.offset
|
|
19
19
|
*
|