void IfReplacer::replaceMaterials(SoNode *sceneRoot, const SoType &typeToReplace) { // Find all nodes of the given type SoSearchAction sa; sa.setType(typeToReplace); sa.setInterest(SoSearchAction::ALL); sa.apply(sceneRoot); // Replace the tail of each path with a material. To do this, we // need to apply an SoCallbackAction to the path to gather the // material components. for (int i = 0; i < sa.getPaths().getLength(); i++) { // Cast the path to a full path, just in case SoFullPath *path = (SoFullPath *) sa.getPaths()[i]; ASSERT(path->getTail()->isOfType(typeToReplace)); // The path better have at least one group above the material if (path->getLength() < 2 || ! path->getNodeFromTail(1)->isOfType(SoGroup::getClassTypeId())) continue; // Create a material node that represents the material in // effect at the tail of the path SoMaterial *newMaterial = createMaterialForPath(path); newMaterial->ref(); // Replace the tail node with that material SoGroup *parent = (SoGroup *) path->getNodeFromTail(1); parent->replaceChild(path->getTail(), newMaterial); newMaterial->unref(); } }
// doc from parent void SoFCSelection::handleEvent(SoHandleEventAction * action) { static char buf[513]; HighlightModes mymode = (HighlightModes) this->highlightMode.getValue(); const SoEvent * event = action->getEvent(); #ifdef NO_FRONTBUFFER // mouse move events for preselection if (event->isOfType(SoLocation2Event::getClassTypeId())) { // NOTE: If preselection is off then we do not check for a picked point because otherwise this search may slow // down extremely the system on really big data sets. In this case we just check for a picked point if the data // set has been selected. if (mymode == AUTO || mymode == ON) { const SoPickedPoint * pp = this->getPickedPoint(action); if (pp && pp->getPath()->containsPath(action->getCurPath())) { if (!highlighted) { if (Gui::Selection().setPreselect(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2])){ SoFCSelection::turnoffcurrent(action); SoFCSelection::currenthighlight = (SoFullPath*)action->getCurPath()->copy(); SoFCSelection::currenthighlight->ref(); highlighted = TRUE; this->touch(); // force scene redraw this->redrawHighlighted(action, TRUE); } } snprintf(buf,512,"Preselected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); getMainWindow()->showMessage(QString::fromAscii(buf),3000); } else { // picked point if (highlighted) { if (mymode == AUTO) SoFCSelection::turnoffcurrent(action); //FIXME: I think we should set 'highlighted' to false whenever no point is picked //else highlighted = FALSE; Gui::Selection().rmvPreselect(); } } } } // key press events else if (event->isOfType(SoKeyboardEvent ::getClassTypeId())) { SoKeyboardEvent * const e = (SoKeyboardEvent *) event; if (SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::LEFT_SHIFT) || SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::RIGHT_SHIFT) ) bShift = true; if (SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::LEFT_SHIFT) || SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::RIGHT_SHIFT) ) bShift = false; if (SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::LEFT_CONTROL) || SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::RIGHT_CONTROL) ) bCtrl = true; if (SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::LEFT_CONTROL) || SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::RIGHT_CONTROL) ) bCtrl = false; } // mouse press events for (de)selection else if (event->isOfType(SoMouseButtonEvent::getClassTypeId())) { SoMouseButtonEvent * const e = (SoMouseButtonEvent *) event; if (SoMouseButtonEvent::isButtonReleaseEvent(e,SoMouseButtonEvent::BUTTON1)) { //FIXME: Shouldn't we remove the preselection for newly selected objects? // Otherwise the tree signals that an object is preselected even though it is hidden. (Werner) const SoPickedPoint * pp = this->getPickedPoint(action); if (pp && pp->getPath()->containsPath(action->getCurPath())) { if (bCtrl) { if (Gui::Selection().isSelected(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString())) { Gui::Selection().rmvSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString()); } else { Gui::Selection().addSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); if (mymode == OFF) { snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); getMainWindow()->showMessage(QString::fromAscii(buf),3000); } } } else { // Ctrl if (!Gui::Selection().isSelected(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString())) { Gui::Selection().clearSelection(documentName.getValue().getString()); Gui::Selection().addSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); } else { Gui::Selection().clearSelection(documentName.getValue().getString()); Gui::Selection().addSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,0 ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); } if (mymode == OFF) { snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); getMainWindow()->showMessage(QString::fromAscii(buf),3000); } } action->setHandled(); } // picked point } // mouse release } inherited::handleEvent(action); #else // If we don't need to pick for locate highlighting, // then just behave as separator and return. // NOTE: we still have to pick for ON even though we don't have // to re-render, because the app needs to be notified as the mouse // goes over locate highlight nodes. //if (highlightMode.getValue() == OFF) { // inherited::handleEvent( action ); // return; //} // // If this is a mouseMotion event, then check for locate highlighting // if (event->isOfType(SoLocation2Event::getClassTypeId())) { // check to see if the mouse is over our geometry... SbBool underTheMouse = FALSE; const SoPickedPoint * pp = this->getPickedPoint(action); SoFullPath *pPath = (pp != NULL) ? (SoFullPath *) pp->getPath() : NULL; if (pPath && pPath->containsPath(action->getCurPath())) { // Make sure I'm the lowest LocHL in the pick path! underTheMouse = TRUE; for (int i = 0; i < pPath->getLength(); i++) { SoNode *node = pPath->getNodeFromTail(i); if (node->isOfType(SoFCSelection::getClassTypeId())) { if (node != this) underTheMouse = FALSE; break; // found the lowest LocHL - look no further } } } // Am I currently highlighted? if (isHighlighted(action)) { if (! underTheMouse) { // re-draw the object with it's normal color //if(mymode != OFF) redrawHighlighted(action, FALSE); Gui::Selection().rmvPreselect(); } else { action->setHandled(); //const SoPickedPoint * pp = action->getPickedPoint(); Gui::Selection().setPreselectCoord(pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); } } // Else I am not currently highlighted else { // If under the mouse, then highlight! if (underTheMouse) { // draw this object highlighted if (mymode != OFF) redrawHighlighted(action, TRUE); //const SoPickedPoint * pp = action->getPickedPoint(); Gui::Selection().setPreselect(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); } } //if(selected == SELECTED){ // redrawHighlighted(action, TRUE); //} //if(selectionCleared ){ // redrawHighlighted(action, FALSE); // selectionCleared = false; //} } // key press events else if (event->isOfType(SoKeyboardEvent ::getClassTypeId())) { SoKeyboardEvent * const e = (SoKeyboardEvent *) event; if (SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::LEFT_SHIFT) || SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::RIGHT_SHIFT) ) bShift = true; if (SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::LEFT_SHIFT) || SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::RIGHT_SHIFT) ) bShift = false; if (SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::LEFT_CONTROL) || SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::RIGHT_CONTROL) ) bCtrl = true; if (SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::LEFT_CONTROL) || SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::RIGHT_CONTROL) ) bCtrl = false; } // mouse press events for (de)selection (only if selection is enabled on this node) else if (event->isOfType(SoMouseButtonEvent::getClassTypeId()) && selectionMode.getValue() == SoFCSelection::SEL_ON) { SoMouseButtonEvent * const e = (SoMouseButtonEvent *) event; if (SoMouseButtonEvent::isButtonReleaseEvent(e,SoMouseButtonEvent::BUTTON1)) { //FIXME: Shouldn't we remove the preselection for newly selected objects? // Otherwise the tree signals that an object is preselected even though it is hidden. (Werner) const SoPickedPoint * pp = this->getPickedPoint(action); if (pp && pp->getPath()->containsPath(action->getCurPath())) { if (bCtrl) { if (Gui::Selection().isSelected(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString())) { Gui::Selection().rmvSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString()); } else { Gui::Selection().addSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); if (mymode == OFF) { snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); getMainWindow()->statusBar()->showMessage(QString::fromAscii(buf),3000); } } } else { // Ctrl if (!Gui::Selection().isSelected(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString())) { Gui::Selection().clearSelection(documentName.getValue().getString()); Gui::Selection().addSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); } else { Gui::Selection().clearSelection(documentName.getValue().getString()); Gui::Selection().addSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,0 ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); } if (mymode == OFF) { snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); getMainWindow()->statusBar()->showMessage(QString::fromAscii(buf),3000); } } action->setHandled(); } // picked point } // mouse release } // Let the base class traverse the children. if (action->getGrabber() != this) inherited::handleEvent(action); #endif }
virtual void apply(SoNode* node) { if (!headlightRot) { SoSearchAction sa; sa.setNode(viewer->getHeadlight()); sa.apply(viewer->getSceneRoot()); SoFullPath* fullPath = (SoFullPath*) sa.getPath(); if (fullPath) { SoGroup *group = (SoGroup*) fullPath->getNodeFromTail(1); headlightRot = (SoRotation*) group->getChild(0); if (!headlightRot->isOfType(SoRotation::getClassTypeId())) headlightRot = 0; } } const SbViewportRegion vpr = getViewportRegion(); const SbVec2s & size = vpr.getViewportSizePixels(); const int width = size[0]; const int height = size[1]; const int vpsize = width / 2; SoCamera * camera = viewer->getCamera(); const SbVec3f position = camera->position.getValue(); const SbRotation orientation = camera->orientation.getValue(); const float nearplane = camera->nearDistance.getValue(); const float farplane = camera->farDistance.getValue(); camera->enableNotify(false); // Front View rotateCamera(SbRotation(SbVec3f(0,0,1), M_PI)); SbViewportRegion vp; vp.setViewportPixels(SbVec2s(0, height-width/2), SbVec2s(width, width/2) ); setViewportRegion(vp); SoGLRenderAction::apply(node); // Left View SbRotation r1(SbVec3f(0,0,1), -M_PI/2); rotateCamera(r1*SbRotation(SbVec3f(0,1,0), -M_PI/2)); vp.setViewportPixels(SbVec2s(0, height-width), SbVec2s(width/2, width) ); setViewportRegion(vp); SoGLRenderAction::apply(node); // Right View rotateCamera(SbRotation(SbVec3f(0,1,0), -M_PI)); vp.setViewportPixels(SbVec2s(width/2, height-width), SbVec2s(width/2, width) ); setViewportRegion(vp); SoGLRenderAction::apply(node); setViewportRegion(vpr); camera->position = position; camera->orientation = orientation; camera->enableNotify(true); // Restore original viewport region setViewportRegion(vpr); }