@jscad/modeling 2.9.0 → 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 (86) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/jscad-modeling.min.js +410 -395
  3. package/package.json +2 -2
  4. package/src/geometries/geom2/index.d.ts +1 -0
  5. package/src/geometries/geom2/index.js +2 -1
  6. package/src/geometries/geom2/validate.d.ts +3 -0
  7. package/src/geometries/geom2/validate.js +36 -0
  8. package/src/geometries/geom3/index.d.ts +1 -0
  9. package/src/geometries/geom3/index.js +2 -1
  10. package/src/geometries/geom3/isA.js +1 -1
  11. package/src/geometries/geom3/validate.d.ts +3 -0
  12. package/src/geometries/geom3/validate.js +62 -0
  13. package/src/geometries/path2/index.d.ts +1 -0
  14. package/src/geometries/path2/index.js +2 -1
  15. package/src/geometries/path2/validate.d.ts +3 -0
  16. package/src/geometries/path2/validate.js +41 -0
  17. package/src/geometries/poly2/arePointsInside.js +0 -35
  18. package/src/geometries/poly3/index.d.ts +1 -0
  19. package/src/geometries/poly3/index.js +2 -1
  20. package/src/geometries/poly3/measureArea.test.js +16 -16
  21. package/src/geometries/poly3/measureBoundingSphere.test.js +8 -8
  22. package/src/geometries/poly3/validate.d.ts +4 -0
  23. package/src/geometries/poly3/validate.js +50 -0
  24. package/src/measurements/measureCenterOfMass.test.js +2 -2
  25. package/src/operations/booleans/intersect.test.js +8 -0
  26. package/src/operations/booleans/scission.test.js +4 -4
  27. package/src/operations/booleans/subtract.test.js +8 -0
  28. package/src/operations/booleans/trees/Node.js +10 -16
  29. package/src/operations/booleans/trees/PolygonTreeNode.js +13 -14
  30. package/src/operations/booleans/trees/Tree.js +1 -2
  31. package/src/operations/booleans/trees/splitPolygonByPlane.js +2 -3
  32. package/src/operations/booleans/union.test.js +27 -0
  33. package/src/operations/expansions/expand.test.js +30 -21
  34. package/src/operations/expansions/offset.test.js +25 -0
  35. package/src/operations/extrusions/earcut/assignHoles.js +7 -3
  36. package/src/operations/extrusions/earcut/assignHoles.test.js +50 -4
  37. package/src/operations/extrusions/earcut/linkedList.js +1 -1
  38. package/src/operations/extrusions/extrudeFromSlices.test.js +14 -8
  39. package/src/operations/extrusions/extrudeLinear.test.js +15 -9
  40. package/src/operations/extrusions/extrudeRectangular.test.js +15 -8
  41. package/src/operations/extrusions/extrudeRotate.test.js +12 -0
  42. package/src/operations/extrusions/project.test.js +5 -5
  43. package/src/operations/hulls/hull.test.js +24 -1
  44. package/src/operations/hulls/hullChain.test.js +6 -4
  45. package/src/operations/hulls/hullPath2.test.js +1 -1
  46. package/src/operations/modifiers/generalize.test.js +6 -0
  47. package/src/operations/transforms/align.test.js +12 -0
  48. package/src/operations/transforms/center.test.js +12 -0
  49. package/src/operations/transforms/mirror.test.js +16 -0
  50. package/src/operations/transforms/rotate.test.js +10 -0
  51. package/src/operations/transforms/scale.test.js +15 -0
  52. package/src/operations/transforms/transform.test.js +5 -0
  53. package/src/operations/transforms/translate.test.js +16 -0
  54. package/src/primitives/arc.test.js +11 -0
  55. package/src/primitives/circle.test.js +15 -9
  56. package/src/primitives/cube.test.js +3 -0
  57. package/src/primitives/cuboid.test.js +9 -24
  58. package/src/primitives/cylinder.test.js +7 -4
  59. package/src/primitives/cylinderElliptic.js +13 -6
  60. package/src/primitives/cylinderElliptic.test.js +72 -50
  61. package/src/primitives/ellipse.js +3 -1
  62. package/src/primitives/ellipse.test.js +14 -8
  63. package/src/primitives/ellipsoid.js +6 -4
  64. package/src/primitives/ellipsoid.test.js +84 -80
  65. package/src/primitives/geodesicSphere.test.js +3 -0
  66. package/src/primitives/line.test.js +1 -0
  67. package/src/primitives/polygon.test.js +15 -10
  68. package/src/primitives/polyhedron.test.js +14 -42
  69. package/src/primitives/rectangle.test.js +3 -0
  70. package/src/primitives/roundedCuboid.test.js +5 -0
  71. package/src/primitives/roundedCylinder.js +6 -4
  72. package/src/primitives/roundedCylinder.test.js +40 -36
  73. package/src/primitives/roundedRectangle.test.js +5 -0
  74. package/src/primitives/sphere.test.js +52 -73
  75. package/src/primitives/square.test.js +3 -0
  76. package/src/primitives/star.test.js +6 -0
  77. package/src/primitives/torus.test.js +7 -0
  78. package/src/primitives/triangle.test.js +7 -0
  79. package/src/utils/areAllShapesTheSameType.js +2 -2
  80. package/src/utils/areAllShapesTheSameType.test.js +17 -0
  81. package/src/utils/index.d.ts +1 -0
  82. package/src/utils/index.js +3 -1
  83. package/src/utils/trigonometry.d.ts +2 -0
  84. package/src/utils/trigonometry.js +35 -0
  85. package/src/utils/trigonometry.test.js +25 -0
  86. package/test/helpers/nearlyEqual.js +4 -1
@@ -36,6 +36,7 @@ test('extrudeFromSlices (defaults)', (t) => {
36
36
  geometry3 = extrudeFromSlices({ }, poly2)
37
37
  pts = geom3.toPoints(geometry3)
38
38
 
39
+ t.notThrows(() => geom3.validate(geometry3))
39
40
  t.is(pts.length, 12)
40
41
  t.true(comparePolygonsAsPoints(pts, exp))
41
42
  })
@@ -68,6 +69,7 @@ test('extrudeFromSlices (torus)', (t) => {
68
69
  }, hex
69
70
  )
70
71
  const pts = geom3.toPoints(geometry3)
72
+ t.notThrows(() => geom3.validate(geometry3))
71
73
  t.is(pts.length, 96)
72
74
  })
73
75
 
@@ -86,6 +88,8 @@ test('extrudeFromSlices (same shape, changing dimensions)', (t) => {
86
88
  }, base
87
89
  )
88
90
  const pts = geom3.toPoints(geometry3)
91
+ // expected to throw because capEnd is false (non-closed geometry)
92
+ t.throws(() => geom3.validate(geometry3))
89
93
  t.is(pts.length, 26)
90
94
  })
91
95
 
@@ -103,20 +107,21 @@ test('extrudeFromSlices (changing shape, changing dimensions)', (t) => {
103
107
  }, base
104
108
  )
105
109
  const pts = geom3.toPoints(geometry3)
110
+ t.notThrows.skip(() => geom3.validate(geometry3))
106
111
  t.is(pts.length, 304)
107
112
  })
108
113
 
109
114
  test('extrudeFromSlices (holes)', (t) => {
110
115
  const geometry2 = geom2.create(
111
116
  [
112
- [[-10.0, 10.0], [-10.0, -10.0]],
113
- [[-10.0, -10.0], [10.0, -10.0]],
114
- [[10.0, -10.0], [10.0, 10.0]],
115
- [[10.0, 10.0], [-10.0, 10.0]],
116
- [[-5.0, -5.0], [-5.0, 5.0]],
117
- [[5.0, -5.0], [-5.0, -5.0]],
118
- [[5.0, 5.0], [5.0, -5.0]],
119
- [[-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]]
120
125
  ]
121
126
  )
122
127
  const geometry3 = extrudeFromSlices({ }, geometry2)
@@ -155,6 +160,7 @@ test('extrudeFromSlices (holes)', (t) => {
155
160
  [[-5, -5, 0], [5, -5, 0], [-10, -10, 0]],
156
161
  [[-10, -10, 0], [-10, 10, 0], [-5, -5, 0]]
157
162
  ]
163
+ t.notThrows(() => geom3.validate(geometry3))
158
164
  t.is(pts.length, 32)
159
165
  t.true(comparePolygonsAsPoints(pts, exp))
160
166
  })
@@ -25,6 +25,7 @@ test('extrudeLinear (defaults)', (t) => {
25
25
  [[5, 5, 0], [5, -5, 0], [-5, -5, 0]],
26
26
  [[-5, -5, 0], [-5, 5, 0], [5, 5, 0]]
27
27
  ]
28
+ t.notThrows(() => geom3.validate(geometry3))
28
29
  t.is(pts.length, 12)
29
30
  t.true(comparePolygonsAsPoints(pts, exp))
30
31
  })
@@ -48,6 +49,7 @@ test('extrudeLinear (no twist)', (t) => {
48
49
  [[5, 5, 0], [5, -5, 0], [-5, -5, 0]],
49
50
  [[-5, -5, 0], [-5, 5, 0], [5, 5, 0]]
50
51
  ]
52
+ t.notThrows(() => geom3.validate(geometry3))
51
53
  t.is(pts.length, 12)
52
54
  t.true(comparePolygonsAsPoints(pts, exp))
53
55
 
@@ -67,6 +69,7 @@ test('extrudeLinear (no twist)', (t) => {
67
69
  [[5, -5, 0], [5, 5, 0], [-5, 5, 0]],
68
70
  [[-5, 5, 0], [-5, -5, 0], [5, -5, 0]]
69
71
  ]
72
+ t.notThrows(() => geom3.validate(geometry3))
70
73
  t.is(pts.length, 12)
71
74
  t.true(comparePolygonsAsPoints(pts, exp))
72
75
  })
@@ -98,6 +101,7 @@ test('extrudeLinear (twist)', (t) => {
98
101
  [[5, 5, 0], [5, -5, 0], [-5, -5, 0]],
99
102
  [[-5, -5, 0], [-5, 5, 0], [5, 5, 0]]
100
103
  ]
104
+ t.notThrows(() => geom3.validate(geometry3))
101
105
  t.is(pts.length, 12)
102
106
  t.true(comparePolygonsAsPoints(pts, exp))
103
107
 
@@ -138,19 +142,20 @@ test('extrudeLinear (twist)', (t) => {
138
142
 
139
143
  geometry3 = extrudeLinear({ height: 15, twistAngle: Math.PI / 2, twistSteps: 30 }, geometry2)
140
144
  pts = geom3.toPoints(geometry3)
145
+ t.notThrows(() => geom3.validate(geometry3))
141
146
  t.is(pts.length, 244)
142
147
  })
143
148
 
144
149
  test('extrudeLinear (holes)', (t) => {
145
150
  const geometry2 = geom2.create([
146
- [[-5.00000, 5.00000], [-5.00000, -5.00000]],
147
- [[-5.00000, -5.00000], [5.00000, -5.00000]],
148
- [[5.00000, -5.00000], [5.00000, 5.00000]],
149
- [[5.00000, 5.00000], [-5.00000, 5.00000]],
150
- [[-2.00000, -2.00000], [-2.00000, 2.00000]],
151
- [[2.00000, -2.00000], [-2.00000, -2.00000]],
152
- [[2.00000, 2.00000], [2.00000, -2.00000]],
153
- [[-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]]
154
159
  ])
155
160
  const geometry3 = extrudeLinear({ height: 15 }, geometry2)
156
161
  const pts = geom3.toPoints(geometry3)
@@ -188,6 +193,7 @@ test('extrudeLinear (holes)', (t) => {
188
193
  [[-2, -2, 0], [2, -2, 0], [-5, -5, 0]],
189
194
  [[-5, -5, 0], [-5, 5, 0], [-2, -2, 0]]
190
195
  ]
196
+ t.notThrows(() => geom3.validate(geometry3))
191
197
  t.is(pts.length, 32)
192
198
  t.true(comparePolygonsAsPoints(pts, exp))
193
199
  })
@@ -195,7 +201,7 @@ test('extrudeLinear (holes)', (t) => {
195
201
  test('extrudeLinear (path2)', (t) => {
196
202
  const geometry2 = path2.fromPoints({ closed: true }, [[0, 0], [12, 0], [6, 10]])
197
203
  const geometry3 = extrudeLinear({ height: 15 }, geometry2)
198
- t.true(geom3.isA(geometry3))
204
+ t.notThrows(() => geom3.validate(geometry3))
199
205
  const pts = geom3.toPoints(geometry3)
200
206
  const exp = [
201
207
  [[6, 10, 0], [0, 0, 0], [0, 0, 15]],
@@ -12,10 +12,12 @@ test('extrudeRectangular (defaults)', (t) => {
12
12
 
13
13
  let obs = extrudeRectangular({ }, geometry1)
14
14
  let pts = geom3.toPoints(obs)
15
+ t.notThrows(() => geom3.validate(obs))
15
16
  t.is(pts.length, 44)
16
17
 
17
18
  obs = extrudeRectangular({ }, geometry2)
18
19
  pts = geom3.toPoints(obs)
20
+ t.notThrows(() => geom3.validate(obs))
19
21
  t.is(pts.length, 32)
20
22
  })
21
23
 
@@ -25,10 +27,12 @@ test('extrudeRectangular (chamfer)', (t) => {
25
27
 
26
28
  let obs = extrudeRectangular({ corners: 'chamfer' }, geometry1)
27
29
  let pts = geom3.toPoints(obs)
30
+ t.notThrows(() => geom3.validate(obs))
28
31
  t.is(pts.length, 60)
29
32
 
30
33
  obs = extrudeRectangular({ corners: 'chamfer' }, geometry2)
31
34
  pts = geom3.toPoints(obs)
35
+ t.notThrows(() => geom3.validate(obs))
32
36
  t.is(pts.length, 48)
33
37
  })
34
38
 
@@ -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)
45
+ t.notThrows(() => geom3.validate(obs))
41
46
  t.is(pts.length, 84)
42
47
 
43
48
  obs = extrudeRectangular({ segments: 8, corners: 'round' }, geometry2)
44
49
  pts = geom3.toPoints(obs)
50
+ t.notThrows(() => geom3.validate(obs))
45
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)
68
+ t.notThrows(() => geom3.validate(obs))
62
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
 
@@ -34,15 +35,18 @@ test('extrudeRotate: (angle) extruding of a geom2 produces an expected geom3', (
34
35
  [[26, 4.898587196589413e-16, 8], [10, 4.898587196589413e-16, 8], [10, -4.898587196589413e-16, -8]],
35
36
  [[10, -4.898587196589413e-16, -8], [26, -4.898587196589413e-16, -8], [26, 4.898587196589413e-16, 8]]
36
37
  ]
38
+ t.notThrows(() => geom3.validate(geometry3))
37
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)
44
+ t.notThrows(() => geom3.validate(geometry3))
42
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)
49
+ t.notThrows(() => geom3.validate(geometry3))
46
50
  t.is(pts.length, 28)
47
51
  })
48
52
 
@@ -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
 
@@ -112,6 +122,7 @@ test('extrudeRotate: (overlap +/-) extruding of a geom2 produces an expected geo
112
122
  [[7, 4.898587196589413e-16, 8], [0, 4.898587196589413e-16, 8], [0, -4.898587196589413e-16, -8]],
113
123
  [[0, -4.898587196589413e-16, -8], [7, -4.898587196589413e-16, -8], [7, 4.898587196589413e-16, 8]]
114
124
  ]
125
+ t.notThrows.skip(() => geom3.validate(obs))
115
126
  t.is(pts.length, 8)
116
127
  t.true(comparePolygonsAsPoints(pts, exp))
117
128
 
@@ -140,6 +151,7 @@ test('extrudeRotate: (overlap +/-) extruding of a geom2 produces an expected geo
140
151
  [[2, 2.4492935982947064e-16, 4], [1, 4.898587196589413e-16, 8], [0, 4.898587196589413e-16, 8]],
141
152
  [[0, 4.898587196589413e-16, 8], [1, -4.898587196589413e-16, -8], [2, 2.4492935982947064e-16, 4]]
142
153
  ]
154
+ t.notThrows.skip(() => geom3.validate(obs))
143
155
  t.is(pts.length, 18)
144
156
  t.true(comparePolygonsAsPoints(pts, exp))
145
157
  })
@@ -16,14 +16,14 @@ test('project (defaults)', (t) => {
16
16
 
17
17
  const results = project({ }, geometry0, geometry1, geometry2, geometry3, geometry4)
18
18
  t.is(results.length, 5)
19
- t.true(geom2.isA(results[0]))
20
- t.true(geom2.isA(results[1]))
19
+ t.notThrows(() => geom2.validate(results[0]))
20
+ t.notThrows(() => geom2.validate(results[1]))
21
21
  t.is(results[2], geometry2)
22
22
  t.is(results[3], geometry3)
23
23
  t.is(results[4], geometry4)
24
24
 
25
25
  const result = project({ }, torus({ outerSegments: 4 }))
26
- t.true(geom2.isA(result))
26
+ t.notThrows(() => geom2.validate(result))
27
27
  const pts = geom2.toPoints(result)
28
28
  const exp = [
29
29
  [0, -2.9999933333333333],
@@ -40,7 +40,7 @@ test('project (defaults)', (t) => {
40
40
 
41
41
  test('project (X and Y axis)', (t) => {
42
42
  let result = project({ axis: [1, 0, 0], origin: [1, 0, 0] }, torus({ outerSegments: 4 }))
43
- t.true(geom2.isA(result))
43
+ t.notThrows(() => geom2.validate(result))
44
44
  let pts = geom2.toPoints(result)
45
45
  let exp = [
46
46
  [-1.0000200000000001, -3.999986666666667],
@@ -81,7 +81,7 @@ test('project (X and Y axis)', (t) => {
81
81
  t.true(comparePoints(pts, exp))
82
82
 
83
83
  result = project({ axis: [0, 1, 0], origin: [0, -1, 0] }, torus({ outerSegments: 4 }))
84
- t.true(geom2.isA(result))
84
+ t.notThrows(() => geom2.validate(result))
85
85
  pts = geom2.toPoints(result)
86
86
  exp = [
87
87
  [3.999986666666667, -1.0000200000000001],
@@ -16,12 +16,14 @@ test('hull (single, geom2)', (t) => {
16
16
  let obs = hull(geometry)
17
17
  let pts = geom2.toPoints(obs)
18
18
 
19
+ t.notThrows(() => geom2.validate(geometry))
19
20
  t.is(pts.length, 0)
20
21
 
21
22
  geometry = geom2.fromPoints([[5, 5], [-5, 5], [-5, -5], [5, -5]])
22
23
  obs = hull(geometry)
23
24
  pts = geom2.toPoints(obs)
24
25
 
26
+ t.notThrows(() => geom2.validate(geometry))
25
27
  t.is(pts.length, 4)
26
28
 
27
29
  // convex C shape
@@ -40,6 +42,7 @@ test('hull (single, geom2)', (t) => {
40
42
  obs = hull(geometry)
41
43
  pts = geom2.toPoints(obs)
42
44
 
45
+ t.notThrows(() => geom2.validate(geometry))
43
46
  t.is(pts.length, 7)
44
47
  })
45
48
 
@@ -66,23 +69,27 @@ test('hull (multiple, overlapping, geom2)', (t) => {
66
69
  let obs = hull(geometry1, geometry1)
67
70
  let pts = geom2.toPoints(obs)
68
71
 
72
+ t.notThrows(() => geom2.validate(obs))
69
73
  t.is(pts.length, 4)
70
74
 
71
75
  // one inside another
72
76
  obs = hull(geometry1, geometry2)
73
77
  pts = geom2.toPoints(obs)
74
78
 
79
+ t.notThrows(() => geom2.validate(obs))
75
80
  t.is(pts.length, 4)
76
81
 
77
82
  // one overlapping another
78
83
  obs = hull(geometry1, geometry3)
79
84
  pts = geom2.toPoints(obs)
80
85
 
86
+ t.notThrows(() => geom2.validate(obs))
81
87
  t.is(pts.length, 8)
82
88
 
83
89
  obs = hull(geometry2, geometry4)
84
90
  pts = geom2.toPoints(obs)
85
91
 
92
+ t.notThrows(() => geom2.validate(obs))
86
93
  t.is(pts.length, 7)
87
94
  })
88
95
 
@@ -108,22 +115,27 @@ test('hull (multiple, various, geom2)', (t) => {
108
115
 
109
116
  let obs = hull(geometry1, geometry2)
110
117
  let pts = geom2.toPoints(obs)
118
+ t.notThrows(() => geom2.validate(obs))
111
119
  t.is(pts.length, 5)
112
120
 
113
121
  obs = hull(geometry1, geometry3)
114
122
  pts = geom2.toPoints(obs)
123
+ t.notThrows(() => geom2.validate(obs))
115
124
  t.is(pts.length, 5)
116
125
 
117
126
  obs = hull(geometry2, geometry3)
118
127
  pts = geom2.toPoints(obs)
128
+ t.notThrows(() => geom2.validate(obs))
119
129
  t.is(pts.length, 5)
120
130
 
121
131
  obs = hull(geometry1, geometry2, geometry3)
122
132
  pts = geom2.toPoints(obs)
133
+ t.notThrows(() => geom2.validate(obs))
123
134
  t.is(pts.length, 6)
124
135
 
125
136
  obs = hull(geometry5, geometry4)
126
137
  pts = geom2.toPoints(obs)
138
+ t.notThrows(() => geom2.validate(obs))
127
139
  t.is(pts.length, 8)
128
140
  })
129
141
 
@@ -133,6 +145,7 @@ test('hull (single, path2)', (t) => {
133
145
  let obs = hull(geometry)
134
146
  let pts = path2.toPoints(obs)
135
147
 
148
+ t.notThrows(() => path2.validate(obs))
136
149
  t.is(pts.length, 0)
137
150
 
138
151
  geometry = path2.fromPoints({}, [[0, 0], [5, 0], [5, 10], [4, 1]])
@@ -140,6 +153,7 @@ test('hull (single, path2)', (t) => {
140
153
  obs = hull(geometry)
141
154
  pts = path2.toPoints(obs)
142
155
 
156
+ t.notThrows(() => path2.validate(obs))
143
157
  t.is(pts.length, 3)
144
158
  })
145
159
 
@@ -165,22 +179,27 @@ test('hull (multiple, various, path2)', (t) => {
165
179
 
166
180
  let obs = hull(geometry1, geometry2)
167
181
  let pts = path2.toPoints(obs)
182
+ t.notThrows(() => path2.validate(obs))
168
183
  t.is(pts.length, 5)
169
184
 
170
185
  obs = hull(geometry1, geometry3)
171
186
  pts = path2.toPoints(obs)
187
+ t.notThrows(() => path2.validate(obs))
172
188
  t.is(pts.length, 5)
173
189
 
174
190
  obs = hull(geometry2, geometry3)
175
191
  pts = path2.toPoints(obs)
192
+ t.notThrows(() => path2.validate(obs))
176
193
  t.is(pts.length, 5)
177
194
 
178
195
  obs = hull(geometry1, geometry2, geometry3)
179
196
  pts = path2.toPoints(obs)
197
+ t.notThrows(() => path2.validate(obs))
180
198
  t.is(pts.length, 6)
181
199
 
182
200
  obs = hull(geometry5, geometry4)
183
201
  pts = path2.toPoints(obs)
202
+ t.notThrows(() => path2.validate(obs))
184
203
  t.is(pts.length, 8)
185
204
  })
186
205
 
@@ -190,6 +209,7 @@ test('hull (single, geom3)', (t) => {
190
209
  let obs = hull(geometry)
191
210
  let pts = geom3.toPoints(obs)
192
211
 
212
+ t.notThrows(() => geom3.validate(obs))
193
213
  t.is(pts.length, 0)
194
214
 
195
215
  geometry = sphere({ radius: 2, segments: 8 })
@@ -197,6 +217,7 @@ test('hull (single, geom3)', (t) => {
197
217
  obs = hull(geometry)
198
218
  pts = geom3.toPoints(obs)
199
219
 
220
+ t.notThrows.skip(() => geom3.validate(obs))
200
221
  t.is(pts.length, 32)
201
222
  })
202
223
 
@@ -214,6 +235,7 @@ test('hull (multiple, geom3)', (t) => {
214
235
  [[1, -1, 1], [-1, -1, 1], [-1, -1, -1], [1, -1, -1]]
215
236
  ]
216
237
 
238
+ t.notThrows(() => geom3.validate(obs))
217
239
  t.is(pts.length, 6)
218
240
  t.true(comparePolygonsAsPoints(pts, exp))
219
241
 
@@ -236,6 +258,7 @@ test('hull (multiple, geom3)', (t) => {
236
258
  [[1, 1, -1], [6.5, 6.5, 3.5], [6.5, 3.5, 3.5], [1, -1, -1]]
237
259
  ]
238
260
 
261
+ t.notThrows(() => geom3.validate(obs))
239
262
  t.is(pts.length, 12)
240
263
  t.true(comparePolygonsAsPoints(pts, exp))
241
264
  })
@@ -248,6 +271,6 @@ test('hull (multiple, overlapping, geom3)', (t) => {
248
271
  const obs = hull(geometry1, geometry2, geometry3)
249
272
  const pts = geom3.toPoints(obs)
250
273
 
251
- // t.is(pts.length, 160)
274
+ t.notThrows(() => geom3.validate(obs))
252
275
  t.is(pts.length, 92)
253
276
  })
@@ -12,12 +12,14 @@ test('hullChain (two, geom2)', (t) => {
12
12
  let obs = hullChain(geometry1, geometry1)
13
13
  let pts = geom2.toPoints(obs)
14
14
 
15
+ t.notThrows(() => geom2.validate(obs))
15
16
  t.is(pts.length, 4)
16
17
 
17
18
  // different
18
19
  obs = hullChain(geometry1, geometry2)
19
20
  pts = geom2.toPoints(obs)
20
21
 
22
+ t.notThrows(() => geom2.validate(obs))
21
23
  t.is(pts.length, 6)
22
24
  })
23
25
 
@@ -31,16 +33,16 @@ test('hullChain (three, geom2)', (t) => {
31
33
  let pts = geom2.toPoints(obs)
32
34
 
33
35
  // the sides change based on the bestplane chosen in trees/Node.js
36
+ t.notThrows(() => geom2.validate(obs))
34
37
  t.is(pts.length, 10)
35
- // t.is(pts.length, 11)
36
38
 
37
39
  // closed
38
40
  obs = hullChain(geometry1, geometry2, geometry3, geometry1)
39
41
  pts = geom2.toPoints(obs)
40
42
 
41
43
  // the sides change based on the bestplane chosen in trees/Node.js
44
+ t.notThrows(() => geom2.validate(obs))
42
45
  t.is(pts.length, 10)
43
- // t.is(pts.length, 13)
44
46
  })
45
47
 
46
48
  test('hullChain (three, geom3)', (t) => {
@@ -73,13 +75,13 @@ test('hullChain (three, geom3)', (t) => {
73
75
  let obs = hullChain(geometry1, geometry2, geometry3)
74
76
  let pts = geom3.toPoints(obs)
75
77
 
76
- // t.is(pts.length, 27)
78
+ t.notThrows.skip(() => geom3.validate(obs))
77
79
  t.is(pts.length, 23)
78
80
 
79
81
  // closed
80
82
  obs = hullChain(geometry1, geometry2, geometry3, geometry1)
81
83
  pts = geom3.toPoints(obs)
82
84
 
83
- // t.is(pts.length, 45)
85
+ t.notThrows.skip(() => geom3.validate(obs))
84
86
  t.is(pts.length, 28)
85
87
  })
@@ -10,7 +10,7 @@ test('hullPath2', (t) => {
10
10
  const geometry2 = path2.fromPoints({ closed }, [[0, 0], [4, -4], [4, 4]])
11
11
 
12
12
  const obs = hullPath2(geometry1, geometry2)
13
- t.true(path2.isA(obs))
13
+ t.notThrows(() => path2.validate(obs))
14
14
  const pts = path2.toPoints(obs)
15
15
  t.is(pts.length, 4)
16
16
  })
@@ -28,6 +28,7 @@ test('generalize: generalize of a geom3 produces an expected geom3', (t) => {
28
28
  [[-1.5707963267948966, -0.7853981633974483, 3.141592653589793], [1.5707963267948966, -0.7853981633974483, 3.141592653589793],
29
29
  [1.5707963267948966, 0.7853981633974483, 3.141592653589793], [-1.5707963267948966, 0.7853981633974483, 3.141592653589793]]
30
30
  ]
31
+ t.notThrows(() => geom3.validate(result))
31
32
  t.true(comparePolygonsAsPoints(pts, exp))
32
33
 
33
34
  // apply snap only
@@ -47,6 +48,7 @@ test('generalize: generalize of a geom3 produces an expected geom3', (t) => {
47
48
  [[-1.5707910908071407, -0.7854138713607164, 3.1415821816142815], [1.5707910908071407, -0.7854138713607164, 3.1415821816142815],
48
49
  [1.5707910908071407, 0.7854138713607164, 3.1415821816142815], [-1.5707910908071407, 0.7854138713607164, 3.1415821816142815]]
49
50
  ]
51
+ t.notThrows(() => geom3.validate(result))
50
52
  t.true(comparePolygonsAsPoints(pts, exp))
51
53
 
52
54
  // apply triangulate only
@@ -78,6 +80,7 @@ test('generalize: generalize of a geom3 produces an expected geom3', (t) => {
78
80
  [[-1.5707963267948966, -0.7853981633974483, 3.141592653589793], [1.5707963267948966, 0.7853981633974483, 3.141592653589793],
79
81
  [-1.5707963267948966, 0.7853981633974483, 3.141592653589793]]
80
82
  ]
83
+ t.notThrows(() => geom3.validate(result))
81
84
  t.true(comparePolygonsAsPoints(pts, exp))
82
85
 
83
86
  const geometry2 = result // save the triangles for another test
@@ -99,6 +102,7 @@ test('generalize: generalize of a geom3 produces an expected geom3', (t) => {
99
102
  [[-1.5707963267948966, -0.7853981633974483, 3.141592653589793], [1.5707963267948966, -0.7853981633974483, 3.141592653589793],
100
103
  [1.5707963267948966, 0.7853981633974483, 3.141592653589793], [-1.5707963267948966, 0.7853981633974483, 3.141592653589793]]
101
104
  ]
105
+ t.notThrows(() => geom3.validate(result))
102
106
  t.true(comparePolygonsAsPoints(pts, exp))
103
107
 
104
108
  // apply repairs only (triangles)
@@ -130,6 +134,7 @@ test('generalize: generalize of a geom3 produces an expected geom3', (t) => {
130
134
  [[-1.5707963267948966, -0.7853981633974483, 3.141592653589793], [1.5707963267948966, 0.7853981633974483, 3.141592653589793],
131
135
  [-1.5707963267948966, 0.7853981633974483, 3.141592653589793]]
132
136
  ]
137
+ t.notThrows(() => geom3.validate(result))
133
138
  t.true(comparePolygonsAsPoints(pts, exp))
134
139
  })
135
140
 
@@ -190,5 +195,6 @@ test('generalize: generalize of a geom3 with T junctions produces an expected ge
190
195
  [[0, 1, 1], [-1, 1, 1], [0, 0, 1]],
191
196
  [[-1, 1, 1], [-1, 0, 1], [0, 0, 1]]
192
197
  ]
198
+ t.notThrows(() => geom3.validate(result))
193
199
  t.true(comparePolygonsAsPoints(pts, exp))
194
200
  })
@@ -1,6 +1,7 @@
1
1
  const test = require('ava')
2
2
 
3
3
  const { comparePoints } = require('../../../test/helpers')
4
+ const { geom3 } = require('../../geometries')
4
5
  const { measureBoundingBox, measureAggregateBoundingBox } = require('../../measurements')
5
6
  const { cube } = require('../../primitives')
6
7
 
@@ -11,6 +12,7 @@ test('align: single object returns geometry unchanged if all axes are none', (t)
11
12
  const aligned = align({ modes: ['none', 'none', 'none'] }, original)
12
13
  const bounds = measureBoundingBox(aligned)
13
14
  const expectedBounds = [[8, 8, 8], [12, 12, 12]]
15
+ t.notThrows(() => geom3.validate(aligned))
14
16
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected. Result: ' + JSON.stringify(bounds))
15
17
  })
16
18
 
@@ -19,6 +21,7 @@ test('align: single objects returns geometry aligned, different modes on each ax
19
21
  const aligned = align({ modes: ['center', 'min', 'max'] }, original)
20
22
  const bounds = measureBoundingBox(aligned)
21
23
  const expectedBounds = [[-2, 0, -4], [2, 4, 0]]
24
+ t.notThrows(() => geom3.validate(aligned))
22
25
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected. Result: ' + JSON.stringify(bounds))
23
26
  })
24
27
 
@@ -27,6 +30,7 @@ test('align: unfilled modes and relativeTo arrays return results with expected v
27
30
  const aligned = align({ modes: ['center'], relativeTo: [0] }, original)
28
31
  const bounds = measureBoundingBox(aligned)
29
32
  const expectedBounds = [[-2, 8, 8], [2, 12, 12]]
33
+ t.notThrows(() => geom3.validate(aligned))
30
34
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected. Result: ' + JSON.stringify(bounds))
31
35
  })
32
36
 
@@ -38,6 +42,8 @@ test('align: multiple objects grouped returns geometry aligned, different modes
38
42
  const aligned = align({ modes: ['center', 'min', 'max'], relativeTo: [6, -10, 0], grouped: true }, original)
39
43
  const bounds = measureAggregateBoundingBox(aligned)
40
44
  const expectedBounds = [[1.5, -10, -9], [10.5, -1, 0]]
45
+ t.notThrows(() => geom3.validate(aligned[0]))
46
+ t.notThrows(() => geom3.validate(aligned[1]))
41
47
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected. Result: ' + JSON.stringify(bounds))
42
48
  })
43
49
 
@@ -49,6 +55,8 @@ test('align: multiple objects ungrouped returns geometry aligned, different mode
49
55
  const aligned = align({ modes: ['center', 'min', 'max'], relativeTo: [30, 30, 30] }, original)
50
56
  const bounds = measureAggregateBoundingBox(aligned)
51
57
  const expectedBounds = [[28, 30, 26], [32, 34, 30]]
58
+ t.notThrows(() => geom3.validate(aligned[0]))
59
+ t.notThrows(() => geom3.validate(aligned[1]))
52
60
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected. Result: ' + JSON.stringify(bounds))
53
61
  })
54
62
 
@@ -60,6 +68,8 @@ test('align: multiple objects grouped, relativeTo is nulls, returns geometry unc
60
68
  const aligned = align({ modes: ['center', 'min', 'max'], relativeTo: [null, null, null], grouped: true }, original)
61
69
  const bounds = measureAggregateBoundingBox(aligned)
62
70
  const expectedBounds = [[3, 3, 3], [12, 12, 12]]
71
+ t.notThrows(() => geom3.validate(aligned[0]))
72
+ t.notThrows(() => geom3.validate(aligned[1]))
63
73
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected. Result: ' + JSON.stringify(bounds))
64
74
  })
65
75
 
@@ -71,6 +81,8 @@ test('align: multiple objects ungrouped, relativeTo is nulls, returns geometry a
71
81
  const aligned = align({ modes: ['center', 'min', 'max'], relativeTo: [null, null, null], grouped: false }, original)
72
82
  const bounds = measureAggregateBoundingBox(aligned)
73
83
  const expectedBounds = [[5.5, 3, 8], [9.5, 7, 12]]
84
+ t.notThrows(() => geom3.validate(aligned[0]))
85
+ t.notThrows(() => geom3.validate(aligned[1]))
74
86
  t.true(comparePoints(bounds, expectedBounds), 'Bounding box was not as expected. Result: ' + JSON.stringify(bounds))
75
87
  })
76
88