Skip to content
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "GeometryBasics"
uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
authors = ["SimonDanisch <sdanisch@gmail.com>"]
version = "0.2.13"
version = "0.2.15"

[deps]
IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ julia> metafree(poi)
3
1

# for other geometries metatypes are predefined
julia> multipoi = MultiPointMeta([p1], city="Abuja", rainfall=1221.2)
1-element MultiPointMeta{Point{2,Int64},MultiPoint{2,Int64,Point{2,Int64},Array{Point{2,Int64},1}},(:city, :rainfall),Tuple{String,Float64}}:
[3, 1]

# connect the points with lines
julia> l1 = Line(p1, p2)
Line([3, 1] => [1, 3])
Expand Down
2 changes: 1 addition & 1 deletion src/GeometryBasics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ module GeometryBasics
export OffsetInteger, ZeroIndex, OneIndex, GLIndex
export FaceView, SimpleFaceView
export AbstractPoint, PointMeta, PointWithUV
export PolygonMeta, MultiPointMeta, MultiLineStringMeta, MeshMeta
export PolygonMeta, MultiPointMeta, MultiLineStringMeta, MeshMeta, LineStringMeta, MultiPolygonMeta
export decompose, coordinates, faces, normals, decompose_uv, decompose_normals, texturecoordinates
export Tesselation, pointmeta, Normal, UV, UVW
export GLTriangleFace, GLNormalMesh3D, GLPlainTriangleMesh, GLUVMesh3D, GLUVNormalMesh3D
Expand Down
4 changes: 2 additions & 2 deletions src/interfaces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function faces(f::AbstractVector{<:AbstractFace})
return f
end

function normals(primitive, nvertices=nothing)
function normals(primitive, nvertices=nothing; kw...)
# doesn't have any specific algorithm to generate normals
# so will be generated from faces + positions
# which we indicate by returning nothing!
Expand All @@ -27,7 +27,7 @@ function normals(primitive, nvertices=nothing)
return nothing
end

function faces(primitive, nvertices=nothing)
function faces(primitive, nvertices=nothing; kw...)
# doesn't have any specific algorithm to generate faces
# so will try to triangulate the coordinates!
return nothing
Expand Down
8 changes: 8 additions & 0 deletions src/metadata.jl
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ Base.getindex(x::SimplexFaceMeta, idx::Int) = getindex(metafree(x), idx)

@meta_type(Polygon, polygon, AbstractPolygon, N, T)

@meta_type(LineString, lines, AbstractVector, P <: Line)
Base.getindex(x::LineStringMeta, idx::Int) = getindex(metafree(x), idx)
Base.size(x::LineStringMeta) = size(metafree(x))

@meta_type(MultiPoint, points, AbstractVector, P <: AbstractPoint)
Base.getindex(x::MultiPointMeta, idx::Int) = getindex(metafree(x), idx)
Base.size(x::MultiPointMeta) = size(metafree(x))
Expand All @@ -179,6 +183,10 @@ Base.size(x::MultiPointMeta) = size(metafree(x))
Base.getindex(x::MultiLineStringMeta, idx::Int) = getindex(metafree(x), idx)
Base.size(x::MultiLineStringMeta) = size(metafree(x))

@meta_type(MultiPolygon, polygons, AbstractVector, P <: Polygon)
Base.getindex(x::MultiPolygonMeta, idx::Int) = getindex(metafree(x), idx)
Base.size(x::MultiPolygonMeta) = size(metafree(x))

@meta_type(Mesh, mesh, AbstractMesh, Element <: Polytope)
Base.getindex(x::MeshMeta, idx::Int) = getindex(metafree(x), idx)
Base.size(x::MeshMeta) = size(metafree(x))
1 change: 0 additions & 1 deletion src/viewtypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ struct TupleView{T, N, Skip, A} <: AbstractVector{T}
data::A
connect::Bool
end
Base.show(io::IO, ::Type{<: TupleView{T, N, Skip}}) where {T, N, Skip} = print(io, "TupleView{$T, $Skip}")

function Base.size(x::TupleView{T, N, M}) where {T, N, M}
nitems = length(x.data) ÷ (N - (N - M))
Expand Down
55 changes: 35 additions & 20 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,38 +56,31 @@ using GeometryBasics: attributes
end

end

@testset "polygon with metadata" begin
polys = [Polygon(rand(Point{2, Float32}, 20)) for i in 1:10]
pnames = [randstring(4) for i in 1:10]
numbers = LinRange(0.0, 1.0, 10)
bin = rand(Bool, 10)
# create just an array
plain = meta(polys, name = pnames, value = numbers, category = bin)
# create a polygon
poly = PolygonMeta(polys[1], name = pnames[1], value = numbers[1], category = bin[1])
# create a MultiPolygon with the right type & meta information!
multipoly = MultiPolygon(polys; name = pnames, value = numbers, category = bin)
for x in (plain, multipoly)
for (mp, p, n, num, b) in zip(x, polys, pnames, numbers, bin)
@test mp.polygon == p
@test mp.name == n
@test mp.value == num
@test mp.category == b
end

filtered = filter(i -> i.value < 0.7, x)
@test length(filtered) == 7
end
@test GeometryBasics.getcolumn(plain, :name) == pnames
@test GeometryBasics.MetaType(Polygon) == PolygonMeta
@test_throws ErrorException GeometryBasics.meta(plain)
multipoly = MultiPolygonMeta(polys, name = pnames, value = numbers, category = bin)
@test multipoly isa AbstractVector
@test poly isa GeometryBasics.AbstractPolygon

@test GeometryBasics.getcolumn(poly, :name) == pnames[1]
@test GeometryBasics.MetaFree(PolygonMeta) == Polygon

@test GeometryBasics.getcolumn(multipoly, :name) == pnames
@test GeometryBasics.MetaFree(MultiPolygonMeta) == MultiPolygon

meta_p = meta(polys[1], boundingbox=Rect(0, 0, 2, 2))
@test meta_p.boundingbox === Rect(0, 0, 2, 2)
@test metafree(meta_p) === polys[1]
attributes(meta_p) == Dict{Symbol, Any}(:boundingbox => meta_p.boundingbox,
:polygon => polys[1])
end

@testset "point with metadata" begin
p = Point(1.1, 2.2)
@test p isa AbstractVector{Float64}
Expand All @@ -99,8 +92,26 @@ using GeometryBasics: attributes
@test metafree(pm) === p
@test propertynames(pm) == (:position, :a, :b)
end

@testset "MultiPoint with metadata" begin
p = collect(Point{2, Float64}(x, x+1) for x in 1:5)
@test p isa AbstractVector
mpm = MultiPointMeta(p, a=1, b=2)
@test coordinates(mpm) == mpm
@test meta(mpm) === (a=1, b=2)
@test metafree(mpm) == p
@test propertynames(mpm) == (:points, :a, :b)
end

@testset "MultiLineString with metadata" begin
@testset "LineString with metadata" begin
linestring = LineStringMeta(Point{2, Int}[(10, 10), (20, 20), (10, 40)], a = 1, b = 2)
@test linestring isa AbstractVector
@test meta(linestring) === (a = 1, b = 2)
@test metafree(linestring) == linestring
@test propertynames(linestring) == (:lines, :a, :b)
end

@testset "MultiLineString with metadata" begin
linestring1 = LineString(Point{2, Int}[(10, 10), (20, 20), (10, 40)])
linestring2 = LineString(Point{2, Int}[(40, 40), (30, 30), (40, 20), (30, 10)])
multilinestring = MultiLineString([linestring1, linestring2])
Expand Down Expand Up @@ -362,7 +373,11 @@ end
@test coordinates(m) === points
end


@testset "convert mesh + meta" begin
m = uv_normal_mesh(Circle(Point2f0(0), 1f0))
# for 2D primitives we dont actually calculate normals
@test !hasproperty(m, :normals)
end

@testset "convert mesh + meta" begin
m = uv_normal_mesh(FRect3D(Vec3f0(-1), Vec3f0(1, 2, 3)))
Expand Down