@jscad/modeling 3.0.2-alpha.0 → 3.0.3-alpha.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.
Files changed (116) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/jscad-modeling.es.js +2 -2
  3. package/dist/jscad-modeling.min.js +2 -2
  4. package/package.json +2 -2
  5. package/src/colors/colorize.test.js +1 -1
  6. package/src/geometries/geom2/index.d.ts +0 -2
  7. package/src/geometries/geom2/index.js +0 -2
  8. package/src/geometries/geom3/applyTransforms.test.js +2 -2
  9. package/src/geometries/geom3/clone.test.js +2 -2
  10. package/src/geometries/geom3/create.js +1 -9
  11. package/src/geometries/geom3/{fromPoints.d.ts → fromVertices.d.ts} +1 -1
  12. package/src/geometries/geom3/{fromPoints.js → fromVertices.js} +3 -2
  13. package/src/geometries/geom3/{fromPoints.test.js → fromVertices.test.js} +6 -6
  14. package/src/geometries/geom3/{fromPointsConvex.d.ts → fromVerticesConvex.d.ts} +1 -1
  15. package/src/geometries/geom3/fromVerticesConvex.js +25 -0
  16. package/src/geometries/geom3/{fromPointsConvex.test.js → fromVerticesConvex.test.js} +3 -3
  17. package/src/geometries/geom3/index.d.ts +3 -5
  18. package/src/geometries/geom3/index.js +4 -6
  19. package/src/geometries/geom3/invert.test.js +2 -2
  20. package/src/geometries/geom3/isA.test.js +2 -2
  21. package/src/geometries/geom3/toString.test.js +2 -2
  22. package/src/geometries/geom3/{toPoints.d.ts → toVertices.d.ts} +1 -1
  23. package/src/geometries/geom3/{toPoints.js → toVertices.js} +3 -2
  24. package/src/geometries/geom3/{toPoints.test.js → toVertices.test.js} +4 -4
  25. package/src/geometries/geom3/transform.test.js +2 -2
  26. package/src/geometries/geom3/validate.test.js +4 -4
  27. package/src/geometries/index.d.ts +1 -0
  28. package/src/geometries/index.js +1 -0
  29. package/src/geometries/path2/create.js +1 -10
  30. package/src/geometries/path2/index.d.ts +0 -2
  31. package/src/geometries/path2/index.js +0 -2
  32. package/src/geometries/path3/applyTransforms.js +22 -0
  33. package/src/geometries/path3/applyTransforms.test.js +28 -0
  34. package/src/geometries/path3/close.d.ts +3 -0
  35. package/src/geometries/path3/close.js +31 -0
  36. package/src/geometries/path3/close.test.js +43 -0
  37. package/src/geometries/path3/concat.d.ts +3 -0
  38. package/src/geometries/path3/concat.js +36 -0
  39. package/src/geometries/path3/concat.test.js +35 -0
  40. package/src/geometries/path3/create.d.ts +4 -0
  41. package/src/geometries/path3/create.js +30 -0
  42. package/src/geometries/path3/create.test.js +8 -0
  43. package/src/geometries/path3/equals.d.ts +3 -0
  44. package/src/geometries/path3/equals.js +48 -0
  45. package/src/geometries/path3/equals.test.js +38 -0
  46. package/src/geometries/path3/fromVertices.d.ts +8 -0
  47. package/src/geometries/path3/fromVertices.js +45 -0
  48. package/src/geometries/path3/fromVertices.test.js +33 -0
  49. package/src/geometries/path3/index.d.ts +13 -0
  50. package/src/geometries/path3/index.js +21 -0
  51. package/src/geometries/path3/isA.d.ts +3 -0
  52. package/src/geometries/path3/isA.js +20 -0
  53. package/src/geometries/path3/isA.test.js +19 -0
  54. package/src/geometries/path3/reverse.d.ts +3 -0
  55. package/src/geometries/path3/reverse.js +19 -0
  56. package/src/geometries/path3/reverse.test.js +9 -0
  57. package/src/geometries/path3/toString.d.ts +3 -0
  58. package/src/geometries/path3/toString.js +24 -0
  59. package/src/geometries/path3/toVertices.d.ts +4 -0
  60. package/src/geometries/path3/toVertices.js +16 -0
  61. package/src/geometries/path3/toVertices.test.js +13 -0
  62. package/src/geometries/path3/transform.d.ts +4 -0
  63. package/src/geometries/path3/transform.js +21 -0
  64. package/src/geometries/path3/transform.test.js +50 -0
  65. package/src/geometries/path3/type.d.ts +10 -0
  66. package/src/geometries/path3/validate.d.ts +1 -0
  67. package/src/geometries/path3/validate.js +41 -0
  68. package/src/geometries/poly2/create.js +1 -6
  69. package/src/geometries/poly3/create.js +1 -6
  70. package/src/operations/booleans/intersectGeom3.test.js +4 -4
  71. package/src/operations/booleans/subtractGeom3.test.js +4 -4
  72. package/src/operations/booleans/unionGeom3.test.js +5 -5
  73. package/src/operations/extrusions/extrudeFromSlices.test.js +6 -6
  74. package/src/operations/extrusions/extrudeLinear.test.js +8 -8
  75. package/src/operations/extrusions/extrudeRotate.test.js +12 -12
  76. package/src/operations/hulls/hull.test.js +5 -5
  77. package/src/operations/hulls/hullChain.test.js +5 -5
  78. package/src/operations/hulls/toUniquePoints.js +2 -2
  79. package/src/operations/modifiers/generalize.test.js +6 -6
  80. package/src/operations/modifiers/insertTjunctions.test.js +2 -2
  81. package/src/operations/modifiers/retessellate.test.js +10 -10
  82. package/src/operations/modifiers/snap.test.js +4 -4
  83. package/src/operations/offsets/offsetGeom3.test.js +4 -4
  84. package/src/operations/transforms/center.test.js +7 -7
  85. package/src/operations/transforms/mirror.test.js +7 -7
  86. package/src/operations/transforms/rotate.test.js +7 -7
  87. package/src/operations/transforms/scale.test.js +7 -7
  88. package/src/operations/transforms/transform.test.js +2 -2
  89. package/src/operations/transforms/translate.test.js +7 -7
  90. package/src/primitives/cube.test.js +4 -4
  91. package/src/primitives/cuboid.test.js +4 -4
  92. package/src/primitives/cylinder.test.js +5 -5
  93. package/src/primitives/cylinderElliptic.test.js +9 -9
  94. package/src/primitives/ellipsoid.test.js +5 -5
  95. package/src/primitives/geodesicSphere.test.js +4 -4
  96. package/src/primitives/polyhedron.test.js +2 -2
  97. package/src/primitives/roundedCuboid.test.js +7 -7
  98. package/src/primitives/roundedCylinder.test.js +9 -9
  99. package/src/primitives/sphere.test.js +5 -5
  100. package/src/primitives/torus.test.js +4 -4
  101. package/src/geometries/geom2/fromCompactBinary.d.ts +0 -3
  102. package/src/geometries/geom2/fromCompactBinary.js +0 -40
  103. package/src/geometries/geom2/fromToCompactBinary.test.js +0 -100
  104. package/src/geometries/geom2/toCompactBinary.d.ts +0 -3
  105. package/src/geometries/geom2/toCompactBinary.js +0 -56
  106. package/src/geometries/geom3/fromCompactBinary.d.ts +0 -3
  107. package/src/geometries/geom3/fromCompactBinary.js +0 -42
  108. package/src/geometries/geom3/fromPointsConvex.js +0 -25
  109. package/src/geometries/geom3/fromToCompactBinary.test.js +0 -139
  110. package/src/geometries/geom3/toCompactBinary.d.ts +0 -3
  111. package/src/geometries/geom3/toCompactBinary.js +0 -66
  112. package/src/geometries/path2/fromCompactBinary.d.ts +0 -3
  113. package/src/geometries/path2/fromCompactBinary.js +0 -31
  114. package/src/geometries/path2/fromToCompactBinary.test.js +0 -114
  115. package/src/geometries/path2/toCompactBinary.d.ts +0 -3
  116. package/src/geometries/path2/toCompactBinary.js +0 -50
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jscad/modeling",
3
- "version": "3.0.2-alpha.0",
3
+ "version": "3.0.3-alpha.0",
4
4
  "description": "Constructive Solid Geometry (CSG) Library for JSCAD",
5
5
  "homepage": "https://openjscad.xyz/",
6
6
  "repository": "https://github.com/jscad/OpenJSCAD.org",
@@ -64,5 +64,5 @@
64
64
  "rollup": "^2.79.1",
65
65
  "rollup-plugin-banner": "^0.2.1"
66
66
  },
67
- "gitHead": "ac80d1a7cb0a8efb21aff9193d4a8bccb6e31f1c"
67
+ "gitHead": "b0a83db054ec02ccddd9e19e51f86bf30f72a69e"
68
68
  }
@@ -36,7 +36,7 @@ test('color (rgba on objects)', (t) => {
36
36
 
37
37
  test('color (rgba on geometry)', (t) => {
38
38
  const obj0 = geom2.create([[[0, 0], [1, 0], [0, 1]]])
39
- const obj1 = geom3.fromPoints([[[0, 0, 0], [1, 0, 0], [1, 0, 1]]])
39
+ const obj1 = geom3.fromVertices([[[0, 0, 0], [1, 0, 0], [1, 0, 1]]])
40
40
  const obj2 = path2.fromPoints({ closed: true }, [[0, 0], [1, 0], [1, 1]])
41
41
  const obj3 = poly3.create([[0, 0, 0], [1, 0, 0], [1, 1, 0]])
42
42
 
@@ -1,14 +1,12 @@
1
1
  export { clone } from './clone.js'
2
2
  export { create } from './create.js'
3
3
  export { fromSides } from './fromSides.js'
4
- export { fromCompactBinary } from './fromCompactBinary.js'
5
4
  export { isA } from './isA.js'
6
5
  export { reverse } from './reverse.js'
7
6
  export { toOutlines } from './toOutlines.js'
8
7
  export { toPoints } from './toPoints.js'
9
8
  export { toSides } from './toSides.js'
10
9
  export { toString } from './toString.js'
11
- export { toCompactBinary } from './toCompactBinary.js'
12
10
  export { transform } from './transform.js'
13
11
  export { validate } from './validate.js'
14
12
 
@@ -11,13 +11,11 @@
11
11
  export { clone } from './clone.js'
12
12
  export { create } from './create.js'
13
13
  export { fromSides } from './fromSides.js'
14
- export { fromCompactBinary } from './fromCompactBinary.js'
15
14
  export { isA } from './isA.js'
16
15
  export { reverse } from './reverse.js'
17
16
  export { toOutlines } from './toOutlines.js'
18
17
  export { toPoints } from './toPoints.js'
19
18
  export { toSides } from './toSides.js'
20
19
  export { toString } from './toString.js'
21
- export { toCompactBinary } from './toCompactBinary.js'
22
20
  export { transform } from './transform.js'
23
21
  export { validate } from './validate.js'
@@ -1,6 +1,6 @@
1
1
  import test from 'ava'
2
2
 
3
- import { fromPoints } from './index.js'
3
+ import { fromVertices } from './index.js'
4
4
 
5
5
  import { applyTransforms } from './applyTransforms.js'
6
6
 
@@ -15,7 +15,7 @@ test('applyTransforms: Updates a geom3 with transformed polygons', (t) => {
15
15
  isRetesselated: false,
16
16
  transforms: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
17
17
  }
18
- const geometry = fromPoints(vertices)
18
+ const geometry = fromVertices(vertices)
19
19
  const updated = applyTransforms(geometry)
20
20
  t.is(geometry, updated)
21
21
  t.true(comparePolygons(updated.polygons[0], expected.polygons[0]))
@@ -1,6 +1,6 @@
1
1
  import test from 'ava'
2
2
 
3
- import { clone, create, fromPoints } from './index.js'
3
+ import { clone, create, fromVertices } from './index.js'
4
4
 
5
5
  import { comparePolygons, compareVectors } from '../../../test/helpers/index.js'
6
6
 
@@ -23,7 +23,7 @@ test('clone: Creates a clone of a populated geom3', (t) => {
23
23
  ],
24
24
  transforms: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
25
25
  }
26
- const geometry = fromPoints(vertices)
26
+ const geometry = fromVertices(vertices)
27
27
  const another = clone(geometry)
28
28
  t.not(another, geometry)
29
29
  t.true(comparePolygons(another.polygons[0], expected.polygons[0]))
@@ -24,12 +24,4 @@ import * as mat4 from '../../maths/mat4/index.js'
24
24
  * @returns {Geom3} a new geometry
25
25
  * @alias module:modeling/geometries/geom3.create
26
26
  */
27
- export const create = (polygons) => {
28
- if (polygons === undefined) {
29
- polygons = [] // empty contents
30
- }
31
- return {
32
- polygons,
33
- transforms: mat4.create()
34
- }
35
- }
27
+ export const create = (polygons = []) => ({ polygons, transforms: mat4.create() })
@@ -1,4 +1,4 @@
1
1
  import type { Geom3 } from './type.d.ts'
2
2
  import type { Vec3 } from '../../maths/vec3/type.d.ts'
3
3
 
4
- export function fromPoints(points: Array<Array<Vec3>>): Geom3
4
+ export function fromVertices(vertices: Array<Array<Vec3>>): Geom3
@@ -4,14 +4,15 @@ import { create } from './create.js'
4
4
 
5
5
  /**
6
6
  * Construct a new 3D geometry from a list of vertices.
7
+ *
7
8
  * The list of vertices should contain sub-arrays, each defining a single polygon of vertices.
8
9
  * In addition, the vertices should follow the right-hand rule for rotation in order to
9
10
  * define an external facing polygon.
10
11
  * @param {Array} listOfLists - list of lists, where each list is a set of vertices to construct a polygon
11
12
  * @returns {Geom3} a new geometry
12
- * @alias module:modeling/geometries/geom3.fromPoints
13
+ * @alias module:modeling/geometries/geom3.fromVertices
13
14
  */
14
- export const fromPoints = (listOfLists) => {
15
+ export const fromVertices = (listOfLists) => {
15
16
  if (!Array.isArray(listOfLists)) {
16
17
  throw new Error('the given vertices must be an array')
17
18
  }
@@ -1,10 +1,10 @@
1
1
  import test from 'ava'
2
2
 
3
- import { fromPoints } from './index.js'
3
+ import { fromVertices } from './index.js'
4
4
 
5
5
  import { comparePolygons, compareVectors } from '../../../test/helpers/index.js'
6
6
 
7
- test('fromPoints: Creates a populated geom3', (t) => {
7
+ test('fromVertices: Creates a populated geom3', (t) => {
8
8
  const vertices = [[[0, 0, 0], [1, 0, 0], [1, 0, 1]]]
9
9
  const expected = {
10
10
  polygons: [
@@ -13,12 +13,12 @@ test('fromPoints: Creates a populated geom3', (t) => {
13
13
  isRetesselated: false,
14
14
  transforms: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
15
15
  }
16
- const obs = fromPoints(vertices)
16
+ const obs = fromVertices(vertices)
17
17
  t.true(comparePolygons(obs.polygons[0], expected.polygons[0]))
18
18
  t.true(compareVectors(obs.transforms, expected.transforms))
19
19
  })
20
20
 
21
- test('fromPoints: throws for improper vertices', (t) => {
22
- t.throws(() => fromPoints(), { instanceOf: Error })
23
- t.throws(() => fromPoints(0, 0, 0), { instanceOf: Error })
21
+ test('fromVertices: throws for improper vertices', (t) => {
22
+ t.throws(() => fromVertices(), { instanceOf: Error })
23
+ t.throws(() => fromVertices(0, 0, 0), { instanceOf: Error })
24
24
  })
@@ -1,4 +1,4 @@
1
1
  import type { Geom3 } from './type.d.ts'
2
2
  import type { Vec3 } from '../../maths/vec3/type.d.ts'
3
3
 
4
- export function fromPointsConvex(points: Array<Array<Vec3>>): Geom3
4
+ export function fromVerticesConvex(vertices: Array<Array<Vec3>>): Geom3
@@ -0,0 +1,25 @@
1
+ import { runner } from '../../operations/hulls/quickhull/index.js'
2
+ import { create } from './create.js'
3
+ import * as poly3 from '../poly3/index.js'
4
+
5
+ /**
6
+ * Construct a new convex 3D geometry from a list of unique vertices.
7
+ *
8
+ * @param {Array} uniqueVertices - list of vertices to construct convex 3D geometry
9
+ * @returns {geom3} a new geometry
10
+ * @alias module:modeling/geometries/geom3.fromVerticesConvex
11
+ */
12
+ export const fromVerticesConvex = (uniqueVertices) => {
13
+ if (!Array.isArray(uniqueVertices)) {
14
+ throw new Error('the given vertices must be an array')
15
+ }
16
+
17
+ const faces = runner(uniqueVertices, { skipTriangulation: true })
18
+
19
+ const polygons = faces.map((face) => {
20
+ const vertices = face.map((index) => uniqueVertices[index])
21
+ return poly3.create(vertices)
22
+ })
23
+
24
+ return create(polygons)
25
+ }
@@ -1,8 +1,8 @@
1
1
  import test from 'ava'
2
2
 
3
- import { fromPointsConvex, validate } from './index.js'
3
+ import { fromVerticesConvex, validate } from './index.js'
4
4
 
5
- test('fromPointsConvex (uniquePoints)', (t) => {
5
+ test('fromVerticesConvex (uniqueVertices)', (t) => {
6
6
  const out = []
7
7
  for (let x = -9; x <= 9; ++x) {
8
8
  for (let y = -9; y <= 9; ++y) {
@@ -14,7 +14,7 @@ test('fromPointsConvex (uniquePoints)', (t) => {
14
14
  }
15
15
  }
16
16
 
17
- const obs = fromPointsConvex(out)
17
+ const obs = fromVerticesConvex(out)
18
18
  validate(obs)
19
19
  t.is(obs.polygons.length, 170)
20
20
  t.true(obs.polygons.every((f) => ([3, 4, 8, 9].indexOf(f.vertices.length) !== -1)))
@@ -1,14 +1,12 @@
1
1
  export { clone } from './clone.js'
2
2
  export { create } from './create.js'
3
- export { fromPoints } from './fromPoints.js'
4
- export { fromPointsConvex } from './fromPointsConvex.js'
5
- export { fromCompactBinary } from './fromCompactBinary.js'
3
+ export { fromVertices } from './fromVertices.js'
4
+ export { fromVerticesConvex } from './fromVerticesConvex.js'
6
5
  export { invert } from './invert.js'
7
6
  export { isA } from './isA.js'
8
- export { toPoints } from './toPoints.js'
9
7
  export { toPolygons } from './toPolygons.js'
10
8
  export { toString } from './toString.js'
11
- export { toCompactBinary } from './toCompactBinary.js'
9
+ export { toVertices } from './toVertices.js'
12
10
  export { transform } from './transform.js'
13
11
  export { validate } from './validate.js'
14
12
 
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * @example
7
7
  * import { geometries } from '@jscad/modeling'
8
- * const myShape = geometries.geom3.fromPoints([
8
+ * const myShape = geometries.geom3.fromVertices([
9
9
  * [[-1,-1,-1], [-1,-1,1], [-1,1,1], [-1,1,-1]],
10
10
  * [[1,-1,-1], [1,1,-1], [1,1,1], [1,-1,1]],
11
11
  * [[-1,-1,-1], [1,-1,-1], [1,-1,1], [-1,-1,1]]
@@ -16,14 +16,12 @@
16
16
  */
17
17
  export { clone } from './clone.js'
18
18
  export { create } from './create.js'
19
- export { fromPoints } from './fromPoints.js'
20
- export { fromPointsConvex } from './fromPointsConvex.js'
21
- export { fromCompactBinary } from './fromCompactBinary.js'
19
+ export { fromVertices } from './fromVertices.js'
20
+ export { fromVerticesConvex } from './fromVerticesConvex.js'
22
21
  export { invert } from './invert.js'
23
22
  export { isA } from './isA.js'
24
- export { toPoints } from './toPoints.js'
25
23
  export { toPolygons } from './toPolygons.js'
26
24
  export { toString } from './toString.js'
27
- export { toCompactBinary } from './toCompactBinary.js'
25
+ export { toVertices } from './toVertices.js'
28
26
  export { transform } from './transform.js'
29
27
  export { validate } from './validate.js'
@@ -1,6 +1,6 @@
1
1
  import test from 'ava'
2
2
 
3
- import { invert, create, fromPoints } from './index.js'
3
+ import { invert, create, fromVertices } from './index.js'
4
4
 
5
5
  import { comparePolygons, compareVectors } from '../../../test/helpers/index.js'
6
6
 
@@ -23,7 +23,7 @@ test('invert: Creates a invert of a populated geom3', (t) => {
23
23
  ],
24
24
  transforms: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
25
25
  }
26
- const geometry = fromPoints(vertices)
26
+ const geometry = fromVertices(vertices)
27
27
  const another = invert(geometry)
28
28
  t.not(another, geometry)
29
29
  t.true(comparePolygons(another.polygons[0], expected.polygons[0]))
@@ -1,10 +1,10 @@
1
1
  import test from 'ava'
2
2
 
3
- import { isA, create, fromPoints } from './index.js'
3
+ import { isA, create, fromVertices } from './index.js'
4
4
 
5
5
  test('isA: identifies created geom3', (t) => {
6
6
  const p1 = create()
7
- const p2 = fromPoints([[[0, 0, 0], [1, 0, 0], [1, 0, 1]]])
7
+ const p2 = fromVertices([[[0, 0, 0], [1, 0, 0], [1, 0, 1]]])
8
8
  t.true(isA(p1))
9
9
  t.true(isA(p2))
10
10
  })
@@ -1,6 +1,6 @@
1
1
  import test from 'ava'
2
2
 
3
- import { create, fromPoints, toString } from './index.js'
3
+ import { create, fromVertices, toString } from './index.js'
4
4
 
5
5
  test('toString: serialize empty geom3 into a string', (t) => {
6
6
  const geometry = create()
@@ -10,7 +10,7 @@ test('toString: serialize empty geom3 into a string', (t) => {
10
10
  })
11
11
 
12
12
  test('toString: serialize geom3 into a string', (t) => {
13
- const geometry = fromPoints([[[0, 0, 3], [0, 1, 3], [2, 0, 3]]])
13
+ const geometry = fromVertices([[[0, 0, 3], [0, 1, 3], [2, 0, 3]]])
14
14
  const result = toString(geometry)
15
15
  const expected = 'geom3 (1 polygons):\n poly3: [[0.0000000, 0.0000000, 3.0000000], [0.0000000, 1.0000000, 3.0000000], [2.0000000, 0.0000000, 3.0000000]]\n'
16
16
  t.is(result, expected)
@@ -1,4 +1,4 @@
1
1
  import type { Geom3 } from './type.d.ts'
2
2
  import type { Vec3 } from '../../maths/vec3/type.d.ts'
3
3
 
4
- export function toPoints(geometry: Geom3): Array<Array<Vec3>>
4
+ export function toVertices(geometry: Geom3): Array<Array<Vec3>>
@@ -4,12 +4,13 @@ import { toPolygons } from './toPolygons.js'
4
4
 
5
5
  /**
6
6
  * Return the given geometry as a list of points, after applying transforms.
7
+ *
7
8
  * The returned array should not be modified as the points are shared with the geometry.
8
9
  * @param {Geom3} geometry - the geometry
9
10
  * @return {Array} list of points, where each sub-array represents a polygon
10
- * @alias module:modeling/geometries/geom3.toPoints
11
+ * @alias module:modeling/geometries/geom3.toVertices
11
12
  */
12
- export const toPoints = (geometry) => {
13
+ export const toVertices = (geometry) => {
13
14
  const polygons = toPolygons(geometry)
14
15
  return polygons.map((polygon) => poly3.toVertices(polygon))
15
16
  }
@@ -1,17 +1,17 @@
1
1
  import test from 'ava'
2
2
 
3
- import { toPoints, fromPoints, toString } from './index.js'
3
+ import { toVertices, fromVertices, toString } from './index.js'
4
4
 
5
5
  import { comparePolygonsAsPoints } from '../../../test/helpers/index.js'
6
6
 
7
- test('toPoints: Creates an array of vertices from a populated geom3', (t) => {
7
+ test('toVertices: Creates an array of vertices from a populated geom3', (t) => {
8
8
  const vertices = [[[0, 0, 0], [1, 0, 0], [1, 0, 1]]]
9
- const geometry = fromPoints(vertices)
9
+ const geometry = fromVertices(vertices)
10
10
 
11
11
  toString(geometry)
12
12
 
13
13
  const expected = [[[0, 0, 0], [1, 0, 0], [1, 0, 1]]]
14
- const vertexList = toPoints(geometry)
14
+ const vertexList = toVertices(geometry)
15
15
  t.deepEqual(vertexList, expected)
16
16
  t.true(comparePolygonsAsPoints(vertexList, expected))
17
17
 
@@ -2,7 +2,7 @@ import test from 'ava'
2
2
 
3
3
  import { mat4 } from '../../maths/index.js'
4
4
 
5
- import { transform, fromPoints, toPolygons } from './index.js'
5
+ import { transform, fromVertices, toPolygons } from './index.js'
6
6
 
7
7
  import { comparePolygons, compareVectors } from '../../../test/helpers/index.js'
8
8
 
@@ -20,7 +20,7 @@ test('transform: Adjusts the transforms of a populated geom3', (t) => {
20
20
  ],
21
21
  transforms: [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
22
22
  }
23
- const geometry = fromPoints(vertices)
23
+ const geometry = fromVertices(vertices)
24
24
  let another = transform(rotate90, geometry)
25
25
  t.not(geometry, another)
26
26
  t.true(comparePolygons(another.polygons[0], expected.polygons[0]))
@@ -1,7 +1,7 @@
1
1
  import test from 'ava'
2
2
 
3
3
  import * as vec3 from '../../maths/vec3/index.js'
4
- import { fromPoints, validate } from './index.js'
4
+ import { fromVertices, validate } from './index.js'
5
5
 
6
6
  // tetrahedron
7
7
  const a = vec3.fromValues(-1, -1, 1)
@@ -11,16 +11,16 @@ const d = vec3.fromValues(1, 1, 1)
11
11
 
12
12
  test('validate: allow valid geom3', (t) => {
13
13
  // simplest valid geometry
14
- const geometry = fromPoints([[a, b, c], [d, b, a], [d, a, c], [c, b, d]])
14
+ const geometry = fromVertices([[a, b, c], [d, b, a], [d, a, c], [c, b, d]])
15
15
  t.notThrows(() => validate(geometry))
16
16
  })
17
17
 
18
18
  test('validate: throw exception for nan', (t) => {
19
- const geometry = fromPoints([[a, b, c], [d, b, a], [d, a, c], [c, b, [1, 1, NaN]]])
19
+ const geometry = fromVertices([[a, b, c], [d, b, a], [d, a, c], [c, b, [1, 1, NaN]]])
20
20
  t.throws(() => validate(geometry))
21
21
  })
22
22
 
23
23
  test('validate: throw exception for infinity', (t) => {
24
- const geometry = fromPoints([[a, b, c], [d, b, a], [d, a, c], [c, b, [1, 1, Infinity]]])
24
+ const geometry = fromVertices([[a, b, c], [d, b, a], [d, a, c], [c, b, [1, 1, Infinity]]])
25
25
  t.throws(() => validate(geometry))
26
26
  })
@@ -1,6 +1,7 @@
1
1
  export * as geom2 from './geom2/index.js'
2
2
  export * as geom3 from './geom3/index.js'
3
3
  export * as path2 from './path2/index.js'
4
+ export * as path3 from './path3/index.js'
4
5
  export * as poly2 from './poly2/index.js'
5
6
  export * as poly3 from './poly3/index.js'
6
7
  export * as slice from './slice/index.js'
@@ -16,6 +16,7 @@
16
16
  export * as geom2 from './geom2/index.js'
17
17
  export * as geom3 from './geom3/index.js'
18
18
  export * as path2 from './path2/index.js'
19
+ export * as path3 from './path3/index.js'
19
20
  export * as poly2 from './poly2/index.js'
20
21
  export * as poly3 from './poly3/index.js'
21
22
  export * as slice from './slice/index.js'
@@ -21,13 +21,4 @@ import * as mat4 from '../../maths/mat4/index.js'
21
21
  * @example
22
22
  * let newPath = create()
23
23
  */
24
- export const create = (points) => {
25
- if (points === undefined) {
26
- points = []
27
- }
28
- return {
29
- points: points,
30
- isClosed: false,
31
- transforms: mat4.create()
32
- }
33
- }
24
+ export const create = (points = []) => ({ points: points, isClosed: false, transforms: mat4.create() })
@@ -7,12 +7,10 @@ export { concat } from './concat.js'
7
7
  export { create } from './create.js'
8
8
  export { equals } from './equals.js'
9
9
  export { fromPoints, FromPointsOptions } from './fromPoints.js'
10
- export { fromCompactBinary } from './fromCompactBinary.js'
11
10
  export { isA } from './isA.js'
12
11
  export { reverse } from './reverse.js'
13
12
  export { toPoints } from './toPoints.js'
14
13
  export { toString } from './toString.js'
15
- export { toCompactBinary } from './toCompactBinary.js'
16
14
  export { transform } from './transform.js'
17
15
  export { validate } from './validate.js'
18
16
 
@@ -16,11 +16,9 @@ export { concat } from './concat.js'
16
16
  export { create } from './create.js'
17
17
  export { equals } from './equals.js'
18
18
  export { fromPoints } from './fromPoints.js'
19
- export { fromCompactBinary } from './fromCompactBinary.js'
20
19
  export { isA } from './isA.js'
21
20
  export { reverse } from './reverse.js'
22
21
  export { toPoints } from './toPoints.js'
23
22
  export { toString } from './toString.js'
24
- export { toCompactBinary } from './toCompactBinary.js'
25
23
  export { transform } from './transform.js'
26
24
  export { validate } from './validate.js'
@@ -0,0 +1,22 @@
1
+ import * as mat4 from '../../maths/mat4/index.js'
2
+ import * as vec3 from '../../maths/vec3/index.js'
3
+
4
+ /*
5
+ * Apply the transforms of the given geometry.
6
+ *
7
+ * NOTE: This function must be called BEFORE exposing any data. See toVertices.
8
+ *
9
+ * @param {Path3} geometry - the geometry to transform
10
+ * @returns {Path3} the given geometry
11
+ * @function
12
+ *
13
+ * @example
14
+ * geometry = applyTransforms(geometry)
15
+ */
16
+ export const applyTransforms = (geometry) => {
17
+ if (mat4.isIdentity(geometry.transforms)) return geometry
18
+
19
+ geometry.vertices = geometry.vertices.map((vertex) => vec3.transform(vec3.create(), vertex, geometry.transforms))
20
+ geometry.transforms = mat4.create()
21
+ return geometry
22
+ }
@@ -0,0 +1,28 @@
1
+ import test from 'ava'
2
+
3
+ import { fromVertices } from './index.js'
4
+
5
+ import { applyTransforms } from './applyTransforms.js'
6
+
7
+ import { comparePoints, compareVectors } from '../../../test/helpers/index.js'
8
+
9
+ test('applyTransforms: Updates a populated path with transformed points', (t) => {
10
+ const vertices = [[0, 0, 0], [1, 0, 0], [0, 1, 0]]
11
+ const expected = {
12
+ vertices: [[0, 0, 0], [1, 0, 0], [0, 1, 0]],
13
+ isClosed: false,
14
+ transforms: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
15
+ }
16
+ const geometry = fromVertices({}, vertices)
17
+ const updated = applyTransforms(geometry)
18
+ t.is(geometry, updated)
19
+ t.true(comparePoints(updated.vertices, expected.vertices))
20
+ t.false(updated.isClosed)
21
+ t.true(compareVectors(updated.transforms, expected.transforms))
22
+
23
+ const updated2 = applyTransforms(updated)
24
+ t.is(updated, updated2)
25
+ t.true(comparePoints(updated2.vertices, expected.vertices))
26
+ t.false(updated2.isClosed)
27
+ t.true(compareVectors(updated2.transforms, expected.transforms))
28
+ })
@@ -0,0 +1,3 @@
1
+ import type { Path3 } from './type.d.ts'
2
+
3
+ export function close(geometry: Path3): Path3
@@ -0,0 +1,31 @@
1
+ import { EPS } from '../../maths/constants.js'
2
+
3
+ import * as vec3 from '../../maths/vec3/index.js'
4
+
5
+ /**
6
+ * Close the given geometry.
7
+ *
8
+ * @param {Path3} geometry - the path to close
9
+ * @returns {Path3} a new path
10
+ * @function
11
+ * @alias module:modeling/geometries/path3.close
12
+ */
13
+ export const close = (geometry) => {
14
+ if (geometry.isClosed) return geometry
15
+
16
+ const cloned = Object.assign({}, geometry)
17
+ cloned.isClosed = true
18
+
19
+ if (cloned.vertices.length > 1) {
20
+ // make sure the paths are formed properly
21
+ const vertices = cloned.vertices
22
+ const p0 = vertices[0]
23
+ let pn = vertices[vertices.length - 1]
24
+ while (vec3.distance(p0, pn) < (EPS * EPS)) {
25
+ vertices.pop()
26
+ if (vertices.length === 1) break
27
+ pn = vertices[vertices.length - 1]
28
+ }
29
+ }
30
+ return cloned
31
+ }
@@ -0,0 +1,43 @@
1
+ import test from 'ava'
2
+
3
+ import { close, create, fromVertices } from './index.js'
4
+
5
+ test('close: closes an empty path', (t) => {
6
+ const p1 = create()
7
+ t.false(p1.isClosed)
8
+
9
+ const p2 = close(p1)
10
+ t.true(p2.isClosed)
11
+ t.not(p1, p2)
12
+
13
+ const p3 = close(p2)
14
+ t.true(p3.isClosed)
15
+ t.is(p2, p3)
16
+ })
17
+
18
+ test('close: closes various paths', (t) => {
19
+ let p1 = create()
20
+ p1 = close(p1)
21
+ t.true(p1.isClosed)
22
+ t.is(0, p1.vertices.length)
23
+
24
+ let p2 = fromVertices({ closed: false }, [])
25
+ p2 = close(p2)
26
+ t.true(p2.isClosed)
27
+ t.is(0, p2.vertices.length)
28
+
29
+ let p3 = fromVertices({ closed: true }, [[0, 0, 0]])
30
+ p3 = close(p3)
31
+ t.true(p3.isClosed)
32
+ t.is(1, p3.vertices.length)
33
+
34
+ let p4 = fromVertices({ closed: true }, [[0, 0, 0], [0, 0, 0]])
35
+ p4 = close(p4)
36
+ t.true(p4.isClosed)
37
+ t.is(1, p4.vertices.length) // the last point is removed
38
+
39
+ let p5 = fromVertices({ closed: true }, [[0, 0, 0], [1, 1, 0], [0, 0, 0]])
40
+ p5 = close(p5)
41
+ t.true(p5.isClosed)
42
+ t.is(2, p5.vertices.length) // the last point is removed
43
+ })
@@ -0,0 +1,3 @@
1
+ import type { Path3 } from './type.d.ts'
2
+
3
+ export function concat(...paths: Array<Path3>): Path3
@@ -0,0 +1,36 @@
1
+ import { equals } from '../../maths/vec3/index.js'
2
+
3
+ import { fromVertices } from './fromVertices.js'
4
+ import { toVertices } from './toVertices.js'
5
+
6
+ /**
7
+ * Concatenate the given paths.
8
+ *
9
+ * If both contain the same vertex at the junction, merge it into one.
10
+ * A concatenation of zero paths is an empty, open path.
11
+ * A concatenation of one closed path to a series of open paths produces a closed path.
12
+ * A concatenation of a path to a closed path is an error.
13
+ *
14
+ * @param {...Path3} paths - the paths to concatenate
15
+ * @returns {Path3} a new path
16
+ * @function
17
+ * @alias module:modeling/geometries/path3.concat
18
+ *
19
+ * @example
20
+ * let newPath = concat(fromVertices({}, [[1, 2, 3]]), fromVertices({}, [[4, 5, 6]]))
21
+ */
22
+ export const concat = (...paths) => {
23
+ // Only the last path can be closed, producing a closed path.
24
+ let isClosed = false
25
+ let vertices = []
26
+ paths.forEach((path, i) => {
27
+ const tmp = toVertices(path).slice()
28
+ if (vertices.length > 0 && tmp.length > 0 && equals(tmp[0], vertices[vertices.length - 1])) tmp.shift()
29
+ if (tmp.length > 0 && isClosed) {
30
+ throw new Error(`Cannot concatenate to a closed path; check the ${i}th path`)
31
+ }
32
+ isClosed = path.isClosed
33
+ vertices = vertices.concat(tmp)
34
+ })
35
+ return fromVertices({ closed: isClosed }, vertices)
36
+ }