==========================
Selection and Highlighting
==========================

In many applications, a user needs to be able to select an object in a 3D scene in order to interact with it in some way. Typically, it is desirable to provide some kind of visual feedback to the user after the selection is made. |HPSNOW| provides a highlighting mechanism that can be used to provide this feedback. Selection and highlighting operate independently - that is - you can select an object without highlighting it, and you can highlight an object without selecting it. 

This tutorial will demonstrate how to select and highlight geometry in a |HPSNOW| scene. It is assumed that you have a scene set up with a view hierarchy and a segment available to accept the geometry and attributes that will be demonstrated below. If you don't have such a scene, you can use the either the ``mfc_sandbox`` or the ``wpf_sandbox`` as a framework for running through the tutorial.


4.1 Building a Highlight Style
==============================

A style is a collection of attributes that are applied to an object as a set. The first step toward creating a selection highlighting mechanic is to create a :doc:`style </prog_guide/0403_styles>` that will indicate the object is selected. For example, you could define a style that will color the selected object yellow with red edges when selected. Styles are referred to by a name that you provide upon creation. Additionally, all styles live in a :doc:`portfolio </prog_guide/0401_portfolios_introduction>`.

The code snippet below demonstrates how to create a style that makes the faces of an object yellow with red edges:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00730_tutorial4_1.cpp
		   :start-after: //! [create_style]
		   :end-before: //! [create_style]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00730_tutorial4_1.cs
		   :start-after: //! [create_style]
		   :end-before: //! [create_style]
		   
To execute this code, first load a model into the sandbox (using *File > Load* is fine). In this case we have loaded *samples/data/cube.hsf*.

.. image:: images/04/cube.png

*Cube demonstrating use of NamedStyleDefinition to make faces yellow and edges red.*

.. _0402:

4.2 Using a selection operator
==============================

Consider the simple scene below:

.. image:: images/04/4.2.a.png

*A shell composed of a few triangles*

To begin an interactive selection, you must instantiate an operator and make it active to the ``HPS::View`` object. For applicatons that host multiple views, be aware that a single instance of an operator can only be attached to one view. For this example, we will use the ``HPS::HighlightOperator`` to select the shell pictured in the image above. See the code snippet below for how it is activated. This is a pre-built operator available as part of the |HPSNOW| library and operates upon a simple mouse click.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00730_tutorial4_1.cpp
		   :start-after: //! [attach_operator]
		   :end-before: //! [attach_operator]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00730_tutorial4_1.cs
		   :start-after: //! [attach_operator]
		   :end-before: //! [attach_operator]
		   
.. image:: images/04/4.2.b.png

*The highlight style is activated on the shell, applying the highlight style when you click it*

Note that you are not required to use one of the pre-built operators. You can define your own custom operator with any type of functionality as long as it derives from the ``HPS::Operator`` base class. For more information on custom operators, see the :doc:`custom operators </prog_guide/0602_custom_operators>` section of the Programming Guide.

Whatever type of operator you end up using, note that the operator will remain active until it is explicitly detached. Multiple operators can also be active on a ``HPS::View`` simultaneously, and events are passed between each of them until they are consumed.

Selecting By Area
-----------------

Frequently, it is desirable for the user to be able to perform a box-selection by dragging the mouse over the scene. In this case, there is no difference in the application's logic - you simply use a different type of operator. An operator is provided for this purpose, the ``HPS::HighlightAreaOperator``. The ``HPS::HighlightAreaOperator`` will select any object within or partially within the box you draw.


.. _0403:

4.3 Processing Selection Results
================================

Selection results are always based around :ref:`keys <prog_guide/0101_database:keys>`. When performing a selection, |HPSNOW| will return a ``HPS::SelectionResults`` object which contains the keys of any objects that were found by the operator. After obtaining the key, you can then use it to do any additional processing. Obtain the key to the selected item or items in the following way:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00730_tutorial4_1.cpp
		   :start-after: //! [processing_selection]
		   :end-before: //! [processing_selection]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00730_tutorial4_1.cs
		   :start-after: //! [processing_selection]
		   :end-before: //! [processing_selection]
		   
		   
Performing Selection Programmatically
-------------------------------------

If you want to perform a selection programmatically, without the use of an operator, please see the :doc:`selection section </prog_guide/0603_selection>` of the Programming Guide for a detailed explanation.


4.4 Summary
===========

These examples have all dealt with selection and highlighting as part of a single procedure in response to a selection event. Note that you can also select an object without highlighting it by using alternate version of the operators. For example, instead of using ``HPS::HighlightOperator`` or ``HPS::HighlightAreaOperator``, you would simply use ``HPS::SelectOperator`` or ``HPS::SelectAreaOperator``.

Highlighting an object without having to select it first can also be done by simply applying a style directly. This is discussed in the :doc:`styles </prog_guide/0403_styles>` section of the Programming Guide.
