##########################################
Getting Tessellation using ``A3DMeshData``
##########################################

.. sidebar:: Sample code

   A :ref:`sample application <sample_mesh_viewer>` is provided in the HOOPS Exchange package, along with a :doc:`tutorial </tutorials/c/mesh-viewer-sample>`.
   They describe how to use the :cpp:struct:`A3DMeshData` for creating a simple model viewer.

This document presents the layout and usage of the :cpp:struct:`A3DMeshData`.
This structure abstracts the tessellation mechanism presented in :doc:`/guide/geometry/getting_tessellation` and is used in conjunction with the :cpp:func:`A3DRiComputeMesh` function.

Topology
========

In the context of ``A3DMeshData``, a mesh is a set of *x* / *y* / *z* *vertices*.

Vertex Coordinates
------------------

Each vertex is located in 3D space using a triplet of values.
They are stored in :cpp:member:`~A3DMeshData::m_pdCoords` as a flat list in which **each sequential group of 3 values forms the coordinates of the same vertex**.

The following table describes the content of :cpp:member:`~A3DMeshData::m_pdCoords` for a unit-size cube containing 8 vertices.

.. figure:: a3dmeshdata_vertices.svg
   :align: center

   A unit-length cube.
   The numbers corresponds to the indices in the below table.


The value in the *Index* column can be used in :cpp:member:`~A3DMeshData::m_pdCoords` to get the *X* coordinate of each corresponding vertex.
*Y* and *Z* coordinates can be retrieved using respectively *Index + 1* and *Index + 2*.

.. sidebar:: Memory representation of :cpp:member:`~A3DMeshData::m_pdCoords`:

   .. code:: c

      {
        0.0, 0.0, 0.0, // Vertex #0
        1.0, 0.0, 0.0, // Vertex #1
        1.0, 1.0, 0.0, // Vertex #2
        0.0, 1.0, 0.0, // Vertex #3
        0.0, 0.0, 1.0, // Vertex #4
        1.0, 0.0, 1.0, // Vertex #5
        1.0, 1.0, 1.0, // Vertex #6
        0.0, 1.0, 1.0, // Vertex #7
      }

======= ======= ======= ======= ======
Vertex  Index   *X*     *Y*     *Z*
======= ======= ======= ======= ======
#0      **0**   *0.0*   *0.0*   *0.0*
#1      **3**   *1.0*   *0.0*   *0.0*
#2      **6**   *1.0*   *1.0*   *0.0*
#3      **9**   *0.0*   *1.0*   *0.0*
#4      **12**   *0.0*   *0.0*   *1.0*
#5      **15**   *1.0*   *0.0*   *1.0*
#6      **18**   *1.0*   *1.0*   *1.0*
#7      **21**   *0.0*   *1.0*   *1.0*
======= ======= ======= ======= ======

In this case, :cpp:member:`~A3DMeshData::m_uiCoordSize` is *24* (*3* x *8*).

The following code example shows how to iterate through the vertices of an :cpp:struct:`A3DMeshData`:

.. code:: c

   for (A3DUns32 v_index = 0 ; v_index < s_data.m_uiCoordSize ; v_index += 3) {
       A3DDouble x = s_data.m_pdCoords[v_index];
       A3DDouble y = s_data.m_pdCoords[v_index + 1];
       A3DDouble z = s_data.m_pdCoords[v_index + 2];
   }

Vertex Normals
--------------

Normal coordinates follow exactly the same layout organization as vertex coordinates.
:cpp:member:`~A3DMeshData::m_pdNormals` is used to store the normal coordinates, and the size of the array is set in :cpp:member:`~A3DMeshData::m_uiNormalSize`.

Faces and Triangles
-------------------

A mesh is composed of :cpp:member:`~A3DMeshData::m_uiFaceSize` faces.
Each face *f* is composed of ``m_puiTriangleCountPerFace[f]`` triangles.
A single triangle is defined using *3* vertices stored in :cpp:member:`~A3DMeshData::m_ppuiPointIndicesPerFace`.

``m_ppuiPointIndicesPerFace[f]`` is an array of vertex indices for the face *f*, where *f* is in the range [0 ; :cpp:member:`~A3DMeshData::m_uiFaceSize` ].
The first three indices make the first triangle of face *f*, second group of 3 makes the second triangle and so on.
The length of ``m_ppuiPointIndicesPerFace[f]`` is then ``3 * m_puiTriangleCountPerFace[f]``.

Each value of ``m_ppuiPointIndicesPerFace[f]`` is an index used to retrieve the actual coordinates in :cpp:member:`~A3DMeshData::m_pdCoords`.

Going back to the unit cube mentioned above.
In our case, the cube has 8 faces, each made up of 2 triangles.

.. figure:: a3dmeshdata_triangles.svg
   :align: center

   In this model, all faces have exactly 2 triangles.
   Both triangles of the front face (#0) are highlighted.

In this case:

- :cpp:member:`~A3DMeshData::m_uiFaceSize` is *6* and
- :cpp:member:`~A3DMeshData::m_puiTriangleCountPerFace` is ``{2, 2, 2, 2, 2, 2}``.

:cpp:member:`~A3DMeshData::m_ppuiPointIndicesPerFace` can then be represented like this:


.. sidebar:: Memory representation of :cpp:member:`~A3DMeshData::m_ppuiPointIndicesPerFace`:

   .. code:: c

      {
       {            // Face 0:
           0, 1, 2, // - Triangle 0
           0, 2, 3  // - Triangle 1
       },
       {            // Face: 1
           5, 4, 7, // - Triangle 0
           5, 7, 6  // - Triangle 1
       },
       {            // Face: 2
           4, 0, 3, // - Triangle 0
           4, 3, 7  // - Triangle 1
       },
       {            // Face: 3
           1, 5, 6, // - Triangle 0
           1, 6, 2  // - Triangle 1
       },
       {            // Face: 4
           3, 2, 6, // - Triangle 0
           3, 6, 7  // - Triangle 1
       },
       {            // Face: 5
           4, 5, 1, // - Triangle 0
           4, 1, 0  // - Triangle 1
       },
      }



+---------+-------------+----------------+------------+------------+------------+
| Face    | Triangle    | Index [f][t]   | Vertex 0   | Vertex 1   | Vertex 2   |
+=========+=============+================+============+============+============+
|   #0    |     #0      |   **[0][0]**   |    *0*     |    *1*     |    *2*     |
|         +-------------+----------------+------------+------------+------------+
|         |     #1      |   **[0][3]**   |    *0*     |    *2*     |    *3*     |
+---------+-------------+----------------+------------+------------+------------+
|   #1    |     #0      |   **[1][0]**   |    *5*     |    *4*     |    *7*     |
|         +-------------+----------------+------------+------------+------------+
|         |     #1      |   **[1][3]**   |    *5*     |    *7*     |    *6*     |
+---------+-------------+----------------+------------+------------+------------+
|   #2    |     #0      |   **[2][0]**   |    *4*     |    *0*     |    *3*     |
|         +-------------+----------------+------------+------------+------------+
|         |     #1      |   **[2][3]**   |    *4*     |    *3*     |    *7*     |
+---------+-------------+----------------+------------+------------+------------+
|   #3    |     #0      |   **[3][0]**   |    *1*     |    *5*     |    *6*     |
|         +-------------+----------------+------------+------------+------------+
|         |     #1      |   **[3][3]**   |    *1*     |    *6*     |    *2*     |
+---------+-------------+----------------+------------+------------+------------+
|   #4    |     #0      |   **[4][0]**   |    *3*     |    *2*     |    *6*     |
|         +-------------+----------------+------------+------------+------------+
|         |     #1      |   **[4][3]**   |    *3*     |    *6*     |    *7*     |
+---------+-------------+----------------+------------+------------+------------+
|   #5    |     #0      |   **[5][0]**   |    *4*     |    *5*     |    *1*     |
|         +-------------+----------------+------------+------------+------------+
|         |     #1      |   **[5][3]**   |    *4*     |    *1*     |    *0*     |
+---------+-------------+----------------+------------+------------+------------+

In this case, :cpp:member:`~A3DMeshData::m_ppuiPointIndicesPerFace` is an array of *36* indices: *6 faces x 2 triangles x 3 indices*.
Please note that, in our case, the computation of the size is simplified given that all faces have the same number of triangles.


The following code example iterates through each vertices, per triangle and per face:

.. code:: c

   // Iterate though each face
   for (A3DUns32 face_i = 0; face_i < s_data.m_uiFaceSize; ++face_i) {
       A3DUns32 n_triangles = s_data.m_puiTriangleCountPerFace[face_i];
       printf("Face #%d (%d triangles):\n", face_i, n_triangles);
   
       // Iterate through each triangle
       for (A3DUns32 triangle_i = 0; triangle_i < n_triangles; ++triangle_i) {
           printf("\t- Triangle #%d:\n", triangle_i);
   
           // Iterate through each vertex
           for (A3DUns32 vertex_i = 0; vertex_i < 3; ++vertex_i) {
   
               A3DUns32 vertex_index = s_data.m_ppuiPointIndicesPerFace[face_i][triangle_i * 3 + vertex_i];
   
               A3DDouble x = s_data.m_pdCoords[vertex_index];
               A3DDouble y = s_data.m_pdCoords[vertex_index + 1];
               A3DDouble z = s_data.m_pdCoords[vertex_index + 2];
   
               printf("\t\t- Vertex #%d: {%f, %f, %f}\n", vertex_i, x, y, z);
           }
       }
   }

Which, in the case our our unit-cube, would result the following output:

.. code-block:: text

   Face #0 (2 triangles):
	   - Triangle #0:
		   - Vertex #0: {0.0, 0.0, 0.0}
		   - Vertex #1: {1.0, 0.0, 0.0}
		   - Vertex #2: {1.0, 1.0, 0.0}
	   - Triangle #1:
		   - Vertex #0: {0.0, 0.0, 0.0}
		   - Vertex #1: {1.0, 1.0, 0.0}
		   - Vertex #2: {0.0, 1.0, 0.0}
   ... other faces ...


.. rubric:: Normal Indices

Similarly, triangle normals are stored in `m_ppuiNormalIndicesPerFace[f]`, which contains indices to use with :cpp:member:`~A3DMeshData::m_pdNormals`.
The layout is exactly the same.

Texturing
=========

Each face can be individually configured to hold any number of textures.

UV-coordinates
--------------

Each texture coordinate (also named *uv-coord*) is located in 2D space using a pair of values.
They are stored in :cpp:member:`~A3DMeshData::m_pdTextureUV` as a flat list in which each sequential
group of 2 values form the coordinates of the same texture point:

The following table provides an example of 4 texture coordinates.
*Index* corresponds to the index of the first coordinate (*U*) of each uv-coord.
The *V* coordinate can be retrieved by offsetting from *Index*.

.. sidebar:: Memory representation of :cpp:member:`~A3DMeshData::m_pdTextureUV`:

   .. code:: c
   
      {
       0.24, 0.17, // UV-Coord 0
       0.73, 0.54, // UV-Coord 1
       0.11, 0.79, // UV-Coord 2
       0.95, 0.67, // UV-Coord 3
      }

========== ======= ====== ======
 UV-Coord   Index    U      V
========== ======= ====== ======
   #0       **0**  *0.24* *0.17*
   #1       **2**  *0.73* *0.54*
   #2       **4**  *0.11* *0.79*
   #3       **6**  *0.95* *0.67*
========== ======= ====== ======

In this case, :cpp:member:`~A3DMeshData::m_uiTextureSize` is *8* (*2* x *4*).

The following code example shows how to iterate through the texture coordinates of an
:cpp:struct:`A3DMeshData`:

.. code:: c

   for (A3DUns32 v_index = 0 ; v_index < s_data.m_uiTextureSize ; v_index += 2) {
       A3DDouble u = s_data.m_pdTextureUV[v_index];
       A3DDouble v = s_data.m_pdTextureUV[v_index + 1];
   }

Faces and Textures
------------------

The number of textures on face *F* is stored in ``m_puiTextureCountPerFace[F]``.
This array can be set to *0* if the mesh data is not textured.

`m_ppuiTextureUVIndicesPerFace[f]` is an array of uv-coordinate indices for the face *f*, where *f* is in the range [0 ; :cpp:member:`~A3DMeshData::m_uiFaceSize` ].
The array provides sequential triplets of texture indices grouped by triangle, then by vertex, then by texture number.
This means that the length of `m_ppuiTextureUVIndicesPerFace[f]` is ``m_puiTextureCountPerFace[f] * 3 * m_puiTriangleCountPerFace[f]``.

The indices provided in :cpp:member:`~A3DMeshData::m_ppuiTextureUVIndicesPerFace` are used to retrieve the actual uv-coordinates in :cpp:member:`~A3DMeshData::m_pdTextureUV`.

Using the unit cube described above (6 faces, 2 triangles per face), the table below shows the content of :cpp:member:`~A3DMeshData::m_ppuiTextureUVIndicesPerFace` if each face has exactly 2 texture.
The value in the *Index* column can be used in :cpp:member:`~A3DMeshData::m_ppuiTextureUVIndicesPerFace` to get the uv-cooord index of the first  texture (*UV-Coord 0*) of each corresponding vertex.
*Index* is then offset to get the uv-coordinates of other textures.

.. sidebar:: Memory representation of :cpp:member:`~A3DMeshData::m_ppuiTextureUVIndicesPerFace`:

   .. code:: c
   
      {
          {         // Face 0
              2, 1, // Triangle 0, Vertex 0
              2, 1, // Triangle 0, Vertex 1
              0, 1, // Triangle 0, Vertex 2
              0, 2, // Triangle 1, Vertex 0
              0, 2, // Triangle 1, Vertex 1
              0, 2, // Triangle 1, Vertex 2
          },
          {         // Face 1
              1, 0, // Triangle 0, Vertex 0
              1, 0, // Triangle 0, Vertex 1
              1, 0, // Triangle 0, Vertex 2
              2, 3, // Triangle 1, Vertex 0
              2, 3, // Triangle 1, Vertex 1
              3, 2, // Triangle 1, Vertex 2
          },
          {         // Face 2
              0, 2, // Triangle 0, Vertex 0
              0, 2, // Triangle 0, Vertex 1
              1, 3, // Triangle 0, Vertex 2
              2, 1, // Triangle 1, Vertex 0
              2, 1, // Triangle 1, Vertex 1
              1, 0, // Triangle 1, Vertex 2
          },
          {         // Face 3
              3, 0, // Triangle 0, Vertex 0
              3, 0, // Triangle 0, Vertex 1
              2, 1, // Triangle 0, Vertex 2
              1, 2, // Triangle 1, Vertex 0
              1, 2, // Triangle 1, Vertex 1
              0, 3, // Triangle 1, Vertex 2
          },
          {         // Face 4
              2, 1, // Triangle 0, Vertex 0
              2, 1, // Triangle 0, Vertex 1
              0, 3, // Triangle 0, Vertex 2
              1, 2, // Triangle 1, Vertex 0
              1, 2, // Triangle 1, Vertex 1
              3, 0, // Triangle 1, Vertex 2
          },
          {         // Face 5
              0, 3, // Triangle 0, Vertex 0
              0, 3, // Triangle 0, Vertex 1
              2, 1, // Triangle 0, Vertex 2
              3, 0, // Triangle 1, Vertex 0
              3, 0, // Triangle 1, Vertex 1
              2, 1, // Triangle 1, Vertex 2
          }
      }

+---------+------------+------------+-------------+--------------+--------------+
| Face #  | Triangle # |  Vertex #  |    Index    |  UV-Coord 0  |  UV-Coord 1  |
+=========+============+============+=============+==============+==============+
|         |            |     #0     |  **[0][0]** |      *2*     |      *1*     |
|         |            +------------+-------------+--------------+--------------+
|         |     #0     |     #1     |  **[0][2]** |      *2*     |      *1*     |
|         |            +------------+-------------+--------------+--------------+
|         |            |     #2     |  **[0][4]** |      *0*     |      *1*     |
|   #0    +------------+------------+-------------+--------------+--------------+
|         |            |     #0     |  **[0][6]** |      *0*     |      *2*     |
|         |            +------------+-------------+--------------+--------------+
|         |     #1     |     #1     |  **[0][8]** |      *0*     |      *2*     |
|         |            +------------+-------------+--------------+--------------+
|         |            |     #2     | **[0][10]** |      *0*     |      *2*     |
+---------+------------+------------+-------------+--------------+--------------+
|         |            |     #0     |  **[1][0]** |      *1*     |      *0*     |
|         |            +------------+-------------+--------------+--------------+
|         |     #0     |     #1     |  **[1][2]** |      *1*     |      *0*     |
|         |            +------------+-------------+--------------+--------------+
|         |            |     #2     |  **[1][4]** |      *1*     |      *0*     |
|   #1    +------------+------------+-------------+--------------+--------------+
|         |            |     #0     |  **[1][6]** |      *2*     |      *3*     |
|         |            +------------+-------------+--------------+--------------+
|         |     #1     |     #1     |  **[1][8]** |      *2*     |      *3*     |
|         |            +------------+-------------+--------------+--------------+
|         |            |     #2     | **[1][10]** |      *3*     |      *2*     |
+---------+------------+------------+-------------+--------------+--------------+
|         |            |     #0     |  **[2][0]** |      *0*     |      *2*     |
|         |            +------------+-------------+--------------+--------------+
|         |     #0     |     #1     |  **[2][2]** |      *0*     |      *2*     |
|         |            +------------+-------------+--------------+--------------+
|         |            |     #2     |  **[2][4]** |      *1*     |      *3*     |
|   #2    +------------+------------+-------------+--------------+--------------+
|         |            |     #0     |  **[2][6]** |      *2*     |      *1*     |
|         |            +------------+-------------+--------------+--------------+
|         |     #1     |     #1     |  **[2][8]** |      *2*     |      *1*     |
|         |            +------------+-------------+--------------+--------------+
|         |            |     #2     | **[2][10]** |      *1*     |      *0*     |
+---------+------------+------------+-------------+--------------+--------------+
|         |            |     #0     |  **[3][0]** |      *3*     |      *0*     |
|         |            +------------+-------------+--------------+--------------+
|         |     #0     |     #1     |  **[3][2]** |      *3*     |      *0*     |
|         |            +------------+-------------+--------------+--------------+
|         |            |     #2     |  **[3][4]** |      *2*     |      *1*     |
|   #3    +------------+------------+-------------+--------------+--------------+
|         |            |     #0     |  **[3][6]** |      *1*     |      *2*     |
|         |            +------------+-------------+--------------+--------------+
|         |     #1     |     #1     |  **[3][8]** |      *1*     |      *2*     |
|         |            +------------+-------------+--------------+--------------+
|         |            |     #2     | **[3][10]** |      *0*     |      *3*     |
+---------+------------+------------+-------------+--------------+--------------+
|         |            |     #0     |  **[4][0]** |      *2*     |      *1*     |
|         |            +------------+-------------+--------------+--------------+
|         |     #0     |     #1     |  **[4][2]** |      *2*     |      *1*     |
|         |            +------------+-------------+--------------+--------------+
|         |            |     #2     |  **[4][4]** |      *0*     |      *3*     |
|   #4    +------------+------------+-------------+--------------+--------------+
|         |            |     #0     |  **[4][6]** |      *1*     |      *2*     |
|         |            +------------+-------------+--------------+--------------+
|         |     #1     |     #1     |  **[4][8]** |      *1*     |      *2*     |
|         |            +------------+-------------+--------------+--------------+
|         |            |     #2     | **[4][10]** |      *3*     |      *0*     |
+---------+------------+------------+-------------+--------------+--------------+
|         |            |     #0     |  **[5][0]** |      *0*     |      *3*     |
|         |            +------------+-------------+--------------+--------------+
|         |     #0     |     #1     |  **[5][2]** |      *0*     |      *3*     |
|         |            +------------+-------------+--------------+--------------+
|         |            |     #2     |  **[5][4]** |      *2*     |      *1*     |
|   #5    +------------+------------+-------------+--------------+--------------+
|         |            |     #0     |  **[5][6]** |      *3*     |      *0*     |
|         |            +------------+-------------+--------------+--------------+
|         |     #1     |     #1     |  **[5][8]** |      *3*     |      *0*     |
|         |            +------------+-------------+--------------+--------------+
|         |            |     #2     | **[5][10]** |      *2*     |      *1*     |
+---------+------------+------------+-------------+--------------+--------------+

Since each face has two triangles (and 3 vertices per triangle), the total number of uv-coordinates *per face* is *12*: *2 triangles x 3 vertices x 2 textures*.
The total number of uv-coordinates for the entire cube is then *72*: *12 per face x 6 faces*.
Please note that, in our case, the computation of the size is simplified given that all faces have the same number of triangles and textures.

The following code example iterates through each uv-coord, per texture, per triangle and per face:

.. code:: c

   assert(s_data.m_puiTextureCountPerFace != 0); // Ensure the mesh has textures
   
   // Iterate through each face
   for (A3DUns32 face_i = 0; face_i < s_data.m_uiFaceSize; ++face_i) {
       A3DUns32 n_triangles = s_data.m_puiTriangleCountPerFace[face_i];
       printf("Face #%d (%d triangles):\n", face_i, n_triangles);
   
       // Iterate through each triangle
       for (A3DUns32 triangle_i = 0; triangle_i < n_triangles; ++triangle_i) {
           printf("\t- Triangle #%d:\n", triangle_i);
   
           // Iterate through each vertex
           for (A3DUns32 vertex_i = 0; vertex_i < 3; ++vertex_i) {
               printf("\t\t- Vertex #%d:\n", vertex_i);
   
               // Iterate through each texture
               for (A3DUns32 texture_i = 0; texture_i < s_data.m_puiTextureCountPerFace[face_i]; texture_i++) {
                   A3DUns32 uv_index = s_data.m_ppuiTextureUVIndicesPerFace[face_i][
                       (3 * s_data.m_puiTextureCountPerFace[face_i] * triangle_i) +
                       (s_data.m_puiTextureCountPerFace[face_i] * vertex_i) +
                       texture_i
                   ];
   
                   A3DDouble u = s_data.m_pdTextureUV[uv_index];
                   A3DDouble v = s_data.m_pdTextureUV[uv_index + 1];
   
                   printf("\t\t\t- Texture #%d: {%f, %f}\n", texture_i, u, v);
               }
           }
       }
   }

Which, in the case our our unit-cube, would result the following output:

.. code-block:: text

   Face #0 (2 triangles):
	   - Triangle #0:
		   - Vertex #0:
			   - Texture #0: {0.11, 0.79}
			   - Texture #1: {0.73, 0.54}
		   - Vertex #1:
			   - Texture #0: {0.11, 0.79}
			   - Texture #1: {0.73, 0.54}
		   - Vertex #2:
			   - Texture #0: {0.24, 0.17}
			   - Texture #1: {0.73, 0.54}
	   - Triangle #1:
		   - Vertex #0:
			   - Texture #0: {0.24, 0.17}
			   - Texture #1: {0.11, 0.79}
		   - Vertex #1:
			   - Texture #0: {0.24, 0.17}
			   - Texture #1: {0.11, 0.79}
		   - Vertex #2:
			   - Texture #0: {0.24, 0.17}
			   - Texture #1: {0.11, 0.79}
   ... other faces ...
   

Styling
=======

:cpp:struct:`A3DMeshData` contains styling information for the entire mesh as well as per face.
Mesh and face style information are stored, respectively in :cpp:member:`~A3DMeshData::m_uiStyleIndex` and :cpp:member:`~A3DMeshData::m_puiStyleIndexPerFace`.

See :ref:`getting_global_style_information` for more information about how to retrieve style information from style indexes. 

