Skip to content

Meshes

In this guide, you will learn fundamental elements to understand and manipulate meshes in OpenGeode. Let's begin by introducing every kind of mesh you can work with in OpenGeode.

There are several kinds of meshes representing points, lines, surfaces and solids.

Mesh Hierarchy

All these meshes are available in 2D and 3D (with the exception of solids that are by definition three-dimensional, and vertex sets and graphs which are dimensionless). The dimension is given by a template parameter. For example, two aliases are defined for TriangulatedSurface: TriangulatedSurface2D and TriangulatedSurface3D.

Mesh definitions

We will take the example of a PolygonalSurface mesh to give some definitions on meshes and to show how to manipulate meshes. Potential differences with other kinds of meshes will be pointed if necessary.

Mesh Surface

Let's take the above polygonal mesh as the example.

Vertices and Polygons

This PolygonalSurface is defined by 11 vertices (left) and 6 polygons (right) as shown on the image below.

Mesh Surface 2

Indexing of vertices is continuous, starting at 0 and ending at number of vertices - 1. The polygon indexing is the same.

To known the number of vertices and polygons, use the following methods :

cpp
// Let's have a PolygonalSurface2D& called surface
const auto nbv = surface.nb_vertices();
const auto nbp = surface.nb_polygons();
...
// Let's have a PolygonalSurface2D& called surface
const auto nbv = surface.nb_vertices();
const auto nbp = surface.nb_polygons();
...

Polygons are defined by an ordered list of vertices. For example, the first polygon (with index 0) is defined by vertices: 6, 5, 8, 9, 10. It is easy to get the index of vertices defining a polygon using :

cpp
// Let's have a PolygonalSurface2D& called surface;
const auto pv0 = surface.polygon_vertex( {0, 0} ); // 6
const auto pv1 = surface.polygon_vertex( {0, 1} ); // 5
const auto pv2 = surface.polygon_vertex( {0, 2} ); // 8
...
// Let's have a PolygonalSurface2D& called surface;
const auto pv0 = surface.polygon_vertex( {0, 0} ); // 6
const auto pv1 = surface.polygon_vertex( {0, 1} ); // 5
const auto pv2 = surface.polygon_vertex( {0, 2} ); // 8
...

Mesh Surface 3

Each of these vertices is then a PolygonVertex.

NB: For a Solid, they are called PolyhedronVertex.

Edges and Facets

Even if meshes are entirely defined by vertices and polygons, you can access the mesh facets and edges. Edges are defined for Surfaces and Solids and facets for Solids. All the methods related to edges and facets are accessible using the surface.edges() or solid.facets() getters. As for vertices and polygons, edge and facet indexings are continuous and start at 0.

This feature is optional and disabled by default. To enable it : surface.enable_edges();

In the example, the polygonal surface is composed of 16 edges indexed from 0 to 15.

Mesh Surface 4

cpp
// Let's have a PolygonalSurface2D& called surface;
surface.enable_edges();
const auto nbe = surface.edges().nb_edges();
const auto vertices = surface.edges().edge_vertices( 3 ); // [4, 5]
const auto edge = surface.edges().edge_from_vertices( {8, 0} ); // 1
// Let's have a PolygonalSurface2D& called surface;
surface.enable_edges();
const auto nbe = surface.edges().nb_edges();
const auto vertices = surface.edges().edge_vertices( 3 ); // [4, 5]
const auto edge = surface.edges().edge_from_vertices( {8, 0} ); // 1

As for vertices, it is possible to have access to the global index of a polygon edge. Each PolygonEdge is the edge that starts from the same PolygonVertex; for example, PolygonEdge (2, 1) is the edge of polygon 2 that starts from the PolygonVertex (2, 1).

Mesh Surface 5

NB: For Solids, there are PolyhedronFacet and PolyhedronFacetEdge.

Topological queries

Meshes provide numerous methods to query the mesh topology. One information you can get, for example, is which polygons are adjacent to each other. More precisely, to known which polygon is adjacent to another one through a given PolygonEdge, you can use the following code :

cpp
// Let's have a PolygonalSurface2D& called surface;
const auto polygon = surface.polygon_adjacent( {0, 0} ); // 1
// Let's have a PolygonalSurface2D& called surface;
const auto polygon = surface.polygon_adjacent( {0, 0} ); // 1

Mesh Surface 6

You can have more information and get the index of the PolygonEdge on the adjacent polygon, using the following code :

cpp
// Let's have a PolygonalSurface2D& called surface;
const auto polygon = surface.polygon_adjacent_edge( {0, 0} ); // {1, 2}
// Let's have a PolygonalSurface2D& called surface;
const auto polygon = surface.polygon_adjacent_edge( {0, 0} ); // {1, 2}

ajdacent

If there is no polygon adjacent to the given PolygonEdge, the results of these methods are empty optionals, and the given PolygonEdge is on a border. There is a method to known if a PolygonEdge is on a border :

cpp
// Let's have a PolygonalSurface2D& called surface;
const auto on_border0 = surface.is_edge_on_border( {0, 0} ); // false
const auto on_border1 = surface.is_edge_on_border( {0, 2} ); // true
// Let's have a PolygonalSurface2D& called surface;
const auto on_border0 = surface.is_edge_on_border( {0, 0} ); // false
const auto on_border1 = surface.is_edge_on_border( {0, 2} ); // true

Mesh Surface 7

You can go from one edge on a border to another one using :

cpp
// Let's have a PolygonalSurface2D& called surface;
PolygonEdge start{0, 2};
auto next_edge = surface.next_on_border( start ); // {0, 3}
next_edge = surface.next_on_border( next_edge ); // {0, 4}
next_edge = surface.next_on_border( next_edge ); // {2, 0}
auto prev_edge = surface.previous_on_border( next_edge ); // {0, 4}
...
// Let's have a PolygonalSurface2D& called surface;
PolygonEdge start{0, 2};
auto next_edge = surface.next_on_border( start ); // {0, 3}
next_edge = surface.next_on_border( next_edge ); // {0, 4}
next_edge = surface.next_on_border( next_edge ); // {2, 0}
auto prev_edge = surface.previous_on_border( next_edge ); // {0, 4}
...

You can notice that "next" turns in the same direction than polygon vertices, and "previous" turns therefore in the inverse direction.

An exception is raised if you give as method parameter a PolygonEdge that is not on a border.

Another topological query is to get the polygon list around a vertex:

cpp
// Let's have a PolygonalSurface2D& called surface;
const auto polygons_around4 = surface.polygons_around( 4 ); // an inlined vector containing {4, 3, 1, 2, 5}
// Let's have a PolygonalSurface2D& called surface;
const auto polygons_around4 = surface.polygons_around( 4 ); // an inlined vector containing {4, 3, 1, 2, 5}

Mesh Surface 8

Geometrical queries

Beside topological queries, you can also ask for geometrical mesh queries such as polygon area, edge length, polygon barycenter and so on.

You can get the (axis-aligned) bounding box of a mesh using:

cpp
// Let's have a PolygonalSurface2D& called surface;
const auto bbox = surface.bounding_box();
// Let's have a PolygonalSurface2D& called surface;
const auto bbox = surface.bounding_box();

Mesh Surface 9

Manipulating meshes

All the queries illustrated above are const mesh methods. As a consequence, you can work with a const mesh and have access to all the information you want. If you want to create or modify a mesh, however, you should use a builder as explained in the following guide.

Geode-solutions' documentation website