Skip to content

Commit 2d9f476

Browse files
committed
gMerge branch 'sd/meshes'
2 parents 5481267 + 3bf780f commit 2d9f476

File tree

10 files changed

+278
-194
lines changed

10 files changed

+278
-194
lines changed

src/GeometryBasics.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module GeometryBasics
77
include("fixed_arrays.jl")
88
include("offsetintegers.jl")
99
include("basic_types.jl")
10+
include("interfaces.jl")
1011
include("metadata.jl")
1112
include("viewtypes.jl")
1213
include("geometry_primitives.jl")
@@ -29,6 +30,7 @@ module GeometryBasics
2930
export FaceView, SimpleFaceView
3031
export AbstractPoint, PointMeta, PointWithUV
3132
export decompose, coordinates, faces, normals, decompose_uv, decompose_normals
33+
export Tesselation
3234
export GLTriangleFace, GLNormalMesh3D, GLPlainTriangleMesh, GLUVMesh3D, GLUVNormalMesh3D
3335
export AbstractMesh, Mesh, TriangleMesh
3436
export GLNormalMesh2D, PlainTriangleMesh

src/basic_types.jl

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,6 @@ abstract type AbstractNgonFace{N, T} <: AbstractFace{N, T} end
2020

2121
abstract type AbstractSimplex{Dim, N, T} <: StaticVector{Dim, T} end
2222

23-
"""
24-
coordinates(geometry)
25-
Returns the edges/vertices/coordinates of a geometry. Is allowed to return lazy iterators!
26-
Use `decompose(ConcretePointType, geometry)` to get `Vector{ConcretePointType}` with
27-
`ConcretePointType` to be something like `Point{3, Float32}`.
28-
"""
29-
function coordinates(points::AbstractVector{<:AbstractPoint})
30-
return points
31-
end
32-
33-
"""
34-
faces(geometry)
35-
Returns the face connections of a geometry. Is allowed to return lazy iterators!
36-
Use `decompose(ConcreteFaceType, geometry)` to get `Vector{ConcreteFaceType}` with
37-
`ConcreteFaceType` to be something like `TriangleFace{Int}`.
38-
"""
39-
function faces(f::AbstractVector{<:AbstractFace})
40-
return f
41-
end
42-
4323
"""
4424
Face index, connecting points to form a simplex
4525
"""
@@ -57,7 +37,9 @@ const LineFace{T} = NgonFace{2, T}
5737
const TriangleFace{T} = NgonFace{3, T}
5838
const QuadFace{T} = NgonFace{4, T}
5939

60-
Base.show(io::IO, x::TriangleFace{T}) where T = print(io, "TriangleFace(", join(x, ", "), ")")
40+
function Base.show(io::IO, x::TriangleFace{T}) where T
41+
print(io, "TriangleFace(", join(x, ", "), ")")
42+
end
6143

6244
Face(::Type{<: NgonFace{N}}, ::Type{T}) where {N, T} = NgonFace{N, T}
6345
Face(F::Type{NgonFace{N, FT}}, ::Type{T}) where {FT, N, T} = F
@@ -100,14 +82,14 @@ Base.length(::NNgon{N}) where N = N
10082
The Ngon Polytope element type when indexing an array of points with a SimplexFace
10183
"""
10284
function Polytope(P::Type{<: AbstractPoint{Dim, T}}, ::Type{<: AbstractNgonFace{N, IT}}) where {N, Dim, T, IT}
103-
Ngon{Dim, T, N, P}
85+
return Ngon{Dim, T, N, P}
10486
end
10587

10688
"""
10789
The fully concrete Ngon type, when constructed from a point type!
10890
"""
10991
function Polytope(::Type{<: NNgon{N}}, P::Type{<: AbstractPoint{NDim, T}}) where {N, NDim, T}
110-
Ngon{NDim, T, N, P}
92+
return Ngon{NDim, T, N, P}
11193
end
11294

11395

@@ -157,11 +139,10 @@ const Tetrahedron{T} = TetrahedronP{T, Point{3, T}}
157139

158140
Base.show(io::IO, x::TetrahedronP) = print(io, "Tetrahedron(", join(x, ", "), ")")
159141

160-
161142
coordinates(x::Simplex) = x.points
162143

163144
function (::Type{<: NSimplex{N}})(points::Vararg{P, N}) where {P <: AbstractPoint{Dim, T}, N} where {Dim, T}
164-
Simplex{Dim, T, N, P}(SVector(points))
145+
return Simplex{Dim, T, N, P}(SVector(points))
165146
end
166147

167148
# Base Array interface
@@ -172,14 +153,14 @@ Base.length(::NSimplex{N}) where N = N
172153
The Simplex Polytope element type when indexing an array of points with a SimplexFace
173154
"""
174155
function Polytope(P::Type{<: AbstractPoint{Dim, T}}, ::Type{<: AbstractSimplexFace{N}}) where {N, Dim, T}
175-
Simplex{Dim, T, N, P}
156+
return Simplex{Dim, T, N, P}
176157
end
177158

178159
"""
179160
The fully concrete Simplex type, when constructed from a point type!
180161
"""
181162
function Polytope(::Type{<: NSimplex{N}}, P::Type{<: AbstractPoint{NDim, T}}) where {N, NDim, T}
182-
Simplex{NDim, T, N, P}
163+
return Simplex{NDim, T, N, P}
183164
end
184165
Base.show(io::IO, x::LineP) = print(io, "Line(", x[1], " => ", x[2], ")")
185166

@@ -193,13 +174,14 @@ struct LineString{
193174
} <: AbstractVector{LineP{Dim, T, P}}
194175
points::V
195176
end
177+
196178
coordinates(x::LineString) = x.points
197179

198180
Base.size(x::LineString) = size(coordinates(x))
199181
Base.getindex(x::LineString, i) = getindex(coordinates(x), i)
200182

201183
function LineString(points::AbstractVector{LineP{Dim, T, P}}) where {Dim, T, P}
202-
LineString{Dim, T, P, typeof(points)}(points)
184+
return LineString{Dim, T, P, typeof(points)}(points)
203185
end
204186

205187
"""
@@ -214,15 +196,15 @@ linestring = LineString(points)
214196
```
215197
"""
216198
function LineString(points::AbstractVector{<: AbstractPoint}, skip = 1)
217-
LineString(connect(points, LineP, skip))
199+
return LineString(connect(points, LineP, skip))
218200
end
219201

220202
function LineString(points::AbstractVector{<: Pair{P, P}}) where P <: AbstractPoint{N, T} where {N, T}
221-
LineString(reinterpret(LineP{N, T, P}, points))
203+
return LineString(reinterpret(LineP{N, T, P}, points))
222204
end
223205

224206
function LineString(points::AbstractVector{<: AbstractPoint}, faces::AbstractVector{<: LineFace})
225-
LineString(connect(points, faces))
207+
return LineString(connect(points, faces))
226208
end
227209

228210
"""
@@ -246,7 +228,7 @@ linestring = LineString(points, faces, 2)
246228
"""
247229
function LineString(points::AbstractVector{<: AbstractPoint}, indices::AbstractVector{<: Integer}, skip = 1)
248230
faces = connect(indices, LineFace, skip)
249-
LineString(points, faces)
231+
return LineString(points, faces)
250232
end
251233

252234
struct Polygon{
@@ -262,21 +244,21 @@ end
262244
Base.:(==)(a::Polygon, b::Polygon) = (a.exterior == b.exterior) && (a.interiors == b.interiors)
263245

264246
function Polygon(exterior::E, interiors::AbstractVector{E}) where E <: AbstractVector{LineP{Dim, T, P}} where {Dim, T, P}
265-
Polygon{Dim, T, P, typeof(exterior), typeof(interiors)}(exterior, interiors)
247+
return Polygon{Dim, T, P, typeof(exterior), typeof(interiors)}(exterior, interiors)
266248
end
267249

268250
Polygon(exterior::L) where L <: AbstractVector{<: LineP} = Polygon(exterior, L[])
269251

270252
function Polygon(exterior::AbstractVector{P}, skip::Int = 1) where P <: AbstractPoint{Dim, T} where {Dim, T}
271-
Polygon(LineString(exterior, skip))
253+
return Polygon(LineString(exterior, skip))
272254
end
273255

274256
function Polygon(exterior::AbstractVector{P}, faces::AbstractVector{<: Integer}, skip::Int = 1) where P <: AbstractPoint{Dim, T} where {Dim, T}
275-
Polygon(LineString(exterior, faces, skip))
257+
return Polygon(LineString(exterior, faces, skip))
276258
end
277259

278260
function Polygon(exterior::AbstractVector{P}, faces::AbstractVector{<: LineFace}) where P <: AbstractPoint{Dim, T} where {Dim, T}
279-
Polygon(LineString(exterior, faces))
261+
return Polygon(LineString(exterior, faces))
280262
end
281263

282264

@@ -290,7 +272,7 @@ struct MultiPolygon{
290272
end
291273

292274
function MultiPolygon(polygons::AbstractVector{P}; kw...) where P <: AbstractPolygon{Dim, T} where {Dim, T}
293-
MultiPolygon(meta(polygons; kw...))
275+
return MultiPolygon(meta(polygons; kw...))
294276
end
295277

296278
Base.getindex(mp::MultiPolygon, i) = mp.polygons[i]
@@ -306,7 +288,7 @@ struct MultiLineString{
306288
end
307289

308290
function MultiLineString(linestrings::AbstractVector{L}; kw...) where L <: AbstractVector{LineP{Dim, T, P}} where {Dim, T, P}
309-
MultiLineString(meta(linestrings; kw...))
291+
return MultiLineString(meta(linestrings; kw...))
310292
end
311293

312294
Base.getindex(ms::MultiLineString, i) = ms.linestrings[i]
@@ -342,7 +324,7 @@ const AbstractMesh{Element} = AbstractVector{Element}
342324
The conrecte AbstractMesh implementation
343325
"""
344326
struct Mesh{
345-
Dim, T <: Real,
327+
Dim, T <: Number,
346328
Element <: Polytope{Dim, T},
347329
V <: AbstractVector{Element}
348330
} <: AbstractMesh{Element}

src/geometry_primitives.jl

Lines changed: 3 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
##
22
# Generic base overloads
3-
43
Base.extrema(primitive::GeometryPrimitive) = (minimum(primitive), maximum(primitive))
54
function widths(x::AbstractRange)
65
mini, maxi = Float32.(extrema(x))
@@ -54,6 +53,9 @@ function convert_simplex(::Type{Vec{N, T}}, x) where {N, T}
5453
return (Vec{N, T}(ntuple(i-> i <= N2 ? T(x[i]) : T(0), N)),)
5554
end
5655

56+
collect_with_eltype(::Type{T}, vec::Vector{T}) where T = vec
57+
collect_with_eltype(::Type{T}, vec::AbstractVector{T}) where T = collect(vec)
58+
5759
function collect_with_eltype(::Type{T}, iter) where T
5860
# TODO we could be super smart about allocating the right length
5961
# but its kinda annoying, since e.g. T == Triangle and first(iter) isa Quad
@@ -70,71 +72,6 @@ function collect_with_eltype(::Type{T}, iter) where T
7072
end
7173

7274

73-
function faces(primitive, nvertices=30)
74-
# doesn't have any specific algorithm to generate faces
75-
# so will try to triangulate the coordinates!
76-
return nothing
77-
end
78-
79-
function decompose(::Type{F}, primitive, args...) where {F<:AbstractFace}
80-
f = faces(primitive, args...)
81-
f === nothing && return nothing
82-
return collect_with_eltype(F, f)
83-
end
84-
85-
function decompose(::Type{T}, primitive::AbstractVector{T}) where {T}
86-
return primitive
87-
end
88-
89-
function decompose(::Type{T}, primitive::AbstractVector{T}) where {T<:AbstractFace}
90-
return primitive
91-
end
92-
93-
function decompose(::Type{T}, primitive::AbstractVector{T}) where {T<:AbstractPoint}
94-
return primitive
95-
end
96-
97-
function decompose(::Type{P}, primitive, args...) where {P<:AbstractPoint}
98-
return collect_with_eltype(P, coordinates(primitive, args...))
99-
end
100-
101-
function decompose(::Type{Point}, primitive::Union{GeometryPrimitive{Dim}, Mesh{Dim}}, args...) where {Dim}
102-
return collect_with_eltype(Point{Dim, Float32}, coordinates(primitive, args...))
103-
end
104-
105-
# Dispatch type to make `decompose(UV{Vec2f0}, priomitive)` work
106-
struct UV{T} end
107-
UV(::Type{T}) where T = UV{T}()
108-
struct UVW{T} end
109-
UVW(::Type{T}) where T = UVW{T}()
110-
struct Normal{T} end
111-
Normal(::Type{T}) where T = Normal{T}()
112-
113-
function decompose(::UV{T}, primitive::GeometryPrimitive, args...) where T
114-
return collect_with_eltype(T, texturecoordinates(primitive, args...))
115-
end
116-
117-
decompose_uv(args...) = decompose(UV(Vec2f0), args...)
118-
119-
function decompose(::UVW{T}, primitive::GeometryPrimitive, args...) where T
120-
return collect_with_eltype(T, texturecoordinates(primitive, args...))
121-
end
122-
123-
function normals(primitive, nvertices=30)
124-
# doesn't have any specific algorithm to generate normals
125-
# so will be generated from faces + positions
126-
return nothing
127-
end
128-
129-
130-
function decompose(::Normal{T}, primitive::GeometryPrimitive, args...) where T
131-
n = normals(primitive, args...)
132-
n === nothing && return nothing
133-
return collect_with_eltype(T, n)
134-
end
135-
136-
decompose_normals(args...) = decompose(Normal(Vec3f0), args...)
137-
13875
"""
13976
The unnormalized normal of three vertices.
14077
"""
@@ -169,14 +106,6 @@ function normals(vertices::AbstractVector{<: AbstractPoint{3, T}},
169106
return normals_result
170107
end
171108

172-
function normals(mesh::AbstractMesh)
173-
if hasproperty(mesh, :normals)
174-
return mesh.normals
175-
else
176-
return normals(coordinates(mesh), faces(mesh))
177-
end
178-
end
179-
180109
##
181110
# Some more primitive types
182111

@@ -273,8 +202,6 @@ function rotation(c::Cylinder{3, T}) where T
273202
return hcat(v, w, u)
274203
end
275204

276-
best_nvertices(x::Cylinder{2}) = (2, 2)
277-
278205
function coordinates(c::Cylinder{2, T}, nvertices=(2, 2)) where T
279206
r = Rect(c.origin[1] - c.r/2, c.origin[2], c.r, height(c))
280207
M = rotation(c)
@@ -287,8 +214,6 @@ function faces(sphere::Cylinder{2}, nvertices=(2, 2))
287214
return faces(Rect(0, 0, 1, 1), nvertices)
288215
end
289216

290-
best_nvertices(x::Cylinder{3}) = 30
291-
292217
function coordinates(c::Cylinder{3, T}, nvertices=30) where T
293218
if isodd(nvertices)
294219
nvertices = 2 * (nvertices ÷ 2)

0 commit comments

Comments
 (0)