44Base. extrema (primitive:: GeometryPrimitive ) = (minimum (primitive), maximum (primitive))
55function widths (x:: AbstractRange )
66 mini, maxi = Float32 .(extrema (x))
7- maxi - mini
7+ return maxi - mini
88end
99
1010# #
1111# conversion & decompose
1212
1313"""
14- simplex_convert (::Type{Face{3}}, f::Face{N})
14+ convert_simplex (::Type{Face{3}}, f::Face{N})
1515
1616Triangulate an N-Face into a tuple of triangular faces.
1717"""
18- @generated function simplex_convert (:: Type{TriangleFace{T}} , f:: NgonFace{N} ) where {T, N}
18+ @generated function convert_simplex (:: Type{TriangleFace{T}} , f:: NgonFace{N} ) where {T, N}
1919 3 <= N || error (" decompose not implented for N <= 3 yet. N: $N " )# other wise degenerate
2020 v = Expr (:tuple )
2121 for i = 3 : N
@@ -25,11 +25,11 @@ Triangulate an N-Face into a tuple of triangular faces.
2525end
2626
2727"""
28- simplex_convert (::Type{Face{2}}, f::Face{N})
28+ convert_simplex (::Type{Face{2}}, f::Face{N})
2929
3030Extract all line segments in a Face.
3131"""
32- @generated function simplex_convert (:: Type{LineFace{T}} , f:: NgonFace{N} ) where {T, N}
32+ @generated function convert_simplex (:: Type{LineFace{T}} , f:: NgonFace{N} ) where {T, N}
3333 2 <= N || error (" decompose not implented for N <= 2 yet. N: $N " )# other wise degenerate
3434
3535 v = Expr (:tuple )
@@ -41,35 +41,47 @@ Extract all line segments in a Face.
4141 return v
4242end
4343
44- to_pointn (:: Type{T} , x) where T<: Point = simplex_convert (T, x)[1 ]
44+ to_pointn (:: Type{T} , x) where T<: Point = convert_simplex (T, x)[1 ]
4545
46- simplex_convert (:: Type{Point} , x:: Point ) = (x,)
47- function simplex_convert (:: Type{Point{N, T}} , x) where {N, T}
46+ convert_simplex (:: Type{Point} , x:: Point ) = (x,)
47+ function convert_simplex (:: Type{Point{N, T}} , x) where {N, T}
4848 N2 = length (x)
4949 return (Point {N, T} (ntuple (i-> i <= N2 ? T (x[i]) : T (0 ), N)),)
5050end
5151
52- function simplex_convert (:: Type{Vec{N, T}} , x) where {N, T}
52+ function convert_simplex (:: Type{Vec{N, T}} , x) where {N, T}
5353 N2 = length (x)
5454 return (Vec {N, T} (ntuple (i-> i <= N2 ? T (x[i]) : T (0 ), N)),)
5555end
5656
57-
5857function collect_with_eltype (:: Type{T} , iter) where T
5958 # TODO we could be super smart about allocating the right length
6059 # but its kinda annoying, since e.g. T == Triangle and first(iter) isa Quad
6160 # will need double the length etc - but could all be figured out ;)
6261 result = T[]
6362 for element in iter
64- # simplex_convert always returns a tuple,
63+ # convert_simplex always returns a tuple,
6564 # so that e.g. convert(Triangle, quad) can return 2 elements
66- for telement in simplex_convert (T, element)
65+ for telement in convert_simplex (T, element)
6766 push! (result, telement)
6867 end
6968 end
7069 return result
7170end
7271
72+
73+ function faces (primitive, nvertices= 30 )
74+ # doesn't have any specific algorithm to generate faces
75+ # so will try to triangulate the coordinates!
76+ return nothing
77+ end
78+
79+ function decompose (:: Type{F} , primitive, args... ) where {F<: AbstractFace }
80+ f = faces (primitive, args... )
81+ f === nothing && return nothing
82+ return collect_with_eltype (F, f)
83+ end
84+
7385function decompose (:: Type{T} , primitive:: AbstractVector{T} ) where {T}
7486 return primitive
7587end
@@ -86,27 +98,45 @@ function decompose(::Type{P}, primitive, args...) where {P<:AbstractPoint}
8698 return collect_with_eltype (P, coordinates (primitive, args... ))
8799end
88100
89- function decompose (:: Type{F} , primitive, args... ) where {F<: AbstractFace }
90- return collect_with_eltype (F, faces (primitive, args... ))
91- end
101+
92102
93103function decompose (:: Type{Point} , primitive:: GeometryPrimitive{Dim} , args... ) where {Dim}
94104 return collect_with_eltype (Point{Dim, Float32}, coordinates (primitive, args... ))
95105end
96106
107+ # Dispatch type to make `decompose(UV{Vec2f0}, priomitive)` work
108+ struct UV{T} end
109+ UV (:: Type{T} ) where T = UV {T} ()
110+ struct UVW{T} end
111+ UVW (:: Type{T} ) where T = UVW {T} ()
112+ struct Normal{T} end
113+ Normal (:: Type{T} ) where T = Normal {T} ()
114+
115+ function decompose (:: UV{T} , primitive:: GeometryPrimitive , args... ) where T
116+ return collect_with_eltype (T, texturecoordinates (primitive, args... ))
117+ end
118+
119+ decompose_uv (args... ) = decompose (UV (Vec2f0), args... )
97120
98- function decompose_uv ( primitive:: GeometryPrimitive , args... )
99- return collect_with_eltype (Vec2f0 , texturecoordinates (primitive, args... ))
121+ function decompose ( :: UVW{T} , primitive:: GeometryPrimitive , args... ) where T
122+ return collect_with_eltype (T , texturecoordinates (primitive, args... ))
100123end
101124
102- function decompose_uvw (primitive:: GeometryPrimitive , args... )
103- return collect_with_eltype (Vec3f0, texturecoordinates (primitive, args... ))
125+ function normals (primitive, nvertices= 30 )
126+ # doesn't have any specific algorithm to generate normals
127+ # so will be generated from faces + positions
128+ return nothing
104129end
105130
106- function decompose_normals (primitive:: GeometryPrimitive , args... )
107- return collect_with_eltype (Vec3f0, normals (primitive, args... ))
131+
132+ function decompose (:: Normal{T} , primitive:: GeometryPrimitive , args... ) where T
133+ n = normals (primitive, args... )
134+ n === nothing && return nothing
135+ return collect_with_eltype (T, n)
108136end
109137
138+ decompose_normals (args... ) = decompose (Normal (Vec3f0), args... )
139+
110140"""
111141The unnormalized normal of three vertices.
112142"""
@@ -124,8 +154,10 @@ normals{VT,FD,FT,FO}(vertices::Vector{Point{3, VT}},
124154```
125155Compute all vertex normals.
126156"""
127- function normals (vertices:: AbstractVector{<: AbstractPoint{3, T}} , faces:: AbstractVector{F} ) where {T, F <: NgonFace }
128- normals_result = zeros (Vec{3 , T}, length (vertices)) # initilize with same type as verts but with 0
157+ function normals (vertices:: AbstractVector{<: AbstractPoint{3, T}} ,
158+ faces:: AbstractVector{F} ;
159+ normaltype= Vec{3 , T}) where {T, F <: NgonFace }
160+ normals_result = zeros (normaltype, length (vertices)) # initilize with same type as verts but with 0
129161 for face in faces
130162 v = metafree .(vertices[face])
131163 # we can get away with two edges since faces are planar.
@@ -230,6 +262,8 @@ function rotation(c::Cylinder{3, T}) where T
230262 return hcat (v, w, u)
231263end
232264
265+ best_nvertices (x:: Cylinder{2} ) = (2 , 2 )
266+
233267function coordinates (c:: Cylinder{2, T} , nvertices= (2 , 2 )) where T
234268 r = Rect (c. origin[1 ] - c. r/ 2 , c. origin[2 ], c. r, height (c))
235269 M = rotation (c)
@@ -238,9 +272,19 @@ function coordinates(c::Cylinder{2, T}, nvertices=(2, 2)) where T
238272 return (M * (to_pointn (Point3{T}, point) .- vo) .+ vo for point in points)
239273end
240274
275+ function faces (sphere:: Cylinder{2} , nvertices= (2 , 2 ))
276+ return faces (Rect (0 , 0 , 1 , 1 ), nvertices)
277+ end
278+
279+ best_nvertices (x:: Cylinder{3} ) = 30
280+
241281function coordinates (c:: Cylinder{3, T} , nvertices= 30 ) where T
242- isodd (nvertices) && (nvertices = 2 * div (nvertices, 2 ))
243- nbv = div (nvertices, 2 )
282+ if isodd (nvertices)
283+ nvertices = 2 * (nvertices ÷ 2 )
284+ end
285+ nvertices = max (8 , nvertices);
286+ nbv = nvertices ÷ 2
287+
244288 M = rotation (c)
245289 h = height (c)
246290 range = 1 : (2 * nbv + 2 )
@@ -259,15 +303,6 @@ function coordinates(c::Cylinder{3, T}, nvertices=30) where T
259303 return (inner (i) for i in range)
260304end
261305
262- function texturecoordinates (s:: Cylinder , nvertices= 24 )
263- ux = LinRange (0 , 1 , nvertices)
264- return ivec ((Vec (φ, θ) for θ in reverse (ux), φ in ux))
265- end
266-
267- function faces (sphere:: Cylinder{2} , nvertices= (2 , 2 ))
268- return faces (Rect (0 , 0 , 1 , 1 ), nvertices)
269- end
270-
271306function faces (c:: Cylinder{3} , facets= 30 )
272307 isodd (facets) ? facets = 2 * div (facets, 2 ) : nothing
273308 facets < 8 ? facets = 8 : nothing ; nbv = Int (facets / 2 )
@@ -287,10 +322,6 @@ function faces(c::Cylinder{3}, facets=30)
287322 return indexes
288323end
289324
290- function normals (s:: Cylinder{T} , nvertices= 24 ) where T
291- return coordinates (Sphere (Point {3, T} (0 ), 1f0 ), nvertices)
292- end
293-
294325# #
295326# Sphere
296327
337368function normals (s:: Sphere{T} , nvertices= 24 ) where {T}
338369 return coordinates (Sphere (Point {3, T} (0 ), 1 ), nvertices)
339370end
371+
372+ function coordinates (p:: Pyramid{T} , nvertices= nothing ) where {T}
373+ leftup = Point {3, T} (- p. width , p. width, 0 ) / 2
374+ leftdown = Point (- p. width, - p. width, 0 ) / 2
375+ tip = Point {3, T} (p. middle + Point {3, T} (0 , 0 , p. length))
376+ lu = Point {3, T} (p. middle + leftup)
377+ ld = Point {3, T} (p. middle + leftdown)
378+ ru = Point {3, T} (p. middle - leftdown)
379+ rd = Point {3, T} (p. middle - leftup)
380+ return Point{3 , T}[
381+ tip, rd, ru,
382+ tip, ru, lu,
383+ tip, lu, ld,
384+ tip, ld, rd,
385+ rd, ru, lu,
386+ lu, ld, rd
387+ ]
388+ end
389+
390+ function faces (r:: Pyramid , nvertices= nothing ) where FT
391+ return (TriangleFace (triangle) for triangle in TupleView {3} (1 : 18 ))
392+ end
0 commit comments