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:
SoExtSelection::NO_LASSO : No lasso is drawn and the behavior is the same as for SoSelection( C++ | Java | .NET ).
SoExtSelection::LASSO: A series of connected lines is drawn following the mouse motion. When the mouse button is released, the first point and the last point of this set of lines are connected forming a polygon.
SoExtSelection::RECTANGLE: A rectangle is drawn following the mouse motion as a rubberband.
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.
SoExtSelection::FULL_BBOX: Selects objects whose bounding box is completely contained by the lasso.
SoExtSelection::PART_BBOX: Selects objects whose bounding box intersects the lasso (or is contained by the lasso).
SoExtSelection::FULL: Selects objects whose geometry is completely contained by the lasso.
SoExtSelection::PART: Selects objects whose geometry intersects the lasso (or is contained by the lasso).
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:
SoExtSelection::ALL_SHAPES: All shapes surrounded by the lasso and between the near plane and the far plane of the view volume (in other words, even hidden shapes) are selected.
SoExtSelection::VISIBLE_SHAPES: Unlike the previous mode, only visible shapes surrounded by the lasso are selected. This mode can be used only if the lasso policy is FULL or PART. This mode provides better performance than the previous mode.
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.9. Retrieving details on point shapes
SoExtSelection *extSelection = new SoSelection; extSelection->setPointFilterCallback(soExtSelectionPointCB); ... extSelection->addChild(new SoPointSet); ... ... SbBool soExtSelectionPointCB(void *userData, SoCallbackAction *action, const SoPrimitiveVertex *v) { const SoDetail *detail = v->getDetail(); int coordIndex= ((SoPointDetail*)detail)->getCoordinateIndex(); ... // Specific treatment for point coordIndex of the selected // SoPointSet shape. ... return FALSE; // Continue examining next primitives. }
SoExtSelection extSelection = new SoExtSelection(); extSelection.PointFilterCallback = new SoExtSelection.PointCB(soExtSelectionPointCB); //... extSelection.AddChild(new SoPointSet()); //... bool soExtSelectionPointCB(SoCallbackAction action, ref SoPrimitiveVertex v) { SoDetail detail = v.Detail; int coordIndex = ((SoPointDetail) detail).GetCoordinateIndex(); ... // Specific treatment for point coordIndex of the selected // SoPointSet shape. ... return false; // Continue examining next primitives }
Example 10.10. How to use SoExtSelection
The following example is extracted from the file:
$OIVHOME/src/Inventor/examples/Features/
ExtSelection/extSelection.cxx.
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; }
// 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();
// 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:
SoExtSelection::setStartSelectionCallback()
SoExtSelection::setMovingSelectionCallback()
SoExtSelection::setEndSelectionCallback()
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.