/*------------------------------------------------------------- * This example demonstrates the use of the pick filter * callback to implement a top level selection policy. * That is, always select the top most group beneath the * selection node, rather than selecting the actual * shape that was picked. *------------------------------------------------------------*/ # include <windows.h> #include <Inventor/SoDB.h> #include <Inventor/SoInput.h> #include <Inventor/SoPath.h> #include <Inventor/SoPickedPoint.h> #include <Inventor/Win/SoWin.h> #include <Inventor/Win/viewers/SoWinExaminerViewer.h> #include <Inventor/actions/SoBoxHighlightRenderAction.h> #include <Inventor/nodes/SoSelection.h> // Pick the topmost node beneath the selection node SoPath * pickFilterCB(void *, const SoPickedPoint *pick) { // See which child of selection got picked SoPath *p = pick->getPath(); int i; for (i = 0; i < p->getLength() - 1; i++) { SoNode *n = p->getNode(i); if (n->isOfType(SoSelection::getClassTypeId())) break; } // Copy 2 nodes from the path: // selection and the picked child return p->copy(i, 2); } int main(int, char **argv) { // Initialization HWND mainWindow = SoWin::init(argv[0]); // Open the data file SoInput in; char *datafile = "../data/parkbench.iv"; if (! in.openFile(datafile)) { fprintf(stderr, "Cannot open %s for reading./n", datafile); exit(-1); } // Read the input file SoNode *n; SoSeparator *sep = new SoSeparator; while ((SoDB::read(&in, n) != FALSE) && (n != NULL)) sep->addChild(n); // Create two selection roots - one will use the pick filter. SoSelection *topLevelSel = new SoSelection; topLevelSel->addChild(sep); topLevelSel->setPickFilterCallback(pickFilterCB); SoSelection *defaultSel = new SoSelection; defaultSel->addChild(sep); // Create two viewers, one to show the pick filter for top level // selection, the other to show default selection. SoWinExaminerViewer *viewer1 = new SoWinExaminerViewer(mainWindow); viewer1->setSceneGraph(topLevelSel); viewer1->setGLRenderAction(new SoBoxHighlightRenderAction()); viewer1->redrawOnSelectionChange(topLevelSel); viewer1->setTitle("Top Level Selection"); #ifdef WIN32 // Under WINxx, creating an Inventor component (a viewer in this // case) with no parent is not supported. Under UNIX/X/Motif a // top level shell would be automatically created to be the parent, // but here we need to create a simple window ourselves. HWND hwnd; RECT rect; GetWindowRect( mainWindow, &rect ); hwnd = CreateWindow("button", "", WS_OVERLAPPEDWINDOW | BS_OWNERDRAW, rect.right + 1, // X position rect.top, // Y position rect.right - rect.left, // Width rect.bottom - rect.top, // Height NULL, // Parent NULL, // Menu NULL,//SoWin::getInstance(), // App instance handle NULL); // Window creation data SoWinExaminerViewer *viewer2 = new SoWinExaminerViewer( hwnd ); ShowWindow( hwnd, SW_SHOW ); #else SoWinExaminerViewer *viewer2 = new SoWinExaminerViewer(); #endif viewer2->setSceneGraph(defaultSel); viewer2->setGLRenderAction(new SoBoxHighlightRenderAction()); viewer2->redrawOnSelectionChange(defaultSel); viewer2->setTitle("Default Selection"); viewer1->show(); viewer2->show(); SoWin::show(mainWindow); SoWin::mainLoop(); return 0; }