@jscad/modeling 2.9.1 → 2.9.4

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 (72) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +4 -4
  3. package/dist/jscad-modeling.min.js +414 -420
  4. package/package.json +3 -2
  5. package/src/colors/colorize.test.js +1 -1
  6. package/src/geometries/geom2/toOutlines.js +66 -52
  7. package/src/geometries/geom3/applyTransforms.js +1 -2
  8. package/src/geometries/geom3/create.js +1 -1
  9. package/src/geometries/geom3/create.test.js +1 -1
  10. package/src/geometries/geom3/fromPoints.js +1 -1
  11. package/src/geometries/path2/index.d.ts +0 -1
  12. package/src/geometries/path2/index.js +0 -1
  13. package/src/geometries/poly3/create.js +1 -1
  14. package/src/geometries/poly3/validate.js +14 -0
  15. package/src/maths/constants.d.ts +1 -0
  16. package/src/maths/constants.js +11 -0
  17. package/src/maths/mat4/isMirroring.js +11 -11
  18. package/src/maths/utils/aboutEqualNormals.js +1 -5
  19. package/src/operations/booleans/intersectGeom2.test.js +69 -0
  20. package/src/operations/booleans/intersectGeom3.js +2 -1
  21. package/src/operations/booleans/{intersect.test.js → intersectGeom3.test.js} +3 -71
  22. package/src/operations/booleans/subtractGeom2.test.js +72 -0
  23. package/src/operations/booleans/subtractGeom3.js +2 -1
  24. package/src/operations/booleans/{subtract.test.js → subtractGeom3.test.js} +3 -74
  25. package/src/operations/booleans/to3DWalls.js +1 -1
  26. package/src/operations/booleans/unionGeom2.test.js +166 -0
  27. package/src/operations/booleans/unionGeom3.js +2 -1
  28. package/src/operations/booleans/{union.test.js → unionGeom3.test.js} +3 -168
  29. package/src/operations/expansions/expandGeom3.test.js +14 -14
  30. package/src/operations/expansions/expandShell.js +5 -4
  31. package/src/operations/expansions/extrudePolygon.js +7 -7
  32. package/src/operations/extrusions/extrudeFromSlices.js +3 -2
  33. package/src/operations/extrusions/extrudeFromSlices.test.js +2 -2
  34. package/src/operations/extrusions/extrudeRotate.js +5 -1
  35. package/src/operations/extrusions/extrudeRotate.test.js +5 -5
  36. package/src/operations/extrusions/extrudeWalls.js +2 -2
  37. package/src/operations/extrusions/project.js +11 -14
  38. package/src/operations/extrusions/project.test.js +50 -50
  39. package/src/operations/extrusions/slice/repair.js +62 -0
  40. package/src/operations/hulls/hullChain.test.js +4 -4
  41. package/src/operations/hulls/hullGeom2.js +6 -18
  42. package/src/operations/hulls/hullGeom3.js +5 -18
  43. package/src/operations/hulls/hullPath2.js +4 -14
  44. package/src/operations/hulls/hullPoints2.js +43 -92
  45. package/src/operations/hulls/toUniquePoints.js +34 -0
  46. package/src/operations/modifiers/generalize.js +2 -13
  47. package/src/operations/modifiers/generalize.test.js +0 -32
  48. package/src/operations/modifiers/insertTjunctions.js +1 -1
  49. package/src/operations/modifiers/insertTjunctions.test.js +21 -21
  50. package/src/operations/modifiers/mergePolygons.js +11 -14
  51. package/src/operations/{booleans → modifiers}/reTesselateCoplanarPolygons.js +33 -32
  52. package/src/operations/{booleans → modifiers}/reTesselateCoplanarPolygons.test.js +5 -5
  53. package/src/operations/{booleans → modifiers}/retessellate.js +2 -9
  54. package/src/operations/{booleans → modifiers}/retessellate.test.js +0 -0
  55. package/src/operations/modifiers/snapPolygons.test.js +12 -12
  56. package/src/operations/modifiers/triangulatePolygons.js +3 -3
  57. package/src/operations/transforms/center.js +1 -1
  58. package/src/primitives/cuboid.js +1 -1
  59. package/src/primitives/cylinderElliptic.js +1 -1
  60. package/src/primitives/ellipsoid.js +2 -2
  61. package/src/primitives/polyhedron.js +1 -1
  62. package/src/primitives/roundedCuboid.js +6 -6
  63. package/src/primitives/roundedCylinder.js +1 -1
  64. package/src/primitives/torus.test.js +6 -6
  65. package/src/primitives/triangle.js +1 -2
  66. package/src/utils/trigonometry.js +1 -2
  67. package/src/geometries/path2/eachPoint.d.ts +0 -9
  68. package/src/geometries/path2/eachPoint.js +0 -17
  69. package/src/geometries/path2/eachPoint.test.js +0 -11
  70. package/src/operations/extrusions/slice/repairSlice.js +0 -47
  71. package/src/operations/modifiers/edges.js +0 -195
  72. package/src/operations/modifiers/repairTjunctions.js +0 -44
@@ -1,86 +1,15 @@
1
1
  const test = require('ava')
2
2
 
3
- const { comparePolygonsAsPoints, comparePoints } = require('../../../test/helpers')
3
+ const { comparePolygonsAsPoints } = require('../../../test/helpers')
4
4
 
5
- const { geom2, geom3 } = require('../../geometries')
5
+ const { geom3 } = require('../../geometries')
6
6
 
7
- const { circle, rectangle, sphere, cuboid } = require('../../primitives')
7
+ const { sphere, cuboid } = require('../../primitives')
8
8
 
9
9
  const { subtract } = require('./index')
10
10
 
11
11
  const { center } = require('../transforms/center')
12
12
 
13
- // test('subtract: subtract of a path produces expected changes to points', (t) => {
14
- // let geometry = path.fromPoints({}, [[0, 1, 0], [1, 0, 0]])
15
- //
16
- // geometry = subtract({normal: [1, 0, 0]}, geometry)
17
- // let obs = path.toPoints(geometry)
18
- // let exp = []
19
- //
20
- // t.deepEqual(obs, exp)
21
- // })
22
-
23
- test('subtract: subtract of one or more geom2 objects produces expected geometry', (t) => {
24
- const geometry1 = circle({ radius: 2, segments: 8 })
25
-
26
- // subtract of one object
27
- const result1 = subtract(geometry1)
28
- let obs = geom2.toPoints(result1)
29
- let exp = [
30
- [2, 0],
31
- [1.4142000000000001, 1.4142000000000001],
32
- [0, 2],
33
- [-1.4142000000000001, 1.4142000000000001],
34
- [-2, 0],
35
- [-1.4142000000000001, -1.4142000000000001],
36
- [0, -2],
37
- [1.4142000000000001, -1.4142000000000001]
38
- ]
39
- t.notThrows(() => geom2.validate(result1))
40
- t.is(obs.length, 8)
41
- t.true(comparePoints(obs, exp))
42
-
43
- // subtract of two non-overlapping objects
44
- const geometry2 = center({ relativeTo: [10, 10, 0] }, rectangle({ size: [4, 4] }))
45
-
46
- const result2 = subtract(geometry1, geometry2)
47
- obs = geom2.toPoints(result2)
48
- exp = [
49
- [2, 0],
50
- [1.4142000000000001, 1.4142000000000001],
51
- [0, 2],
52
- [-1.4142000000000001, 1.4142000000000001],
53
- [-2, 0],
54
- [-1.4142000000000001, -1.4142000000000001],
55
- [0, -2],
56
- [1.4142000000000001, -1.4142000000000001]
57
- ]
58
- t.notThrows(() => geom2.validate(result2))
59
- t.is(obs.length, 8)
60
- t.true(comparePoints(obs, exp))
61
-
62
- // subtract of two partially overlapping objects
63
- const geometry3 = rectangle({ size: [18, 18] })
64
-
65
- const result3 = subtract(geometry2, geometry3)
66
- obs = geom2.toPoints(result3)
67
- exp = [
68
- [12, 12], [9, 9], [8, 9], [8, 12], [9, 8], [12, 8]
69
- ]
70
- t.notThrows(() => geom2.validate(result3))
71
- t.is(obs.length, 6)
72
- t.true(comparePoints(obs, exp))
73
-
74
- // subtract of two completely overlapping objects
75
- const result4 = subtract(geometry1, geometry3)
76
- obs = geom2.toPoints(result4)
77
- exp = [
78
- ]
79
- t.notThrows(() => geom2.validate(result4))
80
- t.is(obs.length, 0)
81
- t.deepEqual(obs, exp)
82
- })
83
-
84
13
  test('subtract: subtract of one or more geom3 objects produces expected geometry', (t) => {
85
14
  const geometry1 = sphere({ radius: 2, segments: 8 })
86
15
 
@@ -14,7 +14,7 @@ const to3DWall = (z0, z1, side) => {
14
14
  vec3.fromVec2(vec3.create(), side[1], z1),
15
15
  vec3.fromVec2(vec3.create(), side[0], z1)
16
16
  ]
17
- return poly3.fromPoints(points)
17
+ return poly3.create(points)
18
18
  }
19
19
 
20
20
  /*
@@ -0,0 +1,166 @@
1
+ const test = require('ava')
2
+
3
+ const { comparePoints } = require('../../../test/helpers')
4
+
5
+ const { geom2 } = require('../../geometries')
6
+
7
+ const { circle, rectangle } = require('../../primitives')
8
+
9
+ const { union } = require('./index')
10
+
11
+ const { center } = require('../transforms/center')
12
+ const { translate } = require('../transforms/translate')
13
+
14
+ test('union of one or more geom2 objects produces expected geometry', (t) => {
15
+ const geometry1 = circle({ radius: 2, segments: 8 })
16
+
17
+ // union of one object
18
+ const result1 = union(geometry1)
19
+ let obs = geom2.toPoints(result1)
20
+ let exp = [
21
+ [2, 0],
22
+ [1.4142000000000001, 1.4142000000000001],
23
+ [0, 2],
24
+ [-1.4142000000000001, 1.4142000000000001],
25
+ [-2, 0],
26
+ [-1.4142000000000001, -1.4142000000000001],
27
+ [0, -2],
28
+ [1.4142000000000001, -1.4142000000000001]
29
+ ]
30
+ t.notThrows(() => geom2.validate(result1))
31
+ t.true(comparePoints(obs, exp))
32
+
33
+ // union of two non-overlapping objects
34
+ const geometry2 = center({ relativeTo: [10, 10, 0] }, rectangle({ size: [4, 4] }))
35
+
36
+ const result2 = union(geometry1, geometry2)
37
+ obs = geom2.toPoints(result2)
38
+ exp = [
39
+ [2, 0],
40
+ [1.4142000000000001, 1.4142000000000001],
41
+ [0, 2],
42
+ [-1.4142000000000001, 1.4142000000000001],
43
+ [-2, 0],
44
+ [-1.4142000000000001, -1.4142000000000001],
45
+ [0, -2],
46
+ [8, 12],
47
+ [8, 8],
48
+ [12, 8],
49
+ [12, 12],
50
+ [1.4142000000000001, -1.4142000000000001]
51
+ ]
52
+ t.notThrows(() => geom2.validate(result2))
53
+ t.true(comparePoints(obs, exp))
54
+
55
+ // union of two partially overlapping objects
56
+ const geometry3 = rectangle({ size: [18, 18] })
57
+
58
+ const result3 = union(geometry2, geometry3)
59
+ obs = geom2.toPoints(result3)
60
+ exp = [
61
+ [11.999973333333333, 11.999973333333333],
62
+ [7.999933333333333, 11.999973333333333],
63
+ [9.000053333333334, 7.999933333333333],
64
+ [-9.000053333333334, 9.000053333333334],
65
+ [-9.000053333333334, -9.000053333333334],
66
+ [9.000053333333334, -9.000053333333334],
67
+ [7.999933333333333, 9.000053333333334],
68
+ [11.999973333333333, 7.999933333333333]
69
+ ]
70
+ t.notThrows(() => geom2.validate(result3))
71
+ t.true(comparePoints(obs, exp))
72
+
73
+ // union of two completely overlapping objects
74
+ const result4 = union(geometry1, geometry3)
75
+ obs = geom2.toPoints(result4)
76
+ exp = [
77
+ [-9.000046666666666, -9.000046666666666],
78
+ [9.000046666666666, -9.000046666666666],
79
+ [9.000046666666666, 9.000046666666666],
80
+ [-9.000046666666666, 9.000046666666666]
81
+ ]
82
+ t.notThrows(() => geom2.validate(result4))
83
+ t.true(comparePoints(obs, exp))
84
+
85
+ // union of unions of non-overlapping objects (BSP gap from #907)
86
+ const circ = circle({ radius: 1, segments: 32 })
87
+ const result5 = union(
88
+ union(
89
+ translate([17, 21], circ),
90
+ translate([7, 0], circ)
91
+ ),
92
+ union(
93
+ translate([3, 21], circ),
94
+ translate([17, 21], circ)
95
+ )
96
+ )
97
+ obs = geom2.toPoints(result5)
98
+ t.notThrows.skip(() => geom2.validate(result5))
99
+ t.is(obs.length, 112)
100
+ })
101
+
102
+ test('union of geom2 with closing issues #15', (t) => {
103
+ const c = geom2.create([
104
+ [[-45.82118740347841168159, -16.85726810555620147625], [-49.30331715865012398581, -14.68093629710870118288]],
105
+ [[-49.10586702080816223770, -15.27604177352110781385], [-48.16645938811709015681, -15.86317173589183227023]],
106
+ [[-49.60419521731581937729, -14.89550781504266296906], [-49.42407001323204696064, -15.67605088949303393520]],
107
+ [[-49.05727291218684626983, -15.48661638542171203881], [-49.10586702080816223770, -15.27604177352110781385]],
108
+ [[-49.30706235399220815907, -15.81529674600091794900], [-46.00505780290426827150, -17.21108547999804727624]],
109
+ [[-46.00505780290426827150, -17.21108547999804727624], [-45.85939703723252591772, -17.21502856394236857795]],
110
+ [[-45.85939703723252591772, -17.21502856394236857795], [-45.74972032664388166268, -17.11909303495791334626]],
111
+ [[-45.74972032664388166268, -17.11909303495791334626], [-45.73424573227583067592, -16.97420292661295349035]],
112
+ [[-45.73424573227583067592, -16.97420292661295349035], [-45.82118740347841168159, -16.85726810555620147625]],
113
+ [[-49.30331715865012398581, -14.68093629710870118288], [-49.45428884427643367871, -14.65565769658912387285]],
114
+ [[-49.45428884427643367871, -14.65565769658912387285], [-49.57891661679624917269, -14.74453612941635327616]],
115
+ [[-49.57891661679624917269, -14.74453612941635327616], [-49.60419521731581937729, -14.89550781504266296906]],
116
+ [[-49.42407001323204696064, -15.67605088949303393520], [-49.30706235399220815907, -15.81529674600091794900]],
117
+ [[-48.16645938811709015681, -15.86317173589183227023], [-49.05727291218684626983, -15.48661638542171203881]]
118
+ ])
119
+ const d = geom2.create([
120
+ [[-49.03431352173912216585, -15.58610714407888764299], [-49.21443872582289458251, -14.80556406962851667686]],
121
+ [[-68.31614651314507113966, -3.10790373951434872879], [-49.34036769611472550423, -15.79733157434056778357]],
122
+ [[-49.58572929483430868913, -14.97552686612213790340], [-49.53755741140093959984, -15.18427183431472826669]],
123
+ [[-49.53755741140093959984, -15.18427183431472826669], [-54.61235529924312714911, -11.79066769321313756791]],
124
+ [[-49.30227466841120076424, -14.68159232649114187552], [-68.09792828135776687759, -2.77270756611528668145]],
125
+ [[-49.21443872582289458251, -14.80556406962851667686], [-49.30227466841120076424, -14.68159232649114187552]],
126
+ [[-49.34036769611472550423, -15.79733157434056778357], [-49.18823337756091262918, -15.82684012194931710837]],
127
+ [[-49.18823337756091262918, -15.82684012194931710837], [-49.06069007212390431505, -15.73881563386780157998]],
128
+ [[-49.06069007212390431505, -15.73881563386780157998], [-49.03431352173912216585, -15.58610714407888764299]],
129
+ [[-68.09792828135776687759, -2.77270756611528668145], [-68.24753735887460948106, -2.74623350179570024920]],
130
+ [[-68.24753735887460948106, -2.74623350179570024920], [-68.37258141465594007968, -2.83253376987636329432]],
131
+ [[-68.37258141465594007968, -2.83253376987636329432], [-68.40089829889257089235, -2.98180502037078554167]],
132
+ [[-68.40089829889257089235, -2.98180502037078554167], [-68.31614651314507113966, -3.10790373951434872879]],
133
+ [[-54.61235529924312714911, -11.79066769321313756791], [-49.58572929483430868913, -14.97552686612213790340]]
134
+ ])
135
+ // geom2.toOutlines(c)
136
+ // geom2.toOutlines(d)
137
+
138
+ const obs = union(c, d)
139
+ // const outlines = geom2.toOutlines(obs)
140
+ const pts = geom2.toPoints(obs)
141
+ const exp = [
142
+ [-49.10585516965137, -15.276000175919414],
143
+ [-49.0573272145917, -15.486679335654257],
144
+ [-49.307011370463215, -15.815286644243773],
145
+ [-46.00502320253235, -17.211117609669667],
146
+ [-45.85943933735334, -17.215031154432545],
147
+ [-45.74972963250071, -17.119149307742074],
148
+ [-45.734205904941305, -16.974217700023555],
149
+ [-48.166473975068946, -15.86316234184296],
150
+ [-49.318621553259746, -15.801589237573706],
151
+ [-49.585786209072104, -14.975570389622606],
152
+ [-68.31614189569036, -3.1078763476921982],
153
+ [-49.53751915699663, -15.184292776976012],
154
+ [-68.09789654941396, -2.7727464644978874],
155
+ [-68.24752441084793, -2.7462648116024244],
156
+ [-68.37262739176788, -2.8324932478777995],
157
+ [-68.40093536555268, -2.98186020632758],
158
+ [-54.61234310251047, -11.79072766159384],
159
+ [-49.30335872868453, -14.680880468978017],
160
+ [-49.34040695243976, -15.797284338334542],
161
+ [-45.82121705016925, -16.857333163105647]
162
+ ]
163
+ t.notThrows(() => geom2.validate(obs))
164
+ t.is(pts.length, 20) // number of sides in union
165
+ t.true(comparePoints(pts, exp))
166
+ })
@@ -1,6 +1,7 @@
1
1
  const flatten = require('../../utils/flatten')
2
2
 
3
- const retessellate = require('./retessellate')
3
+ const retessellate = require('../modifiers/retessellate')
4
+
4
5
  const unionSub = require('./unionGeom3Sub')
5
6
 
6
7
  /*
@@ -1,113 +1,14 @@
1
1
  const test = require('ava')
2
2
 
3
- const { comparePolygonsAsPoints, comparePoints } = require('../../../test/helpers')
3
+ const { comparePolygonsAsPoints } = require('../../../test/helpers')
4
4
 
5
- const { geom2, geom3 } = require('../../geometries')
5
+ const { geom3 } = require('../../geometries')
6
6
 
7
- const { circle, rectangle, sphere, cuboid } = require('../../primitives')
7
+ const { sphere, cuboid } = require('../../primitives')
8
8
 
9
9
  const { union } = require('./index')
10
10
 
11
11
  const { center } = require('../transforms/center')
12
- const { translate } = require('../transforms/translate')
13
-
14
- // test('union: union of a path produces expected changes to points', (t) => {
15
- // let geometry = path.fromPoints({}, [[0, 1, 0], [1, 0, 0]])
16
- //
17
- // geometry = union({normal: [1, 0, 0]}, geometry)
18
- // let obs = path.toPoints(geometry)
19
- // let exp = []
20
- //
21
- // t.deepEqual(obs, exp)
22
- // })
23
-
24
- test('union of one or more geom2 objects produces expected geometry', (t) => {
25
- const geometry1 = circle({ radius: 2, segments: 8 })
26
-
27
- // union of one object
28
- const result1 = union(geometry1)
29
- let obs = geom2.toPoints(result1)
30
- let exp = [
31
- [2, 0],
32
- [1.4142000000000001, 1.4142000000000001],
33
- [0, 2],
34
- [-1.4142000000000001, 1.4142000000000001],
35
- [-2, 0],
36
- [-1.4142000000000001, -1.4142000000000001],
37
- [0, -2],
38
- [1.4142000000000001, -1.4142000000000001]
39
- ]
40
- t.notThrows(() => geom2.validate(result1))
41
- t.true(comparePoints(obs, exp))
42
-
43
- // union of two non-overlapping objects
44
- const geometry2 = center({ relativeTo: [10, 10, 0] }, rectangle({ size: [4, 4] }))
45
-
46
- const result2 = union(geometry1, geometry2)
47
- obs = geom2.toPoints(result2)
48
- exp = [
49
- [2, 0],
50
- [1.4142000000000001, 1.4142000000000001],
51
- [0, 2],
52
- [-1.4142000000000001, 1.4142000000000001],
53
- [-2, 0],
54
- [-1.4142000000000001, -1.4142000000000001],
55
- [0, -2],
56
- [8, 12],
57
- [8, 8],
58
- [12, 8],
59
- [12, 12],
60
- [1.4142000000000001, -1.4142000000000001]
61
- ]
62
- t.notThrows(() => geom2.validate(result2))
63
- t.true(comparePoints(obs, exp))
64
-
65
- // union of two partially overlapping objects
66
- const geometry3 = rectangle({ size: [18, 18] })
67
-
68
- const result3 = union(geometry2, geometry3)
69
- obs = geom2.toPoints(result3)
70
- exp = [
71
- [11.999973333333333, 11.999973333333333],
72
- [7.999933333333333, 11.999973333333333],
73
- [9.000053333333334, 7.999933333333333],
74
- [-9.000053333333334, 9.000053333333334],
75
- [-9.000053333333334, -9.000053333333334],
76
- [9.000053333333334, -9.000053333333334],
77
- [7.999933333333333, 9.000053333333334],
78
- [11.999973333333333, 7.999933333333333]
79
- ]
80
- t.notThrows(() => geom2.validate(result3))
81
- t.true(comparePoints(obs, exp))
82
-
83
- // union of two completely overlapping objects
84
- const result4 = union(geometry1, geometry3)
85
- obs = geom2.toPoints(result4)
86
- exp = [
87
- [-9.000046666666666, -9.000046666666666],
88
- [9.000046666666666, -9.000046666666666],
89
- [9.000046666666666, 9.000046666666666],
90
- [-9.000046666666666, 9.000046666666666]
91
- ]
92
- t.notThrows(() => geom2.validate(result4))
93
- t.true(comparePoints(obs, exp))
94
-
95
- // union of unions of non-overlapping objects (BSP gap from #907)
96
- const circ = circle({ radius: 1, segments: 32 })
97
- const result5 = union(
98
- union(
99
- translate([17, 21], circ),
100
- translate([7, 0], circ),
101
- ),
102
- union(
103
- translate([3, 21], circ),
104
- translate([17, 21], circ),
105
- )
106
- )
107
- obs = geom2.toPoints(result5)
108
- t.notThrows.skip(() => geom2.validate(result5))
109
- t.is(obs.length, 112)
110
- })
111
12
 
112
13
  test('union of one or more geom3 objects produces expected geometry', (t) => {
113
14
  const geometry1 = sphere({ radius: 2, segments: 8 })
@@ -230,69 +131,3 @@ test('union of geom3 with rounding issues #137', (t) => {
230
131
  t.notThrows(() => geom3.validate(obs))
231
132
  t.is(pts.length, 6) // number of polygons in union
232
133
  })
233
-
234
- test('union of geom2 with closing issues #15', (t) => {
235
- const c = geom2.create([
236
- [[-45.82118740347841168159, -16.85726810555620147625], [-49.30331715865012398581, -14.68093629710870118288]],
237
- [[-49.10586702080816223770, -15.27604177352110781385], [-48.16645938811709015681, -15.86317173589183227023]],
238
- [[-49.60419521731581937729, -14.89550781504266296906], [-49.42407001323204696064, -15.67605088949303393520]],
239
- [[-49.05727291218684626983, -15.48661638542171203881], [-49.10586702080816223770, -15.27604177352110781385]],
240
- [[-49.30706235399220815907, -15.81529674600091794900], [-46.00505780290426827150, -17.21108547999804727624]],
241
- [[-46.00505780290426827150, -17.21108547999804727624], [-45.85939703723252591772, -17.21502856394236857795]],
242
- [[-45.85939703723252591772, -17.21502856394236857795], [-45.74972032664388166268, -17.11909303495791334626]],
243
- [[-45.74972032664388166268, -17.11909303495791334626], [-45.73424573227583067592, -16.97420292661295349035]],
244
- [[-45.73424573227583067592, -16.97420292661295349035], [-45.82118740347841168159, -16.85726810555620147625]],
245
- [[-49.30331715865012398581, -14.68093629710870118288], [-49.45428884427643367871, -14.65565769658912387285]],
246
- [[-49.45428884427643367871, -14.65565769658912387285], [-49.57891661679624917269, -14.74453612941635327616]],
247
- [[-49.57891661679624917269, -14.74453612941635327616], [-49.60419521731581937729, -14.89550781504266296906]],
248
- [[-49.42407001323204696064, -15.67605088949303393520], [-49.30706235399220815907, -15.81529674600091794900]],
249
- [[-48.16645938811709015681, -15.86317173589183227023], [-49.05727291218684626983, -15.48661638542171203881]]
250
- ])
251
- const d = geom2.create([
252
- [[-49.03431352173912216585, -15.58610714407888764299], [-49.21443872582289458251, -14.80556406962851667686]],
253
- [[-68.31614651314507113966, -3.10790373951434872879], [-49.34036769611472550423, -15.79733157434056778357]],
254
- [[-49.58572929483430868913, -14.97552686612213790340], [-49.53755741140093959984, -15.18427183431472826669]],
255
- [[-49.53755741140093959984, -15.18427183431472826669], [-54.61235529924312714911, -11.79066769321313756791]],
256
- [[-49.30227466841120076424, -14.68159232649114187552], [-68.09792828135776687759, -2.77270756611528668145]],
257
- [[-49.21443872582289458251, -14.80556406962851667686], [-49.30227466841120076424, -14.68159232649114187552]],
258
- [[-49.34036769611472550423, -15.79733157434056778357], [-49.18823337756091262918, -15.82684012194931710837]],
259
- [[-49.18823337756091262918, -15.82684012194931710837], [-49.06069007212390431505, -15.73881563386780157998]],
260
- [[-49.06069007212390431505, -15.73881563386780157998], [-49.03431352173912216585, -15.58610714407888764299]],
261
- [[-68.09792828135776687759, -2.77270756611528668145], [-68.24753735887460948106, -2.74623350179570024920]],
262
- [[-68.24753735887460948106, -2.74623350179570024920], [-68.37258141465594007968, -2.83253376987636329432]],
263
- [[-68.37258141465594007968, -2.83253376987636329432], [-68.40089829889257089235, -2.98180502037078554167]],
264
- [[-68.40089829889257089235, -2.98180502037078554167], [-68.31614651314507113966, -3.10790373951434872879]],
265
- [[-54.61235529924312714911, -11.79066769321313756791], [-49.58572929483430868913, -14.97552686612213790340]]
266
- ])
267
- // geom2.toOutlines(c)
268
- // geom2.toOutlines(d)
269
-
270
- const obs = union(c, d)
271
- // const outlines = geom2.toOutlines(obs)
272
- const pts = geom2.toPoints(obs)
273
- const exp = [
274
- [-49.10585516965137, -15.276000175919414],
275
- [-49.0573272145917, -15.486679335654257],
276
- [-49.307011370463215, -15.815286644243773],
277
- [-46.00502320253235, -17.211117609669667],
278
- [-45.85943933735334, -17.215031154432545],
279
- [-45.74972963250071, -17.119149307742074],
280
- [-45.734205904941305, -16.974217700023555],
281
- [-48.166473975068946, -15.86316234184296],
282
- [-49.318621553259746, -15.801589237573706],
283
- [-49.585786209072104, -14.975570389622606],
284
- [-68.31614189569036, -3.1078763476921982],
285
- [-49.53751915699663, -15.184292776976012],
286
- [-68.09789654941396, -2.7727464644978874],
287
- [-68.24752441084793, -2.7462648116024244],
288
- [-68.37262739176788, -2.8324932478777995],
289
- [-68.40093536555268, -2.98186020632758],
290
- [-54.61234310251047, -11.79072766159384],
291
- [-49.30335872868453, -14.680880468978017],
292
- [-49.34040695243976, -15.797284338334542],
293
- [-45.82121705016925, -16.857333163105647]
294
- ]
295
- t.notThrows(() => geom2.validate(obs))
296
- t.is(pts.length, 20) // number of sides in union
297
- t.true(comparePoints(pts, exp))
298
- })
@@ -6,20 +6,20 @@ const expandGeom3 = require('./expandGeom3')
6
6
  test('expandGeom3: expand completes properly, issue 876', async (t) => {
7
7
  setTimeout(() => t.fail(), 1000)
8
8
  const polies = [
9
- poly3.fromPoints([[-19.61, -0.7999999999999986, 11.855], [-19.61, -0.8000000000000015, -11.855], [-19.61, -2.7500000000000018, -11.855], [-19.61, -2.7499999999999982, 11.855]]),
10
- poly3.fromPoints([[-17.32, -2.75, 10], [-17.32, -2.7500000000000013, -10], [-17.32, -0.8000000000000014, -10], [-17.32, -0.7999999999999987, 10]]),
11
- poly3.fromPoints([[-16.863040644206997, -0.8000000000000015, -10.28], [-16.863040644206997, -2.7500000000000018, -10.28], [-14.292644267871385, -2.7500000000000018, -11.855000000000016], [-14.292644267871383, -0.8000000000000015, -11.855000000000018]]),
12
- poly3.fromPoints([[-17.319999999999993, -0.8000000000000015, -9.999999999999996], [-17.319999999999993, -2.7500000000000018, -9.999999999999996], [-16.87560702649131, -2.7500000000000018, -10.272299999999998], [-16.866696319053347, -0.8000000000000015, -10.277759999999997]]),
13
- poly3.fromPoints([[-16.863040644207004, -2.7500000000000013, -10.280000000000001], [-16.863040644207004, -0.8000000000000014, -10.280000000000001], [-16.86669631905335, -0.8000000000000012, -10.27776], [-16.875607026491313, -2.75, -10.272300000000001]]),
14
- poly3.fromPoints([[-14.107140000000015, -0.7999999999999987, 11.85500000000003], [-14.107140000000015, -2.7499999999999982, 11.85500000000003], [-17.319999999999975, -2.7499999999999982, 9.999999999999956], [-17.319999999999975, -0.7999999999999987, 9.999999999999956]]),
15
- poly3.fromPoints([[-17.32, -0.7999999999999988, 9.999999999999993], [-17.32, -0.7999999999999986, 11.855], [-14.107139999999994, -0.7999999999999986, 11.855]]),
16
- poly3.fromPoints([[-17.32, -0.800000000000001, -11.855], [-17.32, -0.8000000000000008, -10.000000000000078], [-14.292644267871482, -0.800000000000001, -11.855]]),
17
- poly3.fromPoints([[-17.32, -0.800000000000001, -11.855], [-19.61, -0.800000000000001, -11.855], [-19.61, -0.7999999999999986, 11.855], [-17.32, -0.7999999999999986, 11.855]]),
18
- poly3.fromPoints([[-17.32, -2.7500000000000013, -10.000000000000076], [-17.32, -2.7500000000000018, -11.855], [-14.292644267871482, -2.7500000000000018, -11.855]]),
19
- poly3.fromPoints([[-17.32, -2.7499999999999982, 11.855], [-17.32, -2.7499999999999987, 9.999999999999996], [-14.107139999999996, -2.7499999999999982, 11.855]]),
20
- poly3.fromPoints([[-17.32, -2.7499999999999982, 11.855], [-19.61, -2.7499999999999982, 11.855], [-19.61, -2.7500000000000018, -11.855], [-17.32, -2.7500000000000018, -11.855]]),
21
- poly3.fromPoints([[-14.107139999999996, -0.7999999999999986, 11.855], [-19.61, -0.7999999999999986, 11.855], [-19.61, -2.7499999999999982, 11.855], [-14.107139999999994, -2.7499999999999982, 11.855]]),
22
- poly3.fromPoints([[-19.61, -0.8000000000000015, -11.855], [-14.292644267871486, -0.8000000000000015, -11.855], [-14.292644267871482, -2.7500000000000018, -11.855], [-19.61, -2.7500000000000018, -11.855]])
9
+ poly3.create([[-19.61, -0.7999999999999986, 11.855], [-19.61, -0.8000000000000015, -11.855], [-19.61, -2.7500000000000018, -11.855], [-19.61, -2.7499999999999982, 11.855]]),
10
+ poly3.create([[-17.32, -2.75, 10], [-17.32, -2.7500000000000013, -10], [-17.32, -0.8000000000000014, -10], [-17.32, -0.7999999999999987, 10]]),
11
+ poly3.create([[-16.863040644206997, -0.8000000000000015, -10.28], [-16.863040644206997, -2.7500000000000018, -10.28], [-14.292644267871385, -2.7500000000000018, -11.855000000000016], [-14.292644267871383, -0.8000000000000015, -11.855000000000018]]),
12
+ poly3.create([[-17.319999999999993, -0.8000000000000015, -9.999999999999996], [-17.319999999999993, -2.7500000000000018, -9.999999999999996], [-16.87560702649131, -2.7500000000000018, -10.272299999999998], [-16.866696319053347, -0.8000000000000015, -10.277759999999997]]),
13
+ poly3.create([[-16.863040644207004, -2.7500000000000013, -10.280000000000001], [-16.863040644207004, -0.8000000000000014, -10.280000000000001], [-16.86669631905335, -0.8000000000000012, -10.27776], [-16.875607026491313, -2.75, -10.272300000000001]]),
14
+ poly3.create([[-14.107140000000015, -0.7999999999999987, 11.85500000000003], [-14.107140000000015, -2.7499999999999982, 11.85500000000003], [-17.319999999999975, -2.7499999999999982, 9.999999999999956], [-17.319999999999975, -0.7999999999999987, 9.999999999999956]]),
15
+ poly3.create([[-17.32, -0.7999999999999988, 9.999999999999993], [-17.32, -0.7999999999999986, 11.855], [-14.107139999999994, -0.7999999999999986, 11.855]]),
16
+ poly3.create([[-17.32, -0.800000000000001, -11.855], [-17.32, -0.8000000000000008, -10.000000000000078], [-14.292644267871482, -0.800000000000001, -11.855]]),
17
+ poly3.create([[-17.32, -0.800000000000001, -11.855], [-19.61, -0.800000000000001, -11.855], [-19.61, -0.7999999999999986, 11.855], [-17.32, -0.7999999999999986, 11.855]]),
18
+ poly3.create([[-17.32, -2.7500000000000013, -10.000000000000076], [-17.32, -2.7500000000000018, -11.855], [-14.292644267871482, -2.7500000000000018, -11.855]]),
19
+ poly3.create([[-17.32, -2.7499999999999982, 11.855], [-17.32, -2.7499999999999987, 9.999999999999996], [-14.107139999999996, -2.7499999999999982, 11.855]]),
20
+ poly3.create([[-17.32, -2.7499999999999982, 11.855], [-19.61, -2.7499999999999982, 11.855], [-19.61, -2.7500000000000018, -11.855], [-17.32, -2.7500000000000018, -11.855]]),
21
+ poly3.create([[-14.107139999999996, -0.7999999999999986, 11.855], [-19.61, -0.7999999999999986, 11.855], [-19.61, -2.7499999999999982, 11.855], [-14.107139999999994, -2.7499999999999982, 11.855]]),
22
+ poly3.create([[-19.61, -0.8000000000000015, -11.855], [-14.292644267871486, -0.8000000000000015, -11.855], [-14.292644267871482, -2.7500000000000018, -11.855], [-19.61, -2.7500000000000018, -11.855]])
23
23
  ]
24
24
 
25
25
  const sub = geom3.create(polies)
@@ -10,7 +10,8 @@ const poly3 = require('../../geometries/poly3')
10
10
 
11
11
  const sphere = require('../../primitives/sphere')
12
12
 
13
- const retessellate = require('../booleans/retessellate')
13
+ const retessellate = require('../modifiers/retessellate')
14
+
14
15
  const unionGeom3Sub = require('../booleans/unionGeom3Sub')
15
16
 
16
17
  const extrudePolygon = require('./extrudePolygon')
@@ -166,7 +167,7 @@ const expandShell = (options, geometry) => {
166
167
  startfacevertices.push(p1)
167
168
  endfacevertices.push(p2)
168
169
  const points = [prevp2, p2, p1, prevp1]
169
- const polygon = poly3.fromPoints(points)
170
+ const polygon = poly3.create(points)
170
171
  polygons.push(polygon)
171
172
  }
172
173
  prevp1 = p1
@@ -174,8 +175,8 @@ const expandShell = (options, geometry) => {
174
175
  }
175
176
  }
176
177
  endfacevertices.reverse()
177
- polygons.push(poly3.fromPoints(startfacevertices))
178
- polygons.push(poly3.fromPoints(endfacevertices))
178
+ polygons.push(poly3.create(startfacevertices))
179
+ polygons.push(poly3.create(endfacevertices))
179
180
 
180
181
  const cylinder = geom3.create(polygons)
181
182
  result = unionGeom3Sub(result, cylinder)
@@ -17,14 +17,14 @@ const extrudePolygon = (offsetvector, polygon1) => {
17
17
  const polygon2 = poly3.transform(mat4.fromTranslation(mat4.create(), offsetvector), polygon1)
18
18
  const numvertices = polygon1.vertices.length
19
19
  for (let i = 0; i < numvertices; i++) {
20
- const sidefacepoints = []
21
20
  const nexti = (i < (numvertices - 1)) ? i + 1 : 0
22
- sidefacepoints.push(polygon1.vertices[i])
23
- sidefacepoints.push(polygon2.vertices[i])
24
- sidefacepoints.push(polygon2.vertices[nexti])
25
- sidefacepoints.push(polygon1.vertices[nexti])
26
- const sidefacepolygon = poly3.fromPoints(sidefacepoints)
27
- newpolygons.push(sidefacepolygon)
21
+ const sideFacePolygon = poly3.create([
22
+ polygon1.vertices[i],
23
+ polygon2.vertices[i],
24
+ polygon2.vertices[nexti],
25
+ polygon1.vertices[nexti]
26
+ ])
27
+ newpolygons.push(sideFacePolygon)
28
28
  }
29
29
  newpolygons.push(poly3.invert(polygon2))
30
30
 
@@ -5,7 +5,7 @@ const geom3 = require('../../geometries/geom3')
5
5
  const poly3 = require('../../geometries/poly3')
6
6
 
7
7
  const slice = require('./slice')
8
- const repairSlice = require('./slice/repairSlice')
8
+ const repairSlice = require('./slice/repair')
9
9
 
10
10
  const extrudeWalls = require('./extrudeWalls')
11
11
 
@@ -59,7 +59,8 @@ const extrudeFromSlices = (options, base) => {
59
59
 
60
60
  // Repair gaps in the base slice
61
61
  if (repair) {
62
- repairSlice(base)
62
+ // note: base must be a slice, if base is geom2 this doesn't repair
63
+ base = repairSlice(base)
63
64
  }
64
65
 
65
66
  const sMax = numberOfSlices - 1
@@ -32,7 +32,7 @@ test('extrudeFromSlices (defaults)', (t) => {
32
32
  t.is(pts.length, 12)
33
33
  t.true(comparePolygonsAsPoints(pts, exp))
34
34
 
35
- const poly2 = poly3.fromPoints([[10, 10, 0], [-10, 10, 0], [-10, -10, 0], [10, -10, 0]])
35
+ const poly2 = poly3.create([[10, 10, 0], [-10, 10, 0], [-10, -10, 0], [10, -10, 0]])
36
36
  geometry3 = extrudeFromSlices({ }, poly2)
37
37
  pts = geom3.toPoints(geometry3)
38
38
 
@@ -45,7 +45,7 @@ test('extrudeFromSlices (torus)', (t) => {
45
45
  const sqrt3 = Math.sqrt(3) / 2
46
46
  const radius = 10
47
47
 
48
- let hex = poly3.fromPoints([
48
+ let hex = poly3.create([
49
49
  [radius, 0, 0],
50
50
  [radius / 2, radius * sqrt3, 0],
51
51
  [-radius / 2, radius * sqrt3, 0],
@@ -114,7 +114,11 @@ const extrudeRotate = (options, geometry) => {
114
114
 
115
115
  const matrix = mat4.create()
116
116
  const createSlice = (progress, index, base) => {
117
- const Zrotation = rotationPerSlice * index + startAngle
117
+ let Zrotation = rotationPerSlice * index + startAngle
118
+ // fix rounding error when rotating 2 * PI radians
119
+ if (totalRotation === Math.PI * 2 && index === segments) {
120
+ Zrotation = startAngle
121
+ }
118
122
  mat4.multiply(matrix, mat4.fromZRotation(matrix, Zrotation), mat4.fromXRotation(mat4.create(), Math.PI / 2))
119
123
 
120
124
  return slice.transform(matrix, base)
@@ -11,7 +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
+ t.notThrows(() => geom3.validate(geometry3))
15
15
  t.is(pts.length, 96)
16
16
  })
17
17
 
@@ -61,7 +61,7 @@ test('extrudeRotate: (startAngle) extruding of a geom2 produces an expected geom
61
61
  [18.38477631085024, 18.384776310850235, 8],
62
62
  [-11.803752993228215, 23.166169628897567, 8]
63
63
  ]
64
- t.notThrows.skip(() => geom3.validate(geometry3))
64
+ t.notThrows(() => geom3.validate(geometry3))
65
65
  t.is(pts.length, 40)
66
66
  t.true(comparePoints(pts[0], exp))
67
67
 
@@ -72,7 +72,7 @@ test('extrudeRotate: (startAngle) extruding of a geom2 produces an expected geom
72
72
  [18.38477631085024, -18.384776310850235, 8],
73
73
  [23.166169628897567, 11.803752993228215, 8]
74
74
  ]
75
- t.notThrows.skip(() => geom3.validate(geometry3))
75
+ t.notThrows(() => geom3.validate(geometry3))
76
76
  t.is(pts.length, 40)
77
77
  t.true(comparePoints(pts[0], exp))
78
78
  })
@@ -83,12 +83,12 @@ test('extrudeRotate: (segments) extruding of a geom2 produces an expected geom3'
83
83
  // test segments
84
84
  let geometry3 = extrudeRotate({ segments: 4 }, geometry2)
85
85
  let pts = geom3.toPoints(geometry3)
86
- t.notThrows.skip(() => geom3.validate(geometry3))
86
+ t.notThrows(() => geom3.validate(geometry3))
87
87
  t.is(pts.length, 32)
88
88
 
89
89
  geometry3 = extrudeRotate({ segments: 64 }, geometry2)
90
90
  pts = geom3.toPoints(geometry3)
91
- t.notThrows.skip(() => geom3.validate(geometry3))
91
+ t.notThrows(() => geom3.validate(geometry3))
92
92
  t.is(pts.length, 512)
93
93
 
94
94
  // test overlapping edges
@@ -64,11 +64,11 @@ const extrudeWalls = (slice0, slice1) => {
64
64
  edges0.forEach((edge0, i) => {
65
65
  const edge1 = edges1[i]
66
66
 
67
- const poly0 = poly3.fromPoints([edge0[0], edge0[1], edge1[1]])
67
+ const poly0 = poly3.create([edge0[0], edge0[1], edge1[1]])
68
68
  const poly0area = poly3.measureArea(poly0)
69
69
  if (Number.isFinite(poly0area) && poly0area > EPSAREA) walls.push(poly0)
70
70
 
71
- const poly1 = poly3.fromPoints([edge0[0], edge1[1], edge1[0]])
71
+ const poly1 = poly3.create([edge0[0], edge1[1], edge1[0]])
72
72
  const poly1area = poly3.measureArea(poly1)
73
73
  if (Number.isFinite(poly1area) && poly1area > EPSAREA) walls.push(poly1)
74
74
  })