void SoFile::copyContents(const SoFieldContainer *fromFC, SbBool copyConnections) // //////////////////////////////////////////////////////////////////////// { // Detach sensor temporarily so we do not read the file again nameChangedSensor->detach(); // Copy the usual stuff SoNode::copyContents(fromFC, copyConnections); // Copy the kids const SoFile *fromGroup = (const SoFile *) fromFC; SoChildList *fromChildren = fromGroup->getChildren(); for (int i = 0; i < fromChildren->getLength(); i++) { // If this node is being copied, it must be "inside" (see // SoNode::copy() for details.) Therefore, all of its children // must be inside, as well. SoNode *fromKid = (*fromChildren)[i]; SoNode *kidCopy = (SoNode *) findCopy(fromKid, copyConnections); #ifdef DEBUG if (kidCopy == NULL) SoDebugError::post("(internal) SoFile::copyContents", "Child %d has not been copied yet", i); #endif /* DEBUG */ children.append(kidCopy); } // Reattach sensor nameChangedSensor->attach(&name); }
/*! \fn SoXipGLSLUniformGroup::doAction(SoAction * action) * Adds a node to the SoXipGLSLUniformGroupElement in the current state * \param action - the current state action, no action taken if input action is NULL * \return void */ void SoXipGLSLUniformGroup::groupUpdate(SoAction * action) { SoChildList * children = this->getChildren(); GLint prg = SoXipGLSLShaderProgramElement::get(action->getState()); if (mNumPrograms > GLSL_MAX_NUM_SHADERS) { SoDebugError::postWarning(__FUNCTION__, "supports %i shaders (requested %d)", GLSL_MAX_NUM_SHADERS, mNumPrograms); mNumPrograms = GLSL_MAX_NUM_SHADERS; } for (int i = 0; i < mNumPrograms; i++) { /* To prevent uniforms from updating every frame we only update the uniform if the time stamp of the selected shader is out of date or if anything has changed among the uniforms such as names or values. TODO: This fix do not work since we have no way of knowing if other instances of this node also changes the same uniforms. Since this will not change the timestamp in the manager the uniform remains as last updated and fix don't work. No solution to the problem yet! Stefan Lindholm */ #if 0 int handle = SoXipGLSLShaderProgramElement::getProgramID(action->getState(), prgTags[i].getString()); if (glIsProgram(handle)) { SoXipGLSLShaderProgramElement::set(action->getState(), prgTags[i].getString()); children->traverse(action); } #else __uint64 currTime = SoXipGLSLShaderProgramElement::getTimeStamp(action->getState(), prgTags[i].getString()); if (currTime != mProgramTimeStamps[i] || mNeedsUpdate) { SoXipGLSLShaderProgramElement::set(action->getState(), prgTags[i].getString()); children->traverse(action); mProgramTimeStamps[i] = currTime; } #endif } SoXipGLSLShaderProgramElement::set(action->getState(), prg); mNeedsUpdate = false; }
/*! Updates \a path to be the same path as this path. */ void SoLightPath::makeTempPath(SoTempPath *path) const { const int n = this->indices.getLength(); SoNode *node = this->headnode; path->setHead(node); for (int i = 1; i < n; i++) { int childidx = this->indices[i]; // check validity of path, return if invalid SoChildList *children = node->getChildren(); if (children == NULL || childidx < 0 || childidx >= children->getLength()) break; node = (*children)[childidx]; path->append(childidx); // childidx should be ok } }
/*! Add a copy of this node and (recursively) all children to the copy dictionary of SoFieldContainer if this has not already been done. Used internally during copy operations. */ SoNode * SoNode::addToCopyDict(void) const { #if COIN_DEBUG && 0 // debug SoDebugError::postInfo("SoNode::addToCopyDict", "%s node", this->getTypeId().getName().getString()); #endif // debug SoNode * cp = (SoNode *)SoFieldContainer::checkCopy(this); if (!cp) { // We need to do some extra work when copying nodes that are // ProtoInstance root nodes. We create a new ProtoInstance node, // and register its root node as the copy. pederb, 2002-06-17 SoProtoInstance * inst = SoProtoInstance::findProtoInstance(this); if (inst) { SoProto * proto = inst->getProtoDefinition(); SoProtoInstance * newinst = proto->createProtoInstance(); if (inst->getName().getLength()) newinst->setName(inst->getName()); cp = newinst->getRootNode(); assert(cp); // We have to call addCopy() before calling copyContents() since // the proto instance might have a field that has a pointer to // the root node. pederb, 2002-09-04 SoFieldContainer::addCopy(this, cp); newinst->copyContents(inst, FALSE); } else { if (this->isOfType(SoProto::getClassTypeId())) { // just copy the pointer. A PROTO definition is // read-only. It's not possible to change it after it has been // created so this should be safe. cp = (SoNode*) this; } else { cp = (SoNode *)this->getTypeId().createInstance(); } assert(cp); SoFieldContainer::addCopy(this, cp); SoChildList * l = this->getChildren(); for (int i=0; l && (i < l->getLength()); i++) (void)(*l)[i]->addToCopyDict(); } } return cp; }
/*! Returns the indexth node in path. */ SoNode * SoLightPath::getNode(const int index) const { #if COIN_DEBUG && 1 // debug if (index < 0 || index >= this->indices.getLength()) { SoDebugError::postInfo("SoLightPath::getNode", "index %d out of bounds", index); } #endif // debug SoNode *node = this->headnode; for (int i = 1; i < index; i++) { int childidx = this->indices[i]; SoChildList *children = node->getChildren(); node = NULL; if (children == NULL || childidx < 0 || childidx >= children->getLength()) break; node = (*children)[childidx]; } return node; }
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; }
/*! \fn SoXipGLSLUniformGroup::doAction(SoAction * action) * Adds a node to the SoXipGLSLUniformGroupElement in the current state * \param action - the current state action, no action taken if input action is NULL * \return void */ void SoXipGLSLUniformGroup::doAction(SoAction * action) { SoChildList * children = this->getChildren(); children->traverse(action); }