TSeparatorKit* ComponentHeliostatField::OpenHeliostatComponent( QString fileName ) { if ( fileName.isEmpty() ) return 0; SoInput componentInput; if ( !componentInput.openFile( fileName.toLatin1().constData() ) ) { QMessageBox::warning( 0, QString( "Scene Graph Structure" ), QString( "Cannot open file %1:\n." ).arg( fileName ) ); return 0; } SoSeparator* componentSeparator = SoDB::readAll( &componentInput ); componentInput.closeFile(); if ( !componentSeparator ) { QMessageBox::warning( 0, QString( "Scene Graph Structure" ), QString( "Error reading file %1:\n%2." ) .arg( fileName ) ); return 0; } TSeparatorKit* componentRoot = static_cast< TSeparatorKit* >( componentSeparator->getChild(0) ); componentRoot->ref(); return componentRoot; }
void SimDynamicsWindow::updateComVisu() { if (!robot) { return; } std::vector<RobotNodePtr> n = robot->getRobotNodes(); std::map< VirtualRobot::RobotNodePtr, SoSeparator* >::iterator i = comVisuMap.begin(); while (i != comVisuMap.end()) { SoSeparator* sep = i->second; SoMatrixTransform* m = dynamic_cast<SoMatrixTransform*>(sep->getChild(0)); if (m) { Eigen::Matrix4f ma = dynamicsRobot->getComGlobal(i->first); ma.block(0, 3, 3, 1) *= 0.001f; m->matrix.setValue(CoinVisualizationFactory::getSbMatrix(ma)); } i++; } }
/*! * Reads the scene saved on the file with given \a filename and return a pointer to the scene. * * Returns null on any error. */ TSceneKit* Document::GetSceneKitFromFile( const QString& fileName ) { SoInput sceneInput; if ( !sceneInput.openFile( fileName.toLatin1().constData() ) ) { QString message = QString( "Cannot open file %1." ).arg( fileName ); emit Warning( message ); return 0; } if( !sceneInput.isValidFile() ) { QString message = QString( "Error reading file %1.\n" ).arg( fileName ); emit Warning( message ); return 0; } SoSeparator* graphSeparator = SoDB::readAll( &sceneInput ); sceneInput.closeFile(); if ( !graphSeparator ) { QString message = QString( "Error reading file %1.\n" ).arg( fileName ); emit Warning( message ); return 0; } return static_cast< TSceneKit* >( graphSeparator->getChild(0) ); 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 SoRegPoint::notify(SoNotList * node) { SoField * f = node->getLastField(); if (f == &this->base || f == &this->normal || f == &this->length) { SoTranslation* move = static_cast<SoTranslation*>(root->getChild(0)); move->translation.setValue(base.getValue() + normal.getValue() * length.getValue()); } else if (f == &this->color) { SoSeparator* sub = static_cast<SoSeparator*>(root->getChild(1)); SoBaseColor* col = static_cast<SoBaseColor*>(sub->getChild(0)); col->rgb = this->color.getValue(); } else if (f == &this->text) { SoSeparator* sub = static_cast<SoSeparator*>(root->getChild(1)); SoText2* label = static_cast<SoText2*>(sub->getChild(2)); label->string = this->text.getValue(); } SoShape::notify(node); }
void ViewProviderTransformed::unsetEdit(int ModNum) { ViewProvider::unsetEdit(ModNum); while (pcRejectedRoot->getNumChildren() > 7) { SoSeparator* sep = static_cast<SoSeparator*>(pcRejectedRoot->getChild(7)); SoMultipleCopy* rejectedTrfms = static_cast<SoMultipleCopy*>(sep->getChild(2)); rejectedTrfms ->removeAllChildren(); sep->removeChild(1); sep->removeChild(0); pcRejectedRoot ->removeChild(7); } pcRejectedRoot->removeAllChildren(); pcRoot->removeChild(pcRejectedRoot); pcRejectedRoot->unref(); }
IvObjectDragger::IvObjectDragger(QtCoinViewerPtr viewer, ItemPtr pItem, float draggerScale, bool bAllowRotation) : IvDragger(viewer, pItem, draggerScale) { // create a root node for the dragger nodes _draggerRoot = new SoSeparator; ItemPtr selectedItem = GetSelectedItem(); selectedItem->GetIvRoot()->insertChild(_draggerRoot, 0); // create and size a transform box dragger and then add it to the scene graph _transformBox = new SoTransformBoxDragger; _transformBox->scaleFactor.setValue(_ab.extents.x * _scale, _ab.extents.y * _scale, _ab.extents.z * _scale); _transformBox->translation.setValue(_ab.pos.x, _ab.pos.y, _ab.pos.z); _toffset = selectedItem->GetTransform(); _draggerRoot->addChild(_transformBox); // disable the scaling part of the transform box _transformBox->setPart("scaler", NULL); // disable the rotation around the X and Z axes if (!bAllowRotation) { const char *rotators[2] = { "rotator1", "rotator3" }; for (int i = 0; i < 2; i++) _transformBox->setPart(rotators[i], NULL); } // get the material node that governs the color of the dragger and // note the dragger's normal color if (bAllowRotation) { SoRotateCylindricalDragger *rp = (SoRotateCylindricalDragger *)_transformBox->getPart("rotator1", false); SoSeparator *s = (SoSeparator *) rp->getPart("rotator", false); _draggerMaterial = (SoMaterial *) s->getChild(0); } else _draggerMaterial = new SoMaterial(); _normalColor = _draggerMaterial->diffuseColor[0]; // add a motion callback handler for the dragger _transformBox->addMotionCallback(_MotionHandler, this); UpdateDragger(); }
IvJointDragger::IvJointDragger(QtCoinViewerPtr viewer, ItemPtr pItem, int iSelectedLink, float draggerScale, int iJointIndex, bool bHilitJoint) : IvDragger(viewer, pItem, draggerScale) { KinBodyItemPtr pbody = boost::dynamic_pointer_cast<KinBodyItem>(pItem); BOOST_ASSERT( !!pItem ); _trackball = NULL; _draggerRoot = NULL; if( !pbody || !pbody->GetBody() ) { return; } if((iSelectedLink < 0)||(iSelectedLink >= (int)pbody->GetBody()->GetLinks().size())) { return; } if((iJointIndex < 0)||(iJointIndex >= (int)pbody->GetBody()->GetJoints().size())) { return; } _iSelectedLink = iSelectedLink; _iJointIndex = iJointIndex; KinBody::JointConstPtr pjoint = pbody->GetBody()->GetJoints().at(iJointIndex); _jointtype = pjoint->GetType(); _dofindex = pjoint->GetDOFIndex(); _jointname = pjoint->GetName(); _jointoffset = 0; //pjoint->GetOffset(); pjoint->GetLimits(_vlower,_vupper); _pLinkNode = pbody->GetIvLink(iSelectedLink); if( _pLinkNode == NULL ) { RAVELOG_WARN("no link is selected\n"); return; } Transform tlink = pbody->GetBody()->GetLinks().at(iSelectedLink)->GetTransform(); // create a root node for the dragger nodes _draggerRoot = new SoSeparator; SoTransform* draggertrans = new SoTransform(); _pLinkNode->insertChild(_draggerRoot, 1); // insert right after transform // add a new material to change the color of the nodes being dragged _bHilitJoint = bHilitJoint; if (_bHilitJoint) { _material = new SoMaterial; _material->set("diffuseColor 0.8 0.6 0.2"); _material->setOverride(true); _pLinkNode->insertChild(_material, 1); } Vector vaxes[3]; for(int i = 0; i < pjoint->GetDOF(); ++i) { vaxes[i] = tlink.inverse().rotate(pjoint->GetAxis(i)); } // need to make sure the rotation is pointed towards the joint axis Vector vnorm = Vector(1,0,0).cross(vaxes[0]); dReal fsinang = RaveSqrt(vnorm.lengthsqr3()); if( fsinang > 0.0001f ) { vnorm /= fsinang; } else vnorm = Vector(1,0,0); Vector vtrans = tlink.inverse()*pjoint->GetAnchor(); draggertrans->translation.setValue(vtrans.x, vtrans.y, vtrans.z); draggertrans->rotation = SbRotation(SbVec3f(vnorm.x, vnorm.y, vnorm.z), atan2f(fsinang,vaxes[0].x)); _draggerRoot->addChild(draggertrans); // construct an Inventor trackball dragger float scale = _scale; _trackball = new SoTrackballDragger; AABB ab; _GetBounds(_pLinkNode, ab); _trackball->scaleFactor.setValue(ab.extents.x * scale, ab.extents.y * scale, ab.extents.z * scale); _trackball->setAnimationEnabled(false); _draggerRoot->addChild(_trackball); // get the material nodes that govern the color of the dragger and // note the dragger's normal color const char* rotators[3] = { "XRotator", "YRotator", "ZRotator" }; const char* rotatorsActive[3] = { "XRotatorActive", "YRotatorActive", "ZRotatorActive" }; // enable or disable each axis for (int i = 0; i < 3; i++) { if (i < pjoint->GetDOF()) { SoSeparator *s = (SoSeparator *)_trackball->getPart(rotators[i], false); _draggerMaterial[i] = (SoMaterial *) s->getChild(0); _normalColor = _draggerMaterial[i]->diffuseColor[0]; } else { // disable the rotator on this axis _trackball->setPart(rotators[i], NULL); _trackball->setPart(rotatorsActive[i], NULL); _draggerMaterial[i] = NULL; } } // add a motion callback handler for the dragger _trackball->addMotionCallback(_MotionHandler, this); UpdateDragger(); }
void ViewProviderTransformed::recomputeFeature(void) { PartDesign::Transformed* pcTransformed = static_cast<PartDesign::Transformed*>(getObject()); pcTransformed->getDocument()->recomputeFeature(pcTransformed); const std::vector<App::DocumentObjectExecReturn*> log = pcTransformed->getDocument()->getRecomputeLog(); PartDesign::Transformed::rejectedMap rejected_trsf = pcTransformed->getRejectedTransformations(); unsigned rejected = 0; for (PartDesign::Transformed::rejectedMap::const_iterator r = rejected_trsf.begin(); r != rejected_trsf.end(); r++) rejected += r->second.size(); QString msg = QString::fromLatin1("%1"); if (rejected > 0) { msg = QString::fromLatin1("<font color='orange'>%1<br/></font>\r\n%2"); if (rejected == 1) msg = msg.arg(QObject::tr("One transformed shape does not intersect support")); else { msg = msg.arg(QObject::tr("%1 transformed shapes do not intersect support")); msg = msg.arg(rejected); } } if (log.size() > 0) { msg = msg.arg(QString::fromLatin1("<font color='red'>%1<br/></font>")); msg = msg.arg(QString::fromStdString(log.back()->Why)); } else { msg = msg.arg(QString::fromLatin1("<font color='green'>%1<br/></font>")); msg = msg.arg(QObject::tr("Transformation succeeded")); } signalDiagnosis(msg); // Clear all the rejected stuff while (pcRejectedRoot->getNumChildren() > 7) { SoSeparator* sep = static_cast<SoSeparator*>(pcRejectedRoot->getChild(7)); SoMultipleCopy* rejectedTrfms = static_cast<SoMultipleCopy*>(sep->getChild(2)); rejectedTrfms ->removeAllChildren(); sep->removeChild(1); sep->removeChild(0); pcRejectedRoot ->removeChild(7); } for (PartDesign::Transformed::rejectedMap::const_iterator o = rejected_trsf.begin(); o != rejected_trsf.end(); o++) { if (o->second.empty()) continue; TopoDS_Shape shape; if ((o->first)->getTypeId().isDerivedFrom(PartDesign::FeatureAddSub::getClassTypeId())) { PartDesign::FeatureAddSub* feature = static_cast<PartDesign::FeatureAddSub*>(o->first); shape = feature->AddSubShape.getShape().getShape(); } if (shape.IsNull()) continue; // Display the rejected transformations in red TopoDS_Shape cShape(shape); try { // calculating the deflection value Standard_Real xMin, yMin, zMin, xMax, yMax, zMax; { Bnd_Box bounds; BRepBndLib::Add(cShape, bounds); bounds.SetGap(0.0); bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax); } Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 * Deviation.getValue(); // create or use the mesh on the data structure // Note: This DOES have an effect on cShape #if OCC_VERSION_HEX >= 0x060600 Standard_Real AngDeflectionRads = AngularDeflection.getValue() / 180.0 * M_PI; BRepMesh_IncrementalMesh(cShape,deflection,Standard_False, AngDeflectionRads,Standard_True); #else BRepMesh_IncrementalMesh(cShape,deflection); #endif // We must reset the location here because the transformation data // are set in the placement property TopLoc_Location aLoc; cShape.Location(aLoc); // count triangles and nodes in the mesh int nbrTriangles=0, nbrNodes=0; TopExp_Explorer Ex; for (Ex.Init(cShape,TopAbs_FACE);Ex.More();Ex.Next()) { Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(TopoDS::Face(Ex.Current()), aLoc); // Note: we must also count empty faces if (!mesh.IsNull()) { nbrTriangles += mesh->NbTriangles(); nbrNodes += mesh->NbNodes(); } } // create memory for the nodes and indexes SoCoordinate3* rejectedCoords = new SoCoordinate3(); rejectedCoords ->point .setNum(nbrNodes); SoNormal* rejectedNorms = new SoNormal(); rejectedNorms ->vector .setNum(nbrNodes); SoIndexedFaceSet* rejectedFaceSet = new SoIndexedFaceSet(); rejectedFaceSet ->coordIndex .setNum(nbrTriangles*4); // get the raw memory for fast fill up SbVec3f* verts = rejectedCoords ->point .startEditing(); SbVec3f* norms = rejectedNorms ->vector .startEditing(); int32_t* index = rejectedFaceSet ->coordIndex .startEditing(); // preset the normal vector with null vector for (int i=0; i < nbrNodes; i++) norms[i]= SbVec3f(0.0,0.0,0.0); int ii = 0,FaceNodeOffset=0,FaceTriaOffset=0; for (Ex.Init(cShape, TopAbs_FACE); Ex.More(); Ex.Next(),ii++) { TopLoc_Location aLoc; const TopoDS_Face &actFace = TopoDS::Face(Ex.Current()); // get the mesh of the shape Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(actFace,aLoc); if (mesh.IsNull()) continue; // getting the transformation of the shape/face gp_Trsf myTransf; Standard_Boolean identity = true; if (!aLoc.IsIdentity()) { identity = false; myTransf = aLoc.Transformation(); } // getting size of node and triangle array of this face int nbNodesInFace = mesh->NbNodes(); int nbTriInFace = mesh->NbTriangles(); // check orientation TopAbs_Orientation orient = actFace.Orientation(); // cycling through the poly mesh const Poly_Array1OfTriangle& Triangles = mesh->Triangles(); const TColgp_Array1OfPnt& Nodes = mesh->Nodes(); for (int g=1; g <= nbTriInFace; g++) { // Get the triangle Standard_Integer N1,N2,N3; Triangles(g).Get(N1,N2,N3); // change orientation of the triangle if the face is reversed if ( orient != TopAbs_FORWARD ) { Standard_Integer tmp = N1; N1 = N2; N2 = tmp; } // get the 3 points of this triangle gp_Pnt V1(Nodes(N1)), V2(Nodes(N2)), V3(Nodes(N3)); // transform the vertices to the place of the face if (!identity) { V1.Transform(myTransf); V2.Transform(myTransf); V3.Transform(myTransf); } // calculating per vertex normals // Calculate triangle normal gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z()); gp_Vec Normal = (v2-v1)^(v3-v1); // add the triangle normal to the vertex normal for all points of this triangle norms[FaceNodeOffset+N1-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z()); norms[FaceNodeOffset+N2-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z()); norms[FaceNodeOffset+N3-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z()); // set the vertices verts[FaceNodeOffset+N1-1].setValue((float)(V1.X()),(float)(V1.Y()),(float)(V1.Z())); verts[FaceNodeOffset+N2-1].setValue((float)(V2.X()),(float)(V2.Y()),(float)(V2.Z())); verts[FaceNodeOffset+N3-1].setValue((float)(V3.X()),(float)(V3.Y()),(float)(V3.Z())); // set the index vector with the 3 point indexes and the end delimiter index[FaceTriaOffset*4+4*(g-1)] = FaceNodeOffset+N1-1; index[FaceTriaOffset*4+4*(g-1)+1] = FaceNodeOffset+N2-1; index[FaceTriaOffset*4+4*(g-1)+2] = FaceNodeOffset+N3-1; index[FaceTriaOffset*4+4*(g-1)+3] = SO_END_FACE_INDEX; } // counting up the per Face offsets FaceNodeOffset += nbNodesInFace; FaceTriaOffset += nbTriInFace; } // normalize all normals for (int i=0; i < nbrNodes; i++) norms[i].normalize(); // end the editing of the nodes rejectedCoords ->point .finishEditing(); rejectedNorms ->vector .finishEditing(); rejectedFaceSet ->coordIndex .finishEditing(); // fill in the transformation matrices SoMultipleCopy* rejectedTrfms = new SoMultipleCopy(); rejectedTrfms->matrix.setNum((o->second).size()); SbMatrix* mats = rejectedTrfms->matrix.startEditing(); std::list<gp_Trsf>::const_iterator trsf = (o->second).begin(); for (unsigned int i=0; i < (o->second).size(); i++,trsf++) { Base::Matrix4D mat; Part::TopoShape::convertToMatrix(*trsf,mat); mats[i] = convert(mat); } rejectedTrfms->matrix.finishEditing(); rejectedTrfms->addChild(rejectedFaceSet); SoSeparator* sep = new SoSeparator(); sep->addChild(rejectedCoords); sep->addChild(rejectedNorms); sep->addChild(rejectedTrfms); pcRejectedRoot->addChild(sep); } catch (...) { Base::Console().Error("Cannot compute Inventor representation for the rejected transformations of shape of %s.\n", pcTransformed->getNameInDocument()); } } }
IVElement::IVElement(string ivfile, KthReal sc) { for(int i=0;i<3;i++){ position[i]= 0.0f; orientation[i]=0.0f; } orientation[2]=1.0f; orientation[3]=0.0f; scale=sc; trans= new SoTranslation; rot = new SoRotation; sca = new SoScale(); color = new SoMaterial; posVec = new SoSFVec3f; trans->translation.connectFrom(posVec); posVec->setValue((float)position[0],(float)position[1],(float)position[2]); rotVec = new SoSFRotation; rotVec->setValue(SbVec3f((float)orientation[0],(float)orientation[1], (float)orientation[2]),(float)orientation[3]); rot->rotation.connectFrom(rotVec); scaVec= new SoSFVec3f; scaVec->setValue((float)scale,(float)scale,(float)scale); sca->scaleFactor.connectFrom(scaVec); SoInput input; ivmodel = new SoSeparator; ivmodel->ref(); ivmodel->addChild(sca); if(input.openFile(ivfile.c_str())) ivmodel->addChild(SoDB::readAll(&input)); else { //ivmodel->addChild(new SoSphere()); static const char *str[] = { "#VRML V1.0 ascii\n", "DEF pointgoal Separator {\n", " Separator {\n", " MaterialBinding { value PER_PART }\n", " Coordinate3 {\n", " point [\n", " 0.0 0.0 0.0\n", " ]\n", " }\n", " DrawStyle { pointSize 5 }\n", " PointSet { }\n", " }\n", "}\n", NULL }; input.setStringArray(str); SoSeparator *sep = SoDB::readAll(&input); sep->ref(); while (sep->getNumChildren() > 0) { ivmodel->addChild(sep->getChild(0)); sep->removeChild(0); } sep->unref(); } ivmodel->ref(); }
SoCamera * SoSceneTextureCubeMapP::ensureCamera(void) { if (this->hasSceneChanged == FALSE) return this->cachedCamera; this->hasSceneChanged = FALSE; SoCamera * camera = this->findCamera(); SbBool hasCamera = (camera != NULL); // does the scene provide a camera? if (hasCamera) { if (this->cachedCamera != camera) { if (this->cachedCamera) this->cachedCamera->unref(); this->cachedCamera = camera; this->cachedCamera->ref(); } } else if (this->hadSceneCamera || this->cachedCamera == NULL) { // create default camera: static int didwarn = 0; if (!didwarn) { SoDebugError::postWarning("SoSceneTextureCubeMap::ensureCamera", "The scene does not provide a camera. " "A perspective camera at position (0,0,0) " "will be used."); didwarn = 1; } if (this->cachedCamera) this->cachedCamera->unref(); this->cachedCamera = new SoPerspectiveCamera; this->cachedCamera->position = SbVec3f(0, 0, 0); this->cachedCamera->nearDistance = 0.1f; this->cachedCamera->farDistance = 100; ((SoPerspectiveCamera*)this->cachedCamera)->heightAngle = (float) (M_PI / 2.0f); this->cachedCamera->ref(); } assert(this->cachedCamera); SoNode * scene = PUBLIC(this)->scene.getValue(); if (hasCamera) { if (scene != this->cachedScene) { if (this->cachedScene) this->cachedScene->unref(); this->cachedScene = scene; this->cachedScene->ref(); } } else if (this->cachedScene == NULL || this->hadSceneCamera) { if (this->cachedScene) this->cachedScene->unref(); SoSeparator * root = new SoSeparator(); root->addChild(this->cachedCamera); root->addChild(scene); this->cachedScene = (SoNode *)root; this->cachedScene->ref(); } else { assert(this->cachedScene->isOfType(SoSeparator::getClassTypeId())); SoSeparator * root = (SoSeparator*)this->cachedScene; assert(root->getNumChildren() == 2); if (root->getChild(1) != scene) ((SoSeparator *)this->cachedScene)->replaceChild(1, scene); } this->hadSceneCamera = hasCamera; return this->cachedCamera; }
void SoFCBoundingBox::GLRender (SoGLRenderAction *action) { SbVec3f corner[2], ctr, *vptr; SbBool coord, dimension; // grab the current state //SoState *state = action->getState(); if (!shouldGLRender(action)) return; // get the latest values from the fields corner[0] = minBounds.getValue(); corner[1] = maxBounds.getValue(); coord = coordsOn.getValue(); dimension = dimensionsOn.getValue(); // set the coordinates for the LineSet to point to vptr = bboxCoords->point.startEditing(); for (int i = 0; i < 8; i++) { for (int j = 0; j < 3; j++) { vptr[i][j] = corner[bBoxVerts[i][j]][j]; } } // if coord is true then set the text nodes if (coord) { ctr = (corner[1] - corner[0]) / 2.0f; for (int i = 0; i < 8; i++) { // create the string for the text std::stringstream str; str.precision(2); str.setf(std::ios::fixed | std::ios::showpoint); str << "(" << vptr[i][0] << "," << vptr[i][1] << "," << vptr[i][2] << ")"; SoSeparator *sep = (SoSeparator *)textSep->getChild(i); SoTransform *trans = (SoTransform *)sep->getChild(0); trans->translation.setValue(vptr[i].getValue()); SoText2* t = (SoText2 *)sep->getChild(1); t->string.setValue(str.str().c_str()); } textSep->ref(); if (root->findChild(textSep) < 0) root->addChild(textSep); } else { if (root->findChild(textSep) >= 0) root->removeChild(textSep); } // if dimension is true then set the text nodes if (dimension) { ctr = (corner[1] - corner[0]) / 2.0f; for (int i = 0; i < 3; i++) { // create the string for the text std::stringstream str; str.precision(2); str.setf(std::ios::fixed | std::ios::showpoint); str << (2.0f * ctr[i]); SoSeparator *sep = (SoSeparator *)dimSep->getChild(i); SoTransform *trans = (SoTransform *)sep->getChild(0); SbVec3f point = corner[0]; point[i] += ctr[i]; trans->translation.setValue(point.getValue()); SoText2* t = (SoText2 *)sep->getChild(1); t->string.setValue(str.str().c_str()); } dimSep->ref(); if (root->findChild(dimSep) < 0) root->addChild(dimSep); } else { if (root->findChild(dimSep) >= 0) root->removeChild(dimSep); } bboxCoords->point.finishEditing(); // Avoid shading SoState * state = action->getState(); state->push(); SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR); root->GLRender(action); state->pop(); }