##################
Instance Modifiers
##################

:doc:`InstanceModifiers </api_ref/viewing/enums/Communicator.instancemodifier>` allow you to activate certain special behaviors generally related to drawing the scene. They are all activated with a single function for convenience. ``InstanceModifiers`` can serve very different purposes.


Setting and unsetting
=====================

An :doc:`InstanceModifiers </api_ref/viewing/enums/Communicator.instancemodifier>` can be set with the :ref:`setInstanceModifier <api_ref/viewing/classes/Communicator.Model:setinstancemodifier>` function by specifying the ``InstanceModifier`` type, the :ref:`NodeIds <api_ref/viewing/modules/Communicator:nodeid>` it should apply to and passing "true" as the third parameter.

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

Similar to the :ref:`setNodesVisibility() <api_ref/viewing/classes/Communicator.Model:setnodesvisibility>` behavior (information about node visibility :ref:`here <prog_guide/viewing/model_attributes/visibility:toc_node_visibility>`) this function will "push" the An :doc:`InstanceModifiers </api_ref/viewing/enums/Communicator.instancemodifier>` activation all the way to the leaf nodes of the model tree (e.g. if you are applying an ``InstanceModifier`` to the root node of the model tree it will be active for all nodes in the model).

To deactivate an ``InstanceModifier`` simply call the same function but with "false" as the final parameter:

.. literalinclude:: /../../applications/client/docs/PG_Viewing_instancemodifiers.ts
	   :start-after: //! [webviewer_instancemodifierunset]
	   :end-before: //! [webviewer_instancemodifierunset]
	
There is currently no way to query if an ``InstanceModifier`` is active on a node. You will need to keep track of that yourself.


AlwaysDraw
==========

If set, the instance will be drawn before other instances and will not be culled to reach the target frame rate. This can be useful if you want to ensure that a piece of geometry stays visible (e.g. during an editing operation) especially if the bounding box for that geometry is small relative to other objects and so the object would ordinarily be culled during interaction if the scene is complex.


DoNot modifiers
===============

** :ref:`DoNotCut <api_ref/viewing/enums/Communicator.InstanceModifier:donotcut>` **

Geometry with the ``DoNotCut`` instance modifier set will not be affected when cutting planes are active. In general, you might want to activate those settings on geometry that is not part of the main model like widgets or 3D annotations.


** :ref:`DoNotExplode <api_ref/viewing/enums/Communicator.InstanceModifier:donotexplode>` **

Geometry with the ``DoNotExplode`` instance modifier set will not be affected when the model is exploded or cutting planes are active. In general, you might want to activate those settings on geometry that is not part of the main model like widgets or 3D annotations.


** :ref:`DoNotLight <api_ref/viewing/enums/Communicator.InstanceModifier:donotlight>` **

If set, the instance will not be lit. We are using this setting internally when rendering PMI text that should not be shaded.

.. image:: images/instance_modifiers_pmi_donotlight.png

*PMI drawn with the DoNotLight InstanceModifier set. No shading is applied to the text.*


** :ref:`DoNotOutlineHighlight <api_ref/viewing/enums/Communicator.InstanceModifier:donotoutlinehighlight>` **

If set, the instance will not be outlined when highlighted. We are using this setting internally to avoid outlining PMI text while highlighting.


** :ref:`DoNotSelect <api_ref/viewing/enums/Communicator.InstanceModifier:donotselect>` **

If set, the instance will not be selectable. Excluding geometry from selection or making it only selectable in certain circumstances can be useful for geometry that is not part of the main model like handles or other types of widgets.


** :ref:`DoNotUseVertexColors <api_ref/viewing/enums/Communicator.InstanceModifier:donotusevertexcolors>` **

If set, the instance will not use the mesh's per-vertex colors. This can be useful if you want to temporarily force a mesh to be drawn in a certain color.


** :ref:`DoNotXRay <api_ref/viewing/enums/Communicator.InstanceModifier:donotxray>` **

If set, the instance will not be affected by :ref:`DrawMode.XRay <api_ref/viewing/enums/Communicator.DrawMode:xray>`. This ``InstanceModifier`` would generally be applied to geometry that is not part of the main model.


** :ref:`ExcludeBounding <api_ref/viewing/enums/Communicator.InstanceModifier:excludebounding>` **

If set, the instance will not be included in bounding calculations. This ``InstanceModifier`` would generally be applied to geometry that is not part of the main model and therefore should be ignored for bounding calculations.


** :ref:`OverrideSceneVisibility <api_ref/viewing/enums/Communicator.InstanceModifier:overridescenevisibility>` **

If set, then scene visibility (global visibility for faces/edges/points) will not be applied to the specified nodes.

.. image:: images/instance_modifiers_wireframe.png

*A model in wireframe rendering mode with the ``OverrideSceneVisiblity`` instance modifier set for one of its parts*



** :ref:`ScreenOriented <api_ref/viewing/enums/Communicator.InstanceModifier:screenoriented>` **

If set, the instance will be oriented such that the cardinal axes of object space are aligned with the cardinal axes of screen space. In practice, that means that the insertion point of the geometry will still move and rotate with the camera the geometry itself will not rotate. Use this ``InstanceModifier`` for geometry you want to display billboarded (always facing the camera).



** :ref:`ScreenSpace <api_ref/viewing/enums/Communicator.InstanceModifier:screenspace>` **

If set, the instance will be oriented such that the cardinal axes of object space are aligned with the cardinal axes of screen space.

** :ref:`ScreenSpaceStretched <api_ref/viewing/enums/Communicator.InstanceModifier:screenspacestretched>` **

If set, the instance will be drawn in a space that extends from ``X = -1`` at the left side of the screen to ``X = 1`` at the right side of the screen and from ``Y = -1`` at the bottom of the screen to ``Y = 1`` at the top of the screen.

With one of those ``InstanceModifiers`` set you can essentially render your geometry in a fixed screen space location meaning that the geometry will not move with the main camera.

** :ref:`SuppressCameraScale <api_ref/viewing/enums/Communicator.InstanceModifier:suppresscamerascale>` **

If set, the instance will be drawn at the same size regardless of camera settings. We are using this ``InstanceModifier`` internally to draw the geometry handles that rotate and move with the camera like any other geometry but always retain the same size relative to the main window.

.. image:: images/instance_modifiers_geometry_handles.png

*Geometry handles drawn with the ``SuppressCameraScale`` instance modifier to ensure that they stay the same size no matter how far the main camera is zoomed in or out*
