@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
|
@@ -1,21 +1,6 @@
|
|
|
1
|
-
const vec3 = require('../../../maths/vec3')
|
|
2
|
-
|
|
3
|
-
const geom3 = require('../../../geometries/geom3')
|
|
4
1
|
const poly3 = require('../../../geometries/poly3')
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
const calculatePlane = require('./calculatePlane')
|
|
9
|
-
|
|
10
|
-
const toPolygon3D = (vector, edge) => {
|
|
11
|
-
const points = [
|
|
12
|
-
vec3.subtract(vec3.create(), edge[0], vector),
|
|
13
|
-
vec3.subtract(vec3.create(), edge[1], vector),
|
|
14
|
-
vec3.add(vec3.create(), edge[1], vector),
|
|
15
|
-
vec3.add(vec3.create(), edge[0], vector)
|
|
16
|
-
]
|
|
17
|
-
return poly3.fromPoints(points)
|
|
18
|
-
}
|
|
2
|
+
const earcut = require('../earcut')
|
|
3
|
+
const PolygonHierarchy = require('../earcut/polygonHierarchy')
|
|
19
4
|
|
|
20
5
|
/**
|
|
21
6
|
* Return a list of polygons which are enclosed by the slice.
|
|
@@ -24,52 +9,31 @@ const toPolygon3D = (vector, edge) => {
|
|
|
24
9
|
* @alias module:modeling/extrusions/slice.toPolygons
|
|
25
10
|
*/
|
|
26
11
|
const toPolygons = (slice) => {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
12
|
+
const hierarchy = new PolygonHierarchy(slice)
|
|
13
|
+
|
|
14
|
+
const polygons = []
|
|
15
|
+
hierarchy.roots.forEach(({ solid, holes }) => {
|
|
16
|
+
// hole indices
|
|
17
|
+
let index = solid.length
|
|
18
|
+
const holesIndex = []
|
|
19
|
+
holes.forEach((hole, i) => {
|
|
20
|
+
holesIndex.push(index)
|
|
21
|
+
index += hole.length
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// compute earcut triangulation for each solid
|
|
25
|
+
const vertices = [solid, ...holes].flat()
|
|
26
|
+
const data = vertices.flat()
|
|
27
|
+
// Get original 3D vertex by index
|
|
28
|
+
const getVertex = (i) => hierarchy.to3D(vertices[i])
|
|
29
|
+
const indices = earcut(data, holesIndex)
|
|
30
|
+
for (let i = 0; i < indices.length; i += 3) {
|
|
31
|
+
// Map back to original vertices
|
|
32
|
+
const tri = indices.slice(i, i + 3).map(getVertex)
|
|
33
|
+
polygons.push(poly3.fromPointsAndPlane(tri, hierarchy.plane))
|
|
42
34
|
}
|
|
43
35
|
})
|
|
44
36
|
|
|
45
|
-
// create one LARGE polygon to encompass the side, i.e. base
|
|
46
|
-
const direction = vec3.subtract(vec3.create(), farthestEdge[0], midpoint)
|
|
47
|
-
const perpendicular = vec3.cross(vec3.create(), splane, direction)
|
|
48
|
-
|
|
49
|
-
const p1 = vec3.add(vec3.create(), midpoint, direction)
|
|
50
|
-
vec3.add(p1, p1, direction)
|
|
51
|
-
const p2 = vec3.add(vec3.create(), midpoint, perpendicular)
|
|
52
|
-
vec3.add(p2, p2, perpendicular)
|
|
53
|
-
const p3 = vec3.subtract(vec3.create(), midpoint, direction)
|
|
54
|
-
vec3.subtract(p3, p3, direction)
|
|
55
|
-
const p4 = vec3.subtract(vec3.create(), midpoint, perpendicular)
|
|
56
|
-
vec3.subtract(p4, p4, perpendicular)
|
|
57
|
-
const poly1 = poly3.fromPoints([p1, p2, p3, p4])
|
|
58
|
-
const base = geom3.create([poly1])
|
|
59
|
-
|
|
60
|
-
const wallPolygons = edges.map((edge) => toPolygon3D(splane, edge))
|
|
61
|
-
const walls = geom3.create(wallPolygons)
|
|
62
|
-
|
|
63
|
-
// make an insection of the base and the walls, creating... a set of polygons!
|
|
64
|
-
const geometry3 = intersectGeom3Sub(base, walls)
|
|
65
|
-
|
|
66
|
-
// return only those polygons from the base
|
|
67
|
-
let polygons = geom3.toPolygons(geometry3)
|
|
68
|
-
polygons = polygons.filter((polygon) => {
|
|
69
|
-
const a = vec3.angle(splane, poly3.plane(polygon))
|
|
70
|
-
// walls should be PI / 2 radians rotated from the base
|
|
71
|
-
return Math.abs(a) < (Math.PI / 90)
|
|
72
|
-
})
|
|
73
37
|
return polygons
|
|
74
38
|
}
|
|
75
39
|
|
|
@@ -43,7 +43,7 @@ test('hull (single, geom2)', (t) => {
|
|
|
43
43
|
t.is(pts.length, 7)
|
|
44
44
|
})
|
|
45
45
|
|
|
46
|
-
test('hull (multiple,
|
|
46
|
+
test('hull (multiple, overlapping, geom2)', (t) => {
|
|
47
47
|
const geometry1 = geom2.fromPoints([[5, 5], [-5, 5], [-5, -5], [5, -5]])
|
|
48
48
|
const geometry2 = geom2.fromPoints([[3, 3], [-3, 3], [-3, -3], [3, -3]])
|
|
49
49
|
const geometry3 = geom2.fromPoints([[6, 3], [-6, 3], [-6, -3], [6, -3]])
|
|
@@ -5,7 +5,7 @@ const union = require('../booleans/union')
|
|
|
5
5
|
const hull = require('./hull')
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Create a chain of hulled geometries from the given
|
|
8
|
+
* Create a chain of hulled geometries from the given geometries.
|
|
9
9
|
* Essentially hull A+B, B+C, C+D, etc., then union the results.
|
|
10
10
|
* The given geometries should be of the same type, either geom2 or geom3 or path2.
|
|
11
11
|
*
|
|
@@ -30,7 +30,7 @@ const hullGeom2 = (...geometries) => {
|
|
|
30
30
|
|
|
31
31
|
const hullpoints = hullPoints2(uniquepoints)
|
|
32
32
|
|
|
33
|
-
// NOTE: more
|
|
33
|
+
// NOTE: more than three points are required to create a new geometry
|
|
34
34
|
if (hullpoints.length < 3) return geom2.create()
|
|
35
35
|
|
|
36
36
|
// assemble a new geometry from the list of points
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
const flatten = require('../../utils/flatten')
|
|
2
2
|
|
|
3
|
-
const vec2 = require('../../maths/vec2')
|
|
4
|
-
|
|
5
3
|
const path2 = require('../../geometries/path2')
|
|
6
4
|
|
|
7
5
|
const hullPoints2 = require('./hullPoints2')
|
|
@@ -16,11 +14,15 @@ const hullPath2 = (...geometries) => {
|
|
|
16
14
|
|
|
17
15
|
// extract the unique points from the geometries
|
|
18
16
|
const uniquepoints = []
|
|
17
|
+
const found = new Set()
|
|
19
18
|
geometries.forEach((geometry) => {
|
|
20
19
|
const points = path2.toPoints(geometry)
|
|
21
20
|
points.forEach((point) => {
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
21
|
+
const key = point.toString()
|
|
22
|
+
if (!found.has(key)) {
|
|
23
|
+
uniquepoints.push(point)
|
|
24
|
+
found.add(key)
|
|
25
|
+
}
|
|
24
26
|
})
|
|
25
27
|
})
|
|
26
28
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const test = require('ava')
|
|
2
|
+
|
|
3
|
+
const { path2 } = require('../../geometries')
|
|
4
|
+
|
|
5
|
+
const hullPath2 = require('./hullPath2')
|
|
6
|
+
|
|
7
|
+
test('hullPath2', (t) => {
|
|
8
|
+
const closed = true
|
|
9
|
+
const geometry1 = path2.fromPoints({ closed }, [[0, 0], [-4, 4], [-4, -4]])
|
|
10
|
+
const geometry2 = path2.fromPoints({ closed }, [[0, 0], [4, -4], [4, 4]])
|
|
11
|
+
|
|
12
|
+
const obs = hullPath2(geometry1, geometry2)
|
|
13
|
+
t.true(path2.isA(obs))
|
|
14
|
+
const pts = path2.toPoints(obs)
|
|
15
|
+
t.is(pts.length, 4)
|
|
16
|
+
})
|
|
@@ -42,7 +42,7 @@ test('hullPoints2 bug #114 2 circles with 18 segments', (t) => {
|
|
|
42
42
|
[7.298133329356933, -1.9283628290596186]
|
|
43
43
|
]
|
|
44
44
|
|
|
45
|
-
// we just want to
|
|
45
|
+
// we just want to be sure no err happens for this case
|
|
46
46
|
const out = hullPoints2(points)
|
|
47
47
|
t.is(out.length, 19)
|
|
48
48
|
})
|
|
@@ -722,7 +722,7 @@ class QuickHull {
|
|
|
722
722
|
for (let i = 0; i < this.newFaces.length; i += 1) {
|
|
723
723
|
const face = this.newFaces[i]
|
|
724
724
|
if (face.mark === VISIBLE) {
|
|
725
|
-
while (this.doAdjacentMerge(face, MERGE_NON_CONVEX_WRT_LARGER_FACE)) {}
|
|
725
|
+
while (this.doAdjacentMerge(face, MERGE_NON_CONVEX_WRT_LARGER_FACE)) {} // eslint-disable-line no-empty
|
|
726
726
|
}
|
|
727
727
|
}
|
|
728
728
|
|
|
@@ -733,7 +733,7 @@ class QuickHull {
|
|
|
733
733
|
const face = this.newFaces[i]
|
|
734
734
|
if (face.mark === NON_CONVEX) {
|
|
735
735
|
face.mark = VISIBLE
|
|
736
|
-
while (this.doAdjacentMerge(face, MERGE_NON_CONVEX)) {}
|
|
736
|
+
while (this.doAdjacentMerge(face, MERGE_NON_CONVEX)) {} // eslint-disable-line no-empty
|
|
737
737
|
}
|
|
738
738
|
}
|
|
739
739
|
|
|
@@ -99,9 +99,7 @@ const splitPolygon = (openedge, polygon, eps) => {
|
|
|
99
99
|
/*
|
|
100
100
|
* TBD This should be part of vec3.
|
|
101
101
|
*/
|
|
102
|
-
const almostEquals = (eps, v1, v2) =>
|
|
103
|
-
return (Math.abs(v1[0] - v2[0]) <= eps && Math.abs(v1[1] - v2[1]) <= eps && Math.abs(v1[2] - v2[2]) <= eps)
|
|
104
|
-
}
|
|
102
|
+
const almostEquals = (eps, v1, v2) => (Math.abs(v1[0] - v2[0]) <= eps && Math.abs(v1[1] - v2[1]) <= eps && Math.abs(v1[2] - v2[2]) <= eps)
|
|
105
103
|
|
|
106
104
|
const enclosedEdge = (openedge, edge, eps) => {
|
|
107
105
|
if (openedge.distance < edge.distance) {
|
|
@@ -151,7 +149,7 @@ const splitEdge = (openedges, edge, eps) => {
|
|
|
151
149
|
*/
|
|
152
150
|
const cullOpenEdges = (edges) => {
|
|
153
151
|
const openedges = []
|
|
154
|
-
edges.forEach((edge
|
|
152
|
+
edges.forEach((edge) => {
|
|
155
153
|
const polygons = edge.polygons
|
|
156
154
|
if (polygons.length === 1) {
|
|
157
155
|
// console.log('open edge: ',edge[0],'<-->',edge[1])
|
|
@@ -15,15 +15,11 @@ const repairTjunctions = require('./repairTjunctions')
|
|
|
15
15
|
|
|
16
16
|
/*
|
|
17
17
|
*/
|
|
18
|
-
const generalizePath2 = (options, geometry) =>
|
|
19
|
-
return geometry
|
|
20
|
-
}
|
|
18
|
+
const generalizePath2 = (options, geometry) => geometry
|
|
21
19
|
|
|
22
20
|
/*
|
|
23
21
|
*/
|
|
24
|
-
const generalizeGeom2 = (options, geometry) =>
|
|
25
|
-
return geometry
|
|
26
|
-
}
|
|
22
|
+
const generalizeGeom2 = (options, geometry) => geometry
|
|
27
23
|
|
|
28
24
|
/*
|
|
29
25
|
*/
|
|
@@ -77,6 +73,7 @@ const generalizeGeom3 = (options, geometry) => {
|
|
|
77
73
|
* @param {Boolean} [options.simplify=false] the geometries should be simplified
|
|
78
74
|
* @param {Boolean} [options.triangulate=false] the geometries should be triangulated
|
|
79
75
|
* @param {Boolean} [options.repair=false] the geometries should be repaired
|
|
76
|
+
* @param {...Object} geometries - the geometries to generalize
|
|
80
77
|
* @return {Object|Array} the modified geometry, or a list of modified geometries
|
|
81
78
|
* @alias module:modeling/modifiers.generalize
|
|
82
79
|
*/
|
|
@@ -84,7 +81,7 @@ const generalize = (options, ...geometries) => {
|
|
|
84
81
|
geometries = flatten(geometries)
|
|
85
82
|
if (geometries.length === 0) throw new Error('wrong number of arguments')
|
|
86
83
|
|
|
87
|
-
const results = geometries.map((geometry
|
|
84
|
+
const results = geometries.map((geometry) => {
|
|
88
85
|
if (path2.isA(geometry)) return generalizePath2(options, geometry)
|
|
89
86
|
if (geom2.isA(geometry)) return generalizeGeom2(options, geometry)
|
|
90
87
|
if (geom3.isA(geometry)) return generalizeGeom3(options, geometry)
|
|
@@ -11,7 +11,7 @@ const { snap } = require('./index')
|
|
|
11
11
|
test('snap: snap of a path2 produces an expected path2', (t) => {
|
|
12
12
|
const geometry1 = path2.create()
|
|
13
13
|
const geometry2 = arc({ radius: 1 / 2, segments: 8 })
|
|
14
|
-
const geometry3 = arc({ radius: 1.
|
|
14
|
+
const geometry3 = arc({ radius: 1.3333333333333333 / 2, segments: 8 })
|
|
15
15
|
const geometry4 = arc({ radius: Math.PI * 1000 / 2, segments: 8 })
|
|
16
16
|
|
|
17
17
|
const results = snap(geometry1, geometry2, geometry3, geometry4)
|
|
@@ -55,7 +55,7 @@ test('snap: snap of a path2 produces an expected path2', (t) => {
|
|
|
55
55
|
test('snap: snap of a geom2 produces an expected geom2', (t) => {
|
|
56
56
|
const geometry1 = geom2.create()
|
|
57
57
|
const geometry2 = rectangle({ size: [1, 1, 1] })
|
|
58
|
-
const geometry3 = rectangle({ size: [1.
|
|
58
|
+
const geometry3 = rectangle({ size: [1.3333333333333333, 1.3333333333333333, 1.3333333333333333] })
|
|
59
59
|
const geometry4 = rectangle({ size: [Math.PI * 1000, Math.PI * 1000, Math.PI * 1000] })
|
|
60
60
|
|
|
61
61
|
const results = snap(geometry1, geometry2, geometry3, geometry4)
|
|
@@ -87,7 +87,7 @@ test('snap: snap of a geom2 produces an expected geom2', (t) => {
|
|
|
87
87
|
test('snap: snap of a geom3 produces an expected geom3', (t) => {
|
|
88
88
|
const geometry1 = geom3.create()
|
|
89
89
|
const geometry2 = cuboid({ size: [1, 1, 1] })
|
|
90
|
-
const geometry3 = cuboid({ size: [1.
|
|
90
|
+
const geometry3 = cuboid({ size: [1.3333333333333333, 1.3333333333333333, 1.3333333333333333] })
|
|
91
91
|
const geometry4 = cuboid({ size: [Math.PI * 1000, Math.PI * 1000, Math.PI * 1000] })
|
|
92
92
|
|
|
93
93
|
const results = snap(geometry1, geometry2, geometry3, geometry4)
|
|
@@ -7,7 +7,7 @@ type NullableNumber = null | number
|
|
|
7
7
|
|
|
8
8
|
export interface AlignOptions {
|
|
9
9
|
modes?: Array<'center' | 'max' | 'min' | 'none'>
|
|
10
|
-
relativeTo?: [NullableNumber] | [NullableNumber
|
|
10
|
+
relativeTo?: [NullableNumber] | [NullableNumber, NullableNumber] | [NullableNumber, NullableNumber, NullableNumber]
|
|
11
11
|
grouped?: boolean
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -24,18 +24,18 @@ const centerGeometry = (options, object) => {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* Center the given
|
|
27
|
+
* Center the given objects using the given options.
|
|
28
28
|
* @param {Object} options - options for centering
|
|
29
29
|
* @param {Array} [options.axes=[true,true,true]] - axis of which to center, true or false
|
|
30
|
-
* @param {Array} [options.relativeTo=[0,0,0]] - relative point of which to center the
|
|
31
|
-
* @param {...Object}
|
|
32
|
-
* @return {Object|Array} the centered
|
|
30
|
+
* @param {Array} [options.relativeTo=[0,0,0]] - relative point of which to center the objects
|
|
31
|
+
* @param {...Object} objects - the objects to center
|
|
32
|
+
* @return {Object|Array} the centered object, or a list of centered objects
|
|
33
33
|
* @alias module:modeling/transforms.center
|
|
34
34
|
*
|
|
35
35
|
* @example
|
|
36
36
|
* let myshape = center({axes: [true,false,false]}, sphere()) // center about the X axis
|
|
37
37
|
*/
|
|
38
|
-
const center = (options, ...
|
|
38
|
+
const center = (options, ...objects) => {
|
|
39
39
|
const defaults = {
|
|
40
40
|
axes: [true, true, true],
|
|
41
41
|
relativeTo: [0, 0, 0]
|
|
@@ -43,13 +43,13 @@ const center = (options, ...geometries) => {
|
|
|
43
43
|
}
|
|
44
44
|
const { axes, relativeTo } = Object.assign({}, defaults, options)
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
if (
|
|
46
|
+
objects = flatten(objects)
|
|
47
|
+
if (objects.length === 0) throw new Error('wrong number of arguments')
|
|
48
48
|
if (relativeTo.length !== 3) throw new Error('relativeTo must be an array of length 3')
|
|
49
49
|
|
|
50
50
|
options = { axes, relativeTo }
|
|
51
51
|
|
|
52
|
-
const results =
|
|
52
|
+
const results = objects.map((object) => {
|
|
53
53
|
if (path2.isA(object)) return centerGeometry(options, object)
|
|
54
54
|
if (geom2.isA(object)) return centerGeometry(options, object)
|
|
55
55
|
if (geom3.isA(object)) return centerGeometry(options, object)
|
|
@@ -59,25 +59,25 @@ const center = (options, ...geometries) => {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
|
-
* Center the given
|
|
63
|
-
* @param {...Object}
|
|
64
|
-
* @return {Object|Array} the centered
|
|
62
|
+
* Center the given objects about the X axis.
|
|
63
|
+
* @param {...Object} objects - the objects to center
|
|
64
|
+
* @return {Object|Array} the centered object, or a list of centered objects
|
|
65
65
|
* @alias module:modeling/transforms.centerX
|
|
66
66
|
*/
|
|
67
67
|
const centerX = (...objects) => center({ axes: [true, false, false] }, objects)
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
|
-
* Center the given
|
|
71
|
-
* @param {...Object}
|
|
72
|
-
* @return {Object|Array} the centered
|
|
70
|
+
* Center the given objects about the Y axis.
|
|
71
|
+
* @param {...Object} objects - the objects to center
|
|
72
|
+
* @return {Object|Array} the centered object, or a list of centered objects
|
|
73
73
|
* @alias module:modeling/transforms.centerY
|
|
74
74
|
*/
|
|
75
75
|
const centerY = (...objects) => center({ axes: [false, true, false] }, objects)
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
|
-
* Center the given
|
|
79
|
-
* @param {...Object}
|
|
80
|
-
* @return {Object|Array} the centered
|
|
78
|
+
* Center the given objects about the Z axis.
|
|
79
|
+
* @param {...Object} objects - the objects to center
|
|
80
|
+
* @return {Object|Array} the centered object, or a list of centered objects
|
|
81
81
|
* @alias module:modeling/transforms.centerZ
|
|
82
82
|
*/
|
|
83
83
|
const centerZ = (...objects) => center({ axes: [false, false, true] }, objects)
|
|
@@ -8,12 +8,12 @@ const geom3 = require('../../geometries/geom3')
|
|
|
8
8
|
const path2 = require('../../geometries/path2')
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Mirror the given
|
|
11
|
+
* Mirror the given objects using the given options.
|
|
12
12
|
* @param {Object} options - options for mirror
|
|
13
13
|
* @param {Array} [options.origin=[0,0,0]] - the origin of the plane
|
|
14
14
|
* @param {Array} [options.normal=[0,0,1]] - the normal vector of the plane
|
|
15
|
-
* @param {...Object}
|
|
16
|
-
* @return {Object|Array} the mirrored
|
|
15
|
+
* @param {...Object} objects - the objects to mirror
|
|
16
|
+
* @return {Object|Array} the mirrored object, or a list of mirrored objects
|
|
17
17
|
* @alias module:modeling/transforms.mirror
|
|
18
18
|
*
|
|
19
19
|
* @example
|
|
@@ -47,25 +47,25 @@ const mirror = (options, ...objects) => {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
* Mirror the given
|
|
51
|
-
* @param {...Object}
|
|
52
|
-
* @return {Object|Array} the mirrored
|
|
50
|
+
* Mirror the given objects about the X axis.
|
|
51
|
+
* @param {...Object} objects - the objects to mirror
|
|
52
|
+
* @return {Object|Array} the mirrored object, or a list of mirrored objects
|
|
53
53
|
* @alias module:modeling/transforms.mirrorX
|
|
54
54
|
*/
|
|
55
55
|
const mirrorX = (...objects) => mirror({ normal: [1, 0, 0] }, objects)
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
|
-
* Mirror the given
|
|
59
|
-
* @param {...Object}
|
|
60
|
-
* @return {Object|Array} the mirrored
|
|
58
|
+
* Mirror the given objects about the Y axis.
|
|
59
|
+
* @param {...Object} objects - the geometries to mirror
|
|
60
|
+
* @return {Object|Array} the mirrored object, or a list of mirrored objects
|
|
61
61
|
* @alias module:modeling/transforms.mirrorY
|
|
62
62
|
*/
|
|
63
63
|
const mirrorY = (...objects) => mirror({ normal: [0, 1, 0] }, objects)
|
|
64
64
|
|
|
65
65
|
/**
|
|
66
|
-
* Mirror the given
|
|
66
|
+
* Mirror the given objects about the Z axis.
|
|
67
67
|
* @param {...Object} objects - the geometries to mirror
|
|
68
|
-
* @return {Object|Array} the mirrored
|
|
68
|
+
* @return {Object|Array} the mirrored object, or a list of mirrored objects
|
|
69
69
|
* @alias module:modeling/transforms.mirrorZ
|
|
70
70
|
*/
|
|
71
71
|
const mirrorZ = (...objects) => mirror({ normal: [0, 0, 1] }, objects)
|
|
@@ -7,10 +7,10 @@ const geom3 = require('../../geometries/geom3')
|
|
|
7
7
|
const path2 = require('../../geometries/path2')
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Rotate the given
|
|
10
|
+
* Rotate the given objects using the given options.
|
|
11
11
|
* @param {Array} angles - angle (RADIANS) of rotations about X, Y, and Z axis
|
|
12
|
-
* @param {...Object}
|
|
13
|
-
* @return {Object|Array} the rotated
|
|
12
|
+
* @param {...Object} objects - the objects to rotate
|
|
13
|
+
* @return {Object|Array} the rotated object, or a list of rotated objects
|
|
14
14
|
* @alias module:modeling/transforms.rotate
|
|
15
15
|
*
|
|
16
16
|
* @example
|
|
@@ -42,28 +42,28 @@ const rotate = (angles, ...objects) => {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
|
-
* Rotate the given
|
|
45
|
+
* Rotate the given objects about the X axis, using the given options.
|
|
46
46
|
* @param {Number} angle - angle (RADIANS) of rotations about X
|
|
47
|
-
* @param {...Object}
|
|
48
|
-
* @return {Object|Array} the rotated
|
|
47
|
+
* @param {...Object} objects - the objects to rotate
|
|
48
|
+
* @return {Object|Array} the rotated object, or a list of rotated objects
|
|
49
49
|
* @alias module:modeling/transforms.rotateX
|
|
50
50
|
*/
|
|
51
51
|
const rotateX = (angle, ...objects) => rotate([angle, 0, 0], objects)
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
|
-
* Rotate the given
|
|
54
|
+
* Rotate the given objects about the Y axis, using the given options.
|
|
55
55
|
* @param {Number} angle - angle (RADIANS) of rotations about Y
|
|
56
|
-
* @param {...Object}
|
|
57
|
-
* @return {Object|Array} the rotated
|
|
56
|
+
* @param {...Object} objects - the objects to rotate
|
|
57
|
+
* @return {Object|Array} the rotated object, or a list of rotated objects
|
|
58
58
|
* @alias module:modeling/transforms.rotateY
|
|
59
59
|
*/
|
|
60
60
|
const rotateY = (angle, ...objects) => rotate([0, angle, 0], objects)
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
|
-
* Rotate the given
|
|
63
|
+
* Rotate the given objects about the Z axis, using the given options.
|
|
64
64
|
* @param {Number} angle - angle (RADIANS) of rotations about Z
|
|
65
|
-
* @param {...Object}
|
|
66
|
-
* @return {Object|Array} the rotated
|
|
65
|
+
* @param {...Object} objects - the objects to rotate
|
|
66
|
+
* @return {Object|Array} the rotated object, or a list of rotated objects
|
|
67
67
|
* @alias module:modeling/transforms.rotateZ
|
|
68
68
|
*/
|
|
69
69
|
const rotateZ = (angle, ...objects) => rotate([0, 0, angle], objects)
|
|
@@ -7,10 +7,10 @@ const geom3 = require('../../geometries/geom3')
|
|
|
7
7
|
const path2 = require('../../geometries/path2')
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Scale the given
|
|
11
|
-
* @param {Array} factors - X, Y, Z factors by which to scale the
|
|
12
|
-
* @param {...Object}
|
|
13
|
-
* @return {Object|Array} the scaled
|
|
10
|
+
* Scale the given objects using the given options.
|
|
11
|
+
* @param {Array} factors - X, Y, Z factors by which to scale the objects
|
|
12
|
+
* @param {...Object} objects - the objects to scale
|
|
13
|
+
* @return {Object|Array} the scaled object, or a list of scaled objects
|
|
14
14
|
* @alias module:modeling/transforms.scale
|
|
15
15
|
*
|
|
16
16
|
* @example
|
|
@@ -40,31 +40,31 @@ const scale = (factors, ...objects) => {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
|
-
* Scale the given
|
|
44
|
-
* @param {Number} factor - X factor by which to scale the
|
|
45
|
-
* @param {...Object}
|
|
46
|
-
* @return {Object|Array} the scaled
|
|
43
|
+
* Scale the given objects about the X axis using the given options.
|
|
44
|
+
* @param {Number} factor - X factor by which to scale the objects
|
|
45
|
+
* @param {...Object} objects - the objects to scale
|
|
46
|
+
* @return {Object|Array} the scaled object, or a list of scaled objects
|
|
47
47
|
* @alias module:modeling/transforms.scaleX
|
|
48
48
|
*/
|
|
49
|
-
const scaleX = (
|
|
49
|
+
const scaleX = (factor, ...objects) => scale([factor, 1, 1], objects)
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
|
-
* Scale the given
|
|
53
|
-
* @param {Number} factor - Y factor by which to scale the
|
|
54
|
-
* @param {...Object}
|
|
55
|
-
* @return {Object|Array} the scaled
|
|
52
|
+
* Scale the given objects about the Y axis using the given options.
|
|
53
|
+
* @param {Number} factor - Y factor by which to scale the objects
|
|
54
|
+
* @param {...Object} objects - the objects to scale
|
|
55
|
+
* @return {Object|Array} the scaled object, or a list of scaled objects
|
|
56
56
|
* @alias module:modeling/transforms.scaleY
|
|
57
57
|
*/
|
|
58
|
-
const scaleY = (
|
|
58
|
+
const scaleY = (factor, ...objects) => scale([1, factor, 1], objects)
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
|
-
* Scale the given
|
|
62
|
-
* @param {Number} factor - Z factor by which to scale the
|
|
63
|
-
* @param {...Object}
|
|
64
|
-
* @return {Object|Array} the scaled
|
|
61
|
+
* Scale the given objects about the Z axis using the given options.
|
|
62
|
+
* @param {Number} factor - Z factor by which to scale the objects
|
|
63
|
+
* @param {...Object} objects - the objects to scale
|
|
64
|
+
* @return {Object|Array} the scaled object, or a list of scaled objects
|
|
65
65
|
* @alias module:modeling/transforms.scaleZ
|
|
66
66
|
*/
|
|
67
|
-
const scaleZ = (
|
|
67
|
+
const scaleZ = (factor, ...objects) => scale([1, 1, factor], objects)
|
|
68
68
|
|
|
69
69
|
module.exports = {
|
|
70
70
|
scale,
|
|
@@ -5,10 +5,10 @@ const geom3 = require('../../geometries/geom3')
|
|
|
5
5
|
const path2 = require('../../geometries/path2')
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Transform the given
|
|
8
|
+
* Transform the given objects using the given matrix.
|
|
9
9
|
* @param {mat4} matrix - a transformation matrix
|
|
10
|
-
* @param {...Object}
|
|
11
|
-
* @return {Object|Array} the transformed
|
|
10
|
+
* @param {...Object} objects - the objects to transform
|
|
11
|
+
* @return {Object|Array} the transformed object, or a list of transformed objects
|
|
12
12
|
* @alias module:modeling/transforms.transform
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
@@ -7,10 +7,10 @@ const geom3 = require('../../geometries/geom3')
|
|
|
7
7
|
const path2 = require('../../geometries/path2')
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Translate the given
|
|
11
|
-
* @param {Array} offset - offset (vector) of which to translate the
|
|
12
|
-
* @param {...Object}
|
|
13
|
-
* @return {Object|Array} the translated
|
|
10
|
+
* Translate the given objects using the given options.
|
|
11
|
+
* @param {Array} offset - offset (vector) of which to translate the objects
|
|
12
|
+
* @param {...Object} objects - the objects to translate
|
|
13
|
+
* @return {Object|Array} the translated object, or a list of translated objects
|
|
14
14
|
* @alias module:modeling/transforms.translate
|
|
15
15
|
*
|
|
16
16
|
* @example
|
|
@@ -38,28 +38,28 @@ const translate = (offset, ...objects) => {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
|
-
* Translate the given
|
|
42
|
-
* @param {Number} offset - X offset of which to translate the
|
|
43
|
-
* @param {...Object}
|
|
44
|
-
* @return {Object|Array} the translated
|
|
41
|
+
* Translate the given objects along the X axis using the given options.
|
|
42
|
+
* @param {Number} offset - X offset of which to translate the objects
|
|
43
|
+
* @param {...Object} objects - the objects to translate
|
|
44
|
+
* @return {Object|Array} the translated object, or a list of translated objects
|
|
45
45
|
* @alias module:modeling/transforms.translateX
|
|
46
46
|
*/
|
|
47
47
|
const translateX = (offset, ...objects) => translate([offset, 0, 0], objects)
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
* Translate the given
|
|
50
|
+
* Translate the given objects along the Y axis using the given options.
|
|
51
51
|
* @param {Number} offset - Y offset of which to translate the geometries
|
|
52
|
-
* @param {...Object}
|
|
53
|
-
* @return {Object|Array} the translated
|
|
52
|
+
* @param {...Object} objects - the objects to translate
|
|
53
|
+
* @return {Object|Array} the translated object, or a list of translated objects
|
|
54
54
|
* @alias module:modeling/transforms.translateY
|
|
55
55
|
*/
|
|
56
56
|
const translateY = (offset, ...objects) => translate([0, offset, 0], objects)
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
|
-
* Translate the given
|
|
59
|
+
* Translate the given objects along the Z axis using the given options.
|
|
60
60
|
* @param {Number} offset - Z offset of which to translate the geometries
|
|
61
|
-
* @param {...Object}
|
|
62
|
-
* @return {Object|Array} the translated
|
|
61
|
+
* @param {...Object} objects - the objects to translate
|
|
62
|
+
* @return {Object|Array} the translated object, or a list of translated objects
|
|
63
63
|
* @alias module:modeling/transforms.translateZ
|
|
64
64
|
*/
|
|
65
65
|
const translateZ = (offset, ...objects) => translate([0, 0, offset], objects)
|
package/src/primitives/arc.js
CHANGED
|
@@ -131,8 +131,6 @@ test('cylinderElliptic (options)', (t) => {
|
|
|
131
131
|
// test startAngle and endAngle
|
|
132
132
|
obs = cylinderElliptic({ startRadius: [1, 2], endRadius: [2, 1], startAngle: Math.PI / 2, endAngle: Math.PI * 2 * 0.75, segments: 12 })
|
|
133
133
|
pts = geom3.toPoints(obs)
|
|
134
|
-
exp = [
|
|
135
|
-
]
|
|
136
134
|
|
|
137
135
|
t.is(pts.length, 28)
|
|
138
136
|
// t.true(comparePolygonsAsPoints(pts, exp))
|
|
@@ -10,7 +10,7 @@ const { isGTE, isNumberArray } = require('./commonChecks')
|
|
|
10
10
|
* @param {Object} [options] - options for construction
|
|
11
11
|
* @param {Array} [options.center=[0,0,0]] - center of ellipsoid
|
|
12
12
|
* @param {Array} [options.radius=[1,1,1]] - radius of ellipsoid, along X, Y and Z
|
|
13
|
-
* @param {Number} [options.segments=32] - number of
|
|
13
|
+
* @param {Number} [options.segments=32] - number of segments to create per full rotation
|
|
14
14
|
* @param {Array} [options.axes] - an array with three vectors for the x, y and z base vectors
|
|
15
15
|
* @returns {geom3} new 3D geometry
|
|
16
16
|
* @alias module:modeling/primitives.ellipsoid
|