Esempio n. 1
0
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);
}
Esempio n. 2
0
/*!
  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
  }
}
Esempio n. 3
0
/*!
  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;
}
Esempio n. 4
0
/*!
  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;
}
Esempio n. 5
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;
}