@jscad/modeling 2.7.2 → 2.9.1

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 (238) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/jscad-modeling.min.js +443 -398
  3. package/package.json +2 -2
  4. package/src/curves/bezier/tangentAt.test.js +1 -1
  5. package/src/curves/bezier/valueAt.test.js +1 -1
  6. package/src/geometries/geom2/index.d.ts +1 -0
  7. package/src/geometries/geom2/index.js +12 -1
  8. package/src/geometries/geom2/isA.js +2 -2
  9. package/src/geometries/geom2/toCompactBinary.js +4 -4
  10. package/src/geometries/geom2/toString.js +1 -1
  11. package/src/geometries/geom2/transform.test.js +1 -1
  12. package/src/geometries/geom2/validate.d.ts +3 -0
  13. package/src/geometries/geom2/validate.js +36 -0
  14. package/src/geometries/geom3/fromCompactBinary.js +1 -1
  15. package/src/geometries/geom3/index.d.ts +1 -0
  16. package/src/geometries/geom3/index.js +19 -1
  17. package/src/geometries/geom3/isA.js +2 -2
  18. package/src/geometries/geom3/toCompactBinary.js +4 -4
  19. package/src/geometries/geom3/toString.js +1 -1
  20. package/src/geometries/geom3/transform.test.js +1 -1
  21. package/src/geometries/geom3/validate.d.ts +3 -0
  22. package/src/geometries/geom3/validate.js +62 -0
  23. package/src/geometries/index.js +8 -1
  24. package/src/geometries/path2/eachPoint.js +3 -3
  25. package/src/geometries/path2/index.d.ts +1 -0
  26. package/src/geometries/path2/index.js +13 -1
  27. package/src/geometries/path2/isA.js +2 -2
  28. package/src/geometries/path2/reverse.js +4 -4
  29. package/src/geometries/path2/toCompactBinary.js +6 -6
  30. package/src/geometries/path2/toString.js +1 -1
  31. package/src/geometries/path2/transform.test.js +1 -1
  32. package/src/geometries/path2/validate.d.ts +3 -0
  33. package/src/geometries/path2/validate.js +41 -0
  34. package/src/geometries/poly2/arePointsInside.js +0 -35
  35. package/src/geometries/poly2/arePointsInside.test.js +1 -1
  36. package/src/geometries/poly2/index.js +6 -0
  37. package/src/geometries/poly3/index.d.ts +1 -0
  38. package/src/geometries/poly3/index.js +9 -2
  39. package/src/geometries/poly3/invert.js +7 -1
  40. package/src/geometries/poly3/isA.js +2 -2
  41. package/src/geometries/poly3/isConvex.js +2 -2
  42. package/src/geometries/poly3/measureArea.js +4 -4
  43. package/src/geometries/poly3/measureArea.test.js +16 -16
  44. package/src/geometries/poly3/measureBoundingBox.js +2 -2
  45. package/src/geometries/poly3/measureBoundingSphere.js +2 -2
  46. package/src/geometries/poly3/measureBoundingSphere.test.js +8 -8
  47. package/src/geometries/poly3/measureSignedVolume.js +4 -4
  48. package/src/geometries/poly3/toPoints.js +2 -2
  49. package/src/geometries/poly3/toString.js +2 -2
  50. package/src/geometries/poly3/transform.js +2 -2
  51. package/src/geometries/poly3/validate.d.ts +4 -0
  52. package/src/geometries/poly3/validate.js +50 -0
  53. package/src/maths/index.js +1 -1
  54. package/src/maths/line2/equals.js +2 -2
  55. package/src/maths/line2/fromValues.js +2 -2
  56. package/src/maths/line2/intersectPointOfLines.js +1 -1
  57. package/src/maths/line2/intersectPointOfLines.test.js +1 -1
  58. package/src/maths/line2/reverse.test.js +1 -1
  59. package/src/maths/line2/transform.test.js +1 -1
  60. package/src/maths/line3/equals.js +2 -2
  61. package/src/maths/line3/reverse.test.js +1 -1
  62. package/src/maths/line3/transform.test.js +1 -1
  63. package/src/maths/mat4/fromVectorRotation.js +1 -1
  64. package/src/maths/mat4/fromVectorRotation.test.js +1 -1
  65. package/src/maths/mat4/identity.test.js +1 -1
  66. package/src/maths/mat4/invert.js +18 -18
  67. package/src/maths/mat4/isIdentity.js +1 -1
  68. package/src/maths/mat4/isMirroring.js +4 -4
  69. package/src/maths/mat4/isMirroring.test.js +1 -1
  70. package/src/maths/mat4/leftMultiplyVec3.js +2 -2
  71. package/src/maths/mat4/toString.js +2 -2
  72. package/src/maths/mat4/translate.test.js +1 -1
  73. package/src/maths/plane/flip.test.js +1 -1
  74. package/src/maths/plane/fromPoints.d.ts +1 -1
  75. package/src/maths/plane/fromPoints.js +1 -3
  76. package/src/maths/plane/signedDistanceToPoint.js +1 -1
  77. package/src/maths/plane/transform.test.js +1 -1
  78. package/src/maths/utils/aboutEqualNormals.js +2 -2
  79. package/src/maths/vec2/abs.d.ts +1 -1
  80. package/src/maths/vec2/add.test.js +1 -1
  81. package/src/maths/vec2/angleDegrees.d.ts +1 -1
  82. package/src/maths/vec2/angleRadians.d.ts +1 -1
  83. package/src/maths/vec2/create.js +1 -1
  84. package/src/maths/vec2/cross.test.js +1 -1
  85. package/src/maths/vec2/divide.test.js +1 -1
  86. package/src/maths/vec2/fromAngleDegrees.js +1 -1
  87. package/src/maths/vec2/fromScalar.js +1 -1
  88. package/src/maths/vec2/length.d.ts +1 -1
  89. package/src/maths/vec2/length.js +1 -1
  90. package/src/maths/vec2/lerp.test.js +1 -1
  91. package/src/maths/vec2/multiply.test.js +1 -1
  92. package/src/maths/vec2/negate.test.js +1 -1
  93. package/src/maths/vec2/normal.js +1 -1
  94. package/src/maths/vec2/normalize.d.ts +1 -1
  95. package/src/maths/vec2/normalize.test.js +1 -1
  96. package/src/maths/vec2/rotate.test.js +1 -1
  97. package/src/maths/vec2/squaredLength.d.ts +1 -1
  98. package/src/maths/vec2/squaredLength.js +3 -3
  99. package/src/maths/vec2/subtract.test.js +1 -1
  100. package/src/maths/vec2/toString.js +1 -1
  101. package/src/maths/vec2/transform.test.js +1 -1
  102. package/src/maths/vec3/abs.d.ts +1 -1
  103. package/src/maths/vec3/add.test.js +1 -1
  104. package/src/maths/vec3/cross.test.js +1 -1
  105. package/src/maths/vec3/divide.test.js +1 -1
  106. package/src/maths/vec3/fromScalar.js +1 -1
  107. package/src/maths/vec3/fromVec2.d.ts +1 -1
  108. package/src/maths/vec3/fromVec2.js +3 -3
  109. package/src/maths/vec3/length.d.ts +1 -1
  110. package/src/maths/vec3/length.js +4 -4
  111. package/src/maths/vec3/lerp.test.js +1 -1
  112. package/src/maths/vec3/multiply.test.js +1 -1
  113. package/src/maths/vec3/negate.d.ts +1 -1
  114. package/src/maths/vec3/negate.test.js +1 -1
  115. package/src/maths/vec3/normalize.d.ts +1 -1
  116. package/src/maths/vec3/normalize.test.js +1 -1
  117. package/src/maths/vec3/rotateX.test.js +1 -1
  118. package/src/maths/vec3/rotateY.test.js +1 -1
  119. package/src/maths/vec3/rotateZ.test.js +1 -1
  120. package/src/maths/vec3/scale.test.js +1 -1
  121. package/src/maths/vec3/squaredLength.d.ts +1 -1
  122. package/src/maths/vec3/squaredLength.js +4 -4
  123. package/src/maths/vec3/subtract.test.js +1 -1
  124. package/src/maths/vec3/toString.js +1 -1
  125. package/src/maths/vec3/transform.test.js +1 -1
  126. package/src/maths/vec4/toString.js +1 -1
  127. package/src/maths/vec4/transform.test.js +1 -1
  128. package/src/measurements/measureBoundingSphere.js +4 -4
  129. package/src/measurements/measureCenterOfMass.js +1 -1
  130. package/src/measurements/measureCenterOfMass.test.js +2 -2
  131. package/src/operations/booleans/intersect.test.js +8 -0
  132. package/src/operations/booleans/mayOverlap.js +3 -3
  133. package/src/operations/booleans/retessellate.js +2 -2
  134. package/src/operations/booleans/scission.js +1 -1
  135. package/src/operations/booleans/scission.test.js +4 -4
  136. package/src/operations/booleans/subtract.js +1 -1
  137. package/src/operations/booleans/subtract.test.js +8 -0
  138. package/src/operations/booleans/trees/Node.js +10 -16
  139. package/src/operations/booleans/trees/PolygonTreeNode.js +13 -14
  140. package/src/operations/booleans/trees/Tree.js +1 -2
  141. package/src/operations/booleans/trees/splitPolygonByPlane.js +2 -3
  142. package/src/operations/booleans/union.test.js +28 -1
  143. package/src/operations/booleans/unionGeom3Sub.js +1 -1
  144. package/src/operations/expansions/expand.js +2 -2
  145. package/src/operations/expansions/expand.test.js +32 -55
  146. package/src/operations/expansions/expandShell.js +24 -18
  147. package/src/operations/expansions/offset.js +1 -1
  148. package/src/operations/expansions/offset.test.js +50 -89
  149. package/src/operations/expansions/offsetFromPoints.js +11 -6
  150. package/src/operations/extrusions/earcut/assignHoles.js +91 -0
  151. package/src/operations/extrusions/earcut/assignHoles.test.js +74 -0
  152. package/src/operations/extrusions/earcut/eliminateHoles.js +131 -0
  153. package/src/operations/extrusions/earcut/index.js +252 -0
  154. package/src/operations/extrusions/earcut/linkedList.js +58 -0
  155. package/src/operations/extrusions/earcut/linkedListSort.js +54 -0
  156. package/src/operations/extrusions/earcut/linkedPolygon.js +197 -0
  157. package/src/operations/extrusions/earcut/polygonHierarchy.js +64 -0
  158. package/src/operations/extrusions/earcut/triangle.js +16 -0
  159. package/src/operations/extrusions/extrudeFromSlices.js +10 -3
  160. package/src/operations/extrusions/extrudeFromSlices.test.js +47 -31
  161. package/src/operations/extrusions/extrudeLinear.js +10 -5
  162. package/src/operations/extrusions/extrudeLinear.test.js +91 -35
  163. package/src/operations/extrusions/extrudeLinearGeom2.js +5 -2
  164. package/src/operations/extrusions/extrudeLinearPath2.js +24 -0
  165. package/src/operations/extrusions/extrudeRectangular.js +1 -1
  166. package/src/operations/extrusions/extrudeRectangular.test.js +22 -15
  167. package/src/operations/extrusions/extrudeRotate.test.js +31 -27
  168. package/src/operations/extrusions/project.js +1 -1
  169. package/src/operations/extrusions/project.test.js +5 -5
  170. package/src/operations/extrusions/slice/calculatePlane.js +7 -4
  171. package/src/operations/extrusions/slice/isA.js +2 -2
  172. package/src/operations/extrusions/slice/repairSlice.js +47 -0
  173. package/src/operations/extrusions/slice/toPolygons.js +24 -60
  174. package/src/operations/hulls/hull.test.js +25 -2
  175. package/src/operations/hulls/hullChain.js +1 -1
  176. package/src/operations/hulls/hullChain.test.js +6 -4
  177. package/src/operations/hulls/hullGeom2.js +1 -1
  178. package/src/operations/hulls/hullPath2.js +6 -4
  179. package/src/operations/hulls/hullPath2.test.js +16 -0
  180. package/src/operations/hulls/hullPoints2.test.js +1 -1
  181. package/src/operations/modifiers/edges.js +1 -1
  182. package/src/operations/modifiers/generalize.js +1 -1
  183. package/src/operations/modifiers/generalize.test.js +6 -0
  184. package/src/operations/modifiers/snap.test.js +3 -3
  185. package/src/operations/transforms/align.d.ts +1 -1
  186. package/src/operations/transforms/align.test.js +12 -0
  187. package/src/operations/transforms/center.js +17 -17
  188. package/src/operations/transforms/center.test.js +12 -0
  189. package/src/operations/transforms/mirror.js +12 -12
  190. package/src/operations/transforms/mirror.test.js +16 -0
  191. package/src/operations/transforms/rotate.js +12 -12
  192. package/src/operations/transforms/rotate.test.js +10 -0
  193. package/src/operations/transforms/scale.js +19 -19
  194. package/src/operations/transforms/scale.test.js +15 -0
  195. package/src/operations/transforms/transform.js +3 -3
  196. package/src/operations/transforms/transform.test.js +5 -0
  197. package/src/operations/transforms/translate.js +14 -14
  198. package/src/operations/transforms/translate.test.js +16 -0
  199. package/src/primitives/arc.js +1 -1
  200. package/src/primitives/arc.test.js +11 -0
  201. package/src/primitives/circle.test.js +15 -9
  202. package/src/primitives/cube.test.js +3 -0
  203. package/src/primitives/cuboid.test.js +9 -24
  204. package/src/primitives/cylinder.test.js +7 -4
  205. package/src/primitives/cylinderElliptic.js +13 -6
  206. package/src/primitives/cylinderElliptic.test.js +72 -52
  207. package/src/primitives/ellipse.js +3 -1
  208. package/src/primitives/ellipse.test.js +14 -8
  209. package/src/primitives/ellipsoid.js +7 -5
  210. package/src/primitives/ellipsoid.test.js +84 -82
  211. package/src/primitives/geodesicSphere.d.ts +0 -1
  212. package/src/primitives/geodesicSphere.test.js +3 -0
  213. package/src/primitives/line.test.js +1 -0
  214. package/src/primitives/polygon.test.js +15 -10
  215. package/src/primitives/polyhedron.js +1 -1
  216. package/src/primitives/polyhedron.test.js +14 -42
  217. package/src/primitives/rectangle.test.js +3 -0
  218. package/src/primitives/roundedCuboid.test.js +5 -0
  219. package/src/primitives/roundedCylinder.js +6 -4
  220. package/src/primitives/roundedCylinder.test.js +40 -36
  221. package/src/primitives/roundedRectangle.test.js +5 -0
  222. package/src/primitives/sphere.test.js +52 -73
  223. package/src/primitives/square.test.js +3 -0
  224. package/src/primitives/star.test.js +6 -0
  225. package/src/primitives/torus.d.ts +0 -1
  226. package/src/primitives/torus.test.js +8 -1
  227. package/src/primitives/triangle.js +1 -1
  228. package/src/primitives/triangle.test.js +7 -0
  229. package/src/text/vectorText.js +2 -2
  230. package/src/utils/areAllShapesTheSameType.js +2 -2
  231. package/src/utils/areAllShapesTheSameType.test.js +17 -0
  232. package/src/utils/index.d.ts +1 -0
  233. package/src/utils/index.js +3 -1
  234. package/src/utils/padArrayToLength.js +1 -1
  235. package/src/utils/trigonometry.d.ts +2 -0
  236. package/src/utils/trigonometry.js +35 -0
  237. package/src/utils/trigonometry.test.js +25 -0
  238. package/test/helpers/nearlyEqual.js +4 -1
@@ -16,25 +16,28 @@ test('extrudeFromSlices (defaults)', (t) => {
16
16
  let geometry3 = extrudeFromSlices({ }, geometry2)
17
17
  let pts = geom3.toPoints(geometry3)
18
18
  const exp = [
19
- [[10.0, -10.0, 0.0], [10.0, 10.0, 0.0], [10.0, 10.0, 1.0]],
20
- [[10.0, -10.0, 0.0], [10.0, 10.0, 1.0], [10.0, -10.0, 1.0]],
21
- [[10.0, 10.0, 0.0], [-10.0, 10.0, 0.0], [-10.0, 10.0, 1.0]],
22
- [[10.0, 10.0, 0.0], [-10.0, 10.0, 1.0], [10.0, 10.0, 1.0]],
23
- [[-10.0, 10.0, 0.0], [-10.0, -10.0, 0.0], [-10.0, -10.0, 1.0]],
24
- [[-10.0, 10.0, 0.0], [-10.0, -10.0, 1.0], [-10.0, 10.0, 1.0]],
25
- [[-10.0, -10.0, 0.0], [10.0, -10.0, 0.0], [10.0, -10.0, 1.0]],
26
- [[-10.0, -10.0, 0.0], [10.0, -10.0, 1.0], [-10.0, -10.0, 1.0]],
27
- [[10, 10, 1], [-10, 10, 1], [-10, -10, 1], [10, -10, 1]],
28
- [[10, -10, 0], [-10, -10, 0], [-10, 10, 0], [10, 10, 0]]
19
+ [[10, -10, 0], [10, 10, 0], [10, 10, 1]],
20
+ [[10, -10, 0], [10, 10, 1], [10, -10, 1]],
21
+ [[10, 10, 0], [-10, 10, 0], [-10, 10, 1]],
22
+ [[10, 10, 0], [-10, 10, 1], [10, 10, 1]],
23
+ [[-10, 10, 0], [-10, -10, 0], [-10, -10, 1]],
24
+ [[-10, 10, 0], [-10, -10, 1], [-10, 10, 1]],
25
+ [[-10, -10, 0], [10, -10, 0], [10, -10, 1]],
26
+ [[-10, -10, 0], [10, -10, 1], [-10, -10, 1]],
27
+ [[-10, -10, 1], [10, -10, 1], [10, 10, 1]],
28
+ [[10, 10, 1], [-10, 10, 1], [-10, -10, 1]],
29
+ [[10, 10, 0], [10, -10, 0], [-10, -10, 0]],
30
+ [[-10, -10, 0], [-10, 10, 0], [10, 10, 0]]
29
31
  ]
30
- t.is(pts.length, 10)
32
+ t.is(pts.length, 12)
31
33
  t.true(comparePolygonsAsPoints(pts, exp))
32
34
 
33
35
  const poly2 = poly3.fromPoints([[10, 10, 0], [-10, 10, 0], [-10, -10, 0], [10, -10, 0]])
34
36
  geometry3 = extrudeFromSlices({ }, poly2)
35
37
  pts = geom3.toPoints(geometry3)
36
38
 
37
- t.is(pts.length, 10)
39
+ t.notThrows(() => geom3.validate(geometry3))
40
+ t.is(pts.length, 12)
38
41
  t.true(comparePolygonsAsPoints(pts, exp))
39
42
  })
40
43
 
@@ -66,6 +69,7 @@ test('extrudeFromSlices (torus)', (t) => {
66
69
  }, hex
67
70
  )
68
71
  const pts = geom3.toPoints(geometry3)
72
+ t.notThrows(() => geom3.validate(geometry3))
69
73
  t.is(pts.length, 96)
70
74
  })
71
75
 
@@ -84,7 +88,9 @@ test('extrudeFromSlices (same shape, changing dimensions)', (t) => {
84
88
  }, base
85
89
  )
86
90
  const pts = geom3.toPoints(geometry3)
87
- t.is(pts.length, 25)
91
+ // expected to throw because capEnd is false (non-closed geometry)
92
+ t.throws(() => geom3.validate(geometry3))
93
+ t.is(pts.length, 26)
88
94
  })
89
95
 
90
96
  test('extrudeFromSlices (changing shape, changing dimensions)', (t) => {
@@ -101,20 +107,21 @@ test('extrudeFromSlices (changing shape, changing dimensions)', (t) => {
101
107
  }, base
102
108
  )
103
109
  const pts = geom3.toPoints(geometry3)
104
- t.is(pts.length, 298)
110
+ t.notThrows.skip(() => geom3.validate(geometry3))
111
+ t.is(pts.length, 304)
105
112
  })
106
113
 
107
114
  test('extrudeFromSlices (holes)', (t) => {
108
115
  const geometry2 = geom2.create(
109
116
  [
110
- [[-10.0, 10.0], [-10.0, -10.0]],
111
- [[-10.0, -10.0], [10.0, -10.0]],
112
- [[10.0, -10.0], [10.0, 10.0]],
113
- [[10.0, 10.0], [-10.0, 10.0]],
114
- [[-5.0, -5.0], [-5.0, 5.0]],
115
- [[5.0, -5.0], [-5.0, -5.0]],
116
- [[5.0, 5.0], [5.0, -5.0]],
117
- [[-5.0, 5.0], [5.0, 5.0]]
117
+ [[-10, 10], [-10, -10]],
118
+ [[-10, -10], [10, -10]],
119
+ [[10, -10], [10, 10]],
120
+ [[10, 10], [-10, 10]],
121
+ [[-5, -5], [-5, 5]],
122
+ [[5, -5], [-5, -5]],
123
+ [[5, 5], [5, -5]],
124
+ [[-5, 5], [5, 5]]
118
125
  ]
119
126
  )
120
127
  const geometry3 = extrudeFromSlices({ }, geometry2)
@@ -136,15 +143,24 @@ test('extrudeFromSlices (holes)', (t) => {
136
143
  [[5, 5, 0], [5, -5, 1], [5, 5, 1]],
137
144
  [[-5, 5, 0], [5, 5, 0], [5, 5, 1]],
138
145
  [[-5, 5, 0], [5, 5, 1], [-5, 5, 1]],
139
- [[-10, -10, 1], [-5, -10, 1], [-5, 10, 1], [-10, 10, 1]],
140
- [[10, -10, 1], [10, -5, 1], [-5, -5, 1], [-5, -10, 1]],
141
- [[10, 10, 1], [5, 10, 1], [5, -5, 1], [10, -5, 1]],
142
- [[5, 5, 1], [5, 10, 1], [-5, 10, 1], [-5, 5, 1]],
143
- [[-10, 10, 0], [-5, 10, 0], [-5, -10, 0], [-10, -10, 0]],
144
- [[10, -10, 0], [-5, -10, 0], [-5, -5, 0], [10, -5, 0]],
145
- [[10, -5, 0], [5, -5, 0], [5, 10, 0], [10, 10, 0]],
146
- [[5, 10, 0], [5, 5, 0], [-5, 5, 0], [-5, 10, 0]]
146
+ [[10, -10, 1], [10, 10, 1], [5, 5, 1]],
147
+ [[-5, 5, 1], [5, 5, 1], [10, 10, 1]],
148
+ [[10, -10, 1], [5, 5, 1], [5, -5, 1]],
149
+ [[-5, 5, 1], [10, 10, 1], [-10, 10, 1]],
150
+ [[-10, -10, 1], [10, -10, 1], [5, -5, 1]],
151
+ [[-5, -5, 1], [-5, 5, 1], [-10, 10, 1]],
152
+ [[-10, -10, 1], [5, -5, 1], [-5, -5, 1]],
153
+ [[-5, -5, 1], [-10, 10, 1], [-10, -10, 1]],
154
+ [[5, 5, 0], [10, 10, 0], [10, -10, 0]],
155
+ [[10, 10, 0], [5, 5, 0], [-5, 5, 0]],
156
+ [[5, -5, 0], [5, 5, 0], [10, -10, 0]],
157
+ [[-10, 10, 0], [10, 10, 0], [-5, 5, 0]],
158
+ [[5, -5, 0], [10, -10, 0], [-10, -10, 0]],
159
+ [[-10, 10, 0], [-5, 5, 0], [-5, -5, 0]],
160
+ [[-5, -5, 0], [5, -5, 0], [-10, -10, 0]],
161
+ [[-10, -10, 0], [-10, 10, 0], [-5, -5, 0]]
147
162
  ]
148
- t.is(pts.length, 24)
163
+ t.notThrows(() => geom3.validate(geometry3))
164
+ t.is(pts.length, 32)
149
165
  t.true(comparePolygonsAsPoints(pts, exp))
150
166
  })
@@ -1,16 +1,20 @@
1
1
  const flatten = require('../../utils/flatten')
2
2
 
3
3
  const geom2 = require('../../geometries/geom2')
4
+ const path2 = require('../../geometries/path2')
4
5
 
5
6
  const extrudeLinearGeom2 = require('./extrudeLinearGeom2')
7
+ const extrudeLinearPath2 = require('./extrudeLinearPath2')
6
8
 
7
9
  /**
8
10
  * Extrude the given geometry in an upward linear direction using the given options.
11
+ * Accepts path2 or geom2 objects as input. Paths must be closed.
12
+ *
9
13
  * @param {Object} options - options for extrude
10
14
  * @param {Number} [options.height=1] the height of the extrusion
11
15
  * @param {Number} [options.twistAngle=0] the final rotation (RADIANS) about the origin of the shape (if any)
12
16
  * @param {Integer} [options.twistSteps=1] the resolution of the twist about the axis (if any)
13
- * @param {...Object} geometry - the list of geometry to extrude
17
+ * @param {...Object} objects - the geometries to extrude
14
18
  * @return {Object|Array} the extruded geometry, or a list of extruded geometry
15
19
  * @alias module:modeling/extrusions.extrudeLinear
16
20
  *
@@ -21,17 +25,18 @@ const extrudeLinear = (options, ...objects) => {
21
25
  const defaults = {
22
26
  height: 1,
23
27
  twistAngle: 0,
24
- twistSteps: 1
28
+ twistSteps: 1,
29
+ repair: true
25
30
  }
26
- const { height, twistAngle, twistSteps } = Object.assign({ }, defaults, options)
31
+ const { height, twistAngle, twistSteps, repair } = Object.assign({ }, defaults, options)
27
32
 
28
33
  objects = flatten(objects)
29
34
  if (objects.length === 0) throw new Error('wrong number of arguments')
30
35
 
31
- options = { offset: [0, 0, height], twistAngle: twistAngle, twistSteps: twistSteps }
36
+ options = { offset: [0, 0, height], twistAngle, twistSteps, repair }
32
37
 
33
38
  const results = objects.map((object) => {
34
- // if (path.isA(object)) return pathextrude(options, object)
39
+ if (path2.isA(object)) return extrudeLinearPath2(options, object)
35
40
  if (geom2.isA(object)) return extrudeLinearGeom2(options, object)
36
41
  // if (geom3.isA(object)) return geom3.extrude(options, object)
37
42
  return object
@@ -2,7 +2,7 @@ const test = require('ava')
2
2
 
3
3
  const comparePolygonsAsPoints = require('../../../test/helpers/comparePolygonsAsPoints')
4
4
 
5
- const { geom2, geom3 } = require('../../geometries')
5
+ const { geom2, geom3, path2 } = require('../../geometries')
6
6
 
7
7
  const { extrudeLinear } = require('./index')
8
8
 
@@ -20,10 +20,13 @@ test('extrudeLinear (defaults)', (t) => {
20
20
  [[-5, 5, 0], [-5, -5, 1], [-5, 5, 1]],
21
21
  [[-5, -5, 0], [5, -5, 0], [5, -5, 1]],
22
22
  [[-5, -5, 0], [5, -5, 1], [-5, -5, 1]],
23
- [[5, 5, 1], [-5, 5, 1], [-5, -5, 1], [5, -5, 1]],
24
- [[5, -5, 0], [-5, -5, 0], [-5, 5, 0], [5, 5, 0]]
23
+ [[-5, -5, 1], [5, -5, 1], [5, 5, 1]],
24
+ [[5, 5, 1], [-5, 5, 1], [-5, -5, 1]],
25
+ [[5, 5, 0], [5, -5, 0], [-5, -5, 0]],
26
+ [[-5, -5, 0], [-5, 5, 0], [5, 5, 0]]
25
27
  ]
26
- t.is(pts.length, 10)
28
+ t.notThrows(() => geom3.validate(geometry3))
29
+ t.is(pts.length, 12)
27
30
  t.true(comparePolygonsAsPoints(pts, exp))
28
31
  })
29
32
 
@@ -41,10 +44,13 @@ test('extrudeLinear (no twist)', (t) => {
41
44
  [[-5, 5, 0], [-5, -5, 15], [-5, 5, 15]],
42
45
  [[-5, -5, 0], [5, -5, 0], [5, -5, 15]],
43
46
  [[-5, -5, 0], [5, -5, 15], [-5, -5, 15]],
44
- [[5, 5, 15], [-5, 5, 15], [-5, -5, 15], [5, -5, 15]],
45
- [[5, -5, 0], [-5, -5, 0], [-5, 5, 0], [5, 5, 0]]
47
+ [[-5, -5, 15], [5, -5, 15], [5, 5, 15]],
48
+ [[5, 5, 15], [-5, 5, 15], [-5, -5, 15]],
49
+ [[5, 5, 0], [5, -5, 0], [-5, -5, 0]],
50
+ [[-5, -5, 0], [-5, 5, 0], [5, 5, 0]]
46
51
  ]
47
- t.is(pts.length, 10)
52
+ t.notThrows(() => geom3.validate(geometry3))
53
+ t.is(pts.length, 12)
48
54
  t.true(comparePolygonsAsPoints(pts, exp))
49
55
 
50
56
  geometry3 = extrudeLinear({ height: -15 }, geometry2)
@@ -58,10 +64,13 @@ test('extrudeLinear (no twist)', (t) => {
58
64
  [[-5, -5, 0], [-5, 5, -15], [-5, -5, -15]],
59
65
  [[5, -5, 0], [-5, -5, 0], [-5, -5, -15]],
60
66
  [[5, -5, 0], [-5, -5, -15], [5, -5, -15]],
61
- [[5, -5, -15], [-5, -5, -15], [-5, 5, -15], [5, 5, -15]],
62
- [[5, 5, 0], [-5, 5, 0], [-5, -5, 0], [5, -5, 0]]
67
+ [[-5, 5, -15], [5, 5, -15], [5, -5, -15]],
68
+ [[5, -5, -15], [-5, -5, -15], [-5, 5, -15]],
69
+ [[5, -5, 0], [5, 5, 0], [-5, 5, 0]],
70
+ [[-5, 5, 0], [-5, -5, 0], [5, -5, 0]]
63
71
  ]
64
- t.is(pts.length, 10)
72
+ t.notThrows(() => geom3.validate(geometry3))
73
+ t.is(pts.length, 12)
65
74
  t.true(comparePolygonsAsPoints(pts, exp))
66
75
  })
67
76
 
@@ -79,11 +88,21 @@ test('extrudeLinear (twist)', (t) => {
79
88
  [[-5, 5, 0], [-7.0710678118654755, -4.440892098500626e-16, 15], [-4.440892098500626e-16, 7.0710678118654755, 15]],
80
89
  [[-5, -5, 0], [5, -5, 0], [4.440892098500626e-16, -7.0710678118654755, 15]],
81
90
  [[-5, -5, 0], [4.440892098500626e-16, -7.0710678118654755, 15], [-7.0710678118654755, -4.440892098500626e-16, 15]],
82
- [[7.071067811865477, 8.881784197001252e-16, 15], [1.7763568394002505e-15, 7.071067811865477, 15],
83
- [-7.071067811865475, 0, 15], [0, -7.0710678118654755, 15]],
84
- [[5, -5, 0], [-5, -5, 0], [-5, 5, 0], [5, 5, 0]]
91
+ [
92
+ [-7.0710678118654755, -4.440892098500626e-16, 15],
93
+ [4.440892098500626e-16, -7.0710678118654755, 15],
94
+ [7.0710678118654755, 4.440892098500626e-16, 15]
95
+ ],
96
+ [
97
+ [7.0710678118654755, 4.440892098500626e-16, 15],
98
+ [-4.440892098500626e-16, 7.0710678118654755, 15],
99
+ [-7.0710678118654755, -4.440892098500626e-16, 15]
100
+ ],
101
+ [[5, 5, 0], [5, -5, 0], [-5, -5, 0]],
102
+ [[-5, -5, 0], [-5, 5, 0], [5, 5, 0]]
85
103
  ]
86
- t.is(pts.length, 10)
104
+ t.notThrows(() => geom3.validate(geometry3))
105
+ t.is(pts.length, 12)
87
106
  t.true(comparePolygonsAsPoints(pts, exp))
88
107
 
89
108
  geometry3 = extrudeLinear({ height: 15, twistAngle: Math.PI / 2, twistSteps: 3 }, geometry2)
@@ -113,27 +132,30 @@ test('extrudeLinear (twist)', (t) => {
113
132
  [[-6.830127018922193, -1.8301270189221923, 10], [5, -5, 15], [-5, -5, 15]],
114
133
  [[1.8301270189221923, -6.830127018922193, 10], [6.830127018922193, 1.8301270189221923, 10], [5, 5, 15]],
115
134
  [[1.8301270189221923, -6.830127018922193, 10], [5, 5, 15], [5, -5, 15]],
116
- [[-5, 5, 15], [-5, -5, 15], [5, -5, 15], [5, 5, 15]],
117
- [[5, -5, 0], [-5, -5, 0], [-5, 5, 0], [5, 5, 0]]
135
+ [[5, -5, 15], [5, 5, 15], [-5, 5, 15]],
136
+ [[-5, 5, 15], [-5, -5, 15], [5, -5, 15]],
137
+ [[5, 5, 0], [5, -5, 0], [-5, -5, 0]],
138
+ [[-5, -5, 0], [-5, 5, 0], [5, 5, 0]]
118
139
  ]
119
- t.is(pts.length, 26)
140
+ t.is(pts.length, 28)
120
141
  t.true(comparePolygonsAsPoints(pts, exp))
121
142
 
122
143
  geometry3 = extrudeLinear({ height: 15, twistAngle: Math.PI / 2, twistSteps: 30 }, geometry2)
123
144
  pts = geom3.toPoints(geometry3)
124
- t.is(pts.length, 242)
145
+ t.notThrows(() => geom3.validate(geometry3))
146
+ t.is(pts.length, 244)
125
147
  })
126
148
 
127
149
  test('extrudeLinear (holes)', (t) => {
128
150
  const geometry2 = geom2.create([
129
- [[-5.00000, 5.00000], [-5.00000, -5.00000]],
130
- [[-5.00000, -5.00000], [5.00000, -5.00000]],
131
- [[5.00000, -5.00000], [5.00000, 5.00000]],
132
- [[5.00000, 5.00000], [-5.00000, 5.00000]],
133
- [[-2.00000, -2.00000], [-2.00000, 2.00000]],
134
- [[2.00000, -2.00000], [-2.00000, -2.00000]],
135
- [[2.00000, 2.00000], [2.00000, -2.00000]],
136
- [[-2.00000, 2.00000], [2.00000, 2.00000]]
151
+ [[-5, 5], [-5, -5]],
152
+ [[-5, -5], [5, -5]],
153
+ [[5, -5], [5, 5]],
154
+ [[5, 5], [-5, 5]],
155
+ [[-2, -2], [-2, 2]],
156
+ [[2, -2], [-2, -2]],
157
+ [[2, 2], [2, -2]],
158
+ [[-2, 2], [2, 2]]
137
159
  ])
138
160
  const geometry3 = extrudeLinear({ height: 15 }, geometry2)
139
161
  const pts = geom3.toPoints(geometry3)
@@ -154,15 +176,49 @@ test('extrudeLinear (holes)', (t) => {
154
176
  [[2, 2, 0], [2, -2, 15], [2, 2, 15]],
155
177
  [[-2, 2, 0], [2, 2, 0], [2, 2, 15]],
156
178
  [[-2, 2, 0], [2, 2, 15], [-2, 2, 15]],
157
- [[-5, -5, 15], [-2, -5, 15], [-2, 5, 15], [-5, 5, 15]],
158
- [[5, -5, 15], [5, -2, 15], [-2, -2, 15], [-2, -5, 15]],
159
- [[5, 5, 15], [2, 5, 15], [2, -2, 15], [5, -2, 15]],
160
- [[2, 2, 15], [2, 5, 15], [-2, 5, 15], [-2, 2, 15]],
161
- [[-5, 5, 0], [-2, 5, 0], [-2, -5, 0], [-5, -5, 0]],
162
- [[5, -5, 0], [-2, -5, 0], [-2, -2, 0], [5, -2, 0]],
163
- [[5, -2, 0], [2, -2, 0], [2, 5, 0], [5, 5, 0]],
164
- [[2, 5, 0], [2, 2, 0], [-2, 2, 0], [-2, 5, 0]]
179
+ [[5, -5, 15], [5, 5, 15], [2, 2, 15]],
180
+ [[-2, 2, 15], [2, 2, 15], [5, 5, 15]],
181
+ [[5, -5, 15], [2, 2, 15], [2, -2, 15]],
182
+ [[-2, 2, 15], [5, 5, 15], [-5, 5, 15]],
183
+ [[-5, -5, 15], [5, -5, 15], [2, -2, 15]],
184
+ [[-2, -2, 15], [-2, 2, 15], [-5, 5, 15]],
185
+ [[-5, -5, 15], [2, -2, 15], [-2, -2, 15]],
186
+ [[-2, -2, 15], [-5, 5, 15], [-5, -5, 15]],
187
+ [[2, 2, 0], [5, 5, 0], [5, -5, 0]],
188
+ [[5, 5, 0], [2, 2, 0], [-2, 2, 0]],
189
+ [[2, -2, 0], [2, 2, 0], [5, -5, 0]],
190
+ [[-5, 5, 0], [5, 5, 0], [-2, 2, 0]],
191
+ [[2, -2, 0], [5, -5, 0], [-5, -5, 0]],
192
+ [[-5, 5, 0], [-2, 2, 0], [-2, -2, 0]],
193
+ [[-2, -2, 0], [2, -2, 0], [-5, -5, 0]],
194
+ [[-5, -5, 0], [-5, 5, 0], [-2, -2, 0]]
165
195
  ]
166
- t.is(pts.length, 24)
196
+ t.notThrows(() => geom3.validate(geometry3))
197
+ t.is(pts.length, 32)
167
198
  t.true(comparePolygonsAsPoints(pts, exp))
168
199
  })
200
+
201
+ test('extrudeLinear (path2)', (t) => {
202
+ const geometry2 = path2.fromPoints({ closed: true }, [[0, 0], [12, 0], [6, 10]])
203
+ const geometry3 = extrudeLinear({ height: 15 }, geometry2)
204
+ t.notThrows(() => geom3.validate(geometry3))
205
+ const pts = geom3.toPoints(geometry3)
206
+ const exp = [
207
+ [[6, 10, 0], [0, 0, 0], [0, 0, 15]],
208
+ [[6, 10, 0], [0, 0, 15], [6, 10, 15]],
209
+ [[0, 0, 0], [12, 0, 0], [12, 0, 15]],
210
+ [[0, 0, 0], [12, 0, 15], [0, 0, 15]],
211
+ [[12, 0, 0], [6, 10, 0], [6, 10, 15]],
212
+ [[12, 0, 0], [6, 10, 15], [12, 0, 15]],
213
+ [[12, 0, 15], [6, 10, 15], [0, 0, 15]],
214
+ [[0, 0, 0], [6, 10, 0], [12, 0, 0]]
215
+ ]
216
+
217
+ t.is(pts.length, 8)
218
+ t.true(comparePolygonsAsPoints(pts, exp))
219
+ })
220
+
221
+ test('extrudeLinear (unclosed path throws error)', (t) => {
222
+ const geometry2 = path2.fromPoints({ closed: false }, [[0, 0], [12, 0], [6, 10]])
223
+ t.throws(() => extrudeLinear({}, geometry2))
224
+ })
@@ -14,6 +14,7 @@ const extrudeFromSlices = require('./extrudeFromSlices')
14
14
  * @param {Array} [options.offset] - the direction of the extrusion as a 3D vector
15
15
  * @param {Number} [options.twistAngle] - the final rotation (RADIANS) about the origin
16
16
  * @param {Integer} [options.twistSteps] - the number of steps created to produce the twist (if any)
17
+ * @param {Boolean} [options.repair] - repair gaps in the geometry
17
18
  * @param {geom2} geometry - the geometry to extrude
18
19
  * @returns {geom3} the extruded 3D geometry
19
20
  */
@@ -21,9 +22,10 @@ const extrudeGeom2 = (options, geometry) => {
21
22
  const defaults = {
22
23
  offset: [0, 0, 1],
23
24
  twistAngle: 0,
24
- twistSteps: 12
25
+ twistSteps: 12,
26
+ repair: true
25
27
  }
26
- let { offset, twistAngle, twistSteps } = Object.assign({ }, defaults, options)
28
+ let { offset, twistAngle, twistSteps, repair } = Object.assign({ }, defaults, options)
27
29
 
28
30
  if (twistSteps < 1) throw new Error('twistSteps must be 1 or more')
29
31
 
@@ -53,6 +55,7 @@ const extrudeGeom2 = (options, geometry) => {
53
55
  numberOfSlices: twistSteps + 1,
54
56
  capStart: true,
55
57
  capEnd: true,
58
+ repair,
56
59
  callback: createTwist
57
60
  }
58
61
  return extrudeFromSlices(options, baseSlice)
@@ -0,0 +1,24 @@
1
+ const geom2 = require('../../geometries/geom2')
2
+ const path2 = require('../../geometries/path2')
3
+
4
+ const extrudeLinearGeom2 = require('./extrudeLinearGeom2')
5
+
6
+ /*
7
+ * Extrude the given geometry using the given options.
8
+ *
9
+ * @param {Object} [options] - options for extrude
10
+ * @param {Array} [options.offset] - the direction of the extrusion as a 3D vector
11
+ * @param {Number} [options.twistAngle] - the final rotation (RADIANS) about the origin
12
+ * @param {Integer} [options.twistSteps] - the number of steps created to produce the twist (if any)
13
+ * @param {path2} geometry - the geometry to extrude
14
+ * @returns {geom3} the extruded 3D geometry
15
+ */
16
+ const extrudePath2 = (options, geometry) => {
17
+ if (!geometry.isClosed) throw new Error('extruded path must be closed')
18
+ // Convert path2 to geom2
19
+ const points = path2.toPoints(geometry)
20
+ const geometry2 = geom2.fromPoints(points)
21
+ return extrudeLinearGeom2(options, geometry2)
22
+ }
23
+
24
+ module.exports = extrudePath2
@@ -12,7 +12,7 @@ const extrudeRectangularGeom2 = require('./extrudeRectangularGeom2')
12
12
  * @param {Object} options - options for extrusion, if any
13
13
  * @param {Number} [options.size=1] - size of the rectangle
14
14
  * @param {Number} [options.height=1] - height of the extrusion
15
- * @param {...Object} geometry - the list of geometry to extrude
15
+ * @param {...Object} objects - the geometries to extrude
16
16
  * @return {Object|Array} the extruded object, or a list of extruded objects
17
17
  * @alias module:modeling/extrusions.extrudeRectangular
18
18
  *
@@ -12,11 +12,13 @@ test('extrudeRectangular (defaults)', (t) => {
12
12
 
13
13
  let obs = extrudeRectangular({ }, geometry1)
14
14
  let pts = geom3.toPoints(obs)
15
- t.is(pts.length, 50)
15
+ t.notThrows(() => geom3.validate(obs))
16
+ t.is(pts.length, 44)
16
17
 
17
18
  obs = extrudeRectangular({ }, geometry2)
18
19
  pts = geom3.toPoints(obs)
19
- t.is(pts.length, 40)
20
+ t.notThrows(() => geom3.validate(obs))
21
+ t.is(pts.length, 32)
20
22
  })
21
23
 
22
24
  test('extrudeRectangular (chamfer)', (t) => {
@@ -25,11 +27,13 @@ test('extrudeRectangular (chamfer)', (t) => {
25
27
 
26
28
  let obs = extrudeRectangular({ corners: 'chamfer' }, geometry1)
27
29
  let pts = geom3.toPoints(obs)
28
- t.is(pts.length, 42)
30
+ t.notThrows(() => geom3.validate(obs))
31
+ t.is(pts.length, 60)
29
32
 
30
33
  obs = extrudeRectangular({ corners: 'chamfer' }, geometry2)
31
34
  pts = geom3.toPoints(obs)
32
- t.is(pts.length, 32)
35
+ t.notThrows(() => geom3.validate(obs))
36
+ t.is(pts.length, 48)
33
37
  })
34
38
 
35
39
  test('extrudeRectangular (segments = 8, round)', (t) => {
@@ -38,26 +42,29 @@ test('extrudeRectangular (segments = 8, round)', (t) => {
38
42
 
39
43
  let obs = extrudeRectangular({ segments: 8, corners: 'round' }, geometry1)
40
44
  let pts = geom3.toPoints(obs)
41
- t.is(pts.length, 56)
45
+ t.notThrows(() => geom3.validate(obs))
46
+ t.is(pts.length, 84)
42
47
 
43
48
  obs = extrudeRectangular({ segments: 8, corners: 'round' }, geometry2)
44
49
  pts = geom3.toPoints(obs)
45
- t.is(pts.length, 40)
50
+ t.notThrows(() => geom3.validate(obs))
51
+ t.is(pts.length, 64)
46
52
  })
47
53
 
48
54
  test('extrudeRectangular (holes)', (t) => {
49
55
  const geometry2 = geom2.create([
50
- [[15.00000, 15.00000], [-15.00000, 15.00000]],
51
- [[-15.00000, 15.00000], [-15.00000, -15.00000]],
52
- [[-15.00000, -15.00000], [15.00000, -15.00000]],
53
- [[15.00000, -15.00000], [15.00000, 15.00000]],
54
- [[-5.00000, 5.00000], [5.00000, 5.00000]],
55
- [[5.00000, 5.00000], [5.00000, -5.00000]],
56
- [[5.00000, -5.00000], [-5.00000, -5.00000]],
57
- [[-5.00000, -5.00000], [-5.00000, 5.00000]]
56
+ [[15, 15], [-15, 15]],
57
+ [[-15, 15], [-15, -15]],
58
+ [[-15, -15], [15, -15]],
59
+ [[15, -15], [15, 15]],
60
+ [[-5, 5], [5, 5]],
61
+ [[5, 5], [5, -5]],
62
+ [[5, -5], [-5, -5]],
63
+ [[-5, -5], [-5, 5]]
58
64
  ])
59
65
 
60
66
  const obs = extrudeRectangular({ size: 2, height: 15, segments: 16, corners: 'round' }, geometry2)
61
67
  const pts = geom3.toPoints(obs)
62
- t.is(pts.length, 122)
68
+ t.notThrows(() => geom3.validate(obs))
69
+ t.is(pts.length, 192)
63
70
  })
@@ -11,6 +11,7 @@ test('extrudeRotate: (defaults) extruding of a geom2 produces an expected geom3'
11
11
 
12
12
  const geometry3 = extrudeRotate({ }, geometry2)
13
13
  const pts = geom3.toPoints(geometry3)
14
+ t.notThrows.skip(() => geom3.validate(geometry3))
14
15
  t.is(pts.length, 96)
15
16
  })
16
17
 
@@ -29,21 +30,24 @@ test('extrudeRotate: (angle) extruding of a geom2 produces an expected geom3', (
29
30
  [[26, -4.898587196589413e-16, -8], [7.0710678118654755, 7.071067811865475, -8], [18.38477631085024, 18.384776310850235, -8]],
30
31
  [[26, 4.898587196589413e-16, 8], [26, -4.898587196589413e-16, -8], [18.38477631085024, 18.384776310850235, -8]],
31
32
  [[26, 4.898587196589413e-16, 8], [18.38477631085024, 18.384776310850235, -8], [18.38477631085024, 18.384776310850235, 8]],
32
- [[18.38477631085024, 18.384776310850235, 7.999999999999998], [18.38477631085024, 18.384776310850235, -8],
33
- [7.071067811865478, 7.071067811865474, -8], [7.071067811865476, 7.071067811865475, 8]],
34
- [[10, 4.898587196589411e-16, 8], [10, -4.898587196589413e-16, -8],
35
- [26, -4.898587196589412e-16, -8], [26, 4.898587196589414e-16, 8]]
33
+ [[7.071067811865476, 7.0710678118654755, -8], [7.071067811865476, 7.0710678118654755, 8], [18.384776310850242, 18.384776310850235, 8]],
34
+ [[18.384776310850242, 18.384776310850235, 8], [18.384776310850242, 18.384776310850235, -8], [7.071067811865476, 7.0710678118654755, -8]],
35
+ [[26, 4.898587196589413e-16, 8], [10, 4.898587196589413e-16, 8], [10, -4.898587196589413e-16, -8]],
36
+ [[10, -4.898587196589413e-16, -8], [26, -4.898587196589413e-16, -8], [26, 4.898587196589413e-16, 8]]
36
37
  ]
37
- t.is(pts.length, 10)
38
+ t.notThrows(() => geom3.validate(geometry3))
39
+ t.is(pts.length, 12)
38
40
  t.true(comparePolygonsAsPoints(pts, exp))
39
41
 
40
42
  geometry3 = extrudeRotate({ segments: 4, angle: -250 * 0.017453292519943295 }, geometry2)
41
43
  pts = geom3.toPoints(geometry3)
42
- t.is(pts.length, 26)
44
+ t.notThrows(() => geom3.validate(geometry3))
45
+ t.is(pts.length, 28)
43
46
 
44
47
  geometry3 = extrudeRotate({ segments: 4, angle: 250 * 0.017453292519943295 }, geometry2)
45
48
  pts = geom3.toPoints(geometry3)
46
- t.is(pts.length, 26)
49
+ t.notThrows(() => geom3.validate(geometry3))
50
+ t.is(pts.length, 28)
47
51
  })
48
52
 
49
53
  test('extrudeRotate: (startAngle) extruding of a geom2 produces an expected geom3', (t) => {
@@ -57,6 +61,7 @@ test('extrudeRotate: (startAngle) extruding of a geom2 produces an expected geom
57
61
  [18.38477631085024, 18.384776310850235, 8],
58
62
  [-11.803752993228215, 23.166169628897567, 8]
59
63
  ]
64
+ t.notThrows.skip(() => geom3.validate(geometry3))
60
65
  t.is(pts.length, 40)
61
66
  t.true(comparePoints(pts[0], exp))
62
67
 
@@ -67,6 +72,7 @@ test('extrudeRotate: (startAngle) extruding of a geom2 produces an expected geom
67
72
  [18.38477631085024, -18.384776310850235, 8],
68
73
  [23.166169628897567, 11.803752993228215, 8]
69
74
  ]
75
+ t.notThrows.skip(() => geom3.validate(geometry3))
70
76
  t.is(pts.length, 40)
71
77
  t.true(comparePoints(pts[0], exp))
72
78
  })
@@ -77,22 +83,26 @@ test('extrudeRotate: (segments) extruding of a geom2 produces an expected geom3'
77
83
  // test segments
78
84
  let geometry3 = extrudeRotate({ segments: 4 }, geometry2)
79
85
  let pts = geom3.toPoints(geometry3)
86
+ t.notThrows.skip(() => geom3.validate(geometry3))
80
87
  t.is(pts.length, 32)
81
88
 
82
89
  geometry3 = extrudeRotate({ segments: 64 }, geometry2)
83
90
  pts = geom3.toPoints(geometry3)
91
+ t.notThrows.skip(() => geom3.validate(geometry3))
84
92
  t.is(pts.length, 512)
85
93
 
86
94
  // test overlapping edges
87
95
  geometry2 = geom2.fromPoints([[0, 0], [2, 1], [1, 2], [1, 3], [3, 4], [0, 5]])
88
96
  geometry3 = extrudeRotate({ segments: 8 }, geometry2)
89
97
  pts = geom3.toPoints(geometry3)
98
+ t.notThrows.skip(() => geom3.validate(geometry3))
90
99
  t.is(pts.length, 64)
91
100
 
92
101
  // test overlapping edges that produce hollow shape
93
102
  geometry2 = geom2.fromPoints([[30, 0], [30, 60], [0, 60], [0, 50], [10, 40], [10, 30], [0, 20], [0, 10], [10, 0]])
94
103
  geometry3 = extrudeRotate({ segments: 8 }, geometry2)
95
104
  pts = geom3.toPoints(geometry3)
105
+ t.notThrows.skip(() => geom3.validate(geometry3))
96
106
  t.is(pts.length, 80)
97
107
  })
98
108
 
@@ -107,16 +117,13 @@ test('extrudeRotate: (overlap +/-) extruding of a geom2 produces an expected geo
107
117
  [[7, -4.898587196589413e-16, -8], [4.898587196589413e-16, -2.999519565323715e-32, -8], [9.184850993605148e-16, 7, -8]],
108
118
  [[7, 4.898587196589413e-16, 8], [7, -4.898587196589413e-16, -8], [9.184850993605148e-16, 7, -8]],
109
119
  [[7, 4.898587196589413e-16, 8], [9.184850993605148e-16, 7, -8], [-6.123233995736767e-17, 7, 8]],
110
- [
111
- [-4.898587196589414e-16, 0, 8], [-6.123233995736777e-17, 6.999999999999999, 8],
112
- [9.18485099360515e-16, 7.000000000000001, -8], [4.898587196589413e-16, 0, -8]
113
- ],
114
- [
115
- [7, 4.898587196589413e-16, 8], [0, 4.898587196589413e-16, 8],
116
- [0, -4.898587196589413e-16, -8], [7, -4.898587196589413e-16, -8]
117
- ]
120
+ [[4.898587196589413e-16, -2.999519565323715e-32, -8], [-4.898587196589413e-16, 2.999519565323715e-32, 8], [-6.123233995736767e-17, 7, 8]],
121
+ [[-6.123233995736767e-17, 7, 8], [9.184850993605148e-16, 7, -8], [4.898587196589413e-16, -2.999519565323715e-32, -8]],
122
+ [[7, 4.898587196589413e-16, 8], [0, 4.898587196589413e-16, 8], [0, -4.898587196589413e-16, -8]],
123
+ [[0, -4.898587196589413e-16, -8], [7, -4.898587196589413e-16, -8], [7, 4.898587196589413e-16, 8]]
118
124
  ]
119
- t.is(pts.length, 6)
125
+ t.notThrows.skip(() => geom3.validate(obs))
126
+ t.is(pts.length, 8)
120
127
  t.true(comparePolygonsAsPoints(pts, exp))
121
128
 
122
129
  // overlap of Y axis; larger number of - points
@@ -137,18 +144,15 @@ test('extrudeRotate: (overlap +/-) extruding of a geom2 produces an expected geo
137
144
  [[0.7071067811865472, 0.7071067811865478, 8], [1.414213562373095, 1.4142135623730951, 4], [-1.2246467991473532e-16, 2, 4]],
138
145
  [[0.7071067811865472, 0.7071067811865478, 8], [-1.2246467991473532e-16, 2, 4], [-4.286263797015736e-16, 1, 8]],
139
146
  [[-3.4638242249419727e-16, 3.4638242249419736e-16, 8], [0.7071067811865472, 0.7071067811865478, 8], [-4.286263797015736e-16, 1, 8]],
140
- [
141
- [-4.898587196589412e-16, 0, 8], [-4.2862637970157346e-16, 0.9999999999999998, 8],
142
- [-1.2246467991473475e-16, 2.0000000000000004, 3.9999999999999964], [5.510910596163092e-16, 1.0000000000000004, -8],
143
- [4.898587196589414e-16, 0, -8]
144
- ],
145
- [
146
- [0, -4.898587196589413e-16, -8.000000000000002], [1.0000000000000027, -4.898587196589413e-16, -8.000000000000002],
147
- [2.000000000000001, 2.449293598294702e-16, 3.9999999999999964], [1.0000000000000004, 4.898587196589411e-16, 8],
148
- [0, 4.898587196589411e-16, 8]
149
- ]
147
+ [[5.51091059616309e-16, 1, -8], [4.898587196589413e-16, -2.999519565323715e-32, -8], [-4.898587196589415e-16, 2.9995195653237163e-32, 8]],
148
+ [[-4.898587196589415e-16, 2.9995195653237163e-32, 8], [-4.286263797015738e-16, 1, 8], [-1.2246467991473544e-16, 2, 4]],
149
+ [[-1.2246467991473544e-16, 2, 4], [5.51091059616309e-16, 1, -8], [-4.898587196589415e-16, 2.9995195653237163e-32, 8]],
150
+ [[0, 4.898587196589413e-16, 8], [0, -4.898587196589413e-16, -8], [1, -4.898587196589413e-16, -8]],
151
+ [[2, 2.4492935982947064e-16, 4], [1, 4.898587196589413e-16, 8], [0, 4.898587196589413e-16, 8]],
152
+ [[0, 4.898587196589413e-16, 8], [1, -4.898587196589413e-16, -8], [2, 2.4492935982947064e-16, 4]]
150
153
  ]
151
- t.is(pts.length, 14)
154
+ t.notThrows.skip(() => geom3.validate(obs))
155
+ t.is(pts.length, 18)
152
156
  t.true(comparePolygonsAsPoints(pts, exp))
153
157
  })
154
158
 
@@ -60,7 +60,7 @@ const projectGeom3 = (options, geometry) => {
60
60
  * @param {Object} options - options for project
61
61
  * @param {Array} [options.axis=[0,0,1]] the axis of the plane (default is Z axis)
62
62
  * @param {Array} [options.origin=[0,0,0]] the origin of the plane
63
- * @param {...Object} geometry - the list of 3D geometry to project
63
+ * @param {...Object} objects - the list of 3D geometry to project
64
64
  * @return {geom2|Array} the projected 2D geometry, or a list of 2D projected geometry
65
65
  * @alias module:modeling/extrusions.project
66
66
  *