diff --git a/src/decompose.jl b/src/decompose.jl index 903c033..38150d5 100644 --- a/src/decompose.jl +++ b/src/decompose.jl @@ -137,19 +137,26 @@ end # less strict version of above decompose(::Type{Simplex{1}}, f::Simplex{N, T}) where {N, T} = decompose(Simplex{1,T}, f) + +decompose(::Type{P}, points::AbstractVector{P}) where {P<: Point} = points +function decompose(::Type{Point{N1, T1}}, points::AbstractVector{Point{N2, T2}}) where {N1, T1, N2, T2} + return map(x-> to_pointn(Point{N1, T1}, x), points) +end + """ Get decompose a `HyperRectangle` into points. """ function decompose( - PT::Type{Point{N, T1}}, rect::HyperRectangle{N, T2} - ) where {N, T1, T2} + PT::Type{Point{N1, T1}}, rect::HyperRectangle{N2, T2} + ) where {N1, N2, T1, T2} # The general strategy is that since there are a deterministic number of # points, we can generate all points by looking at the binary increments. w = widths(rect) o = origin(rect) - points = T1[o[j]+((i>>(j-1))&1)*w[j] for j=1:N, i=0:(2^N-1)] - reshape(reinterpret(PT, points), (2^N,)) + points = T1[o[j]+((i>>(j-1))&1)*w[j] for j=1:N2, i=0:(2^N2-1)] + return decompose(PT, reshape(reinterpret(Point{N2, T1}, points), (2^N2,))) end + """ Get decompose a `HyperRectangle` into Texture Coordinates. """ @@ -163,23 +170,6 @@ function decompose( points = T1[((i>>(j-1))&1) for j=1:N, i=0:(2^N-1)] reshape(reinterpret(UVWT, points), (8,)) end -decompose(::Type{FT}, faces::Vector{FT}) where {FT<:Face} = faces -function decompose(::Type{FT1}, faces::Vector{FT2}) where {FT1<:Face, FT2<:Face} - isempty(faces) && return FT1[] - N1,N2 = length(FT1), length(FT2) - - n = length(decompose(FT1, first(faces))) - outfaces = Vector{FT1}(undef, length(faces)*n) - i = 1 - for face in faces - for outface in decompose(FT1, face) - outfaces[i] = outface - i += 1 - end - end - outfaces -end - """ Get decompose a `HyperRectangle` into faces. @@ -198,6 +188,30 @@ function decompose( decompose(FT, faces) end +function decompose( + FT::Type{Face{N, T}}, rect::HyperRectangle{2, T2} + ) where {N, T, T2} + return decompose(FT, SimpleRectangle(minimum(rect), widths(rect))) +end + +decompose(::Type{FT}, faces::Vector{FT}) where {FT<:Face} = faces + +function decompose(::Type{FT1}, faces::Vector{FT2}) where {FT1<:Face, FT2<:Face} + isempty(faces) && return FT1[] + N1,N2 = length(FT1), length(FT2) + + n = length(decompose(FT1, first(faces))) + outfaces = Vector{FT1}(undef, length(faces)*n) + i = 1 + for face in faces + for outface in decompose(FT1, face) + outfaces[i] = outface + i += 1 + end + end + outfaces +end + function decompose(P::Type{Point{2, PT}}, r::SimpleRectangle, resolution=(2,2)) where PT w, h = resolution vec(P[(x,y) for x=range(r.x, stop=r.x+r.w, length=w), y=range(r.y, stop=r.y+r.h, length=h)]) @@ -283,10 +297,8 @@ end # Define decompose for your own meshtype, to easily convert it to Homogenous attributes #Gets the normal attribute to a mesh -function decompose(T::Type{Point{3, VT}}, mesh::AbstractMesh) where VT - vts = mesh.vertices - eltype(vts) == T && return vts - eltype(vts) <: Point && return map(T, vts) +function decompose(T::Type{Point{N, VT}}, mesh::AbstractMesh) where {N, VT} + return decompose(T, mesh.vertices) end # gets the wanted face type diff --git a/src/primitives.jl b/src/primitives.jl index 1f92703..10a1860 100644 --- a/src/primitives.jl +++ b/src/primitives.jl @@ -18,17 +18,17 @@ function (meshtype::Type{T})(c::GeometryPrimitive, args...) where T <: AbstractM newattribs[fieldname] = decompose(eltype(typ), c, args...) end end - T(newattribs) + return T(newattribs) end function to_pointn(::Type{Point{N, T}}, p::StaticVector{N2}, d = T(0)) where {T, N, N2} - Point(ntuple(i-> i <= N2 ? p[i] : d, Val{N})) + return Point{N, T}(ntuple(i-> i <= N2 ? T(p[i]) : T(d), N)) end function (::Type{T})(c::Circle, n = 32) where T <: AbstractMesh newattribs = Dict{Symbol, Any}() VT = vertextype(T) - verts = decompose(VT, c) + verts = decompose(VT, c, n) N = length(verts) push!(verts, to_pointn(VT, origin(c))) # middle point middle_idx = length(verts) @@ -36,12 +36,12 @@ function (::Type{T})(c::Circle, n = 32) where T <: AbstractMesh faces = map(1:N) do i FT(i, middle_idx, i + 1) end - T(vertices = verts, faces = faces) + return T(vertices = verts, faces = faces) end function (meshtype::Type{T})( c::Union{HyperCube{3,T}, HyperRectangle{3,HT}} - ) where {T <: HMesh,HT} + ) where {T <: HMesh, HT} xdir = Vec{3, HT}(1, 0, 0) ydir = Vec{3, HT}(0, 1, 0) zdir = Vec{3, HT}(0, 0, 1) @@ -61,5 +61,5 @@ function (meshtype::Type{T})( map!(v, v) do v (v .* w) + o end - mesh + return mesh end diff --git a/test/decompose.jl b/test/decompose.jl index 8c1c9e7..84929de 100644 --- a/test/decompose.jl +++ b/test/decompose.jl @@ -10,9 +10,14 @@ end a = HyperRectangle(Vec(0,0),Vec(1,1)) pt_expa = Point{2,Int}[(0,0), (1,0), (0,1), (1,1)] @test decompose(Point{2,Int},a) == pt_expa + mesh = GLNormalMesh(a) + @test decompose(Point2f0, mesh) == pt_expa + b = HyperRectangle(Vec(1,1,1),Vec(1,1,1)) pt_expb = Point{3,Int}[(1,1,1),(2,1,1),(1,2,1),(2,2,1),(1,1,2),(2,1,2),(1,2,2),(2,2,2)] @test decompose(Point{3,Int}, b) == pt_expb + mesh = NormalMesh{Int, GLTriangle, Int}(b) + # TODO order of NormalMesh & decompose doesn't agree -.- end @testset "Faces" begin @@ -135,7 +140,6 @@ end end - @testset "HyperSphere" begin sphere = Sphere{Float32}(Point3f0(0), 1f0) @@ -154,12 +158,12 @@ end [4, 5, 8], [4, 8, 7], [5, 6, 9], [5, 9, 8] ] @test f == face_target - - points = decompose(Point2f0, Circle(Point2f0(0), 0f0), 20) + circle = Circle(Point2f0(0), 1f0) + points = decompose(Point2f0, circle, 20) @test length(points) == 20 - + mesh = GLNormalMesh(circle, 32) + # end-1, since we add a middle point for the mesh! + @test decompose(Point2f0, mesh)[1:end-1] ≈ decompose(Point2f0, circle, 32) end - - end