Skip to content

Commit 5d04195

Browse files
authored
Merge pull request #20 from JuliaGeometry/sd/fix
fix for MeshIO
2 parents 2fda42e + c7353d8 commit 5d04195

File tree

5 files changed

+75
-41
lines changed

5 files changed

+75
-41
lines changed

src/basic_types.jl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,11 +352,22 @@ end
352352
Tables.schema(mesh::Mesh) = Tables.schema(getfield(mesh, :simplices))
353353

354354
function Base.getproperty(mesh::Mesh, name::Symbol)
355-
return getproperty(getfield(mesh, :simplices), name)
355+
if name === :position
356+
# a mesh always has position defined by coordinates...
357+
return coordinates(mesh)
358+
else
359+
return getproperty(getfield(mesh, :simplices), name)
360+
end
356361
end
357362

358363
function Base.propertynames(mesh::Mesh)
359-
return propertynames(getfield(mesh, :simplices))
364+
names = propertynames(getfield(mesh, :simplices))
365+
if :positions in names
366+
return names
367+
else
368+
# a mesh always has positions!
369+
return (names..., :position)
370+
end
360371
end
361372

362373
function Base.summary(io::IO, ::Mesh{Dim, T, Element}) where {Dim, T, Element}

src/geometry_primitives.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,7 @@ function decompose(::Type{P}, primitive, args...) where {P<:AbstractPoint}
9898
return collect_with_eltype(P, coordinates(primitive, args...))
9999
end
100100

101-
102-
103-
function decompose(::Type{Point}, primitive::GeometryPrimitive{Dim}, args...) where {Dim}
101+
function decompose(::Type{Point}, primitive::Union{GeometryPrimitive{Dim}, Mesh{Dim}}, args...) where {Dim}
104102
return collect_with_eltype(Point{Dim, Float32}, coordinates(primitive, args...))
105103
end
106104

src/meshes.jl

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,19 @@ Polygon triangluation!
124124
"""
125125
function mesh(polygon::AbstractVector{P}; pointtype=P, facetype=GLTriangleFace,
126126
normaltype=nothing, nvertices=nothing) where {P<:AbstractPoint{2}}
127+
127128
faces = decompose(facetype, polygon)
128129
positions = decompose(pointtype, polygon)
130+
129131
if nvertices !== nothing
130132
error("Resampling polygon not supported!")
131133
end
134+
132135
if normaltype !== nothing
133136
n = normals(positions, faces; normaltype=normaltype)
134137
positions = meta(positions; normals=n)
135138
end
139+
136140
return Mesh(positions, faces)
137141
end
138142

@@ -215,3 +219,40 @@ function decompose(::UV{T}, mesh::Mesh) where {T}
215219
error("Mesh doesn't have UV texture coordinates")
216220
end
217221
end
222+
223+
"""
224+
pointmeta(mesh::Mesh; meta_data...)
225+
226+
Attaches metadata to the coordinates of a mesh
227+
"""
228+
function pointmeta(mesh::Mesh; meta_data...)
229+
points = coordinates(mesh)
230+
attr = GeometryBasics.attributes(points)
231+
delete!(attr, :position) # position == metafree(points)
232+
# delete overlapping attributes so we can replace with `meta_data`
233+
foreach(k-> delete!(attr, k), keys(meta_data))
234+
return Mesh(meta(metafree(points); attr..., meta_data...), faces(mesh))
235+
end
236+
237+
"""
238+
pop_pointmeta(mesh::Mesh, property::Symbol)
239+
Remove `property` from point metadata.
240+
Returns the new mesh, and the property!
241+
"""
242+
function pop_pointmeta(mesh::Mesh, property::Symbol)
243+
points = coordinates(mesh)
244+
attr = GeometryBasics.attributes(points)
245+
delete!(attr, :position) # position == metafree(points)
246+
# delete overlapping attributes so we can replace with `meta_data`
247+
m = pop!(attr, property)
248+
return Mesh(meta(metafree(points); attr...), faces(mesh)), m
249+
end
250+
251+
"""
252+
facemeta(mesh::Mesh; meta_data...)
253+
254+
Attaches metadata to the faces of a mesh
255+
"""
256+
function facemeta(mesh::Mesh; meta_data...)
257+
return Mesh(coordinates(mesh), meta(faces(mesh); meta_data...))
258+
end

src/metadata.jl

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,12 @@ macro meta_type(name, mainfield, supertype, params...)
8080
GeometryBasics.meta(x::AbstractVector{<: $MetaName}) = getcolumns(x, :meta)[1]
8181

8282
function GeometryBasics.meta(main::$supertype; meta...)
83+
isempty(meta) && return elements # no meta to add!
8384
return $MetaName(main; meta...)
8485
end
8586

8687
function GeometryBasics.meta(elements::AbstractVector{T}; meta...) where T <: $supertype
88+
isempty(meta) && return elements # no meta to add!
8789
n = length(elements)
8890
for (k, v) in meta
8991
if v isa AbstractVector
@@ -131,35 +133,3 @@ Base.getindex(x::NgonFaceMeta, idx::Int) = getindex(metafree(x), idx)
131133
Base.getindex(x::SimplexFaceMeta, idx::Int) = getindex(metafree(x), idx)
132134

133135
@meta_type(Polygon, polygon, AbstractPolygon, N, T)
134-
135-
"""
136-
pointmeta(mesh::Mesh; meta_data...)
137-
138-
Attaches metadata to the coordinates of a mesh
139-
"""
140-
function pointmeta(mesh::Mesh; meta_data...)
141-
points = coordinates(mesh)
142-
attr = GeometryBasics.attributes(points)
143-
delete!(attr, :position) # position == metafree(points)
144-
# delete overlapping attributes so we can replace with `meta_data`
145-
foreach(k-> delete!(attr, k), keys(meta_data))
146-
return Mesh(meta(metafree(points); attr..., meta_data...), faces(mesh))
147-
end
148-
149-
function pop_pointmeta(mesh::Mesh, property::Symbol)
150-
points = coordinates(mesh)
151-
attr = GeometryBasics.attributes(points)
152-
delete!(attr, :position) # position == metafree(points)
153-
# delete overlapping attributes so we can replace with `meta_data`
154-
m = pop!(attr, property)
155-
return Mesh(meta(metafree(points); attr...), faces(mesh)), m
156-
end
157-
158-
"""
159-
facemeta(mesh::Mesh; meta_data...)
160-
161-
Attaches metadata to the faces of a mesh
162-
"""
163-
function facemeta(mesh::Mesh; meta_data...)
164-
Mesh(coordinates(mesh), meta(faces(mesh); meta_data...))
165-
end

test/runtests.jl

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ using LinearAlgebra
108108
@test y == [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1)]
109109

110110
end
111-
111+
112112
@testset "connected views" begin
113113
numbers = [1, 2, 3, 4, 5, 6]
114114
x = connect(numbers, Point{2})
@@ -279,9 +279,15 @@ end
279279

280280
@testset "decompose/triangulation" begin
281281
primitive = Sphere(Point3f0(0), 1)
282-
triangle_mesh(primitive)
282+
mesh = triangle_mesh(primitive)
283+
@test decompose(Point, mesh) isa Vector{Point3f0}
284+
@test decompose(Point, primitive) isa Vector{Point3f0}
283285
primitive = Rect2D(0, 0, 1, 1)
284-
triangle_mesh(primitive)
286+
mesh = triangle_mesh(primitive)
287+
288+
@test decompose(Point, mesh) isa Vector{Point2f0}
289+
@test decompose(Point, primitive) isa Vector{Point2f0}
290+
285291
primitive = Rect3D(0, 0, 0, 1, 1, 1)
286292
triangle_mesh(primitive)
287293

@@ -295,8 +301,8 @@ end
295301
points = decompose(Point2f0, Circle(Point2f0(0), 1))
296302
triangle_mesh(points)
297303
@test true # yay no errors so far!
298-
end
299304

305+
end
300306

301307
@testset "Tests from GeometryTypes" begin
302308
include("geometrytypes.jl")
@@ -317,7 +323,15 @@ end
317323

318324
m, colpopt = GeometryBasics.pop_pointmeta(m, :color)
319325
m, xxpopt = GeometryBasics.pop_pointmeta(m, :xx)
326+
320327
@test propertynames(m) == (:position,)
321328
@test colpopt === color
322329
@test xxpopt === xx
330+
331+
@testset "creating meta" begin
332+
x = Point3f0[(1,3,4)]
333+
# no meta gets added, so should stay the same
334+
@test meta(x) === x
335+
@test meta(x, value=[1]).position === x
336+
end
323337
end

0 commit comments

Comments
 (0)