@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.
- package/CHANGELOG.md +50 -0
- package/README.md +4 -4
- package/dist/jscad-modeling.min.js +435 -444
- package/package.json +3 -2
- package/src/colors/colorize.d.ts +6 -5
- package/src/colors/colorize.test.js +1 -1
- package/src/geometries/geom2/toOutlines.js +66 -52
- package/src/geometries/geom2/type.d.ts +3 -2
- package/src/geometries/geom3/applyTransforms.js +1 -2
- package/src/geometries/geom3/create.js +1 -1
- package/src/geometries/geom3/create.test.js +1 -1
- package/src/geometries/geom3/fromPoints.js +1 -1
- package/src/geometries/geom3/type.d.ts +3 -2
- package/src/geometries/path2/index.d.ts +0 -1
- package/src/geometries/path2/index.js +0 -1
- package/src/geometries/path2/type.d.ts +3 -2
- package/src/geometries/poly3/create.js +1 -1
- package/src/geometries/poly3/measureBoundingSphere.d.ts +2 -2
- package/src/geometries/poly3/measureBoundingSphere.js +46 -8
- package/src/geometries/poly3/measureBoundingSphere.test.js +16 -26
- package/src/geometries/poly3/type.d.ts +3 -2
- package/src/geometries/poly3/validate.js +14 -0
- package/src/geometries/types.d.ts +4 -2
- package/src/maths/constants.d.ts +1 -0
- package/src/maths/constants.js +11 -0
- package/src/maths/mat4/fromRotation.js +9 -7
- package/src/maths/mat4/fromTaitBryanRotation.js +8 -6
- package/src/maths/mat4/fromXRotation.js +4 -2
- package/src/maths/mat4/fromYRotation.js +4 -2
- package/src/maths/mat4/fromZRotation.js +4 -2
- package/src/maths/mat4/isMirroring.js +11 -11
- package/src/maths/mat4/rotate.js +9 -5
- package/src/maths/mat4/rotateX.js +4 -2
- package/src/maths/mat4/rotateY.js +4 -2
- package/src/maths/mat4/rotateZ.js +4 -2
- package/src/maths/mat4/translate.test.js +2 -3
- package/src/maths/utils/aboutEqualNormals.js +1 -5
- package/src/maths/utils/index.d.ts +1 -0
- package/src/maths/utils/index.js +2 -0
- package/src/{utils → maths/utils}/trigonometry.d.ts +0 -0
- package/src/{utils → maths/utils}/trigonometry.js +1 -2
- package/src/{utils → maths/utils}/trigonometry.test.js +0 -0
- package/src/maths/vec2/distance.js +1 -1
- package/src/maths/vec2/fromAngleRadians.js +4 -2
- package/src/maths/vec2/length.js +1 -1
- package/src/maths/vec2/length.test.js +0 -10
- package/src/maths/vec3/angle.js +2 -2
- package/src/maths/vec3/angle.test.js +0 -12
- package/src/maths/vec3/distance.js +1 -1
- package/src/maths/vec3/length.js +1 -1
- package/src/maths/vec3/length.test.js +0 -10
- package/src/operations/booleans/intersectGeom2.test.js +69 -0
- package/src/operations/booleans/intersectGeom3.js +2 -1
- package/src/operations/booleans/{intersect.test.js → intersectGeom3.test.js} +3 -71
- package/src/operations/booleans/subtractGeom2.test.js +72 -0
- package/src/operations/booleans/subtractGeom3.js +2 -1
- package/src/operations/booleans/{subtract.test.js → subtractGeom3.test.js} +3 -74
- package/src/operations/booleans/to3DWalls.js +1 -1
- package/src/operations/booleans/trees/PolygonTreeNode.js +2 -2
- package/src/operations/booleans/unionGeom2.test.js +166 -0
- package/src/operations/booleans/unionGeom3.js +2 -1
- package/src/operations/booleans/{union.test.js → unionGeom3.test.js} +3 -168
- package/src/operations/expansions/expandGeom3.test.js +14 -14
- package/src/operations/expansions/expandShell.js +5 -4
- package/src/operations/expansions/extrudePolygon.js +7 -7
- package/src/operations/extrusions/extrudeFromSlices.js +3 -2
- package/src/operations/extrusions/extrudeFromSlices.test.js +2 -2
- package/src/operations/extrusions/extrudeRotate.js +5 -1
- package/src/operations/extrusions/extrudeRotate.test.js +47 -47
- package/src/operations/extrusions/extrudeWalls.js +2 -2
- package/src/operations/extrusions/project.js +11 -14
- package/src/operations/extrusions/project.test.js +49 -49
- package/src/operations/extrusions/slice/repair.js +62 -0
- package/src/operations/hulls/hullChain.test.js +4 -4
- package/src/operations/hulls/hullGeom2.js +6 -18
- package/src/operations/hulls/hullGeom3.js +5 -18
- package/src/operations/hulls/hullPath2.js +4 -14
- package/src/operations/hulls/hullPoints2.js +43 -92
- package/src/operations/hulls/toUniquePoints.js +34 -0
- package/src/operations/modifiers/generalize.js +2 -13
- package/src/operations/modifiers/generalize.test.js +0 -32
- package/src/operations/modifiers/insertTjunctions.js +1 -1
- package/src/operations/modifiers/insertTjunctions.test.js +21 -21
- package/src/operations/modifiers/mergePolygons.js +11 -14
- package/src/operations/{booleans → modifiers}/reTesselateCoplanarPolygons.js +33 -32
- package/src/operations/{booleans → modifiers}/reTesselateCoplanarPolygons.test.js +5 -5
- package/src/operations/{booleans → modifiers}/retessellate.js +2 -9
- package/src/operations/{booleans → modifiers}/retessellate.test.js +0 -0
- package/src/operations/modifiers/snapPolygons.test.js +12 -12
- package/src/operations/modifiers/triangulatePolygons.js +3 -3
- package/src/operations/transforms/center.js +1 -1
- package/src/primitives/circle.test.js +7 -0
- package/src/primitives/cuboid.js +1 -1
- package/src/primitives/cylinderElliptic.js +5 -3
- package/src/primitives/cylinderElliptic.test.js +7 -1
- package/src/primitives/ellipse.js +1 -1
- package/src/primitives/ellipse.test.js +7 -0
- package/src/primitives/ellipsoid.js +3 -3
- package/src/primitives/geodesicSphere.js +3 -2
- package/src/primitives/polyhedron.js +1 -1
- package/src/primitives/roundedCuboid.js +10 -8
- package/src/primitives/roundedCylinder.js +2 -2
- package/src/primitives/torus.test.js +11 -7
- package/src/primitives/triangle.js +1 -2
- package/src/utils/index.d.ts +0 -1
- package/src/utils/index.js +1 -3
- package/src/geometries/path2/eachPoint.d.ts +0 -9
- package/src/geometries/path2/eachPoint.js +0 -17
- package/src/geometries/path2/eachPoint.test.js +0 -11
- package/src/maths/mat4/constants.d.ts +0 -1
- package/src/maths/mat4/constants.js +0 -5
- package/src/operations/extrusions/slice/repairSlice.js +0 -47
- package/src/operations/modifiers/edges.js +0 -195
- 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[
|
|
136
|
-
const spherecenter = bound
|
|
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,113 +1,14 @@
|
|
|
1
1
|
const test = require('ava')
|
|
2
2
|
|
|
3
|
-
const { comparePolygonsAsPoints
|
|
3
|
+
const { comparePolygonsAsPoints } = require('../../../test/helpers')
|
|
4
4
|
|
|
5
|
-
const {
|
|
5
|
+
const { geom3 } = require('../../geometries')
|
|
6
6
|
|
|
7
|
-
const {
|
|
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.
|
|
10
|
-
poly3.
|
|
11
|
-
poly3.
|
|
12
|
-
poly3.
|
|
13
|
-
poly3.
|
|
14
|
-
poly3.
|
|
15
|
-
poly3.
|
|
16
|
-
poly3.
|
|
17
|
-
poly3.
|
|
18
|
-
poly3.
|
|
19
|
-
poly3.
|
|
20
|
-
poly3.
|
|
21
|
-
poly3.
|
|
22
|
-
poly3.
|
|
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('../
|
|
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.
|
|
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.
|
|
178
|
-
polygons.push(poly3.
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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/
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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)
|