Skip to content

Commit d80cb6a

Browse files
committed
preserve meta when converting
1 parent 009860d commit d80cb6a

File tree

3 files changed

+38
-5
lines changed

3 files changed

+38
-5
lines changed

src/geometry_primitives.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ function widths(x::AbstractRange)
66
return maxi - mini
77
end
88

9+
# GeometryPrimitive's don't have attributes per se
10+
function attributes(nometa::GeometryPrimitive)
11+
return Dict{Symbol, Any}()
12+
end
13+
914
##
1015
# conversion & decompose
1116

src/meshes.jl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,25 +110,32 @@ function mesh(primitive::Meshable;
110110
# triangulation.jl
111111
faces = decompose(facetype, positions)
112112
end
113-
attributes = Dict{Symbol, Any}()
113+
114+
# We want to preserve any existing attributes!
115+
attrs = attributes(primitive)
116+
# Make sure this doesn't contain position, we'll add position explicitely via meta!
117+
delete!(attrs, :position)
114118

115119
if uv !== nothing
116-
attributes[:uv] = decompose(UV(uv), primitive)
120+
# this may overwrite an existing :uv, but will only create a copy
121+
# if it has a different eltype, otherwise it should replace it
122+
# with exactly the same instance - which is what we want here
123+
attrs[:uv] = decompose(UV(uv), primitive)
117124
end
118125

119126
if normaltype !== nothing
120127
primitive_normals = normals(primitive)
121128
if primitive_normals !== nothing
122-
attributes[:normals] = decompose(normaltype, primitive_normals)
129+
attrs[:normals] = decompose(normaltype, primitive_normals)
123130
else
124131
# Normals not implemented for primitive, so we calculate them!
125132
n = normals(positions, faces)
126133
if n !== nothing # ok jeez, this is a 2d mesh which cant have normals
127-
attributes[:normals] = n
134+
attrs[:normals] = n
128135
end
129136
end
130137
end
131-
return Mesh(meta(positions; attributes...), faces)
138+
return Mesh(meta(positions; attrs...), faces)
132139
end
133140

134141
"""

test/runtests.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,27 @@ end
323323
include("geometrytypes.jl")
324324
end
325325

326+
@testset "convert mesh + meta" begin
327+
m = uv_normal_mesh(FRect3D(Vec3f0(-1), Vec3f0(1, 2, 3)))
328+
m_normal = normal_mesh(m)
329+
# make sure we don't loose the uv
330+
@test hasproperty(m_normal, :uv)
331+
@test m == m_normal
332+
# Make sure we don't create any copies
333+
@test m.position === m_normal.position
334+
@test m.normals === m_normal.normals
335+
@test m.uv === m_normal.uv
336+
337+
m = GeometryBasics.mesh(FRect3D(Vec3f0(-1), Vec3f0(1, 2, 3));
338+
uv=Vec2{Float64}, normaltype=Vec3{Float64}, pointtype=Point3{Float64})
339+
m_normal = normal_mesh(m)
340+
@test hasproperty(m_normal, :uv)
341+
@test m.position !== m_normal.position
342+
@test m.normals !== m_normal.normals
343+
# uv stays untouched, since we don't specify the element type in normalmesh
344+
@test m.uv === m_normal.uv
345+
end
346+
326347
@testset "modifying meta" begin
327348
xx = rand(10)
328349
points = rand(Point3f0, 10)

0 commit comments

Comments
 (0)