HOOPS Visualize Documentation

< Tutorial index

CORE GRAPHICS TUTORIALS

4 Selection and Highlighting

Tutorial 4: 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. HOOPS Visualize 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 Visualize 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 style 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 portfolio.

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

[snippet t.4.1.a]
mySegmentKey.GetPortfolioControl().Push(myPortfolio);
NamedStyleDefinition myHighlightStyle = myPortfolio.DefineNamedStyle("myStyle", Database::CreateRootSegment());
myHighlightStyle.GetSource().GetMaterialMappingControl().SetFaceColor(RGBAColor(1.0f, 1.0f, 0.0f));
myHighlightStyle.GetSource().GetMaterialMappingControl().SetEdgeColor(RGBAColor(1.0f, 0.0f, 0.0f));
myHighlightStyle.GetSource().GetVisibilityControl().SetFaces(true).SetEdges(true);
mySegmentKey.GetStyleControl().PushNamed("myStyle");
PortfolioKey myPortfolio = Database.CreatePortfolio();
mySegmentKey.GetPortfolioControl().Push(myPortfolio);
NamedStyleDefinition myHighlightStyle = myPortfolio.DefineNamedStyle("myStyle", Database.CreateRootSegment());
myHighlightStyle.GetSource().GetMaterialMappingControl().SetFaceColor(new RGBAColor(1.0f, 1.0f, 0.0f));
myHighlightStyle.GetSource().GetMaterialMappingControl().SetEdgeColor(new RGBAColor(1.0f, 0.0f, 0.0f));
myHighlightStyle.GetSource().GetVisibilityControl().SetFaces(true).SetEdges(true);
mySegmentKey.GetStyleControl().PushNamed("myStyle");

4.2 Using a selection operator

Consider the simple scene below:

[figure 4.2.a] A shell composed of a few triangles

To begin an interactive selection, you must instantiate an operator and make it active to the 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 HighlightOperator to select the shell pictured in the image above. This is a pre-built operator available as part of the Visualize library and operates upon a simple mouse click. Note that all operators work at the entity level only.

[snippet t.4.2.a]
// Get a reference to your View object. In this case I'm using the View from the mfc_sandbox application.
View myView = GetCanvas().GetAttachedLayout().GetAttachedView();
HighlightOperator* myHighlightOperator = new HighlightOperator();
// operator becomes 'active' after pushing it onto the operator stack
myView.GetOperatorControl().Push(myHighlightOperator);
// set the highlight style, which we previously defined
HighlightOptionsKit hok("myHighlightStyle");
myHighlightOperator->SetHighlightOptions(hok);
// Get a reference to your View object. In this case I'm using the View from the mfc_sandbox application.
View myView = GetCanvas().GetAttachedLayout().GetAttachedView();
HighlightOperator myHighlightOperator = new HighlightOperator();
// operator becomes 'active' after pushing it onto the operator stack
myView.GetOperatorControl().Push(myHighlightOperator);
// set the highlight style, which we previously defined
HighlightOptionsKit hok = new HighlightOptionsKit("myHighlightStyle");
myHighlightOperator.SetHighlightOptions(hok);
[figure 4.2.b] The highlight style is activated on the shell after selection

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 Operator base class. For more information on custom operators, see section 6.2 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 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 HighlightAreaOperator. The HighlightAreaOperator will select any object within or partially within the box you draw.

4.3 Processing selection results

Selection results are always based around keys. When performing a selection, Visualize will return a 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:

[snippet t.4.3]
SelectionResults selectionResults = myHighlightOperator->GetActiveSelection();
SelectionResultsIterator it = selectionResults.GetIterator();
while (it.IsValid())
{
SelectionItem selectionItem = it.GetItem();
Key key;
if (selectionItem.ShowSelectedItem(key))
{
if (key.Type() == Type::ShellKey)
{
ShellKey shellKey(key);
// do something with this object
}
}
it.Next();
}
$processing_selection

4.4 Performing selection programmatically

If you want to perform a selection programmatically, without the use of an operator, please see section 6.3 of the Programming Guide for a detailed explanation.

4.5 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 HighlightOperator or HighlightAreaOperator, you would simply use SelectOperator or 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 Core Graphics Programming Guide section 4.3.