Skip to content

Commit 94496a5

Browse files
committed
prototype MultiFace Rect -> Mesh pipeline
1 parent 73385bf commit 94496a5

File tree

3 files changed

+54
-18
lines changed

3 files changed

+54
-18
lines changed

src/basic_types.jl

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,21 @@ end
6464

6565
MultiFace(; kwargs...) = MultiFace(NamedTuple(kwargs))
6666
MultiFace{Names}(args...) where {Names} = MultiFace(NamedTuple{Names}(args))
67+
MultiFace{Names}(args::Tuple{Vararg{<: AbstractFace}}) where {Names} = MultiFace(NamedTuple{Names}(args))
68+
MultiFace{Names, FT}(args) where {Names, FT <: AbstractFace} = MultiFace(NamedTuple{Names}(FT.(args)))
6769

68-
Base.names(::Type{<: MultiFace{N, T, FT, Names}}) where {N, T, FT, Names} = Names
69-
function Base.getindex(f::MultiFace{N, T, FT, Names, N_Attrib}, i::Integer) where {N, T, FT, Names, N_Attrib}
70-
return ntuple(n -> f.faces[n][i], N_Attrib)
71-
end
70+
Base.getindex(f::MultiFace, i::Int64) = Base.getindex(getfield(f, :faces), i) # TODO: StaticVector should index with Integer
71+
@inline Base.hasproperty(f::MultiFace, field::Symbol) = hasproperty(getfield(f, :faces), field)
72+
@inline Base.getproperty(f::MultiFace, field::Symbol) = getproperty(getfield(f, :faces), field)
73+
@inline Base.propertynames(f::MultiFace) = propertynames(getfield(f, :faces))
74+
@inline Base.propertynames(::Type{<: MultiFace{N, T, FT, Names}}) where {N, T, FT, Names} = Names
7275

7376
# TODO: Some shorthands
7477
const NormalFace = MultiFace{(:position, :normal)}
7578
const NormalUVFace = MultiFace{(:position, :normal, :uv)}
7679

80+
# TODO: enable something like NormalUVFace{QuadFace}[...]
81+
7782
@propagate_inbounds Base.getindex(x::Polytope, i::Integer) = coordinates(x)[i]
7883
@propagate_inbounds Base.iterate(x::Polytope) = iterate(coordinates(x))
7984
@propagate_inbounds Base.iterate(x::Polytope, i) = iterate(coordinates(x), i)
@@ -340,7 +345,7 @@ struct Mesh{
340345
end
341346

342347
if FT <: MultiFace
343-
f_names = names(FT)
348+
f_names = propertynames(FT)
344349
if Names != f_names
345350
error(
346351
"Cannot construct a mesh with vertex attribute names $Names and MultiFace " *

src/meshes.jl

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ It also only losely correlates to the number of vertices, depending on the algor
1414
function mesh(primitive::AbstractGeometry; pointtype=Point, facetype=GLTriangleFace, vertex_attributes...)
1515
positions = decompose(pointtype, primitive)
1616
_f = faces(primitive)
17+
1718
# If faces returns nothing for primitive, we try to triangulate!
1819
if isnothing(_f)
1920
if eltype(positions) <: Point2
@@ -23,11 +24,30 @@ function mesh(primitive::AbstractGeometry; pointtype=Point, facetype=GLTriangleF
2324
error("No triangulation for $(typeof(primitive))")
2425
end
2526
else
27+
if _f isa AbstractVector{<: MultiFace}
28+
if facetype isa MultiFace
29+
# drop faces that facetype doesn't include
30+
names = propertynames(facetype)
31+
_f = map(f -> MultiFace{names}(getproperty.((f,), names)), _f)
32+
else
33+
# drop faces for vertex attributes that aren't given
34+
names = (:position, keys(vertex_attributes)...)
35+
_f2 = map(f -> MultiFace{names}(getproperty.((f,), names)), _f)
36+
37+
# and remap to a simple face type so that decompose can handle the rest
38+
_f, mappings = merge_vertex_indices(_f2)
39+
positions = positions[mappings[1]]
40+
vertex_attributes = NamedTuple(
41+
(Pair(names[i], vertex_attributes[i-1][mappings[i]]) for i in 2:length(mappings))
42+
)
43+
end
44+
end
2645
f = decompose(facetype, _f)
2746
end
2847
return Mesh(positions, f; vertex_attributes...)
2948
end
3049

50+
3151
const SimpleMesh{N, T, FT} = Mesh{N, T, FT, (:position,), Tuple{Vector{Point{N, T}}}, Vector{FT}}
3252
const SimpleTriangleMesh{N} = SimpleMesh{N, Float32, GLTriangleFace}
3353

@@ -72,20 +92,20 @@ end
7292

7393
function uv_normal_mesh(primitive::AbstractGeometry{N}) where {N}
7494
return mesh(
75-
primitive, uv = decompose_uv(primitive), normals = decompose_normals(primitive),
95+
primitive, uv = decompose_uv(primitive), normal = decompose_normals(primitive),
7696
pointtype=Point{N,Float32}, facetype=GLTriangleFace)
7797
end
7898

7999
function normal_mesh(points::AbstractVector{<:Point},
80100
faces::AbstractVector{<:AbstractFace})
81101
_points = decompose(Point3f, points)
82102
_faces = decompose(GLTriangleFace, faces)
83-
return Mesh(_faces, position = _points, normals = normals(_points, _faces))
103+
return Mesh(_faces, position = _points, normal = normals(_points, _faces))
84104
end
85105

86106
function normal_mesh(primitive::AbstractGeometry{N}) where {N}
87107
return mesh(
88-
primitive, normals = decompose_normals(primitive),
108+
primitive, normal = decompose_normals(primitive),
89109
pointtype=Point{N,Float32}, facetype=GLTriangleFace)
90110
end
91111

@@ -224,7 +244,7 @@ function merge_vertex_indices(
224244
for i in 1:N
225245
# get the i-th set of vertex indices from multi_face, i.e.
226246
# (multi_face.position_index[i], multi_face.normal_index[i], ...)
227-
vertex = ntuple(n -> multi_face.faces[n][i], N_Attrib)
247+
vertex = ntuple(n -> multi_face[n][i], N_Attrib)
228248

229249
# if the vertex exists, get it's index
230250
# otherwise register it with the next available vertex index

src/primitives/rectangles.jl

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -563,22 +563,33 @@ end
563563

564564
##
565565
# Rect3 decomposition
566-
function coordinates(rect::Rect3)
566+
function coordinates(rect::Rect3{T}) where T
567567
# TODO use n
568568
w = widths(rect)
569569
o = origin(rect)
570-
points = Point{3,Int}[(0, 0, 0), (0, 0, 1), (0, 1, 1), (0, 1, 0), (0, 0, 0), (1, 0, 0),
571-
(1, 0, 1), (0, 0, 1), (0, 0, 0), (0, 1, 0), (1, 1, 0), (1, 0, 0),
572-
(1, 1, 1), (0, 1, 1), (0, 0, 1), (1, 0, 1), (1, 1, 1), (1, 0, 1),
573-
(1, 0, 0), (1, 1, 0), (1, 1, 1), (1, 1, 0), (0, 1, 0), (0, 1, 1)]
574-
return ((x .* w .+ o) for x in points)
570+
# points = Point{3,Int}[(0, 0, 0), (0, 0, 1), (0, 1, 1), (0, 1, 0), (0, 0, 0), (1, 0, 0),
571+
# (1, 0, 1), (0, 0, 1), (0, 0, 0), (0, 1, 0), (1, 1, 0), (1, 0, 0),
572+
# (1, 1, 1), (0, 1, 1), (0, 0, 1), (1, 0, 1), (1, 1, 1), (1, 0, 1),
573+
# (1, 0, 0), (1, 1, 0), (1, 1, 1), (1, 1, 0), (0, 1, 0), (0, 1, 1)]
574+
# return ((x .* w .+ o) for x in points)
575+
return Point{3, T}[o + (x, y, z) .* w for x in (0, 1) for y in (0, 1) for z in (0, 1)]
576+
end
577+
578+
function normals(::Rect3)
579+
return Vec3f[(-1,0,0), (1,0,0), (0,-1,0), (0,1,0), (0,0,-1), (0,0,1)]
575580
end
576581

577582
function texturecoordinates(rect::Rect3)
578583
return coordinates(Rect3(0, 0, 0, 1, 1, 1))
579584
end
580585

581-
function faces(rect::Rect3)
582-
return QuadFace{Int}[(1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12), (13, 14, 15, 16),
583-
(17, 18, 19, 20), (21, 22, 23, 24),]
586+
function faces(::Rect3)
587+
return NormalUVFace{QuadFace}.([
588+
((1, 2, 3, 4), 1, (1, 2, 3, 4)), # -x
589+
((5, 6, 7, 8), 2, (5, 6, 7, 8)), # +x
590+
((1, 2, 5, 6), 3, (1, 2, 5, 6)), # -y
591+
((3, 4, 7, 8), 4, (3, 4, 7, 8)), # +y
592+
((1, 3, 5, 7), 5, (1, 3, 5, 7)), # -z
593+
((2, 4, 6, 8), 6, (2, 4, 6, 8)), # +z
594+
])
584595
end

0 commit comments

Comments
 (0)