Volume Meshes
Volumetric meshes, such as tetrahedral (tet) and hexahedral (hex, cubelike) meshes, represent a region of 3D space. Polyscope can display tet and hex meshes, including those which have a mix of hex and tet elements. We’ll use the term cell to refer generically to a tet or hex in a volume mesh. As always, Polyscope can also handle scalar, color, or vector quantities associated with the vertices or cells of the mesh, and you can click on the mesh elements to inspect values.
Registering a volume mesh
Example: registering a tetrahedral mesh from libIGL
#include "polyscope/polyscope.h"
#include "polyscope/volume_mesh.h"
#include <igl/readMESH.h>
// Initialize Polyscope
polyscope::init();
// Read mesh from file
Eigen::MatrixXd V; // vertex positions
Eigen::MatrixXi T; // tetrahedra
Eigen::MatrixXi F; // faces (we don't use these here)
igl::readMESH("path/to/volume.mesh", V, T, F);
// Register the volume mesh with Polyscope
polyscope::registerTetMesh("my mesh", V, T);
// Add a scalar quantity
size_t nVerts = V.rows();
std::vector<double> scalarV(nVerts);
for (size_t i = 0; i < nVerts; i++) {
// use the xcoordinate of vertex position as a test function
scalarV[i] = V(i,0);
}
polyscope::getVolumeMesh("my mesh")>addVertexScalarQuantity("scalar Q", scalarV);
// Show the GUI
polyscope::show();
Volume meshes are registered with Polyscope by passing the location of each vertex in the mesh, as well as the vertex indices for each cell. There are a few different variants to register meshes with tets, hexes, or a mix of the two. All of these register helpers return a pointer to a polyscope::VolumeMesh
object which you can then add quantities to.
polyscope::registerTetMesh(std::string name, const V& vertexPositions, const C& tetIndices)
Add a new volume mesh structure to Polyscope, with all tetrahedral elements.

vertexPositions
is the vector array of 3D vertex locations. The type should be adaptable to an array offloat
valued 3vectors; this allows many common types to be used as input, includingEigen::MatrixXd
andstd::vector<std::array<double, 3>>
. The length will be the number of vertices. 
tetIndices
is the 2D array of vertex indices for each tetrahedral cell, with dimension(C,4)
whereC
is the number of tets. The type should be adaptable to a nested array ofsize_t
; this allows many common types to be used as input, includingEigen::MatrixXi
andstd::vector<std::array<size_t, 4>>
. All indices should be valid 0based indices in to the vertex list.
polyscope::registerHexMesh(std::string name, const V& vertexPositions, const C& hexIndices)
Add a new volume mesh structure to Polyscope, with all hexahedral (cubelike) elements.

vertexPositions
is the vector array of 3D vertex locations. The type should be adaptable to an array offloat
valued 3vectors; this allows many common types to be used as input, includingEigen::MatrixXd
andstd::vector<std::array<double, 3>>
. The length will be the number of vertices. 
hexIndices
is the 2D array of vertex indices for each hexahedral cell, with dimension(C,8)
whereC
is the number of hexes. The type should be adaptable to a nested array ofsize_t
; this allows many common types to be used as input, includingEigen::MatrixXi
andstd::vector<std::array<size_t, 8>>
. All indices should be valid 0based indices in to the vertex list.
polyscope::registerVolumeMesh(std::string name, const V& vertexPositions, const C& hexIndices)
Add a new volume mesh structure to Polyscope, which may have a mix of cell types. This variant takes a rectangular array as input, where all cell rows have 8 entries, but cells with less than 8 vertices are padded with negative values.
For instance, a row of the 2D array hexIndices
which refers to a tet cell might hold [12, 9, 22, 51, 1, 1, 1, 1]
.

vertexPositions
is the vector array of 3D vertex locations. The type should be adaptable to an array offloat
valued 3vectors; this allows many common types to be used as input, includingEigen::MatrixXd
andstd::vector<std::array<double, 3>>
. The length will be the number of vertices. 
hexIndices
is the 2D array of vertex indices for each hexahedral cell, with dimension(C,8)
whereC
is the number of tet/hexes. For tet elements, the rows of the array should be padded with negative indices, which will be ignored. The type should be adaptable to a nested array ofunsigned int
; this allows many common types to be used as input, includingEigen::MatrixXi
andstd::vector<std::array<int, 8>>
. All indices should be valid 0based indices in to the vertex list. Signed types should be used to support the negative element convention as described above.
polyscope::registerTetHexMesh(std::string name, const V& vertexPositions, const Ct& tetIndices, const Ct& hexIndices)
Add a new volume mesh structure to Polyscope. This variant takes a mix of tet and hex elements, where each are given in their own separate list.

vertexPositions
is the vector array of 3D vertex locations. The type should be adaptable to an array offloat
valued 3vectors; this allows many common types to be used as input, includingEigen::MatrixXd
andstd::vector<std::array<double, 3>>
. The length will be the number of vertices. 
tetIndices
is the 2D array of vertex indices for each tetrahedral cell, with dimension(C,4)
whereC
is the number of tets. The type should be adaptable to a nested array ofsize_t
; this allows many common types to be used as input, includingEigen::MatrixXi
andstd::vector<std::array<size_t, 4>>
. All indices should be valid 0based indices in to the vertex list. 
hexIndices
is the 2D array of vertex indices for each hexahedral cell, with dimension(C,8)
whereC
is the number of hexes. The type should be adaptable to a nested array ofsize_t
; this allows many common types to be used as input, includingEigen::MatrixXi
andstd::vector<std::array<size_t, 8>>
. All indices should be valid 0based indices in to the vertex list.
For the purposes of element ordering, the cells are presumed to be ordered with all tetrahedral cells coming first, then hexahedral cells.
No support for 2D
Unlike other structures, 2D volume meshes are not supported; they don’t make much sense (see 2D data).
Updating a mesh
The locations of the vertices in a mesh can be updated with the member function updateVertexPositions(newPositions)
. All quantities will be preserved. Changing the connectivity or element counts in a mesh is not supported, you will need to register a new mesh (perhaps with the same name to overwrite).
void VolumeMesh::updateVertexPositions(const V& newPositions)
Update the vertex positions in a volume mesh structure.
newPositions
is the vector array of 3D vertex locations. The type should be adaptable to an array offloat
valued 3vectors. The length must be equal to the current number of vertices.
Slice planes
Slice planes are particularly useful for inspecting the internal stucture of a volume mesh, as shown in the demo video at the top. Slice planes can be manipulated programmatically or manually in the GUI; see the slice plane documentation for more details.
Options
Parameter  Meaning  Getter  Setter  Persistent? 

enabled  is the structure enabled?  bool isEnabled() 
setEnabled(bool newVal) 
yes 
transparency  transparency alpha for this structure in [0,1] 
double getTransparency() 
setTransparency(double val) 
yes 
color  the color of the outside of the volume  glm::vec3 getColor() 
setColor(glm::vec3 val) 
yes 
interior color  the color of the inside of the volume  glm::vec3 getInteriorColor() 
setInteriorColor(glm::vec3 val) 
yes 
edge color  the color of the edges of the mesh  glm::vec3 getEdgeColor() 
setEdgeColor(glm::vec3 val) 
yes 
edge width  how thick to draw mesh edges, use 0. to disable and 1. for reasonable edges 
double getEdgeWidth() 
setEdgeWidth(double val) 
yes 
material  what material to use  std::string getMaterial() 
setMaterial(std::string name) 
yes 
(all setters return this
to support chaining. setEnabled()/setTransparency() return generic setter, so chain them last)