Drake
Drake C++ Documentation
MeshFieldLinear< T, MeshType > Class Template Reference

Detailed Description

template<class T, class MeshType>
class drake::geometry::MeshFieldLinear< T, MeshType >

MeshFieldLinear represents a continuous piecewise-linear scalar field f defined on a (triangular or tetrahedral) mesh; the field value changes linearly within each element E (triangle or tetrahedron), and the gradient ∇f is constant within each element.

The field is continuous across adjacent elements, but its gradient is discontinuous from one element to the other.

To represent a piecewise linear field f, we store one field value per vertex of the mesh. Each element E (triangle or tetrahedron) has (d+1) vertices, where d is the dimension of the element. For triangle, d = 2, and for tetrahedron, d = 3.

On each element E, we define a linear function fᵉ:ℝ³→ℝ using the field values at vertices of E. The gradient ∇fᵉ:ℝ³→ℝ³ is a constant map, so we write ∇fᵉ for the constant gradient vector on E as well. For a point Q in element E, we have:

   f(Q) = fᵉ(Q) for Q ∈ E,
  ∇f(Q) = ∇fᵉ for Q ∈ E.

Notice that the domain of fᵉ is the entire space of ℝ³, while the domain of f is the underlying space of the mesh.

The following sections are details for interested readers.

Barycentric coordinate

For a linear triangle or tetrahedron element E in 3-D, we use barycentric coordinate:

  (b₀, b₁, b₂)     for triangle,
  (b₀, b₁, b₂, b₃) for tetrahedron,
  ∑bᵢ = 1, bᵢ ≥ 0,

to identify a point Q that lies in the simplicial element E. The coefficient bᵢ is the weight of vertex Vᵉᵢ of the element E, where the index i is a local index within the element E, not the global index of the entire mesh. In other words, vertex Vᵉᵢ is the iᵗʰ vertex of E, not the iᵗʰ vertex among all vertices in the mesh. The point Q in E can be expressed as:

  Q = ∑bᵉᵢ(Q)Vᵉᵢ,

where we indicate the barycentric coordinate of a point Q on an element E as bᵉᵢ(Q).

Field value from barycentric coordinates

At a point Q in element E, the piecewise linear field f has value:

  f(Q) = fᵉ(Q) = ∑bᵉᵢ(Q)Fᵉᵢ

where Fᵉᵢ is the field value at the iᵗʰ vertex of element E.

Frame dependency

A MeshFieldLinear is a frame-dependent quantity. Instances of a field should be named, as with any other frame-dependent quantity, with a trailing _F indicating the field's frame F. The field's frame is implicitly defined to be the same as the mesh's frame on which the field is instantiated. The field's frame affects two APIs:

  • The gradients reported by EvaluateGradient() are expressed in the field's frame.
  • The cartesian point passed to EvaluateCartesian() must be measured and expressed in the field's frame.

The field (along with its corresponding mesh) can be transformed into a new frame by invoking the TransformVertices() method on the mesh and Transform() on the field, passing the same math::RigidTransform to both.

Gradient

Consider each bᵉᵢ:ℝ³→ℝ as a linear function, its gradient ∇bᵉᵢ:ℝ³→ℝ³ is a constant map, and we write ∇bᵉᵢ for the constant gradient vector. The gradient of the piecewise linear field f at a point Q in an element E is:

  ∇f(Q) = ∇fᵉ = ∑Fᵉᵢ∇bᵉᵢ.

Field value from Cartesian coordinates

At a point Q in element E, the piecewise linear field f has value:

  f(Q) = ∇fᵉ⋅Q + fᵉ(0,0,0).

Notice that (0,0,0) may or may not lie in element E.

Template Parameters
Ta valid Eigen scalar for field values.
MeshTypethe type of the meshes: TriangleSurfaceMesh or VolumeMesh.

#include <drake/geometry/proximity/mesh_field_linear.h>

Public Member Functions

 MeshFieldLinear (std::vector< T > &&values, const MeshType *mesh, MeshGradientMode gradient_mode=MeshGradientMode::kOkOrThrow)
 Constructs a MeshFieldLinear. More...
 
 MeshFieldLinear (std::vector< T > &&values, const MeshType *mesh, std::vector< Vector3< T >> &&gradients)
 (Advanced) Constructor variant which receives the pre-computed, per-element gradients of the field. More...
 
bool is_gradient_field_degenerate () const
 
const T & EvaluateAtVertex (int v) const
 Evaluates the field value at a vertex. More...
 
template<typename B >
promoted_numerical_t< B, T > Evaluate (int e, const typename MeshType::template Barycentric< B > &b) const
 Evaluates the field value at a location on an element. More...
 
template<typename C >
promoted_numerical_t< C, T > EvaluateCartesian (int e, const Vector3< C > &p_MQ) const
 Evaluates the field at a point Qp on an element. More...
 
Vector3< T > EvaluateGradient (int e) const
 Evaluates the gradient in the domain of the element indicated by e. More...
 
void Transform (const math::RigidTransform< typename MeshType::ScalarType > &X_NM)
 (Advanced) Transforms this mesh field to be measured and expressed in frame N (from its original frame M). More...
 
std::unique_ptr< MeshFieldLinearCloneAndSetMesh (const MeshType *new_mesh) const
 Copy to a new MeshFieldLinear and set the new MeshFieldLinear to use a new compatible mesh. More...
 
const MeshType & mesh () const
 
const std::vector< T > & values () const
 
bool Equal (const MeshFieldLinear< T, MeshType > &field) const
 Checks to see whether the given MeshFieldLinear object is equal via deep exact comparison. More...
 
Implements MoveConstructible, MoveAssignable

To copy a MeshFieldLinear, use CloneAndSetMesh().

 MeshFieldLinear (MeshFieldLinear &&)=default
 
MeshFieldLinearoperator= (MeshFieldLinear &&)=default
 

Constructor & Destructor Documentation

◆ MeshFieldLinear() [1/3]

MeshFieldLinear ( MeshFieldLinear< T, MeshType > &&  )
default

◆ MeshFieldLinear() [2/3]

MeshFieldLinear ( std::vector< T > &&  values,
const MeshType *  mesh,
MeshGradientMode  gradient_mode = MeshGradientMode::kOkOrThrow 
)

Constructs a MeshFieldLinear.

Parameters
valuesThe field value at each vertex of the mesh.
meshThe mesh M to which this field refers.
gradient_modeWhether to calculate gradient field, and how to report failures. Calculating gradient allows EvaluateCartesian() to evaluate the field directly instead of converting Cartesian coordinates to barycentric coordinates first. If no gradient is calculated, EvaluateCartesian() will be slower. On the other hand, calculating gradient requires certain quality from mesh elements. If the mesh quality is very poor, calculating gradient may either throw or mark the gradient field as degenerate. See is_gradient_field_degenerate(). The default is to succeed or throw.

You can use the parameter gradient_mode to trade time and space of this constructor for speed of EvaluateCartesian(). For gradient_mode != kNone (kOkOrThrow by default, or kOkOrMarkDegenerate similarly) and good mesh quality, this constructor will take longer time to compute and will store one field-gradient vector for each element in the mesh, but the interpolation by EvaluateCartesian() will be faster because we will use a dot product with the Cartesian coordinates directly, instead of solving a linear system to convert Cartesian coordinates to barycentric coordinates first.

When gradient_mode != kNone and gradient calculation succeeds, EvaluateGradient() on a mesh element will be available. Otherwise, EvaluateGradient() will throw.

The following features are independent of the choice of gradient_mode.

  • Evaluating the field at a vertex.
  • Evaluating the field at a user-given barycentric coordinate.
Note
When gradient_mode != kNone, a poor quality element can cause numerical errors in calculating field gradients. A poor quality element is defined as having an extremely large aspect ratio R=E/h, where E is the longest edge length and h is the shortest height. A height of a triangular element is the distance between a vertex and its opposite edge. A height of a tetrahedral element is the distance between a vertex and its opposite triangular face. For example, an extremely skinny triangle has poor quality, and a tetrahedron with four vertices almost co-planar also has poor quality. The exact threshold of the acceptable aspect ratio depends on many factors including the underlying scalar type and the exact shape and size of the element; however, a rough conservative estimation is 1e12.
Precondition
The mesh is non-null, and the number of entries in values is the same as the number of vertices of the mesh.

◆ MeshFieldLinear() [3/3]

MeshFieldLinear ( std::vector< T > &&  values,
const MeshType *  mesh,
std::vector< Vector3< T >> &&  gradients 
)

(Advanced) Constructor variant which receives the pre-computed, per-element gradients of the field.

gradients[i] is the gradient of the linear function defined on the ith element of mesh.

The caller is responsible for making sure that the gradients are consistent with the field values defined at the vertices. Failure to do so will lead to nonsensical results when evaluating the field near a mesh vertex as opposed to at the vertex.

As with the other constructor, mesh must remain alive at least as long as this field instance.

Precondition
gradients.size() == mesh.num_elements().

Member Function Documentation

◆ CloneAndSetMesh()

std::unique_ptr<MeshFieldLinear> CloneAndSetMesh ( const MeshType *  new_mesh) const

Copy to a new MeshFieldLinear and set the new MeshFieldLinear to use a new compatible mesh.

MeshFieldLinear needs a mesh to operate; however, MeshFieldLinear does not own the mesh. In fact, several MeshFieldLinear objects can use the same mesh.

◆ Equal()

bool Equal ( const MeshFieldLinear< T, MeshType > &  field) const

Checks to see whether the given MeshFieldLinear object is equal via deep exact comparison.

The name of the objects are exempt from this comparison. NaNs are treated as not equal as per the IEEE standard.

Parameters
fieldThe field for comparison.
Returns
true if the given field is equal.

◆ Evaluate()

promoted_numerical_t<B, T> Evaluate ( int  e,
const typename MeshType::template Barycentric< B > &  b 
) const

Evaluates the field value at a location on an element.

The return type depends on both the field's scalar type T and the Barycentric coordinate type B. See promoted_numerical_t for details.

Warning
This can only be evaluated if the underlying MeshType itself supports barycentric evaluation (e.g., compare TriangleSurfaceMesh with PolygonSurfaceMesh).
Parameters
eThe index of the element.
bThe barycentric coordinates.
Exceptions
std::exceptionif MeshType doesn't support Barycentric coordinates.
Template Parameters
BThe scalar type for the barycentric coordinate.

◆ EvaluateAtVertex()

const T& EvaluateAtVertex ( int  v) const

Evaluates the field value at a vertex.

Parameters
vThe index of the vertex.
Precondition
v ∈ [0, this->mesh().num_vertices()).

◆ EvaluateCartesian()

promoted_numerical_t<C, T> EvaluateCartesian ( int  e,
const Vector3< C > &  p_MQ 
) const

Evaluates the field at a point Qp on an element.

If the element is a tetrahedron, Qp is the input point Q. If the element is a triangle, Qp is the projection of Q on the triangle's plane.

If gradients have been calculated, it evaluates the field value directly. Otherwise, it converts Cartesian coordinates to barycentric coordinates for barycentric interpolation.

The return type depends on both the field's scalar type T and the Cartesian coordinate type C. See promoted_numerical_t for details.

Parameters
eThe index of the element.
p_MQThe position of point Q expressed in frame M, in Cartesian coordinates. M is the frame of the mesh.
Exceptions
std::exceptionif the field does not have gradients defined and the MeshType doesn't support Barycentric coordinates.

◆ EvaluateGradient()

Vector3<T> EvaluateGradient ( int  e) const

Evaluates the gradient in the domain of the element indicated by e.

The gradient is a vector in R³ expressed in frame M. For surface meshes, it will particularly lie parallel to the plane of the corresponding triangle.

Exceptions
std::exceptionif the gradient vector was not calculated.
std::exceptionif the gradient field is marked degenerate.

◆ is_gradient_field_degenerate()

bool is_gradient_field_degenerate ( ) const
Returns
true iff the gradient field could not be computed, and the mesh was constructed with MeshGradientMode::kOkOrMarkDegenerate.

◆ mesh()

const MeshType& mesh ( ) const

◆ operator=()

MeshFieldLinear& operator= ( MeshFieldLinear< T, MeshType > &&  )
default

◆ Transform()

void Transform ( const math::RigidTransform< typename MeshType::ScalarType > &  X_NM)

(Advanced) Transforms this mesh field to be measured and expressed in frame N (from its original frame M).

See the class documentation for further details.

Warning
This method should always be invoked in tandem with the transformation of the underlying mesh into the same frame (TransformVertices()). To be safe, the mesh should be transformed first.

◆ values()

const std::vector<T>& values ( ) const

The documentation for this class was generated from the following file: