# 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. 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. 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. 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
...`````` 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. 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). 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`````` 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`````` 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}`````` ## 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();`````` ## 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