Răsfoiți Sursa

first pass working version of softimage tool port

Asad M. Zaman 22 ani în urmă
părinte
comite
23aa2a9ead

+ 219 - 106
pandatool/src/softegg/softNodeDesc.cxx

@@ -38,12 +38,10 @@ SoftNodeDesc(SoftNodeDesc *parent, const string &name) :
 
   // Add ourselves to our parent.
   if (_parent != (SoftNodeDesc *)NULL) {
-    cout << "parent name " << _parent->get_name();
+    softegg_cat.spam() << "parent name " << _parent->get_name();
     _parent->_children.push_back(this);
   }
 
-  vpool = NULL;
-
   fullname = NULL;
 
   numTexLoc = 0;
@@ -95,20 +93,20 @@ set_model(SAA_Elem *model) {
 void SoftNodeDesc::
 set_parent(SoftNodeDesc *parent) {
   if (_parent) {
-    cout << endl;
+    softegg_cat.spam() << endl;
     /*
-    cout << " expected _parent to be null!?\n";
+    softegg_cat.spam() << " expected _parent to be null!?\n";
     if (_parent == parent)
-      cout << " parent already set\n";
+      softegg_cat.spam() << " parent already set\n";
     else {
-      cout << " current parent " << _parent->get_name() << " new parent " 
+      softegg_cat.spam() << " current parent " << _parent->get_name() << " new parent " 
            << parent << endl;
     }
     */
     return;
   }
   _parent = parent;
-  cout << " set parent to " << _parent->get_name() << endl;
+  softegg_cat.spam() << " set parent to " << _parent->get_name() << endl;
 
   // Add ourselves to our parent.
   _parent->_children.push_back(this);
@@ -209,15 +207,15 @@ void SoftNodeDesc::
 mark_joint_parent() {
   if (_joint_type == JT_none) {
     _joint_type = JT_joint_parent;
-    cout << " marked parent " << get_name();
+    softegg_cat.spam() << " marked parent " << get_name();
   }
   else
-    cout << " ?parent " << get_name() << " joint type " << _joint_type;
+    softegg_cat.spam() << " ?parent " << get_name() << " joint type " << _joint_type;
   
   if (_parent != (SoftNodeDesc *)NULL) {
     _parent->mark_joint_parent();
   }
-  cout << endl;
+  softegg_cat.spam() << endl;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -232,7 +230,7 @@ check_joint_parent() {
   for (ci = _children.begin(); ci != _children.end(); ++ci) {
     SoftNodeDesc *child = (*ci);
     if (child->is_joint()) {
-      cout << "child " << child->get_name();
+      softegg_cat.spam() << "child " << child->get_name();
       mark_joint_parent();
     }
     child->check_joint_parent();
@@ -252,7 +250,7 @@ check_junk(bool parent_junk) {
 
   if (parent_junk) {
     _joint_type = JT_junk;
-    cout << "junk node " << get_name() << endl;
+    softegg_cat.spam() << "junk node " << get_name() << endl;
   }
   if ( (strstr(name, "con-") != NULL) || 
        (strstr(name, "con_") != NULL) || 
@@ -261,20 +259,16 @@ check_junk(bool parent_junk) {
        (strstr(name, "camRIG") != NULL) ||
        (strstr(name, "cam_rig") != NULL) ||
        (strstr(name, "bars") != NULL) )
-       // split
-       /*
-       (!_search_prefix || (strstr(name, _search_prefix) != NULL)) )
-       */
     {
       _joint_type = JT_junk;
-      cout << "junk node " << get_name() << endl;
+      softegg_cat.spam() << "junk node " << get_name() << endl;
       parent_junk = true;
       Children::const_iterator ci;
       for (ci = _children.begin(); ci != _children.end(); ++ci) {
         SoftNodeDesc *child = (*ci);
-        cout << child->get_name() << ",";
+        softegg_cat.spam() << child->get_name() << ",";
       }
-      cout << endl;
+      softegg_cat.spam() << endl;
     }
   Children::const_iterator ci;
   for (ci = _children.begin(); ci != _children.end(); ++ci) {
@@ -283,6 +277,35 @@ check_junk(bool parent_junk) {
   }
 }
 
+///////////////////////////////////////////////////////////////////////
+//     Function: SoftNodeTree::is_partial
+//       Access: Public
+//  Description: check to see if this is a selected branch we want to 
+//               descend - this will prevent creating geometry for 
+//               other parts
+///////////////////////////////////////////////////////////////////////
+bool SoftNodeDesc::
+is_partial(char *search_prefix) {
+  const char *name = fullname;
+
+  // if no search prefix then return false
+  if (!search_prefix)
+    return false;
+  // if name is search_prefix, return false
+  if (strstr(name, search_prefix) != NULL) {
+    cout << "matched " << name << " ";
+    return false;
+  }
+  // if name is not search_prefix, look in its parent
+  if (strstr(name, search_prefix) == NULL) {
+    cout << "node " << name << " ";
+    if (_parent) 
+      return _parent->is_partial(search_prefix);
+  }
+  // neither name nor its parent is search_prefix
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: SoftNodeDesc::check_pseudo_joints
 //       Access: Private
@@ -298,7 +321,7 @@ check_pseudo_joints(bool joint_above) {
     // (JT_joint_parent is set), and it is the child of a joint
     // (joint_above is set).
     _joint_type = JT_pseudo_joint;
-    cout << "pseudo " << get_name() << " case1\n";
+    softegg_cat.spam() << "pseudo " << get_name() << " case1\n";
   }
 
   if (_joint_type == JT_joint) {
@@ -317,7 +340,7 @@ check_pseudo_joints(bool joint_above) {
       SoftNodeDesc *child = (*ci);
       child->check_pseudo_joints(joint_above);
       if (child->is_joint()) {
-        cout << get_name() << " any_joint true by " << child->get_name() << endl;
+        softegg_cat.spam() << get_name() << " any_joint true by " << child->get_name() << endl;
         any_joints = true;
       }
     }
@@ -330,7 +353,7 @@ check_pseudo_joints(bool joint_above) {
         SoftNodeDesc *child = (*ci);
         if (child->_joint_type == JT_joint_parent) {
           child->_joint_type = JT_pseudo_joint;
-          cout << "pseudo " << child->get_name() << " case2 by parent " << get_name() << "\n";
+          softegg_cat.spam() << "pseudo " << child->get_name() << " case2 by parent " << get_name() << "\n";
         } else if (child->_joint_type == JT_none || child->_joint_type == JT_junk) {
           all_joints = false;
         }
@@ -340,34 +363,13 @@ check_pseudo_joints(bool joint_above) {
         // Finally, if all children or at least one is a joint, then we are too.
         if (_joint_type == JT_joint_parent) {
           _joint_type = JT_pseudo_joint;
-          cout << "pseudo " << get_name() << " case3\n";
+          softegg_cat.spam() << "pseudo " << get_name() << " case3\n";
         }
       }
     }
   }
   else
-    cout << "found null joint " << get_name() << endl;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: SoftToEggConverter::create_vpool
-//       Access: Public
-//  Description: Creates a new vpool for future soft skining,
-//               this is a one to one reference to external index.
-////////////////////////////////////////////////////////////////////
-void SoftNodeDesc::
-create_vpool(string vpool_name) {
-  vpool = new EggVertexPool(vpool_name);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: SoftToEggConverter::get_vpool
-//       Access: Public
-//  Description: Get vpool 
-////////////////////////////////////////////////////////////////////
-EggVertexPool *SoftNodeDesc::
-get_vpool() {
-  return vpool;
+    softegg_cat.spam() << "found null joint " << get_name() << endl;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -384,28 +386,28 @@ get_transform(SAA_Scene *scene, EggGroup *egg_group, bool global) {
   /*
   if ( strstr( _parent->get_name().c_str(), "scale" ) != NULL ) {
     scale_joint = 1;
-    cout << "scale joint flag set!\n";
+    softegg_cat.spam() << "scale joint flag set!\n";
   }
   */
 
   if (!global && _parent->is_joint() && !stec.flatten && !scale_joint) {
 
     SAA_modelGetMatrix( scene, get_model(), SAA_COORDSYS_LOCAL,  matrix );
-    cout << get_name() << " using local matrix :parent ";
+    softegg_cat.spam() << get_name() << " using local matrix :parent ";
 
   } else {
 
     SAA_modelGetMatrix( scene, get_model(), SAA_COORDSYS_GLOBAL,  matrix );
-    cout << get_name() << " using global matrix :parent ";
+    softegg_cat.spam() << get_name() << " using global matrix :parent ";
 
   }
 
-  cout << _parent->get_name() << endl;
+  softegg_cat.spam() << _parent->get_name() << endl;
 
-  cout << "model matrix = " << matrix[0][0] << " " << matrix[0][1] << " " << matrix[0][2] << " " << matrix[0][3] << "\n";
-  cout << "model matrix = " << matrix[1][0] << " " << matrix[1][1] << " " << matrix[1][2] << " " << matrix[1][3] << "\n";
-  cout << "model matrix = " << matrix[2][0] << " " << matrix[2][1] << " " << matrix[2][2] << " " << matrix[2][3] << "\n";
-  cout << "model matrix = " << matrix[3][0] << " " << matrix[3][1] << " " << matrix[3][2] << " " << matrix[3][3] << "\n";
+  softegg_cat.spam() << "model matrix = " << matrix[0][0] << " " << matrix[0][1] << " " << matrix[0][2] << " " << matrix[0][3] << "\n";
+  softegg_cat.spam() << "model matrix = " << matrix[1][0] << " " << matrix[1][1] << " " << matrix[1][2] << " " << matrix[1][3] << "\n";
+  softegg_cat.spam() << "model matrix = " << matrix[2][0] << " " << matrix[2][1] << " " << matrix[2][2] << " " << matrix[2][3] << "\n";
+  softegg_cat.spam() << "model matrix = " << matrix[3][0] << " " << matrix[3][1] << " " << matrix[3][2] << " " << matrix[3][3] << "\n";
 
   if (!global && is_joint()) {
     LMatrix4d m4d(matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],
@@ -414,7 +416,7 @@ get_transform(SAA_Scene *scene, EggGroup *egg_group, bool global) {
                   matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]);
     if (!m4d.almost_equal(LMatrix4d::ident_mat(), 0.0001)) {
       egg_group->set_transform(m4d);
-      cout << "set transform in egg_group\n";
+      softegg_cat.spam() << "set transform in egg_group\n";
     }
   }
   return;
@@ -447,14 +449,14 @@ get_joint_transform(SAA_Scene *scene,  EggGroup *egg_group, EggXfmSAnim *anim, b
     /*
     if ( strstr( _parent->get_name().c_str(), "scale" ) != NULL ) {
       scale_joint = 1;    
-      cout << "scale joint flag set!\n";
+      softegg_cat.spam() << "scale joint flag set!\n";
     }
     */
 
-    cout << "\n\nanimating child " << name << endl;
+    softegg_cat.spam() << "\n\nanimating child " << name << endl;
 
     if (_parent->is_joint() && !stec.flatten && !scale_joint ) {
-      cout << "using local matrix\n";
+      softegg_cat.spam() << "using local matrix\n";
 
       //get SAA orientation
       SAA_modelGetRotation( scene, skeletonPart, SAA_COORDSYS_LOCAL, 
@@ -468,7 +470,7 @@ get_joint_transform(SAA_Scene *scene,  EggGroup *egg_group, EggXfmSAnim *anim, b
       SAA_modelGetScaling( scene, skeletonPart, SAA_COORDSYS_LOCAL, 
                            &i, &j, &k );
     } else {
-      cout << " using global matrix\n";
+      softegg_cat.spam() << " using global matrix\n";
 
       //get SAA orientation
       SAA_modelGetRotation( scene, skeletonPart, SAA_COORDSYS_GLOBAL, 
@@ -483,9 +485,9 @@ get_joint_transform(SAA_Scene *scene,  EggGroup *egg_group, EggXfmSAnim *anim, b
                            &i, &j, &k );
     }
     
-    cout << "\nanim data: " << i << " " << j << " " << k << endl;
-    cout << "\t" << p << " " << h << " " << r << endl;
-    cout << "\t" << x << " " << y << " " << z << endl;
+    softegg_cat.spam() << "\nanim data: " << i << " " << j << " " << k << endl;
+    softegg_cat.spam() << "\t" << p << " " << h << " " << r << endl;
+    softegg_cat.spam() << "\t" << x << " " << y << " " << z << endl;
 
     // make sure the ordering is correct
     anim->set_order(anim->get_standard_order());
@@ -502,55 +504,40 @@ get_joint_transform(SAA_Scene *scene,  EggGroup *egg_group, EggXfmSAnim *anim, b
     anim->add_component_data("z", z);
   }
   else {
-    cout << "Cannot build anim table - no skeleton\n";
+    softegg_cat.spam() << "Cannot build anim table - no skeleton\n";
   }
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: SoftNodeDesc::load_model
+//     Function: SoftNodeDesc::load_poly_model
 //       Access: Private
 //  Description: Converts the indicated Soft polyset to a bunch of
 //               EggPolygons and parents them to the indicated egg
 //               group.
 ////////////////////////////////////////////////////////////////////
 void SoftNodeDesc::
-load_model(SAA_Scene *scene, SAA_ModelType type) {
+load_poly_model(SAA_Scene *scene, SAA_ModelType type) {
   SI_Error result;
   const char *name = get_name().c_str();
   
   int i;
   int id = 0;
 
-  //  int                    anim_start;
-  //  int                    anim_end;
-  //  int                    anim_rate;
-  //  int                    pose_frame;
-  //  int                    verbose;
-  //  int                    flatten;
-  //  int                    shift_textures;
-  //  int                    ignore_tex_offsets;
-
-  fullname = name;
-  
   // if making a pose - get deformed geometry
   if ( stec.make_pose )
     gtype = SAA_GEOM_DEFORMED;
         
-  // If the model is a NURBS in soft, set its step before tesselating
-  if ( type == SAA_MNSRF )
-    SAA_nurbsSurfaceSetStep( scene, _model, stec.nurbs_step, stec.nurbs_step );
-  
   // If the model is a PATCH in soft, set its step before tesselating
   else if ( type == SAA_MPTCH )
     SAA_patchSetStep( scene, _model, stec.nurbs_step, stec.nurbs_step );
   
   // Get the number of triangles    
   result = SAA_modelGetNbTriangles( scene, _model, gtype, id, &numTri);
-  cout << "triangles: " << numTri << "\n";
+  softegg_cat.spam() << "triangles: " << numTri << "\n";
   
   if ( result != SI_SUCCESS ) {
-    cout << "Error: couldn't get number of triangles!\n";
-    cout << "\tbailing on model: " << name << "\n";
+    softegg_cat.spam() << "Error: couldn't get number of triangles!\n";
+    softegg_cat.spam() << "\tbailing on model: " << name << "\n";
     return;    
   }
   
@@ -563,24 +550,24 @@ load_model(SAA_Scene *scene, SAA_ModelType type) {
   // or is animated via constraint only ( these nodes are
   // tagged by the animator with the keyword "joint"
   // somewhere in the nodes name)
-  cout << "is Skeleton? " << isSkeleton << "\n";
+  softegg_cat.spam() << "is Skeleton? " << isSkeleton << "\n";
   
   /*************************************************************************************/
   
   // model is not a null and has no triangles!
   if ( !numTri ) {
-    cout << "no triangles!\n";
+    softegg_cat.spam() << "no triangles!\n";
   }
   else {
     // allocate array of triangles
     triangles = (SAA_SubElem *) new SAA_SubElem[numTri];
     if (!triangles) {
-      cout << "Not enough Memory for triangles...\n";
+      softegg_cat.spam() << "Not enough Memory for triangles...\n";
       exit(1);
     }
     // triangulate model and read the triangles into array
     SAA_modelGetTriangles( scene, _model, gtype, id, numTri, triangles );
-    cout << "got triangles\n";
+    softegg_cat.spam() << "got triangles\n";
     
     /***********************************************************************************/
     
@@ -590,10 +577,10 @@ load_model(SAA_Scene *scene, SAA_ModelType type) {
     materials = (SAA_Elem*) new SAA_Elem[numTri];
     SAA_triangleGetMaterials( scene, _model, numTri, triangles, materials );
     if (!materials) {
-      cout << "Not enough Memory for materials...\n";
+      softegg_cat.spam() << "Not enough Memory for materials...\n";
       exit(1);
     }
-    cout << "got materials\n";
+    softegg_cat.spam() << "got materials\n";
     
     /***********************************************************************************/
     
@@ -615,7 +602,7 @@ load_model(SAA_Scene *scene, SAA_ModelType type) {
     
     // get local textures if present
     if ( numTexLoc ) {
-      cout << "numTexLoc = " << numTexLoc << endl;
+      softegg_cat.spam() << "numTexLoc = " << numTexLoc << endl;
       
       // allocate arrays of texture info
       uScale = new float[numTri];
@@ -638,7 +625,7 @@ load_model(SAA_Scene *scene, SAA_ModelType type) {
         result = SAA_elementIsValid( scene, &textures[i], &valid );
         
         if ( result != SI_SUCCESS )
-          cout << "SAA_elementIsValid failed!!!!\n";
+          softegg_cat.spam() << "SAA_elementIsValid failed!!!!\n";
         
         // texture present - get the name and uv info 
         if ( valid ) {
@@ -646,27 +633,27 @@ load_model(SAA_Scene *scene, SAA_ModelType type) {
           // panda can now read the .pic files.
           texNameArray[i] = stec.GetTextureName(scene, &textures[i]);
           
-          cout << " tritex[" << i << "] named: " << texNameArray[i] << endl;
+          softegg_cat.spam() << " tritex[" << i << "] named: " << texNameArray[i] << endl;
           
           SAA_texture2DGetUVSwap( scene, &textures[i], &uv_swap );
           
           if ( uv_swap == TRUE )
-            cout << " swapping u and v...\n" ;
+            softegg_cat.spam() << " swapping u and v...\n" ;
           
           SAA_texture2DGetUScale( scene, &textures[i], &uScale[i] );
           SAA_texture2DGetVScale( scene, &textures[i], &vScale[i] );
           SAA_texture2DGetUOffset( scene, &textures[i], &uOffset[i] );
           SAA_texture2DGetVOffset( scene, &textures[i], &vOffset[i] );
           
-          cout << "tritex[" << i << "] uScale: " << uScale[i] << " vScale: " << vScale[i] << endl;
-          cout << " uOffset: " << uOffset[i] << " vOffset: " << vOffset[i] << endl;
+          softegg_cat.spam() << "tritex[" << i << "] uScale: " << uScale[i] << " vScale: " << vScale[i] << endl;
+          softegg_cat.spam() << " uOffset: " << uOffset[i] << " vOffset: " << vOffset[i] << endl;
           
           SAA_texture2DGetRepeats( scene, &textures[i], &uRepeat, &vRepeat );
-          cout << "uRepeat = " << uRepeat << ", vRepeat = " << vRepeat << endl;
+          softegg_cat.spam() << "uRepeat = " << uRepeat << ", vRepeat = " << vRepeat << endl;
         }
         else {
-          cout << "Invalid texture...\n";
-          cout << " tritex[" << i << "] named: (null)\n";
+          softegg_cat.spam() << "Invalid texture...\n";
+          softegg_cat.spam() << " tritex[" << i << "] named: (null)\n";
         }
       }
     }
@@ -679,21 +666,21 @@ load_model(SAA_Scene *scene, SAA_ModelType type) {
         // get the referenced texture
         SAA_modelRelationGetT2DGlbElements( scene, _model, 
                                             TEX_PER_MAT, textures ); 
-        cout << "numTexGlb = " << numTexGlb << endl;
+        softegg_cat.spam() << "numTexGlb = " << numTexGlb << endl;
         // check to see if texture is present
         SAA_elementIsValid( scene, textures, &valid );
         if ( valid ) {  // texture present - get the name and uv info 
           SAA_texture2DGetUVSwap( scene, textures, &uv_swap );
           
           if ( uv_swap == TRUE )
-            cout << " swapping u and v...\n";
+            softegg_cat.spam() << " swapping u and v...\n";
           
           // according to drose, we don't need to convert .pic files to .rgb,
           // panda can now read the .pic files.
           texNameArray = new char *[1];
           *texNameArray = stec.GetTextureName(scene, textures);
           
-          cout << " global tex named: " << *texNameArray << endl;
+          softegg_cat.spam() << " global tex named: " << *texNameArray << endl;
           
           // allocate arrays of texture info
           uScale = new float;
@@ -706,19 +693,145 @@ load_model(SAA_Scene *scene, SAA_ModelType type) {
           SAA_texture2DGetUOffset( scene, textures, uOffset );
           SAA_texture2DGetVOffset( scene, textures, vOffset );
           
-          cout << " global tex uScale: " << *uScale << " vScale: " << *vScale << endl;
-          cout << "            uOffset: " << *uOffset << " vOffset: " << *vOffset << endl;
+          softegg_cat.spam() << " global tex uScale: " << *uScale << " vScale: " << *vScale << endl;
+          softegg_cat.spam() << "            uOffset: " << *uOffset << " vOffset: " << *vOffset << endl;
           
           SAA_texture2DGetRepeats(  scene, textures, &uRepeat, &vRepeat );
-          cout << "uRepeat = " << uRepeat << ", vRepeat = " << vRepeat << endl;
+          softegg_cat.spam() << "uRepeat = " << uRepeat << ", vRepeat = " << vRepeat << endl;
         }
         else {
-          cout << "Invalid Texture...\n";
+          softegg_cat.spam() << "Invalid Texture...\n";
         }
       }
     }
   }
-  cout << "got textures" << endl;
+  softegg_cat.spam() << "got textures" << endl;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: SoftNodeDesc::load_nurbs_model
+//       Access: Private
+//  Description: Converts the indicated Soft polyset to a bunch of
+//               EggPolygons and parents them to the indicated egg
+//               group.
+////////////////////////////////////////////////////////////////////
+void SoftNodeDesc::
+load_nurbs_model(SAA_Scene *scene, SAA_ModelType type) {
+  SI_Error result;
+  const char *name = get_name().c_str();
+  
+  // if making a pose - get deformed geometry
+  if ( stec.make_pose )
+    gtype = SAA_GEOM_DEFORMED;
+        
+  // If the model is a NURBS in soft, set its step before tesselating
+  if ( type == SAA_MNSRF )
+    SAA_nurbsSurfaceSetStep( scene, _model, stec.nurbs_step, stec.nurbs_step );
+  
+  // get the materials
+  /***********************************************************************************/
+  const void *relinfo;
+
+  SAA_modelRelationGetMatNbElements( scene, get_model(), FALSE, &relinfo,
+                                     &numNurbMats );
+
+  softegg_cat.spam() << "nurbs surf has " << numNurbMats << " materials\n";
+
+  if ( numNurbMats ) {
+    materials = new SAA_Elem[numNurbMats];
+    if (!materials) {
+      softegg_cat.spam() << "Out Of Memory on allocating materials\n";
+      exit(1);
+    }
+    
+    SAA_modelRelationGetMatElements( scene, get_model(), relinfo, 
+                                     numNurbMats, materials ); 
+    
+    softegg_cat.spam() << "got materials\n";
+
+    // get the textures
+    /***********************************************************************************/
+    numNurbTexLoc = 0;
+    numNurbTexGlb = 0;
+    
+    // find out how many local textures per NURBS surface
+    // ASSUME it only has one material
+    SAA_materialRelationGetT2DLocNbElements( scene, &materials[0], FALSE, &relinfo, &numNurbTexLoc );
+    
+    // if present, get local textures
+    if ( numNurbTexLoc ) {
+      softegg_cat.spam() << name << " had " << numNurbTexLoc << " local tex\n";
+      nassertv(numNurbTexLoc == 1);
+      
+      textures = new SAA_Elem[numNurbTexLoc];
+      
+      // get the referenced texture
+      SAA_materialRelationGetT2DLocElements( scene, &materials[0], TEX_PER_MAT, &textures[0] );
+      
+    }
+    // if no locals, try to get globals
+    else {
+      SAA_modelRelationGetT2DGlbNbElements( scene, get_model(), FALSE, &relinfo, &numNurbTexGlb );
+      
+      if ( numNurbTexGlb ) {
+        softegg_cat.spam() << name << " had " << numNurbTexGlb << " global tex\n";
+        nassertv(numNurbTexGlb == 1);
+        
+        textures = new SAA_Elem[numNurbTexGlb];
+        
+        // get the referenced texture
+        SAA_modelRelationGetT2DGlbElements( scene, get_model(), TEX_PER_MAT, &textures[0] );
+      }
+    }
+    
+    if ( numNurbTexLoc || numNurbTexGlb) {
+      
+      // allocate the texture name array
+      texNameArray = new char *[1];
+      // allocate arrays of texture info
+      uScale = new float;
+      vScale = new float;
+      uOffset = new float;
+      vOffset = new float;
+      
+      // check to see if texture is present
+      result = SAA_elementIsValid( scene, &textures[0], &valid );
+      
+      if ( result != SI_SUCCESS )
+        softegg_cat.spam() << "SAA_elementIsValid failed!!!!\n";
+      
+      // texture present - get the name and uv info 
+      if ( valid ) {
+        // according to drose, we don't need to convert .pic files to .rgb,
+        // panda can now read the .pic files.
+        texNameArray[0] = stec.GetTextureName(scene, &textures[0]);
+        
+        softegg_cat.spam() << " tritex[0] named: " << texNameArray[0] << endl;
+        
+        SAA_texture2DGetUVSwap( scene, &textures[0], &uv_swap );
+        
+        if ( uv_swap == TRUE )
+          softegg_cat.spam() << " swapping u and v...\n" ;
+        
+        SAA_texture2DGetUScale( scene, &textures[0], &uScale[0] );
+        SAA_texture2DGetVScale( scene, &textures[0], &vScale[0] );
+        SAA_texture2DGetUOffset( scene, &textures[0], &uOffset[0] );
+        SAA_texture2DGetVOffset( scene, &textures[0], &vOffset[0] );
+        
+        softegg_cat.spam() << "tritex[0] uScale: " << uScale[0] << " vScale: " << vScale[0] << endl;
+        softegg_cat.spam() << " uOffset: " << uOffset[0] << " vOffset: " << vOffset[0] << endl;
+        
+        SAA_texture2DGetRepeats( scene, &textures[0], &uRepeat, &vRepeat );
+        softegg_cat.spam() << "uRepeat = " << uRepeat << ", vRepeat = " << vRepeat << endl;
+      }
+      else {
+        softegg_cat.spam() << "Invalid texture...\n";
+        softegg_cat.spam() << " tritex[0] named: (null)\n";
+      }
+    }
+    
+    softegg_cat.spam() << "got textures\n";
+  }
 }
 
 //

+ 10 - 7
pandatool/src/softegg/softNodeDesc.h

@@ -61,6 +61,7 @@ public:
   bool is_junk() const;
   void set_joint();
   bool is_joint_parent() const;
+  bool is_partial(char *search_prefix);
 
   SoftNodeDesc *_parent;
   typedef pvector< PT(SoftNodeDesc) > Children;
@@ -74,7 +75,6 @@ private:
   void check_pseudo_joints(bool joint_above);
 
   SAA_ModelType type;
-  const char *fullname;
 
   SAA_Elem *_model;
 
@@ -98,11 +98,18 @@ public:
   int uRepeat, vRepeat;
   float        matrix[4][4];
 
+  const char *fullname;
+
   int numTri;
   //  int numShapes;
   int numTexLoc;
   int numTexGlb;
 
+  // if the node is a MNSRF
+  int numNurbTexLoc;
+  int numNurbTexGlb;
+  int numNurbMats;
+
   float *uScale;
   float *vScale;
   float *uOffset;
@@ -120,12 +127,8 @@ public:
 
   void get_transform(SAA_Scene *scene, EggGroup *egg_group, bool global);
   void get_joint_transform(SAA_Scene *scene, EggGroup *egg_group, EggXfmSAnim *anim, bool global);
-  void load_model(SAA_Scene *scene, SAA_ModelType type);
-
-  EggVertexPool *vpool;
-
-  EggVertexPool *get_vpool();
-  void create_vpool(string vpool_name);
+  void load_poly_model(SAA_Scene *scene, SAA_ModelType type);
+  void load_nurbs_model(SAA_Scene *scene, SAA_ModelType type);
 
   static TypeHandle get_class_type() {
     return _type_handle;

+ 34 - 29
pandatool/src/softegg/softNodeTree.cxx

@@ -39,6 +39,7 @@
 SoftNodeTree::
 SoftNodeTree() {
   _root = new SoftNodeDesc(NULL, "----root");
+  _root->fullname = "----root";
   _fps = 0.0;
   _use_prefix = 0;
   _search_prefix = NULL;
@@ -126,7 +127,7 @@ GetModelNoteInfo( SAA_Scene *scene, SAA_Elem *model ) {
     else
       modelNote[size] = '\0';
     
-    cout << "\nmodelNote = " << modelNote << endl;
+    softegg_cat.spam() << "\nmodelNote = " << modelNote << endl;
   }
   
   return modelNote;
@@ -175,7 +176,7 @@ build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database) {
   SAA_Elem *models;
 
   SAA_sceneGetNbModels( &scene, &numModels ); 
-  cout << "Scene has " << numModels << " model(s)...\n";
+  softegg_cat.spam() << "Scene has " << numModels << " model(s)...\n";
   
   // This while loop walks through the entire Soft hierarchy, one
   // node at a time. 
@@ -190,9 +191,9 @@ build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database) {
       for ( int i = 0; i < numModels; i++ ) {
         int level;
         status = SAA_elementGetHierarchyLevel( &scene, &models[i], &level );
-        cout << "model[" << i << "]" << endl;
-        cout << " level " << level << endl;
-        cout << " status is " << status << "\n";
+        softegg_cat.spam() << "model[" << i << "]" << endl;
+        softegg_cat.spam() << " level " << level << endl;
+        softegg_cat.spam() << " status is " << status << "\n";
 
         node = build_node(&scene, &models[i]);
         if (!level && node)
@@ -343,12 +344,12 @@ get_egg_group(SoftNodeDesc *node_desc) {
   nassertr(_egg_root != (EggGroupNode *)NULL, NULL);
 
   // lets print some relationship
-  cout << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
+  softegg_cat.spam() << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
   if (node_desc->_parent)
-    cout << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
+    softegg_cat.spam() << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
   else
-    cout << " parent " << node_desc->_parent;
-  cout << endl;
+    softegg_cat.spam() << " parent " << node_desc->_parent;
+  softegg_cat.spam() << endl;
 
   if (node_desc->_egg_group == (EggGroup *)NULL) {
     // We need to make a new group node.
@@ -361,7 +362,7 @@ get_egg_group(SoftNodeDesc *node_desc) {
 
     if (!node_desc->_parent || node_desc->_parent == _root) {
       // The parent is the root.
-      cout << "came hereeeee\n";
+      softegg_cat.spam() << "came hereeeee\n";
       _egg_root->add_child(egg_group);
     } else {
       // The parent is another node.
@@ -388,15 +389,15 @@ get_egg_table(SoftNodeDesc *node_desc) {
   nassertr(node_desc->is_joint(), NULL);
   
   // lets print some relationship
-  cout << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
+  softegg_cat.spam() << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
   if (node_desc->_parent)
-    cout << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
+    softegg_cat.spam() << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
   else
-    cout << " parent " << node_desc->_parent;
-  cout << endl;
+    softegg_cat.spam() << " parent " << node_desc->_parent;
+  softegg_cat.spam() << endl;
 
   if (node_desc->_egg_table == (EggTable *)NULL) {
-    cout << "creating a new table\n";
+    softegg_cat.spam() << "creating a new table\n";
     // We need to make a new table node.
     //    nassertr(node_desc->_parent != (SoftNodeDesc *)NULL, NULL);
     
@@ -446,21 +447,21 @@ handle_null(SAA_Scene *scene, SoftNodeDesc *node_desc, char *node_name) {
   SAA_Elem *model = node_desc->get_model();
   
   SAA_modelGetAlgorithm( scene, model, &algo );
-  cout << " null algorithm: " << algo << endl;
+  softegg_cat.spam() << " null algorithm: " << algo << endl;
   
   if ( algo == SAA_ALG_INV_KIN ) {
     //    MakeJoint( &scene, lastJoint, lastAnim,  model, name );
     node_desc->set_joint();
-    cout << " encountered IK root: " << name << endl;
+    softegg_cat.spam() << " encountered IK root: " << name << endl;
   }
   else if ( algo == SAA_ALG_INV_KIN_LEAF ) {
     //    MakeJoint( &scene, lastJoint, lastAnim, model, name );
     node_desc->set_joint();
-    cout << " encountered IK leaf: " << name << endl;
+    softegg_cat.spam() << " encountered IK leaf: " << name << endl;
   }
   else if ( algo == SAA_ALG_STANDARD ) {
     SAA_Boolean isSkeleton = FALSE;
-    cout << " encountered Standard null: " << name << endl;
+    softegg_cat.spam() << " encountered Standard null: " << name << endl;
 
     SAA_modelIsSkeleton( scene, model, &isSkeleton );
 
@@ -471,11 +472,11 @@ handle_null(SAA_Scene *scene, SoftNodeDesc *node_desc, char *node_name) {
     if ( isSkeleton || (strstr( name, "joint" ) != NULL) ) {
       //      MakeJoint( &scene, lastJoint, lastAnim, model, name );
       node_desc->set_joint();
-      cout << " animating Standard null!!!\n";
+      softegg_cat.spam() << " animating Standard null!!!\n";
     }
   }
   else
-    cout << " encountered some other NULL: " << algo << endl;
+    softegg_cat.spam() << " encountered some other NULL: " << algo << endl;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -487,7 +488,7 @@ handle_null(SAA_Scene *scene, SoftNodeDesc *node_desc, char *node_name) {
 ////////////////////////////////////////////////////////////////////
 SoftNodeDesc *SoftNodeTree::
 build_node(SAA_Scene *scene, SAA_Elem *model) {
-  char *name;
+  char *name, *fullname;
   string node_name;
   int numChildren;
   int thisChild;
@@ -495,14 +496,16 @@ build_node(SAA_Scene *scene, SAA_Elem *model) {
   SAA_ModelType type;
   SAA_Boolean isSkeleton = FALSE;
 
+  fullname = GetFullName(scene, model);
   if (_use_prefix)
-    name = GetFullName(scene, model);
+    name = fullname;
   else
     name = GetName(scene, model);
 
   node_name = name;
 
   SoftNodeDesc *node_desc = r_build_node(NULL, node_name);
+  node_desc->fullname = fullname;
   node_desc->set_model(model);
   SAA_modelIsSkeleton( scene, model, &isSkeleton );
   if (isSkeleton || (strstr(node_desc->get_name().c_str(), "joint") != NULL))
@@ -516,23 +519,25 @@ build_node(SAA_Scene *scene, SAA_Elem *model) {
     handle_null(scene, node_desc, name);
   
   SAA_modelGetNbChildren( scene, model, &numChildren );
-  cout << " Model " << node_name << " children: " << numChildren << endl;
+  softegg_cat.spam() << " Model " << node_name << " children: " << numChildren << endl;
   
   if ( numChildren ) {
     children = new SAA_Elem[numChildren];
     SAA_modelGetChildren( scene, model, numChildren, children );
     if (!children)
-      cout << "Not enough Memory for children...\n";
+      softegg_cat.spam() << "Not enough Memory for children...\n";
     
     for ( thisChild = 0; thisChild < numChildren; thisChild++ ) {
+      fullname = GetFullName(scene, &children[thisChild]);
       if (_use_prefix)
-        node_name = GetFullName(scene, &children[thisChild]);
+        node_name = fullname;
       else
         node_name = GetName(scene, &children[thisChild]);
       
-      cout << " building child " << thisChild << "...";
+      softegg_cat.spam() << " building child " << thisChild << "...";
       
       SoftNodeDesc *node_child = r_build_node(node_desc, node_name);
+      node_child->fullname = fullname;
       node_child->set_model(&children[thisChild]);
       
       //  if (strstr(name, "joint") != NULL)
@@ -557,7 +562,7 @@ r_build_node(SoftNodeDesc *parent_node, const string &name) {
   // corresponding SoftNodeDesc immediately.
   NodesByName::const_iterator ni = _nodes_by_name.find(name);
   if (ni != _nodes_by_name.end()) {
-    cout << "  already built node " << (*ni).first;
+    softegg_cat.spam() << "  already built node " << (*ni).first;
     node_desc = (*ni).second;
     
     if (stec.flatten)
@@ -575,7 +580,7 @@ r_build_node(SoftNodeDesc *parent_node, const string &name) {
   else
     node_desc = new SoftNodeDesc(parent_node, name);
 
-  cout << " node name : " << name << endl;
+  softegg_cat.spam() << " node name : " << name << endl;
   _nodes.push_back(node_desc);
 
   _nodes_by_name.insert(NodesByName::value_type(name, node_desc));

+ 453 - 103
pandatool/src/softegg/softToEggConverter.cxx

@@ -25,6 +25,7 @@
 #include "eggGroup.h"
 #include "eggTable.h"
 #include "eggVertex.h"
+#include "eggComment.h"
 #include "eggVertexPool.h"
 #include "eggNurbsSurface.h"
 #include "eggNurbsCurve.h"
@@ -218,15 +219,22 @@ ShowOpts()
 bool SoftToEggConverter::
 DoGetopts(int &argc, char **&argv) {
   bool okflag = true;
-  int i = 1;
+  int i = 0;
   softegg_cat.info() << "argc " << argc << "\n";
   if (argc <2) {
     Usage();
     okflag = false;
   }
+  while( i < argc ) {
+    strcat(_commandLine, argv[i]);
+    strcat(_commandLine, " ");
+    ++i;
+  }
+  softegg_cat.info() << endl << _commandLine << endl;
+  
+  i = 1;
   while ((i < argc-1) && (argv[i][0] == '-') && okflag) {
     softegg_cat.info() << "arg " << i << " is " << argv[i] << "\n";
-    //    softegg_cat.info() << argv[i] << ", " << argv[i+1];
     okflag = HandleGetopts(i, argc, argv);
   }
   return okflag;
@@ -509,7 +517,7 @@ GetTextureName( SAA_Scene *scene, SAA_Elem *texture ) {
   SAA_texture2DGetPicName( scene, texture, _MAX_PATH, tempName );
 
   if (tex_path) {
-    //  cout << "tempName :" << tempName << endl;
+    //  softegg_cat.spam() << "tempName :" << tempName << endl;
     strcpy(fileName, tex_path);
 
     // do some processing on the name string
@@ -520,7 +528,7 @@ GetTextureName( SAA_Scene *scene, SAA_Elem *texture ) {
     else
       tmpName = tempName;
 
-    //    cout << "tmpName : " << tmpName << endl;
+    //    softegg_cat.spam() << "tmpName : " << tmpName << endl;
     strcat(fileName, "/");
     strcat(fileName, tmpName);
   }
@@ -529,7 +537,7 @@ GetTextureName( SAA_Scene *scene, SAA_Elem *texture ) {
   }
 
   strcat(fileName, ".pic");
-  //  cout << "fileName : " << fileName << endl;
+  //  softegg_cat.spam() << "fileName : " << fileName << endl;
 
   return fileName;
 }
@@ -576,10 +584,14 @@ convert_soft(bool from_selection) {
 
   EggData egg_data;
   set_egg_data(&egg_data, false);
-  cout << "eggData " << &get_egg_data() << "\n";
+  softegg_cat.spam() << "eggData " << &get_egg_data() << "\n";
+  
+  // append the command line 
+  softegg_cat.info() << _commandLine << endl;
+  get_egg_data().insert(get_egg_data().begin(), new EggComment("", _commandLine));
 
   if (_egg_data->get_coordinate_system() != CS_default) {
-    cout << "coordinate system is not default\n";
+    softegg_cat.spam() << "coordinate system is not default\n";
     exit(1);
   }
 
@@ -593,11 +605,11 @@ convert_soft(bool from_selection) {
 
   char *root_name = _tree.GetRootName( eggFileName );
 
-  cout << "main group name: " << root_name << endl;
+  softegg_cat.spam() << "main group name: " << root_name << endl;
   if (root_name)
     _character_name = root_name;
   
-  if (make_poly) {
+  if (make_poly || make_nurbs) {
     if (!convert_char_model()) {
       all_ok = false;
     }
@@ -608,11 +620,11 @@ convert_soft(bool from_selection) {
     }
 
     //  reparent_decals(&get_egg_data());
-    cout << softegg_cat.info() << "Converted Softimage file\n";
+    softegg_cat.info() << softegg_cat.info() << "Converted Softimage file\n";
 
     // write out the egg model file
     _egg_data->write_egg(Filename(eggFileName));
-    cout << softegg_cat.info() << "Wrote Egg file " << eggFileName << endl;
+    softegg_cat.info() << softegg_cat.info() << "Wrote Egg file " << eggFileName << endl;
   }
   if (make_anim) {
     if (!convert_char_chan()) {
@@ -620,11 +632,11 @@ convert_soft(bool from_selection) {
     }
 
     //  reparent_decals(&get_egg_data());
-    cout << softegg_cat.info() << "Converted Softimage file\n";
+    softegg_cat.info() << softegg_cat.info() << "Converted Softimage file\n";
     
     // write out the egg model file
     _egg_data->write_egg(Filename(animFileName));
-    cout << softegg_cat.info() << "Wrote Anim file " << animFileName << endl;
+    softegg_cat.info() << softegg_cat.info() << "Wrote Anim file " << animFileName << endl;
   }
   return all_ok;
 }
@@ -723,7 +735,7 @@ convert_char_model() {
     MGlobal::viewFrame(frame);
   }
 #endif
-  cout << "character name " << _character_name << "\n";
+  softegg_cat.spam() << "character name " << _character_name << "\n";
   EggGroup *char_node = new EggGroup(eggGroupName);
   get_egg_data().add_child(char_node);
   char_node->set_dart_type(EggGroup::DT_default);
@@ -765,8 +777,8 @@ convert_char_chan() {
   SAA_sceneGetPlayCtrlEndFrame(&scene, &end_frame);
   SAA_sceneGetPlayCtrlFrameStep( &scene, &frame_inc );
   
-  cout << "animation start frame: " << start_frame << " end frame: " << end_frame << endl;
-  cout << "animation frame inc: " << frame_inc << endl;
+  softegg_cat.spam() << "animation start frame: " << start_frame << " end frame: " << end_frame << endl;
+  softegg_cat.spam() << "animation frame inc: " << frame_inc << endl;
   
   _tree._fps = output_frame_rate / frame_inc;
   //  _tree.clear_egg(&get_egg_data(), NULL, root_node);
@@ -796,11 +808,11 @@ convert_char_chan() {
     end_frame = anim_end;
   for ( frame = start_frame; frame <= end_frame; frame += frame_inc) {
     SAA_frame2Seconds( &scene, frame, &time );
-    //    cout << "got time " << time << endl;
+    //    softegg_cat.spam() << "got time " << time << endl;
     if (!make_pose) {
       SAA_updatelistEvalScene( &scene, time );
     }
-    cout << "\n> animating frame " << frame << endl;
+    softegg_cat.spam() << "\n> animating frame " << frame << endl;
 
     //    if (softegg_cat.is_debug()) {
     //      softegg_cat.debug(false)
@@ -815,7 +827,7 @@ convert_char_chan() {
     for (i = 0; i < num_nodes; i++) {
       SoftNodeDesc *node_desc = _tree.get_node(i);
       if (node_desc->is_joint()) {
-        cout << "-----joint " << node_desc->get_name() << "\n";
+        softegg_cat.spam() << "-----joint " << node_desc->get_name() << "\n";
         EggXfmSAnim *anim = _tree.get_egg_anim(node_desc);
         // following function fills in the anim structure
         node_desc->get_joint_transform(&scene, tgroup, anim, TRUE);
@@ -852,7 +864,7 @@ convert_hierarchy(EggGroupNode *egg_root) {
   int num_nodes = _tree.get_num_nodes();
 
   _tree.clear_egg(&get_egg_data(), egg_root, NULL);
-  cout << "num_nodes = " << num_nodes << endl;
+  softegg_cat.spam() << "num_nodes = " << num_nodes << endl;
   for (int i = 0; i < num_nodes; i++) {
     if (!process_model_node(_tree.get_node(i))) {
       return false;
@@ -878,55 +890,65 @@ process_model_node(SoftNodeDesc *node_desc) {
   SAA_ModelType type;
 
   name = node_desc->get_name().c_str();
-  cout << "element name <" << name << ">\n";
+  softegg_cat.spam() << "element name <" << name << ">\n";
 
   if (node_desc->is_junk()) {
-    cout << "no processing, it is junk\n";
+    softegg_cat.spam() << "no processing, it is junk\n";
+    return true;
+  }
+
+  // split
+  if (node_desc->is_partial(search_prefix)) {
+    cout << endl;
     return true;
   }
+  else
+    cout << endl << name << ":being processed" << endl;
 
   egg_group = _tree.get_egg_group(node_desc);
 
   // find out what type of node we're dealing with
   SAA_modelGetType( &scene, node_desc->get_model(), &type );
 
-  cout << "encountered ";
+  softegg_cat.spam() << "encountered ";
   switch(type){
   case SAA_MNILL:
-    cout << "null\n";
+    softegg_cat.spam() << "null\n";
     break;
   case SAA_MPTCH:
-    cout << "patch\n";
+    softegg_cat.spam() << "patch\n";
     break;
   case SAA_MFACE:
-    cout << "face\n";
+    softegg_cat.spam() << "face\n";
     break;
   case SAA_MSMSH:
-    cout << "mesh\n";
+    softegg_cat.spam() << "mesh\n";
     node_desc->get_transform(&scene, egg_group, TRUE);
     make_polyset(node_desc, egg_group, type);
     break;
   case SAA_MJNT:
-    cout << "joint";
-    cout << " joint type " << node_desc->is_joint() << endl;
+    softegg_cat.spam() << "joint";
+    softegg_cat.spam() << " joint type " << node_desc->is_joint() << endl;
     break;
   case SAA_MSPLN:
-    cout << "spline\n";
+    softegg_cat.spam() << "spline\n";
     break;
   case SAA_MMETA:
-    cout << "meta element\n";
+    softegg_cat.spam() << "meta element\n";
     break;
   case SAA_MBALL:
-    cout << "meta ball\n";
+    softegg_cat.spam() << "meta ball\n";
     break;
   case SAA_MNCRV:
-    cout << "nurbs curve\n";
+    softegg_cat.spam() << "nurbs curve\n";
     break;
   case SAA_MNSRF:
-    cout << "nurbs surf\n";
+    softegg_cat.spam() << "nurbs surf\n";
+    node_desc->get_transform(&scene, egg_group, TRUE);
+    make_nurb_surface(node_desc, egg_group, type);
     break;
   default:
-    cout << "unknown type: " << type << "\n";
+    softegg_cat.spam() << "unknown type: " << type << "\n";
   }
 
   if (node_desc->is_joint())
@@ -958,7 +980,7 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
 
   
   SAA_modelGetNodeVisibility( &scene, node_desc->get_model(), &visible ); 
-  cout << "model visibility: " << visible << endl; 
+  softegg_cat.spam() << "model visibility: " << visible << endl; 
   
   ///////////////////////////////////////////////////////////////////////
   // Only create egg polygon data if: the node is visible, and its not
@@ -975,7 +997,7 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
        )
     {
       // load all node data from soft for this node_desc
-      node_desc->load_model(&scene, type);
+      node_desc->load_poly_model(&scene, type);
 
       string vpool_name = name + ".verts";
       EggVertexPool *vpool = new EggVertexPool(vpool_name);
@@ -985,19 +1007,8 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
       // solves a problem of soft-skinning trying to access
       // vertex pool before it is defined.
 
-      //_tree.get_egg_root()->add_child(vpool);
       _tree.get_egg_root()->insert(_tree.get_egg_root()->begin(), vpool);
 
-      //egg_group->add_child(vpool);
-
-      /*
-      // create a copy of vpool in node_desc which will be used later
-      // for soft_skinning
-      node_desc->create_vpool(vpool_name);
-      */
-
-      // little detour...bear with me for now...TODO: move these to a new function
-      
       // We will need to transform all vertices from world coordinate
       // space into the vertex space appropriate to this node.  Usually,
       // this is the same thing as world coordinate space, and this matrix
@@ -1035,7 +1046,7 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
         SAA_DVector normals[3];
         SAA_ctrlVertexGetNormals( &scene, node_desc->get_model(), 3, cvertices, normals );
         for (i=0; i<3; ++i)
-          cout << "normals[" << i <<"] = " << normals[i].x << " " <<  normals[i].y
+          softegg_cat.spam() << "normals[" << i <<"] = " << normals[i].x << " " <<  normals[i].y
                << " " << normals[i].z << " " <<  normals[i].w << "\n";
         
         // allocate arrays for u & v coords
@@ -1056,11 +1067,11 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
                                             3, uCoords, vCoords );
             }
             else
-              cout << "Not enough Memory for texture coords...\n";
+              softegg_cat.spam() << "Not enough Memory for texture coords...\n";
             
 #if 1
             for ( i=0; i<3; i++ )
-              cout << "texcoords[" << i << "] = ( " << uCoords[i] << " , " << vCoords[i] <<" )\n";
+              softegg_cat.spam() << "texcoords[" << i << "] = ( " << uCoords[i] << " , " << vCoords[i] <<" )\n";
 #endif
           }
           else if (node_desc->numTexGlb) {
@@ -1078,7 +1089,7 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
                                                      node_desc->numTexGlb, node_desc->textures, uCoords, vCoords );
             }
             else
-              cout << "Not enough Memory for texture coords...\n";
+              softegg_cat.spam() << "Not enough Memory for texture coords...\n";
           }
         }
         
@@ -1091,10 +1102,10 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
           
           _VCT_X_MAT( global, local, node_desc->matrix );
           
-          cout << "indices[" << i << "] = " << indices[i] << "\n";
-          cout << "cvert[" << i << "] = " << cvertPos[i].x << " " << cvertPos[i].y
+          softegg_cat.spam() << "indices[" << i << "] = " << indices[i] << "\n";
+          softegg_cat.spam() << "cvert[" << i << "] = " << cvertPos[i].x << " " << cvertPos[i].y
                               << " " << cvertPos[i].z << " " << cvertPos[i].w << "\n";
-          cout << " global cvert[" << i << "] = " << global.x << " " << global.y
+          softegg_cat.spam() << " global cvert[" << i << "] = " << global.x << " " << global.y
                               << " " << global.z << " " << global.w << "\n";
           
           //      LPoint3d p3d(cvertPos[i].x, cvertPos[i].y, cvertPos[i].z);
@@ -1105,9 +1116,9 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
           local = normals[i];
           _VCT_X_MAT( global, local, node_desc->matrix );
           
-          cout << "normals[" << i <<"] = " << normals[i].x << " " <<  normals[i].y
+          softegg_cat.spam() << "normals[" << i <<"] = " << normals[i].x << " " <<  normals[i].y
                << " " << normals[i].z << " " <<  normals[i].w << "\n";
-          cout << " global normals[" << i <<"] = " << global.x << " " <<  global.y
+          softegg_cat.spam() << " global normals[" << i <<"] = " << global.x << " " <<  global.y
                << " " << global.z << " " <<  global.w << "\n";
           
           LVector3d n3d(global.x, global.y, global.z);
@@ -1121,12 +1132,12 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
           if ( valid ) {
             SAA_materialGetDiffuse( &scene, &node_desc->materials[idx/3], &r, &g, &b );
             SAA_materialGetTransparency( &scene, &node_desc->materials[idx/3], &a );
-            vert.set_color(Colorf(r, g, b, 1.0));
-            cout << "color r = " << r << " g = " << g << " b = " << b << " a = " << a << "\n";
+            vert.set_color(Colorf(r, g, b, 1.0f - a));
+            softegg_cat.spam() << "color r = " << r << " g = " << g << " b = " << b << " a = " << 1.0f - a << "\n";
           }
           else {     // no material - default to white
             vert.set_color(Colorf(1.0, 1.0, 1.0, 1.0));
-            cout << "default color\n";
+            softegg_cat.spam() << "default color\n";
           }
           
           // if texture present set the texture coordinates
@@ -1135,7 +1146,7 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
             
             u = uCoords[i];
             v = 1.0f - vCoords[i];
-            cout << "texcoords[" << i << "] = " << u << " " 
+            softegg_cat.spam() << "texcoords[" << i << "] = " << u << " " 
                                 << v << endl;
             
             vert.set_uv(TexCoordd(u, v));
@@ -1148,13 +1159,13 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
           // keep a one to one copy in this node's vpool
           EggVertex *t_vert = new EggVertex(vert);
           if (!t_vert) {
-            cout << "out of memeory " << endl;
+            softegg_cat.spam() << "out of memeory " << endl;
             nassertv(t_vert != NULL);
           }
           node_desc->get_vpool()->add_vertex(t_vert, indices[i]);
           */
 
-          cout << "\n";
+          softegg_cat.spam() << "\n";
         }
         
         // Now apply the shader.
@@ -1163,19 +1174,350 @@ make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
             if (!strstr(node_desc->texNameArray[idx], "noIcon"))
               set_shader_attributes(node_desc, *egg_poly, node_desc->texNameArray[idx]);
             else
-              cout << "texname :" << node_desc->texNameArray[idx] << endl;
+              softegg_cat.spam() << "texname :" << node_desc->texNameArray[idx] << endl;
           }
           else {
             if (!strstr(node_desc->texNameArray[0], "noIcon"))
               set_shader_attributes(node_desc, *egg_poly, node_desc->texNameArray[0]);
             else 
-              cout << "texname :" << node_desc->texNameArray[0] << endl;
+              softegg_cat.spam() << "texname :" << node_desc->texNameArray[0] << endl;
+        }
+      }
+      }
+    }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: SoftToEggConverter::make_nurb_surface
+//       Access: Private
+//  Description: Converts the indicated Soft nurbs set to a bunch of
+//               EggPolygons and parents them to the indicated egg
+//               group.
+////////////////////////////////////////////////////////////////////
+void SoftToEggConverter::
+make_nurb_surface(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
+  string name = node_desc->get_name();
+  int id = 0;
+
+  float *uCoords = NULL;
+  float *vCoords = NULL;
+
+
+  SAA_Boolean valid;
+  SAA_Boolean visible;
+
+  int i, j, k;
+
+  
+  SAA_modelGetNodeVisibility( &scene, node_desc->get_model(), &visible ); 
+  softegg_cat.spam() << "model visibility: " << visible << endl; 
+  softegg_cat.spam() << "nurbs!!!surface!!!" << endl;
+  
+  ///////////////////////////////////////
+  // check to see if its a nurbs surface
+  ///////////////////////////////////////
+  if ( (type == SAA_MNSRF) && ( visible ) && (( make_nurbs ) 
+                                              || ( !make_nurbs && !make_poly &&  make_duv )) )
+    {
+      // load all node data from soft for this node_desc
+      node_desc->load_nurbs_model(&scene, type);
+
+      string vpool_name = name + ".verts";
+      EggVertexPool *vpool = new EggVertexPool(vpool_name);
+
+      // add the vertices in the _tree._egg_root node, so that 
+      // they will be written out first in egg file. This 
+      // solves a problem of soft-skinning trying to access
+      // vertex pool before it is defined.
+
+      //_tree.get_egg_root()->add_child(vpool);
+      _tree.get_egg_root()->insert(_tree.get_egg_root()->begin(), vpool);
+
+      //egg_group->add_child(vpool);
+
+      /*
+      // create a copy of vpool in node_desc which will be used later
+      // for soft_skinning
+      node_desc->create_vpool(vpool_name);
+      */
+
+      int uRows, vRows;
+      int uKnots, vKnots;
+      int uExtra, vExtra;
+      int uDegree, vDegree;
+      int uCurves, vCurves;
+
+      vector <double> Knots;
+
+      EggNurbsSurface *eggNurbs = new EggNurbsSurface( name );
+
+      // create nurbs representation of surface
+      SAA_nurbsSurfaceGetDegree( &scene, node_desc->get_model(), &uDegree, &vDegree );
+      softegg_cat.spam() << "nurbs degree: " << uDegree << " u, " << vDegree << " v\n";
+
+      SAA_nurbsSurfaceGetNbKnots( &scene, node_desc->get_model(), &uKnots, &vKnots );
+      softegg_cat.spam() << "nurbs knots: " << uKnots << " u, " << vKnots << " v\n";
+
+      SAA_Boolean uClosed = FALSE;
+      SAA_Boolean vClosed = FALSE;
+
+      SAA_nurbsSurfaceGetClosed( &scene, node_desc->get_model(), &uClosed, &vClosed);    
+
+      uExtra = vExtra = 2;
+      if ( uClosed ) {
+        softegg_cat.spam() << "nurbs is closed in u...\n";
+        uExtra += 4;
+      }
+      if ( vClosed ) {
+        softegg_cat.spam() << "nurbs is closed in v...\n";
+        vExtra += 4;
+      }
+      eggNurbs->setup(uDegree+1, vDegree+1,
+                      uKnots + uExtra, vKnots + vExtra);
+
+      softegg_cat.spam() << "from eggNurbs: num u knots " << eggNurbs->get_num_u_knots() << endl;
+      softegg_cat.spam() << "from eggNurbs: num v knots " << eggNurbs->get_num_v_knots() << endl;
+      softegg_cat.spam() << "from eggNurbs: num u cvs " << eggNurbs->get_num_u_cvs() << endl;
+      softegg_cat.spam() << "from eggNurbs: num v cvs " << eggNurbs->get_num_v_cvs() << endl;
+            
+      SAA_nurbsSurfaceGetNbVertices( &scene, node_desc->get_model(), &uRows, &vRows );
+      softegg_cat.spam() << "nurbs vertices: " << uRows << " u, " << vRows << " v\n";
+            
+      SAA_nurbsSurfaceGetNbCurves( &scene, node_desc->get_model(), &uCurves, &vCurves );
+      softegg_cat.spam() << "nurbs curves: " << uCurves << " u, " << vCurves << " v\n";
+
+      if ( shift_textures ) {
+        if ( uClosed )
+          // shift starting point on NURBS surface for correct textures
+          SAA_nurbsSurfaceShiftParameterization( &scene, node_desc->get_model(), -2, 0 );
+
+        if ( vClosed )
+          // shift starting point on NURBS surface for correct textures
+          SAA_nurbsSurfaceShiftParameterization( &scene, node_desc->get_model(), 0, -2 );
+      }
+
+      SAA_nurbsSurfaceSetStep( &scene, node_desc->get_model(), nurbs_step, nurbs_step );
+
+      // Is this a double sided polygon? meaning check for back face flag
+      char *modelNoteStr = _tree.GetModelNoteInfo( &scene, node_desc->get_model() );
+      if ( modelNoteStr != NULL ) {
+        if ( strstr( modelNoteStr, "bface" ) != NULL ) {
+          eggNurbs->set_bface_flag(TRUE);
+          softegg_cat.spam() << "Set backface flag\n";
         }
       }
+        
+      double *uKnotArray = new double[uKnots];
+      double *vKnotArray = new double[vKnots];
+      result = SAA_nurbsSurfaceGetKnots( &scene, node_desc->get_model(), node_desc->gtype, 0, 
+                                         uKnots, vKnots, uKnotArray, vKnotArray );
+      
+      if (result != SI_SUCCESS) {
+        softegg_cat.spam() << "Couldn't get knots\n";
+        exit(1);
+      }
+
+      // Lets prepare the softimage knots and then assign to eggKnots      
+      add_knots( Knots, uKnotArray, uKnots, uClosed, uDegree ); 
+      softegg_cat.spam() << "u knots: ";
+      for (i = 0; i < (int)Knots.size(); i++) {
+        softegg_cat.spam() << Knots[i] << " ";
+        eggNurbs->set_u_knot(i, Knots[i]);
+      }
+      softegg_cat.spam() << endl;
+
+      Knots.resize(0);
+      add_knots( Knots, vKnotArray, vKnots, vClosed, vDegree ); 
+      softegg_cat.spam() << "v knots: ";
+      for (i = 0; i < (int)Knots.size(); i++) {
+        softegg_cat.spam() << Knots[i] << " ";
+        eggNurbs->set_v_knot(i, Knots[i]);
+      }
+      softegg_cat.spam() << endl;
+
+      // lets get the number of vertices from softimage
+      int numVert;
+      SAA_modelGetNbVertices( &scene, node_desc->get_model(), &numVert );
+        
+      softegg_cat.spam() << numVert << " CV's\n";
+
+      // get the CV's
+      SAA_DVector *vertices = NULL;
+      vertices = new SAA_DVector[numVert];
+    
+      SAA_modelGetVertices( &scene, node_desc->get_model(), node_desc->gtype, 0, numVert, vertices );
+      
+      LMatrix4d vertex_frame_inv = egg_group->get_vertex_frame_inv();
+
+      // create the buffer for EggVertices
+      EggVertex *verts = new EggVertex[numVert];
+
+      softegg_cat.spam() << endl << eggNurbs->get_num_cvs() << endl << endl;
+      
+      //for ( i = 0; i<eggNurbs->get_num_cvs(); i++ ) {
+      for ( k = 0; k<numVert; k++ ) {
+        SAA_DVector global;
+
+        /*
+        int ui = eggNurbs->get_u_index(i);
+        int vi = eggNurbs->get_v_index(i);
+
+        int k = vRows * ui + vi;
+
+        softegg_cat.spam() << i << ": ui " << ui << ", vi " << vi << ", k " << k << endl;
+
+        softegg_cat.spam() << "original cv[" << k << "] = " 
+             << vertices[k].x << " " << vertices[k].y << " "
+             << vertices[k].z << " " << vertices[k].w << endl;
+        */
+        
+        // convert to global coords
+        _VCT_X_MAT( global, vertices[k], node_desc->matrix );
+        
+        //preserve original weight
+        global.w = vertices[k].w;
+        
+        // normalize coords to weight
+        global.x *= global.w;
+        global.y *= global.w;
+        global.z *= global.w;
+        
+        /*
+        softegg_cat.spam() << "global cv[" << k << "] = "
+             << global.x << " " << global.y << " "
+             << global.x << " " << global.w << endl;
+        */
+        
+        LPoint4d p4d(global.x, global.y, global.z, global.w);
+        p4d = p4d * vertex_frame_inv;
+        verts[k].set_pos(p4d);
+
+        // check to see if material is present
+        if (node_desc->numNurbMats) {
+          float r,g,b,a;
+          SAA_elementIsValid( &scene, &node_desc->materials[0], &valid );
+          // material present - get the color 
+          if ( valid ) {
+            SAA_materialGetDiffuse( &scene, &node_desc->materials[0], &r, &g, &b );
+            SAA_materialGetTransparency( &scene, &node_desc->materials[0], &a );
+            verts[k].set_color(Colorf(r, g, b, 1.0f - a));
+            //softegg_cat.spam() << "color r = " << r << " g = " << g << " b = " << b << " a = " << a << "\n";
+          }
+          else {     // no material - default to white
+            verts[k].set_color(Colorf(1.0, 1.0, 1.0, 1.0));
+            softegg_cat.spam() << "default color\n";
+          }
+        }
+        vpool->add_vertex(verts+k, k);
+        eggNurbs->add_vertex(vpool->get_vertex(k));
+        
+        if ( uClosed ) {
+          // add first uDegree verts to end of row
+          if ( (k % uRows) == ( uRows - 1) ) {
+            for ( i = 0; i < uDegree; i++ ) {
+              // add vref's to NURBS info 
+              eggNurbs->add_vertex( vpool->get_vertex(i+((k/uRows)*uRows)) );
+            }
+          }
+        }
+      }
+
+      // check to see if the NURB is closed in v    
+      if ( vClosed && !uClosed ) {
+        // add first vDegree rows of verts to end of list
+        for ( int i = 0; i < vDegree*uRows; i++ ) 
+          eggNurbs->add_vertex( vpool->get_vertex(i) ); 
+      }
+      // check to see if the NURB is closed in u and v    
+      else if ( vClosed && uClosed ) {
+        // add the first (degree) v verts and a few
+        // extra - for good measure
+        for ( i = 0; i < vDegree; i++ ) {
+          // add first vDegree rows of verts to end of list
+          for ( j = 0; j < uRows; j++ )
+            eggNurbs->add_vertex( vpool->get_vertex(j+(i*uRows)) );
+          
+          // if u is closed to we have added uDegree
+          // verts onto the ends of the rows - add them here too
+          for ( k = 0; k < uDegree; k++ )
+            eggNurbs->add_vertex( vpool->get_vertex(k+(i*uRows)+((k/uRows)*uRows)) );
+        }
+      }
+      
+      // We add the NURBS to the group down here, after all of the vpools
+      // for the trim curves have been added.
+      egg_group->add_child(eggNurbs);
+
+      // Now apply the shader.
+      if (node_desc->textures != NULL) {
+        if (!strstr(node_desc->texNameArray[0], "noIcon"))
+          set_shader_attributes(node_desc, *eggNurbs, node_desc->texNameArray[0]);
+        else 
+          softegg_cat.spam() << "texname :" << node_desc->texNameArray[0] << endl;
       }
     }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: add_knots
+//       Access: Public 
+//  Description: Given a parametric surface, and its knots, create
+//               the appropriate egg structure by filling in Soft's
+//               implicit knots and assigning the rest to eggKnots. 
+////////////////////////////////////////////////////////////////////
+void SoftToEggConverter::
+add_knots( vector <double> &eggKnots, double *knots, int numKnots, SAA_Boolean closed, int degree ) {
+  
+  int k = 0;
+  double lastKnot = knots[0];
+  double    *newKnots;
+  
+  // add initial implicit knot(s)
+  if ( closed ) {
+    int i = 0;
+    newKnots = new double[degree];
+    
+    // need to add (degree) number of knots 
+    for ( k = numKnots - 1; k >= numKnots - degree; k-- ) {
+      // we have to know these in order to calculate
+      // next knot value so hold them in temp array
+      newKnots[i] =  lastKnot - (knots[k] - knots[k-1]);
+      lastKnot = newKnots[i];
+      i++;
+    }
+    for ( k = degree - 1; k >= 0; k-- ) {
+      eggKnots.push_back( newKnots[k] );
+      softegg_cat.spam() << "knots[" << k << "] = " << newKnots[k] << endl;
+    }
+  }
+  else {
+    eggKnots.push_back( knots[k] );
+    softegg_cat.spam() << "knots[" << k << "] = " << knots[k] << endl;
+  }
+
+  // add the regular complement of knots
+  for (k = 0; k < numKnots; k++) {
+    eggKnots.push_back( knots[k] );
+    softegg_cat.spam() << "knots[" << k+1 << "] = " << knots[k] << endl;
+  }
+
+  lastKnot = knots[numKnots-1];
+  
+  // add trailing implicit knots
+  if ( closed ) {
+    // need to add (degree) number of knots 
+    for ( k = 1; k <= degree; k++ ) {
+      eggKnots.push_back( lastKnot + (knots[k] - knots[k-1]) );
+      softegg_cat.spam() << "knots[" << k << "] = " << lastKnot + (knots[k] - knots[k-1]) << endl;
+      lastKnot = lastKnot + (knots[k] - knots[k-1]);
+    }
+  }
+  else {
+    eggKnots.push_back( knots[k-1] );
+    softegg_cat.spam() << "knots[" << k+1 << "] = " << knots[k-1] << endl;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: FindClosestTriVert
 //       Access: Public
@@ -1197,9 +1539,9 @@ FindClosestTriVert( EggVertexPool *vpool, SAA_DVector *vertices, int numVert ) {
   EggVertexPool::iterator vi;
   for (vi = vpool->begin(); vi != vpool->end(); ++vi, ++i) {
     EggVertex *vert = (*vi);
-    cout << "vert external index = " << vert->get_external_index() << endl;
-    //    cout << "found vert " << vert << endl;
-    //    cout << "vert [" << i << "] " << vpool->get_vertex(i+1);
+    softegg_cat.spam() << "vert external index = " << vert->get_external_index() << endl;
+    //    softegg_cat.spam() << "found vert " << vert << endl;
+    //    softegg_cat.spam() << "vert [" << i << "] " << vpool->get_vertex(i+1);
     LPoint3d p3d = vert->get_pos3();
 
     // find closest model vertex 
@@ -1218,12 +1560,12 @@ FindClosestTriVert( EggVertexPool *vpool, SAA_DVector *vertices, int numVert ) {
     }
     vertMap[i] = closest;
     
-    cout << "mapping v " << i << " of " << vpoolSize-1 << ":( "
+    softegg_cat.spam() << "mapping v " << i << " of " << vpoolSize-1 << ":( "
          << p3d[0] << " "
          << p3d[1] << " "
          << p3d[2] << ")\n";
 
-    cout << "    to cv " << closest << " of " << numVert-1 << ":( "
+    softegg_cat.spam() << "    to cv " << closest << " of " << numVert-1 << ":( "
          << vertices[closest].x << " "
          << vertices[closest].y << " "
          << vertices[closest].z << " )\tdelta = " << closestDist << endl;
@@ -1244,13 +1586,17 @@ make_soft_skin() {
   SoftNodeDesc *node_desc;
   SAA_Boolean isSkeleton;
 
-  cout << endl << "----------------------------------------------------------------" << endl;
+  softegg_cat.spam() << endl << "----------------------------------------------------------------" << endl;
 
   for (int i = 0; i < num_nodes; i++) {
     node_desc = _tree.get_node(i);
     SAA_modelIsSkeleton( &scene, node_desc->get_model(), &isSkeleton );
 
     if (isSkeleton && node_desc->is_joint()) {
+
+      if (node_desc->is_partial(search_prefix))
+          continue;
+
       // Now that we've added all the polygons (and created all the
       // vertices), go back through the vertex pool and set up the
       // appropriate joint membership for each of the vertices.
@@ -1265,17 +1611,17 @@ make_soft_skin() {
 
       SAA_skeletonGetNbEnvelopes( &scene, model, &numEnv );
       if ( numEnv == 0 ) {
-        cout << "no soft skinning for joint " << node_desc->get_name() << endl;
+        softegg_cat.spam() << "no soft skinning for joint " << node_desc->get_name() << endl;
         continue;
       }
       
       // it's got envelopes - must be soft skinned
-      cout << endl << "found skeleton part( " << node_desc->get_name() << ")!\n";
-      cout << "numEnv = " << numEnv << endl;
+      softegg_cat.spam() << endl << "found skeleton part( " << node_desc->get_name() << ")!\n";
+      softegg_cat.spam() << "numEnv = " << numEnv << endl;
       // allocate envelope array
       envelopes = new SAA_Elem[numEnv];
       if ( envelopes == NULL ) {
-        cout << "Out Of Memory" << endl;
+        softegg_cat.spam() << "Out Of Memory" << endl;
         exit(1);
       }
       int thisEnv;
@@ -1284,26 +1630,26 @@ make_soft_skin() {
         
       SAA_skeletonGetEnvelopes( &scene, model, numEnv, envelopes );
       for ( thisEnv = 0; thisEnv < numEnv; thisEnv++ ) {
-        cout << "env[" << thisEnv << "]: ";
+        softegg_cat.spam() << "env[" << thisEnv << "]: ";
         SAA_envelopeGetType( &scene, &envelopes[thisEnv], &envType );
         
         if ( envType == SAA_ENVTYPE_NONE ) {
-          cout << "envType = none\n";
+          softegg_cat.spam() << "envType = none\n";
         }
         else if ( envType == SAA_ENVTYPE_FLXLCL ) {
-          cout << "envType = flexible, local\n";
+          softegg_cat.spam() << "envType = flexible, local\n";
           hasEnvVertices = 1;
         }
         else if ( envType == SAA_ENVTYPE_FLXGLB ) {
-          cout << "envType = flexible, global\n";
+          softegg_cat.spam() << "envType = flexible, global\n";
           hasEnvVertices = 1;
         }
         else if ( envType == SAA_ENVTYPE_RGDGLB ) {
-          cout << "envType = rigid, global\n";
+          softegg_cat.spam() << "envType = rigid, global\n";
           hasEnvVertices = 1;
         }
         else {
-          cout << "envType = unknown\n";
+          softegg_cat.spam() << "envType = unknown\n";
         }
 
       }
@@ -1321,9 +1667,9 @@ make_soft_skin() {
         int totalEnvVertices = 0;
         for( i = 0; i < numEnv; i++ ) {
           totalEnvVertices += numEnvVertices[i];
-          cout << "numEnvVertices[" << i << "] = " << numEnvVertices[i] << endl;
+          softegg_cat.spam() << "numEnvVertices[" << i << "] = " << numEnvVertices[i] << endl;
         }
-        cout << "total env verts = " << totalEnvVertices << endl;
+        softegg_cat.spam() << "total env verts = " << totalEnvVertices << endl;
         if ( totalEnvVertices == 0 )
           continue;
 
@@ -1332,25 +1678,25 @@ make_soft_skin() {
           result = SAA_envelopeGetCtrlVertices( &scene, model,
                                                 numEnv, envelopes, numEnvVertices, envVertices);
           if (result != SI_SUCCESS) {
-            cout << "error: GetCtrlVertices\n";
+            softegg_cat.spam() << "error: GetCtrlVertices\n";
             exit(1);
           }
           // loop through for each envelope
           for ( i = 0; i < numEnv; i++ ) {
             float *weights = NULL;
             int vertArrayOffset = 0;
-            cout << "envelope[" << i << "]: ";
+            softegg_cat.spam() << "envelope[" << i << "]: ";
             weights = new float[numEnvVertices[i]];
             if ( weights ) {
               char *envName;
               int *vpoolMap = NULL;
               for ( j = 0; j < i; j++ )
                 vertArrayOffset += numEnvVertices[j];
-              cout << "envVertArray offset = " << vertArrayOffset;
+              softegg_cat.spam() << "envVertArray offset = " << vertArrayOffset;
 
               /*              
               if (vertArrayOffset == totalEnvVertices) {
-                cout << endl;                  vpoolMap = FindClosestTriVert( vpool, globalModelVertices, modelNumVert );
+                softegg_cat.spam() << endl;                  vpoolMap = FindClosestTriVert( vpool, globalModelVertices, modelNumVert );
 
                 break;
               }
@@ -1371,26 +1717,26 @@ make_soft_skin() {
                 envName = _tree.GetName( &scene, &envelopes[i] );
               }
 
-              cout << " envelop name is [" << envName << "]" << endl;
+              softegg_cat.spam() << " envelop name is [" << envName << "]" << endl;
               
               if (result != SI_SUCCESS) {
-                cout << "warning: this envelop doesn't have any weights\n";
+                softegg_cat.spam() << "warning: this envelop doesn't have any weights\n";
                 continue;
               }
 
               result = SAA_modelGetType( &scene, &envelopes[i], &type );
               if (result != SI_SUCCESS) {
-                cout << "choked on get type\n";
+                softegg_cat.spam() << "choked on get type\n";
                 exit(1);
               }
 
-              cout << "envelope model type ";
+              softegg_cat.spam() << "envelope model type ";
               if ( type == SAA_MSMSH )
-                cout << "MESH\n";
+                softegg_cat.spam() << "MESH\n";
               else if ( type == SAA_MNSRF )
-                cout << "NURBS\n";
+                softegg_cat.spam() << "NURBS\n";
               else
-                cout << "OTHER\n";
+                softegg_cat.spam() << "OTHER\n";
               
               int *envVtxIndices = NULL;
               envVtxIndices = new int[numEnvVertices[i]];
@@ -1400,7 +1746,7 @@ make_soft_skin() {
                                                  &envVertices[vertArrayOffset], envVtxIndices );
               
               if (result != SI_SUCCESS) {
-                cout << "error: choked on get indices\n";
+                softegg_cat.spam() << "error: choked on get indices\n";
                 exit(1);
               }
 
@@ -1437,7 +1783,7 @@ make_soft_skin() {
               string s_name = envName;
               SoftNodeDesc *mesh_node = find_node(s_name);
               if (!mesh_node) {
-                cout << "error: node " << s_name << " not found in tree\n";
+                softegg_cat.spam() << "error: node " << s_name << " not found in tree\n";
                 exit(1);
               }
               string vpool_name = s_name + ".verts";
@@ -1445,13 +1791,13 @@ make_soft_skin() {
 
               // find the mapping of the vertices that match this envelop
               if (vpool) {
-                cout << "found vpool of size " << vpool->size() << endl;
+                softegg_cat.spam() << "found vpool of size " << vpool->size() << endl;
                 if ( !make_nurbs || (type == SAA_MSMSH) ) {
                   vpoolMap = FindClosestTriVert( vpool, globalModelVertices, modelNumVert );
                 }
               }
               else {
-                cout << "error: vpool " << vpool_name << " not found\n";
+                softegg_cat.spam() << "error: vpool " << vpool_name << " not found\n";
                 exit(1);
               }
 
@@ -1465,9 +1811,13 @@ make_soft_skin() {
                     && ( envVtxIndices[j] >= 0 )) {
                   if ( (type == SAA_MNSRF) && make_nurbs ) { 
                     // assign all referenced control vertices
-                    EggVertex *vert = vpool->get_vertex(envVtxIndices[j]+1);
+                    EggVertex *vert = vpool->get_vertex(envVtxIndices[j]);
+                    if (!vert) {
+                      softegg_cat.spam() << "possible error: index " << envVtxIndices[j] << ": vert is " << vert << endl;
+                      continue;
+                    }
                     joint->ref_vertex( vert, scaledWeight );
-                    cout << j << ": adding vref to cv " << envVtxIndices[j] 
+                    softegg_cat.spam() << j << ": adding vref to cv " << envVtxIndices[j]
                          << " with weight " << scaledWeight << endl; 
 
                     /*
@@ -1480,18 +1830,18 @@ make_soft_skin() {
                   else {    
                     //assign all the tri verts associated
                     // with this control vertex to joint
-                    cout << j << "--trying to find " << envVtxIndices[j] << endl;
+                    softegg_cat.spam() << j << "--trying to find " << envVtxIndices[j] << endl;
                     for ( k = 0; k < (int)vpool->size(); k++ ) {
                       if ( vpoolMap[k] == envVtxIndices[j] ) {
                         EggVertex *vert = vpool->get_vertex(k+1);
                         //                        EggVertex *vert = mesh_node->get_vpool()->get_vertex(vpoolMap[k]+1);
                         if (!vert) {
-                          cout << "possible error: index " << k+1 << ": vert is " << vert << endl;
+                          softegg_cat.spam() << "possible error: index " << k+1 << ": vert is " << vert << endl;
                           break;
                         }
 
                         joint->ref_vertex(vert, scaledWeight);
-                        cout << j << ": adding vref from cv " << envVtxIndices[j]
+                        softegg_cat.spam() << j << ": adding vref from cv " << envVtxIndices[j]
                              << " to vert " << k+1 << " with weight " << scaledWeight
                              << "(vpool)\n";
                         /*

+ 6 - 39
pandatool/src/softegg/softToEggConverter.h

@@ -44,7 +44,6 @@ class EggVertexPool;
 class EggNurbsCurve;
 class EggPrimitive;
 class EggXfmSAnim;
-//class MayaShaderColorDef;
 
 
 ////////////////////////////////////////////////////////////////////
@@ -89,36 +88,13 @@ private:
   bool convert_hierarchy(EggGroupNode *egg_root);
   bool process_model_node(SoftNodeDesc *node_desc);
 
-  /*
-  void get_joint_transform(const MDagPath &dag_path, EggGroup *egg_group);
-
-  // I ran into core dumps trying to pass around a MFnMesh object by
-  // value.  From now on, all MFn* objects will be passed around by
-  // reference.
-  void make_nurbs_surface(const MDagPath &dag_path, 
-                          MFnNurbsSurface &surface,
-                          EggGroup *group);
-  EggNurbsCurve *make_trim_curve(const MFnNurbsCurve &curve,
-                                 const string &nurbs_name,
-                                 EggGroupNode *egg_group,
-                                 int trim_curve_index);
-  void make_nurbs_curve(const MDagPath &dag_path, 
-                        const MFnNurbsCurve &curve,
-                        EggGroup *group);
-  */
   void make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type);
-  /*
-  void make_locator(const MDagPath &dag_path, const MFnDagNode &dag_node,
-                    EggGroup *egg_group);
-  bool get_vertex_weights(SoftNodeDesc *node_desc, 
-                          pvector<EggGroup *> &joints, vector<float> &weights);
-  */
+  void make_nurb_surface(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type);
+  void add_knots( vector <double> &eggKnots, double *knots, int numKnots, SAA_Boolean closed, int degree );
+
   void set_shader_attributes(SoftNodeDesc *node_desc, EggPrimitive &primitive, char *texName);
   void apply_texture_properties(EggTexture &tex, int uRepeat, int vRepeat);
-  /*
-  bool compare_texture_properties(EggTexture &tex, 
-                                  const MayaShaderColorDef &color_def);
-  */
+
   bool reparent_decals(EggGroupNode *egg_parent);
 
   string _program_name;
@@ -140,7 +116,7 @@ public:
   const char *_commandName;
 
   // This is the entire command line.
-  const char *_commandLine;
+  char _commandLine[4096];
 
   char        *rsrc_path;
   char        *database_name;
@@ -179,20 +155,11 @@ public:
   
   char *GetTextureName( SAA_Scene *scene, SAA_Elem *texture );
 
-  /*
-  MayaShaders _shaders;
-  */
   EggTextureCollection _textures;
-  /*
-  PT(MayaApi) _maya;
-  */
 
   bool _polygon_output;
   double _polygon_tolerance;
-  /*
-  bool _respect_maya_double_sided;
-  bool _always_show_vertex_color;
-  */
+
   enum TransformType {
     TT_invalid,
     TT_all,