################
Geometry Handles
################

.. image:: images/geometry_handles_main.png

After you read this guide, you should know how to add handles to the scene and customize the handle geometry.


Introduction
============

Geometry handles are used to change the position matrix of parts in the scene. There are two types of transformation: translation and rotation. The handle operator adds ten default handles; three axis translation, four plane translation, and three axis rotation. One plane translation handle translates along the plane defined by the view plane normal. All other handles rotate or translate around the X, Y, or Z axis.

The handle operator is used to interact with the handles in the scene. It listens for handle events and transforms parts accordingly. It also provides an API for interfacing with the handles. The API can be used for adding handles at a position, setting which nodes are moved by the handles, transforming world space points as the handles are moved, setting the handle size scalar, adding handles oriented along an arbitrary vector, and customizing the geometry that is displayed for the handles.


Handle operator
===============

Get the handle operator
.......................

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

	
Handle placement position
.........................

The following code assumes that a face has been selected. For brevity, we will omit checking for a null selection item.

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

To position the handles at the center of the bounding box for the selected parts, we can use the :ref:`addHandles() <api_ref/viewing/classes/Communicator.Operator.HandleOperator:addhandles>` function, and provide an array of node IDs. 

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

To position the handles at a world space coordinate, the add handles function can be used with the optional position parameter added. If a position is explicitly provided, the node ids can optionally be added with the :ref:`setNodeIds() <api_ref/viewing/classes/Communicator.Operator.HandleOperator:setnodeids>` function.

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

	
Set node IDs
............

To set the node ids for the parts that will be moved with the handles, use the :ref:`setNodeIds() <api_ref/viewing/classes/Communicator.Operator.HandleOperator:setnodeids>` function.

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

	
Point tracking
..............

The handle operator allows world space points to be tracked and updates the position as the handles move. This can be useful if you have line markup that is attached to a position on a part. When the handles are used to move a part, you can easily keep track of the new point position, and update the line markup.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Operators_geometry_handles.ts
   :start-after: //! [handle_add_tracked_point]
   :end-before: //! [handle_add_tracked_point]
	
The index of the tracked point returned from the :ref:`addTrackedPoint() <api_ref/viewing/classes/Communicator.Operator.HandleOperator:addtrackedpoint>` function can be used to retrieve the new position in the array of points returned by the :ref:`getTrackedPoints() <api_ref/viewing/classes/Communicator.Operator.HandleOperator:gettrackedpoints>` function. The ``getTrackedPoints()`` function can be called after receiving a handle event to keep any markup

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Operators_geometry_handles.ts
   :start-after: //! [handle_get_tracked_point]
   :end-before: //! [handle_get_tracked_point]
   
	
Handle scale
............

To change the handle scale, use the :ref:`setHandleSize() <api_ref/viewing/classes/Communicator.Operator.HandleOperator:sethandlesize>` function. This must be set before the handles are added to the scene.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Operators_geometry_handles.ts
   :start-after: //! [handle_scale]
   :end-before: //! [handle_scale]
	
	
Custom handle configuration
...........................

Instead of using the default handle configuration, you can add your own set of handles to the scene. For example, if you want to move along the X and Y axis only, you can add just the X axis, Y axis, and Z plane handles.

.. image:: images/geometry_handles_custom_handle.png
	
.. literalinclude:: /../../applications/client/docs/PG_Viewing_Operators_geometry_handles.ts
   :start-after: //! [handle_configuration]
   :end-before: //! [handle_configuration]

**NOTE:** Notice the last parameter in :ref:`addPlaneTranslationHandle <api_ref/viewing/classes/Communicator.Operator.HandleOperator:addplanetranslationhandle>`, ``new Communicator.Point3(-1,0,0))``. This is a position vector that can control the orientation of the handle. Since the axis handles are symmetrical and are drawn along the axis, there is no need to specify a position vector. The rotate handles and plane translation handles however, require a position vector to place them in the default orientation. The pictures below show the default handles with and without the position vector. For the X, Y and Z axis, the position vector used in the default configuration is inverse Y, inverse Z, and inverse X respectively.

.. image:: images/geometry_handles_custom_handle1.png

.. image:: images/geometry_handles_custom_handle2.png


Custom handle geometry
......................

The geometry that gets used by default for the axis, plane, view plane, and rotate handles can be set using the following functions:

* :ref:`setAxisMeshData() <api_ref/viewing/classes/Communicator.Operator.HandleOperator:setaxismeshdata>`
* :ref:`setPlaneMeshData() <api_ref/viewing/classes/Communicator.Operator.HandleOperator:setplanemeshdata>`
* :ref:`setViewPlaneMeshData() <api_ref/viewing/classes/Communicator.Operator.HandleOperator:setviewplanemeshdata>`
* :ref:`setRotateMeshData() <api_ref/viewing/classes/Communicator.Operator.HandleOperator:setrotatemeshdata>`

Each function takes a :doc:`MeshData </api_ref/viewing/classes/Communicator.MeshData>` object that represents the geometry for the X axis. The geometry will be transformed to match the normal that will be used to apply the transformation when the handles are added.

The following code replaces the axis cylindrical handles with a rectangle.

.. image:: images/geometry_handles_custom_handle_geo.png
	
.. literalinclude:: /../../applications/client/docs/PG_Viewing_Operators_geometry_handles.ts
   :start-after: //! [handle_custom_geometry]
   :end-before: //! [handle_custom_geometry]
   

Custom handle axis
..................

.. literalinclude:: /../../applications/client/docs/PG_Viewing_Operators_geometry_handles.ts
   :start-after: //! [handle_custom_axis]
   :end-before: //! [handle_custom_axis]
   
.. image:: images/geometry_handles_custom_handle_axis.png


Handle events
.............

The following callbacks contain information about drag events as they occur. This includes the type of handle event (translate vs rotate), the node ids for the parts that are transformed, and the matrices for those nodes (initial matrix for :ref:`handleEventStart <api_ref/viewing/interfaces/Communicator.CallbackMap:handleeventstart>`, initial and new matrix for :ref:`handleEvent <api_ref/viewing/interfaces/Communicator.CallbackMap:handleevent>` and :ref:`handleEventEnd <api_ref/viewing/interfaces/Communicator.CallbackMap:handleeventend>`)

* ``handleEventStart`` – triggered when the handle operator begins to drag the handles.
* ``handleEvent`` – triggered on each drag update.
* ``handleEventEnd`` – triggered when the drag event has finished.

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