void SoBoxSelectionRenderAction::apply(SoNode * node) { SoGLRenderAction::apply(node); if (this->hlVisible) { if (PRIVATE(this)->searchaction == NULL) { PRIVATE(this)->searchaction = new SoSearchAction; } PRIVATE(this)->searchaction->setType(SoFCSelection::getClassTypeId()); PRIVATE(this)->searchaction->setInterest(SoSearchAction::ALL); PRIVATE(this)->searchaction->apply(node); const SoPathList & pathlist = PRIVATE(this)->searchaction->getPaths(); if (pathlist.getLength() > 0) { for (int i = 0; i < pathlist.getLength(); i++ ) { SoPath * path = pathlist[i]; assert(path); SoFCSelection * selection = (SoFCSelection *) path->getTail(); assert(selection->getTypeId().isDerivedFrom(SoFCSelection::getClassTypeId())); if (selection->selected.getValue() && selection->style.getValue() == SoFCSelection::BOX) { PRIVATE(this)->basecolor->rgb.setValue(selection->colorSelection.getValue()); if (PRIVATE(this)->selectsearch == NULL) { PRIVATE(this)->selectsearch = new SoSearchAction; } PRIVATE(this)->selectsearch->setType(SoShape::getClassTypeId()); PRIVATE(this)->selectsearch->setInterest(SoSearchAction::FIRST); PRIVATE(this)->selectsearch->apply(selection); SoPath* shapepath = PRIVATE(this)->selectsearch->getPath(); if (shapepath) { SoPathList list; list.append(shapepath); this->drawBoxes(path, &list); } PRIVATE(this)->selectsearch->reset(); } else if (selection->isHighlighted() && selection->selected.getValue() == SoFCSelection::NOTSELECTED && selection->style.getValue() == SoFCSelection::BOX) { PRIVATE(this)->basecolor->rgb.setValue(selection->colorHighlight.getValue()); if (PRIVATE(this)->selectsearch == NULL) { PRIVATE(this)->selectsearch = new SoSearchAction; } PRIVATE(this)->selectsearch->setType(SoShape::getClassTypeId()); PRIVATE(this)->selectsearch->setInterest(SoSearchAction::FIRST); PRIVATE(this)->selectsearch->apply(selection); SoPath* shapepath = PRIVATE(this)->selectsearch->getPath(); if (shapepath) { SoPathList list; list.append(shapepath); PRIVATE(this)->highlightPath = path; PRIVATE(this)->highlightPath->ref(); this->drawBoxes(path, &list); } PRIVATE(this)->selectsearch->reset(); } } } PRIVATE(this)->searchaction->reset(); } }
void ViewProviderVRMLObject::getLocalResources(SoNode* node, std::list<std::string>& resources) { // search for SoVRMLInline files SoSearchAction sa; sa.setType(SoVRMLInline::getClassTypeId()); sa.setInterest(SoSearchAction::ALL); sa.setSearchingAll(true); sa.apply(node); const SoPathList & pathlist = sa.getPaths(); for (int i = 0; i < pathlist.getLength(); i++ ) { SoPath * path = pathlist[i]; SoVRMLInline * vrml = static_cast<SoVRMLInline*>(path->getTail()); const SbString& url = vrml->getFullURLName(); if (url.getLength() > 0) { // add the resource file if not yet listed if (std::find(resources.begin(), resources.end(), url.getString()) == resources.end()) { resources.push_back(url.getString()); } // if the resource file could be loaded check if it references further resources if (vrml->getChildData()) { getLocalResources(vrml->getChildData(), resources); } } } // search for SoVRMLImageTexture, ... files getResourceFile<SoVRMLImageTexture >(node, resources); getResourceFile<SoVRMLMovieTexture >(node, resources); getResourceFile<SoVRMLScript >(node, resources); getResourceFile<SoVRMLBackground >(node, resources); getResourceFile<SoVRMLAudioClip >(node, resources); getResourceFile<SoVRMLAnchor >(node, resources); }
IvDragger::IvDragger(QtCoinViewerPtr viewer, ItemPtr pItem, float draggerScale) { _selectedItem = pItem; _viewer = viewer; _scale = draggerScale; _penv = viewer->GetEnv(); //_ptext = NULL; // set some default behavioral options _checkCollision = false; _prevtransparency = pItem->GetIvTransparency()->value; pItem->GetIvTransparency()->value = SoGLRenderAction::SCREEN_DOOR; if( !!pItem &&(pItem->GetIvRoot() != NULL)) { _GetBounds(pItem->GetIvRoot(), _ab); // make the item transparent SoSearchAction search; search.setType(SoMaterial::getClassTypeId()); search.setInterest(SoSearchAction::ALL); search.apply(pItem->GetIvRoot()); for(int i = 0; i < search.getPaths().getLength(); ++i) { SoPath* path = search.getPaths()[i]; SoMaterial* pmtrl = (SoMaterial*)path->getTail(); vtransparency.push_back(pmtrl->transparency[0]); pmtrl->transparency = 0.25f; } _vlinkaxes.resize(pItem->GetNumIvLinks()); for(size_t i = 0; i < _vlinkaxes.size(); ++i) { _vlinkaxes[i] = _CreateAxes(i == 0 ? 1.0f : 0.25f,0.5f); pItem->GetIvLink(i)->addChild(_vlinkaxes[i]); } } }
SoNode* ViewProviderDocumentObject::findFrontRootOfType(const SoType& type) const { // first get the document this object is part of and get its GUI counterpart App::Document* pAppDoc = pcObject->getDocument(); Gui::Document* pGuiDoc = Gui::Application::Instance->getDocument(pAppDoc); SoSearchAction searchAction; searchAction.setType(type); searchAction.setInterest(SoSearchAction::FIRST); // search in all view providers for the node type std::vector<App::DocumentObject*> obj = pAppDoc->getObjects(); for (std::vector<App::DocumentObject*>::iterator it = obj.begin(); it != obj.end(); ++it) { const ViewProvider* vp = pGuiDoc->getViewProvider(*it); // Ignore 'this' view provider. It could also happen that vp is 0, e.g. when // several objects have been added to the App::Document before notifying the // Gui::Document if (!vp || vp == this) continue; SoSeparator* front = vp->getFrontRoot(); //if (front && front->getTypeId() == type) // return front; if (front) { searchAction.apply(front); SoPath* path = searchAction.getPath(); if (path) return path->getTail(); } } return 0; }
void IfWeeder::weedMaterial(SoNode *root, IfWeederMaterialEntry *entry) { // If the material affects no shapes at all, get rid of it. This // can happen when vertex property nodes are used. if (entry->shapes.getLength() == 0) { SoSearchAction sa; sa.setNode(entry->material); sa.setInterest(SoSearchAction::ALL); sa.apply(root); for (int i = 0; i < sa.getPaths().getLength(); i++) { SoPath *path = sa.getPaths()[i]; SoSeparator *parent = (SoSeparator *) path->getNodeFromTail(1); int index = path->getIndexFromTail(0); ASSERT(parent->isOfType(SoSeparator::getClassTypeId())); ASSERT(parent->getChild(index) == entry->material); parent->removeChild(index); } } // Remove all material values from the material node that are // not used by any dependent shapes. Adjust the indices in the // dependent shapes accordingly. removeDuplicateMaterials(entry); // Now remove all material values that are not used by any // dependent shapes. Again, adjust the indices in the dependent // shapes. removeUnusedMaterials(entry); }
void SoSFPath::fixCopy(SbBool copyConnections) // //////////////////////////////////////////////////////////////////////// { if (value != NULL) { // If the head of the path has been copied, then each of the // other nodes in the path must have been copied as // well. Change the copied path to start at the copy and go // through the copied nodes. SoNode *headCopy = (SoNode *) SoFieldContainer::findCopy(value->getHead(), copyConnections); if (headCopy != NULL) { // Create a new path through the copied nodes SoPath *pathCopy = new SoPath(headCopy); pathCopy->ref(); for (int i = 1; i < ((SoFullPath *) value)->getLength(); i++) pathCopy->append(value->getIndex(i)); setVal(pathCopy); pathCopy->unref(); } } }
SoPath *pickFilterCB(void *, const SoPickedPoint *pick) { SoPath *path = pick->getPath(); for (int i=0; i< path->getLength(); i++) { LabObject *found = NULL; if (LabObject::isLabObject(path->getNodeFromTail(i), &found)) { //return path->copy(0, i+1); return path->copy(0, path->getLength()-i); } } return new SoPath(); }
void SoFCIndexedFaceSet::doAction(SoAction * action) { if (action->getTypeId() == Gui::SoGLSelectAction::getClassTypeId()) { SoNode* node = action->getNodeAppliedTo(); if (!node) return; // on no node applied // The node we have is the parent of this node and the coordinate node // thus we search there for it. SoSearchAction sa; sa.setInterest(SoSearchAction::FIRST); sa.setSearchingAll(false); sa.setType(SoCoordinate3::getClassTypeId(), 1); sa.apply(node); SoPath * path = sa.getPath(); if (!path) return; // make sure we got the node we wanted SoNode* coords = path->getNodeFromTail(0); if (!(coords && coords->getTypeId().isDerivedFrom(SoCoordinate3::getClassTypeId()))) return; startSelection(action); renderSelectionGeometry(static_cast<SoCoordinate3*>(coords)->point.getValues(0)); stopSelection(action); } else if (action->getTypeId() == Gui::SoVisibleFaceAction::getClassTypeId()) { SoNode* node = action->getNodeAppliedTo(); if (!node) return; // on no node applied // The node we have is the parent of this node and the coordinate node // thus we search there for it. SoSearchAction sa; sa.setInterest(SoSearchAction::FIRST); sa.setSearchingAll(false); sa.setType(SoCoordinate3::getClassTypeId(), 1); sa.apply(node); SoPath * path = sa.getPath(); if (!path) return; // make sure we got the node we wanted SoNode* coords = path->getNodeFromTail(0); if (!(coords && coords->getTypeId().isDerivedFrom(SoCoordinate3::getClassTypeId()))) return; startVisibility(action); renderVisibleFaces(static_cast<SoCoordinate3*>(coords)->point.getValues(0)); stopVisibility(action); } inherited::doAction(action); }
SoCamera * SoSceneTextureCubeMapP::findCamera(void) { SoSearchAction sa; sa.setType(SoCamera::getClassTypeId()); sa.setInterest(SoSearchAction::FIRST); sa.apply(PUBLIC(this)->scene.getValue()); SoPath * path = sa.getPath(); if (path == NULL) return NULL; else return (SoCamera *)path->getTail(); }
void AlignmentGroup::setRandomColor() { std::vector<Gui::ViewProviderDocumentObject*>::iterator it; for (it = this->_views.begin(); it != this->_views.end(); ++it) { float r = /*(float)rand()/(float)RAND_MAX*/0.0f; float g = (float)rand()/(float)RAND_MAX; float b = (float)rand()/(float)RAND_MAX; if ((*it)->isDerivedFrom(Gui::ViewProviderGeometryObject::getClassTypeId())) { SoSearchAction searchAction; searchAction.setType(SoMaterial::getClassTypeId()); searchAction.setInterest(SoSearchAction::FIRST); searchAction.apply((*it)->getRoot()); SoPath* selectionPath = searchAction.getPath(); if (selectionPath) { SoMaterial* material = static_cast<SoMaterial*>(selectionPath->getTail()); material->diffuseColor.setValue(r, g, b); } } } }
void ModList::selectAllId(SoNode *node, int count) { SoPath *path = new SoPath(node); _allId = findToken(path); #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL1) cerr << "ModList::selectAllId: Select All on " << _allId << endl; #endif if (_allId > 0) { _numSel += count - _selList[_allId]; _selList[_allId] = count; if (_numSel == 1) _oneSel = _allId; } path->unref(); }
// Override from SoField to check node pointer. SbBool SoSFNode::referencesCopy(void) const { if (inherited::referencesCopy()) return TRUE; SoBase * n = this->getValue(); if (!n) return FALSE; if (n->isOfType(SoNode::getClassTypeId()) || n->isOfType(SoEngine::getClassTypeId())) { if (SoFieldContainer::checkCopy(coin_assert_cast<SoFieldContainer *>(n))) return TRUE; } else if (n->isOfType(SoPath::getClassTypeId())) { SoPath * p = coin_assert_cast<SoPath *>(n); if (p->getHead() == NULL) return FALSE; if (SoFieldContainer::checkCopy(p->getHead())) return TRUE; } else { assert(0 && "strange internal error"); } return FALSE; }
IvDragger::~IvDragger() { ItemPtr selectedItem = GetSelectedItem(); if( !!selectedItem &&(selectedItem->GetIvRoot() != NULL)) { for(size_t i = 0; i < _vlinkaxes.size(); ++i) { selectedItem->GetIvLink(i)->removeChild(_vlinkaxes[i]); } _vlinkaxes.clear(); // revert transparency SoSearchAction search; search.setType(SoMaterial::getClassTypeId()); search.setInterest(SoSearchAction::ALL); search.apply(selectedItem->GetIvRoot()); for(int i = 0; i < search.getPaths().getLength(); ++i) { SoPath* path = search.getPaths()[i]; SoMaterial* pmtrl = (SoMaterial*)path->getTail(); if( i < (int)vtransparency.size() ) pmtrl->transparency = vtransparency[i]; } selectedItem->GetIvTransparency()->value = _prevtransparency; } }
/*! Empty method in Coin. Can be used by subclasses to be told when status change. */ void SoFCSelection::redrawHighlighted(SoAction * action , SbBool doHighlight ) { //Base::Console().Log("SoFCSelection::redrawHighlighted() (%p) doHigh=%d \n",this,doHighlight?1:0); #ifdef NO_FRONTBUFFER #else // If we are about to highlight, and there is something else highlighted, // that something else needs to unhighlight. if (doHighlight && currenthighlight != NULL && !(*((SoFullPath *)action->getCurPath()) == *currenthighlight)) { SoNode *tail = currenthighlight->getTail(); if (tail->isOfType( SoFCSelection::getClassTypeId())) ((SoFCSelection *)tail)->redrawHighlighted(action, FALSE); else { // Just get rid of the path. It's no longer valid for redraw. currenthighlight->unref(); currenthighlight = NULL; } } SoPath *pathToRender; // save the path to ourself for later de-highlight if (doHighlight) { if (currenthighlight != NULL) currenthighlight->unref(); currenthighlight = (SoFullPath *) action->getCurPath()->copy(); currenthighlight->ref(); // We will be rendering this new path to highlight it pathToRender = currenthighlight; pathToRender->ref(); } // delete our path if we are no longer highlighted else { if (currenthighlight) { // We will be rendering this old path to unhighlight it pathToRender = currenthighlight; pathToRender->ref(); currenthighlight->unref(); currenthighlight = NULL; } } // If highlighting is forced on for this node, we don't need this special render. if (highlightMode.getValue() != AUTO) { pathToRender->unref(); return; } SoState *state = action->getState(); //void* window; //void* context; //void *display; QGLWidget* window; SoGLRenderAction *glAction; //SoWindowElement::get(state, window, context, display, glAction); SoGLWidgetElement::get(state, window); SoGLRenderActionElement::get(state, glAction); // If we don't have a current window, then simply return... if (window == 0 /*|| context == NULL || display == NULL*/ || glAction == NULL) return; window->makeCurrent(); #ifndef WIN32 // set the current window //glXMakeCurrent(display, window, context); #endif // render into the front buffer (save the current buffering type) GLint whichBuffer; glGetIntegerv(GL_DRAW_BUFFER, &whichBuffer); if (whichBuffer != GL_FRONT) glDrawBuffer(GL_FRONT); highlighted = TRUE; glAction->apply(pathToRender); highlighted = FALSE; // restore the buffering type if (whichBuffer != GL_FRONT) glDrawBuffer((GLenum)whichBuffer); glFlush(); pathToRender->unref(); #endif }
////////////////////////////////////////////////////////////////////////////// // // 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); }
void SoSurroundScale::updateMySurroundParams(SoAction *action, const SbMatrix &myInv ) // //////////////////////////////////////////////////////////////////////// { const SoFullPath *curPath = (const SoFullPath *) action->getCurPath(); int curPathLength = curPath->getLength(); // If the container node is out of range, just return. int numUpCon = (int) numNodesUpToContainer.getValue(); if ( (numUpCon <= 0) || (numUpCon > (curPathLength - 1)) ){ cachedScale.setValue(1,1,1); cachedInvScale.setValue(1,1,1); cachedTranslation.setValue(0,0,0); cacheOK = FALSE; return; } // CHECK TO SEE IF OUR CACHED VALUES ARE OKAY // IF SO, JUST RETURN if ( cacheOK ) return; // Find the path to apply the bounding box action to. It should end // 'numUpCon' above this one. SoPath *applyPath = curPath->copy(0, (curPathLength - numUpCon)); applyPath->ref(); // See if there is a node to do a reset at. If so, build a resetPath SoPath *resetPath = NULL; int numUpReset = (int) numNodesUpToReset.getValue(); if (numUpReset >= 0 && (numUpReset < numUpCon) ) { // Build a path ending at the reset node. resetPath = curPath->copy(0, curPathLength - numUpReset ); resetPath->ref(); } SoFullPath *fullResetPath = (SoFullPath *) resetPath; // Create a getBoundingBox action // Set the reset path if we have one. // Apply the bounding box action and find out how big the box was. // Temporarily set the ignoreInBbox flag TRUE, so we don't infinite loop! SbViewportRegion vpRegion(0,0); SoState *state = action->getState(); vpRegion = SoViewportRegionElement::get(state); static SoGetBoundingBoxAction *boundingBoxAction = NULL; if (boundingBoxAction == NULL) boundingBoxAction = new SoGetBoundingBoxAction(vpRegion); else boundingBoxAction->setViewportRegion(vpRegion); if (fullResetPath) boundingBoxAction->setResetPath( fullResetPath, FALSE, SoGetBoundingBoxAction::BBOX); SbBool oldFlag = isIgnoreInBbox(); setIgnoreInBbox( TRUE ); boundingBoxAction->apply( applyPath ); setIgnoreInBbox( oldFlag ); SbXfBox3f &myXfBox = boundingBoxAction->getXfBoundingBox(); // Transform the box into our local space, then project it. myXfBox.transform( myInv ); SbBox3f myBox = myXfBox.project(); // Get the scale for this node to add to the ctm. if (myBox.isEmpty()) { cachedScale.setValue(1,1,1); cachedInvScale.setValue(1,1,1); cachedTranslation.setValue(0,0,0); cacheOK = TRUE; return; } else { float x, y, z; myBox.getSize(x,y,z); cachedScale.setValue( .5*x, .5*y, .5*z ); float minLength = .01 * cachedScale.length(); // Macro defined just before beginning of this method. FUDGE(cachedScale[0],minLength); FUDGE(cachedScale[1],minLength); FUDGE(cachedScale[2],minLength); // Find the inverse values for (int j = 0; j < 3; j++ ) cachedInvScale[j] = 1.0 / cachedScale[j]; } // Get the translation for this node to add to the ctm. // This will get the cube centered about the bbox center. // If the bounding box is not centered at the origin, we have to // move the cube to the correct place. if (doTranslations) cachedTranslation = 0.5 * ( myBox.getMin() + myBox.getMax() ); else cachedTranslation.setValue(0,0,0); // Establish the cached values to save us some time later... cacheOK = TRUE; if (resetPath) resetPath->unref(); if (applyPath) applyPath->unref(); }
static SoSeparator * setUpGraph(const SbViewportRegion &vpReg, SoInput *sceneInput, Options &options) // ////////////////////////////////////////////////////////////// { // Create a root separator to hold everything. Turn // caching off, since the transformation will blow // it anyway. SoSeparator *root = new SoSeparator; root->ref(); root->renderCaching = SoSeparator::OFF; // Add a camera to view the scene SoPerspectiveCamera *camera = new SoPerspectiveCamera; root->addChild(camera); // Add a transform node to spin the scene SoTransform *sceneTransform = new SoTransform; sceneTransform->setName(SCENE_XFORM_NAME); root->addChild(sceneTransform); // Read and add input scene graph SoSeparator *inputRoot = SoDB::readAll(sceneInput); if (inputRoot == NULL) { fprintf(stderr, "Cannot read scene graph\n"); root->unref(); exit(1); } root->addChild(inputRoot); SoPath *path; SoGroup *parent, *group; SoSearchAction act; // expand out all File nodes and replace them with groups // containing the children SoFile *fileNode; act.setType(SoFile::getClassTypeId()); act.setInterest(SoSearchAction::FIRST); act.apply(inputRoot); while ((path = act.getPath()) != NULL) { fileNode = (SoFile *) path->getTail(); path->pop(); parent = (SoGroup *) path->getTail(); group = fileNode->copyChildren(); if (group) { parent->replaceChild(fileNode, group); // apply action again and continue act.apply(inputRoot); } } // expand out all node kits and replace them with groups // containing the children SoBaseKit *kitNode; SoChildList *childList; act.setType(SoBaseKit::getClassTypeId()); act.setInterest(SoSearchAction::FIRST); act.apply(inputRoot); while ((path = act.getPath()) != NULL) { kitNode = (SoBaseKit *) path->getTail(); path->pop(); parent = (SoGroup *) path->getTail(); group = new SoGroup; childList = kitNode->getChildren(); for (int i=0; i<childList->getLength(); i++) group->addChild((*childList)[i]); parent->replaceChild(kitNode, group); act.apply(inputRoot); } // check to see if there are any lights // if no lights, add a directional light to the scene act.setType(SoLight::getClassTypeId()); act.setInterest(SoSearchAction::FIRST); act.apply(inputRoot); if (act.getPath() == NULL) { // no lights SoDirectionalLight *light = new SoDirectionalLight; root->insertChild(light, 1); } else options.hasLights = TRUE; // check to see if there are any texures in the scene act.setType(SoTexture2::getClassTypeId()); act.setInterest(SoSearchAction::FIRST); act.apply(inputRoot); if (act.getPath() != NULL) options.hasTextures = TRUE; camera->viewAll(root, vpReg); // print out information about the scene graph int32_t numTris, numLines, numPoints, numNodes; countPrimitives( inputRoot, numTris, numLines, numPoints, numNodes ); printf("Number of nodes in scene graph: %d\n", numNodes ); printf("Number of triangles in scene graph: %d\n", numTris ); printf("Number of lines in scene graph: %d\n", numLines ); printf("Number of points in scene graph: %d\n\n", numPoints ); // Make the center of rotation the center of // the scene SoGetBoundingBoxAction bba(vpReg); bba.apply(root); sceneTransform->center = bba.getBoundingBox().getCenter(); return root; }
void SoDragPointDragger::metaKeyChangeCB( void *, SoDragger *inDragger ) // //////////////////////////////////////////////////////////////////////// { SoDragPointDragger *dp = (SoDragPointDragger *) inDragger; SoHandleEventAction *ha = dp->getHandleEventAction(); // We care if the shift key is down for drawing feedback. const SoEvent *event = dp->getEvent(); dp->shftDown = event->wasShiftDown(); // Don't check for grabber yet. // CONTROL key press overrides if the grabber is a childDragger. // [1] We only respond to CONTROL key press events. if ( !SO_KEY_PRESS_EVENT(event, LEFT_CONTROL) && !SO_KEY_PRESS_EVENT(event, RIGHT_CONTROL)) return; //[2] Should we return? // Stay here if there's no grabber and the mouse is over us, // or over a surrogate part. // Stay here if we are the grabber. // Stay here if our currentDragger is grabbing events. // Return if anyone else is grabbing. SbBool takeIt = FALSE; if ( ha->getGrabber() == NULL ) { // grabber is NULL... const SoPickedPoint *p = ha->getPickedPoint(); if ( p && p->getPath()) { // Are we on the pickPath? // Or is the path a surrogate path for us or any draggers // contained within us? if ( p->getPath()->containsNode(dp) || dp->isPathSurrogateInMySubgraph(p->getPath()) ) takeIt = TRUE; } } else if ( ha->getGrabber() == dp ) takeIt = TRUE; else if ( ha->getGrabber() == dp->currentDragger ) takeIt = TRUE; else takeIt = FALSE; if ( !takeIt ) return; //[3] Now, switch the set of visible draggers... dp->showNextDraggerSet(); //[4] If a child is grabbing, release events and hand it all over to // the next one... SoDragger *oldDragger = dp->currentDragger; if (oldDragger) { // Ref the oldDragger. oldDragger->ref(); // Release the grabber. This will call grabEventsCleanUp() if // the grabber is a dragger. ha->releaseGrabber(); // If there was an oldDragger, // [a] select a new dragger to grab events. // [b] Set up a plane or line projector oriented like newDragger. // [c] Find out where current mouse position intersects that new // plane or line. The new gesture will continue from there. SoDragger *newDragger; SbVec3f projPt; SbLineProjector lp; SbPlaneProjector pp; lp.setViewVolume( dp->getViewVolume() ); pp.setViewVolume( dp->getViewVolume() ); lp.setWorkingSpace( dp->getLocalToWorldMatrix() ); pp.setWorkingSpace( dp->getLocalToWorldMatrix() ); if ( oldDragger == dp->xTranslator.getValue() ) { newDragger = (SoDragger *) dp->yTranslator.getValue(); lp.setLine( SbLine( SbVec3f(0,0,0), SbVec3f(0,1,0))); projPt = lp.project(dp->getNormalizedLocaterPosition()); } else if ( oldDragger == dp->yTranslator.getValue() ) { newDragger = (SoDragger *) dp->zTranslator.getValue(); lp.setLine( SbLine( SbVec3f(0,0,0), SbVec3f(0,0,1))); projPt = lp.project(dp->getNormalizedLocaterPosition()); } else if ( oldDragger == dp->zTranslator.getValue() ) { newDragger = (SoDragger *) dp->xTranslator.getValue(); lp.setLine( SbLine( SbVec3f(0,0,0), SbVec3f(1,0,0))); projPt = lp.project(dp->getNormalizedLocaterPosition()); } else if ( oldDragger == dp->yzTranslator.getValue() ) { newDragger = (SoDragger *) dp->xzTranslator.getValue(); pp.setPlane( SbPlane( SbVec3f(0,1,0), SbVec3f(0,0,0))); projPt = pp.project(dp->getNormalizedLocaterPosition()); } else if ( oldDragger == dp->xzTranslator.getValue() ) { newDragger = (SoDragger *) dp->xyTranslator.getValue(); pp.setPlane( SbPlane( SbVec3f(0,0,1), SbVec3f(0,0,0))); projPt = pp.project(dp->getNormalizedLocaterPosition()); } else if ( oldDragger == dp->xyTranslator.getValue() ) { newDragger = (SoDragger *) dp->yzTranslator.getValue(); pp.setPlane( SbPlane( SbVec3f(1,0,0), SbVec3f(0,0,0))); projPt = pp.project(dp->getNormalizedLocaterPosition()); } // unref oldDragger. We don't need it any more. oldDragger->unref(); // Give newDragger our handleEvent action. newDragger->setHandleEventAction(ha); // Cast the projPt into world space for the new starting point. dp->getLocalToWorldMatrix().multVecMatrix(projPt,projPt); newDragger->setStartingPoint( projPt ); // Give the newDragger a path to itself SoPath *pathToDragger; // We must ref() & unref() dpThisPath to dispose of it. SoPath *dpThisPath = dp->createPathToThis(); if (dpThisPath) dpThisPath->ref(); pathToDragger = dp->createPathToPart( dp->getPartString(newDragger), TRUE, dpThisPath ); if (dpThisPath) dpThisPath->unref(); if (pathToDragger) pathToDragger->ref(); newDragger->setTempPathToThis( pathToDragger ); if (pathToDragger) pathToDragger->unref(); // Give the newDragger our viewing information. newDragger->setViewVolume(dp->getViewVolume()); newDragger->setViewportRegion(dp->getViewportRegion()); // Set the grabber. This will call starting callbacks on the new // grabber, as well as it's registered parent, moi! ha->setGrabber( newDragger ); } //[5] set handled ha->setHandled(); }
void ViewProviderRobotObject::updateData(const App::Property* prop) { Robot::RobotObject* robObj = static_cast<Robot::RobotObject*>(pcObject); if (prop == &robObj->RobotVrmlFile) { // read also from file const char* filename = robObj->RobotVrmlFile.getValue(); QString fn = QString::fromUtf8(filename); QFile file(fn); SoInput in; pcRobotRoot->removeAllChildren(); if (!fn.isEmpty() && file.open(QFile::ReadOnly)) { QByteArray buffer = file.readAll(); in.setBuffer((void *)buffer.constData(), buffer.length()); SoSeparator * node = SoDB::readAll(&in); if (node) pcRobotRoot->addChild(node); pcRobotRoot->addChild(pcTcpRoot); } // search for the conection points +++++++++++++++++++++++++++++++++++++++++++++++++ Axis1Node = Axis2Node = Axis3Node = Axis4Node = Axis5Node = Axis6Node = 0; SoSearchAction searchAction; SoPath * path; // Axis 1 searchAction.setName("FREECAD_AXIS1"); searchAction.setInterest(SoSearchAction::FIRST); searchAction.setSearchingAll(FALSE); searchAction.apply(pcRobotRoot); path = searchAction.getPath(); if(path){ SoNode* node = path->getTail(); std::string typeName = (const char*)node->getTypeId().getName(); if (!node || node->getTypeId() != SoVRMLTransform::getClassTypeId()) throw; // should not happen Axis1Node = static_cast<SoVRMLTransform *>(node); } // Axis 2 searchAction.setName("FREECAD_AXIS2"); searchAction.setInterest(SoSearchAction::FIRST); searchAction.setSearchingAll(FALSE); searchAction.apply(pcRobotRoot); path = searchAction.getPath(); if(path){ SoNode* node = path->getTail(); std::string typeName = (const char*)node->getTypeId().getName(); if (!node || node->getTypeId() != SoVRMLTransform::getClassTypeId()) throw; // should not happen Axis2Node = static_cast<SoVRMLTransform *>(node); } // Axis 3 searchAction.setName("FREECAD_AXIS3"); searchAction.setInterest(SoSearchAction::FIRST); searchAction.setSearchingAll(FALSE); searchAction.apply(pcRobotRoot); path = searchAction.getPath(); if(path){ SoNode* node = path->getTail(); std::string typeName = (const char*)node->getTypeId().getName(); if (!node || node->getTypeId() != SoVRMLTransform::getClassTypeId()) throw; // should not happen Axis3Node = static_cast<SoVRMLTransform *>(node); } // Axis 4 searchAction.setName("FREECAD_AXIS4"); searchAction.setInterest(SoSearchAction::FIRST); searchAction.setSearchingAll(FALSE); searchAction.apply(pcRobotRoot); path = searchAction.getPath(); if(path){ SoNode* node = path->getTail(); std::string typeName = (const char*)node->getTypeId().getName(); if (!node || node->getTypeId() != SoVRMLTransform::getClassTypeId()) throw; // should not happen Axis4Node = static_cast<SoVRMLTransform *>(node); } // Axis 5 searchAction.setName("FREECAD_AXIS5"); searchAction.setInterest(SoSearchAction::FIRST); searchAction.setSearchingAll(FALSE); searchAction.apply(pcRobotRoot); path = searchAction.getPath(); if(path){ SoNode* node = path->getTail(); std::string typeName = (const char*)node->getTypeId().getName(); if (!node || node->getTypeId() != SoVRMLTransform::getClassTypeId()) throw; // should not happen Axis5Node = static_cast<SoVRMLTransform *>(node); } // Axis 6 searchAction.setName("FREECAD_AXIS6"); searchAction.setInterest(SoSearchAction::FIRST); searchAction.setSearchingAll(FALSE); searchAction.apply(pcRobotRoot); path = searchAction.getPath(); if(path){ SoNode* node = path->getTail(); std::string typeName = (const char*)node->getTypeId().getName(); if (!node || node->getTypeId() != SoVRMLTransform::getClassTypeId()) throw; // should not happen Axis6Node = static_cast<SoVRMLTransform *>(node); } if(Axis1Node) Axis1Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis1.getValue()*(M_PI/180)); if(Axis2Node) Axis2Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis2.getValue()*(M_PI/180)); if(Axis3Node) Axis3Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis3.getValue()*(M_PI/180)); if(Axis4Node) Axis4Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis4.getValue()*(M_PI/180)); if(Axis5Node) Axis5Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis5.getValue()*(M_PI/180)); if(Axis6Node) Axis6Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis6.getValue()*(M_PI/180)); }else if (prop == &robObj->Axis1) { if(Axis1Node){ Axis1Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis1.getValue()*(M_PI/180)); if(toolShape) toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix()); } }else if (prop == &robObj->Axis2) { if(Axis2Node){ Axis2Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis2.getValue()*(M_PI/180)); if(toolShape) toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix()); } }else if (prop == &robObj->Axis3) { if(Axis3Node){ Axis3Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis3.getValue()*(M_PI/180)); if(toolShape) toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix()); } }else if (prop == &robObj->Axis4) { if(Axis4Node){ Axis4Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis4.getValue()*(M_PI/180)); if(toolShape) toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix()); } }else if (prop == &robObj->Axis5) { if(Axis5Node){ Axis5Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis5.getValue()*(M_PI/180)); if(toolShape) toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix()); } }else if (prop == &robObj->Axis6) { if(Axis6Node){ Axis6Node->rotation.setValue(SbVec3f(0.0,1.0,0.0),robObj->Axis6.getValue()*(M_PI/180)); if(toolShape) toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix()); } }else if (prop == &robObj->Tcp) { Base::Placement loc = robObj->Tcp.getValue(); SbMatrix M; M.setTransform(SbVec3f(loc.getPosition().x,loc.getPosition().y,loc.getPosition().z), SbRotation(loc.getRotation()[0],loc.getRotation()[1],loc.getRotation()[2],loc.getRotation()[3]), SbVec3f(150,150,150) ); if(pcDragger) pcDragger->setMotionMatrix(M); if(toolShape) toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix()); //pcTcpTransform->translation = SbVec3f(loc.getPosition().x,loc.getPosition().y,loc.getPosition().z); //pcTcpTransform->rotation = SbRotation(loc.getRotation()[0],loc.getRotation()[1],loc.getRotation()[2],loc.getRotation()[3]); }else if (prop == &robObj->ToolShape) { App::DocumentObject* o = robObj->ToolShape.getValue<App::DocumentObject*>(); if(o && (o->isDerivedFrom(Part::Feature::getClassTypeId()) || o->isDerivedFrom(App::VRMLObject::getClassTypeId())) ){ //Part::Feature *p = dynamic_cast<Part::Feature *>(o); toolShape = Gui::Application::Instance->getViewProvider(o); toolShape->setTransformation((robObj->Tcp.getValue() * (robObj->ToolBase.getValue().inverse())).toMatrix()); }else toolShape = 0; } }
int main(int argc, char ** argv) { if ( argc != 3 ) { fprintf(stderr, "Usage: %s <infile.iv> <outfile.iv>\n", argv[0]); return -1; } SoDB::init(); SoNodeKit::init(); SoInteraction::init(); SoGenerateSceneGraphAction::initClass(); SoTweakAction::initClass(); SoInput in; SoNode * scene, * graph; if ( !in.openFile(argv[1]) ) { fprintf(stderr, "%s: error opening \"%s\" for reading.\n", argv[0], argv[1]); return -1; } scene = SoDB::readAll(&in); if ( scene == NULL ) { fprintf(stderr, "%s: error parsing \"%s\"\n", argv[0], argv[1]); return -1; } scene->ref(); SoGenerateSceneGraphAction action; // action.setDropTypeIfNameEnabled(TRUE); action.apply(scene); graph = action.getGraph(); if ( graph == NULL ) { fprintf(stderr, "%s: error generating scene graph\n", argv[0]); return -1; } graph->ref(); scene->unref(); scene = NULL; // figure out camera settings and needed rendering canvas size SoGetBoundingBoxAction bbaction(SbViewportRegion(64,64)); // just something bbaction.apply(graph); SbBox3f bbox = bbaction.getBoundingBox(); SbVec3f min = bbox.getMin(); SbVec3f max = bbox.getMax(); float bwidth = max[0] - min[0]; float bheight = max[1] - min[1]; // fprintf(stdout, "min: %g %g %g\n", min[0], min[1], min[2]); // fprintf(stdout, "max: %g %g %g\n", max[0], max[1], max[2]); // place camera SoSearchAction search; search.setType(SoCamera::getClassTypeId()); search.setInterest(SoSearchAction::FIRST); search.apply(graph); SoPath * campath = search.getPath(); SoOrthographicCamera * cam = (SoOrthographicCamera *) campath->getTail(); assert(cam != NULL); SbVec3f pos = cam->position.getValue(); cam->position.setValue(SbVec3f(min[0] + ((max[0]-min[0])/2.0), min[1] + ((max[1]-min[1])/2.0), pos[2])); cam->height.setValue(bheight); if ( TRUE ) { // FIXME: only write .iv-scene if asked SoOutput out; if ( !out.openFile(argv[2]) ) { fprintf(stderr, "%s: error opening \"%s\" for writing.\n", argv[0], argv[2]); return -1; } SoWriteAction writer(&out); // writer.setCoinFormattingEnabled(TRUE); writer.apply(graph); } int width = (int) ceil(bwidth * 150.0) + 2; int height = (int) ceil(bheight * 150.0); fprintf(stderr, "image: %d x %d\n", width, height); if ( TRUE ) { // FIXME: only write image if asked SoOffscreenRenderer renderer(SbViewportRegion(width, height)); SoGLRenderAction * glra = renderer.getGLRenderAction(); glra->setNumPasses(9); // FIXME: auto-crop image afterwards? seems like it's a perfect fit right now renderer.setComponents(SoOffscreenRenderer::RGB_TRANSPARENCY); renderer.setBackgroundColor(SbColor(1.0,1.0,1.0)); renderer.render(graph); // FIXME: support command line option filename // FIXME: also support .eps renderer.writeToFile("output.png", "png"); } graph->unref(); return 0; }