######
Meshes
######


A mesh is a collection of faces, lines, and points. Faces can contain geometry attributes including points, normals, UVs, etc. Lines consist of pairs of positions. Points consist of a position. The :doc:`MeshData </api_ref/viewing/classes/Communicator.Meshdata>` class is a blueprint for instances of a mesh that allow the reuse of the underlying geometry.


Creating meshes
===============

To add a mesh to the scene several functions must be used. First, use the :ref:`createMesh() <api_ref/viewing/classes/Communicator.Model:createmesh>` function which accepts a :doc:`MeshData </api_ref/viewing/classes/Communicator.Meshdata>` object and returns a :doc:`MeshID  </api_ref/viewing/modules/communicator:meshid>`. Next, use the :doc:`MeshInstanceData  </api_ref/viewing/classes/Communicator.Meshinstancedata>` :ref:`constructor <api_ref/viewing/classes/Communicator.Meshinstancedata:constructor>` with the``MeshId`` returned from ``createMesh()`` to create a ``MeshInstanceData`` object. Finally, use the ``MeshInstanceData`` object with the ``createMeshInstance()`` function to insert the mesh into your scene and make it visible.

Sample code demonstrating the use of ``createMesh()`` can be seen :ref:`below <prog_guide/viewing/geometry/meshes:createmeshdata>`, and a snippet demonstrating the use of the ``MeshInstanceData`` constructor with ``createMeshInstance()`` can be seen :ref:`here <prog_guide/viewing/geometry/meshes:instanceconstructor>`.


MeshId
------

A :ref:`MeshId <api_ref/viewing/modules/Communicator:meshid>` is a pair of numbers that is a unique identifier to a mesh object. It can be used to create a :doc:`MeshInstanceData </api_ref/viewing/classes/Communicator.Meshinstancedata>` object. The :ref:`replaceMesh() <api_ref/viewing/classes/Communicator.Model:replacemesh>` function can be used to change the ``MeshData`` geometry identified by the ``MeshId``. If the geometry for any mesh changes, all instances of that mesh in the scene will update accordingly. 


MeshData
--------

:doc:`MeshData </api_ref/viewing/classes/Communicator.Meshdata>` is used to represent mesh geometry and is passed into :ref:`createMesh() <api_ref/viewing/classes/Communicator.Model:createmesh>`.

Face data contains an array of floating-point data describing the points in space for the faces to be added to the mesh and is defined by calling :ref:`addFaces() <api_ref/viewing/classes/Communicator.Meshdata:addfaces>`. This function will add one face element. To add multiple faces, call :ref:`addFaces()  <api_ref/viewing/classes/Communicator.Meshdata:addfaces>` for each face. Face data can also contain normals, colors, or texture parameters for the corresponding vertex data points.  

The snippet below contains ``createTriangleMeshData`` which creates a ``MeshData`` object representing a triangle with vertex coordinates (0,0,0), (0,1,0), (1,0,0). Note that the ``MeshData`` :doc:`FaceWinding  </api_ref/viewing/enums/Communicator.FaceWinding>` is set to :ref:`clockwise  <api_ref/viewing/enums/Communicator.FaceWinding:clockwise>`, and the normal for each vertex is (0,0,1). If the ``FaceWinding`` was set to ``CounterClockwise``, the normal for these coordinates would be (0,0,-1). If the normal does not match the specified ``FaceWinding``, the face lighting will not be correct. With backface visibility off (the default setting), the triangle will only be visible when the camera direction is facing towards the front. Changing ``FaceWinding`` will change which side the triangle is visible from. To update the MeshData's ``FaceWinding`` use :ref:`setFaceWinding() <api_ref/viewing/classes/Communicator.Meshdata:setFaceWinding>`.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Geometry_Meshes.ts
	   :start-after: //! [mesh_data_face]
	   :end-before: //! [mesh_data_face]

.. image:: images/viewing_geometry_meshes_1.png

*Triangle face mesh instance*

Polyline data contains an array of floating-point data describing the points on the line and is defined by calling :ref:`addPolyLine() <api_ref/viewing/classes/Communicator.Meshdata:addpolyline>`. 

``createPolylineMeshData`` creates a :doc:`MeshData </api_ref/viewing/classes/Communicator.Meshdata>` object representing a polyline containing the coordinates (0,0,0), (0,1,0), (1,0,0):

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Geometry_Meshes.ts
	   :start-after: //! [mesh_data_polyline]
	   :end-before: //! [mesh_data_polyline]

.. image:: images/viewing_geometry_meshes_2.png

*Polyline mesh instance*

Point data contains an array of floating-point data describing the points and is defined by calling :ref:`addPoints()  <api_ref/viewing/classes/Communicator.Meshdata:addpoints>`. 

``createPointMeshData`` returns a ``MeshData`` object representing the points at the coordinates (0,0,0), (0,1,0), (1,0,0):

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Geometry_Meshes.ts
	   :start-after: //! [mesh_data_point]
	   :end-before: //! [mesh_data_point]

.. image:: images/viewing_geometry_meshes_3.png

*Point mesh instance*


Create meshData
================

The code snippet below creates a function which generates :doc:`MeshData  </api_ref/viewing/classes/Communicator.Meshdata>` for a cube. We will use this function to create three cube instances. 

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Geometry_Meshes.ts
	   :start-after: //! [mesh_create_meshdata]
	   :end-before: //! [mesh_create_meshdata]


Create mesh
===========

Below we use ``createCubeMeshData`` to create a :doc:`MeshData </api_ref/viewing/classes/Communicator.Meshdata>` object. We then use the ``MeshData`` to create a mesh. The :ref:`createMesh() <api_ref/viewing/classes/Communicator.Model:createmesh>` function returns a :ref:`MeshId  <api_ref/viewing/modules/Communicator:meshid>` which will be used to instantiate the mesh.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Geometry_Meshes.ts
	   :start-after: //! [mesh_create_meshId]
	   :end-before: //! [mesh_create_meshId]


MeshInstanceData
================

:doc:`MeshInstanceData </api_ref/viewing/classes/Communicator.MeshInstanceData>` is an object representing a mesh instance. This class allows for specifying properties of a mesh instance. Examples of instance properties that can be set are :doc:`color </api_ref/viewing/classes/Communicator.Color>` and transformation :doc:`matrix  </api_ref/viewing/classes/Communicator.Matrix>`. The function :ref:`createMeshInstance() <api_ref/viewing/classes/Communicator.Model:createmeshinstance>` takes a ``MeshInstanceData`` object and returns a :ref:`NodeId <api_ref/viewing/modules/Communicator:nodeid>` that references that instance.


NodeId
======

A :ref:`NodeId <api_ref/viewing/modules/communicator:nodeid>` is a number that references an assembly tree node. To get the type of node referenced by a ``NodeId``, you can use the :ref:`getNodeType()  <api_ref/viewing/classes/Communicator.Model:getnodetype>` function. A ``NodeId`` can be used to interact with, and retrieve properties about a node. For example, the ``NodeId`` can be used to: get the parent node's ``NodeId``, get the node's matrix, etc.


Create mesh instance
====================

The following code uses the mesh we created :ref:`here <api_ref/viewing/modules/Communicator:createmeshdata>` to instance the cube in the scene. The :ref:`createMeshInstance() <api_ref/viewing/classes/Communicator.Model:createmeshinstance>` function returns a :ref:`NodeId <api_ref/viewing/modules/communicator:nodeid>` that can be used to reference the instance.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Geometry_Meshes.ts
	   :start-after: //! [mesh_create_meshinstance]
	   :end-before: //! [mesh_create_meshinstance]
	   
.. image:: images/viewing_geometry_meshes_4.png

*Cube mesh instance*

In the snippet below we create another mesh instance in the scene. Note that the same :ref:`MeshId  <api_ref/viewing/modules/Communicator:meshid>` is used. A translation is also applied to move the cube along the X axis.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Geometry_Meshes.ts
	   :start-after: //! [mesh_create_meshinstance_2]
	   :end-before: //! [mesh_create_meshinstance_2]

.. image:: images/viewing_geometry_meshes_5.png

*Second cube mesh instance*

The following code snippet will create a third cube mesh instance. Note that for the previous two cubes the same :ref:`MeshId <api_ref/viewing/modules/Communicator:meshid>` was used. In this snippet, we create a new ``MeshId``. 

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Geometry_Meshes.ts
	   :start-after: //! [mesh_create_meshinstance_3]
	   :end-before: //! [mesh_create_meshinstance_3]

.. image:: images/viewing_geometry_meshes_6.png

*Third cube mesh instance*


Replacing meshes
================

Using the :ref:`replaceMesh() <api_ref/viewing/classes/Communicator.Model:replacemesh>` function, we can change the :doc:`MeshData </api_ref/viewing/classes/Communicator.Meshdata>` for all instances of a mesh. Here, we replace the ``MeshData`` for the first two cubes that we instanced. The new ``MeshData`` created is a smaller cube. In the scene, there will now be one large cube and two smaller cubes. Note that replacing mesh data for dynamically created meshes works the same as replacing mesh data loaded from a SC model.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Geometry_Meshes.ts
	   :start-after: //! [mesh_replace_meshdata]
	   :end-before: //! [mesh_replace_meshdata]

.. image:: images/viewing_geometry_meshes_7.png

*One large cube, two smaller cubes*


Level of detail (LOD)
=====================

Utilizing a lower level of detail for a mesh will reduce the geometric complexity of its instance. This is available for models that have either been converted from BREP data, or authored with mesh levels. Additionally, LODs must be authored before the model is loaded. LODs do not exist for models that have been authored in the viewer. The default mesh level can be set with the parameter :ref:`defaultMeshLevel <api_ref/viewing/interfaces/Communicator.WebViewerConfig:defaultmeshlevel>` when the viewer is started.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Geometry_Meshes.ts
	   :start-after: //! [mesh_set_lod]
	   :end-before: //! [mesh_set_lod]


Miscellaneous
=============

* There is no way to save meshes that are authored in the web viewer to a file.
* Meshes authored in the web viewer are generally used for geometry that cannot be created in advance or is not meant to be part of the model file.
* When interacting with meshes once a model is loaded, there is no difference between dynamically created meshes and ones loaded from a SC model.
