Mesh shapes

The mesh shape is the only shape in REDsdk that displays triangles. As a reminder, in fact, there's only one shape for each category of graphic primitive to display in REDsdk (Mesh shapes for triangles, Line shapes for lines, Point shapes for points, Text shapes for texts).

The mesh shape is created using the RED::Factory and the CID_REDMeshShape, as all other shapes: See Creating and destroying shapes for details. It implements the given set of interfaces:

InterfaceDescription
RED::IMeshShapeMesh management API.
RED::IShapeGlobal shape API. Controls shape tree navigation and shape attributes.
RED::IUserDataUser data API to store application custom data associated to a shape.
RED::IChunkSaverShape serialization interface.
RED::IReferenceSolvingShape serialization interface.

The RED::IMeshShape, which is the purpose of this paragraph, contains several services:

  1. Geometry definition APIs: these methods are used to define the contents of the mesh shape to be displayed.
  2. Edge construction APIs: Line shapes can be constructed from meshes in various manners.
  3. Topological services: simple operations, tangents construction services, or texturing services are also present on the shape.
  4. Simple primitives APIs: A set of simple primitives can be created here: torus, sphere, etc...

Geometry definition APIs

First of all, REDsdk geometrical primitives are all index based. This means that all geometrical attributes of a mesh are stored per vertex, as illustrated below:

A mesh vertex data record

A given mesh stores up to 16 channels of information for each of its vertices. Each data channel of a vertex is identified by an entry in the RED::MESH_CHANNEL enumeration. Vertices are accessed by their numbers:

Indexed based vertex access for the rendering

Here, to render the two triangles shown in the illustration, we'll render vertices 0, 1, 2 and then 1, 3, 2. Therefore, we'll access geometry channels stored for the 4 vertices, and reuse data records for vertices 1 and 2 that are used by the two triangles.

Then, the RED::IMeshShape API starts by loading geometrical data arrays for all vertices at a time: RED::IMeshShape::SetArray is used to upload a given RED::MESH_CHANNEL data array for all the vertices of the mesh:

The memory layout of a mesh shape

In the example above, we have three data channels per vertex: RED::MCL_VERTEX, RED::MCL_COLOR and RED::MCL_TEX0. Each data channel has a specific data format for each vertex:

So we see here that the data storage model of a mesh is very flexible and that many data with various layouts can be stored as vertex attributes for a mesh. Then, as a consequence, each array specified using RED::IMeshShape::SetArray must use the same number of vertices: this is the total number of vertices in the mesh.

Arrays in a RED::IMeshShape are defined using the generic RED::MESH_CHANNEL enumeration. However, some arrays have usual meanings, and are used that way throughout the engine:

Then, triangles are specified, that define the mesh surfaces, using RED::IMeshShape::AddTriangles. Please note that triangle strips and triangle fans can be submitted to a mesh, but these are internally turned into triangles. Triangle strips and fans were mostly used in the past to speed-up display performances, but are no longer needed with the way REDsdk render data.

The following example below illustrates the creation of a simple planar mesh:

task

Task: Setup a mesh geometry channels

Here, we define a simple plane as shown below:

And the code sequence to realize it is:

// Creating our mesh shape:
RED::Object* mesh = RED::Factory::CreateInstance( CID_REDMeshShape );
if( !mesh )
  RC_TEST( RED_ALLOC_FAILURE );

RED::IMeshShape* imesh = mesh->As< RED::IMeshShape >();

// We want to create a plane in this example: 4 vertices, with: positions, normals, vertex colors and texture coordinates:
float position[12] = { 0.0f,   0.0f,   0.0f,
                       100.0f, 0.0f,   0.0f,
                       100.0f, 100.0f, 0.0f,
                       0.0f,   100.0f, 0.0f };

float normal[12] = { 0.0f, 0.0f, 1.0f,
                     0.0f, 0.0f, 1.0f,
                     0.0f, 0.0f, 1.0f,
                     0.0f, 0.0f, 1.0f };

unsigned char color[16] = { 255, 0,   0,   255,
                            0,   255, 0,   255,
                            0,   0,   255, 255,
                            0,   0,   0,   255 };

float uv[8] = { 0.0f, 0.0f,
                1.0f, 0.0f,
                1.0f, 1.0f,
                0.0f, 1.0f };

RC_TEST( imesh->SetArray( RED::MCL_VERTEX, position, 4, 3, RED::MFT_FLOAT, iresmgr->GetState() ) );
RC_TEST( imesh->SetArray( RED::MCL_NORMAL, normal, 4, 3, RED::MFT_FLOAT, iresmgr->GetState() ) );
RC_TEST( imesh->SetArray( RED::MCL_COLOR, color, 4, 4, RED::MFT_UBYTE, iresmgr->GetState() ) );
RC_TEST( imesh->SetArray( RED::MCL_TEX0, uv, 4, 2, RED::MFT_FLOAT, iresmgr->GetState() ) );

// Then we need to define our mesh triangles:
int index[6] = { 0, 1, 2,
                 0, 2, 3 };

RC_TEST( imesh->AddTriangles( index, 2, iresmgr->GetState() ) );

Sharing geometry channels

This a very important feature in REDsdk: All geometrical primitives (points, lines, meshes) can share their source data with an external source. This means that a given vertex array can be shared by several shapes or by one shape and an external provider (such as a modelling package like ACIS or PARASOLID).

Data arrays in a mesh can be shared. Instead of calling RED::IMeshShape::SetArray, use RED::IMeshShape::SetSharedArray. Similarly, to share mesh indices, call RED::IMeshShape::SetSharedTriangles.

Using shared arrays overflow the REDsdk transaction system. REDsdk transactions are meant to allow data modification in parallel to the draw. Using shared arrays, this is no longer possible, as the mesh has only one data source array available. Therefore, modifying shared data should be done with caution by the application, and should not occur on an auxiliary thread while a rendering occurs.

Edge construction APIs

The RED::IMeshShape offers several edge construction methods. This can be used to extract all edges in a given mesh. These methods do create a new CID_REDLineShape object, that implements the RED::ILineShape interface:

Please refer to each method documentation for details on these edge shape construction methods.

Topological services

The RED::IMeshShape also offers a few services to manipulate the mesh it stores:

Simple primitives APIs

For some reasons, even after dozen of years in 3D graphics, we still need simple primitives sometimes. The RED::IMeshShape offers a few basic geometry creation services: