Interoperability

Shared vertex tables

Shared vertex tables provide a simple, index based representation for meshes with static connectivity. For instance, the MeshProcessing package is based on a shared vertex representation and implements a variety of algorithms.

Use triangletable and createmesh to convert triangle mesh connectivity to and from a shared vertex representation.

Note

The provided methods "export" or "import" only connectivity (e.g., the triangulation). The user is responsible for copying data associated with attributes.

The additional method facetable is not restricted to triangle meshes but works for polygonal meshes with a prescribed maximum face degree.

Tip

You may want to ensure iscontiguous, e.g., by compact!, before "exporting". Alternatively use compacttriangletable or compactfacetable, which are less general but don't modify or create a Mesh.

Examples

"Export" connectivity and data

t = triangletable(mesh)
x = vec(vattr(mesh, :x))

# use x, t (e.g., with MeshProcessing)

vec(vattr(mesh, :x)) .= x

"Import" connectivity and data

# given positons x and triangulation t

template = createmesh((:x => SVector{3, Float64}), (), (), ())

mesh = createmesh(t, template)
vec(vattr(mesh, :x)) .= x
PMesh.createmeshMethod
mesh = createmesh(faces, template::Mesh, nv::Int = 0)
mesh = createmesh(faces::Matrix, template::Mesh, nv::Int = 0)

Create mesh from index table faces and template that defines attributes. The optional nv specifies the minimum number of vertices that may be larger than the maximum index in triangles.

faces enumerates each face as a sequence of vertex handles or indices. Before passing VHnd to addface!, any invalid indices are removed.

If faces is a Matrix, indices for each face are defined my matrix columns.

Note

Typically, faces is a Vector of triangles, e.g., NTuple{3, Int} or SVector{3, Int}.

You can use NTuple{4, Int} or SVector{4, Int} and "switch" between triangles and quads by providing an invalid index (e.g., zero or NoV) as fourth vertex.

See also triangletable, addface!

source
PMesh.facetableFunction
fs = facetable(::Val(n), mesh[, faces])

Generalized triangletable that converts mesh with maximum face degree n info Vector{SVector{n, Int}}. Faces with degree <n have n - degree trailing zero indices.

Note

Faces with degree >n are ignored with a warning message.

Note

This function is significantly less efficient than triangletable

See also triangletable

source
PMesh.triangletableFunction
triples = triangletable(mesh[, faces])

Generate table of triangles for mesh: triples is a Vector{SVector{3, Int}}, where each element triples[i] contains the vertex indices of the i-th triangle.

The optional argument faces restricts and/or permutes the sequence of faces.

Precondition

This method requires a triangle mesh!

See also facetable, compacttriangletable

source

FileIO and GeometryBasics

A [Mesh] can be converted to a GeometryBasics::Mesh for either rendering (e.g., with Makie.jl) or reading from and writing to files. See FileIO.jl, MeshIO.jl and GeomeytryBasics.jl.

Note

The current version supports only triangle meshes!

Note

The current version supports only a limited number of mesh elements/attributes.

Possible loss of precision

GeomeytryBasics.Mesh is used as an intermediate representation, which uses Float32 unless explicitly specified otherwise.

Currently, only pointstype can be specified (seemingly with lack of support of double precision Point3 by MeshIO).

Examples

template = createmesh((:x => SVector{3, Float64}), (), (), ())

# read mesh from file
mesh = createmesh(FileIO.load("/path/to/file.off"), template, position=:x)
mesh, mobj = read(:MeshIO, "/path/to/file.off", template;
                  pointstype=Point3)

# write mesh to file
FileIO.save("/path/to/file.obj", meshobj(mesh))

# mobj is the GeomeytryBasics representation that can be used for rendering

using Makie
# ... define scene ...
mesh!(scene, mobj)

# conversion from Mesh to GeomeytryBasics::Mesh
mobj = meshobj(mesh)

# conversion from GeomeytryBasics::Mesh to Mesh
createmesh(mobj, template, position=:x)

See also Input/output

Base.readMethod
mesh, mobj = read(:MeshIO, filename, template::Mesh
                  [; position=:x, exceptions=false,
                     pointstype=Point3])

Load mesh from file, e.g., in OFF format using FileIO and GeometryBasics

mobj is the mesh as defined by GeometryBasics and can be used for rendering. GeometryBasics.coordinates(mobj) and GeometryBasics.faces(mobj) provide Vectors of vertex positions and triangle indices, respectively.

Precondition

This method requires a triangle mesh!

Warning

MeshIO.load takes keyword arguments uvtype and normaltype only for file formats, which support these. For other formats, it just fails. We stick to the default settings (Float32) and pass only the vertex position type.

Note

For some file formats (e.g., OBJ), FileIO.load returns a MetaMesh. We drop the meta data, which may include material properties etc.

source
PMesh.createmeshMethod
mesh = createmesh(mobj::GeometryBasics.Mesh, template::Mesh;
                  [position = :x])

Convert GeometryBasics.Mesh to Mesh.

source
PMesh.meshobjFunction
mobj = meshobj(mesh[; position=:x, uv=nothing, normals=nothing,
                      pointstype = Point3, uvtype=Vec2,
                      normaltype=Vec3])

Convert mesh to mesh as defined by GeometryBasics, which can be used for rendering, e.g., with Makie (see Makie.mesh). Texture coordinates uv are passed as matrix columns or as a function that maps vertex positions. Normals are passed as a matrix. They are estimated if either :auto or an empty matrix is passed.

The argument normals is used as follows:

  • nothing: don't include normals as attributes
  • :auto: have GeometryBasics compute normals
  • use provided attribute as normals.

The dimension ni of the input position attribute may differ from the dimension no of the output pointstype:

  • ni == no copy (possibly convert types)
  • ni < no copy and fill remaining components of output with zeros
  • ni > ni copy only fist no dimensions of input
Note

meshobj calls triangletable and not compacttriangletable, i.e., the returned object may represent a mesh including unused vertices.

source