@jscad/modeling 2.9.2 → 2.9.5

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 (114) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +4 -4
  3. package/dist/jscad-modeling.min.js +435 -444
  4. package/package.json +3 -2
  5. package/src/colors/colorize.d.ts +6 -5
  6. package/src/colors/colorize.test.js +1 -1
  7. package/src/geometries/geom2/toOutlines.js +66 -52
  8. package/src/geometries/geom2/type.d.ts +3 -2
  9. package/src/geometries/geom3/applyTransforms.js +1 -2
  10. package/src/geometries/geom3/create.js +1 -1
  11. package/src/geometries/geom3/create.test.js +1 -1
  12. package/src/geometries/geom3/fromPoints.js +1 -1
  13. package/src/geometries/geom3/type.d.ts +3 -2
  14. package/src/geometries/path2/index.d.ts +0 -1
  15. package/src/geometries/path2/index.js +0 -1
  16. package/src/geometries/path2/type.d.ts +3 -2
  17. package/src/geometries/poly3/create.js +1 -1
  18. package/src/geometries/poly3/measureBoundingSphere.d.ts +2 -2
  19. package/src/geometries/poly3/measureBoundingSphere.js +46 -8
  20. package/src/geometries/poly3/measureBoundingSphere.test.js +16 -26
  21. package/src/geometries/poly3/type.d.ts +3 -2
  22. package/src/geometries/poly3/validate.js +14 -0
  23. package/src/geometries/types.d.ts +4 -2
  24. package/src/maths/constants.d.ts +1 -0
  25. package/src/maths/constants.js +11 -0
  26. package/src/maths/mat4/fromRotation.js +9 -7
  27. package/src/maths/mat4/fromTaitBryanRotation.js +8 -6
  28. package/src/maths/mat4/fromXRotation.js +4 -2
  29. package/src/maths/mat4/fromYRotation.js +4 -2
  30. package/src/maths/mat4/fromZRotation.js +4 -2
  31. package/src/maths/mat4/isMirroring.js +11 -11
  32. package/src/maths/mat4/rotate.js +9 -5
  33. package/src/maths/mat4/rotateX.js +4 -2
  34. package/src/maths/mat4/rotateY.js +4 -2
  35. package/src/maths/mat4/rotateZ.js +4 -2
  36. package/src/maths/mat4/translate.test.js +2 -3
  37. package/src/maths/utils/aboutEqualNormals.js +1 -5
  38. package/src/maths/utils/index.d.ts +1 -0
  39. package/src/maths/utils/index.js +2 -0
  40. package/src/{utils → maths/utils}/trigonometry.d.ts +0 -0
  41. package/src/{utils → maths/utils}/trigonometry.js +1 -2
  42. package/src/{utils → maths/utils}/trigonometry.test.js +0 -0
  43. package/src/maths/vec2/distance.js +1 -1
  44. package/src/maths/vec2/fromAngleRadians.js +4 -2
  45. package/src/maths/vec2/length.js +1 -1
  46. package/src/maths/vec2/length.test.js +0 -10
  47. package/src/maths/vec3/angle.js +2 -2
  48. package/src/maths/vec3/angle.test.js +0 -12
  49. package/src/maths/vec3/distance.js +1 -1
  50. package/src/maths/vec3/length.js +1 -1
  51. package/src/maths/vec3/length.test.js +0 -10
  52. package/src/operations/booleans/intersectGeom2.test.js +69 -0
  53. package/src/operations/booleans/intersectGeom3.js +2 -1
  54. package/src/operations/booleans/{intersect.test.js → intersectGeom3.test.js} +3 -71
  55. package/src/operations/booleans/subtractGeom2.test.js +72 -0
  56. package/src/operations/booleans/subtractGeom3.js +2 -1
  57. package/src/operations/booleans/{subtract.test.js → subtractGeom3.test.js} +3 -74
  58. package/src/operations/booleans/to3DWalls.js +1 -1
  59. package/src/operations/booleans/trees/PolygonTreeNode.js +2 -2
  60. package/src/operations/booleans/unionGeom2.test.js +166 -0
  61. package/src/operations/booleans/unionGeom3.js +2 -1
  62. package/src/operations/booleans/{union.test.js → unionGeom3.test.js} +3 -168
  63. package/src/operations/expansions/expandGeom3.test.js +14 -14
  64. package/src/operations/expansions/expandShell.js +5 -4
  65. package/src/operations/expansions/extrudePolygon.js +7 -7
  66. package/src/operations/extrusions/extrudeFromSlices.js +3 -2
  67. package/src/operations/extrusions/extrudeFromSlices.test.js +2 -2
  68. package/src/operations/extrusions/extrudeRotate.js +5 -1
  69. package/src/operations/extrusions/extrudeRotate.test.js +47 -47
  70. package/src/operations/extrusions/extrudeWalls.js +2 -2
  71. package/src/operations/extrusions/project.js +11 -14
  72. package/src/operations/extrusions/project.test.js +49 -49
  73. package/src/operations/extrusions/slice/repair.js +62 -0
  74. package/src/operations/hulls/hullChain.test.js +4 -4
  75. package/src/operations/hulls/hullGeom2.js +6 -18
  76. package/src/operations/hulls/hullGeom3.js +5 -18
  77. package/src/operations/hulls/hullPath2.js +4 -14
  78. package/src/operations/hulls/hullPoints2.js +43 -92
  79. package/src/operations/hulls/toUniquePoints.js +34 -0
  80. package/src/operations/modifiers/generalize.js +2 -13
  81. package/src/operations/modifiers/generalize.test.js +0 -32
  82. package/src/operations/modifiers/insertTjunctions.js +1 -1
  83. package/src/operations/modifiers/insertTjunctions.test.js +21 -21
  84. package/src/operations/modifiers/mergePolygons.js +11 -14
  85. package/src/operations/{booleans → modifiers}/reTesselateCoplanarPolygons.js +33 -32
  86. package/src/operations/{booleans → modifiers}/reTesselateCoplanarPolygons.test.js +5 -5
  87. package/src/operations/{booleans → modifiers}/retessellate.js +2 -9
  88. package/src/operations/{booleans → modifiers}/retessellate.test.js +0 -0
  89. package/src/operations/modifiers/snapPolygons.test.js +12 -12
  90. package/src/operations/modifiers/triangulatePolygons.js +3 -3
  91. package/src/operations/transforms/center.js +1 -1
  92. package/src/primitives/circle.test.js +7 -0
  93. package/src/primitives/cuboid.js +1 -1
  94. package/src/primitives/cylinderElliptic.js +5 -3
  95. package/src/primitives/cylinderElliptic.test.js +7 -1
  96. package/src/primitives/ellipse.js +1 -1
  97. package/src/primitives/ellipse.test.js +7 -0
  98. package/src/primitives/ellipsoid.js +3 -3
  99. package/src/primitives/geodesicSphere.js +3 -2
  100. package/src/primitives/polyhedron.js +1 -1
  101. package/src/primitives/roundedCuboid.js +10 -8
  102. package/src/primitives/roundedCylinder.js +2 -2
  103. package/src/primitives/torus.test.js +11 -7
  104. package/src/primitives/triangle.js +1 -2
  105. package/src/utils/index.d.ts +0 -1
  106. package/src/utils/index.js +1 -3
  107. package/src/geometries/path2/eachPoint.d.ts +0 -9
  108. package/src/geometries/path2/eachPoint.js +0 -17
  109. package/src/geometries/path2/eachPoint.test.js +0 -11
  110. package/src/maths/mat4/constants.d.ts +0 -1
  111. package/src/maths/mat4/constants.js +0 -5
  112. package/src/operations/extrusions/slice/repairSlice.js +0 -47
  113. package/src/operations/modifiers/edges.js +0 -195
  114. package/src/operations/modifiers/repairTjunctions.js +0 -44
@@ -132,8 +132,8 @@ class PolygonTreeNode {
132
132
  const polygon = this.polygon
133
133
  if (polygon) {
134
134
  const bound = poly3.measureBoundingSphere(polygon)
135
- const sphereradius = bound[1] + EPS // ensure radius is LARGER then polygon
136
- const spherecenter = bound[0]
135
+ const sphereradius = bound[3] + EPS // ensure radius is LARGER then polygon
136
+ const spherecenter = bound
137
137
  const d = vec3.dot(splane, spherecenter) - splane[3]
138
138
  if (d > sphereradius) {
139
139
  frontnodes.push(this)
@@ -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)