SoGroup * SoToVRMLActionP::get_current_tail(void) { SoNode * node = this->vrmlpath->getTail(); assert(node->isOfType(SoGroup::getClassTypeId())); return coin_assert_cast<SoGroup*>(node); }
void SoUnknownNode::createFromIsA(SoMFString *isA) // //////////////////////////////////////////////////////////////////////// { for (int i = 0; i < isA->getNum(); i++) { SoType t = SoType::fromName((*isA)[i]); if (t.canCreateInstance() && t.isDerivedFrom(SoNode::getClassTypeId())) { SoNode *alternateRep = (SoNode *)t.createInstance(); alternateRep->ref(); #ifdef DEBUG if (alternateRep == NULL) { SoDebugError::post("SoUnknownNode::createFromIsA", "SoType.createInstance returned " "NULL (type %s)", t.getName().getString()); return; } #endif // Copy over all fields that are shared: int num = instanceFieldData->getNumFields(); for (int j=0; j<num; j++) { const SbName &fieldName = instanceFieldData->getFieldName(j); SoField *f = instanceFieldData->getField(this, j); // Don't copy over fields with default values: if (f->isDefault()) continue; SoField *nf = alternateRep->getField(fieldName); if (nf != NULL && nf->getTypeId() == f->getTypeId()) { nf->copyFrom(*f); if (f->isConnectedFromField()) { SoField *cf; f->getConnectedField(cf); nf->connectFrom(cf); } else if (f->isConnectedFromEngine()) { SoEngineOutput *eo; f->getConnectedEngine(eo); nf->connectFrom(eo); } } } // And if alternateRep is a group, copy over hidden // children: if (alternateRep->isOfType(SoGroup::getClassTypeId())) { SoGroup *g = (SoGroup *)alternateRep; for (int kid = 0; kid < hiddenChildren.getLength(); kid++) { g->addChild(hiddenChildren[kid]); } } addChild(alternateRep); return; } } }
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setCameraType(SoType type) { if(!getSoRenderManager()->getCamera()->isOfType(SoPerspectiveCamera::getClassTypeId()) && !getSoRenderManager()->getCamera()->isOfType(SoOrthographicCamera::getClassTypeId())) { Base::Console().Warning("Quarter::setCameraType", "Only SoPerspectiveCamera and SoOrthographicCamera is supported."); return; } SoType perspectivetype = SoPerspectiveCamera::getClassTypeId(); SbBool oldisperspective = getSoRenderManager()->getCamera()->getTypeId().isDerivedFrom(perspectivetype); SbBool newisperspective = type.isDerivedFrom(perspectivetype); if((oldisperspective && newisperspective) || (!oldisperspective && !newisperspective)) // Same old, same old.. return; SoCamera* currentcam = getSoRenderManager()->getCamera(); SoCamera* newcamera = (SoCamera*)type.createInstance(); // Transfer and convert values from one camera type to the other. if(newisperspective) { convertOrtho2Perspective((SoOrthographicCamera*)currentcam, (SoPerspectiveCamera*)newcamera); } else { convertPerspective2Ortho((SoPerspectiveCamera*)currentcam, (SoOrthographicCamera*)newcamera); } getSoRenderManager()->setCamera(newcamera); getSoEventManager()->setCamera(newcamera); //if the superscene has a camera we need to replace it too SoSeparator* superscene = (SoSeparator*) getSoRenderManager()->getSceneGraph(); SoSearchAction sa; sa.setInterest(SoSearchAction::FIRST); sa.setType(SoCamera::getClassTypeId()); sa.apply(superscene); if(sa.getPath()) { SoNode* node = sa.getPath()->getTail(); SoGroup* parent = (SoGroup*) sa.getPath()->getNodeFromTail(1); if(node && node->isOfType(SoCamera::getClassTypeId())) { parent->replaceChild(node, newcamera); } } };
/*! \fn SoXipTransparentGeometryGroup::getChildByType(const SoType &type) const * Returns a child node of the given type if any, otherwise return null. * \param action - the current state action * \return void */ SoNode *SoXipTransparentGeometryGroup::getChildByType(const SoType &type) const { for (int i = 0; i < getNumChildren(); i++) { SoNode *child = getChild(i); if (child->isOfType(type)) { return child; } } return 0; }
// private convenience method void SoFCSelection::turnoffcurrent(SoAction * action) { #ifdef NO_FRONTBUFFER if (SoFCSelection::currenthighlight && SoFCSelection::currenthighlight->getLength()) { SoNode * tail = SoFCSelection::currenthighlight->getTail(); if (tail->isOfType(SoFCSelection::getClassTypeId())) { ((SoFCSelection*)tail)->highlighted = FALSE; ((SoFCSelection*)tail)->touch(); // force scene redraw if (action) ((SoFCSelection*)tail)->redrawHighlighted(action, FALSE); } } if (SoFCSelection::currenthighlight) { SoFCSelection::currenthighlight->unref(); SoFCSelection::currenthighlight = NULL; } #else if (currenthighlight == NULL) return; SoNode *tail = currenthighlight->getTail(); if (tail->isOfType(SoFCSelection::getClassTypeId())) { // don't redraw if we already are in the middle of rendering // (processing events during render abort might cause this) SoState *state = action->getState(); if (state && state->getDepth() == 1) ((SoFCSelection *)tail)->redrawHighlighted(action, FALSE); } else { // Just get rid of the path. It's no longer valid for redraw. currenthighlight->unref(); currenthighlight = NULL; } #endif }
ViewProvider* Document::getViewProviderByPathFromTail(SoPath * path) const { // Make sure I'm the lowest LocHL in the pick path! for (int i = 0; i < path->getLength(); i++) { SoNode *node = path->getNodeFromTail(i); if (node->isOfType(SoSeparator::getClassTypeId())) { std::map<const App::DocumentObject*,ViewProviderDocumentObject*>::const_iterator it = d->_ViewProviderMap.begin(); for(;it!= d->_ViewProviderMap.end();++it) if (node == it->second->getRoot()) return it->second; } } return 0; }
SoCamera * QuarterWidgetP::searchForCamera(SoNode * root) { SoSearchAction sa; sa.setInterest(SoSearchAction::FIRST); sa.setType(SoCamera::getClassTypeId()); sa.apply(root); if (sa.getPath()) { SoNode * node = sa.getPath()->getTail(); if (node && node->isOfType(SoCamera::getClassTypeId())) { return (SoCamera *) node; } } return NULL; }
void SoGuiTranslation::getMatrix(SoGetMatrixAction * action) { SoDebugError::postInfo("SoGuiTranslation::getMatrix", "invoked"); int i; SoGuiPane * pane = NULL; const SoFullPath * path = (const SoFullPath *) action->getCurPath(); for ( i = path->getLength() - 1; (i >= 0) && (pane == NULL); i-- ) { SoNode * node = path->getNode(i); assert(node); if ( node->isOfType(SoGuiPane::getClassTypeId()) ) pane = (SoGuiPane *) node; } if ( pane == NULL ) { SoDebugError::postInfo("SoGuiTranslation::getMatrix", "SoGuiTranslation only works below an SoGuiPane node"); return; } pane->applyMoveBy(action, this->translation.getValue()); }
void SoXtMaterialList::selectionCallback(// private int materialid) { materialid--; // get index SoXtMaterialDirectory * data = common->getMaterialDirectory(); assert(materialid >= 0 && materialid < data->groups[data->current]->numMaterials); const char * materialdata = data->groups[data->current]->materials[materialid]->data; SoInput reader; if (data->flags & SOXT_BUILTIN_MATERIALS) { reader.setBuffer((void *) materialdata, strlen(materialdata)); } else { if (! reader.openFile(materialdata, FALSE)) { SoDebugError::postWarning("SoXtMaterialList::selectionCallback", "could not open file: \"%s\"", materialdata); return; } } SoNode * material = NULL; if (! SoDB::read(&reader, material)) { SoDebugError::postWarning("SoXtMaterialList::selectionCallback", "failed to read material"); return; } if (! material) { SoDebugError::postWarning("SoXtMaterialList::selectionCallback", "read returned no data"); return; } material->ref(); if (! material->isOfType(SoMaterial::getClassTypeId())) { SoDebugError::postWarning("SoXtMaterialList::selectionCallback", "not a material node!"); material->unref(); return; } common->invokeCallbacks((SoMaterial *) material); material->unref(); } // selectionCallback()
/*! Action method for SoWriteAction. Writes out a node object, and any connected nodes, engines etc, if necessary. */ void SoNode::write(SoWriteAction * action) { SoOutput * out = action->getOutput(); SoNode * node = this; SoProtoInstance * proto = SoProtoInstance::findProtoInstance(this); if (proto) { node = proto; } if (out->getStage() == SoOutput::COUNT_REFS) { node->addWriteReference(out, FALSE); } else if (out->getStage() == SoOutput::WRITE) { if (node->writeHeader(out, FALSE, FALSE)) return; // check for special case where we actually have to write out an // SoEngineOutput "field". An engine output might be connected via // an IS reference in a PROTO, and we then need to write back this // IS reference when exporting the VRML file. SoProto * proto = out->getCurrentProto(); if (proto && node->isOfType(SoNodeEngine::getClassTypeId())) { SoEngineOutputList l; const int num = ((SoNodeEngine*)node)->getOutputs(l); for (int i = 0; i < num; i++) { SbName name; if (((SoNodeEngine*)node)->getOutputName(l[i], name)) { SbName pname = proto->findISReference(node, name); if (pname.getLength()) { out->indent(); out->write(name.getString()); out->write(" IS "); out->write(pname.getString()); out->write("\n"); } } } } node->getFieldData()->write(out, node); node->writeFooter(out); } else assert(0 && "unknown stage"); }
SoMaterial * SoToVRMLActionP::find_or_create_material(void) { SoMaterial * mat = NULL; SoGroup * tail = this->get_current_tail(); int num = tail->getNumChildren(); while (--num >= 0 && mat == NULL) { SoNode * node = tail->getChild(num); if (node->isOfType(SoMaterial::getClassTypeId())) { mat = coin_assert_cast<SoMaterial*>(node); } } if (mat == NULL) { mat = new SoMaterial; tail->addChild(mat); } return mat; }
void SoGuiTranslation::doAction(SoAction * action) { // SoDebugError::postInfo("SoGuiTranslation::doAction", "invoked by %s", action->getTypeId().getName().getString()); int i; SoGuiPane * pane = NULL; const SoFullPath * path = (const SoFullPath *) action->getCurPath(); for ( i = path->getLength() - 1; (i >= 0) && (pane == NULL); i-- ) { SoNode * node = path->getNode(i); assert(node); if ( node->isOfType(SoGuiPane::getClassTypeId()) ) pane = (SoGuiPane *) node; } if ( pane == NULL ) { SoDebugError::postInfo("SoGuiTranslation::doAction", "SoGuiTranslation only works below an SoGuiPane node"); return; } SoModelMatrixElement::translateBy(action->getState(), this, this->translation.getValue()); // pane->moveBy(action->getState(), this->translation.getValue()); }
/*! 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 ViewProviderDragger::unsetEditViewer(Gui::View3DInventorViewer* viewer) { SoNode *child = static_cast<SoFCUnifiedSelection*>(viewer->getSceneGraph())->getChild(0); if (child && child->isOfType(SoPickStyle::getClassTypeId())) static_cast<SoFCUnifiedSelection*>(viewer->getSceneGraph())->removeChild(child); }
// doc from parent void SoFCSelection::handleEvent(SoHandleEventAction * action) { static char buf[513]; HighlightModes mymode = (HighlightModes) this->highlightMode.getValue(); const SoEvent * event = action->getEvent(); #ifdef NO_FRONTBUFFER // mouse move events for preselection if (event->isOfType(SoLocation2Event::getClassTypeId())) { // NOTE: If preselection is off then we do not check for a picked point because otherwise this search may slow // down extremely the system on really big data sets. In this case we just check for a picked point if the data // set has been selected. if (mymode == AUTO || mymode == ON) { const SoPickedPoint * pp = this->getPickedPoint(action); if (pp && pp->getPath()->containsPath(action->getCurPath())) { if (!highlighted) { if (Gui::Selection().setPreselect(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2])){ SoFCSelection::turnoffcurrent(action); SoFCSelection::currenthighlight = (SoFullPath*)action->getCurPath()->copy(); SoFCSelection::currenthighlight->ref(); highlighted = TRUE; this->touch(); // force scene redraw this->redrawHighlighted(action, TRUE); } } snprintf(buf,512,"Preselected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); getMainWindow()->showMessage(QString::fromAscii(buf),3000); } else { // picked point if (highlighted) { if (mymode == AUTO) SoFCSelection::turnoffcurrent(action); //FIXME: I think we should set 'highlighted' to false whenever no point is picked //else highlighted = FALSE; Gui::Selection().rmvPreselect(); } } } } // key press events else if (event->isOfType(SoKeyboardEvent ::getClassTypeId())) { SoKeyboardEvent * const e = (SoKeyboardEvent *) event; if (SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::LEFT_SHIFT) || SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::RIGHT_SHIFT) ) bShift = true; if (SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::LEFT_SHIFT) || SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::RIGHT_SHIFT) ) bShift = false; if (SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::LEFT_CONTROL) || SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::RIGHT_CONTROL) ) bCtrl = true; if (SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::LEFT_CONTROL) || SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::RIGHT_CONTROL) ) bCtrl = false; } // mouse press events for (de)selection else if (event->isOfType(SoMouseButtonEvent::getClassTypeId())) { SoMouseButtonEvent * const e = (SoMouseButtonEvent *) event; if (SoMouseButtonEvent::isButtonReleaseEvent(e,SoMouseButtonEvent::BUTTON1)) { //FIXME: Shouldn't we remove the preselection for newly selected objects? // Otherwise the tree signals that an object is preselected even though it is hidden. (Werner) const SoPickedPoint * pp = this->getPickedPoint(action); if (pp && pp->getPath()->containsPath(action->getCurPath())) { if (bCtrl) { if (Gui::Selection().isSelected(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString())) { Gui::Selection().rmvSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString()); } else { Gui::Selection().addSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); if (mymode == OFF) { snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); getMainWindow()->showMessage(QString::fromAscii(buf),3000); } } } else { // Ctrl if (!Gui::Selection().isSelected(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString())) { Gui::Selection().clearSelection(documentName.getValue().getString()); Gui::Selection().addSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); } else { Gui::Selection().clearSelection(documentName.getValue().getString()); Gui::Selection().addSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,0 ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); } if (mymode == OFF) { snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); getMainWindow()->showMessage(QString::fromAscii(buf),3000); } } action->setHandled(); } // picked point } // mouse release } inherited::handleEvent(action); #else // If we don't need to pick for locate highlighting, // then just behave as separator and return. // NOTE: we still have to pick for ON even though we don't have // to re-render, because the app needs to be notified as the mouse // goes over locate highlight nodes. //if (highlightMode.getValue() == OFF) { // inherited::handleEvent( action ); // return; //} // // If this is a mouseMotion event, then check for locate highlighting // if (event->isOfType(SoLocation2Event::getClassTypeId())) { // check to see if the mouse is over our geometry... SbBool underTheMouse = FALSE; const SoPickedPoint * pp = this->getPickedPoint(action); SoFullPath *pPath = (pp != NULL) ? (SoFullPath *) pp->getPath() : NULL; if (pPath && pPath->containsPath(action->getCurPath())) { // Make sure I'm the lowest LocHL in the pick path! underTheMouse = TRUE; for (int i = 0; i < pPath->getLength(); i++) { SoNode *node = pPath->getNodeFromTail(i); if (node->isOfType(SoFCSelection::getClassTypeId())) { if (node != this) underTheMouse = FALSE; break; // found the lowest LocHL - look no further } } } // Am I currently highlighted? if (isHighlighted(action)) { if (! underTheMouse) { // re-draw the object with it's normal color //if(mymode != OFF) redrawHighlighted(action, FALSE); Gui::Selection().rmvPreselect(); } else { action->setHandled(); //const SoPickedPoint * pp = action->getPickedPoint(); Gui::Selection().setPreselectCoord(pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); } } // Else I am not currently highlighted else { // If under the mouse, then highlight! if (underTheMouse) { // draw this object highlighted if (mymode != OFF) redrawHighlighted(action, TRUE); //const SoPickedPoint * pp = action->getPickedPoint(); Gui::Selection().setPreselect(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); } } //if(selected == SELECTED){ // redrawHighlighted(action, TRUE); //} //if(selectionCleared ){ // redrawHighlighted(action, FALSE); // selectionCleared = false; //} } // key press events else if (event->isOfType(SoKeyboardEvent ::getClassTypeId())) { SoKeyboardEvent * const e = (SoKeyboardEvent *) event; if (SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::LEFT_SHIFT) || SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::RIGHT_SHIFT) ) bShift = true; if (SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::LEFT_SHIFT) || SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::RIGHT_SHIFT) ) bShift = false; if (SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::LEFT_CONTROL) || SoKeyboardEvent::isKeyPressEvent(e,SoKeyboardEvent::RIGHT_CONTROL) ) bCtrl = true; if (SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::LEFT_CONTROL) || SoKeyboardEvent::isKeyReleaseEvent(e,SoKeyboardEvent::RIGHT_CONTROL) ) bCtrl = false; } // mouse press events for (de)selection (only if selection is enabled on this node) else if (event->isOfType(SoMouseButtonEvent::getClassTypeId()) && selectionMode.getValue() == SoFCSelection::SEL_ON) { SoMouseButtonEvent * const e = (SoMouseButtonEvent *) event; if (SoMouseButtonEvent::isButtonReleaseEvent(e,SoMouseButtonEvent::BUTTON1)) { //FIXME: Shouldn't we remove the preselection for newly selected objects? // Otherwise the tree signals that an object is preselected even though it is hidden. (Werner) const SoPickedPoint * pp = this->getPickedPoint(action); if (pp && pp->getPath()->containsPath(action->getCurPath())) { if (bCtrl) { if (Gui::Selection().isSelected(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString())) { Gui::Selection().rmvSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString()); } else { Gui::Selection().addSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); if (mymode == OFF) { snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); getMainWindow()->statusBar()->showMessage(QString::fromAscii(buf),3000); } } } else { // Ctrl if (!Gui::Selection().isSelected(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString())) { Gui::Selection().clearSelection(documentName.getValue().getString()); Gui::Selection().addSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); } else { Gui::Selection().clearSelection(documentName.getValue().getString()); Gui::Selection().addSelection(documentName.getValue().getString() ,objectName.getValue().getString() ,0 ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); } if (mymode == OFF) { snprintf(buf,512,"Selected: %s.%s.%s (%f,%f,%f)",documentName.getValue().getString() ,objectName.getValue().getString() ,subElementName.getValue().getString() ,pp->getPoint()[0] ,pp->getPoint()[1] ,pp->getPoint()[2]); getMainWindow()->statusBar()->showMessage(QString::fromAscii(buf),3000); } } action->setHandled(); } // picked point } // mouse release } // Let the base class traverse the children. if (action->getGrabber() != this) inherited::handleEvent(action); #endif }
void SoVtkAssembly::updateChildren() { for (int i = 0; i < SoGroup::getNumChildren(); i++) { SoNode *child = SoGroup::getChild(i); if (child->isOfType(SoVtkAssembly::getClassTypeId())) { // assembly SoVtkAssembly *assembly = (SoVtkAssembly *) child; assembly->updateChildren(); } } vtkProp3DCollection *parts = mAssembly->GetParts(); for (int i = 0; i < parts->GetNumberOfItems(); i++) { mAssembly->RemovePart(vtkProp3D::SafeDownCast(parts->GetItemAsObject(i))); } for (int i = 0; i < SoGroup::getNumChildren(); i++) { SoNode *child = SoGroup::getChild(i); if (child->isOfType(SoVtkActor::getClassTypeId())) { // actor SoVtkActor *actor = (SoVtkActor *) child; mAssembly->AddPart(actor->getActor()); } if (child->isOfType(SoVtkLODActor::getClassTypeId())) { // actor SoVtkLODActor *actor = (SoVtkLODActor *) child; mAssembly->AddPart(actor->getLODActor()); } if (child->isOfType(SoVtkActor2D::getClassTypeId())) { // actor 2D SoVtkActor2D *actor = (SoVtkActor2D *) child; mAssembly->AddPart(vtkProp3D::SafeDownCast(actor->getActor2D())); } if (child->isOfType(SoVtkImageActor::getClassTypeId())) { // image actor SoVtkImageActor *actor = (SoVtkImageActor *) child; mAssembly->AddPart(actor->getImageActor()); } if (child->isOfType(SoVtkVolume::getClassTypeId())) { // volume SoVtkVolume *vol = (SoVtkVolume *) child; mAssembly->AddPart(vol->getVolume()); } if (child->isOfType(SoVtkAssembly::getClassTypeId())) { // assembly SoVtkAssembly *assembly = (SoVtkAssembly *) child; mAssembly->AddPart(vtkAssembly::SafeDownCast(assembly->getAssembly())); } } }
////////////////////////////////////////////////////////////////////////////// // // 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); } } }
int main(int argc, char ** argv) { fprintf(stderr, "ivcp v0.1\n"); SoDB::init(); SoNodeKit::init(); SoInteraction::init(); if (argc != 3 ) { fprintf(stdout, "Usage: %s infile outfile\n", argv[0]); return 0; } SoInput * in = new SoInput; if (!in->openFile(argv[1])) { fprintf(stderr, "error: could not open file '%s'\n", argv[1]); delete in; SoDB::cleanup(); return -1; } SoNode * scene = SoDB::readAll(in); if (!scene) { fprintf(stderr, "error: could not read file '%s'\n", argv[1]); delete in; SoDB::cleanup(); return -1; } FileType inputFileType; if (in->isFileVRML1()) inputFileType = VRML1; else if (in->isFileVRML2()) inputFileType = VRML2; else inputFileType = INVENTOR; delete in; scene->ref(); SoNode * firstChild = static_cast<SoSeparator*>(scene)->getNumChildren()? static_cast<SoSeparator*>(scene)->getChild(0) :NULL; if (firstChild && firstChild->isOfType(SoForeignFileKit::getClassTypeId())) { SoForeignFileKit * kit = (SoForeignFileKit *) firstChild; if (kit->canWriteScene() ) { SoNode * subscene = NULL; kit->writeScene(subscene); if (!subscene ) { return -1; } subscene->ref(); scene->unref(); scene = subscene; } } SoOutput * out = new SoOutput; if (!out->openFile(argv[2])) { fprintf(stderr, "error: could not open file '%s' for writing\n"); scene->unref(); delete out; SoDB::cleanup(); return -1; } switch (inputFileType) { case VRML1: out->setHeaderString("#VRML V1.0 ascii"); break; case VRML2: out->setHeaderString("#VRML V2.0 utf8"); } SoWriteAction wa(out); wa.apply(scene); out->closeFile(); delete out; scene->unref(); // with actions on the stack, cleanup can't be called... // SoDB::cleanup(); return 0; }