10.8. Extended Selection

Figure 10.8. Extended selection node class


An SoExtSelection( C++ | Java | .NET )node, like the node SoSelection( C++ | Java | .NET )it is derived from, is typically inserted near the top of the scene graph. It offers the same picking capabilities as the SoSelection( C++ | Java | .NET ) node (see the section called “SoSelection”, pp. 260-261 of The Inventor Mentor) but also extends these capabilities by allowing the user to select several objects at the same time. When a left mouse button press occurs, a lasso is displayed and the shape of the lasso follows the mouse motion; as soon as the mouse button is released, all shapes surrounded by the lasso are selected and the lasso is erased. The SoExtSelection( C++ | Java | .NET ) node maintains the paths of selected shapes the same way as SoSelection( C++ | Java | .NET ).

Different shapes are available to represent the lasso:

The lassoPolicy field allows you to chose different ways of determining if a shape is selected. Some choices offer higher performance, others offer higher accuracy.

The policies that use the bounding box computation to determine shape selection are more efficient than the others, but also less accurate.

The lassoMode field allows the user to specify whether shapes that are hidden by other shapes can be selected:

In some cases, it is useful to retrieve a detail object (see SoDetail( C++ | Java | .NET )and derived classes) which contains additional information about the selected shape. A system of callbacks using the methods setTriangleFilterCallback(), setLineSegmentFilterCallback(), and setPointFilterCallback() allows access to this information. The callback function can return FALSE in order to examine the next detail (selected primitive) of the shape, or TRUE to examine the next shape.

The code to retrieve information about point shapes (SoPointSet( C++ | Java | .NET ) ,SoMarkerSet( C++ | Java | .NET ) , etc.) could be as follows:


Example 10.10.  How to use SoExtSelection

Rectangle representation for the lasso

The following example is extracted from the file:

$OIVHOME/src/Inventor/examples/Features/

ExtSelection/extSelection.cxx.


C++
int
main(int argc, char **argv)
{
 ...
 // Creation and initialization of
 // the lasso as the root of the
 // scene graph.
 // The selection policy is
 // SINGLE, the shape of the lasso
 // is a rectangle and the color
 // of the lasso is green
 root = new SoExtSelection;
 root->ref();
 root->setLassoColor(SbColor (0, 1, 0));
 root->policy = SoSelection::SINGLE;
 root->lassoType = SoExtSelection::RECTANGLE;
 ...
 // Building the scene graph with children under
 // the SoExSelection node.
 ...
 viewer = new SoXtExaminerViewer(myWindow);
 viewer->setSceneGraph(root);
 
 // Selected objects are highlighted with a surrounded bounding box.
 viewer->setGLRenderAction (new SoBoxHighlightRenderAction());
 
 viewer->redrawOnSelectionChange(root);
 viewer->setTitle("Selection Test");
 viewer->show();
 
 SoXt::show(myWindow);
 SoXt::mainLoop();
 return 0;
}
  

.NET
// Creation and initialization of
// the lasso as the root of the
// scene graph.
// The selection policy is
// SINGLE, the shape of the lasso
// is a lasso and the color
// of the lasso is red	
root = new SoExtSelection();
...
root.SetLassoColor(new SbColor(1, 0, 0));
root.policy.Value = SoSelection.Policies.SINGLE;
root.lassoPolicy.Value = SoExtSelection.LassoPolicies.PART;  
root.lassoType.Value = SoExtSelection.LassoTypes.LASSO;
...
viewer = new SoWinExaminerViewer(this, "", true, 
	                             SoWinFullViewer.BuildFlags.BUILD_ALL, 
		                         SoWinViewer.Types.BROWSER);
viewer.SetSceneGraph(root);
// Selected objects are highlighted with a surrounded bounding box.
viewer.SetGLRenderAction(new SoBoxHighlightRenderAction());

viewer.RedrawOnSelectionChange(root);
viewer.SetTitle("Selection Test");

viewer.Show();
viewer.ViewAll();

Java
// Creation and initialization of
// the lasso as the root of the
// scene graph.
// The selection policy is
// SINGLE, the shape of the lasso
// is a lasso and the color
// of the lasso is red	
selectionRoot = new SoExtSelection();
selectionRoot.useOverlay(true);
selectionRoot.setLassoWidth (2);
selectionRoot.setLassoColor (new SbColor (0, 1, 0));
//    selectionRoot.setOverlayLassoPattern ((short)0xE0E0);
//    selectionRoot.animateOverlayLasso (true);
selectionRoot.policy.setValue(SoSelection.Policies.SINGLE);
selectionRoot.lassoType.setValue(SoExtSelection.LassoTypes.NOLASSO);
selectionRoot.lassoPolicy.setValue(SoExtSelection.LassoPolicies.PART);

// Add an event callback so we can receive key press events
SoEventCallback myEventCB = new SoEventCallback();
myEventCB.addEventCallback("com.openinventor.inventor.events.SoKeyboardEvent",
			   new MyKeyPressCB(), selectionRoot);

...
// Building the scene graph with children under
// the SoExSelection node.
...

// Create a viewer for viewing the scene
SwSimpleViewer myViewer = new SwSimpleViewer(SwSimpleViewer.EXAMINER) ;
myViewer.getArea().setGLRenderAction(new SoBoxHighlightRenderAction());
myViewer.getArea().redrawOnSelectionChange(selectionRoot);
myViewer.getArea().setSceneGraph(selectionRoot);

panel.add(myViewer);
add(panel);

The fast edit mode allows using the fast edit features from the SoSeparator( C++ | Java | .NET ) node. It enables Open Inventor to cache the frame buffer and the depth buffer in order to edit a sub scene-graph without re-rendering the full scene graph. Saving the buffers and restoring them instead of re-rendering the scene graph is very efficient for large scenes that may be difficult to render at interactive frame rates. This mode is used in the SoExtSelection( C++ | Java | .NET ) node in order to perform fast animation for the lasso and optionally fast rendering of a custom scene graph.

Enable or disable this feature by using the method useFastEdit(). By default this feature is disabled.

Another advantage of this mode is that it does not require high-end hardware features like overlay planes to render selection graphics at interactive rates. Also, unlike the default mode, it does not require GDI functions (which breaks Aero on Microsoft Windows Vista).

Note: See the section called “Fast Editing” for more information about fast editing.

The selection callbacks are called when the selection begins, moves and ends. They can be used for example to do specific 2D rendering over the scene or doing regular selection of objects in the scene. The callback function will be called with the cursor position in pixels and also the corresponding position in 3D space.

Use the following methods to set the selection callbacks:

You have to return TRUE if you handle the event or FALSE if you want to apply the default behavior from the SoSelection( C++ | Java | .NET ) class.

In fastEdit mode you can use the method setSelectionSceneGraph to specify a scene graph to be rendered as custom selection feedback while a selection operation is active. You can also modify this scene graph dynamically during a selection operation, using the selection callbacks.

An example of the new behavior is available in the directory:

$OIVHOME/src/Inventor/examples/Features/FastSelection

This demo shows several types of custom selection feedback like a ruler and an aperture. The geometry used in this example is huge on purpose in order to show the rendering performance improvement when the fast edit feature is used.