Simbody  3.7
SimTK::PolygonalMesh Class Reference

This class provides a description of a mesh made of polygonal faces (not limited to triangles). More...

+ Inheritance diagram for SimTK::PolygonalMesh:

Public Member Functions

 PolygonalMesh ()
 Create an empty PolygonalMesh, with no vertices or faces. More...
 
void clear ()
 Restore this PolygonalMesh to its default-constructed state, meaning that it will contain no vertices or faces after this call. More...
 
int getNumFaces () const
 Get the number of faces in the mesh. More...
 
int getNumVertices () const
 Get the number of vertices in the mesh. More...
 
const Vec3getVertexPosition (int vertex) const
 Get the position of a vertex in the mesh. More...
 
int getNumVerticesForFace (int face) const
 Get the number of vertices that make up a particular face. More...
 
int getFaceVertex (int face, int vertex) const
 Get the index of one of the vertices of a face. More...
 
int addVertex (const Vec3 &position)
 Add a vertex to the mesh. More...
 
int addFace (const Array_< int > &vertices)
 Add a face to the mesh. More...
 
PolygonalMeshscaleMesh (Real scale)
 Scale a mesh by multiplying every vertex by a fixed value. More...
 
PolygonalMeshtransformMesh (const Transform &X_AM)
 Transform a mesh by applying the given Transform to every vertex, leaving the mesh permanently changed. More...
 
void loadFile (const String &pathname)
 Attempt to interpret the given file as a mesh file, with the format determined from the file name extension. More...
 
void loadObjFile (const String &pathname)
 Load a Wavefront OBJ (.obj) file, adding the vertices and faces it contains to this mesh, and ignoring anything else in the file. More...
 
void loadObjFile (std::istream &file)
 Alternate signature for Wavefront OBJ format that takes an already-open istream rather than a pathname. More...
 
void loadVtpFile (const String &pathname)
 Load a VTK PolyData (.vtp) file, adding the vertices and faces it contains to this mesh and ignoring anything else in the file. More...
 
void loadStlFile (const String &pathname)
 Load an STL file, adding the vertices and faces it contains to this mesh and ignoring anything else in the file. More...
 
- Public Member Functions inherited from SimTK::PIMPLHandle< PolygonalMesh, PolygonalMeshImpl, true >
bool isEmptyHandle () const
 Returns true if this handle is empty, that is, does not refer to any implementation object. More...
 
bool isOwnerHandle () const
 Returns true if this handle is the owner of the implementation object to which it refers. More...
 
bool isSameHandle (const PolygonalMesh &other) const
 Determine whether the supplied handle is the same object as "this" PIMPLHandle. More...
 
void disown (PolygonalMesh &newOwner)
 Give up ownership of the implementation to an empty handle. More...
 
PIMPLHandlereferenceAssign (const PolygonalMesh &source)
 "Copy" assignment but with shallow (pointer) semantics. More...
 
PIMPLHandlecopyAssign (const PolygonalMesh &source)
 This is real copy assignment, with ordinary C++ object ("value") semantics. More...
 
void clearHandle ()
 Make this an empty handle, deleting the implementation object if this handle is the owner of it. More...
 
const PolygonalMeshImpl & getImpl () const
 Get a const reference to the implementation associated with this Handle. More...
 
PolygonalMeshImpl & updImpl ()
 Get a writable reference to the implementation associated with this Handle. More...
 
int getImplHandleCount () const
 Return the number of handles the implementation believes are referencing it. More...
 

Static Public Member Functions

static PolygonalMesh createSphereMesh (Real radius, int resolution=1)
 Create a sphere-shaped mesh, with roughly uniform mesh elements. More...
 
static PolygonalMesh createBrickMesh (const Vec3 &halfDims, int resolution=1)
 Create a brick-shaped mesh. More...
 
static PolygonalMesh createCylinderMesh (const UnitVec3 &axis, Real radius, Real halfLength, int resolution=1)
 Create a cylinder-shaped mesh, with the long axis in a given direction. More...
 

Additional Inherited Members

- Public Types inherited from SimTK::PIMPLHandle< PolygonalMesh, PolygonalMeshImpl, true >
typedef PIMPLHandle< PolygonalMesh, PolygonalMeshImpl, PTR > HandleBase
 
typedef HandleBase ParentHandle
 
- Protected Member Functions inherited from SimTK::PIMPLHandle< PolygonalMesh, PolygonalMeshImpl, true >
 PIMPLHandle ()
 The default constructor makes this an empty handle. More...
 
 PIMPLHandle (PolygonalMeshImpl *p)
 This provides consruction of a handle referencing an existing implementation object. More...
 
 PIMPLHandle (const PIMPLHandle &source)
 The copy constructor makes either a deep (value) or shallow (reference) copy of the supplied source PIMPL object, based on whether this is a "pointer semantics" (PTR=true) or "object (value) semantics" (PTR=false, default) class. More...
 
 ~PIMPLHandle ()
 Note that the destructor is non-virtual. More...
 
PIMPLHandleoperator= (const PIMPLHandle &source)
 Copy assignment makes the current handle either a deep (value) or shallow (reference) copy of the supplied source PIMPL object, based on whether this is a "pointer sematics" (PTR=true) or "object (value) semantics" (PTR=false, default) class. More...
 
void setImpl (PolygonalMeshImpl *p)
 Set the implementation for this empty handle. More...
 
bool hasSameImplementation (const PolygonalMesh &other) const
 Determine whether the supplied handle is a reference to the same implementation object as is referenced by "this" PIMPLHandle. More...
 

Detailed Description

This class provides a description of a mesh made of polygonal faces (not limited to triangles).

Its primary purpose is for loading geometry from files, which can then be used for visualization or collision detection. For example, the following lines load a mesh from a Wavefront OBJ file, then create a DecorativeMesh from it.

mesh.loadObjFile("teapot.obj");
DecorativeMesh decoration(mesh);

You can also read a polygon mesh from a VTK PolyData (.vtp) file, or an STL file (.stl) that is in ascii or binary format. You can also build meshes programmatically, and some static methods are provided here for generating some common shapes. If you don't know what kind of file you have, you can attempt to read it with the loadFile() method which will examine the file extension to determine the expected format.

The mesh has its own local frame and vertex locations are given in that frame. You can scale and transform the vertices relative to that frame (changing the values stored in the mesh) but more commonly the mesh will be placed on a body relative to that body's frame, meaning you can re-use the same mesh in various places.

We expect this to be a large object so give it shared (reference) semantics; that is, the copy constructor and copy assignment default to shallow copies (both handles will refer to the same data). If you want to make a deep (non-shared) copy of a PolygonalMesh, use the copyAssign() method provided by the PIMPLHandle base class.

Constructor & Destructor Documentation

◆ PolygonalMesh()

SimTK::PolygonalMesh::PolygonalMesh ( )
inline

Create an empty PolygonalMesh, with no vertices or faces.

Member Function Documentation

◆ createSphereMesh()

static PolygonalMesh SimTK::PolygonalMesh::createSphereMesh ( Real  radius,
int  resolution = 1 
)
static

Create a sphere-shaped mesh, with roughly uniform mesh elements.

Parameters
[in]radiusThe radius of the underlying sphere. Vertices of the mesh will be on the sphere, with mesh elements somewhat inside.
[in]resolution
Control for how dense a mesh to produce. Resolution 0 will produce an octahedron (8 triangular faces). Resolution 1 (the default) gives 32 faces, resolution 2 gives 128. In general for resolution n there will be 2*4^(n+1) faces.
Returns
A PolygonalMesh representing a sphere of the specified radius.

◆ createBrickMesh()

static PolygonalMesh SimTK::PolygonalMesh::createBrickMesh ( const Vec3 halfDims,
int  resolution = 1 
)
static

Create a brick-shaped mesh.

A brick is a rectangular solid (a box) centered at and aligned with the mesh local frame. Note that its size is given with half dimensions. By default you will just get two mesh faces along the longest edge of the brick, with all other edges roughly the same size. You can control the mesh density with the resolution parameter.

Parameters
[in]halfDims
The half-dimensions of the brick. The extreme vertices are at -halfDims and +halfDims, so the brick is centered around the mesh local frame.
[in]resolution
Control for how dense a mesh to produce. For this shape, resolution is interpreted as the number of extra vertices to insert in the longest edge of the brick. Extra vertices are inserted into the shorter edges if needed to keep the edge lengths approximately uniform for every mesh face. resolution=0 gives only vertices at the corners; the default is 1 meaning that the longest edge is split once.
Returns
A PolygonalMesh representing a brick of the requested size.

Controlling the mesh density:

If you want a brick mesh where all the edges in the mesh are roughly the same length, say wantEdgeLength, set resolution like this:

Real wantEdgeLength = ...;
Vec3 halfDims = ...;
int resolution = (int)(max(halfDims)/wantEdgeLength + 0.5);

If you want a brick mesh where all the edges are roughly the same length as the shortest edge of the brick, just set wantEdgeLength=min(halfDims) in the above calculation.

◆ createCylinderMesh()

static PolygonalMesh SimTK::PolygonalMesh::createCylinderMesh ( const UnitVec3 axis,
Real  radius,
Real  halfLength,
int  resolution = 1 
)
static

Create a cylinder-shaped mesh, with the long axis in a given direction.

By default you'll get a 12 sided polygon as the base and elements of roughly similar dimension along the edges. You can control the mesh density with the resolution parameter.

Parameters
[in]axisThe central axis direction of the cylinder, in the mesh local frame. This can be provided using the constants XAxis, YAxis, or ZAxis, or you can provide a unit vector in any direction.
[in]radiusThe cylinder radius.
[in]halfLength
Half the length of the cylinder along its axis. The bases are at -halfLength and +halfLength along the axis, so the cylinder is centered around the mesh local frame origin.
[in]resolution
Control for how dense a mesh to produce (see below for details).
Returns
A PolygonalMesh representing a cylinder of the requested dimensions and orientation.

Controlling the mesh density:


At resolution 0 the base is a hexagon with six triangular faces, and the tube is meshed with quad faces that are about as long as the diameter of the base. Resolution 1 (the default) makes the base a 12-sided polygon and introduces an intermediate 12-sided polygon of have the diameter. There will be triangles in the center still, but quad faces between the polygons. The length of the tube faces will be reduced to match. Higher resolutions refine the mesh similarly.

◆ clear()

void SimTK::PolygonalMesh::clear ( )

Restore this PolygonalMesh to its default-constructed state, meaning that it will contain no vertices or faces after this call.

◆ getNumFaces()

int SimTK::PolygonalMesh::getNumFaces ( ) const

Get the number of faces in the mesh.

◆ getNumVertices()

int SimTK::PolygonalMesh::getNumVertices ( ) const

Get the number of vertices in the mesh.

◆ getVertexPosition()

const Vec3& SimTK::PolygonalMesh::getVertexPosition ( int  vertex) const

Get the position of a vertex in the mesh.

Parameters
[in]vertexThe index of the vertex (as returned by addVertex()).
Returns
The position of the specified vertex, measured and expressed in the mesh local frame.

◆ getNumVerticesForFace()

int SimTK::PolygonalMesh::getNumVerticesForFace ( int  face) const

Get the number of vertices that make up a particular face.

Parameters
[in]faceThe index of the face (as returned by addFace()).

◆ getFaceVertex()

int SimTK::PolygonalMesh::getFaceVertex ( int  face,
int  vertex 
) const

Get the index of one of the vertices of a face.

Parameters
[in]faceThe index of the face (as returned by addFace()).
[in]vertexThe index of the vertex within the face (from 0, 1, or 2 for a triangular face, etc.) These are ordered the same way as when the face was defined.
Returns
The index of the specified vertex.

◆ addVertex()

int SimTK::PolygonalMesh::addVertex ( const Vec3 position)

Add a vertex to the mesh.

Parameters
[in]positionThe position of the vertex to add, measured and expressed in the mesh local frame.
Returns
The index of the newly added vertex.

◆ addFace()

int SimTK::PolygonalMesh::addFace ( const Array_< int > &  vertices)

Add a face to the mesh.

Note that the ordering of the vertices defines the outward normal for the face; they must be counterclockwise around the desired normal.

Parameters
[in]verticesIndices of the vertices which make up the new face, in counterclockwise order with respect to the face normal.
Returns
The index of the newly added face.

◆ scaleMesh()

PolygonalMesh& SimTK::PolygonalMesh::scaleMesh ( Real  scale)

Scale a mesh by multiplying every vertex by a fixed value.

Note that this permanently modifies the vertex locations within the mesh. Since the vertices are measured in the mesh local frame, scaling will appear to occur around the mesh origin (that is, the origin will remain where it was while everything else changes.

Parameters
[in]scaleThe scale factor. Can be any value except zero.
Returns
A reference to this now-scaled mesh object.

◆ transformMesh()

PolygonalMesh& SimTK::PolygonalMesh::transformMesh ( const Transform X_AM)

Transform a mesh by applying the given Transform to every vertex, leaving the mesh permanently changed.

This has the effect of replacing the mesh local frame M with a new frame A.

Parameters
[in]X_AMThe transform giving the pose of the mesh local frame in the new frame A. Every vertex v_M becomes v_A=X_AM*v_M.
Returns
A reference to this now-transformed mesh object.

◆ loadFile()

void SimTK::PolygonalMesh::loadFile ( const String pathname)

Attempt to interpret the given file as a mesh file, with the format determined from the file name extension.

If we recognize the extension we'll call one of the specialized methods below; see the descriptions for more information. Ignoring case, we recognize:

  • .obj : Wavefront OBJ file
  • .stl : 3D Systems Stereolithography file (ascii or binary)
  • .stla: ascii-only stl extension
  • .vtp : VTK PolyData file (we can only read the ascii version)
Parameters
[in]pathnameThe name of a mesh file with a recognized extension.

◆ loadObjFile() [1/2]

void SimTK::PolygonalMesh::loadObjFile ( const String pathname)

Load a Wavefront OBJ (.obj) file, adding the vertices and faces it contains to this mesh, and ignoring anything else in the file.

The suffix for these files is typically ".obj" but we don't check here.

Parameters
[in]pathnameThe name of a .obj file.

◆ loadObjFile() [2/2]

void SimTK::PolygonalMesh::loadObjFile ( std::istream &  file)

Alternate signature for Wavefront OBJ format that takes an already-open istream rather than a pathname.

This is useful for testing since it can be supplied by a stringstream rather than a file.

Parameters
[in,out]fileAn input stream from which to load the file contents.

◆ loadVtpFile()

void SimTK::PolygonalMesh::loadVtpFile ( const String pathname)

Load a VTK PolyData (.vtp) file, adding the vertices and faces it contains to this mesh and ignoring anything else in the file.

The suffix for these files is typically ".vtp" but we don't check here.

Parameters
[in]pathnameThe name of a .vtp file.

◆ loadStlFile()

void SimTK::PolygonalMesh::loadStlFile ( const String pathname)

Load an STL file, adding the vertices and faces it contains to this mesh and ignoring anything else in the file.

The file may be in ascii or binary format. If the suffix is ".stla" then it can only be ascii. Otherwise, including ".stl" or anything else, we'll examine the contents to determine which format is used. STL files include many repeated vertices; we will collapse any that coincide to within a small tolerance so that there is some hope of getting a connected surface.

Parameters
[in]pathnameThe name of a .stl or .stla file.

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