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); }
/*! 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; }