State & basic navigation

State

Generate element handles

The vertices, faces, halfedges, and edges methods generate sequences of used mesh elements (or of a local neighborhood).

Example

# iterate over all vertices in mesh
for v in vertices(mesh)
    @assert isused(mesh, v)
    @show v
end

@assert count(vertices(mesh)) == nv(mesh)
@assert count(faces(mesh)) == nf(mesh)
@assert count(edges(mesh)) == ne(mesh)

# iterate over vertices spanning face f
for v in vertices(mesh, f)
    @show v
end

Properties

Query isused status of elements.

Query number of elements (nv, nf, nh, ne), degree of vertices.

Query storage layout (iscontiguous). Provide hints sizehint!, free unused storage (shrink!).

Query global and local properties of the surface mesh, e.g.,

Manifold surface

Warning

The semantics of PMesh partially differ from other libraries (e.g., PMP) w.r.t. isolated vertices:

Isolated vertices are neither boundary – they are not part of a boundary loop – nor manifold – there is no 1d or 2d neigborhood, nor inner vertices. This affects the methods isboundary, ismanifold and isinner.

The optional keyword argument allowisolated changes the semantics.

isboundary => !isisolated [unless allowisolated]
isisolated => !ismanifold [unless allowisolated]
isinner => !isboundary and !isisolated (&& ismanifold) [unless allowisolated]
!isboundary && !isisolated => ismanifold
Base.isemptyMethod
isempty(mesh)

Is mesh empty, i.e., it does not contain any vertices or edges.

source
Base.sizehint!Function
sizehint!(mesh, nv[, nf=2nv])

Provide a hint on the total number of vertices nv and facesnf` for preallocation of storage.

Tip

Estimate and consider expected dynamic manipulation, i.e., adding elements.

source
PMesh.boundaryhalfedgeMethod
h = boundaryhalfedge(mesh, e)

If e is a boundary edge, return the boundary half-edge h, i.e., isboundary(mesh, h) == true. Return NoH if e is not boundary.

See also isboundary

source
PMesh.degreeFunction
n = degree(mesh, f::FHnd)
n = degree(mesh, v::VHnd)

Get face degree, i.e., number of vertices spanning f, or vertex degree, i.e., number of edges incident to v.

Note

The vertex degree is alternatively called valence (e.g., in the PMP library).

source
PMesh.detailsMethod
@show details(mesh)
@show mesh          # prints only nv, nf

Print detailed overview of mesh with its attributes.

source
PMesh.edgeMethod
e = edge([mesh,] h::HHnd)

Get edge handle from half-edge handle.

source
PMesh.edgesMethod
for e in edges(mesh)
    ...
end

Generate sequence of all edges.

source
PMesh.ehndsMethod
[e for e in ehnds(mesh)]

Generate sequence of all –including unused – edge handles.

source
PMesh.faceMethod
vs = face(mesh, f)

Collect vertices spanning face f.

Note

This method returns the collected Vector{VHnd} from the generator vertices(mesh, f).

See also vertices.

source
PMesh.facesMethod
for f in faces(mesh)
     ...
end

Generate sequence of all used faces.

source
PMesh.fhndsMethod
[f for f in fhnds(mesh)]

Generate sequence of all –including unused – face handles.

source
PMesh.halfedgeFunction
h = halfedge([mesh,] e::EHnd, i)

Get first (i==1) or second (i==2) half-edge of edge e.

source
PMesh.halfedgeMethod
h = halfedge(mesh, f::FHnd)

Get some half-edge in the sequence of half-edges that span the face f.

Note

This method always returns a valid half-edge (and never NoH).

source
PMesh.halfedgeMethod
h = halfedge(mesh, v::VHnd)

Get some outgoing half-edge of vertex v.

Returns h == NoH if there is such half-edge. In this case v is an isolated vertex.

If v is a boundary vertex, h is guaranteed to be a boundary half-egde, i.e., its opposite half-edge equals NoH.

Note

If v is a boundary vertex, there may exist multiple outgoing boundary half-edges. If so, v is not a manifold vertex.

See also isisolated, isboundary, ismanifold

source
PMesh.halfedgesFunction
h0, h1 = halfedges([mesh,] e::EHnd)

Get ordered pair of half-edges h0, h1 such that Int(h0) + 1 == Int(h1).

h0, h1 = halfedges([mesh,] h::HHnd)

Get ordered pair of half-edges h0, h1 such that additionally h0 == h || h1 == h and

Precondition

Requires h != NoE!

source
PMesh.halfedgesMethod
for (h1, h2) in halfedges(mesh)
      ...
end

Generate sequence all pairs of used half-edges.

source
PMesh.hhndsMethod
[h for h in hhnds(mesh)]

Generate sequence of all –including unused – half-edge handles.

source
PMesh.isboundaryFunction
isboundary(mesh, v::VHnd)
isboundary(mesh, f::FHnd)
isboundary(mesh, h::HHnd)
isboundary(mesh, e::EHnd)

Is element a boundary element? (A face is a boundary face if any of its edges is boundary.)

source
PMesh.isclosedMethod
isclosed(mesh; [allowisolated=false])

Is mesh a closed surface without boundary loops or isolated vertices? Optionally ignore isolated vertices.

See also isboundary, isisolated

source
PMesh.isinnerMethod
    isinner(mesh, v::VHnd[; allowisolated=false)

Is v an interior vertex, i.e., neither an isolated vertex nor a boundary vertex. Optionally return true also for isolated vertices.

Note

isinner implies ismanifold because non-manifold vertices require a boundary.

See also isboundary, isisolated, ismanifold

source
PMesh.isisolatedMethod
isisolated(mesh, v)

Is vertex v an isolated vertex, i.e., degree(mesh, v) == 0 or equivalently halfedge(mesh, v) == NoH.

See also degree

source
PMesh.ismanifoldFunction
ismanifold(mesh, v::VHnd)
ismanifold(mesh[; allowisolated=false)

Is mesh locally manifold near vertex v or globally a manifold surface mesh? Optionally ignore isolated vertices.

Note

An isolated vertex is non-manifold. Meshes that contain isolated vertices are non-manifold. – The option allowisolated==true ignores any manifold vertices.

Warning

These semantics differ from PMP!

See also hasisolatedvertices

source
PMesh.nhMethod
n = nh(mesh)

Get number of half-edges in mesh.

source
PMesh.verticesMethod
for v in vertices(mesh)
     ...
end

Generate sequence of all used vertices.

source
PMesh.vhndsMethod
[v for v in vhnds(mesh)]

Generate sequence of all – including unused – vertex handles.

source
PMeshAttributes.iscontiguousFunction
iscontiguous(mesh, VHnd)
iscontiguous(mesh, FHnd)
iscontiguous(mesh, EHnd)
iscontiguous(mesh)

Are elements stored contiguously (i.e., number if used elements equals their total number)? The handle type restricts query to vertices, faces, edges or all elements. (Half-edges are stored contiguously iff edges are stored contiguously.)

See also Compact Storage

source
PMeshAttributes.isusedFunction
isused(mesh, v::VHnd)
isused(mesh, f::FHnd)
isused(mesh, h::HHnd)
isused(mesh, e::EHnd)

Determine if mesh element is used.

source

The basic navigation is provided by the half-edge data structure.

PMesh.edgeFunction
e = edge(mesh, (v0, v1))
e = edge(mesh, v0, v1)

Find edge spanned by vertices v0 and v1 or return NoE if there is no such edge.

See also halfedge

source
PMesh.faceMethod
f = face(mesh, h::HHnd)

Get face spanned by half-edge h or NoH if h is boundary.

source
PMesh.halfedgeFunction
h = halfedge(mesh, (v0, v1))
h = halfedge(mesh, v0, v1)

Find half-edge from vertex v0 to vertex v1 or return NoH if there is no such half-edge.

See also edge

source
PMesh.nextFunction
nh = next(mesh, h::HHnd[,:ccw])   # next
ph = next(mesh, h::Hnd, :cw)      # previous

Get next half-edge within face in counter-clockwise (:ccw) order. The next edge in clockwise order (cw) equals is the previous edge.

See also prev

source
PMesh.nextinstarFunction
nh = nextinstar(mesh[, :cw], h)
np = nextinstar(mesh, :ccw, h)   # previnstar

Get next edge in star turning clockwise (:cw) around source(h). The next edge when turning in counter-clockwise orientation (:ccw) is equal to the previous edge previnstar.

See also cw, previnstar

source
PMesh.oppositeFunction
ho = opposite(mesh, h::HHnd)

Get half-edge "opposite" to h, i.e., with inverse orientation.

source
PMesh.prevMethod
ph = prev(mesh, h::HHnd)

Get previous half-edge within face (in counter-clockwise order).

See also next

source