コード例 #1
0
int QilexDoc::doc_new_kinematic_hand(ct_new_kinematic_chain *data)
{
   int error = 0;
   int tipus = 0;
   void * buffer ; //char *buffer;
   char *buftemp = (char*)malloc(1024);

   SoOutput out;

   size_t sizeModel = 0;

   SoSeparator *kinechain = new SoSeparator;
   SoSeparator *kinetest = new SoSeparator;

   Rchain_hand *kineengine = new Rchain_hand();

   SoTransform *pos_rot = new SoTransform;
   SbVec3f joinax;

   joinax.setValue(SbVec3f(data->x,data->y,data->z));
   pos_rot->translation.setValue(joinax);
   pos_rot->rotation.setValue(SbVec3f(data->axeX, data->axeY, data->axeZ), (float) rad((double) data->angle));

   kinechain = readFile(data->QsModelFile.latin1(), tipus);

   if (kinechain == NULL) // no object read
   { return 1; }
   else  // ok, there's no object with the same name
   {
      error = kineengine->init_dat(data->QsDatFile.latin1()); //

      if (error == 0)
      {
         kinechain->ref();
         kinetest = (SoSeparator*)SoNode::getByName(data->QsName.latin1());

         if (kinetest==NULL)
         {
            //we need to put it in a buffer to write the xml file
            // if is Ok
            SoOutput out;
            out.setBuffer(buftemp, 1024, reallocCB);

            SoWriteAction wa1(&out);
            wa1.apply(kinechain);

            out.getBuffer(buffer, sizeModel);

            kinechain->insertChild(pos_rot, 0);
         }
         error = doc_insert_kinematic_hand(kineengine, kinechain);
      }
   }

   if (error==0)
   {
      writeXML_kineelement((char *)buffer, sizeModel, tipus, data, kineengine);
   }
   return error;
}
コード例 #2
0
ファイル: materialeditor.cpp プロジェクト: ALLPix/SoXt
int
main(int argc, char ** argv)
{
  Widget w = SoXt::init(argc, argv, "SoXtColorEditor");
  SoXtExaminerViewer * viewer = new SoXtExaminerViewer(w);
  SoSeparator * root;
  viewer->setSceneGraph(root = makescene());
  viewer->show();

#if WANT_INTEGRATED
  SoSeparator * editorscene = new SoSeparator;
  SoTranslation * trans = new SoTranslation;
  trans->translation.setValue(SbVec3f(2.0f, 0.0f, 0.0f));
  SoRotationXYZ * rot = new SoRotationXYZ;
  SoMaterial * mat = new SoMaterial;
  mat->diffuseColor.setValue(0.8, 0.8, 0.8);
  rot->axis = SoRotationXYZ::Y;
  rot->angle = 0.5;
  editorscene->addChild(trans);
  editorscene->addChild(rot);
  editorscene->addChild(mat);
  SoGuiMaterialEditor * inscene = new SoGuiMaterialEditor;
  // inscene->wysiwyg.setValue(TRUE);
  inscene->material.setValue(material);
  // inscene->color.getValue(); // update field
  // material->diffuseColor.connectFrom(&(inscene->color));
  editorscene->addChild(inscene);
  root->insertChild(editorscene, 0);

#else
  SoXtMaterialEditor * editor = new SoXtMaterialEditor;
  editor->attach(material);
  editor->show();
#endif

  SoXt::show(w);
  SoXt::mainLoop();
  return 0;
}
コード例 #3
0
int QilexDoc::doc_insert_geometric_object(QDomElement geom_element)
{
   int error = 0;
   const char * buffer;
    
   SbVec3f joinax;
   SoTransform *pos_rot = new SoTransform;

   float joinangle;
   float pos_x, pos_y, pos_z, pos_rx, pos_ry, pos_rz;

   QString data, name;

   QDomNode node;
   QDomElement element;
   QDomNodeList list;

   SoSeparator *geomelement = new SoSeparator;
   SoSeparator *geomtest = new SoSeparator;
   
   name = geom_element.attribute ("name", QString::null);

   data = geom_element.attribute ("pos_x", QString::null);
   pos_x = data.toFloat();

   data = geom_element.attribute ("pos_y", QString::null);
   pos_y = data.toFloat();

   data = geom_element.attribute ("pos_z", QString::null);
   pos_z = data.toFloat();

   data = geom_element.attribute ("pos_rx", QString::null);
   pos_rx = data.toFloat();

   data = geom_element.attribute ("pos_ry", QString::null);
   pos_ry = data.toFloat();

   data = geom_element.attribute ("pos_rz", QString::null);
   pos_rz = data.toFloat();

   data = geom_element.attribute ("pos_angle", QString::null);
   joinangle = data.toFloat();

   joinax.setValue(SbVec3f( pos_x, pos_y, pos_z));
   pos_rot->translation.setValue(joinax);
   pos_rot->rotation.setValue(SbVec3f(pos_rx, pos_ry, pos_rz), (float) rad((double)joinangle));
   
   list = geom_element.elementsByTagName ("model3d");
   if (list.length() == 1)
   {
      node = list.item(0);
      element = node.toElement();

      data = element.attribute ("format", QString::null);
      // some stuff to take care about the format

      data = element.attribute ("size", QString::null);
      size_t size = (size_t)data.toULong(0,10);
      buffer = new char[size];

      data = element.text();
      buffer = data.ascii();

      SoInput input;
      input.setBuffer((void*) buffer, size);

      if (input.isValidBuffer())
      {
         geomelement = SoDB::readAll(&input);
         if (geomelement == NULL)
            error = 10;
      }
      else
         {error = 8;} //   assigno un nombre diferent de 0
   }
   else
   { error =9; }// assigno un nombre diferent de 0

   if (error == 0)
   {
      geomelement->ref();
      geomtest = (SoSeparator*)SoNode::getByName(name.latin1());

      if (geomtest==NULL)
      {
         //we need to put it in a buffer to write the xml file
         // if is Ok
         geomelement->insertChild(pos_rot, 0);
         geomelement->setName(name.latin1());
         view->addObjectCell(geomelement);
      }
   }
   return error; 
}
コード例 #4
0
int QilexDoc::doc_insert_kinematic_chain(QDomElement kine_element)
{
   int error = 0;
   const char * buffer;

   QDomNodeList list;
   
   Rchain *kineengine = new Rchain;
   
   SoSeparator *kinechain = new SoSeparator;
   SoSeparator *kinetest = new SoSeparator;

   //Rchain *kineengine = new Rchain;
   SoTransform *pos_rot = new SoTransform;
   SbVec3f joinax;

   float joinangle;
   float pos_x, pos_y, pos_z, pos_rx, pos_ry, pos_rz;

   QString data, name;

   QDomNode node;
   QDomElement element;
   
   name = kine_element.attribute ("name", QString::null);
   data = kine_element.attribute ("kineengine", QString::null);
   // here put some stuff to select the kinechain engine

   data = kine_element.attribute ("pos_x", QString::null);
   pos_x = data.toFloat();

   data = kine_element.attribute ("pos_y", QString::null);
   pos_y = data.toFloat();
      
   data = kine_element.attribute ("pos_z", QString::null);
   pos_z = data.toFloat();

   data = kine_element.attribute ("pos_rx", QString::null);
   pos_rx = data.toFloat();

   data = kine_element.attribute ("pos_ry", QString::null);
   pos_ry = data.toFloat();

   data = kine_element.attribute ("pos_rz", QString::null);
   pos_rz = data.toFloat();

   data = kine_element.attribute ("pos_angle", QString::null);
   joinangle = data.toFloat();
      
   joinax.setValue(SbVec3f( pos_x, pos_y, pos_z));
   pos_rot->translation.setValue(joinax);
   pos_rot->rotation.setValue(SbVec3f(pos_rx, pos_ry, pos_rz), (float) rad((double)joinangle));

   list = kine_element.elementsByTagName ("kinechain");

   if (list.length() == 1)
   {
      node = list.item(0);
      element = node.toElement();
      error = kineengine->read_element_xml (element);
   }
   else
   { error =4;} // assigno un nombre diferrent de 0
      
   list = kine_element.elementsByTagName ("model3d");
   if (list.length() == 1)
   {
      node = list.item(0);
      element = node.toElement();
            
      data = element.attribute ("format", QString::null);
      // some stuff to take care about the format
            
      data = element.attribute ("size", QString::null);
      size_t size = (size_t)data.toULong(0,10);
      buffer = new char[size];
   
      data = element.text();
      buffer = data.ascii();

  /*    char *buffer2 = new char[size];
      for(unsigned i=0;i<size;i++)
         buffer2[i] = buffer[i];
    */                 
      SoInput input;
      input.setBuffer((void *)buffer, size);

      if (input.isValidBuffer())
      {
         kinechain = SoDB::readAll(&input);
         
         if (kinechain == NULL)
            error = 10;
      }
      else
         {error = 8;} //  assigno un nombre diferent de 0
   }
   else
   { error =9; }// assigno un nombre diferent de 0
      
   if (error == 0)
   {
      kinechain->ref();
      kinetest = (SoSeparator*)SoNode::getByName(name.latin1());

      if (kinetest==NULL)
      {
         //we need to put it in a buffer to write the xml file
         // if is Ok
         kinechain->insertChild(pos_rot, 0);
         kinechain->setName(name.latin1());
         
         error = doc_insert_kinematic_chain(kineengine, kinechain);
      }
   }
   else {error = 5;}
   
   
   return error;
}
コード例 #5
0
int QilexDoc::doc_new_grasping_object(ct_new_grasping_object *data)
{
   int error = 0;
   int tipus = 0;

   void *buffer; //char *buffer;
   char *buftemp = (char*)malloc(1024);
   size_t sizeModel = 0;;

   SoSeparator *object = new SoSeparator;
   SoSeparator *objecttest = new SoSeparator;


   SoTransform *pos_rot = new SoTransform;
   SbVec3f joinax;
   SbVec3f joingrasp0;
   SbVec3f joingrasp1;
   SbVec3f joingrasp2;
   SbVec3f joingrasp3;

   joinax.setValue(SbVec3f(data->x,data->y,data->z));
   pos_rot->translation.setValue(joinax);
   pos_rot->recenter(joinax);
   pos_rot->rotation.setValue(SbVec3f(data->axeX, data->axeY, data->axeZ), (float) rad((double) data->angle));
   object = readFile(data->QsModelFile.latin1(), tipus);


   if (object == NULL) // no object read
   {
      error = 1 ;
   }
   else  // ok, there's no object with the same name
   {
      error = read_grasp_points(data);

      SoMaterial *bronze = new SoMaterial;
      bronze->ambientColor.setValue(0.33,0.22,0.27);
      bronze->diffuseColor.setValue(0.78,0.57,0.11);
      bronze->specularColor.setValue(0.99,0.94,0.81);
      bronze->shininess=0.28;

      SoSphere *grasp_sphere = new SoSphere;
      grasp_sphere->radius=7.0;

      SoFont *font = new SoFont;
      font->size.setValue(28);
      font->name.setValue("Times-Roman");
      SoSeparator *grasp_sep0 = new SoSeparator;
      SoTransform *grasp_transf0 = new SoTransform;
      SoSeparator *text0 = new SoSeparator;
      SoText2 *label_text0 = new SoText2;
      SoSeparator *grasp_sep1 = new SoSeparator;
      SoTransform *grasp_transf1 = new SoTransform;
      SoSeparator *text1 = new SoSeparator;
      SoText2 *label_text1 = new SoText2;
      SoSeparator *grasp_sep2 = new SoSeparator;
      SoTransform *grasp_transf2 = new SoTransform;
      SoSeparator *text2 = new SoSeparator;
      SoText2 *label_text2 = new SoText2;
      SoSeparator *grasp_sep3 = new SoSeparator;
      SoTransform *grasp_transf3 = new SoTransform;
      SoSeparator *text3 = new SoSeparator;
      SoText2 *label_text3 = new SoText2;

      //for (int i=0;i<data->num_point;i++)
      //{
       joingrasp0.setValue(SbVec3f(data->grasp_points[0].px,data->grasp_points[0].py,data->grasp_points[0].pz));
       grasp_transf0->translation.setValue(joingrasp0);
       grasp_transf0->recenter(joingrasp0);
       label_text0->string=" 1";
       text0->addChild(font);
       text0->addChild(label_text0);
       grasp_sep0->addChild(bronze);
       grasp_sep0->addChild(grasp_transf0);
       grasp_sep0->addChild(grasp_sphere);
       grasp_sep0->addChild(text0);
       //grasp_sep0->addChild(line0);
       joingrasp1.setValue(SbVec3f(data->grasp_points[1].px,data->grasp_points[1].py,data->grasp_points[1].pz));
       grasp_transf1->translation.setValue(joingrasp1);
       grasp_transf1->recenter(joingrasp1);
       label_text1->string=" 2";
       text1->addChild(font);
       text1->addChild(label_text1);
       grasp_sep1->addChild(bronze);
       grasp_sep1->addChild(grasp_transf1);
       grasp_sep1->addChild(grasp_sphere);
       grasp_sep1->addChild(text1);
       joingrasp2.setValue(SbVec3f(data->grasp_points[2].px,data->grasp_points[2].py,data->grasp_points[2].pz));
       grasp_transf2->translation.setValue(joingrasp2);
       grasp_transf2->recenter(joingrasp2);
       label_text2->string=" 3";
       text2->addChild(font);
       text2->addChild(label_text2);
       grasp_sep2->addChild(bronze);
       grasp_sep2->addChild(grasp_transf2);
       grasp_sep2->addChild(grasp_sphere);
       grasp_sep2->addChild(text2);
       joingrasp3.setValue(SbVec3f(data->grasp_points[3].px,data->grasp_points[3].py,data->grasp_points[3].pz));
       grasp_transf3->translation.setValue(joingrasp3);
       grasp_transf3->recenter(joingrasp3);
       label_text3->string=" 4";
       text3->addChild(font);
       text3->addChild(label_text3);
       grasp_sep3->addChild(bronze);
       grasp_sep3->addChild(grasp_transf3);
       grasp_sep3->addChild(grasp_sphere);
       grasp_sep3->addChild(text3);
       //object->addChild(grasp_sep);
      //}
      if (error == 0)
      {
      object->ref();
      objecttest = (SoSeparator*)SoNode::getByName(data->QsName.latin1());

      if (objecttest==NULL)
      {

         SoOutput out;
         out.setBuffer(buftemp, 1024, reallocCB);

         SoWriteAction wa1(&out);
         wa1.apply(object);

         out.getBuffer(buffer, sizeModel);

         object->setName(data->QsName.latin1());
	 //grasp_object->addChild(model_object);
	 object->addChild(grasp_sep0);
	 object->addChild(grasp_sep1);
	 object->addChild(grasp_sep2);
	 object->addChild(grasp_sep3);
         object->insertChild(pos_rot, 0);

         view->addObjectCell(object);
         error = 0;

         //writeXML_geomelement((char *)buffer, sizeModel, tipus, data);
	 //S'ha de canviar!!!!!
      }
      else
      {
         object->unref();
         error = 3;
      }
      }
   }
   return error;
}
コード例 #6
0
int QilexDoc::doc_new_geometric_object(ct_new_geometric_object *data)
{
   int error = 0;
   int tipus = 0;

   void *buffer; //char *buffer;
   char *buftemp = (char*)malloc(1024);
   size_t sizeModel = 0;;

   SoSeparator *object = new SoSeparator;
   SoSeparator *objecttest = new SoSeparator;


   SoTransform *pos_rot = new SoTransform;
   SbVec3f joinax;


   joinax.setValue(SbVec3f(data->x,data->y,data->z));
   pos_rot->translation.setValue(joinax);
   pos_rot->recenter(joinax);
   pos_rot->rotation.setValue(SbVec3f(data->axeX, data->axeY, data->axeZ), (float) rad((double) data->angle));
   object = readFile(data->QsModelFile.latin1(), tipus);


   if (object == NULL) // no object read
   {
      error = 1 ;
   }
   else  // ok, there's no object with the same name
   {
      object->ref();
      objecttest = (SoSeparator*)SoNode::getByName(data->QsName.latin1());

      if (objecttest==NULL)
      {

         SoOutput out;
         out.setBuffer(buftemp, 1024, reallocCB);

         SoWriteAction wa1(&out);
         wa1.apply(object);

         out.getBuffer(buffer, sizeModel);

         object->setName(data->QsName.latin1());
         object->insertChild(pos_rot, 0);

         view->addObjectCell(object);
         error = 0;

         writeXML_geomelement((char *)buffer, sizeModel, tipus, data);
      }
      else
      {
         object->unref();
         error = 3;
      }
   }

   return error;
}
コード例 #7
0
ファイル: ivperf.cpp プロジェクト: Alexpux/IvTools
static float
timeRendering(Options &options,
	      const SbViewportRegion &vpr,
	      SoSeparator *&root)
//
//////////////////////////////////////////////////////////////
{
    SbTime 		timeDiff, startTime;
    int 		frameIndex;
    SoTransform		*sceneTransform;
    SoGLRenderAction 	ra(vpr);
    SoNodeList		noCacheList;
    SoSeparator 	*newRoot;

    // clear the window
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //
    // reset autocaching threshold before each experiment
    //   done by replacing every separator in the scene graph
    //   with a new one
    //
    newRoot = (SoSeparator *) replaceSeparators(root);
    newRoot->ref();
    newRoot->renderCaching = SoSeparator::OFF;

    // get a list of separators marked as being touched by the application
    newRoot->getByName(NO_CACHE_NAME, noCacheList);

    // find the transform node that spins the scene
    SoNodeList	xformList;
    newRoot->getByName(SCENE_XFORM_NAME, xformList);
    sceneTransform = (SoTransform *) xformList[0];

    if (options.noMaterials) {  // nuke material node
	removeNodes(newRoot, SoMaterial::getClassTypeId());
	removeNodes(newRoot, SoPackedColor::getClassTypeId());
	removeNodes(newRoot, SoBaseColor::getClassTypeId());
    }

    if (options.noXforms) {  // nuke transforms
	removeNodes(newRoot, SoTransformation::getClassTypeId());
    }

    if (options.noTextures || options.oneTexture) {  // override texture node

	removeNodes(newRoot, SoTexture2::getClassTypeId());

	if (options.oneTexture) {
	    // texture node with simple texture
	    static unsigned char img[] = {
		255, 255, 0, 0,
		255, 255, 0, 0,
		0, 0, 255, 255,
		0, 0, 255, 255
		};
	    SoTexture2 *overrideTex = new SoTexture2;	
	    overrideTex->image.setValue(SbVec2s(4, 4), 1, img);
	    newRoot->insertChild(overrideTex, 1);
	}
    }

    if (options.noFill) {  // draw as points
	SoDrawStyle *overrideFill = new SoDrawStyle;
	overrideFill->style.setValue(SoDrawStyle::POINTS);
	overrideFill->lineWidth.setIgnored(TRUE);
	overrideFill->linePattern.setIgnored(TRUE);
	overrideFill->setOverride(TRUE);
	newRoot->insertChild(overrideFill, 0);

	// cull backfaces so that extra points don't get drawn
	SoShapeHints *cullBackfaces = new SoShapeHints;
	cullBackfaces->shapeType = SoShapeHints::SOLID;
	cullBackfaces->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE;
	cullBackfaces->setOverride(TRUE);
	newRoot->insertChild(cullBackfaces, 0);
    }

    if (options.noVtxXforms) {  // draw invisible
	SoDrawStyle *overrideVtxXforms = new SoDrawStyle;
	overrideVtxXforms->style.setValue(SoDrawStyle::INVISIBLE);
	overrideVtxXforms->setOverride(TRUE);
	newRoot->insertChild(overrideVtxXforms, 0);
    }

    if (options.noLights) {  // set lighting model to base color
	SoLightModel *baseColor = new SoLightModel;
	baseColor->model = SoLightModel::BASE_COLOR;
	newRoot->insertChild(baseColor, 0);
    }
 
    for (frameIndex = 0; ; frameIndex++) {

	// wait till autocaching has kicked in then start timing
	if (frameIndex == NUM_FRAMES_AUTO_CACHING)
	    startTime = SbTime::getTimeOfDay();

	// stop timing and exit loop when requisite number of
	//    frames have been drawn
	if (frameIndex == options.numFrames + NUM_FRAMES_AUTO_CACHING) {
	    glFinish();
	    timeDiff = SbTime::getTimeOfDay() - startTime;
	    break;
	}
	    
	// if not frozen, update realTime and destroy labelled caches
	if (! options.freeze) { 

	    // update realTime 
	    SoSFTime *realTime = (SoSFTime *) SoDB::getGlobalField("realTime");
	    realTime->setValue(SbTime::getTimeOfDay());

	    // touch the separators marked NoCache 
	    for (int i=0; i<noCacheList.getLength(); i++)
		((SoSeparator *) noCacheList[i])->getChild(0)->touch();
	}

	// Rotate the scene
	sceneTransform->rotation.setValue(SbVec3f(1, 1, 1), 
                           frameIndex * 2 * M_PI / options.numFrames);

	if (! options.noClear)
	    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	ra.apply(newRoot);
    }

    // Get rid of newRoot
    newRoot->unref();

    return (timeDiff.getValue() / options.numFrames);
}
コード例 #8
0
ファイル: ivperf.cpp プロジェクト: Alexpux/IvTools
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;
}