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(); } }
void ViewProviderVRMLObject::getResourceFile(SoNode* node, std::list<std::string>& resources) { SoSearchAction sa; sa.setType(T::getClassTypeId()); sa.setInterest(SoSearchAction::ALL); sa.setSearchingAll(true); sa.apply(node); const SoPathList & pathlist = sa.getPaths(); for (int i = 0; i < pathlist.getLength(); i++ ) { SoFullPath * path = static_cast<SoFullPath *>(pathlist[i]); if (path->getTail()->isOfType(T::getClassTypeId())) { T * tex = static_cast<T*>(path->getTail()); for (int j = 0; j < tex->url.getNum(); j++) { this->addResource(tex->url[j], resources); } } } }
// Documented in superclass. Overridden to add highlighting after the // "ordinary" rendering. void SoLineHighlightRenderAction::apply(SoNode * node) { SoGLRenderAction::apply(node); if (this->hlVisible) { if (PRIVATE(this)->searchaction == NULL) { PRIVATE(this)->searchaction = new SoSearchAction; } // Coin, and SGI Inventor, only supports one Selection node in a // graph, so just search for the first one to avoid that the whole // scene graph is searched const SbBool searchall = FALSE; PRIVATE(this)->searchaction->setType(SoSelection::getClassTypeId()); PRIVATE(this)->searchaction->setInterest(searchall ? SoSearchAction::ALL : SoSearchAction::FIRST); PRIVATE(this)->searchaction->apply(node); if (searchall) { const SoPathList & pathlist = PRIVATE(this)->searchaction->getPaths(); if (pathlist.getLength() > 0) { int i; for (i = 0; i < pathlist.getLength(); i++) { SoFullPath * path = static_cast<SoFullPath *>(pathlist[i]); assert(path); SoSelection * selection = static_cast<SoSelection *>(path->getTail()); if (selection->getNumSelected() > 0) PRIVATE(this)->drawBoxes(path, selection->getList()); } } } else { SoFullPath * path = static_cast<SoFullPath *>(PRIVATE(this)->searchaction->getPath()); if (path) { SoSelection * selection = static_cast<SoSelection *>(path->getTail()); assert(selection->getTypeId().isDerivedFrom(SoSelection::getClassTypeId())); if (selection->getNumSelected() > 0) { PRIVATE(this)->drawBoxes(path, selection->getList()); } } } // reset action to clear path PRIVATE(this)->searchaction->reset(); } }
SbBool SoFCSelection::isHighlighted(SoAction *action) // //////////////////////////////////////////////////////////////////////// { SoFullPath *actionPath = (SoFullPath *) action->getCurPath(); return (currenthighlight != NULL && currenthighlight->getTail() == actionPath->getTail() && // nested SoHL! *currenthighlight == *actionPath); }
void ViewProviderVRMLObject::getResourceFile<SoVRMLBackground>(SoNode* node, std::list<std::string>& resources) { SoSearchAction sa; sa.setType(SoVRMLBackground::getClassTypeId()); sa.setInterest(SoSearchAction::ALL); sa.setSearchingAll(true); sa.apply(node); const SoPathList & pathlist = sa.getPaths(); for (int i = 0; i < pathlist.getLength(); i++ ) { SoFullPath * path = static_cast<SoFullPath *>(pathlist[i]); if (path->getTail()->isOfType(SoVRMLBackground::getClassTypeId())) { SoVRMLBackground * vrml = static_cast<SoVRMLBackground*>(path->getTail()); // backUrl for (int j = 0; j < vrml->backUrl.getNum(); j++) { addResource(vrml->backUrl[j], resources); } // bottomUrl for (int j = 0; j < vrml->bottomUrl.getNum(); j++) { addResource(vrml->bottomUrl[j], resources); } // frontUrl for (int j = 0; j < vrml->frontUrl.getNum(); j++) { addResource(vrml->frontUrl[j], resources); } // leftUrl for (int j = 0; j < vrml->leftUrl.getNum(); j++) { addResource(vrml->leftUrl[j], resources); } // rightUrl for (int j = 0; j < vrml->rightUrl.getNum(); j++) { addResource(vrml->rightUrl[j], resources); } // topUrl for (int j = 0; j < vrml->topUrl.getNum(); j++) { addResource(vrml->topUrl[j], resources); } } } }
// Documented in superclass. Overridden to add highlighting after the // "ordinary" rendering. void SoBoxHighlightRenderAction::apply(SoNode * node) { SoGLRenderAction::apply(node); if (this->hlVisible) { if (PRIVATE(this)->searchaction == NULL) { PRIVATE(this)->searchaction = new SoSearchAction; } const SbBool searchall = FALSE; PRIVATE(this)->searchaction->setType(SoSelection::getClassTypeId()); PRIVATE(this)->searchaction->setInterest(searchall ? SoSearchAction::ALL : SoSearchAction::FIRST); PRIVATE(this)->searchaction->apply(node); if (searchall) { const SoPathList & pathlist = PRIVATE(this)->searchaction->getPaths(); if (pathlist.getLength() > 0) { int i; for (i = 0; i < pathlist.getLength(); i++) { SoFullPath * path = static_cast<SoFullPath *>(pathlist[i]); assert(path); SoSelection * selection = static_cast<SoSelection *>(path->getTail()); if (selection->getNumSelected() > 0) this->drawBoxes(path, selection->getList()); } } } else { SoFullPath * path = static_cast<SoFullPath *>(PRIVATE(this)->searchaction->getPath()); if (path) { SoSelection * selection = static_cast<SoSelection *>(path->getTail()); if (selection->getNumSelected()) { this->drawBoxes(path, selection->getList()); } } } PRIVATE(this)->searchaction->reset(); } }
SoNode * SoToVRMLActionP::search_for_node(SoNode * root, const SbName & name, const SoType & type) { SoNodeList mylist; if (name == SbName::empty()) return NULL; mylist.truncate(0); int num = SoNode::getByName(name, mylist); int cnt = 0; SoNode * retnode = NULL; for (int i = 0; i < num; i++) { SoNode * node = mylist[i]; if (node->getTypeId() == type) { retnode = node; cnt++; } } // if there is only one node with that name, return it if (retnode && cnt == 1) return retnode; if (!retnode) return NULL; this->searchaction.setSearchingAll(TRUE); this->searchaction.setName(name); this->searchaction.setType(type); this->searchaction.setInterest(SoSearchAction::LAST); this->searchaction.setFind(SoSearchAction::TYPE|SoSearchAction::NAME); #ifdef HAVE_NODEKITS SbBool old = SoBaseKit::isSearchingChildren(); SoBaseKit::setSearchingChildren(TRUE); #endif // HAVE_NODEKITS this->searchaction.apply(root); SoNode * tail = NULL; SoFullPath * path = reclassify_cast<SoFullPath*>(this->searchaction.getPath()); if (path) { tail = path->getTail(); } this->searchaction.reset(); #ifdef HAVE_NODEKITS SoBaseKit::setSearchingChildren(old); #endif // HAVE_NODEKITS return tail; }
////////////////////////////////////////////////////////////////////////////// // // beginTraversal - have the base class render the passed scene graph, // then render highlights for our selection node. // void SoLineHighlightRenderAction::apply(SoNode *node) // ////////////////////////////////////////////////////////////////////////////// { // Render the scene SoGLRenderAction::apply(node); // Render the highlight? if (! hlVisible) return; // Add the rendering localRoot beneath our local scene graph localRoot // so that we can find a path from localRoot to the selection node // which is under the render root. localRoot->addChild(node); // Find the selection node under the local root static SoSearchAction *sa = NULL; if (sa == NULL) sa = new SoSearchAction; else sa->reset(); sa->setFind(SoSearchAction::TYPE); sa->setInterest(SoSearchAction::FIRST); sa->setType(SoSelection::getClassTypeId()); sa->apply(localRoot); SoPath *hlPath = sa->getPath(); if (hlPath != NULL) { hlPath = hlPath->copy(); hlPath->ref(); // Make sure something is selected SoSelection *sel = (SoSelection *) hlPath->getTail(); if (sel->getNumSelected() > 0) { // Keep the length from the root to the selection // as an optimization so we can reuse this data int reusablePathLength = hlPath->getLength(); // For each selection path, create a new path rooted under our localRoot for (int j = 0; j < sel->getNumSelected(); j++) { // Continue the path down to the selected object. // No need to deal with p[0] since that is the sel node. SoFullPath *p = (SoFullPath *) sel->getPath(j); SoNode *pathTail = p->getTail(); if ( pathTail->isOfType(SoBaseKit::getClassTypeId())) { // Find the last nodekit on the path. SoNode *kitTail = ((SoNodeKitPath *)p)->getTail(); // Extend the selectionPath until it reaches this last kit. SoFullPath *fp = (SoFullPath *) p; int k = 0; do { hlPath->append(fp->getIndex(++k)); } while ( fp->getNode(k) != kitTail ); } else { for (int k = 1; k < p->getLength(); k++) hlPath->append(p->getIndex(k)); } // Render the shape with the local draw style to make the highlight SoGLRenderAction::apply(hlPath); // Restore hlPath for reuse hlPath->truncate(reusablePathLength); } } hlPath->unref(); } // Remove the rendering localRoot from our local scene graph localRoot->removeChild(node); }
////////////////////////////////////////////////////////////////////////////// // // beginTraversal - have the base class render the passed scene graph, // then render highlights for our selection node. // void SoBoxHighlightRenderAction::apply(SoNode *renderRoot) // ////////////////////////////////////////////////////////////////////////////// { // Render the scene SoGLRenderAction::apply(renderRoot); // Render the highlight? if (! hlVisible) return; // Is our cached path still valid? if ((selPath == NULL) || (selPath->getHead() != renderRoot) || (! selPath->getTail()->isOfType(SoSelection::getClassTypeId()))) { // Find the selection node under the render root static SoSearchAction *sa1 = NULL; if (sa1 == NULL) sa1 = new SoSearchAction; else sa1->reset(); sa1->setFind(SoSearchAction::TYPE); sa1->setInterest(SoSearchAction::FIRST); sa1->setType(SoSelection::getClassTypeId()); sa1->apply(renderRoot); // Cache this path if (selPath != NULL) selPath->unref(); selPath = sa1->getPath(); if (selPath != NULL) { selPath = selPath->copy(); selPath->ref(); } } if (selPath != NULL) { // Make sure something is selected SoSelection *sel = (SoSelection *) selPath->getTail(); if (sel->getNumSelected() == 0) return; // Keep the length from the root to the selection // as an optimization so we can reuse this data int reusablePathLength = selPath->getLength(); // For each selection path, create a new path rooted under our // localRoot for (int j = 0; j < sel->getNumSelected(); j++) { // Continue the path down to the selected object. // No need to deal with p[0] since that is the sel node. SoFullPath *p = (SoFullPath *) sel->getPath(j); SoNode *pathTail = p->getTail(); if ( pathTail->isOfType(SoBaseKit::getClassTypeId())) { // Find the last nodekit on the path. SoNode *kitTail = ((SoNodeKitPath *)p)->getTail(); // Extend the selectionPath until it reaches this last kit. SoFullPath *fp = (SoFullPath *) p; int k = 0; do { selPath->append(fp->getIndex(++k)); } while ( fp->getNode(k) != kitTail ); } else { for (int k = 1; k < p->getLength(); k++) selPath->append(p->getIndex(k)); } // Find the camera used to render the selected object and // insert it into the highlight graph as the first child SoNode *camera; static SoSearchAction *sa2 = NULL; if (sa2 == NULL) sa2 = new SoSearchAction; else sa2->reset(); sa2->setFind(SoSearchAction::TYPE); sa2->setInterest(SoSearchAction::LAST); sa2->setType(SoCamera::getClassTypeId()); sa2->apply(selPath); camera =(sa2->getPath() == NULL ? NULL : sa2->getPath()->getTail()); if (camera != NULL) localRoot->insertChild(camera, 0); // Get the bounding box of the object and update the // local highlight graph updateBbox(selPath); // Make sure the box has some size if ((cube->width.getValue() == 0) && (cube->height.getValue() == 0) && (cube->depth.getValue() == 0)) { #ifdef DEBUG SoDebugError::postWarning("SoBoxHighlightRenderAction::apply", "selected object has no bounding box - no highlight rendered"); #endif } else { // Render the highlight SoGLRenderAction::apply(localRoot); } // Restore selPath for reuse selPath->truncate(reusablePathLength); // Remove the camera for the next path if (camera != NULL) localRoot->removeChild(0); } } }