Skip to content

Geometry Central

This section demonstrates using Polyscope with geometry-central! Note that a few useful adaptor functions are included in geometrycentral/surface/meshio.h.

See this repository for a sample project configuration and CMAKE build system.

Registering a surface mesh

#include "polyscope/polyscope.h"
#include "polyscope/surface_mesh.h"

#include "geometrycentral/surface/surface_mesh.h"
#include "geometrycentral/surface/vertex_position_geometry.h"
#include "geometrycentral/surface/meshio.h"

using namespace geometrycentral::surface;

SurfaceMesh& mesh = /* your mesh */;
EmbeddedGeometryInterface& geom = /* your geometry */;

// Be sure your mesh has vertex positions available
geom.requireVertexPositions();

// Register the mesh with polyscope
polyscope::registerSurfaceMesh("myMesh", geom.vertexPositions, 
                              mesh.getFaceVertexList());

// Note: for a VertexPositionGeometry, one could instead use:
VertexPositionGeometry& posGeom = /* your geometry */;
polyscope::registerSurfaceMesh("myMesh", posGeom.inputVertexPositions, 
                               mesh.getFaceVertexList());

Compressed meshes

Polyscope expects dense buffers of data, but geometry-central uses sparse and lazily allocated buffers to support fast mesh modification.

If you are modifying your mesh, be sure to call mesh->compress() before registering it with Polyscope.

Note: Geometry-central meshes must be in “compressed mode” (with dense indices) to register with Polyscope. If you have deleted elements from your mesh, this may require calling SurfaceMesh::compress() before you register it.

Meshdata containers

Geometry-central’s Meshdata<> containers can be passed directly to Polyscope for visualization.

/* (continuing up from the Registering example above) */

VertexData<double> myScalar = /* some scalar on vertices */;
polyscope::getMesh("myMesh")->addVertexScalarQuantity("myScalar", myScalar);

FaceData<double> otherScalar = /* another scalar on faces*/;
polyscope::getMesh("myMesh")->addFaceScalarQuantity("otherScalar", otherScalar);

FaceData<double> anotherScalar = /* another scalar on edges*/;
polyscope::getMesh("myMesh")->addEdgeScalarQuantity("super important edge scalar", 
                                                     anotherScalar);

// Containers holding `Vector3`s can be used for 3D vectors at faces and vertices
// Example: vertex normals as computed in geometry-central
posGeom->requireVertexNormals();
polyscope::getMesh("myMesh")->addVertexVectorQuantity("vertex normals", 
                                                       posGeom->vertexNormals);

Custom ordering

Geometry-central’s ordering of mesh halfedges and corners is different from Polyscope’s default ordering (see indexing convention). As such, you must tell Polyscope about this ordering for edge-valued, halfedge-valued or corner-valued visualizations to work properly. The geometry-central function polyscopePermutations(HalfedgeMesh& mesh) from meshio.h generates the ordering data in an approriate form for Polyscope, and can be passed either at construction time or after.

polyscope::SurfaceMesh* psMesh = 
    polyscope::registerSurfaceMesh("myMesh", 
                                   geom->vertexPositions, 
                                   mesh->getFaceVertexList());

psMesh->setAllPermutations(polyscopePermutations(*mesh));

// could alternately pass polyscopePermutations(*mesh) as additional 
// last parameter of constructor
polyscope::SurfaceMesh* psMesh = 
    polyscope::registerSurfaceMesh("myMesh", 
                                   geom->vertexPositions, 
                                   mesh->getFaceVertexList(),
                                   polyscopePermutations(*mesh));

Tangent vector data

1-forms

To communicate the canonical edge orientation when passing a 1-form, use polyscopeEdgeOrientations(mesh) from meshio.h.

Example:

#include "geometrycentral/surface/meshio.h"

HalfedgeMesh& mesh = /* your mesh */;
EdgeData<double> myForm = /* your 1-form */;

polyscope::getSurfaceMesh("myMesh")->
  addOneFormIntrinsicVectorQuantity("my form", myForm, 
                                    polyscopeEdgeOrientations(mesh));