###########
Mesh Shapes
###########


.. toctree::
    :maxdepth: 1
    :titlesonly:
    :hidden:

    bk_sgo_ms/bk_sg_skinned_mesh_shapes


The mesh shape is the only shape in HOOPS Luminate that displays triangles. As a reminder, in fact, there's only one shape for each category of graphic primitive to display in HOOPS Luminate (:doc:`/book/subjects/bk_sgo/bk_sg_mesh_shapes` for triangles, :doc:`/book/subjects/bk_sgo/bk_sg_line_shapes` for lines, :doc:`/book/subjects/bk_sgo/bk_sg_point_shapes` for points, :doc:`/book/subjects/bk_sgo/bk_sg_text_shapes` for texts).

The mesh shape is created using the ``RED::Factory`` and the ``CID_REDMeshShape``, as all other shapes: See :doc:`/tasks/ta_ca/ta_ca_scenegraph/tk_creating_and_destroying_shapes` for details. It implements the given set of interfaces:

+----------------------------+--------------------------------------------+
| Interface                  | Description                                |
+============================+============================================+
| ``RED::IMeshShape``        | Mesh management API.                       |
+----------------------------+--------------------------------------------+
| ``RED::IShape``            | Global shape API. Controls shape tree      |
|                            | navigation and shape attributes.           |
+----------------------------+--------------------------------------------+
| ``RED::IUserData``         | User data API to store application custom  |
|                            | data associated to a shape.                |
+----------------------------+--------------------------------------------+
| ``RED::IChunkSaver``       | Shape serialization interface.             |
+----------------------------+--------------------------------------------+
| ``RED::IReferenceSolving`` | Shape serialization interface.             |
+----------------------------+--------------------------------------------+

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

  1. ``Geometry Defintion 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 Primitive APIs``: A set of simple primitives can be created here: torus, sphere, etc... 


************************
Geometry Definition APIs
************************

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

.. figure:: mesh_vertex_data.png 
  :align: center
  
  **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:

.. figure:: mesh_triangles.png 
  :align: center
  
  **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:

.. figure:: vertex_arrays.png 
  :align: center
  
  **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:

  * ``RED::MCL_VERTEX``: 3 coordinates xyz, stored in ``RED::MFT_FLOAT`` precision, hence the total array is 48 bytes for the 4 points mesh.
  * ``RED::MCL_COLOR``: 4 values rgba, stored in ``RED::MFT_UBYTE`` precision, for a total of 4 x 4 = 16 bytes for the mesh.
  * ``RED::MCL_TEX0``: 2 uv values, stored again in ``RED::MFT_FLOAT`` precision, for a total of 4 x 2 x 4 = 32 bytes for the mesh.

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:

  * ``RED::MCL_VERTEX`` is intended to store positions of points in the defined mesh. This is leveraged by both GPU and CPU ray-tracers of HOOPS Luminate, so this is an usage constraint.
  * ``RED::MCL_NORMAL`` is usually intended to store vertex normals of mesh points.
  * ``RED::MCL_COLOR`` usually stores vertex colors.
  * Texture coordinates are by convention often stored using ``RED::MCL_TEX0`` - ``RED::MCL_TEX7``.
  * Tangent space vectors are often stored in ``RED::MCL_USER0``.

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 HOOPS Luminate render data.

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

.. include:: /tasks/ta_ca/ta_ca_scenegraph/tk_setup_a_mesh_geometry_channels.rst


*************************
Sharing Geometry Channels
*************************

This a very important feature in HOOPS Luminate: 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 HOOPS Luminate transaction system. HOOPS Luminate 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:

  * ``RED::IMeshShape::BuildEdges``: Constructs a shape simply set with all edges of a mesh, without any redundancy (an edge shared by two triangles appear once in the resulting shape).
  * ``RED::IMeshShape::BuildBorderEdges``: Constructs only border edges of a mesh. Border edges are only used by one triangle in the mesh.
  * ``RED::IMeshShape::BuildContourEdges``: Constructs all edges with contouring extraction information. This can be used to render real-time silhouettes.

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:

  * A collapse method: ``RED::IMeshShape::Collapse``, used to remove duplicate vertices in a mesh, and to reform the mesh after the operation.
  * Normals of a mesh can be recalculated using ``RED::IMeshShape::Shade``, or ``RED::IMeshShape::ShadeTJunction`` to redefine normals for meshes that have cracks in their topology.
  * Triangle winding can be reversed. The visible face of a triangle (P0,P1,P2) is pointed to by the result of cross( P0P1, P0P2 ), and this method reversed the result of the cross operation by switching P1 and P2 for each triangle in the mesh.
  * Texturing services: ``RED::IMeshShape::BuildTextureCoordinates`` can be used to (re)define UVs associated to the geometry.


**********************
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:

  * ``RED::IMeshShape::Quad``
  * ``RED::IMeshShape::Box``
  * ``RED::IMeshShape::Cylinder``
  * ``RED::IMeshShape::Cone``
  * ``RED::IMeshShape::Torus``
  * ``RED::IMeshShape::Sphere``
