@jscad/modeling 3.0.3-alpha.0 → 3.0.5-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 (214) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/jscad-modeling.es.js +2 -7
  3. package/dist/jscad-modeling.min.js +2 -7
  4. package/package.json +8 -9
  5. package/rollup.config.js +8 -4
  6. package/src/colors/colorize.js +17 -1
  7. package/src/curves/bezier/arcLengthToT.js +1 -1
  8. package/src/curves/bezier/create.js +1 -1
  9. package/src/curves/bezier/index.js +7 -7
  10. package/src/curves/bezier/length.js +1 -1
  11. package/src/curves/bezier/lengths.js +2 -1
  12. package/src/curves/bezier/tangentAt.js +1 -1
  13. package/src/curves/bezier/valueAt.js +1 -1
  14. package/src/curves/index.js +3 -3
  15. package/src/geometries/geom2/applyTransforms.js +3 -1
  16. package/src/geometries/geom2/clone.js +5 -1
  17. package/src/geometries/geom2/create.js +4 -14
  18. package/src/geometries/geom2/fromPoints.d.ts +4 -0
  19. package/src/geometries/geom2/fromPoints.js +28 -0
  20. package/src/geometries/geom2/fromPoints.test.js +22 -0
  21. package/src/geometries/geom2/fromSides.js +4 -2
  22. package/src/geometries/geom2/index.d.ts +1 -0
  23. package/src/geometries/geom2/index.js +22 -5
  24. package/src/geometries/geom2/isA.js +5 -1
  25. package/src/geometries/geom2/reverse.js +4 -2
  26. package/src/geometries/geom2/toOutlines.js +2 -1
  27. package/src/geometries/geom2/toPoints.js +5 -2
  28. package/src/geometries/geom2/toSides.js +4 -3
  29. package/src/geometries/geom2/toString.js +3 -2
  30. package/src/geometries/geom2/transform.js +4 -2
  31. package/src/geometries/geom2/validate.js +6 -2
  32. package/src/geometries/geom3/clone.js +5 -1
  33. package/src/geometries/geom3/create.js +5 -19
  34. package/src/geometries/geom3/fromVertices.js +13 -1
  35. package/src/geometries/geom3/fromVerticesConvex.js +1 -1
  36. package/src/geometries/geom3/index.d.ts +1 -0
  37. package/src/geometries/geom3/index.js +26 -4
  38. package/src/geometries/geom3/invert.js +5 -1
  39. package/src/geometries/geom3/isA.js +5 -1
  40. package/src/geometries/geom3/isConvex.d.ts +3 -0
  41. package/src/geometries/geom3/isConvex.js +65 -0
  42. package/src/geometries/geom3/isConvex.test.js +44 -0
  43. package/src/geometries/geom3/toPolygons.js +4 -2
  44. package/src/geometries/geom3/toString.js +3 -2
  45. package/src/geometries/geom3/toVertices.js +8 -4
  46. package/src/geometries/geom3/transform.js +5 -2
  47. package/src/geometries/geom3/validate.js +6 -2
  48. package/src/geometries/index.js +9 -7
  49. package/src/geometries/path2/appendArc.js +7 -5
  50. package/src/geometries/path2/appendArc.test.js +11 -15
  51. package/src/geometries/path2/appendBezier.js +6 -4
  52. package/src/geometries/path2/appendPoints.js +4 -2
  53. package/src/geometries/path2/applyTransforms.js +3 -0
  54. package/src/geometries/path2/clone.js +5 -1
  55. package/src/geometries/path2/close.js +5 -1
  56. package/src/geometries/path2/concat.js +3 -2
  57. package/src/geometries/path2/create.js +4 -15
  58. package/src/geometries/path2/equals.js +12 -7
  59. package/src/geometries/path2/fromPoints.js +5 -3
  60. package/src/geometries/path2/index.js +21 -4
  61. package/src/geometries/path2/isA.js +5 -1
  62. package/src/geometries/path2/reverse.js +4 -2
  63. package/src/geometries/path2/toPoints.js +5 -3
  64. package/src/geometries/path2/toString.js +3 -2
  65. package/src/geometries/path2/transform.js +4 -2
  66. package/src/geometries/path2/validate.js +5 -1
  67. package/src/geometries/path3/applyTransforms.js +1 -1
  68. package/src/geometries/path3/clone.d.ts +3 -0
  69. package/src/geometries/path3/clone.js +11 -0
  70. package/src/geometries/path3/close.js +4 -2
  71. package/src/geometries/path3/concat.js +2 -3
  72. package/src/geometries/path3/create.js +4 -20
  73. package/src/geometries/path3/equals.js +4 -2
  74. package/src/geometries/path3/fromVertices.js +2 -3
  75. package/src/geometries/path3/index.d.ts +1 -0
  76. package/src/geometries/path3/index.js +18 -1
  77. package/src/geometries/path3/isA.js +4 -2
  78. package/src/geometries/path3/reverse.js +2 -3
  79. package/src/geometries/path3/toString.js +2 -3
  80. package/src/geometries/path3/toVertices.js +2 -3
  81. package/src/geometries/path3/transform.js +2 -3
  82. package/src/geometries/path3/validate.js +6 -3
  83. package/src/geometries/poly2/arePointsInside.js +4 -1
  84. package/src/geometries/poly2/clone.js +4 -1
  85. package/src/geometries/poly2/create.js +2 -9
  86. package/src/geometries/poly2/index.js +16 -4
  87. package/src/geometries/poly2/isA.js +5 -1
  88. package/src/geometries/poly2/isConvex.js +5 -1
  89. package/src/geometries/poly2/isSimple.js +5 -1
  90. package/src/geometries/poly2/measureArea.js +4 -1
  91. package/src/geometries/poly2/measureBoundingBox.js +6 -1
  92. package/src/geometries/poly2/reverse.js +4 -1
  93. package/src/geometries/poly2/toPoints.js +6 -1
  94. package/src/geometries/poly2/toString.js +5 -1
  95. package/src/geometries/poly2/transform.js +5 -1
  96. package/src/geometries/poly2/type.d.ts +1 -5
  97. package/src/geometries/poly2/validate.js +6 -2
  98. package/src/geometries/poly3/clone.js +4 -1
  99. package/src/geometries/poly3/create.js +3 -11
  100. package/src/geometries/poly3/fromVerticesAndPlane.js +3 -1
  101. package/src/geometries/poly3/index.js +19 -4
  102. package/src/geometries/poly3/invert.js +4 -1
  103. package/src/geometries/poly3/isA.js +5 -1
  104. package/src/geometries/poly3/isConvex.js +5 -1
  105. package/src/geometries/poly3/measureArea.js +5 -1
  106. package/src/geometries/poly3/measureBoundingBox.js +4 -1
  107. package/src/geometries/poly3/measureBoundingSphere.js +4 -3
  108. package/src/geometries/poly3/measureSignedVolume.js +6 -1
  109. package/src/geometries/poly3/plane.js +6 -0
  110. package/src/geometries/poly3/toString.js +5 -1
  111. package/src/geometries/poly3/toVertices.js +6 -1
  112. package/src/geometries/poly3/transform.js +5 -1
  113. package/src/geometries/poly3/validate.js +6 -2
  114. package/src/geometries/slice/calculatePlane.js +3 -3
  115. package/src/geometries/slice/clone.js +4 -1
  116. package/src/geometries/slice/create.js +5 -10
  117. package/src/geometries/slice/equals.js +5 -1
  118. package/src/geometries/slice/fromOutlines.d.ts +5 -0
  119. package/src/geometries/slice/fromOutlines.js +16 -0
  120. package/src/geometries/slice/fromOutlines.test.js +17 -0
  121. package/src/geometries/slice/fromVertices.js +3 -3
  122. package/src/geometries/slice/index.d.ts +1 -1
  123. package/src/geometries/slice/index.js +20 -5
  124. package/src/geometries/slice/isA.js +5 -1
  125. package/src/geometries/slice/reverse.js +5 -2
  126. package/src/geometries/slice/toEdges.js +5 -3
  127. package/src/geometries/slice/toPolygons.js +5 -1
  128. package/src/geometries/slice/toString.js +5 -1
  129. package/src/geometries/slice/toVertices.js +5 -3
  130. package/src/geometries/slice/transform.js +4 -3
  131. package/src/geometries/slice/validate.js +3 -2
  132. package/src/index.d.ts +1 -0
  133. package/src/index.js +4 -0
  134. package/src/maths/constants.js +11 -7
  135. package/src/maths/index.js +2 -1
  136. package/src/maths/mat4/isOnlyTransformScale.js +1 -1
  137. package/src/maths/plane/fromNormalAndPoint.js +4 -6
  138. package/src/maths/plane/fromPoints.js +8 -7
  139. package/src/maths/plane/fromPointsRandom.js +13 -13
  140. package/src/measurements/measureAggregateEpsilon.js +3 -1
  141. package/src/measurements/measureAggregateEpsilon.test.js +1 -1
  142. package/src/measurements/measureArea.js +6 -4
  143. package/src/measurements/measureArea.test.js +4 -1
  144. package/src/measurements/measureBoundingBox.js +16 -2
  145. package/src/measurements/measureBoundingBox.test.js +4 -1
  146. package/src/measurements/measureBoundingSphere.js +38 -29
  147. package/src/measurements/measureBoundingSphere.test.js +4 -1
  148. package/src/measurements/measureCenterOfMass.js +3 -2
  149. package/src/measurements/measureEpsilon.js +4 -2
  150. package/src/operations/booleans/index.js +2 -0
  151. package/src/operations/booleans/intersect.js +0 -1
  152. package/src/operations/booleans/scission.js +0 -1
  153. package/src/operations/booleans/trees/splitLineSegmentByPlane.js +1 -4
  154. package/src/operations/booleans/trees/splitPolygonByPlane.d.ts +1 -3
  155. package/src/operations/booleans/trees/splitPolygonByPlane.test.js +138 -0
  156. package/src/operations/booleans/union.js +1 -1
  157. package/src/operations/booleans/unionGeom3.test.js +35 -0
  158. package/src/operations/extrusions/extrudeFromSlices.js +16 -6
  159. package/src/operations/extrusions/extrudeFromSlices.test.js +1 -1
  160. package/src/operations/extrusions/extrudeHelical.js +2 -1
  161. package/src/operations/extrusions/extrudeLinear.js +1 -1
  162. package/src/operations/extrusions/extrudeLinearGeom2.js +2 -1
  163. package/src/operations/extrusions/extrudeRotate.js +3 -2
  164. package/src/operations/extrusions/extrudeRotate.test.js +34 -0
  165. package/src/operations/extrusions/extrudeWalls.test.js +60 -0
  166. package/src/operations/hulls/hull.js +3 -2
  167. package/src/operations/hulls/toUniquePoints.js +3 -0
  168. package/src/operations/minkowski/index.d.ts +1 -0
  169. package/src/operations/minkowski/index.js +15 -0
  170. package/src/operations/minkowski/minkowskiSum.d.ts +4 -0
  171. package/src/operations/minkowski/minkowskiSum.js +223 -0
  172. package/src/operations/minkowski/minkowskiSum.test.js +199 -0
  173. package/src/operations/modifiers/generalize.js +9 -2
  174. package/src/operations/modifiers/reTesselateCoplanarPolygons.js +10 -3
  175. package/src/operations/modifiers/reTesselateCoplanarPolygons.test.js +36 -1
  176. package/src/operations/modifiers/retessellate.js +4 -2
  177. package/src/operations/modifiers/snap.js +22 -3
  178. package/src/operations/modifiers/snap.test.js +24 -15
  179. package/src/operations/offsets/offsetGeom3.test.js +5 -7
  180. package/src/operations/transforms/align.js +2 -1
  181. package/src/operations/transforms/align.test.js +1 -1
  182. package/src/operations/transforms/mirror.js +6 -2
  183. package/src/operations/transforms/rotate.js +6 -2
  184. package/src/operations/transforms/scale.js +6 -2
  185. package/src/operations/transforms/transform.js +6 -2
  186. package/src/operations/transforms/transform.test.js +16 -5
  187. package/src/operations/transforms/translate.js +6 -2
  188. package/src/primitives/arc.js +13 -12
  189. package/src/primitives/arc.test.js +104 -113
  190. package/src/primitives/circle.js +10 -9
  191. package/src/primitives/cube.js +5 -6
  192. package/src/primitives/cuboid.js +6 -6
  193. package/src/primitives/cylinder.js +8 -8
  194. package/src/primitives/cylinderElliptic.js +11 -11
  195. package/src/primitives/ellipse.js +10 -9
  196. package/src/primitives/ellipsoid.js +8 -8
  197. package/src/primitives/geodesicSphere.js +6 -6
  198. package/src/primitives/line.js +2 -0
  199. package/src/primitives/polygon.js +6 -7
  200. package/src/primitives/polyhedron.js +7 -8
  201. package/src/primitives/rectangle.js +6 -6
  202. package/src/primitives/roundedCuboid.js +8 -8
  203. package/src/primitives/roundedCylinder.js +9 -9
  204. package/src/primitives/roundedRectangle.js +8 -8
  205. package/src/primitives/sphere.js +7 -8
  206. package/src/primitives/square.js +6 -6
  207. package/src/primitives/star.js +10 -10
  208. package/src/primitives/torus.js +11 -11
  209. package/src/primitives/triangle.js +7 -6
  210. package/src/utils/areAllShapesTheSameType.js +4 -0
  211. package/src/utils/flatten.js +1 -1
  212. package/src/utils/flatten.test.js +94 -0
  213. package/src/geometries/slice/fromGeom2.d.ts +0 -5
  214. package/src/geometries/slice/fromGeom2.js +0 -17
@@ -6,6 +6,7 @@ import { isNumberArray } from './commonChecks.js'
6
6
 
7
7
  /**
8
8
  * Construct an axis-aligned rectangle in two dimensional space with four sides at right angles.
9
+ *
9
10
  * @param {object} [options] - options for construction
10
11
  * @param {Array} [options.center=[0,0]] - center of rectangle
11
12
  * @param {Array} [options.size=[2,2]] - dimension of rectangle, width and length
@@ -15,12 +16,11 @@ import { isNumberArray } from './commonChecks.js'
15
16
  * @example
16
17
  * let myshape = rectangle({size: [10, 20]})
17
18
  */
18
- export const rectangle = (options) => {
19
- const defaults = {
20
- center: [0, 0],
21
- size: [2, 2]
22
- }
23
- const { center, size } = Object.assign({}, defaults, options)
19
+ export const rectangle = (options = {}) => {
20
+ const {
21
+ center = [0, 0],
22
+ size = [2, 2]
23
+ } = options
24
24
 
25
25
  if (!isNumberArray(center, 2)) throw new Error('center must be an array of X and Y values')
26
26
  if (!isNumberArray(size, 2)) throw new Error('size must be an array of X and Y values')
@@ -115,6 +115,7 @@ const stitchSides = (bottomCorners, topCorners) => {
115
115
 
116
116
  /**
117
117
  * Construct an axis-aligned solid cuboid in three dimensional space with rounded corners.
118
+ *
118
119
  * @param {object} [options] - options for construction
119
120
  * @param {Array} [options.center=[0,0,0]] - center of rounded cube
120
121
  * @param {Array} [options.size=[2,2,2]] - dimension of rounded cube; width, depth, height
@@ -126,14 +127,13 @@ const stitchSides = (bottomCorners, topCorners) => {
126
127
  * @example
127
128
  * let myCube = roundedCuboid({size: [10, 20, 10], roundRadius: 2, segments: 16})
128
129
  */
129
- export const roundedCuboid = (options) => {
130
- const defaults = {
131
- center: [0, 0, 0],
132
- size: [2, 2, 2],
133
- roundRadius: 0.2,
134
- segments: 32
135
- }
136
- let { center, size, roundRadius, segments } = Object.assign({}, defaults, options)
130
+ export const roundedCuboid = (options = {}) => {
131
+ let {
132
+ center = [0, 0, 0],
133
+ size = [2, 2, 2],
134
+ roundRadius = 0.2,
135
+ segments = 32
136
+ } = options
137
137
 
138
138
  if (!isNumberArray(center, 3)) throw new Error('center must be an array of X, Y and Z values')
139
139
  if (!isNumberArray(size, 3)) throw new Error('size must be an array of X, Y and Z values')
@@ -12,6 +12,7 @@ import { cylinder } from './cylinder.js'
12
12
 
13
13
  /**
14
14
  * Construct a Z axis-aligned solid cylinder in three dimensional space with rounded ends.
15
+ *
15
16
  * @param {object} [options] - options for construction
16
17
  * @param {Array} [options.center=[0,0,0]] - center of cylinder
17
18
  * @param {number} [options.height=2] - height of cylinder
@@ -24,15 +25,14 @@ import { cylinder } from './cylinder.js'
24
25
  * @example
25
26
  * let myshape = roundedCylinder({ height: 10, radius: 2, roundRadius: 0.5 })
26
27
  */
27
- export const roundedCylinder = (options) => {
28
- const defaults = {
29
- center: [0, 0, 0],
30
- height: 2,
31
- radius: 1,
32
- roundRadius: 0.2,
33
- segments: 32
34
- }
35
- const { center, height, radius, roundRadius, segments } = Object.assign({}, defaults, options)
28
+ export const roundedCylinder = (options = {}) => {
29
+ const {
30
+ center = [0, 0, 0],
31
+ height = 2,
32
+ radius = 1,
33
+ roundRadius = 0.2,
34
+ segments = 32
35
+ } = options
36
36
 
37
37
  if (!isNumberArray(center, 3)) throw new Error('center must be an array of X, Y and Z values')
38
38
  if (!isGTE(height, 0)) throw new Error('height must be positive')
@@ -10,6 +10,7 @@ import { rectangle } from './rectangle.js'
10
10
 
11
11
  /**
12
12
  * Construct an axis-aligned rectangle in two dimensional space with rounded corners.
13
+ *
13
14
  * @param {object} [options] - options for construction
14
15
  * @param {Array} [options.center=[0,0]] - center of rounded rectangle
15
16
  * @param {Array} [options.size=[2,2]] - dimension of rounded rectangle; width and length
@@ -21,14 +22,13 @@ import { rectangle } from './rectangle.js'
21
22
  * @example
22
23
  * let myshape = roundedRectangle({size: [10, 20], roundRadius: 2})
23
24
  */
24
- export const roundedRectangle = (options) => {
25
- const defaults = {
26
- center: [0, 0],
27
- size: [2, 2],
28
- roundRadius: 0.2,
29
- segments: 32
30
- }
31
- let { center, size, roundRadius, segments } = Object.assign({}, defaults, options)
25
+ export const roundedRectangle = (options = {}) => {
26
+ let {
27
+ center = [0, 0],
28
+ size = [2, 2],
29
+ roundRadius = 0.2,
30
+ segments = 32
31
+ } = options
32
32
 
33
33
  if (!isNumberArray(center, 2)) throw new Error('center must be an array of X and Y values')
34
34
  if (!isNumberArray(size, 2)) throw new Error('size must be an array of X and Y values')
@@ -15,14 +15,13 @@ import { isGTE } from './commonChecks.js'
15
15
  * @example
16
16
  * let myshape = sphere({radius: 5})
17
17
  */
18
- export const sphere = (options) => {
19
- const defaults = {
20
- center: [0, 0, 0],
21
- radius: 1,
22
- segments: 32,
23
- axes: [[1, 0, 0], [0, -1, 0], [0, 0, 1]]
24
- }
25
- let { center, radius, segments, axes } = Object.assign({}, defaults, options)
18
+ export const sphere = (options = {}) => {
19
+ let {
20
+ center = [0, 0, 0],
21
+ radius = 1,
22
+ segments = 32,
23
+ axes = [[1, 0, 0], [0, -1, 0], [0, 0, 1]]
24
+ } = options
26
25
 
27
26
  if (!isGTE(radius, 0)) throw new Error('radius must be positive')
28
27
 
@@ -3,6 +3,7 @@ import { isGTE } from './commonChecks.js'
3
3
 
4
4
  /**
5
5
  * Construct an axis-aligned square in two dimensional space with four equal sides at right angles.
6
+ *
6
7
  * @see [rectangle]{@link module:modeling/primitives.rectangle} for more options
7
8
  * @param {object} [options] - options for construction
8
9
  * @param {Array} [options.center=[0,0]] - center of square
@@ -13,12 +14,11 @@ import { isGTE } from './commonChecks.js'
13
14
  * @example
14
15
  * let myshape = square({size: 10})
15
16
  */
16
- export const square = (options) => {
17
- const defaults = {
18
- center: [0, 0],
19
- size: 2
20
- }
21
- let { center, size } = Object.assign({}, defaults, options)
17
+ export const square = (options = {}) => {
18
+ let {
19
+ center = [0, 0],
20
+ size = 2
21
+ } = options
22
22
 
23
23
  if (!isGTE(size, 0)) throw new Error('size must be positive')
24
24
 
@@ -28,6 +28,7 @@ const getPoints = (vertices, radius, startAngle, center) => {
28
28
 
29
29
  /**
30
30
  * Construct a star in two dimensional space.
31
+ *
31
32
  * @see https://en.wikipedia.org/wiki/Star_polygon
32
33
  * @param {object} [options] - options for construction
33
34
  * @param {Array} [options.center=[0,0]] - center of star
@@ -43,16 +44,15 @@ const getPoints = (vertices, radius, startAngle, center) => {
43
44
  * let star1 = star({vertices: 8, outerRadius: 10}) // star with 8/2 density
44
45
  * let star2 = star({vertices: 12, outerRadius: 40, innerRadius: 20}) // star with given radius
45
46
  */
46
- export const star = (options) => {
47
- const defaults = {
48
- center: [0, 0],
49
- vertices: 5,
50
- outerRadius: 1,
51
- innerRadius: 0,
52
- density: 2,
53
- startAngle: 0
54
- }
55
- let { center, vertices, outerRadius, innerRadius, density, startAngle } = Object.assign({}, defaults, options)
47
+ export const star = (options = {}) => {
48
+ let {
49
+ center = [0, 0],
50
+ vertices = 5,
51
+ outerRadius = 1,
52
+ innerRadius = 0,
53
+ density = 2,
54
+ startAngle = 0
55
+ } = options
56
56
 
57
57
  if (!isNumberArray(center, 2)) throw new Error('center must be an array of X and Y values')
58
58
  if (!isGTE(vertices, 2)) throw new Error('vertices must be two or more')
@@ -10,6 +10,7 @@ import { isGT, isGTE } from './commonChecks.js'
10
10
 
11
11
  /**
12
12
  * Construct a torus by revolving a small circle (inner) about the circumference of a large (outer) circle.
13
+ *
13
14
  * @param {object} [options] - options for construction
14
15
  * @param {number} [options.innerRadius=1] - radius of small (inner) circle
15
16
  * @param {number} [options.outerRadius=4] - radius of large (outer) circle
@@ -24,17 +25,16 @@ import { isGT, isGTE } from './commonChecks.js'
24
25
  * @example
25
26
  * let myshape = torus({ innerRadius: 10, outerRadius: 100 })
26
27
  */
27
- export const torus = (options) => {
28
- const defaults = {
29
- innerRadius: 1,
30
- innerSegments: 32,
31
- outerRadius: 4,
32
- outerSegments: 32,
33
- innerRotation: 0,
34
- startAngle: 0,
35
- outerRotation: TAU
36
- }
37
- const { innerRadius, innerSegments, outerRadius, outerSegments, innerRotation, startAngle, outerRotation } = Object.assign({}, defaults, options)
28
+ export const torus = (options = {}) => {
29
+ const {
30
+ innerRadius = 1,
31
+ innerSegments = 32,
32
+ outerRadius = 4,
33
+ outerSegments = 32,
34
+ innerRotation = 0,
35
+ startAngle = 0,
36
+ outerRotation = TAU
37
+ } = options
38
38
 
39
39
  if (!isGT(innerRadius, 0)) throw new Error('innerRadius must be greater than zero')
40
40
  if (!isGTE(innerSegments, 3)) throw new Error('innerSegments must be three or more')
@@ -115,7 +115,9 @@ const createTriangle = (A, B, C, a, b, c) => {
115
115
 
116
116
  /**
117
117
  * Construct a triangle in two dimensional space from the given options.
118
+ *
118
119
  * The triangle is always constructed CCW from the origin, [0, 0, 0].
120
+ *
119
121
  * @see https://www.mathsisfun.com/algebra/trig-solving-triangles.html
120
122
  * @param {object} [options] - options for construction
121
123
  * @param {string} [options.type='SSS'] - type of triangle to construct; A ~ angle, S ~ side
@@ -126,12 +128,11 @@ const createTriangle = (A, B, C, a, b, c) => {
126
128
  * @example
127
129
  * let myshape = triangle({type: 'AAS', values: [degToRad(62), degToRad(35), 7]})
128
130
  */
129
- export const triangle = (options) => {
130
- const defaults = {
131
- type: 'SSS',
132
- values: [1, 1, 1]
133
- }
134
- let { type, values } = Object.assign({}, defaults, options)
131
+ export const triangle = (options = {}) => {
132
+ let {
133
+ type = 'SSS',
134
+ values = [1, 1, 1]
135
+ } = options
135
136
 
136
137
  if (typeof (type) !== 'string') throw new Error('triangle type must be a string')
137
138
  type = type.toUpperCase()
@@ -2,6 +2,8 @@
2
2
  import * as geom2 from '../geometries/geom2/index.js'
3
3
  import * as geom3 from '../geometries/geom3/index.js'
4
4
  import * as path2 from '../geometries/path2/index.js'
5
+ import * as path3 from '../geometries/path3/index.js'
6
+ import * as slice from '../geometries/slice/index.js'
5
7
 
6
8
  /**
7
9
  * @param {Array} shapes - list of shapes to compare
@@ -15,6 +17,8 @@ export const areAllShapesTheSameType = (shapes) => {
15
17
  if (geom2.isA(shape)) currentType = 1
16
18
  if (geom3.isA(shape)) currentType = 2
17
19
  if (path2.isA(shape)) currentType = 3
20
+ if (path3.isA(shape)) currentType = 4
21
+ if (slice.isA(shape)) currentType = 5
18
22
 
19
23
  if (previousType && currentType !== previousType) return false
20
24
  previousType = currentType
@@ -5,4 +5,4 @@
5
5
  * @returns {Array} a flat list of arguments
6
6
  * @alias module:modeling/utils.flatten
7
7
  */
8
- export const flatten = (arr) => arr.reduce((acc, val) => Array.isArray(val) ? acc.concat(flatten(val)) : acc.concat(val), [])
8
+ export const flatten = (arr) => arr.flat(Infinity)
@@ -0,0 +1,94 @@
1
+ import test from 'ava'
2
+
3
+ import { flatten } from './index.js'
4
+
5
+ test('flatten: test an empty array returns empty.', (t) => {
6
+ t.deepEqual(flatten([]), [])
7
+ })
8
+
9
+ test('flatten: test a flat array is unchanged.', (t) => {
10
+ t.deepEqual(flatten([1, 2, 3]), [1, 2, 3])
11
+ })
12
+
13
+ test('flatten: test single level nesting is flattened.', (t) => {
14
+ t.deepEqual(flatten([1, [2, 3], 4]), [1, 2, 3, 4])
15
+ t.deepEqual(flatten([[1, 2], [3, 4]]), [1, 2, 3, 4])
16
+ t.deepEqual(flatten([[1], [2], [3]]), [1, 2, 3])
17
+ })
18
+
19
+ test('flatten: test deep nesting is flattened.', (t) => {
20
+ t.deepEqual(flatten([1, [2, [3, [4]]]]), [1, 2, 3, 4])
21
+ t.deepEqual(flatten([[[[1]]]]), [1])
22
+ t.deepEqual(flatten([1, [2, [3, [4, [5]]]]]), [1, 2, 3, 4, 5])
23
+ })
24
+
25
+ test('flatten: test mixed nesting depths are flattened.', (t) => {
26
+ t.deepEqual(flatten([1, [2, 3], [[4, 5]], [[[6]]]]), [1, 2, 3, 4, 5, 6])
27
+ })
28
+
29
+ test('flatten: test empty nested arrays are removed.', (t) => {
30
+ t.deepEqual(flatten([[]]), [])
31
+ t.deepEqual(flatten([[], []]), [])
32
+ t.deepEqual(flatten([1, [], 2]), [1, 2])
33
+ t.deepEqual(flatten([[], [1], []]), [1])
34
+ })
35
+
36
+ test('flatten: test single element arrays are flattened.', (t) => {
37
+ t.deepEqual(flatten([1]), [1])
38
+ t.deepEqual(flatten([[1]]), [1])
39
+ t.deepEqual(flatten([[[1]]]), [1])
40
+ })
41
+
42
+ test('flatten: test element order is preserved.', (t) => {
43
+ t.deepEqual(flatten([1, [2, 3], 4, [5, 6]]), [1, 2, 3, 4, 5, 6])
44
+ t.deepEqual(flatten([[1, 2], 3, [4, [5, 6]]]), [1, 2, 3, 4, 5, 6])
45
+ })
46
+
47
+ test('flatten: test object references are preserved.', (t) => {
48
+ const obj1 = { id: 1 }
49
+ const obj2 = { id: 2 }
50
+ const obj3 = { id: 3 }
51
+ const result = flatten([obj1, [obj2, obj3]])
52
+ t.is(result[0], obj1)
53
+ t.is(result[1], obj2)
54
+ t.is(result[2], obj3)
55
+ })
56
+
57
+ test('flatten: test various types are preserved.', (t) => {
58
+ const obj = { a: 1 }
59
+ const fn = () => {}
60
+ t.deepEqual(flatten([1, 'string', null, undefined, true]), [1, 'string', null, undefined, true])
61
+
62
+ const result = flatten([obj, [fn]])
63
+ t.is(result[0], obj)
64
+ t.is(result[1], fn)
65
+ })
66
+
67
+ test('flatten: test large flat array is unchanged.', (t) => {
68
+ const large = []
69
+ for (let i = 0; i < 1000; i++) {
70
+ large.push(i)
71
+ }
72
+ const result = flatten(large)
73
+ t.is(result.length, 1000)
74
+ t.is(result[0], 0)
75
+ t.is(result[999], 999)
76
+ })
77
+
78
+ test('flatten: test large nested array is flattened.', (t) => {
79
+ const nested = []
80
+ for (let i = 0; i < 100; i++) {
81
+ nested.push([i * 10, i * 10 + 1, i * 10 + 2])
82
+ }
83
+ const result = flatten(nested)
84
+ t.is(result.length, 300)
85
+ t.is(result[0], 0)
86
+ t.is(result[3], 10)
87
+ })
88
+
89
+ test('flatten: test input array is not modified.', (t) => {
90
+ const input = [1, [2, 3], 4]
91
+ const inputCopy = JSON.stringify(input)
92
+ flatten(input)
93
+ t.is(JSON.stringify(input), inputCopy)
94
+ })
@@ -1,5 +0,0 @@
1
- import type { Geom2 } from '../geom2/type.d.ts'
2
-
3
- import type { Slice } from './type.d.ts'
4
-
5
- export function fromGeom2(geometry: Geom2): Slice
@@ -1,17 +0,0 @@
1
- import * as vec3 from '../../maths/vec3/index.js'
2
- import { toOutlines } from '../geom2/index.js'
3
-
4
- import { create } from './create.js'
5
-
6
- /**
7
- * Create a slice from a geom2.
8
- *
9
- * @param {object} geometry - the 2D geometry to create a slice from
10
- * @returns {Slice} a new slice
11
- * @alias module:modeling/geometries/slice.fromGeom2
12
- */
13
- export const fromGeom2 = (geometry) => {
14
- // Convert from 2D points to 3D vertices
15
- const contours = toOutlines(geometry).map((outline) => outline.map((point) => vec3.fromVec2(vec3.create(), point)))
16
- return create(contours)
17
- }