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);
}
示例#3
0
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;
}
示例#5
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);
}
示例#6
0
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();
	}
    }
}
示例#7
0
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);
}
示例#9
0
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();
}
示例#10
0
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);
            }
        }
    }
}
示例#11
0
文件: modlist.cpp 项目: DundalkIT/pcp
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();
}
示例#12
0
// 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;
}
示例#13
0
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;
    }
}
示例#14
0
/*!
  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
}
示例#15
0
//////////////////////////////////////////////////////////////////////////////
//
//  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);
}    
示例#16
0
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();
}
示例#17
0
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;
 	}

}
示例#20
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;
}