@@ -490,9 +490,53 @@ returned by coordinates(mesh).
490490abstract type AbstractMesh{Dim, T} <: AbstractGeometry{Dim, T} end
491491
492492"""
493- Mesh{D, T , FaceType, FaceArrayType } <: AbstractMesh{D, T } <: AbstractGeometry{D, T }
493+ Mesh{PositionDim, PositionType , FaceType, VertexAttributeNames, VertexAttributeTypes, FaceVectorType } <: AbstractMesh{PositionDim, PositionType } <: AbstractGeometry{PositionDim, PositionType }
494494
495- The type of a concrete mesh. It can hold arbitrary vertex data (including FaceView's).
495+ The type of a concrete mesh. The associated struct contains 3 fields:
496+
497+ ```julia
498+ struct Mesh{...}
499+ vertex_attributes::NamedTuple{VertexAttributeNames, VertexAttributeTypes}
500+ faces::FaceVectorType
501+ views::Vector{UnitRange{Int}}
502+ end
503+ ```
504+
505+ A vertex typically carries multiple distinct pieces of data, e.g. a position,
506+ a normal, a texture coordinate, etc. We call those pieces of data vertex
507+ attributes. The `vertex_attributes` field contains the name and a collection
508+ `<: AbstractVector` or `<: FaceView` for each attribute. The n-th element of that
509+ collection is the value of the corresponding attribute for the n-th vertex.
510+
511+ ```julia
512+ # vertex 1 2 3
513+ vertex_attributes[:position] = [pos1, pos2, pos3, ...]
514+ vertex_attributes[:normal] = [normal1, normal2, normal3, ...]
515+ ...
516+ ```
517+
518+ A `NamedTuple` is used here to allow different meshes to carry different vertex
519+ attributes while also keeping things type stable. The constructor enforces a
520+ few restrictions:
521+ - The first attribute must be named `position` and must have a `Point{PositionDim, PositionType}` eltype.
522+ - Each vertex attribute must refer to the same number of vertices. (All vertex attributes defined by
523+ AbstractVector must match in length. For FaceViews, the number of faces needs to match.)
524+
525+ See also: [`vertex_attributes`](@ref), [`coordinates`](@ref), [`normals`](@ref),
526+ [`texturecoordinates`](@ref), [`decompose`](@ref), [`clear_faceviews`](@ref)
527+
528+ The `faces` field is a collection `<: AbstractVector{FaceType}` containing faces
529+ that describe how vertices are connected. Typically these are `(GL)TriangleFace`s
530+ or `QuadFace`s, but they can be any collection of vertex indices `<: AbstractFace`.
531+
532+ See also: [`faces`](@ref), [`decompose`](@ref)
533+
534+ The `views` field can be used to separate the mesh into mutliple submeshes. Each
535+ submesh is described by a "view" into the `faces` vector, i.e. submesh n uses
536+ `mesh.faces[mesh.views[n]]`. A `Mesh` can be constructed without `views`, which
537+ results in an empty `views` vector.
538+
539+ See also: [`merge`](@ref), [`split_mesh`](@ref)
496540"""
497541struct Mesh{
498542 Dim, T <: Real , # TODO : Number?
@@ -529,7 +573,9 @@ struct Mesh{
529573 va = NamedTuple {names} (values (va))
530574 end
531575
532- # verify that faces of FaceViews match `fs` (in length per face)
576+ # verify that all vertex attributes refer to the same number of vertices
577+ # for Vectors this means same length
578+ # for FaceViews this means same number of faces
533579 N = maximum (f -> value (maximum (f)), fs, init = 0 )
534580 for (name, attrib) in pairs (va)
535581 if attrib isa FaceView
0 commit comments