Browse Source

pandatool: Delete softegg/softprogs

These depend on "SAA" - a Softimage library so long gone I
can't even find references to it on Google.
Sam Edwards 7 years ago
parent
commit
43142e4e80

+ 0 - 55
pandatool/src/softegg/config_softegg.cxx

@@ -1,55 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file config_softegg.cxx
- * @author masad
- * @date 2003-09-25
- */
-
-#include "config_softegg.h"
-#include "softEggGroupUserData.h"
-#include "softNodeDesc.h"
-
-#include "dconfig.h"
-
-Configure(config_softegg);
-NotifyCategoryDef(softegg, ":soft");
-
-ConfigureFn(config_softegg) {
-  init_libsoftegg();
-}
-
-// These control the default behavior of the softegg converter, but not
-// necessarily the default behavior of the soft2egg command-line tool (which
-// has its own defaults).
-
-// Should we respect the Soft?  double-sided flag (true) or ignore it and
-// assume everything is single-sided (false)?
-ConfigVariableBool soft_default_double_sided("soft-default-double-sided", false);
-
-// Should we apply vertex color even when a texture is applied (true) or only
-// when no texture is applied or the vertex-color egg flag is set (false)?
-ConfigVariableBool soft_default_vertex_color("soft-default-vertex-color", true);
-
-/**
- * Initializes the library.  This must be called at least once before any of
- * the functions or classes in this library can be used.  Normally it will be
- * called by the static initializers and need not be called explicitly, but
- * special cases exist.
- */
-void
-init_libsoftegg() {
-  static bool initialized = false;
-  if (initialized) {
-    return;
-  }
-  initialized = true;
-
-  SoftEggGroupUserData::init_type();
-  SoftNodeDesc::init_type();
-}

+ 0 - 28
pandatool/src/softegg/config_softegg.h

@@ -1,28 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file config_softegg.h
- * @author masad
- * @date 2003-09-25
- */
-
-#ifndef CONFIG_SOFTEGG_H
-#define CONFIG_SOFTEGG_H
-
-#include "pandatoolbase.h"
-#include "notifyCategoryProxy.h"
-#include "configVariableBool.h"
-
-NotifyCategoryDeclNoExport(softegg);
-
-extern ConfigVariableBool soft_default_double_sided;
-extern ConfigVariableBool soft_default_vertex_color;
-
-extern void init_libsoftegg();
-
-#endif

+ 0 - 4751
pandatool/src/softegg/soft2Egg.c

@@ -1,4751 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file soft2Egg.c
- * @author masad
- * @date 2003-09-26
- */
-
-#include <SAA.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "pandatoolbase.h"
-
-int init_soft2egg(int, char **);
-
-#if 0
-// DWD includes
-#include "eggBase.h"
-#include <eggParametrics.h>
-#include <animTable.h>
-#include <linMathOutput.h>
-
-// system includes
-#include <fstream.h>
-#include <strstream.h>
-#include <math.h>
-#include <assert.h>
-#include <unistd.h>
-#include <ieeefp.h>
-
-// Performer includes
-#include <Performer/pr/pfLinMath.h>
-
-// SoftImage includes
-#include <SAA.h>
-#include <SI_macros.h>
-
-static const int    TEX_PER_MAT = 1;
-static FILE            *outStream  = stdout;
-// static FILE        *outStream  = stderr;
-
-class soft2egg : public EggBase
-{
-  public:
-
-    soft2egg() : EggBase("r:d:s:m:t:P:b:e:f:T:S:M:A:N:v:o:FhknpaxiucCD")
-    {
-        rsrc_path = "/ful/ufs/soft371_mips2/3D/rsrc";
-        database_name = NULL;
-        scene_name = NULL;
-        model_name = NULL;
-        animFileName = NULL;
-        eggFileName = NULL;
-        tex_path = NULL;
-        eggGroupName = NULL;
-        tex_filename = NULL;
-        search_prefix = NULL;
-        result = SI_SUCCESS;
-
-        skeleton = new EggGroup();
-        foundRoot = FALSE;
-        animRoot = NULL;
-        morphRoot = NULL;
-        geom_as_joint = 0;
-        make_anim = 0;
-        make_nurbs = 0;
-        make_poly = 0;
-        make_soft = 0;
-        make_morph = 1;
-        make_duv = 1;
-        make_dart = TRUE;
-        has_morph = 0;
-        make_pose = 0;
-        animData.is_z_up = FALSE;
-        nurbs_step = 1;
-        anim_start = -1000;
-        anim_end = -1000;
-        anim_rate = 24;
-        pose_frame = -1;
-        verbose = 0;
-        flatten = 0;
-        shift_textures = 0;
-        ignore_tex_offsets = 0;
-        use_prefix = 0;
-    }
-
-    virtual void Help();
-    virtual void Usage();
-    virtual void ShowOpts();
-
-    virtual boolean UseOutputSwitch() const {
-       return false;
-    }
-
-    virtual boolean
-    HandleGetopts(char flag, char *optarg, int &optind, int argc, char **argv);
-
-    int   isNum( float );
-    char *GetRootName( const char * );
-    char *RemovePathName( const char * );
-    char *GetSliderName( const char * );
-    char *GetFullName( SAA_Scene *, SAA_Elem * );
-    char *GetName( SAA_Scene *, SAA_Elem * );
-    char *GetModelNoteInfo( SAA_Scene *, SAA_Elem * );
-    char *MakeTableName( const char *, int );
-    char *DepointellizeName( char * );
-    SAA_Elem *FindModelByName( char *, SAA_Scene *, SAA_Elem *, int );
-    char *ConvertTexture( SAA_Scene *, SAA_Elem * );
-    int  *FindClosestTriVert( EggVertexPool *, SAA_DVector *, int );
-    int  *MakeIndexMap( int *, int, int );
-    int     findShapeVert( SAA_DVector, SAA_DVector *, int );
-    void LoadSoft();
-    void MakeEgg( EggGroup *, EggJoint *, AnimGroup *, SAA_Scene *, SAA_Elem * );
-    void MakeSurfaceCurve(  SAA_Scene *, SAA_Elem *, EggGroup *,
-        EggNurbsSurface *&, int , SAA_SubElem *, bool );
-
-    EggNurbsCurve *MakeUVNurbsCurve( int, long *,  double *, double *,
-        EggGroup *, char * );
-
-    EggNurbsCurve *MakeNurbsCurve( SAA_Scene *, SAA_Elem *, EggGroup *,
-        float [4][4], char * );
-
-    void AddKnots( perf_vector<double> &, double *, int, SAA_Boolean, int );
-    void MakeJoint( SAA_Scene *, EggJoint *&, AnimGroup *&, SAA_Elem *, char * );
-    void MakeSoftSkin( SAA_Scene *, SAA_Elem *, SAA_Elem *, int, char * );
-    void CleanUpSoftSkin( SAA_Scene *, SAA_Elem *, char * );
-    void MakeAnimTable( SAA_Scene *, SAA_Elem *, char * );
-    void MakeVertexOffsets( SAA_Scene *, SAA_Elem *, SAA_ModelType type,
-        int, int, SAA_DVector *, float (*)[4], char * );
-    void MakeMorphTable( SAA_Scene *, SAA_Elem *, SAA_Elem *, int,  char *,
-        float );
-    void MakeLinearMorphTable( SAA_Scene *, SAA_Elem *, int, char *, float );
-    void MakeWeightedMorphTable( SAA_Scene *, SAA_Elem *, SAA_Elem *, int,
-        int, char *, float );
-    void MakeExpressionMorphTable( SAA_Scene *, SAA_Elem *, SAA_Elem *, int,
-        int, char *, float );
-    void MakeTexAnim( SAA_Scene *, SAA_Elem *, char * );
-
-  private:
-
-    char        *rsrc_path;
-    char        *database_name;
-    char        *scene_name;
-    char        *model_name;
-    char        *eggFileName;
-    char         *animFileName;
-    char         *eggGroupName;
-    char        *tex_path;
-    char        *tex_filename;
-    char        *search_prefix;
-
-    SI_Error            result;
-    SAA_Scene           scene;
-    SAA_Elem            model;
-    SAA_Database        database;
-    EggGroup           *dart;
-    EggGroup           *skeleton;
-    AnimGroup          *rootAnim;
-    EggJoint           *rootJnt;
-    AnimGroup          *animRoot;
-    AnimGroup          *morphRoot;
-    EggData             animData;
-
-    int                    nurbs_step;
-    int                    anim_start;
-    int                    anim_end;
-    int                    anim_rate;
-    int                    pose_frame;
-    int                    verbose;
-    int                    flatten;
-    int                    shift_textures;
-    int                    ignore_tex_offsets;
-    int                    use_prefix;
-
-    bool                foundRoot;
-    bool                geom_as_joint;
-    bool                make_anim;
-    bool                make_nurbs;
-    bool                make_poly;
-    bool                make_soft;
-    bool                make_morph;
-    bool                make_duv;
-    bool                make_dart;
-    bool                has_morph;
-    bool                make_pose;
-
-    std::ofstream eggFile;
-    std::ofstream animFile;
-    std::ofstream texFile;
-};
-
-
-/**
- * Displays the "what is this program" message, along with the usage message.
- * Should be overridden in base classes to describe the current program.
- */
-void soft2egg::
-Help()
-{
-    cerr <<
-    "soft2egg takes a SoftImage scene or model\n"
-    "and outputs its contents as an egg file\n";
-
-    Usage();
-}
-
-/**
- * Displays the usage message.
- */
-void soft2egg::
-Usage() {
-  cerr << "\nUsage:\n"
-       << _commandName << " [opts] (must specify -m or -s)\n\n"
-       << "Options:\n";
-
-  ShowOpts();
-  cerr << "\n";
-}
-
-
-
-/**
- * Displays the valid options.  Should be extended in base classes to show
- * additional options relevant to the current program.
- */
-void soft2egg::
-ShowOpts()
-{
-    cerr <<
-    "  -r <path>  - Used to provide soft with the resource\n"
-    "               Defaults to 'c:/Softimage/SOFT_3.9.2/3D/test'.\n"
-      // "               Defaults to 'fulufssoft371_mips23Drsrc'.\n"
-    "  -d <path>  - Database path.\n"
-    "  -s <scene> - Indicates that a scene will be converted.\n"
-    "  -m <model> - Indicates that a model will be converted.\n"
-    "  -t <path>  - Specify path to place converted textures.\n"
-    "  -T <name>  - Specify filename for texture map listing.\n"
-    "  -S <step>  - Specify step for nurbs surface triangulation.\n"
-    "  -M <name>  - Specify model output filename. Defaults to scene name.\n"
-    "  -A <name>  - Specify anim output filename. Defaults to scene name.\n"
-    "  -N <name>  - Specify egg group name.\n"
-    "  -k         - Enable soft assignment for geometry.\n"
-    "  -n         - Specify egg NURBS representation instead of poly's.\n"
-    "  -p         - Specify egg polygon output for geometry.\n"
-    "  -P <frame> - Specify frame number for static pose.\n"
-    "  -b <frame> - Specify starting frame for animation (default = first).\n"
-    "  -e <frame> - Specify ending frame for animation (default = last).\n"
-    "  -f <fps>   - Specify frame rate for animation playback.\n"
-    "  -a         - Compile animation tables if animation present.\n"
-    "  -F         - Ignore hierarchy and build a completely flat skeleton.\n"
-    "  -v <level> - Set debug level.\n"
-    "  -x         - Shift NURBS parameters to preserve Alias textures.\n"
-    "  -i         - Ignore Soft texture uv offsets.\n"
-    "  -u         - Use Soft prefix in model names.\n"
-    "  -c         - Cancel morph conversion.\n"
-    "  -C         - Cancel duv conversion.\n"
-    "  -D         - Don't make the output model a character.\n"
-    "  -o <prefix>- Convert only models with given prefix.\n";
-
-      EggBase::ShowOpts();
-}
-
-
-/**
- *
- */
-boolean soft2egg::
-HandleGetopts(char flag, char *optarg, int &optind, int argc, char **argv)
-{
-    boolean okflag = true;
-
-    switch (flag)
-    {
-      case 'r':       // Set the resource path for soft.
-        if ( strcmp( optarg, "" ) )
-        {
-            // Get the path.
-            rsrc_path = optarg;
-            fprintf( outStream, "using rsrc path %s\n", rsrc_path );
-        }
-        break;
-
-    case 'd':       // Set the database path.
-        if ( strcmp( optarg, "" ) )
-        {
-            // Get the path.
-            database_name = optarg;
-            fprintf( outStream, "using database %s\n", database_name );
-        }
-        break;
-
-    case 's':     // Check if its a scene.
-        if ( strcmp( optarg, "" ) )
-        {
-            // Get scene name.
-            scene_name = optarg;
-            fprintf( outStream, "loading scene %s\n", scene_name );
-        }
-        break;
-
-    case 'm':     // Check if its a model.
-        if ( strcmp( optarg, "" ) )
-        {
-            // Get model name.
-            model_name = optarg;
-            fprintf( outStream, "loading model %s\n", model_name );
-        }
-        break;
-
-    case 't':     // Get converted texture path.
-        if ( strcmp( optarg, "" ) )
-        {
-            // Get tex path name.
-            tex_path = optarg;
-            fprintf( outStream, "texture path:  %s\n", tex_path );
-        }
-        break;
-
-    case 'T':      // Specify texture list filename.
-        if ( strcmp( optarg, "") )
-        {
-            // Get the name.
-            tex_filename = optarg;
-            fprintf( outStream, "creating texture list file: %s\n",
-                tex_filename );
-        }
-        break;
-    case 'S':     // Set NURBS step.
-        if ( strcmp( optarg, "" ) )
-        {
-            nurbs_step = atoi(optarg);
-            fprintf( outStream, "NURBS step:  %d\n", nurbs_step );
-        }
-        break;
-
-    case 'M':     // Set model output file name.
-        if ( strcmp( optarg, "" ) )
-        {
-            eggFileName = optarg;
-            fprintf( outStream, "Model output filename:  %s\n", eggFileName );
-        }
-        break;
-
-    case 'A':     // Set anim output file name.
-        if ( strcmp( optarg, "" ) )
-        {
-            animFileName = optarg;
-            fprintf( outStream, "Anim output filename:  %s\n", animFileName );
-        }
-        break;
-
-    case 'N':     // Set egg model name.
-        if ( strcmp( optarg, "" ) )
-        {
-            eggGroupName = optarg;
-            fprintf( outStream, "Egg group name:  %s\n", eggGroupName );
-        }
-        break;
-
-    case 'o':     // Set search_prefix.
-        if ( strcmp( optarg, "" ) )
-        {
-            search_prefix = optarg;
-            fprintf( outStream, "Only converting models with prefix:  %s\n",
-                search_prefix );
-        }
-        break;
-
-    case 'h':    // print help message
-        Help();
-        exit(1);
-        break;
-
-    case 'c':    // Cancel morph animation conversion
-        make_morph = FALSE;
-        fprintf( outStream, "canceling morph conversion\n" );
-        break;
-
-    case 'C':    // Cancel uv animation conversion
-        make_duv = FALSE;
-        fprintf( outStream, "canceling uv animation conversion\n" );
-        break;
-
-    case 'D':    // Omit the Dart flag
-        make_dart = FALSE;
-        fprintf( outStream, "making a non-character model\n" );
-        break;
-
-    case 'k':    // Enable soft skinning
-        // make_soft = TRUE; fprintf( outStream, "enabling soft skinning\n" );
-        fprintf( outStream, "-k flag no longer necessary\n" );
-        break;
-
-    case 'n':    // Generate egg NURBS output
-        make_nurbs = TRUE;
-        fprintf( outStream, "outputting egg NURBS info\n" );
-        break;
-
-    case 'p':    // Generate egg polygon output
-        make_poly = TRUE;
-        fprintf( outStream, "outputting egg polygon info\n" );
-        break;
-
-    case 'P':    // Generate static pose from given frame
-        if ( strcmp( optarg, "" ) )
-        {
-            make_pose = TRUE;
-            pose_frame = atoi(optarg);
-            fprintf( outStream, "generating static pose from frame %d\n",
-                pose_frame );
-        }
-        break;
-
-    case 'a':     // Compile animation tables.
-        make_anim = TRUE;
-        fprintf( outStream, "attempting to compile anim tables\n" );
-        break;
-
-    case 'F':     // Build a flat skeleton.
-        flatten = TRUE;
-        fprintf( outStream, "building a flat skeleton!!!\n" );
-        break;
-
-    case 'x':     // Shift NURBS parameters to preserve Alias textures.
-        shift_textures = TRUE;
-        fprintf( outStream, "shifting NURBS parameters...\n" );
-        break;
-
-    case 'i':     // Ignore Soft uv texture offsets
-        ignore_tex_offsets = TRUE;
-        fprintf( outStream, "ignoring texture offsets...\n" );
-        break;
-
-    case 'u':     // Use Soft prefix in model names
-        use_prefix = TRUE;
-        fprintf( outStream, "using prefix in model names...\n" );
-        break;
-
-
-    case 'v':     // print debug messages.
-        if ( strcmp( optarg, "" ) )
-        {
-            verbose = atoi(optarg);
-            fprintf( outStream, "using debug level %d\n", verbose );
-        }
-        break;
-
-    case 'b':     // Set animation start frame.
-        if ( strcmp( optarg, "" ) )
-        {
-            anim_start = atoi(optarg);
-            fprintf( outStream, "animation starting at frame:  %d\n",
-                anim_start );
-        }
-        break;
-
-    case 'e':     /// Set animation end frame.
-        if ( strcmp( optarg, "" ) )
-        {
-            anim_end = atoi(optarg);
-            fprintf( outStream, "animation ending at frame:  %d\n", anim_end );
-        }
-        break;
-
-    case 'f':     /// Set animation frame rate.
-        if ( strcmp( optarg, "" ) )
-        {
-            anim_rate = atoi(optarg);
-            fprintf( outStream, "animation frame rate:  %d\n", anim_rate );
-        }
-        break;
-
-    default:
-        okflag = EggBase::HandleGetopts(flag, optarg, optind, argc, argv);
-  }
-
-  return (okflag);
-}
-
-
-
-/**
- * Take a float and make sure it is of the body.
- */
-int soft2egg::
-isNum( float num )
-{
-    return( ( num < HUGE_VAL ) && finite( num ) );
-}
-
-
-/**
- * Given a string, return a copy of the string up to the first occurrence of
- * '-'.
- */
-char *soft2egg::
-GetRootName( const char *name )
-{
-    char *hyphen;
-    char *root;
-    int      len;
-
-    hyphen = strchr( name, '-' );
-    len = hyphen-name;
-
-    if ( (hyphen != NULL) && len )
-    {
-        root = (char *)malloc(sizeof(char)*(len+1));
-        strncpy( root, name, len );
-        root[sizeof(char)*(len)] = '\0';
-    }
-    else
-    {
-        root = (char *)malloc( sizeof(char)*(strlen(name)+1));
-        strcpy( root, name );
-    }
-
-    return( root );
-}
-
-
-/**
- * Given a string, return a copy of the string after the last occurence of '
- */
-char *soft2egg::
-RemovePathName( const char *name )
-{
-    char *slash;
-    char *root;
-
-    if ( *name != NULL )
-    {
-        slash = strrchr( name, '/' );
-
-        root = (char *)malloc( sizeof(char)*(strlen(name)+1));
-
-        if ( slash != NULL )
-            strcpy( root, ++slash );
-        else
-            strcpy( root, name );
-
-        return( root );
-    }
-
-    fprintf( stderr, "Error: RemovePathName received NULL string!\n" );
-    return ( (char *)name );
-}
-
-/**
- * Given a string, return that part of the string after the first occurence of
- * '-' and before the last occurance of '.'
- */
-char *soft2egg::
-GetSliderName( const char *name )
-{
-    if ( name != NULL )
-    {
-        strstream newStr;
-        char *hyphen;
-        char *end;
-
-        hyphen = strchr( name, '-' );
-
-        // pull off stuff before first hyphen
-        if (hyphen != NULL)
-        {
-            newStr << ++hyphen;
-            end = newStr.str();
-        }
-
-        char *lastPeriod;
-
-        lastPeriod = strrchr( end, '.' );
-
-        // ignore stuff after last period
-        if ( lastPeriod != NULL )
-        {
-            *lastPeriod = '\0';
-        }
-
-        if ( verbose >= 1 )
-            fprintf( stdout, "slider name: '%s'\n", end );
-
-        return( end );
-    }
-
-    return( (char *)name );
-}
-
-/**
- * Given an element, return a copy of the element's name WITHOUT prefix.
- */
-char *soft2egg::
-GetName( SAA_Scene *scene, SAA_Elem *element )
-{
-    int    nameLen;
-    char *name;
-
-    // get the name
-    SAA_elementGetNameLength( scene, element, &nameLen );
-    name = (char *)malloc(sizeof(char)*++nameLen);
-    SAA_elementGetName( scene, element, nameLen, name );
-
-    return name;
-}
-
-/**
- * Given an element, return a copy of the element's name complete with prefix.
- */
-char *soft2egg::
-GetFullName( SAA_Scene *scene, SAA_Elem *element )
-{
-    int    nameLen;
-    char *name;
-
-    // get the name
-    SAA_elementGetNameLength( scene, element, &nameLen );
-    name = (char *)malloc(sizeof(char)*++nameLen);
-    SAA_elementGetName( scene, element, nameLen, name );
-
-    int prefixLen;
-    char *prefix;
-
-    // get the prefix
-    SAA_elementGetPrefixLength( scene, element, &prefixLen );
-    prefix = (char *)malloc(sizeof(char)*++prefixLen);
-    SAA_elementGetPrefix( scene, element, prefixLen, prefix );
-
-    strstream fullNameStrm;
-
-    // add 'em together
-    fullNameStrm << prefix << "-" << name << ends;
-
-    // free( name ); free( prefix );
-
-    return fullNameStrm.str();
-}
-
-/**
- * Given an element, return a string containing the contents of its MODEL NOTE
- * entry
- */
-char *soft2egg::
-GetModelNoteInfo( SAA_Scene *scene, SAA_Elem *model )
-{
-
-    int         size;
-    char     *modelNote = NULL;
-    SAA_Boolean bigEndian;
-
-
-    SAA_elementGetUserDataSize( scene, model, "MNOT", &size );
-
-    if ( size != 0 )
-    {
-        // allocate modelNote string
-        modelNote = (char *)malloc(sizeof(char)*(size + 1));
-
-        // get ModelNote data from this model
-        SAA_elementGetUserData( scene, model, "MNOT", size,
-            &bigEndian, (void *)modelNote );
-
-        // strip off newline, if present
-        char *eol = strchr( modelNote, '\n' );
-        if ( eol != NULL)
-            *eol = '\0';
-        else
-            modelNote[size] = '\0';
-
-        if ( verbose >= 1 )
-            fprintf( outStream, "\nmodelNote = %s\n",
-                modelNote );
-    }
-
-    return modelNote;
-}
-
-
-/**
- * Given a string, and a number, return a new string consisting of
- * "string.number".
- */
-char *soft2egg::
-MakeTableName( const char *name, int number )
-{
-    strstream namestrm;
-
-    namestrm << name << "." << number << ends;
-    return namestrm.str();
-}
-
-/**
- * Given a string, find the model in the scene whose name corresponds to the
- * given string.
- */
-SAA_Elem *soft2egg::
-FindModelByName( char *name, SAA_Scene *scene, SAA_Elem *models,
-    int numModels )
-{
-    char     *foundName;
-    SAA_Elem *foundModel = NULL;
-
-    for ( int model = 0; model < numModels; model++ )
-    {
-        foundName = GetName( scene, &models[model] );
-
-        if ( !strcmp( name, foundName ) )
-        {
-            if ( verbose >= 1 )
-                fprintf( outStream, "foundModel: '%s' = '%s'\n",
-                    name, foundName );
-
-            foundModel = &models[model];
-            return( foundModel );
-        }
-    }
-
-    fprintf( outStream, "findModelByName: failed to find model named: '%s'\n",
-        name );
-
-    return ( foundModel );
-}
-
-
-/**
- * Given a string, return the string up to the first period.
- */
-char *soft2egg::
-DepointellizeName( char *name )
-{
-    char    *endPtr;
-    char    *newName;
-
-    newName = (char *)malloc(sizeof(char)*(strlen(name)+1));
-    sprintf( newName, "%s", name );
-
-    endPtr = strchr( newName, '.' );
-    if ( endPtr != NULL )
-      *endPtr = '\0';
-
-    return ( newName );
-}
-
-
-/**
- * Given a string, return a copy of the string without the leading file path,
- * and make an rgb file of the same name in the tex_path directory.
- */
-char *soft2egg::
-ConvertTexture( SAA_Scene *scene, SAA_Elem *texture )
-{
-  char *fileName = NULL;
-  int  fileNameLen = 0;
-
-  // get the texture's name
-  SAA_texture2DGetPicNameLength( scene, texture, &fileNameLen);
-
-  if ( fileNameLen )
-  {
-        fileName = (char *)malloc(sizeof(char)*++fileNameLen);
-        SAA_texture2DGetPicName( scene, texture, fileNameLen, fileName );
-  }
-
-  // make sure we are not being passed a NULL image, an empty image string or
-  // the default image created by egg2soft
-  if ( (fileName != NULL) && strlen( fileName ) && strcmp( fileName,
-        "/fat/people/gregw/new_test/PICTURES/default") &&
-                                ( strstr( fileName, "noIcon" ) == NULL) )
-  {
-    char *texName = NULL;
-    char *texNamePath = NULL;
-    char *tmpName = NULL;
-    char *fileNameExt = NULL;
-
-    // strip off path and add .rgb
-    tmpName = strrchr( fileName, '/' );
-
-    if ( tmpName == NULL )
-        tmpName = fileName;
-    else
-        tmpName++;
-
-    float transp;
-
-        // check for alpha
-        SAA_texture2DGetTransparency( scene, texture, &transp );
-
-        if ( transp != 0.0f ) {
-        texName = (char *)malloc(sizeof(char)*(strlen(tmpName)+6));
-        sprintf( texName, "%s.rgba", tmpName );
-        } else {
-        texName = (char *)malloc(sizeof(char)*(strlen(tmpName)+5));
-        sprintf( texName, "%s.rgb", tmpName );
-        }
-
-    fileNameExt = (char *)malloc(sizeof(char)*(strlen(fileName)+5));
-    sprintf( fileNameExt, "%s.pic", fileName );
-
-    if ( verbose >= 1 )
-        fprintf( outStream, "Looking for texture file: '%s'\n", fileNameExt );
-
-    // try to make conversion of file
-    int found_file = ( access( fileNameExt, F_OK ) == 0);
-
-    if ( found_file )
-    {
-        if ( tex_path )
-        {
-            texNamePath = (char *)malloc(sizeof(char)*(strlen(tex_path) +
-                strlen(texName) + 2));
-
-            sprintf( texNamePath, "%s/%s", tex_path, texName );
-
-            if ( texFile )
-                texFile << texNamePath << ": " << fileNameExt << "\n";
-
-            // make sure conversion doesn't already exist
-            if ( (access( texNamePath, F_OK ) != 0)  && !texFile )
-            {
-                char *command = (char *)malloc(sizeof(char)*
-                    (strlen(fileNameExt) + strlen(texNamePath) + 20));
-
-                sprintf( command, "image-resize -1 %s %s",
-                    fileNameExt, texNamePath );
-
-                if ( verbose >=1 )
-                    fprintf( outStream, "executing %s\n", command );
-
-                system( command );
-
-                // free( command );
-            }
-            else
-                if ( verbose >=1 )
-                    fprintf( outStream, "%s already exists!\n", texNamePath );
-        }
-        else
-        {
-            if ( verbose >= 1 )
-            {
-                fprintf( outStream, "Warning: No texture path defined" );
-                fprintf( outStream, " - No automatic conversion performed\n" );
-            }
-        }
-    }
-    else
-    {
-        fprintf( outStream, "Warning: Couldn't find texture file: %s\n",
-            fileNameExt );
-    }
-
-    // free( fileNameExt );
-
-    if (tex_path)
-        return( texNamePath );
-    else
-        return( texName );
-  }
-  else
-  {
-    fprintf( outStream, "Warning: ConvertTexture received NULL fileName\n" );
-    return( NULL );
-  }
-}
-
-/**
- * Given an egg vertex pool, map each vertex therein to a vertex within an
- * array of SAA model vertices of size numVert.  Mapping is done by closest
- * proximity.
- */
-int *soft2egg::
-FindClosestTriVert( EggVertexPool *vpool, SAA_DVector *vertices, int numVert )
-{
-    int    *vertMap = NULL;
-    int     vpoolSize = vpool->NumVertices();
-    int     i,j;
-    float   thisDist;
-    float   closestDist;
-    int     closest;
-
-
-    vertMap = (int *)malloc(sizeof(int)*vpoolSize);
-
-    // for each vertex in vpool
-    for ( i = 0; i < vpoolSize; i++ )
-    {
-        // find closest model vertex
-        for ( j = 0; j < numVert-1; j++ )
-        {
-            // calculate distance
-            thisDist =    sqrtf(
-                powf( vpool->Vertex(i)->position[0] - vertices[j].x , 2 ) +
-                powf( vpool->Vertex(i)->position[1] - vertices[j].y , 2 ) +
-                powf( vpool->Vertex(i)->position[2] - vertices[j].z , 2 ) );
-
-            // remember this if its the closest so far
-            if ( !j || ( thisDist < closestDist ) )
-            {
-                closest = j;
-                closestDist = thisDist;
-            }
-        }
-        vertMap[i] = closest;
-
-        if ( verbose >= 2 )
-        {
-            fprintf( outStream, "mapping v %d of %d:( %f, %f, %f )\n", i,
-                vpoolSize, vpool->Vertex(i)->position[0],
-                vpool->Vertex(i)->position[1],
-                vpool->Vertex(i)->position[2] );
-            fprintf( outStream, "to cv %d of %d:( %f, %f, %f )\tdelta = %f\n",
-                closest, numVert-1, vertices[closest].x, vertices[closest].y,
-                vertices[closest].z, closestDist );
-        }
-                }
-
-        return( vertMap );
-}
-
-
-/**
- * Given an array of indices that is a map from one set of vertices to
- * another, return an array that performs the reverse mapping of the indices
- * array
- */
-int *soft2egg::
-MakeIndexMap( int *indices, int numIndices, int mapSize )
-{
-    int i, j;
-
-    // allocate map array
-    int *map = (int *)malloc(sizeof(int)*mapSize);
-
-    if ( map != NULL )
-    {
-        for ( i = 0; i < mapSize; i++ )
-        {
-            j = 0;
-            int found = 0;
-            while( j < numIndices )
-            {
-                if ( indices[j] == i )
-                {
-                    map[i] = j;
-                    if ( verbose >= 2 )
-                        fprintf( outStream, "map[%d] = %d\n", i, map[i] );
-                    found = 1;
-                    break;
-                }
-                j++;
-            }
-            if ( !found)
-            {
-                if ( verbose >= 2 )
-                    fprintf( outStream, "Warning: orphan vertex (%d)\n", i );
-                // default to -1 for now
-                map[i] = -1;
-            }
-        }
-    }
-    else
-        fprintf( outStream, "Not enough Memory for index Map...\n");
-
-    return( map );
-}
-
-/**
- * given a vertex, find its corresponding shape vertex and return its index.
- */
-int     soft2egg::
-findShapeVert( SAA_DVector vertex, SAA_DVector *vertices, int numVert )
-{
-    int i;
-    int found = 0;
-
-    for ( i = 0; i < numVert && !found ; i++ )
-    {
-        if ( ( vertex.x == vertices[i].x ) &&
-             ( vertex.y == vertices[i].y ) &&
-             ( vertex.z == vertices[i].z ) )
-        {
-            found = 1;
-
-            if ( verbose >= 2)
-                fprintf( outStream, "found shape vert at index %d\n", i );
-        }
-    }
-
-    if (!found )
-        i = -1;
-    else
-        i--;
-
-    return( i );
-}
-
-
-/**
- * Open the SI database and grab the scene & model info
- */
-void soft2egg::
-LoadSoft()
-{
-    int      i;
-
-    if ( (scene_name == NULL && model_name == NULL) || database_name == NULL )
-    {
-        Usage();
-        exit( 1 );
-    }
-
-    if ((result = SAA_Init(rsrc_path, FALSE)) != SI_SUCCESS)
-    {
-        fprintf( outStream, "Error: Couldn't get resource path!\n");
-        exit( 1 );
-    }
-
-    if ((result = SAA_databaseLoad(database_name, &database)) != SI_SUCCESS)
-    {
-        fprintf( outStream, "Error: Couldn't load database!\n");
-        exit( 1 );
-    }
-
-    if ((result = SAA_sceneGetCurrent(&scene)) == SI_SUCCESS)
-    {
-        // load scene if present
-        if ( scene_name != NULL )
-        {
-            SAA_sceneLoad( &database, scene_name, &scene );
-
-            // if no egg filename specified, make up a name
-            if ( eggFileName == NULL )
-            {
-                eggFileName = (char *)malloc(sizeof(char)*
-                    (strlen( scene_name ) + 14 ));
-                sprintf( eggFileName, "%s", DepointellizeName(scene_name) );
-                if ( make_nurbs )
-                    strcat( eggFileName, "-nurb" );
-                strcat( eggFileName, "-mod.egg" );
-            }
-
-            // open an output file for the geometry if necessary
-            if ( make_poly || make_nurbs )
-            {
-                unlink( eggFileName );
-                eggFile.open( eggFileName, ios::out, 0666 );
-
-                if ( !eggFile )
-                {
-                    fprintf( outStream, "Couldn't open output file: %s\n",
-                        eggFileName );
-                    exit( 1 );
-                }
-            }
-
-            // open an output file for texture list if specified
-            if ( tex_filename != NULL )
-            {
-                unlink( tex_filename );
-                texFile.open( tex_filename, ios::out, 0666 );
-
-                if ( !texFile )
-                {
-                    fprintf( outStream, "Couldn't open output file: %s\n",
-                        tex_filename );
-                    exit( 1 );
-                }
-            }
-
-            if ( SAA_updatelistGet( &scene ) == SI_SUCCESS )
-            {
-                float time;
-
-                fprintf( outStream, "setting Scene to frame %d...\n", pose_frame );
-                // SAA_sceneSetPlayCtrlCurrentFrame( &scene, pose_frame );
-                SAA_frame2Seconds( &scene, pose_frame, &time );
-                SAA_updatelistEvalScene( &scene, time );
-                sginap( 100 );
-                SAA_updatelistEvalScene( &scene, time );
-                if ( make_pose )
-                    SAA_sceneFreeze( &scene );
-            }
-
-            int            numModels;
-            SAA_Elem    *models;
-
-            SAA_sceneGetNbModels( &scene, &numModels );
-            fprintf( outStream, "Scene has %d model(s)...\n", numModels );
-
-            if ( numModels )
-            {
-                // allocate array of models
-                models = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numModels);
-
-                if ( models != NULL )
-                {
-                    char *rootName = GetRootName( eggFileName );
-
-                    if ( eggGroupName == NULL )
-                        dart = _data.CreateGroup( NULL, rootName );
-                    else
-                        dart = _data.CreateGroup( NULL, eggGroupName );
-
-                    if (make_dart)
-                      dart->flags |= EF_DART;
-
-                    AnimGroup    *rootTable;
-
-                    rootTable = animData.CreateTable( NULL, eggFileName );
-
-                    if ( eggGroupName == NULL )
-                        animRoot = animData.CreateBundle( rootTable, rootName );
-                    else
-                        animRoot = animData.CreateBundle( rootTable,
-                            eggGroupName );
-
-                    // propagate commet to anim data
-                    animData.root_group.children.push_front(
-                        new EggComment( _commandLine ) );
-
-                    if ( verbose >= 1 )
-                        fprintf( outStream, "made animRoot: %s\n", rootName );
-
-                    SAA_sceneGetModels( &scene, numModels, models );
-
-                    for ( i = 0; i < numModels; i++ )
-                    {
-                        int level;
-
-                        SAA_elementGetHierarchyLevel( &scene, &models[i], &level );
-                        if ( !level )
-                        {
-                            if ( verbose >= 1 )
-                                fprintf( outStream,
-                                    "\negging scene model[%d]\n", i );
-
-                            MakeEgg( dart, NULL, NULL,  &scene, &models[i] );
-                        }
-                    }
-
-            if ( make_poly || make_nurbs )
-            {
-                // generate soft skinning assignments if desired disabled 1199
-                // to streamline joint assignments.  all joint assignments now
-                // done here.  Hard & Soft.  if ( make_soft)
-                {
-                    char        *name;
-                    char        *fullname;
-                    SAA_Boolean isSkeleton;
-
-                    // search through models and look for skeleton parts
-                    for ( i = 0; i < numModels; i++ )
-                    {
-                        SAA_modelIsSkeleton( &scene, &models[i], &isSkeleton );
-
-                        // get fullname for splitting files, but only use it
-                        // in file if requested
-                        fullname = GetFullName( &scene, &models[i] );
-                        if ( use_prefix )
-                            name = fullname;
-                        else
-                            name = GetName( &scene, &models[i] );
-
-                        // split
-                        if ( strstr( fullname, search_prefix ) != NULL )
-                        {
-                            // for every skel part: get soft skin info
-                            if ( isSkeleton )
-                                MakeSoftSkin( &scene, &models[i], models,
-                                    numModels, name );
-                        }
-
-                        // free( name );
-                    }
-
-                    // make sure all vertices were assigned via soft skinning
-                    // - if not hard assign them
-                    for ( i = 0; i < numModels; i++ )
-                    {
-                        // get fullname for splitting files, but only use it
-                        // in file if requested
-                        fullname = GetFullName( &scene, &models[i] );
-                        if ( use_prefix )
-                            name = fullname;
-                        else
-                            name = GetName( &scene, &models[i] );
-
-                        // split
-                        if ( strstr( fullname, search_prefix ) != NULL )
-                            CleanUpSoftSkin( &scene, &models[i], name );
-
-                        // free( name );
-                    }
-
-                }
-
-
-                // put the skeleton data into the egg data
-                dart->StealChildren( *skeleton );
-
-                // make sure all elements have unique names
-                _data.UniquifyNames();
-
-                // write out the geometry data if requested if ( make_poly ||
-                // make_nurbs ) {
-                    eggFile << _data << "\n";
-                    fprintf( outStream, "\nwriting out %s...\n", eggFileName );
-                    eggFile.close();
-                }
-
-                // close texture list file if opened
-                if ( texFile )
-                    texFile.close();
-
-                // generate animation data if desired
-                if ( make_anim )
-                {
-                if ( animFileName == NULL )
-                {
-                    animFileName = (char *)malloc(sizeof(char)*
-                        (strlen(scene_name)+ 10 ));
-                    sprintf( animFileName, "%s", DepointellizeName(scene_name) );
-                    strcat( animFileName, "-chan.egg" );
-                }
-
-                unlink( animFileName );
-                animFile.open( animFileName, ios::out, 0666 );
-
-                if ( !animFile )
-                {
-                    fprintf( outStream, "Couldn't open output file: %s\n",
-                        animFileName );
-                    exit( 1 );
-                }
-
-                int frame;
-                // int frameStep;
-                float time;
-
-                // get all the animation frame info if not specified on the
-                // command line
-                if (anim_start == -1000)
-                    SAA_sceneGetPlayCtrlStartFrame( &scene, &anim_start );
-
-                if (anim_end == -1000)
-                    SAA_sceneGetPlayCtrlEndFrame( &scene, &anim_end );
-
-                // SAA_sceneGetPlayCtrlFrameStep( &scene, &frameStep );
-
-                fprintf( outStream, "\nframeStart = %d\n", anim_start );
-                fprintf( outStream, "frameEnd = %d\n", anim_end );
-                // fprintf( outStream, "frameStep = %d\n", frameStep );
-
-                // start at first frame and go to last
-                for ( frame = anim_start; frame <= anim_end;
-                        frame += 1)
-                {
-                    SAA_frame2Seconds( &scene, frame, &time );
-                    SAA_updatelistEvalScene( &scene, time );
-                    sginap( 100 );
-                    SAA_updatelistEvalScene( &scene, time );
-                    fprintf( outStream, "\n> animating frame %d\n", frame );
-
-                    // for each model
-                    for ( i = 0; i < numModels; i++ )
-                    {
-                        char           *name;
-                        char           *fullname;
-                        SAA_Boolean     isSkeleton;
-                        SAA_ModelType     type;
-
-                        SAA_modelIsSkeleton( &scene, &models[i], &isSkeleton );
-
-                        // get fullname for splitting files, but only use it
-                        // in file if requested
-                        fullname = GetFullName( &scene, &models[i] );
-                        if ( use_prefix )
-                            name = fullname;
-                        else
-                            name = GetName( &scene, &models[i] );
-
-                        // split
-                        if ( strstr( fullname, search_prefix ) != NULL )
-                        {
-                            // make the morph table for this critter
-                            if ( make_morph )
-                            {
-                                MakeMorphTable( &scene, &models[i], models,
-                                    numModels, name, time );
-                            }
-                        }
-
-                        // find out what type of node we're dealing with
-                        result = SAA_modelGetType( &scene, &models[i], &type );
-
-                        int size;
-
-                        // check for uv texture animation
-                        SAA_elementGetUserDataSize( &scene, &models[i],
-                            "TEX_OFFSETS", &size );
-
-                        // if so, update for this frame if desired
-                        if ( ( size != 0 ) && make_duv )
-                            MakeTexAnim( &scene, &models[i], name );
-
-                        // if we have a skeleton or something that acts like
-                        // one - build anim tables
-                        if ( isSkeleton  ||
-                            ( strstr( name, "joint") != NULL ) )
-                                MakeAnimTable( &scene, &models[i], name );
-
-                        // free( name );
-                    }
-
-                    if ( verbose >= 1 )
-                        fprintf( outStream, "\n" );
-                }
-
-                animFile << animData << "\n";
-                fprintf( outStream, "\nwriting out %s...\n", animFileName );
-                animFile.close();
-                }
-
-                // free( models );
-
-                }
-                else
-                    fprintf( outStream, "Error: Not enough Memory for models...\n");
-            }
-        }
-        // otherwise try to load a model
-        else if ( model_name != NULL )
-        {
-
-            if ( eggFileName == NULL )
-            {
-                eggFileName =
-                    (char *)malloc(sizeof(char)*(strlen( model_name )+13));
-                sprintf( eggFileName, "%s", DepointellizeName( model_name ) );
-
-                if ( make_nurbs )
-                    strcat( eggFileName, "-nurb" );
-                strcat( eggFileName, "-mod.egg" );
-            }
-
-            eggFile.open( eggFileName );
-
-            if ( !eggFile )
-            {
-                fprintf( outStream, "Couldn't open output file: %s\n",
-                    eggFileName );
-                exit( 1 );
-            }
-
-            if ((result =
-                SAA_elementLoad(&database, &scene, model_name, &model))
-                == SI_SUCCESS)
-            {
-                fprintf( outStream, "Loading single model...\n");
-                MakeEgg( NULL, NULL, NULL,  &scene, &model );
-            }
-
-            eggFile << _data << "\n";
-        }
-    }
-
-}
-
-/**
- * Make egg geometry from a given model.  This include textures, tex coords,
- * colors, normals, and joints.
- */
-void soft2egg::
-MakeEgg( EggGroup *parent, EggJoint *lastJoint, AnimGroup *lastAnim,
-            SAA_Scene *scene, SAA_Elem *model )
-{
-    char        *name;
-    char        *fullname;
-    SAA_ModelType type;
-    int         id = 0;
-    int         numShapes;
-    int         numTri;
-    int         numVert;
-    int         numTexLoc = 0;
-    int         numTexGlb = 0;
-    int         i, j;
-    float        matrix[4][4];
-    float        *uScale = NULL;
-    float        *vScale = NULL;
-    float        *uOffset = NULL;
-    float        *vOffset = NULL;
-    SAA_Boolean    uv_swap = FALSE;
-    void        *relinfo;
-    SAA_SubElem *triangles = NULL;
-    SAA_Elem    *materials = NULL;
-    SAA_SubElem *cvertices = NULL;
-    SAA_DVector *cvertPos = NULL;
-    SAA_DVector *vertices = NULL;
-    SAA_DVector *normals = NULL;
-    int            *indices = NULL;
-    int            *indexMap = NULL;
-    int            *numTexTri = NULL;
-    SAA_Elem    *textures = NULL;
-    char        **texNameArray;
-    float        *uCoords = NULL;
-    float        *vCoords = NULL;
-    SAA_GeomType gtype = SAA_GEOM_ORIGINAL;
-    SAA_Boolean    visible;
-
-    // find out what type of node we're dealing with
-    result = SAA_modelGetType( scene, model, &type );
-
-    if ( verbose >= 1 )
-    {
-        if ( type == SAA_MNILL )
-            fprintf( outStream, "encountered null\n");
-        else if ( type == SAA_MPTCH )
-            fprintf( outStream, "encountered patch\n" );
-        else if ( type == SAA_MFACE )
-            fprintf( outStream, "encountered face\n" );
-        else if ( type == SAA_MSMSH )
-            fprintf( outStream, "encountered mesh\n" );
-        else if ( type == SAA_MJNT )
-            fprintf( outStream, "encountered joint\n" );
-        else if ( type == SAA_MSPLN )
-            fprintf( outStream, "encountered spline\n" );
-        else if ( type == SAA_MMETA )
-            fprintf( outStream, "encountered meta element\n" );
-        else if ( type == SAA_MBALL )
-            fprintf( outStream, "encountered metaball\n" );
-        else if ( type == SAA_MNCRV )
-            fprintf( outStream, "encountered nurb curve\n" );
-        else if ( type == SAA_MNSRF )
-            fprintf( outStream, "encountered nurbs surf\n" );
-        else
-            fprintf( outStream, "encountered unknown type: %d\n", type );
-    }
-
-    // Get the name of the model
-
-    // Get the FULL name of the model
-    fullname = GetFullName( scene, model );
-
-    if ( use_prefix )
-    {
-        // Get the FULL name of the trim curve
-        name = fullname;
-    }
-    else
-    {
-        // Get the name of the trim curve
-        name = GetName( scene, model );
-    }
-
-    if ( verbose >= 1 )
-        fprintf( outStream, "element name <%s>\n", name );
-
-    fflush( outStream );
-
-    // get the model's matrix
-    SAA_modelGetMatrix( scene, model, SAA_COORDSYS_GLOBAL,  matrix );
-
-    if ( verbose >= 2 )
-    {
-        fprintf( outStream, "model matrix = %f %f %f %f\n", matrix[0][0],
-             matrix[0][1],  matrix[0][2],  matrix[0][3] );
-        fprintf( outStream, "model matrix = %f %f %f %f\n", matrix[1][0],
-             matrix[1][1],  matrix[1][2],  matrix[1][3] );
-        fprintf( outStream, "model matrix = %f %f %f %f\n", matrix[2][0],
-             matrix[2][1],  matrix[2][2],  matrix[2][3] );
-        fprintf( outStream, "model matrix = %f %f %f %f\n", matrix[3][0],
-             matrix[3][1],  matrix[3][2],  matrix[3][3] );
-    }
-
-    // check to see if this is a branch we don't want to descend - this will
-    // prevent creating geometry for animation control structures
-    if ( (strstr( name, "con-" ) == NULL) &&
-         (strstr( name, "con_" ) == NULL) &&
-         (strstr( name, "fly_" ) == NULL) &&
-         (strstr( name, "fly-" ) == NULL) &&
-         (strstr( name, "camRIG" ) == NULL) &&
-         (strstr( name, "bars" ) == NULL) &&
-         // split
-         (strstr( fullname, search_prefix ) != NULL) )
-    {
-
-    // if making a pose - get deformed geometry
-    if ( make_pose )
-        gtype = SAA_GEOM_DEFORMED;
-
-    // Get the number of key shapes
-    SAA_modelGetNbShapes( scene, model, &numShapes );
-    if ( verbose >= 1 )
-        fprintf( outStream, "MakeEgg: num shapes: %d\n", numShapes);
-
-    // if multiple key shapes exist create table entries for each
-    if ( (numShapes > 0) && make_morph )
-    {
-        has_morph = 1;
-
-        // make sure root morph table exists
-        if ( morphRoot == NULL )
-            morphRoot = animData.CreateTable( animRoot, "morph" );
-
-        char   *tableName;
-
-        // create morph table entry for each key shape (start at second shape
-        // - as first is the original geometry)
-        for ( i = 1; i < numShapes; i++ )
-        {
-            tableName = MakeTableName( name, i );
-            SAnimTable *table = new SAnimTable( );
-            table->name = tableName;
-            table->fps = anim_rate;
-            morphRoot->children.push_back( table );
-            if ( verbose >= 1 )
-                fprintf( outStream, "created table named: '%s'\n", tableName );
-        }
-
-        // free( tableName );
-    }
-
-    SAA_modelGetNodeVisibility( scene, model, &visible );
-    if ( verbose >= 1 )
-        fprintf( outStream, "model visibility: %d\n", visible );
-
-    // Only create egg polygon data if: the node is visible, and its not a
-    // NULL or a Joint, and we're outputing polys (or if we are outputing
-    // NURBS and the model is a poly mesh or a face)
-    if ( visible &&
-         (type != SAA_MNILL) &&
-         (type != SAA_MJNT) &&
-         ((make_poly ||
-         (make_nurbs && ((type == SAA_MSMSH) || (type == SAA_MFACE )) ))
-         || (!make_poly && !make_nurbs && make_duv &&
-            ((type == SAA_MSMSH) || (type == SAA_MFACE )) ))
-       )
-    {
-      // If the model is a NURBS in soft, set its step before tesselating
-      if ( type == SAA_MNSRF )
-        SAA_nurbsSurfaceSetStep( scene, model, nurbs_step, nurbs_step );
-
-      // If the model is a PATCH in soft, set its step before tesselating
-      else if ( type == SAA_MPTCH )
-        SAA_patchSetStep( scene, model, nurbs_step, nurbs_step );
-
-      // Get the number of triangles
-      result = SAA_modelGetNbTriangles( scene, model, gtype, id, &numTri);
-      if ( verbose >= 1 )
-          fprintf( outStream, "triangles: %d\n", numTri);
-
-      if ( result != SI_SUCCESS )
-      {
-        if ( verbose >= 1 ) {
-            fprintf( outStream,
-            "Error: couldn't get number of triangles!\n" );
-            fprintf( outStream, "\tbailing on model: '%s'\n", name );
-        }
-        return;
-      }
-
-      // check to see if surface is also skeleton...
-      SAA_Boolean isSkeleton = FALSE;
-
-      SAA_modelIsSkeleton( scene, model, &isSkeleton );
-
-      // check to see if this surface is used as a skeleton or is animated via
-      // constraint only ( these nodes are tagged by the animator with the
-      // keyword "joint" somewhere in the nodes name)
-      if ( isSkeleton || (strstr( name, "joint" ) != NULL) )
-      {
-          if ( verbose >= 1 )
-              fprintf( outStream, "animating Polys as joint!!!\n" );
-
-            MakeJoint( scene, lastJoint, lastAnim, model, name );
-      }
-
-      // model is not a null and has no triangles!
-      if ( !numTri )
-      {
-        if ( verbose >= 1 )
-            fprintf( outStream, "no triangles!\n");
-      }
-      else
-      {
-        // allocate array of triangles
-        triangles = (SAA_SubElem *)malloc(sizeof(SAA_SubElem)*numTri);
-        if ( triangles != NULL )
-        {
-            // triangulate model and read the triangles into array
-            SAA_modelGetTriangles( scene, model, gtype, id, numTri, triangles );
-        }
-        else
-            fprintf( outStream, "Not enough Memory for triangles...\n");
-
-        // allocate array of materials
-        materials = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numTri);
-        if ( materials != NULL )
-        {
-            // read each triangle's material into array
-            SAA_triangleGetMaterials( scene, model, numTri, triangles,
-                materials );
-        }
-        else
-            fprintf( outStream, "Not enough Memory for materials...\n");
-
-        // allocate array of textures per triangle
-        numTexTri = (int *)malloc(sizeof(int)*numTri);
-
-        // find out how many local textures per triangle
-        for ( i = 0; i < numTri; i++ )
-        {
-            result = SAA_materialRelationGetT2DLocNbElements( scene,
-                                                        &materials[i], FALSE, &relinfo, &numTexTri[i] );
-
-            // polytex
-            if ( result == SI_SUCCESS )
-                numTexLoc += numTexTri[i];
-        }
-
-        // don't need this anymore... free( numTexTri );
-
-        // get local textures if present
-        if ( numTexLoc )
-        {
-            // ASSUME only one texture per material
-            textures = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numTri);
-
-            for ( i = 0; i < numTri; i++ )
-            {
-                // and read all referenced local textures into array
-                SAA_materialRelationGetT2DLocElements( scene, &materials[i],
-                    TEX_PER_MAT , &textures[i] );
-            }
-
-            if ( verbose >= 1 )
-                fprintf( outStream, "numTexLoc = %d\n", numTexLoc);
-        }
-        // if no local textures, try to get global textures
-        else
-        {
-            SAA_modelRelationGetT2DGlbNbElements( scene, model,
-                FALSE, &relinfo, &numTexGlb );
-
-            if ( numTexGlb )
-            {
-                // ASSUME only one texture per model
-                textures = (SAA_Elem *)malloc(sizeof(SAA_Elem));
-
-                // get the referenced texture
-                SAA_modelRelationGetT2DGlbElements( scene, model,
-                    TEX_PER_MAT, textures );
-
-                if ( verbose >= 1 )
-                    fprintf( outStream, "numTexGlb = %d\n", numTexGlb);
-            }
-        }
-
-        // allocate array of control vertices
-        cvertices = (SAA_SubElem *)malloc(sizeof(SAA_SubElem)*numTri*3);
-        if ( cvertices != NULL )
-        {
-            // read each triangle's control vertices into array
-            SAA_triangleGetCtrlVertices( scene, model, gtype, id,
-                numTri, triangles, cvertices );
-
-            if ( verbose >= 2 )
-            {
-                cvertPos = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numTri*3);
-                SAA_ctrlVertexGetPositions(  scene, model, numTri*3,
-                    cvertices, cvertPos);
-
-                for ( i=0; i < numTri*3; i++ )
-                {
-                    fprintf( outStream, "cvert[%d] = %f %f %f %f\n", i,
-                        cvertPos[i].x, cvertPos[i].y, cvertPos[i].z,
-                        cvertPos[i].w );
-                }
-            }
-        }
-        else
-            fprintf( outStream, "Not enough Memory for control vertices...\n");
-
-        // allocate array of control vertex indices this array maps from the
-        // redundant cvertices array into the unique vertices array
-        // (cvertices->vertices)
-        indices = (int *)malloc(sizeof(int)*numTri*3);
-        if ( indices != NULL )
-        {
-            for ( i=0; i < numTri*3; i++ )
-                indices[i] = 0;
-
-            SAA_ctrlVertexGetIndices( scene, model, numTri*3,
-                cvertices, indices );
-
-            if ( verbose >= 2 )
-                for ( i=0; i < numTri*3; i++ )
-                    fprintf( outStream, "indices[%d] = %d\n", i, indices[i] );
-        }
-        else
-            fprintf( outStream, "Not enough Memory for indices...\n");
-
-        // get number of UNIQUE vertices in model
-        SAA_modelGetNbTriVertices( scene, model, &numVert );
-
-        if ( verbose >= 2 )
-            fprintf( outStream, "num unique verts = %d\n", numVert );
-
-        // allocate array of vertices
-        vertices = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numVert);
-
-        // get the UNIQUE vertices of all triangles in model
-        SAA_modelGetTriVertices( scene, model, numVert, vertices );
-
-        if ( verbose >= 2 )
-        {
-            for ( i=0; i < numVert; i++ )
-            {
-                fprintf( outStream, "vertices[%d] = %f ", i, vertices[i].x );
-                fprintf( outStream, "%f %f %f\n", vertices[i].y,
-                vertices[i].z, vertices[i].w );
-            }
-        }
-
-        // allocate indexMap array we contruct this array to map from the
-        // unique vertices array to the redundant cvertices array - it will
-        // save us from doing repetitive searches later
-        indexMap = MakeIndexMap( indices, numTri*3, numVert );
-
-        // allocate array of normals
-        normals = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numTri*3);
-        if ( normals != NULL )
-        {
-            // read each control vertex's normals into an array
-            SAA_ctrlVertexGetNormals( scene, model, numTri*3,
-                cvertices, normals );
-        }
-        else
-            fprintf( outStream, "Not enough Memory for normals...\n");
-
-        if ( verbose >= 2 )
-        {
-            for ( i=0; i<numTri*3; i++ )
-                fprintf( outStream, "normals[%d] = %f %f %f %f\n", i,
-                    normals[i].x, normals[i].y, normals[i].z, normals[i].w );
-        }
-
-        int uRepeat, vRepeat;
-
-        // make sure we have textures before we get t-coords
-        if ( numTexLoc )
-        {
-            // allocate arrays for u & v coords
-            uCoords = (float *)malloc(sizeof(float)*numTri*numTexLoc*3);
-            vCoords = (float *)malloc(sizeof(float)*numTri*numTexLoc*3);
-
-            // read the u & v coords into the arrays
-            if ( uCoords != NULL && vCoords != NULL)
-            {
-              for ( i = 0; i < numTri*numTexLoc*3; i++ )
-                uCoords[i] = vCoords[i] = 0.0f;
-
-                SAA_ctrlVertexGetUVTxtCoords( scene, model, numTri*3,
-                    cvertices, numTexLoc*3, uCoords, vCoords );
-            }
-            else
-                fprintf( outStream, "Not enough Memory for texture coords...\n");
-
-            if ( verbose >= 2 )
-            {
-                for ( i=0; i<numTexLoc*3; i++ )
-                    fprintf( outStream, "texcoords[%d] = ( %f , %f )\n", i,
-                        uCoords[i], vCoords[i] );
-            }
-
-            // allocate arrays of texture info
-            uScale = ( float *)malloc(sizeof(float)*numTri);
-            vScale = ( float *)malloc(sizeof(float)*numTri);
-            uOffset = ( float *)malloc(sizeof(float)*numTri);
-            vOffset = ( float *)malloc(sizeof(float)*numTri);
-            texNameArray = ( char **)malloc(sizeof(char *)*numTri);
-
-            for ( i = 0; i < numTri; i++ )
-            {
-                // initialize the array value
-                texNameArray[i] = NULL;
-
-                SAA_Boolean    valid = FALSE;
-                // check to see if texture is present
-                result = SAA_elementIsValid( scene, &textures[i], &valid );
-
-                if ( result != SI_SUCCESS )
-                    fprintf( outStream, "SAA_elementIsValid failed!!!!\n" );
-
-                // texture present - get the name and uv info
-                if ( valid )
-                {
-                    texNameArray[i] = ConvertTexture( scene, &textures[i] );
-
-                    if ( verbose >= 2 )
-                        fprintf( outStream, " tritex[%d] named: %s\n", i,
-                            texNameArray[i] );
-
-                    SAA_texture2DGetUVSwap( scene, &textures[i], &uv_swap );
-
-                    if ( verbose >= 2 )
-                        if ( uv_swap == TRUE )
-                            fprintf( outStream, " 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] );
-
-                    if ( verbose >= 2 )
-                    {
-                        fprintf(outStream, "tritex[%d] uScale: %f vScale: %f\n",                             i, uScale[i], vScale[i] );
-                        fprintf(outStream, " uOffset: %f vOffset: %f\n",
-                            uOffset[i], vOffset[i] );
-                    }
-
-
-                    SAA_texture2DGetRepeats(  scene, &textures[i], &uRepeat,
-                        &vRepeat );
-
-                    if ( verbose >= 2 )
-                    {
-                        fprintf(outStream, "uRepeat = %d, vRepeat = %d\n",
-                            uRepeat, vRepeat );
-                    }
-                }
-                else
-                {
-                    if ( verbose >= 2 )
-                    {
-                        fprintf( outStream, "Invalid texture...\n");
-                        fprintf( outStream, " tritex[%d] named: (null)\n", i );
-                    }
-                }
-            }
-
-/*
- * debug for ( i = 0; i < numTri; i++ ) { if ( texNameArray[i] != NULL )
- * fprintf( outStream, " tritex[%d] named: %s\n", i, texNameArray[i] ); else
- * fprintf( outStream, " tritex[%d] named: (null)\n", i ); }
- */
-        }
-        // make sure we have textures before we get t-coords
-        else if ( numTexGlb )
-        {
-            SAA_Boolean    valid;
-
-            // check to see if texture is present
-            SAA_elementIsValid( scene, textures, &valid );
-
-            // texture present - get the name and uv info
-            if ( valid )
-            {
-                SAA_texture2DGetUVSwap( scene, textures, &uv_swap );
-
-                if ( verbose >= 1 )
-                    if ( uv_swap == TRUE )
-                        fprintf( outStream, " swapping u and v...\n" );
-
-                // allocate arrays for u & v coords
-                uCoords = (float *)malloc(sizeof(float)*numTri*numTexGlb*3);
-                vCoords = (float *)malloc(sizeof(float)*numTri*numTexGlb*3);
-
-                for ( i = 0; i < numTri*numTexGlb*3; i++ )
-                {
-                    uCoords[i] = vCoords[i] = 0.0f;
-                }
-
-                // read the u & v coords into the arrays
-                if ( uCoords != NULL && vCoords != NULL)
-                {
-                    SAA_triCtrlVertexGetGlobalUVTxtCoords( scene, model,
-                        numTri*3, cvertices, numTexGlb, textures,
-                        uCoords, vCoords );
-                }
-                else
-                    fprintf( outStream, "Not enough Memory for texture coords...\n");
-
-                if ( verbose >= 2 )
-                  {
-                    for ( i=0; i<numTri*numTexGlb*3; i++ )
-                      fprintf( outStream, "texcoords[%d] = ( %f , %f )\n", i,
-                               uCoords[i], vCoords[i] );
-                  }
-
-                texNameArray = ( char **)malloc(sizeof(char *));
-                *texNameArray = ConvertTexture( scene, textures );
-
-                if ( verbose >= 1 )
-                    fprintf( outStream, " global tex named: %s\n",
-                        texNameArray );
-
-                // allocate arrays of texture info
-                uScale = ( float *)malloc(sizeof(float));
-                vScale = ( float *)malloc(sizeof(float));
-                uOffset = ( float *)malloc(sizeof(float));
-                vOffset = ( float *)malloc(sizeof(float));
-
-                SAA_texture2DGetUScale( scene, textures, uScale );
-                SAA_texture2DGetVScale( scene, textures, vScale );
-                SAA_texture2DGetUOffset( scene, textures, uOffset );
-                SAA_texture2DGetVOffset( scene, textures, vOffset );
-
-                if ( verbose >= 1 )
-                {
-                    fprintf( outStream, " global tex uScale: %f vScale: %f\n",
-                        *uScale, *vScale );
-                    fprintf( outStream, " uOffset: %f vOffset: %f\n",
-                        *uOffset, *vOffset );
-                }
-
-                SAA_texture2DGetRepeats(  scene, textures, &uRepeat,
-                    &vRepeat );
-
-                if ( verbose >= 2 )
-                {
-                    fprintf(outStream, "uRepeat = %d, vRepeat = %d\n",
-                        uRepeat, vRepeat );
-                }
-            }
-            else fprintf( outStream, "Invalid texture...\n");
-        }
-
-        // make the egg vertex pool
-        EggVertexPool *pool = _data.CreateVertexPool( parent, name );
-
-        for ( i = 0; i < numVert; i++ )
-        {
-            pfVec3    eggVert;
-            pfVec3    eggNorm;
-
-            // convert to global coords
-            SAA_DVector local = vertices[i];
-            SAA_DVector global;
-
-            _VCT_X_MAT( global, local, matrix );
-
-            // set vertices array to reflect global coords vertices[i].x =
-            // global.x; vertices[i].y = global.y; vertices[i].z = global.z;
-
-            // eggVert.set( vertices[i].x, vertices[i].y, vertices[i].z );
-
-            // we'll preserve original verts for now
-            eggVert.set( global.x, global.y, global.z );
-
-            local = normals[indexMap[i]];
-
-            _VCT_X_MAT( global, local, matrix );
-
-            eggNorm.set( global.x, global.y, global.z );
-            eggNorm.normalize();
-
-            pool->AddVertex( eggVert, i );
-            pool->Vertex(i)->attrib.SetNormal( eggNorm );
-
-            // translate local uv's to global and add to vertex pool
-            if ( numTexLoc && (uCoords != NULL && vCoords !=NULL ))
-            {
-                float u, v;
-
-                if ( ignore_tex_offsets ) {
-                  u = uCoords[indexMap[i]];
-                  v = 1.0f - vCoords[indexMap[i]];
-                } else {
-                  u = (uCoords[indexMap[i]] - uOffset[indexMap[i]/3]) /
-                    uScale[indexMap[i]/3];
-
-                  v = 1.0f - ((vCoords[indexMap[i]] - vOffset[indexMap[i]/3]) /
-                              vScale[indexMap[i]/3]);
-                }
-
-                if ( isNum(u) && isNum(v) )
-                {
-                    if ( uv_swap == TRUE )
-                        pool->Vertex(i)->attrib.SetUV( v, u );
-                    else
-                        pool->Vertex(i)->attrib.SetUV( u, v );
-                }
-            }
-            else if ( numTexGlb && (uCoords != NULL && vCoords !=NULL ) )
-            {
-                float u, v;
-
-                if ( ignore_tex_offsets ) {
-                  u = uCoords[indexMap[i]];
-                  v = 1.0f - vCoords[indexMap[i]];
-                } else {
-                  u = (uCoords[indexMap[i]] - *uOffset) / *uScale;
-                  v = 1.0f - (( vCoords[indexMap[i]] - *vOffset ) / *vScale);
-                }
-
-                if ( isNum(u) && isNum(v) )
-                {
-                    if ( uv_swap == TRUE )
-                        pool->Vertex(i)->attrib.SetUV( v, u );
-                    else
-                        pool->Vertex(i)->attrib.SetUV( u, v );
-                }
-            }
-
-            // if we've encountered textures and we desire duv anims
-            if (( numTexLoc || numTexGlb ) && make_duv )
-            {
-                int            numExp;
-                SAA_Elem   *tex;
-
-                // grab the current texture
-                if ( numTexLoc )
-                    tex = &textures[0];
-                else
-                    tex = textures;
-
-                // find how many expressions for this shape
-                SAA_elementGetNbExpressions( scene, tex, NULL, FALSE,
-                    &numExp );
-
-                // if it has expressions we'll assume its animated
-                if ( numExp )
-                {
-                    // if animated object make base duv's, animtables for the
-                    // duv's and store the original offsets
-                    strstream uName, vName;
-
-                    // create duv target names
-                    uName << name << ".u" << ends;
-                    vName << name << ".v" << ends;
-
-                    // only create tables and store offsets on a per model
-                    // basis (not per vertex)
-                    if ( !i )
-                    {
-
-                        // make sure root morph table exists
-                        if ( morphRoot == NULL )
-                            morphRoot = animData.CreateTable( animRoot,
-                                "morph" );
-
-                        // create morph table entry for each duv
-                        SAnimTable *uTable = new SAnimTable( );
-                        uTable->name = uName.str();
-                        uTable->fps = anim_rate;
-                        morphRoot->children.push_back( uTable );
-                        if ( verbose >= 1 )
-                            fprintf( outStream, "created duv table named: %s\n",                                uName.str() );
-
-                        SAnimTable *vTable = new SAnimTable( );
-                        vTable->name = vName.str();
-                        vTable->fps = anim_rate;
-                        morphRoot->children.push_back( vTable );
-                        if ( verbose >= 1 )
-                            fprintf( outStream, "created duv table named: %s\n",                                vName.str() );
-
-                        float    texOffsets[4];
-
-                        if ( numTexGlb )
-                        {
-                            texOffsets[0] = *uOffset;
-                            texOffsets[1] = *vOffset;
-                            texOffsets[2] = *uScale;
-                            texOffsets[3] = *vScale;
-                        }
-                        else
-                        {
-                            texOffsets[0] = uOffset[indexMap[i]/3];
-                            texOffsets[1] = vOffset[indexMap[i]/3];
-                            texOffsets[2] = uScale[indexMap[i]/3];
-                            texOffsets[3] = vScale[indexMap[i]/3];
-                        }
-
-                        // remember original texture offsets future reference
-                        SAA_elementSetUserData( scene, model, "TEX_OFFSETS",
-                            sizeof( texOffsets ), TRUE, (void  **)&texOffsets );
-                    }
-
-                    EggMorphOffset *duvU;
-                    EggMorphOffset *duvV;
-
-                    // generate base duv's for this vertex
-                    duvU = new EggMorphOffset( uName.str(), 1.0 , 0.0 );
-                    pool->Vertex(i)->attrib.uv_morphs.push_back( *duvU );
-
-                    duvV = new EggMorphOffset( vName.str(), 0.0 , 1.0 );
-                    pool->Vertex(i)->attrib.uv_morphs.push_back( *duvV );
-
-                } // if ( numExp )
-
-            } // if ( numTexLoc || numTexGlb )
-
-        } // for ( i = 0; i < numVert; i++ )
-
-        // if model has key shapes, generate vertex offsets
-        if ( has_morph && make_morph )
-            MakeVertexOffsets( scene, model, type, numShapes, numVert,
-                vertices, matrix,  name );
-
-
-        // create vertex ref list for all polygons in the model
-        EggVertexRef *vref;
-
-        vref = new EggVertexRef( pool);
-        for ( i = 0; i < numVert; i++ )
-        {
-            // add each vert in pool to last joint for hard skinning
-            vref->indices.push_back( EggVertexIndex( i ) );
-        }
-
-/*
- * hard assign poly geometry if no soft-skinning requested disabled 1199 to
- * streamline joint assignments.  all hard-skinning now done in
- * CleanUpSoftSkin.  if ( !make_soft ) { if ( lastJoint != NULL ) {
- * lastJoint->vrefs.AddUniqueNode( *vref );
- */
-
-                // if ( verbose >= 1 ) fprintf( outStream, "hard-skinning %s
-                // (%d vertices)\n", name, i+1 ); } }
-
-        // make an egg group to hold all triangles
-        EggGroup *group = _data.CreateGroup( parent, name);
-
-        // make this group the current parent
-        parent = group;
-
-        EggPolygon *poly = NULL;
-        EggColor *cref = NULL;
-        EggTexture *tref = NULL;
-
-        // for each triangle
-        for ( i = 0; i < numTri*3; i+=3 )
-        {
-            float    r,g,b,a;
-            pfVec4    color;
-
-            // make egg poly for each traingle and reference the appropriate
-            // vertex in the pool
-            poly = _data.CreatePolygon( group, pool );
-            poly->AddVertex(indices[i]);
-            poly->AddVertex(indices[i+1]);
-            poly->AddVertex(indices[i+2]);
-
-            // check for back face flag in model note info
-            char *modelNoteStr = GetModelNoteInfo( scene, model );
-
-            if ( modelNoteStr != NULL )
-            {
-                if ( strstr( modelNoteStr, "bface" ) != NULL )
-                    poly->flags |= EG_BFACE;
-            }
-
-            // check to see if material is present
-            SAA_Boolean    valid;
-            SAA_elementIsValid( scene, &materials[i/3], &valid );
-
-            // material present - get the color
-            if ( valid )
-            {
-                SAA_materialGetDiffuse( scene, &materials[i/3], &r, &g, &b );
-                SAA_materialGetTransparency( scene, &materials[i/3], &a );
-                color.set( r, g, b, 1.0f - a );
-            }
-            // no material - default to white
-            else
-                color.set( 1.0, 1.0, 1.0, 1.0 );
-
-            cref = _data.CreateColor(color);
-            poly->attrib.SetCRef(cref);
-
-            strstream uniqueTexName;
-
-            if (numTexLoc)
-            {
-                // polytex
-                if ( (texNameArray[i/3] != NULL) &&
-                        (strcmp(texNameArray[i/3], "NULL") != 0) )
-                {
-                    // append unique identifier to texname for this particular
-                    // object
-                    uniqueTexName << name << "-"
-                        << RemovePathName(texNameArray[i/3]);
-
-                    tref = _data.CreateTexture( texNameArray[i/3],
-                        uniqueTexName.str() );
-
-                    if ( verbose >= 1 )
-                        fprintf( outStream, " tritex[%d] named: %s\n", i/3,
-                            texNameArray[i/3] );
-                }
-            }
-            else if ( numTexGlb )
-            {
-                if ( texNameArray != NULL )
-                {
-                    // append unique identifier to texname for this particular
-                    // object
-                    uniqueTexName << name << "-"
-                        << RemovePathName(*texNameArray);
-
-                    tref = _data.CreateTexture( *texNameArray,
-                        uniqueTexName.str() );
-
-                    if ( verbose >= 1 )
-                        fprintf( outStream, " tritex named: %s\n",
-                             *texNameArray );
-                }
-            }
-
-            // set the clamp on the texture
-            if ( tref != NULL )
-            {
-                if ( uRepeat > 0 )
-                    tref->wrapu = EggTexture::WM_repeat;
-                else
-                    tref->wrapu = EggTexture::WM_clamp;
-
-                if ( vRepeat > 1 )
-                    tref->wrapv = EggTexture::WM_repeat;
-                else
-                    tref->wrapv = EggTexture::WM_clamp;
-
-                poly->attrib.SetTRef(tref);
-            }
-
-        }
-
-        // we're done - trash triangles...
-        SAA_modelClearTriangles( scene, model );
-
-/*
- * free molloc'd memory free( triangles ); free( materials ); free( normals );
- * free( cvertices ); free( vertices ); free( indices ); free( indexMap );
- */
-
-        // free these only if they were malloc'd for textures
-        if (numTexLoc || numTexGlb)
-        {
-/*
- * free( textures ); free( uCoords ); free( vCoords ); free( texNameArray );
- * free( uScale ); free( vScale ); free( uOffset ); free( vOffset );
- */
-        }
-      }
-    }
-    else
-    {
-        // check to see if its a nurbs surface
-        if ( (type == SAA_MNSRF) && ( visible ) && (( make_nurbs )
-            || ( !make_nurbs && !make_poly &&  make_duv )) )
-        {
-            // check to see if NURBS is also skeleton...
-            SAA_Boolean isSkeleton = FALSE;
-
-            SAA_modelIsSkeleton( scene, model, &isSkeleton );
-
-            // check to see if this NURBS is used as a skeleton or is animated
-            // via constraint only ( these nodes are tagged by the animator
-            // with the keyword "joint" somewhere in the nodes name)
-            if ( isSkeleton || (strstr( name, "joint" ) != NULL) )
-            {
-                MakeJoint( scene, lastJoint, lastAnim, model, name );
-                geom_as_joint = 1;
-                if ( verbose >= 1 )
-                    fprintf( outStream, "animating NURBS as joint!!!\n" );
-            }
-
-            EggNurbsSurface    *eggNurbsSurf = new EggNurbsSurface( name );
-            int uDegree, vDegree;
-
-            // create nurbs representation of surface
-            SAA_nurbsSurfaceGetDegree( scene, model, &uDegree, &vDegree );
-            eggNurbsSurf->u_order = uDegree + 1;
-            eggNurbsSurf->v_order = vDegree + 1;
-            if ( verbose >= 1 )
-            {
-                fprintf( outStream, "nurbs degree: %d u, %d v\n",
-                    uDegree, vDegree );
-                fprintf( outStream, "nurbs order: %d u, %d v\n",
-                    uDegree + 1, vDegree + 1 );
-            }
-
-            SAA_Boolean    uClosed = FALSE;
-            SAA_Boolean    vClosed = FALSE;
-
-            SAA_nurbsSurfaceGetClosed( scene, model, &uClosed, &vClosed);
-
-            if ( verbose >= 1 )
-            {
-                if ( uClosed )
-                    fprintf( outStream, "nurbs is closed in u...\n");
-                if ( vClosed )
-                    fprintf( outStream, "nurbs is closed in v...\n");
-            }
-
-            int uRows, vRows;
-            SAA_nurbsSurfaceGetNbVertices( scene, model, &uRows, &vRows );
-            if ( verbose >= 1 )
-                fprintf( outStream, "nurbs vertices: %d u, %d v\n",
-                    uRows, vRows );
-
-            int uCurves, vCurves;
-            SAA_nurbsSurfaceGetNbCurves( scene, model, &uCurves, &vCurves );
-            if ( verbose >= 1 )
-                fprintf( outStream, "nurbs curves: %d u, %d v\n",
-                    uCurves, vCurves );
-
-            if ( shift_textures )
-            {
-            if ( uClosed )
-                // shift starting point on NURBS surface for correct textures
-                SAA_nurbsSurfaceShiftParameterization( scene, model, -2, 0 );
-
-            if ( vClosed )
-                // shift starting point on NURBS surface for correct textures
-                SAA_nurbsSurfaceShiftParameterization( scene, model, 0, -2 );
-            }
-
-            SAA_nurbsSurfaceSetStep( scene, model, nurbs_step, nurbs_step );
-
-            // check for back face flag in model note info
-            char *modelNoteStr = GetModelNoteInfo( scene, model );
-
-            if ( modelNoteStr != NULL )
-            {
-                if ( strstr( modelNoteStr, "bface" ) != NULL )
-                    eggNurbsSurf->flags |= EG_BFACE;
-            }
-
-            int numKnotsU, numKnotsV;
-
-            SAA_nurbsSurfaceGetNbKnots( scene, model, &numKnotsU, &numKnotsV );
-            if ( verbose >= 1 )
-                fprintf( outStream, "nurbs knots: %d u, %d v\n",
-                    numKnotsU, numKnotsV );
-
-            double *knotsU, *knotsV;
-            knotsU = (double *)malloc(sizeof(double)*numKnotsU);
-            knotsV = (double *)malloc(sizeof(double)*numKnotsV);
-            SAA_nurbsSurfaceGetKnots( scene, model, gtype, 0,
-                numKnotsU, numKnotsV, knotsU, knotsV );
-
-            if ( verbose >= 2 )
-                fprintf( outStream, "u knots:\n" );
-
-            AddKnots( eggNurbsSurf->u_knots, knotsU, numKnotsU, uClosed, uDegree );
-            if ( verbose >= 2 )
-                fprintf( outStream, "v knots:\n" );
-
-            AddKnots( eggNurbsSurf->v_knots, knotsV, numKnotsV, vClosed, vDegree);
-
-            // free( knotsU ); free( knotsV );
-
-            // set sub_div so we can see it in perfly
-            eggNurbsSurf->u_subdiv = (uRows-1)*nurbs_step;
-            eggNurbsSurf->v_subdiv = (vRows-1)*nurbs_step;
-
-            SAA_modelGetNbVertices( scene, model, &numVert );
-
-            if ( verbose >= 2 )
-                fprintf( outStream, "%d CV's\n", numVert );
-
-            // get the CV's
-            vertices = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numVert);
-            SAA_modelGetVertices( scene, model, gtype, 0,
-                numVert, vertices );
-
-            // create pool of NURBS vertices
-            EggVertexPool *pool = _data.CreateVertexPool( parent, name );
-            eggNurbsSurf->SetVertexPool( pool );
-
-            // create vertex ref list for all cv's in the model
-            EggVertexRef *vref;
-
-            vref = new EggVertexRef( pool);
-
-            for ( int k = 0; k<numVert; k++ )
-            {
-                if ( verbose >= 2 )
-                {
-                    fprintf( outStream, "original cv[%d] = %f %f %f %f\n", k,
-                        vertices[k].x, vertices[k].y, vertices[k].z,
-                        vertices[k].w );
-                }
-
-                pfVec4  eggVert;
-
-                // convert to global coords
-                SAA_DVector global;
-
-                _VCT_X_MAT( global, vertices[k], 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;
-
-                // this code is commented out because I am no longer sending
-                // global data to the other routines (ie makevertexoffset)
-
-                // set vertices array to reflect global coords vertices[k].x =
-                // global.x; vertices[k].y = global.y; vertices[k].z =
-                // global.z; vertices[k].w = global.w;
-
-                // if ( verbose >= 2 ) { fprintf( outStream, "global cv[%d] =
-                // %f %f %f %f\n", k, vertices[k].x, vertices[k].y,
-                // vertices[k].z, vertices[k].w ); }
-
-                // eggVert.set( vertices[k].x, vertices[k].y, vertices[k].z,
-                // vertices[k].w );
-
-                if ( verbose >= 2 )
-                {
-                    fprintf( outStream, "global cv[%d] = %f %f %f %f\n", k,
-                        global.x, global.y, global.z,
-                        global.w );
-                }
-
-                eggVert.set( global.x, global.y, global.z,
-                    global.w );
-
-                // populate vertex pool
-                pool->AddVertex( eggVert, k );
-
-                // add vref's to NURBS info
-                eggNurbsSurf->AddVertex( k );
-
-                // add each vert in pool to vref for hard skinning
-                vref->indices.push_back( EggVertexIndex( k ) );
-
-                // check to see if the NURB is closed in u
-                if ( uClosed )
-                {
-                    // add first uDegree verts to end of row
-                    if ( (k % uRows) == ( uRows - 1) )
-                    for ( int i = 0; i < uDegree; i++ )
-                    {
-                        // add vref's to NURBS info
-                        eggNurbsSurf->AddVertex( i+((k/uRows)*uRows) );
-
-                        // add each vert to vref
-                        vref->indices.push_back(
-                            EggVertexIndex( i+((k/uRows)*uRows) ) );
-                    }
-                }
-            }
-
-/*
- * if hard skinned or this nurb is also a joint disabled 1199 to streamline
- * joint assignments.  all hard skinning now done in CleanUpSoftSkin.  if
- * (!make_soft || geom_as_joint) { add the new cv references to the last joint
- * for hard skinning only if ( lastJoint != NULL ) {
- * lastJoint->vrefs.AddUniqueNode( *vref ); geom_as_joint = 0; if ( verbose >=
- * 1 ) fprintf( outStream, "Doing NURBS hard skinning...\n"); } }
- */
-
-            // 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++ )
-                    eggNurbsSurf->AddVertex( 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++ )
-                        eggNurbsSurf->AddVertex( 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++ )
-                        eggNurbsSurf->AddVertex( k+(i*uRows)+((k/uRows)*uRows) );
-                }
-
-            }
-
-            // get the color of the NURBS surface
-            int numNurbMats;
-            EggColor *nurbCref;
-            pfVec4    nurbColor;
-
-            SAA_modelRelationGetMatNbElements( scene, model, FALSE, &relinfo,
-                &numNurbMats );
-
-            if ( verbose >= 1 )
-                fprintf( outStream, "nurbs surf has %d materials\n",
-                    numNurbMats );
-
-            if ( numNurbMats )
-            {
-                float r,g,b,a;
-
-                materials = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numNurbMats);
-
-                SAA_modelRelationGetMatElements( scene, model, relinfo,
-                    numNurbMats, materials );
-
-                SAA_materialGetDiffuse( scene, &materials[0], &r, &g, &b );
-                SAA_materialGetTransparency( scene, &materials[0], &a );
-                nurbColor.set( r, g, b, 1.0f - a );
-                // nurbColor.set( r, g, b, 1.0 );
-
-                nurbCref = _data.CreateColor(nurbColor);
-                eggNurbsSurf->attrib.SetCRef(nurbCref);
-
-                // get the texture of the NURBS surface from the material
-                int numNurbTexLoc = 0;
-                int numNurbTexGlb = 0;
-
-                // ASSUME only one texture per material
-                SAA_Elem nurbTex;
-
-                // 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 )
-                {
-                    if ( verbose >= 1 )
-                        fprintf( outStream, "%s had %d local tex\n", name,
-                            numNurbTexLoc );
-
-                    // get the referenced texture
-                    SAA_materialRelationGetT2DLocElements( scene, &materials[0],
-                        TEX_PER_MAT, &nurbTex );
-
-                }
-                // if no locals, try to get globals
-                else
-                {
-                    SAA_modelRelationGetT2DGlbNbElements( scene, model,
-                        FALSE, &relinfo, &numNurbTexGlb );
-
-                    if ( numNurbTexGlb )
-                    {
-                        if ( verbose >= 1 )
-                            fprintf( outStream, "%s had %d global tex\n", name,
-                                numNurbTexGlb );
-
-                            // get the referenced texture
-                            SAA_modelRelationGetT2DGlbElements( scene,
-                                model, TEX_PER_MAT, &nurbTex );
-                        }
-                }
-
-                // add tex ref's if we found any textures
-                if ( numNurbTexLoc || numNurbTexGlb)
-                {
-                    char    *texName = NULL;
-                    char    *uniqueTexName = NULL;
-                    EggTexture *tref;
-                    pfMatrix  nurbTexMat;
-
-
-                    // convert the texture to .rgb and adjust name
-                    texName = ConvertTexture( scene, &nurbTex );
-
-                    // append unique identifier to texname for this particular
-                    // object
-                    uniqueTexName = (char *)malloc(sizeof(char)*
-                        (strlen(name)+strlen(texName)+3) );
-                    sprintf( uniqueTexName, "%s-%s", name,
-                        RemovePathName(texName) );
-
-                    if ( verbose >= 1 )
-                    {
-                        fprintf( outStream, "creating tref %s\n",
-                            uniqueTexName );
-                    }
-
-                    tref = _data.CreateTexture( texName, uniqueTexName );
-
-                    uScale = ( float *)malloc(sizeof(float));
-                    vScale = ( float *)malloc(sizeof(float));
-                    uOffset = ( float *)malloc(sizeof(float));
-                    vOffset = ( float *)malloc(sizeof(float));
-
-                    // get texture offset info
-                    SAA_texture2DGetUScale( scene, &nurbTex, uScale );
-                    SAA_texture2DGetVScale( scene, &nurbTex, vScale );
-                    SAA_texture2DGetUOffset( scene, &nurbTex, uOffset );
-                    SAA_texture2DGetVOffset( scene, &nurbTex, vOffset );
-                    SAA_texture2DGetUVSwap( scene, &nurbTex, &uv_swap );
-
-
-                    if ( verbose >= 1 )
-                    {
-                        fprintf( outStream, "nurbTex uScale: %f\n", *uScale );
-                        fprintf( outStream, "nurbTex vScale: %f\n", *vScale );
-                        fprintf( outStream, "nurbTex uOffset: %f\n", *uOffset );
-                        fprintf( outStream, "nurbTex vOffset: %f\n", *vOffset );
-                        if ( uv_swap )
-                            fprintf( outStream, "nurbTex u & v swapped!\n" );
-                        else
-                            fprintf( outStream, "nurbTex u & v NOT swapped\n" );
-                    }
-
-                    nurbTexMat.makeIdent();
-
-                    if ( !ignore_tex_offsets )
-                    {
-                        if ( uv_swap )
-                        {
-                            nurbTexMat[0][0] = 0.0f;
-                            nurbTexMat[1][1] = 0.0f;
-                            nurbTexMat[0][1] = 1 / *vScale;
-                            nurbTexMat[1][0] = 1 / *uScale;
-                            nurbTexMat[2][1] = -(*uOffset / *uScale);
-                            nurbTexMat[2][0] = -(*vOffset / *vScale);
-                        }
-                        else
-                        {
-                            nurbTexMat[0][0] = 1 / *uScale;
-                            nurbTexMat[1][1] = 1 / *vScale;
-                            nurbTexMat[2][0] = -(*uOffset / *uScale);
-                            nurbTexMat[2][1] = -(*vOffset / *vScale);
-                        }
-                    }
-
-
-    // call printMat
-    if ( verbose >= 2 )
-    {
-    fprintf( outStream, "nurb tex matrix = %f %f %f %f\n", nurbTexMat[0][0],
-         nurbTexMat[0][1],  nurbTexMat[0][2],  nurbTexMat[0][3] );
-    fprintf( outStream, "nurb tex matrix = %f %f %f %f\n", nurbTexMat[1][0],
-         nurbTexMat[1][1],  nurbTexMat[1][2],  nurbTexMat[1][3] );
-    fprintf( outStream, "nurb tex matrix = %f %f %f %f\n", nurbTexMat[2][0],
-         nurbTexMat[2][1],  nurbTexMat[2][2],  nurbTexMat[2][3] );
-    fprintf( outStream, "nurb tex matrix = %f %f %f %f\n", nurbTexMat[3][0],
-         nurbTexMat[3][1],  nurbTexMat[3][2],  nurbTexMat[3][3] );
-    }
-
-
-                    tref->tex_mat = nurbTexMat;
-                    tref->flags |= EFT_TRANSFORM;
-
-                    eggNurbsSurf->attrib.SetTRef(tref);
-
-                }
-
-                // if we've encountered textures and we desire duv anims
-                if (( numNurbTexLoc || numNurbTexGlb ) && make_duv )
-                {
-                    int            numExp;
-
-                     // find how many expressions for this shape
-                    SAA_elementGetNbExpressions( scene, &nurbTex, NULL, FALSE,
-                        &numExp );
-
-                    // if it has expressions we'll assume its animated
-                    if ( numExp )
-                    {
-                        if ( verbose > 1 )
-                            printf( "nurbTex has %d expressions...\n", numExp );
-
-                        // if animated object make base duv's, animtables for
-                        // the duv's and store the original offsets
-                        strstream uName, vName;
-
-                        // create duv target names
-                        uName << name << ".u" << ends;
-                        vName << name << ".v" << ends;
-
-                        // make sure root morph table exists
-                        if ( morphRoot == NULL )
-                            morphRoot = animData.CreateTable( animRoot,
-                                "morph" );
-
-                        // create morph table entry for each duv
-                        SAnimTable *uTable = new SAnimTable( );
-                        uTable->name = uName.str();
-                        uTable->fps = anim_rate;
-                        morphRoot->children.push_back( uTable );
-                        if ( verbose >= 1 )
-                            fprintf( outStream, "created duv table named: %s\n",                                uName.str() );
-
-                        SAnimTable *vTable = new SAnimTable( );
-                        vTable->name = vName.str();
-                        vTable->fps = anim_rate;
-                        morphRoot->children.push_back( vTable );
-                        if ( verbose >= 1 )
-                            fprintf( outStream, "created duv table named: %s\n",                                vName.str() );
-
-                        float    texOffsets[4];
-
-                        texOffsets[0] = *uOffset;
-                        texOffsets[1] = *vOffset;
-                        texOffsets[2] = *uScale;
-                        texOffsets[3] = *vScale;
-
-                        // remember original texture offsets future reference
-                        SAA_elementSetUserData( scene, model, "TEX_OFFSETS",
-                            sizeof( texOffsets ), TRUE, (void  **)&texOffsets );
-
-                        // create UV's and duv's for each vertex
-                        for( i = 0; i < numVert; i++ )
-                        {
-                            pfVec2            tmpUV;
-                            EggMorphOffset *duvU;
-                            EggMorphOffset *duvV;
-
-                            // create uv's so we can store duv's
-                            eggNurbsSurf->CalcActualUV( i, tmpUV );
-                            pool->Vertex(i)->attrib.SetUV( tmpUV[0], tmpUV[1] );
-
-                            // generate base duv's for this vertex
-                            duvU = new EggMorphOffset(uName.str(), 1.0 , 0.0);
-                            pool->Vertex(i)->attrib.uv_morphs.push_back(*duvU);
-
-                            duvV = new EggMorphOffset(vName.str(), 0.0 , 1.0);
-                            pool->Vertex(i)->attrib.uv_morphs.push_back(*duvV);
-                        }
-
-                  } // if ( numExp )
-                } // if ( numTexLoc || numTexGlb )
-
-                // free( uScale ); free( vScale ); free( uOffset ); free(
-                // vOffset );
-
-                // free( materials );
-            }
-            else
-            {
-                // no material present - default to white
-                nurbColor.set( 1.0, 1.0, 1.0, 1.0 );
-            }
-
-            // check NURBS surface for trim curves
-            int     numTrims;
-            bool    isTrim = TRUE;
-            SAA_SubElem *trims;
-
-            SAA_nurbsSurfaceGetNbTrimCurves( scene, model, SAA_TRIMTYPE_TRIM,
-                &numTrims );
-
-            if ( verbose >= 1 )
-                fprintf( outStream, "nurbs surf has %d trim curves\n",
-                    numTrims );
-
-            if ( numTrims)
-            {
-                trims = (SAA_SubElem *)malloc(sizeof(SAA_SubElem)*numTrims);
-
-                if ( trims )
-                {
-                    SAA_nurbsSurfaceGetTrimCurves( scene, model,
-                        gtype, 0, SAA_TRIMTYPE_TRIM, numTrims,
-                        trims );
-
-                    MakeSurfaceCurve( scene, model, parent, eggNurbsSurf,
-                        numTrims, trims, isTrim );
-                }
-
-                // free( trims );
-            }
-
-            // check NURBS surface for surface curves
-            isTrim = FALSE;
-
-            SAA_nurbsSurfaceGetNbTrimCurves( scene, model,
-                SAA_TRIMTYPE_PROJECTION, &numTrims );
-
-            if ( verbose >= 1 )
-                fprintf( outStream, "nurbs surf has %d surface curves\n",
-                    numTrims );
-
-            if ( numTrims)
-            {
-                trims = (SAA_SubElem *)malloc(sizeof(SAA_SubElem)*numTrims);
-
-                if ( trims )
-                {
-                    SAA_nurbsSurfaceGetTrimCurves( scene, model,
-                        gtype, 0, SAA_TRIMTYPE_PROJECTION,
-                        numTrims, trims );
-
-                    MakeSurfaceCurve( scene, model, parent, eggNurbsSurf,
-                        numTrims, trims, isTrim );
-                }
-
-                // free( trims );
-            }
-
-            // push the NURBS into the egg data
-            parent->children.push_back( eggNurbsSurf );
-
-            // if model has key shapes, generate vertex offsets
-            if ( has_morph && make_morph )
-                MakeVertexOffsets( scene, model, type, numShapes, numVert,
-                    vertices, matrix, name );
-
-
-            // free( vertices );
-
-        }
-
-        // check to see if its a NURBS curve
-        else if ( (type == SAA_MNCRV) && ( visible ) && ( make_nurbs ) )
-        {
-            // ignore for now make the NURBS curve and push it into the egg
-            // data parent->children.push_back( MakeNurbsCurve( scene, model,
-            // parent, matrix, name ) );
-           }
-        else if ( type == SAA_MJNT )
-        {
-            MakeJoint( scene, lastJoint, lastAnim, model, name );
-            if ( verbose >= 1 )
-                fprintf( outStream, "encountered IK joint: %s\n", name );
-        }
-
-        // it must be a NULL
-        else
-        {
-            SAA_AlgorithmType    algo;
-
-            SAA_modelGetAlgorithm( scene, model, &algo );
-            if ( verbose >= 1 )
-                fprintf( outStream, "null algorithm: %d\n", algo );
-
-            if ( algo == SAA_ALG_INV_KIN )
-            {
-                MakeJoint( scene, lastJoint, lastAnim,  model, name );
-                if ( verbose >= 1 )
-                    fprintf( outStream, "encountered IK root: %s\n", name );
-            }
-            else if ( algo == SAA_ALG_INV_KIN_LEAF )
-            {
-                MakeJoint( scene, lastJoint, lastAnim, model, name );
-                if ( verbose >= 1 )
-                    fprintf( outStream, "encountered IK leaf: %s\n", name );
-            }
-            else if ( algo == SAA_ALG_STANDARD )
-            {
-                SAA_Boolean isSkeleton = FALSE;
-
-                if ( verbose >= 1 )
-                    fprintf( outStream, "encountered Standard null: %s\n", name);
-
-                SAA_modelIsSkeleton( scene, model, &isSkeleton );
-
-                // check to see if this NULL is used as a skeleton or is
-                // animated via constraint only ( these nodes are tagged by
-                // the animator with the keyword "joint" somewhere in the
-                // nodes name)
-                if ( isSkeleton || (strstr( name, "joint" ) != NULL) )
-                {
-                    MakeJoint( scene, lastJoint, lastAnim, model, name );
-                    if ( verbose >= 1 )
-                        fprintf( outStream, "animating Standard null!!!\n" );
-                }
-            }
-            else
-                if ( verbose >= 1 )
-                    fprintf( outStream, "encountered some other NULL: %d\n",
-                        algo );
-        }
-    }
-
-
-    // check for children...
-    int        numChildren;
-    int        thisChild;
-    SAA_Elem *children;
-
-    SAA_modelGetNbChildren( scene, model, &numChildren );
-    if ( verbose >= 1 )
-        fprintf( outStream, "Model children: %d\n", numChildren );
-
-    if ( numChildren )
-    {
-        children = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numChildren);
-        SAA_modelGetChildren( scene, model, numChildren, children );
-        if ( children != NULL )
-        {
-            for ( thisChild = 0; thisChild < numChildren; thisChild++ )
-            {
-                if ( verbose >= 1 )
-                    fprintf( outStream, "\negging child %d...\n", thisChild);
-                MakeEgg( parent, lastJoint, lastAnim, scene,
-                    &children[thisChild] );
-            }
-        }
-        else
-            fprintf( outStream, "Not enough Memory for children...\n");
-        // free( children );
-    }
-    fflush( outStream );
-  }
-  else
-    if ( verbose >= 1 )
-        fprintf( outStream, "Don't descend this branch!\n" );
-
-  // we are done for the most part - start cleaning up memory free( name );
-}
-
-
-/**
- * Given a scene and lists of u and v samples create a an egg NURBS curve of
- * degree two from the samples
- */
-void  soft2egg::
-MakeSurfaceCurve(  SAA_Scene *scene, SAA_Elem *model, EggGroup *parent,
-    EggNurbsSurface *&nurbsSurf, int numTrims, SAA_SubElem *trims,
-    bool isTrim )
-{
-    int      i;
-    long      totalSamples = 0;
-    long    *numSamples;
-    double    *uSamples;
-    double    *vSamples;
-    SAA_Elem *trimCurves;
-    char    *name;
-
-    // get UV coord data
-    numSamples = (long *)malloc(sizeof(long)*numTrims);
-
-    SAA_surfaceCurveGetNbLinearSamples( scene, model,  numTrims, trims,
-        numSamples );
-
-    for ( i = 0; i < numTrims; i++ )
-    {
-        totalSamples += numSamples[i];
-        if ( verbose >= 2 )
-            fprintf( outStream, "numSamples[%d] = %d\n", i, numSamples[i] );
-    }
-
-    if ( verbose >= 2 )
-        fprintf( outStream, "total samples = %ld\n", totalSamples );
-
-    uSamples = (double *)malloc(sizeof(double)*totalSamples);
-    vSamples = (double *)malloc(sizeof(double)*totalSamples);
-
-    SAA_surfaceCurveGetLinearSamples( scene, model, numTrims, trims,
-        numSamples, uSamples, vSamples );
-
-    if ( verbose >= 2 )
-        for ( long li = 0; li < totalSamples; li++ )
-            fprintf( outStream, "master list cv[%ld] = %f, %f\n", li,
-                uSamples[li], vSamples[li] );
-
-    trimCurves = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numTrims);
-
-    SAA_surfaceCurveExtract( scene, model, numTrims, trims, trimCurves );
-
-    // if it's a trim create a trim to assign trim curves to
-    EggNurbsSurface::Trim *eggTrim = new EggNurbsSurface::Trim();
-
-    // for each trim curve, make an egg curve and add it to the trims of the
-    // NURBS surface
-    for ( i = 0; i < numTrims; i++ )
-    {
-        if ( use_prefix )
-        {
-            // Get the FULL name of the trim curve
-            name = GetFullName( scene, &trimCurves[i] );
-        }
-        else
-        {
-            // Get the name of the trim curve
-            name = GetName( scene, &trimCurves[i] );
-        }
-
-        if ( isTrim )
-        {
-            // add to trim list
-            EggNurbsSurface::Loop *eggLoop = new EggNurbsSurface::Loop();
-            eggLoop->push_back( MakeUVNurbsCurve( i, numSamples, uSamples,
-                vSamples, parent, name ) );
-            eggTrim->push_back( *eggLoop );
-        }
-        else
-            // add to curve list
-            nurbsSurf->curves.push_back( MakeUVNurbsCurve( i, numSamples,                         uSamples, vSamples, parent, name ) );
-    }
-
-    if ( isTrim )
-        // pus trim list onto trims list
-        nurbsSurf->trims.push_back( *eggTrim );
-
-    // free( name ); free( trimCurves ); free( uSamples ); free( vSamples );
-}
-
-/**
- * Given a scene and lists of u and v samples create a an egg NURBS curve of
- * degree two from the samples
- */
-EggNurbsCurve  *soft2egg::
-MakeUVNurbsCurve( int numCurve, long *numSamples, double *uSamples,
-    double *vSamples, EggGroup *parent, char *name )
-{
-    EggNurbsCurve    *eggNurbsCurve = new EggNurbsCurve( name );
-
-    eggNurbsCurve->order = 2;
-
-
-    if ( verbose >= 2 )
-        fprintf( outStream, "nurbs UV curve %s:\n", name );
-
-    // set sub_div so we can see it in perfly eggNurbsCurve->subdiv =
-    // numSamples[numCurve]4; perfly chokes on big numbers - keep it
-    // reasonable
-    eggNurbsCurve->subdiv = 150;
-
-    // create pool of NURBS vertices
-    EggVertexPool *pool = _data.CreateVertexPool( parent, name );
-    eggNurbsCurve->SetVertexPool( pool );
-
-    // calculate offset to this curve's samples in list of all curve samples
-    int offset = 0;
-
-    for ( int o = 0; o < numCurve; o++ )
-        offset += numSamples[o];
-
-    for ( int k = 0; k<numSamples[numCurve]; k++ )
-    {
-        pfVec3  eggVert;
-
-        // index into the array of samples for this curve
-        eggVert.set( uSamples[k+offset], vSamples[k+offset], 1.0f );
-
-        if ( verbose >= 2 )
-            fprintf( outStream, "cv[%d] = %f %f %f\n", k, eggVert[0],
-                eggVert[1], eggVert[2] );
-
-        // populate vertex pool
-        pool->AddVertex( eggVert, k );
-
-        // add vref's to NURBS info
-        eggNurbsCurve->AddVertex( k );
-    }
-
-    // create numSamples[numCurve]+2 knots
-    eggNurbsCurve->knots.push_back( 0 );
-    for ( k = 0; k < numSamples[numCurve]; k++ )
-        eggNurbsCurve->knots.push_back( k  );
-    eggNurbsCurve->knots.push_back( numSamples[numCurve] - 1 );
-
-    // set color to bright green for now
-    EggColor *nurbCref;
-    pfVec4    nurbColor;
-
-    nurbColor.set( 0.5, 1.0, 0.5, 1.0 );
-    nurbCref = _data.CreateColor(nurbColor);
-    eggNurbsCurve->attrib.SetCRef(nurbCref);
-
-    return( eggNurbsCurve );
-}
-
-/**
- * Given a scene and a NURBS curve model create the the appropriate egg
- * structures
- */
-EggNurbsCurve  *soft2egg::
-MakeNurbsCurve( SAA_Scene *scene, SAA_Elem *model, EggGroup *parent,
-    float matrix[4][4], char *name )
-{
-    EggNurbsCurve    *eggNurbsCurve = new EggNurbsCurve( name );
-    int degree;
-
-    if ( verbose >= 2 )
-        fprintf( outStream, "nurbs curve %s:\n", name );
-
-    // create nurbs representation of surface
-    SAA_nurbsCurveGetDegree( scene, model, &degree );
-    eggNurbsCurve->order = degree + 1;
-    if ( verbose >= 2 )
-        fprintf( outStream, "nurbs curve order: %d\n", degree + 1 );
-
-    SAA_nurbsCurveSetStep( scene, model, nurbs_step );
-
-    SAA_Boolean    closed = FALSE;
-
-    SAA_nurbsCurveGetClosed( scene, model, &closed );
-    if ( closed )
-        if ( verbose >= 2 )
-            fprintf( outStream, "nurbs curve is closed...\n");
-
-    int numKnots;
-
-    SAA_nurbsCurveGetNbKnots( scene, model, &numKnots );
-    if ( verbose >= 2 )
-        fprintf( outStream, "nurbs curve knots: %d\n", numKnots );
-    double *knots;
-    knots = (double *)malloc(sizeof(double)*numKnots);
-    SAA_nurbsCurveGetKnots( scene, model, SAA_GEOM_ORIGINAL, 0,
-        numKnots, knots );
-
-    AddKnots( eggNurbsCurve->knots, knots, numKnots, closed, degree );
-
-    // free( knots );
-
-    int    numCV;
-
-    SAA_modelGetNbVertices( scene, model, &numCV );
-    if ( verbose >= 2 )
-        fprintf( outStream, "%d CV's (=? %d)\n", numCV, (numKnots-(degree+1)) );
-
-    // set sub_div so we can see it in perfly
-    eggNurbsCurve->subdiv = (numCV-1)*nurbs_step;
-
-    // get the CV's
-    SAA_DVector *cvArray;
-    cvArray = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numCV);
-    SAA_modelGetVertices( scene, model, SAA_GEOM_ORIGINAL, 0,
-        numCV, cvArray );
-
-    // create pool of NURBS vertices
-    EggVertexPool *pool = _data.CreateVertexPool( parent, name );
-    eggNurbsCurve->SetVertexPool( pool );
-
-    for ( int k = 0; k<numCV; k++ )
-    {
-        if ( verbose >= 2 )
-            fprintf( outStream, "cv[%d] = %f %f %f %f\n", k, cvArray[k].x,
-                cvArray[k].y, cvArray[k].z, cvArray[k].w );
-
-        pfVec4  eggVert;
-
-        // convert to global coords
-        SAA_DVector local = cvArray[k];
-        SAA_DVector global;
-
-        _HVCT_X_MAT( global, local, matrix );
-
-        eggVert.set( global.x, global.y, global.z, global.w );
-
-        // populate vertex pool
-        pool->AddVertex( eggVert, k );
-
-        // add vref's to NURBS info
-        eggNurbsCurve->AddVertex( k );
-    }
-
-    if ( closed )
-    {
-        // need to replicate first (degree) vertices
-        for ( k = 0; k < degree; k++ )
-        {
-            eggNurbsCurve->AddVertex( k );
-            if ( verbose >= 2 )
-                fprintf( outStream, "adding cv[%d] = %f %f %f %f\n", k,
-                    cvArray[k].x, cvArray[k].y, cvArray[k].z, cvArray[k].w );
-        }
-    }
-
-    // free( cvArray );
-
-    // set color to bright green for now
-    EggColor *nurbCref;
-    pfVec4    nurbColor;
-
-    nurbColor.set( 0.5, 1.0, 0.5, 1.0 );
-    nurbCref = _data.CreateColor(nurbColor);
-    eggNurbsCurve->attrib.SetCRef(nurbCref);
-
-    return( eggNurbsCurve );
-}
-
-/**
- * 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 soft2egg::
-AddKnots( perf_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 = (double *)malloc(sizeof(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] );
-            if ( verbose >= 2 )
-                fprintf( outStream, "knots[%d] = %f\n", k, newKnots[k] );
-        }
-
-        // free( newKnots );
-    }
-    else
-    {
-        eggKnots.push_back( knots[k] );
-        if ( verbose >= 2 )
-            fprintf( outStream, "knots[%d] = %f\n", k, knots[k] );
-    }
-
-    // add the regular complement of knots
-    for (k = 0; k < numKnots; k++)
-    {
-        eggKnots.push_back( knots[k] );
-        if ( verbose >= 2 )
-            fprintf( outStream, "knots[%d] = %f\n", k+1, knots[k] );
-    }
-
-    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]) );
-            if ( verbose >= 2 )
-                fprintf( outStream, "knots[%d] = %f\n", k,
-                    lastKnot + (knots[k] - knots[k-1]) );
-            lastKnot = lastKnot + (knots[k] - knots[k-1]);
-        }
-    }
-    else
-    {
-        eggKnots.push_back( knots[k-1] );
-        if ( verbose >= 2 )
-            fprintf( outStream, "knots[%d] = %f\n", k+1, knots[k-1] );
-    }
-}
-
-/**
- * Given a name, a parent and a model create a new a new EggJoint for that
- * model.
- */
-void soft2egg::
-MakeJoint( SAA_Scene *scene, EggJoint *&lastJoint, AnimGroup *&lastAnim,
-    SAA_Elem *model, char *name )
-{
-    float     matrix[4][4];
-    pfMatrix  Matrix;
-    EggJoint *joint;
-    SAA_Boolean    globalFlag = FALSE;
-    int    scale_joint = 0;
-
-
-    // this is a quick fix to make scaled skeletons possible if the parent
-    // contains the keyword "scale" make this joint a global root joint
-    // instead of a child...
-    if (lastJoint != NULL)
-    {
-        if ( strstr( lastJoint->name.Str(), "scale" ) != NULL )
-        {
-            scale_joint = 1;
-            if ( verbose >= 1 )
-                fprintf( outStream, "scale joint flag set!\n" );
-        }
-    }
-
-    // if not root, flatten is false, and last joint had no scaling applied to
-    // it, then create joint in skeleton tree
-    if ( (lastJoint != NULL) && !flatten && !scale_joint )
-    {
-        if ( verbose >= 1 )
-        {
-            fprintf( outStream, "lastJoint = %s\n", lastJoint->name.Str() );
-            fprintf( outStream, "getting local transform\n" );
-        }
-
-        SAA_elementSetUserData( scene, model, "GLOBAL", sizeof( SAA_Boolean ),
-            TRUE, (void  **)&globalFlag );
-
-        // get the local matrix
-        SAA_modelGetMatrix( scene, model, SAA_COORDSYS_LOCAL,  matrix );
-
-        // make this into a pfMatrix
-        Matrix[0][0] = matrix[0][0];
-        Matrix[0][1] = matrix[0][1];
-        Matrix[0][2] = matrix[0][2];
-        Matrix[0][3] = matrix[0][3];
-        Matrix[1][0] = matrix[1][0];
-        Matrix[1][1] = matrix[1][1];
-        Matrix[1][2] = matrix[1][2];
-        Matrix[1][3] = matrix[1][3];
-        Matrix[2][0] = matrix[2][0];
-        Matrix[2][1] = matrix[2][1];
-        Matrix[2][2] = matrix[2][2];
-        Matrix[2][3] = matrix[2][3];
-        Matrix[3][0] = matrix[3][0];
-        Matrix[3][1] = matrix[3][1];
-        Matrix[3][2] = matrix[3][2];
-        Matrix[3][3] = matrix[3][3];
-
-        joint = _data.CreateJoint( lastJoint, name );
-        joint->transform = Matrix;
-    }
-    // if we already have a root attach this joint to it
-    else if (foundRoot)
-    {
-        if ( verbose >= 1 )
-            fprintf( outStream, "getting global transform\n" );
-
-        globalFlag = TRUE;
-
-        SAA_elementSetUserData( scene, model, "GLOBAL", sizeof( SAA_Boolean ),
-            TRUE, (void *)&globalFlag );
-
-        // get the global matrix
-        SAA_modelGetMatrix( scene, model, SAA_COORDSYS_GLOBAL,  matrix );
-
-        // make this into a pfMatrix
-        Matrix[0][0] = matrix[0][0];
-        Matrix[0][1] = matrix[0][1];
-        Matrix[0][2] = matrix[0][2];
-        Matrix[0][3] = matrix[0][3];
-        Matrix[1][0] = matrix[1][0];
-        Matrix[1][1] = matrix[1][1];
-        Matrix[1][2] = matrix[1][2];
-        Matrix[1][3] = matrix[1][3];
-        Matrix[2][0] = matrix[2][0];
-        Matrix[2][1] = matrix[2][1];
-        Matrix[2][2] = matrix[2][2];
-        Matrix[2][3] = matrix[2][3];
-        Matrix[3][0] = matrix[3][0];
-        Matrix[3][1] = matrix[3][1];
-        Matrix[3][2] = matrix[3][2];
-        Matrix[3][3] = matrix[3][3];
-
-        if ( verbose >= 1 )
-            fprintf( outStream, "attaching orphan chain to root\n" );
-
-        joint = _data.CreateJoint( rootJnt, name );
-        joint->transform = Matrix;
-        lastAnim = rootAnim;
-    }
-    // if root, make a seperate tree for skeleton and create required Table
-    // for the Egg heirarchy
-    else
-    {
-        if ( verbose >= 1 )
-            fprintf( outStream, "getting global transform\n" );
-
-        globalFlag = TRUE;
-
-        SAA_elementSetUserData( scene, model, "GLOBAL", sizeof( SAA_Boolean ),
-            TRUE, (void *)&globalFlag );
-
-        // get the global matrix
-        SAA_modelGetMatrix( scene, model, SAA_COORDSYS_GLOBAL,  matrix );
-
-        // make this into a pfMatrix
-        Matrix[0][0] = matrix[0][0];
-        Matrix[0][1] = matrix[0][1];
-        Matrix[0][2] = matrix[0][2];
-        Matrix[0][3] = matrix[0][3];
-        Matrix[1][0] = matrix[1][0];
-        Matrix[1][1] = matrix[1][1];
-        Matrix[1][2] = matrix[1][2];
-        Matrix[1][3] = matrix[1][3];
-        Matrix[2][0] = matrix[2][0];
-        Matrix[2][1] = matrix[2][1];
-        Matrix[2][2] = matrix[2][2];
-        Matrix[2][3] = matrix[2][3];
-        Matrix[3][0] = matrix[3][0];
-        Matrix[3][1] = matrix[3][1];
-        Matrix[3][2] = matrix[3][2];
-        Matrix[3][3] = matrix[3][3];
-
-        rootJnt = _data.CreateJoint( skeleton, "root" );
-        rootJnt->transform.makeIdent();
-        if ( verbose >= 1 )
-            fprintf( outStream, "setting skeleton root\n" );
-        rootJnt->flags |= EF_TRANSFORM;
-
-        joint = _data.CreateJoint( rootJnt, name );
-        joint->transform = Matrix;
-        foundRoot = TRUE;
-        if ( verbose >= 1 )
-            fprintf( outStream, "found first chain\n" );
-
-        // make skeleton table
-        AnimGroup *skeletonTable;
-        skeletonTable = animData.CreateTable( animRoot, "<skeleton>" );
-        rootAnim = animData.CreateTable( skeletonTable, "root" );
-        XfmSAnimTable *table = new XfmSAnimTable( );
-        table->name = "xform";
-        table->fps = anim_rate;
-        rootAnim->children.push_back( table );
-        lastAnim = rootAnim;
-    }
-
-    joint->flags |= EF_TRANSFORM;
-
-    // if ( make_anim) {
-        AnimGroup *anim = animData.CreateTable( lastAnim, name );
-        XfmSAnimTable *table = new XfmSAnimTable( );
-        if ( verbose >= 1 )
-            fprintf( outStream, "created anim table: %s\n", "xform" );
-        table->name = "xform";
-        table->fps = anim_rate;
-        anim->children.push_back( table );
-        lastAnim = anim;
-    // }
-
-    // make this joint current parent of chain
-    lastJoint = joint;
-}
-
-
-/**
- * Given a skeleton part find its envelopes (if any) get the vertices
- * associated with the envelopes and their weights and make vertex ref's for
- * the joint
- */
-void soft2egg::
-MakeSoftSkin( SAA_Scene *scene, SAA_Elem *model, SAA_Elem *models,
-    int numModels, char *name )
-{
-    int            numEnv;
-    SAA_ModelType   type;
-    SAA_Elem    *envelopes;
-
-    if ( verbose >= 1 )
-        fprintf( outStream, "\n>found skeleton part( %s )!\n", name );
-
-    SAA_skeletonGetNbEnvelopes( scene, model, &numEnv );
-
-    if ( numEnv )
-    {
-        // it's got envelopes - must be soft skinned
-        if ( verbose >= 1 )
-            fprintf( outStream, "numEnv = %d\n", numEnv );
-
-        // allocate envelope array
-        envelopes = ( SAA_Elem *)malloc( sizeof( SAA_Elem )*numEnv );
-
-        if ( envelopes != NULL )
-        {
-            int         thisEnv;
-            SAA_EnvType envType;
-            bool        hasEnvVertices = 0;
-
-            SAA_skeletonGetEnvelopes( scene, model, numEnv, envelopes );
-
-            for ( thisEnv = 0; thisEnv < numEnv; thisEnv++ )
-            {
-                if ( verbose >= 1 )
-                    fprintf( outStream, "env[%d]: ", thisEnv );
-
-                SAA_envelopeGetType( scene, &envelopes[thisEnv], &envType );
-
-                if ( envType == SAA_ENVTYPE_NONE )
-                {
-                    if ( verbose >= 1 )
-                        fprintf( outStream, "envType = none\n" );
-                }
-                else if ( envType == SAA_ENVTYPE_FLXLCL )
-                {
-                    if ( verbose >= 1 )
-                        fprintf( outStream, "envType = flexible, local\n" );
-                    hasEnvVertices = 1;
-                }
-                else if ( envType == SAA_ENVTYPE_FLXGLB )
-                {
-                    if ( verbose >= 1 )
-                        fprintf( outStream, "envType = flexible, global\n" );
-                    hasEnvVertices = 1;
-                }
-                else if ( envType == SAA_ENVTYPE_RGDGLB )
-                {
-                    if ( verbose >= 1 )
-                        fprintf( outStream, "envType = rigid, global\n" );
-                    hasEnvVertices = 1;
-                }
-                else
-                {
-                    if ( verbose >= 1 )
-                        fprintf( outStream, "envType = unknown\n" );
-                }
-            }
-
-            if ( hasEnvVertices)
-            {
-                int            *numEnvVertices;
-                SAA_SubElem    *envVertices = NULL;
-
-                numEnvVertices = (int *)malloc(sizeof(int)*numEnv);
-
-                SAA_envelopeGetNbCtrlVertices( scene, model, numEnv,
-                    envelopes, numEnvVertices );
-
-                if ( numEnvVertices != NULL )
-                {
-                    int totalEnvVertices = 0;
-                    int    i,j,k;
-
-                    for( i = 0; i < numEnv; i++ )
-                    {
-                        totalEnvVertices += numEnvVertices[i];
-                        if ( verbose >= 1 )
-                            fprintf( outStream, "numEnvVertices[%d] = %d\n",
-                                i, numEnvVertices[i] );
-                    }
-
-
-                    if ( verbose >= 1 )
-                        fprintf( outStream, "total env verts = %d\n",
-                            totalEnvVertices );
-
-                    if ( totalEnvVertices )
-                    {
-                    envVertices = (SAA_SubElem *)malloc(sizeof(SAA_SubElem)*totalEnvVertices);
-
-                    if ( envVertices != NULL )
-                    {
-
-                        SAA_envelopeGetCtrlVertices( scene, model,
-                            numEnv, envelopes, numEnvVertices, envVertices);
-
-                        // loop through for each envelope
-                        for ( i = 0; i < numEnv; i++ )
-                        {
-                            float *weights = NULL;
-                            int       vertArrayOffset = 0;
-
-                            if ( verbose >= 2 )
-                                fprintf( outStream, "\nenvelope[%d]:\n", i );
-
-                            weights = (float *)malloc(sizeof(float)*numEnvVertices[i]);
-
-                            if ( weights )
-                            {
-                            char *envName;
-                            int *vpoolMap = NULL;
-
-                            for ( j = 0; j < i; j++ )
-                                vertArrayOffset += numEnvVertices[j];
-
-                            if ( verbose >= 1 )
-                                fprintf( outStream,
-                                    "envVertArray offset = %d\n",
-                                    vertArrayOffset );
-
-                            // get the weights of the envelope vertices
-                            SAA_ctrlVertexGetEnvelopeWeights(
-                                    scene, model, &envelopes[i],
-                                    numEnvVertices[i],
-                                    &envVertices[vertArrayOffset], weights );
-
-                            // Get the name of the envelope model
-                            if ( use_prefix )
-                            {
-                                // Get the FULL name of the envelope
-                                envName = GetFullName( scene, &envelopes[i] );
-                            }
-                            else
-                            {
-                                // Get the name of the envelope
-                                envName = GetName( scene, &envelopes[i] );
-                            }
-
-                            if ( verbose >= 1 )
-                                fprintf( outStream, "envelope name %s\n", envName );
-
-                            // find out if envelope geometry is poly or nurb
-                            // SAA_modelGetType( scene, FindModelByName(
-                            // envName, scene, models, numModels ), &type );
-
-                            SAA_modelGetType( scene, &envelopes[i], &type );
-
-                            if ( verbose >= 1 )
-                            {
-                                fprintf( outStream, "envelope model type ");
-
-                                if ( type == SAA_MSMSH )
-                                        fprintf( outStream, "MESH\n" );
-                                else if ( type == SAA_MNSRF )
-                                        fprintf( outStream, "NURBS\n" );
-                                else
-                                        fprintf( outStream, "OTHER\n" );
-                           }
-
-                            int *envVtxIndices = NULL;
-                            envVtxIndices = (int *)malloc(sizeof(int)*numEnvVertices[i]);
-
-                            // Get the envelope vertex indices
-                            SAA_ctrlVertexGetIndices( scene, &envelopes[i],                                     numEnvVertices[i],
-                                &envVertices[vertArrayOffset], envVtxIndices );
-
-                            // find out how many vertices the model has
-                            int modelNumVert;
-
-                            SAA_modelGetNbVertices( scene, &envelopes[i], &modelNumVert );
-
-                            SAA_DVector *modelVertices = NULL;
-                            modelVertices = (SAA_DVector *)malloc(sizeof(SAA_DVector)*modelNumVert);
-
-                            // get the model vertices
-                            SAA_modelGetVertices( scene, &envelopes[i],
-                                SAA_GEOM_ORIGINAL, 0, modelNumVert,
-                                modelVertices );
-
-                            // create array of global model coords
-                            SAA_DVector *globalModelVertices = NULL;
-                            globalModelVertices = (SAA_DVector *)malloc(sizeof(SAA_DVector)*modelNumVert);
-                            float        matrix[4][4];
-
-                            // tranform local model vert coords to global
-
-                            // first get the global matrix
-                            SAA_modelGetMatrix( scene, &envelopes[i],                                                 SAA_COORDSYS_GLOBAL,  matrix );
-
-                            // populate array of global model verts
-                            for ( j = 0; j < modelNumVert; j++ )
-                            {
-                                _VCT_X_MAT( globalModelVertices[j],
-                                    modelVertices[j], matrix );
-                            }
-
-                            // find the egg vertex pool that corresponds to
-                            // this envelope model
-                            EggVertexPool *envPool =
-                                (EggVertexPool *)(_data.pools.FindName( envName ));
-                            // If we are outputting triangles: create an array
-                            // that maps from a referenced vertex in the
-                            // envelope to a corresponding vertex in the egg
-                            // vertex pool if ( (type == SAA_MNSRF) &&
-                            // !make_nurbs )
-                            if ( !make_nurbs || (type == SAA_MSMSH) )
-                            {
-                                vpoolMap = FindClosestTriVert( envPool,
-                                    globalModelVertices, modelNumVert );
-                            }
-
-
-                            if ( envPool != NULL )
-                            {
-
-                            // find the egg joint that corresponds to this
-                            // model
-                            EggJoint *joint =
-                                (EggJoint *)(skeleton->FindDescendent( name ));
-
-                            // this doesn't seem to be necessary 4799 EggJoint
-                            // *parent = (EggJoint *)joint->parent;
-                            // assert(parent->IsA(NT_EggJoint));
-
-                            // for every envelope vertex
-                            for (j = 0; j < numEnvVertices[i]; j++)
-                            {
-                                double scaledWeight =  weights[j]/ 100.0f;
-
-                                // make sure its in legal range
-                                if (( envVtxIndices[j] < modelNumVert )
-                                    && ( envVtxIndices[j] >= 0 ))
-                                {
-                                  if ( (type == SAA_MNSRF) && make_nurbs )
-                                  {
-                                    // assign all referenced control vertices
-                                    joint->AddVertex( envPool->Vertex(envVtxIndices[j]), scaledWeight );
-
-                                    if ( verbose >= 2 )
-                                        fprintf( outStream,
-                                            "%d: adding vref to cv %d with weight %f\n",
-                                            j, envVtxIndices[j], scaledWeight );
-
-                                    envPool->Vertex(envVtxIndices[j])->AddJoint( joint, scaledWeight );
-                                    // set flag to show this vertex has been
-                                    // assigned
-                                    envPool->Vertex(envVtxIndices[j])->multipleJoints = 1;
-                                  }
-                                  else
-                                  {
-                                    // assign all the tri verts associated
-                                    // with this control vertex to joint
-                                    for ( k = 0; k < envPool->NumVertices(); k++ )
-                                    {
-                                      if ( vpoolMap[k] == envVtxIndices[j] )
-                                      {
-
-                                        // add each vert in pool to last joint
-                                        // for soft skinning
-                                        joint->AddVertex(envPool->Vertex(k),
-                                            scaledWeight);
-
-                                        if ( verbose >= 2 )
-                                            fprintf( outStream,
-                                                "%d: adding vref from cv %d to vert %d with weight %f(vpool)\n",
-                                                j, envVtxIndices[j], k, scaledWeight );
-
-                                        envPool->Vertex(k)->AddJoint( joint, scaledWeight );
-                                        // set flag to show this vertex has
-                                        // been assigned
-                                        envPool->Vertex(k)->multipleJoints = 1;
-                                      }
-                                    }
-                                 }
-                                }
-                                else
-                                    if ( verbose >= 2 )
-                                        fprintf( outStream,
-                                            "%d: Omitted vref from cv %d with weight %f (out of range 0 to %d )\n",
-                                            j, envVtxIndices[j], scaledWeight, modelNumVert );
-                            }
-
-                            }
-                            else
-                                if ( verbose >= 2 )
-                                    fprintf( outStream, "Couldn't find vpool %s!\n", envName );
-
-                            // free( modelVertices ); free(
-                            // globalModelVertices ); free( envVtxIndices );
-                            // free( envName );
-                            } //if (weights)
-                            // free( weights );
-
-                        } // for i
-
-                    } // if (envVertices != NULL)
-                    else
-                        fprintf( outStream, "Not enough memory for envelope vertices...\n");
-                    // free( envVertices );
-                    } // if (totalEnvVertices)
-                    else
-                        if ( verbose >= 1 )
-                            fprintf( outStream, "No envelope vertices present...\n");
-
-                    // free( numEnvVertices );
-
-            } // if (numEnvVertices != NULL)
-
-          } // if (hasEnvVertices)
-
-        } // if (envelopes != NULL)
-        else
-            fprintf( outStream, "Not enough memory for envelopes...\n" );
-
-        // free( envelopes );
-
-    } //if (numEnv)
-
-    else
-        if ( verbose >= 1 )
-            fprintf( outStream, "Skeleton member has no envelopes...\n" );
-}
-
-
-/**
- * Given a model, make sure all its vertices have been soft assigned.  If not
- * hard assign to the last joint we saw.
- */
-void soft2egg::
-CleanUpSoftSkin( SAA_Scene *scene, SAA_Elem *model, char *name )
-{
-    static EggJoint *joint;
-    SAA_Elem        parent;
-    SAA_ModelType     type;
-    SAA_Boolean        skel;
-
-    // find out what type of node we're dealing with
-    SAA_modelGetType( scene, model, &type );
-
-    char   *parentName;
-    int        level;
-    SAA_Elem    *searchNode = model;
-
-    if ( verbose >= 1 )
-        fprintf( outStream, "\nCleaning up model %s\n", name );
-
-    // this step is weird - I think I want it here but it seems to break some
-    // models.  Files like props-props_wh_cookietime.3-0 in
-    // fulrndpubvrmlchipchips_adventurecharzone1roomswarehouse_final need to
-    // do the "if (skel)" bit.
-
-    // am I a skeleton too?
-    SAA_modelIsSkeleton( scene, model, &skel );
-
-    // if not look for the last skeleton part
-    if ( skel )
-        parentName = name;
-    else do
-    {
-        SAA_elementGetHierarchyLevel( scene, searchNode, &level );
-
-        // make sure we don't try to get the root's parent
-        if ( level )
-        {
-            SAA_modelGetParent( scene, searchNode, &parent );
-
-            if ( use_prefix )
-            {
-                // Get the FULL name of the parent
-                parentName = GetFullName( scene, &parent );
-            }
-            else
-            {
-                // Get the name of the parent
-                parentName = GetName( scene, &parent );
-            }
-
-            SAA_modelGetType( scene, &parent, &type );
-
-            SAA_modelIsSkeleton( scene, &parent, &skel );
-
-            if ( verbose >= 1 )
-                fprintf( outStream, "model %s, level %d, type %d, skel %d\n",
-                    parentName, level, type, skel );
-
-            searchNode = &parent;
-        }
-        else
-        {
-            // we reached the root of the tree
-            parentName = NULL;
-            if ( verbose >= 1 )
-                fprintf( outStream, "at root of tree! level %d\n", level );
-            break;
-        }
-
-    // look until parent is a joint or acts like one
-    } while ( !skel && ( strstr( parentName,"joint") == NULL ));
-
-    EggJoint    *thisJoint = NULL;
-
-    if ( parentName != NULL )
-    {
-        if ( verbose >= 1 )
-        {
-            fprintf( outStream, "found model parent joint %s\n", parentName);
-            fprintf( outStream, "looking for joint %s\n", parentName );
-        }
-        thisJoint = (EggJoint *)(skeleton->FindDescendent( parentName ));
-    }
-    else
-        if ( verbose >= 1 )
-                fprintf( outStream, "Couldn't find parent joint!\n");
-
-    if ( thisJoint != NULL )
-    {
-        joint = thisJoint;
-        if ( verbose >= 1 )
-            fprintf( outStream, "setting joint to %s\n", parentName );
-
-        // find the vpool for this model
-        EggVertexPool *vPool =
-            (EggVertexPool *)(_data.pools.FindName( name ));
-
-        if (vPool != NULL)
-        {
-            int i;
-            double membership;
-            int numVerts = vPool->NumVertices() ;
-
-
-            if ( verbose >= 1 )
-                fprintf( outStream, "found vpool %s w/ %d verts\n",
-                name, numVerts );
-
-            for ( i = 0; i < numVerts; i++ )
-            {
-                if ( vPool->Vertex(i)->multipleJoints != 1 )
-                {
-                    if ( verbose >= 1 )
-                    {
-                        fprintf( outStream, "vpool %s vert %d", name, i );
-                        fprintf( outStream, " not assigned!\n" );
-                    }
-
-                    // hard skin this vertex
-                    joint->AddVertex( vPool->Vertex(i), 1.0f );
-                }
-                else
-                {
-                    membership = vPool->Vertex(i)->NetMembership();
-
-
-                    if ( verbose >= 1 )
-                    {
-                        fprintf( outStream, "vpool %s vert %d", name,
-                            i );
-                        fprintf( outStream, " has membership %f\n",
-                            membership );
-                    }
-
-                    if ( membership == 0 )
-                    {
-                        if ( verbose >= 1 )
-                            fprintf( outStream, "adding full weight..\n" );
-
-                        // hard skin this vertex
-                        joint->AddVertex( vPool->Vertex(i), 1.0f );
-                    }
-                }
-            }
-        }
-        else
-            if ( verbose >= 1 )
-                fprintf( outStream, "couldn't find vpool %s\n", name );
-    }
-    else
-    {
-        if ( parentName != NULL )
-            if ( verbose >= 1 )
-                fprintf( outStream, "Couldn't find joint %s\n", parentName );
-    }
-}
-
-/**
- * Given a scene and a skeleton part ,get all the position, rotation, and
- * scale for the skeleton part for this frame and write them out as Egg
- * animation tables.
- */
-void soft2egg::
-MakeAnimTable( SAA_Scene *scene, SAA_Elem *skeletonPart, char *name )
-{
-
-    if ( skeletonPart != NULL )
-    {
-        float    i,j,k;
-        float    h,p,r;
-        float    x,y,z;
-        int         size;
-        SAA_Boolean globalFlag = FALSE;
-        SAA_Boolean bigEndian;
-
-        if ( verbose >= 1 )
-            fprintf( outStream, "\n\nanimating child %s\n", name );
-
-        SAA_elementGetUserDataSize( scene, skeletonPart, "GLOBAL", &size );
-
-        if ( size != 0 )
-            SAA_elementGetUserData( scene, skeletonPart, "GLOBAL",
-                sizeof( SAA_Boolean), &bigEndian, (void *)&globalFlag );
-
-        if ( globalFlag )
-        {
-            if ( verbose >= 1 )
-                fprintf( outStream, " using global matrix\n" );
-
-            // get SAA orientation
-            SAA_modelGetRotation( scene, skeletonPart, SAA_COORDSYS_GLOBAL,
-                &p, &h, &r );
-
-            // get SAA translation
-            SAA_modelGetTranslation( scene, skeletonPart, SAA_COORDSYS_GLOBAL,
-                &x, &y, &z );
-
-            // get SAA scaling
-            SAA_modelGetScaling( scene, skeletonPart, SAA_COORDSYS_GLOBAL,
-                &i, &j, &k );
-        }
-        else
-        {
-            if ( verbose >= 1 )
-                fprintf( outStream, "using local matrix\n" );
-
-            // get SAA orientation
-            SAA_modelGetRotation( scene, skeletonPart, SAA_COORDSYS_LOCAL,
-                &p, &h, &r );
-
-            // get SAA translation
-            SAA_modelGetTranslation( scene, skeletonPart, SAA_COORDSYS_LOCAL,
-                &x, &y, &z );
-
-            // get SAA scaling
-            SAA_modelGetScaling( scene, skeletonPart, SAA_COORDSYS_LOCAL,
-                &i, &j, &k );
-        }
-
-
-        if ( verbose >= 2 )
-            fprintf( outStream, "\nanim data: %f %f %f\n\t%f %f %f\n\t%f %f %f\n",
-                i, j, k, h, p, r, x, y, z );
-
-        // find the appropriate anim table for this skeleton part
-        AnimGroup     *thisGroup;
-        XfmSAnimTable *thisTable;
-
-        // find the anim table associated with this group
-        thisGroup = (AnimGroup *)(animRoot->FindDescendent( name ));
-        if ( verbose >= 2 )
-            fprintf( outStream, "\nlooking for anim group %s\n", name );
-        if ( thisGroup != NULL )
-        {
-            thisTable = (XfmSAnimTable *)(thisGroup->FindDescendent( "xform" ));
-
-            if ( thisTable != NULL )
-            {
-                thisTable->sub_tables[0].AddElement( i );
-                thisTable->sub_tables[1].AddElement( j );
-                thisTable->sub_tables[2].AddElement( k );
-                thisTable->sub_tables[3].AddElement( p );
-                thisTable->sub_tables[4].AddElement( h );
-                thisTable->sub_tables[5].AddElement( r );
-                thisTable->sub_tables[6].AddElement( x );
-                thisTable->sub_tables[7].AddElement( y );
-                thisTable->sub_tables[8].AddElement( z );
-            }
-            else
-                fprintf( outStream, "Couldn't allocate anim table\n" );
-        }
-        else
-            if ( verbose >= 2 )
-                fprintf( outStream, "Couldn't find anim group  %s\n",  name );
-    }
-    else
-    {
-        if ( verbose >= 2 )
-            fprintf( outStream, "Cannot build anim table - no skeleton\n" );
-    }
-}
-
-/**
- * Given a scene, a model , the vertices of its original shape and its name
- * find the difference between the geometry of its key shapes and the models
- * original geometry and add morph vertices to the egg data to reflect these
- * changes.
- */
-void soft2egg::
-MakeVertexOffsets( SAA_Scene *scene, SAA_Elem *model, SAA_ModelType type,
-    int numShapes, int numOrigVert, SAA_DVector *originalVerts, float
-    matrix[4][4], char *name )
-{
-    int i, j;
-    int offset;
-    int    numCV;
-    char *mTableName;
-    SAA_DVector *shapeVerts = NULL;
-    SAA_DVector *uniqueVerts = NULL;
-
-    if ( (type == SAA_MNSRF) && make_nurbs )
-        SAA_nurbsSurfaceSetStep( scene, model, nurbs_step, nurbs_step );
-
-    SAA_modelGetNbVertices( scene, model, &numCV );
-
-    // get the shape verts
-    uniqueVerts = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numCV);
-    SAA_modelGetVertices( scene, model, SAA_GEOM_ORIGINAL, 0,
-        numCV, uniqueVerts );
-
-    if ( verbose >= 2 )
-        fprintf( outStream, "%d CV's\n", numCV );
-
-    if ( verbose >= 2 )
-    {
-        for ( i = 0; i < numCV; i++ )
-            fprintf( outStream, "uniqueVerts[%d] = %f %f %f %f\n", i,
-                uniqueVerts[i].x, uniqueVerts[i].y,
-                uniqueVerts[i].z,  uniqueVerts[i].w );
-    }
-
-    // iterate through for each key shape (except original)
-    for ( i = 1; i < numShapes; i++ )
-    {
-        mTableName = MakeTableName( name, i );
-
-        if ( verbose >= 1 )
-        {
-            fprintf( outStream, "\nMaking geometry offsets for %s...\n",
-                mTableName );
-
-            if ( (type == SAA_MNSRF) && make_nurbs )
-                fprintf( outStream, "calculating NURBS morphs...\n" );
-            else
-                fprintf( outStream, "calculating triangle morphs...\n" );
-        }
-
-        // get the shape verts
-        shapeVerts = (SAA_DVector *)malloc(sizeof(SAA_DVector)*numCV);
-        SAA_modelGetVertices( scene, model, SAA_GEOM_SHAPE, i+1,
-            numCV, shapeVerts );
-
-        if ( verbose >= 2 )
-        {
-            for ( j=0; j < numCV; j++ )
-            {
-                fprintf( outStream, "shapeVerts[%d] = %f %f %f\n", j,
-                    shapeVerts[j].x, shapeVerts[j].y, shapeVerts[j].z );
-            }
-        }
-
-        // find the appropriate vertex pool
-        EggVertexPool *vPool =
-            (EggVertexPool *)(_data.pools.FindName( name ));
-
-        // for every original vertex, compare to the corresponding key shape
-        // vertex and see if a vertex offset is needed
-        for ( j=0; j < numOrigVert; j++ )
-        {
-            double    dx, dy, dz;
-
-            if ( (type == SAA_MNSRF) && make_nurbs )
-            {
-                // dx = shapeVerts[j].x -
-                // (originalVerts[j].xoriginalVerts[j].w); dy =
-                // shapeVerts[j].y - (originalVerts[j].yoriginalVerts[j].w);
-                // dz = shapeVerts[j].z -
-                // (originalVerts[j].zoriginalVerts[j].w);
-                dx = shapeVerts[j].x - originalVerts[j].x;
-                dy = shapeVerts[j].y - originalVerts[j].y;
-                dz = shapeVerts[j].z - originalVerts[j].z;
-            }
-            else
-            {
-                // we need to map from original vertices to triangle shape
-                // vertices here
-                offset = findShapeVert( originalVerts[j], uniqueVerts,
-                    numCV );
-
-                dx = shapeVerts[offset].x - originalVerts[j].x;
-                dy = shapeVerts[offset].y - originalVerts[j].y;
-                dz = shapeVerts[offset].z - originalVerts[j].z;
-            }
-
-            if ( verbose >= 2 )
-            {
-                fprintf( outStream, "oVert[%d] = %f %f %f %f\n", j,
-                    originalVerts[j].x, originalVerts[j].y,
-                    originalVerts[j].z,  originalVerts[j].w );
-
-                if ( (type == SAA_MNSRF) && make_nurbs )
-                {
-                    fprintf( outStream, "global shapeVerts[%d] = %f %f %f %f\n",                        j, shapeVerts[j].x, shapeVerts[j].y,
-                        shapeVerts[j].z, shapeVerts[j].w );
-                }
-                else
-                {
-                    fprintf( outStream,
-                        "global shapeVerts[%d] = %f %f %f\n", offset,
-                        shapeVerts[offset].x,
-                        shapeVerts[offset].y,
-                        shapeVerts[offset].z );
-                }
-
-                fprintf( outStream, "%d: dx = %f, dy = %f, dz = %f\n", j,
-                    dx, dy, dz );
-            }
-
-            // if change isn't negligible, make a morph vertex entry
-            double total = fabs(dx)+fabs(dy)+fabs(dz);
-            if ( total > 0.00001 )
-            {
-                if ( vPool != NULL )
-                {
-                    // create offset
-                    EggMorphOffset *dxyz =
-                        new EggMorphOffset( mTableName, dx, dy, dz );
-
-                    EggVertex *eggVert;
-
-                    // get the appropriate egg vertex
-                    eggVert = vPool->Vertex(j);
-
-                    // add the offset to the vertex
-                    eggVert->morphs.push_back( *dxyz );
-                }
-                else
-                    fprintf( outStream, "Error: couldn't find vertex pool %s\n", name );
-            } // if total
-        } //for j
-    } //for i
-}
-
-
-/**
- * Given a scene, a model, a name and a frame time, determine what type of
- * shape interpolation is used and call the appropriate function to extract
- * the shape weight info for this frame...
- */
-void soft2egg::
-MakeMorphTable( SAA_Scene *scene, SAA_Elem *model, SAA_Elem *models,
-    int numModels, char *name, float time )
-{
-    int         numShapes;
-    SAA_AnimInterpType    type;
-
-    // Get the number of key shapes
-    SAA_modelGetNbShapes( scene, model, &numShapes );
-
-    if ( numShapes > 0 )
-    {
-        if ( verbose >= 1 )
-            fprintf( outStream, "MakeMorphTable: %s: num shapes: %d\n",
-                name, numShapes);
-
-        SAA_modelGetShapeInterpolation( scene, model, &type );
-
-        if ( type == SAA_ANIM_LINEAR || type == SAA_ANIM_CARDINAL )
-        {
-            MakeLinearMorphTable( scene, model, numShapes, name, time );
-        }
-        else     // must be weighted...
-        {
-            // check first for expressions
-            MakeExpressionMorphTable( scene, model, models, numModels,
-                numShapes, name, time );
-        }
-
-    }
-}
-
-
-/**
- * Given a scene, a model, its name, and the time, get the shape fcurve for
- * the model and determine the shape weights for the given time and use them
- * to populate the morph table.
- */
-void soft2egg::
-MakeLinearMorphTable( SAA_Scene *scene, SAA_Elem *model, int numShapes,
-    char *name, float time )
-{
-    int            i;
-    SAA_Elem     fcurve;
-    float        curveVal;
-    SAnimTable *thisTable;
-    char          *tableName;
-
-    if ( verbose >= 1 )
-        fprintf( outStream, "linear interp, getting fcurve\n" );
-
-    SAA_modelFcurveGetShape( scene, model, &fcurve );
-
-    SAA_fcurveEval( scene, &fcurve, time, &curveVal );
-
-    if ( verbose >= 2 )
-        fprintf( outStream, "at time %f, fcurve for %s = %f\n", time,
-            name, curveVal );
-
-    float nextVal = 0.0f;
-
-    // populate morph table values for this frame
-    for ( i = 1; i < numShapes; i++ )
-    {
-        // derive table name from the model name
-        tableName = MakeTableName( name, i );
-
-        if ( verbose >= 2 )
-            fprintf( outStream, "Linear: looking for table '%s'\n", tableName );
-
-        // find the morph table associated with this key shape
-        thisTable = (SAnimTable *)(morphRoot->FindDescendent( tableName ));
-
-        if ( thisTable != NULL )
-        {
-            if ( i == (int)curveVal )
-            {
-                if ( curveVal - i == 0 )
-                {
-                    thisTable->AddElement( 1.0f );
-                    if ( verbose >= 2 )
-                        fprintf( outStream, "adding element 1.0f\n" );
-                }
-                else
-                {
-                    thisTable->AddElement( 1.0f - (curveVal - i) );
-                    nextVal = curveVal - i;
-                    if ( verbose >= 2 )
-                        fprintf( outStream, "adding element %f\n",                                                 1.0f - (curveVal - i) );
-                }
-            }
-            else
-            {
-                if ( nextVal )
-                {
-                    thisTable->AddElement( nextVal );
-                    nextVal = 0.0f;
-                    if ( verbose >= 2 )
-                        fprintf( outStream, "adding element %f\n", nextVal );
-                }
-                else
-                {
-                    thisTable->AddElement( 0.0f );
-                    if ( verbose >= 2 )
-                        fprintf( outStream, "adding element 0.0f\n" );
-                }
-            }
-
-            if ( verbose >= 2 )
-                fprintf( outStream, " to '%s'\n", tableName );
-        }
-        else
-            fprintf( outStream, "%d: Couldn't find table '%s'\n",
-                i, tableName );
-    }
-
-}
-
-/**
- * Given a scene, a model, a list of all models in the scene, the number of
- * models in the scece, the number of key shapes for this model, the name of
- * the model and the current time, determine what method of controlling the
- * shape weights is used and call the appropriate routine.
- */
-void soft2egg::
-MakeWeightedMorphTable( SAA_Scene *scene, SAA_Elem *model, SAA_Elem *models,
-    int numModels,  int numShapes, char *name, float time )
-{
-    SI_Error     result;
-    SAA_Elem    *weightCurves;
-    float         curveVal;
-    SAnimTable *thisTable;
-    char          *tableName;
-
-    // allocate array of weight curves (one for each shape)
-    weightCurves = ( SAA_Elem *)malloc( sizeof( SAA_Elem ) * numShapes );
-
-    result = SAA_modelFcurveGetShapeWeights(
-        scene, model, numShapes, weightCurves );
-
-    if ( result == SI_SUCCESS )
-    {
-        for ( int i = 1; i < numShapes; i++ )
-        {
-                                                SAA_fcurveEval( scene, &weightCurves[i], time, &curveVal );
-
-                                                // make sure soft gave us a
-                                                // reasonable number
-                                                if (!isNum(curveVal))
-                                                        curveVal = 0.0f;
-
-                                                if ( verbose >= 2 )
-                                                                fprintf( outStream, "at time %f, weightCurve[%d] for %s = %f\n",                     time, i, name, curveVal );
-
-
-            // derive table name from the model name
-            tableName = MakeTableName( name, i );
-
-                                                // find and populate shape
-                                                // table
-            if ( verbose >= 2 )
-                fprintf( outStream, "Weight: looking for table '%s'\n",
-                                                                tableName );
-
-            // find the morph table associated with this key shape
-            thisTable = (SAnimTable *)(morphRoot->FindDescendent( tableName ));
-
-            if ( thisTable != NULL )
-            {
-                thisTable->AddElement( curveVal );
-                if ( verbose >= 2 )
-                    fprintf( outStream, "adding element %f\n", curveVal );
-            }
-            else
-                fprintf( outStream, "%d: Couldn't find table '%s'\n",
-                    i, tableName );
-        }
-    }
-}
-
-
-/**
- * Given a scene, a model and its number of key shapes generate a morph table
- * describing transitions btwn the key shapes by evaluating the positions of
- * the controlling sliders.
- */
-void soft2egg::
-MakeExpressionMorphTable( SAA_Scene *scene, SAA_Elem *model, SAA_Elem *models,
-    int numModels,  int numShapes, char *name, float time )
-{
-    int            j;
-    SAnimTable *thisTable;
-    char          *tableName;
-    char          *sliderName;
-    char        *track;
-    int            numExp;
-    SAA_Elem   *expressions;
-    float        expVal;
-    float        sliderVal;
-
-    // populate morph table values for this frame
-
-    // compose track name
-    track = NULL;
-
-    // find how many expressions for this shape
-    SAA_elementGetNbExpressions( scene, model, track, FALSE, &numExp );
-
-    if ( verbose >= 2 )
-        fprintf( outStream, "%s has %d RHS expressions\n", name, numExp );
-
-    if ( numExp )
-    {
-        // get the expressions for this shape
-        expressions = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numExp);
-
-        if ( verbose >= 1 )
-            fprintf( outStream, "getting %d RHS expressions...\n", numExp );
-
-        result = SAA_elementGetExpressions( scene, model, track, FALSE,
-            numExp, expressions );
-
-        if ( !result )
-        {
-            for ( j = 1; j < numExp; j++ )
-            {
-                if ( verbose >= 2 )
-                {
-                // debug see what we got
-                int numvars;
-
-                SAA_expressionGetNbVars( scene, &expressions[j], &numvars );
-
-                int *varnamelen;
-                int *varstrlen;
-                int  expstrlen;
-
-                varnamelen = (int *)malloc(sizeof(int)*numvars);
-                varstrlen = (int *)malloc(sizeof(int)*numvars);
-
-                SAA_expressionGetStringLengths( scene, &expressions[j],
-                    numvars, varnamelen, varstrlen, &expstrlen );
-
-                int *varnamesizes;
-                int *varstrsizes;
-
-                varnamesizes = (int *)malloc(sizeof(int)*numvars);
-                varstrsizes = (int *)malloc(sizeof(int)*numvars);
-
-                for ( int k = 0; k < numvars; k++ )
-                {
-                    varnamesizes[k] = varnamelen[k] + 1;
-                    varstrsizes[k] = varstrlen[k] + 1;
-                }
-
-                int expstrsize = expstrlen + 1;
-
-                char **varnames;
-                char **varstrs;
-
-                varnames = (char **)malloc(sizeof(char *)*numvars);
-                varstrs = (char **)malloc(sizeof(char *)*numvars);
-
-                for ( k = 0; k < numvars; k++ )
-                {
-                    varnames[k] = (char *)malloc(sizeof(char)*
-                        varnamesizes[k]);
-
-                    varstrs[k] = (char *)malloc(sizeof(char)*
-                        varstrsizes[k]);
-                }
-
-                char *expstr = (char *)malloc(sizeof(char)* expstrsize );
-
-                SAA_expressionGetStrings( scene, &expressions[j], numvars,
-                    varnamesizes, varstrsizes, expstrsize, varnames,
-                    varstrs, expstr );
-
-                if ( verbose >= 2 )
-                {
-                    fprintf( outStream, "expression = '%s'\n", expstr );
-                    fprintf( outStream, "has %d variables\n", numvars );
-                }
-                } //if verbose
-
-                if ( verbose >= 2 )
-                    fprintf( outStream, "evaling expression...\n" );
-
-                SAA_expressionEval( scene, &expressions[j], time, &expVal );
-
-                if ( verbose >= 2 )
-                    fprintf( outStream, "time %f: exp val %f\n",
-                        time, expVal );
-
-                // derive table name from the model name
-                tableName = MakeTableName( name, j );
-
-                if ( verbose >= 2 )
-                    fprintf( outStream, "Exp: looking for table '%s'\n",
-                        tableName );
-
-                // find the morph table associated with this key shape
-                thisTable = (SAnimTable *)
-                    (morphRoot->FindDescendent( tableName ));
-
-                if ( thisTable != NULL )
-                {
-                    thisTable->AddElement( expVal );
-                    if ( verbose >= 1 )
-                        fprintf( outStream, "%d: adding element %f to %s\n",
-                            j, expVal, tableName );
-                    fflush( outStream );
-                }
-                else
-                {
-                    fprintf( outStream, "%d: Couldn't find table '%s'", j,
-                            tableName );
-
-                    fprintf( outStream, " for value %f\n", expVal );
-                }
-            }
-        }
-        else
-            fprintf( outStream, "couldn't get expressions!!!\n" );
-    }
-    else
-        // no expression, use weight curves
-        MakeWeightedMorphTable( scene, model, models, numModels,
-            numShapes, name, time );
-
-}
-
-
-/**
- * Given a scene, a POLYGON model, and the name of the that model, get the u
- * and v offsets for the current frame.
- */
-void soft2egg::
-MakeTexAnim( SAA_Scene *scene, SAA_Elem *model, char *modelName )
-{
-    if ( verbose >= 1 )
-        fprintf( outStream, "\n\nmaking texture animation for %s...\n",
-            modelName );
-
-    // get the color of the surface
-    int         numMats;
-    pfVec4        Color;
-    SAA_Elem    *materials;
-    void        *relinfo;
-
-    SAA_modelRelationGetMatNbElements( scene, model, FALSE, &relinfo,
-        &numMats );
-
-    if ( verbose >= 2 )
-        fprintf( outStream, "surface has %d materials\n", numMats );
-
-    if ( numMats )
-    {
-        float r,g,b,a;
-
-        materials = (SAA_Elem *)malloc(sizeof(SAA_Elem)*numMats);
-
-        SAA_modelRelationGetMatElements( scene, model, relinfo,
-            numMats, materials );
-
-        SAA_materialGetDiffuse( scene, &materials[0], &r, &g, &b );
-        SAA_materialGetTransparency( scene, &materials[0], &a );
-        Color.set( r, g, b, 1.0f - a );
-
-        int numTexLoc = 0;
-        int numTexGlb = 0;
-
-        // ASSUME only one texture per material
-        SAA_Elem tex;
-
-        // find out how many local textures per surface ASSUME it only has one
-        // material
-        SAA_materialRelationGetT2DLocNbElements( scene, &materials[0],
-            FALSE, &relinfo, &numTexLoc );
-
-        // if present, get local textures
-        if ( numTexLoc )
-        {
-            if ( verbose >= 1 )
-                fprintf( outStream, "%s had %d local tex\n", modelName,
-                    numTexLoc );
-
-            // get the referenced texture
-            SAA_materialRelationGetT2DLocElements( scene, &materials[0],
-                TEX_PER_MAT, &tex );
-
-        }
-        // if no locals, try to get globals
-        else
-        {
-            SAA_modelRelationGetT2DGlbNbElements( scene, model,
-                FALSE, &relinfo, &numTexGlb );
-
-            if ( numTexGlb )
-            {
-                if ( verbose >= 1 )
-                    fprintf( outStream, "%s had %d global tex\n", modelName, numTexGlb );
-
-                // get the referenced texture
-                SAA_modelRelationGetT2DGlbElements( scene,
-                    model, TEX_PER_MAT, &tex );
-            }
-        }
-
-        // add tex ref's if we found any textures
-        if ( numTexLoc || numTexGlb)
-        {
-            char    *fullTexName = NULL;
-            char    *texName = NULL;
-            char    *uniqueTexName = NULL;
-            int      texNameLen;
-
-            // get its name
-            SAA_texture2DGetPicNameLength( scene, &tex, &texNameLen);
-            fullTexName = (char *)malloc(sizeof(char)*++texNameLen);
-            SAA_texture2DGetPicName( scene, &tex, texNameLen,
-                fullTexName );
-
-            // append unique identifier to texname for this particular object
-            uniqueTexName = (char *)malloc(sizeof(char)*
-                (strlen(modelName)+strlen(texName)+3) );
-            sprintf( uniqueTexName, "%s-%s", modelName, texName );
-            if ( verbose >= 2 )
-                fprintf( outStream, "referencing tref %s\n",
-                    uniqueTexName );
-
-            float uScale;
-            float vScale;
-            float uOffset;
-            float vOffset;
-            SAA_Boolean    uv_swap = FALSE;
-
-            // get texture offset info
-            SAA_texture2DGetUScale( scene, &tex, &uScale );
-            SAA_texture2DGetVScale( scene, &tex, &vScale );
-            SAA_texture2DGetUOffset( scene, &tex, &uOffset );
-            SAA_texture2DGetVOffset( scene, &tex, &vOffset );
-            SAA_texture2DGetUVSwap( scene, &tex, &uv_swap );
-
-
-            if ( verbose >= 2 )
-            {
-                fprintf( outStream, "tex uScale: %f\n", uScale );
-                fprintf( outStream, "tex vScale: %f\n", vScale );
-                fprintf( outStream, "tex uOffset: %f\n", uOffset );
-                fprintf( outStream, "tex vOffset: %f\n", vOffset );
-                if ( uv_swap )
-                    fprintf( outStream, "nurbTex u & v swapped!\n" );
-                else
-                    fprintf( outStream, "nurbTex u & v NOT swapped\n" );
-            }
-
-
-            // find the vpool for this model
-            EggVertexPool *vPool =
-                (EggVertexPool *)(_data.pools.FindName( modelName ));
-
-            // if we found the pool
-            if ( vPool != NULL )
-            {
-                // generate duv's for model
-                float oldOffsets[4];
-                double u, v, du, dv;
-                int        size;
-                SAA_Boolean bigEndian;
-
-                SAA_elementGetUserDataSize( scene, model, "TEX_OFFSETS",                                 &size );
-
-                if ( size != 0 )
-                {
-                    // remember original texture offsets future reference
-                    SAA_elementGetUserData( scene, model, "TEX_OFFSETS",
-                        size, &bigEndian, (void *)&oldOffsets );
-
-                    // get the original scales and offsets
-                    u = oldOffsets[0];
-                    v = oldOffsets[1];
-
-                    du = u - uOffset;
-                    dv = v - vOffset;
-
-                    if ( verbose >= 1 )
-                    {
-                        fprintf( outStream, "original u = %f, v = %f\n",
-                            u, v );
-                        fprintf( outStream, "u = %f, v = %f\n",
-                            uOffset, vOffset );
-                        fprintf( outStream, "du = %f, dv = %f\n",
-                            du, dv );
-                    }
-
-                    strstream uName, vName;
-
-                    // create duv target names
-                    uName << modelName << ".u" << ends;
-                    vName << modelName << ".v" << ends;
-
-                    // find the appropriate table to store the duv animation
-                    // info into
-                    SAnimTable *thisTable;
-
-                    // find the duv U table associated with this model
-                    thisTable = (SAnimTable *)(morphRoot->FindDescendent(
-                        uName.str() ));
-
-                    if ( thisTable != NULL )
-                    {
-                        thisTable->AddElement( du );
-                        if ( verbose >= 1 )
-                            fprintf( outStream, "adding element %f to %s\n",
-                                du, uName.str() );
-                    }
-                    else
-                        fprintf( outStream, "Couldn't find uTable %s\n",
-                            uName.str() );
-
-                    // find the duv V table associated with this model
-                    thisTable = (SAnimTable *)(morphRoot->FindDescendent(
-                        vName.str() ));
-
-                    if ( thisTable != NULL )
-                    {
-                        thisTable->AddElement( dv );
-                        if ( verbose >= 1 )
-                            fprintf( outStream, "adding element %f to %s\n",
-                                dv, uName.str() );
-                    }
-                    else
-                        fprintf( outStream, "Couldn't find vTable %s\n",
-                            uName.str() );
-                }
-            }
-            else
-                if ( verbose >= 2 )
-                    fprintf( outStream, "Couldn't find vpool %s\n", modelName );
-        }
-
-        // free( materials );
-    }
-}
-#endif
-
-/**
- * Instantiate converter and process a file
- */
-EXPCL_MISC SI_Error soft2egg(int argc, char *argv[]) {
-  // pass control to the c++ system
-  init_soft2egg(argc, argv);
-  return SI_SUCCESS;
-}
-#ifdef __cplusplus
-}
-#endif

+ 0 - 44
pandatool/src/softegg/softEggGroupUserData.I

@@ -1,44 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file softEggGroupUserData.I
- * @author masad
- * @date 2003-09-25
- */
-
-/**
- *
- */
-INLINE SoftEggGroupUserData::
-SoftEggGroupUserData() {
-  _vertex_color = false;
-  _double_sided = false;
-}
-
-
-/**
- *
- */
-INLINE SoftEggGroupUserData::
-SoftEggGroupUserData(const SoftEggGroupUserData &copy) :
-  EggUserData(copy),
-  _vertex_color(copy._vertex_color),
-  _double_sided(copy._double_sided)
-{
-}
-
-
-/**
- *
- */
-INLINE void SoftEggGroupUserData::
-operator = (const SoftEggGroupUserData &copy) {
-  EggUserData::operator = (copy);
-  _vertex_color = copy._vertex_color;
-  _double_sided = copy._double_sided;
-}

+ 0 - 16
pandatool/src/softegg/softEggGroupUserData.cxx

@@ -1,16 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file softEggGroupUserData.cxx
- * @author masad
- * @date 2003-09-25
- */
-
-#include "softEggGroupUserData.h"
-
-TypeHandle SoftEggGroupUserData::_type_handle;

+ 0 - 53
pandatool/src/softegg/softEggGroupUserData.h

@@ -1,53 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file softEggGroupUserData.h
- * @author masad
- * @date 2003-09-25
- */
-
-#ifndef SOFTEGGGROUPUSERDATA_H
-#define SOFTEGGGROUPUSERDATA_H
-
-#include "pandatoolbase.h"
-#include "eggUserData.h"
-
-/**
- * This class contains extra user data which is piggybacked onto EggGroup
- * objects for the purpose of the softimage converter.
- */
-class SoftEggGroupUserData : public EggUserData {
-public:
-  INLINE SoftEggGroupUserData();
-  INLINE SoftEggGroupUserData(const SoftEggGroupUserData &copy);
-  INLINE void operator = (const SoftEggGroupUserData &copy);
-
-  bool _vertex_color;
-  bool _double_sided;
-
-public:
-  static TypeHandle get_class_type() {
-    return _type_handle;
-  }
-  static void init_type() {
-    EggUserData::init_type();
-    register_type(_type_handle, "SoftEggGroupUserData",
-                  EggUserData::get_class_type());
-  }
-  virtual TypeHandle get_type() const {
-    return get_class_type();
-  }
-  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
-
-private:
-  static TypeHandle _type_handle;
-};
-
-#include "softEggGroupUserData.I"
-
-#endif

+ 0 - 1310
pandatool/src/softegg/softNodeDesc.cxx

@@ -1,1310 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file softNodeDesc.cxx
- * @author masad
- * @date 2003-10-03
- */
-
-#include "softNodeDesc.h"
-#include "config_softegg.h"
-#include "eggGroup.h"
-#include "eggXfmSAnim.h"
-#include "eggSAnimData.h"
-#include "softToEggConverter.h"
-#include "dcast.h"
-
-using std::endl;
-
-TypeHandle SoftNodeDesc::_type_handle;
-
-/**
- *
- */
-SoftNodeDesc::
-SoftNodeDesc(SoftNodeDesc *parent, const std::string &name) :
-  Namable(name),
-  _parent(parent)
-{
-  _model = nullptr;
-  _egg_group = nullptr;
-  _egg_table = nullptr;
-  _anim = nullptr;
-  _joint_type = JT_none;
-
-  // Add ourselves to our parent.
-  if (_parent != nullptr) {
-    softegg_cat.spam() << "parent name " << _parent->get_name();
-    _parent->_children.push_back(this);
-  }
-
-  // set the _parentJoint to Null
-  _parentJoint = nullptr;
-
-  fullname = nullptr;
-
-  numTexLoc = 0;
-  numTexGlb = 0;
-
-  uScale = nullptr;
-  vScale = nullptr;
-  uOffset = nullptr;
-  vOffset = nullptr;
-
-  valid;
-  uv_swap;
-  // SAA_Boolean visible;
-  numTexTri = nullptr;
-  textures = nullptr;
-  materials = nullptr;
-  triangles = nullptr;
-  gtype = SAA_GEOM_ORIGINAL;
-}
-
-/**
- *
- */
-SoftNodeDesc::
-~SoftNodeDesc() {
-  // I think it is a mistake to try to delete this.  This was one member of an
-  // entire array allocated at once; you can't delete individual elements of
-  // an array.
-
-  // Screw cleanup, anyway--we'll just let the array leak.
-  /*
-  if (_model != (SAA_Elem *)NULL) {
-    delete _model;
-  }
-  */
-}
-
-/**
- * Indicates an associated between the SoftNodeDesc and some SAA_Elem
- * instance.
- */
-void SoftNodeDesc::
-set_model(SAA_Elem *model) {
-  _model = model;
-}
-
-/**
- * Sometimes, parent is not known at node creation As soon as it is known, set
- * the parent
- */
-void SoftNodeDesc::
-set_parent(SoftNodeDesc *parent) {
-  if (_parent) {
-    softegg_cat.spam() << endl;
-    /*
-    softegg_cat.spam() << " expected _parent to be null!?\n";
-    if (_parent == parent)
-      softegg_cat.spam() << " parent already set\n";
-    else {
-      softegg_cat.spam() << " current parent " << _parent->get_name() << " new parent "
-           << parent << endl;
-    }
-    */
-    return;
-  }
-  _parent = parent;
-  softegg_cat.spam() << " set parent to " << _parent->get_name() << endl;
-
-  // Add ourselves to our parent.
-  _parent->_children.push_back(this);
-}
-
-/**
- * Sometimes, parent is not known at node creation As soon as it is known, set
- * the parent
- */
-void SoftNodeDesc::
-force_set_parent(SoftNodeDesc *parent) {
-  if (_parent)
-    softegg_cat.spam() << " current parent " << _parent->get_name();
-
-  _parent = parent;
-
-  if (_parent)
-    softegg_cat.spam() << " new parent " << _parent->get_name() << endl;
-
-  // Add ourselves to our parent.
-  _parent->_children.push_back(this);
-}
-
-/**
- * Returns true if a Soft dag path has been associated with this node, false
- * otherwise.
- */
-bool SoftNodeDesc::
-has_model() const {
-  return (_model != nullptr);
-}
-
-/**
- * Returns the SAA_Elem * associated with this node.  It is an error to call
- * this unless has_model() returned true.
- */
-SAA_Elem *SoftNodeDesc::
-get_model() const {
-  nassertr(_model != nullptr, _model);
-  return _model;
-}
-
-/**
- * Returns true if the node should be treated as a joint by the converter.
- */
-bool SoftNodeDesc::
-is_joint() const {
-  // return _joint_type == JT_joint || _joint_type == JT_pseudo_joint;
-  return _joint_type == JT_joint;
-}
-
-/**
- * Returns true if the node should be treated as a junk by the converter.
- */
-bool SoftNodeDesc::
-is_junk() const {
-  return _joint_type == JT_junk;
-}
-
-/**
- * sets the _joint_type to JT_joint
- */
-void SoftNodeDesc::
-set_joint() {
-  _joint_type = JT_joint;
-}
-/**
- * Returns true if the node is the parent or ancestor of a joint.
- */
-bool SoftNodeDesc::
-is_joint_parent() const {
-  return _joint_type == JT_joint_parent;
-}
-
-/**
- * Recursively clears the egg pointers from this node and all children.
- */
-void SoftNodeDesc::
-clear_egg() {
-  _egg_group = nullptr;
-  _egg_table = nullptr;
-  _anim = nullptr;
-
-  Children::const_iterator ci;
-  for (ci = _children.begin(); ci != _children.end(); ++ci) {
-    SoftNodeDesc *child = (*ci);
-    child->clear_egg();
-  }
-}
-
-/**
- * Indicates that this node has at least one child that is a joint or a
- * pseudo-joint.
- */
-void SoftNodeDesc::
-mark_joint_parent() {
-  if (_joint_type == JT_none) {
-    _joint_type = JT_joint_parent;
-    softegg_cat.spam() << " marked parent " << get_name();
-  }
-  else
-    softegg_cat.spam() << " ?parent " << get_name() << " joint type " << _joint_type;
-
-  if (_parent != nullptr) {
-    _parent->mark_joint_parent();
-  }
-  softegg_cat.spam() << endl;
-}
-
-/**
- * Walks the hierarchy, if a node is joint, make sure all its parents are
- * marked JT_joint_parent
- */
-void SoftNodeDesc::
-check_joint_parent() {
-  Children::const_iterator ci;
-  for (ci = _children.begin(); ci != _children.end(); ++ci) {
-    SoftNodeDesc *child = (*ci);
-    if (child->is_joint()) {
-      softegg_cat.spam() << "child " << child->get_name();
-      mark_joint_parent();
-    }
-    child->check_joint_parent();
-  }
-}
-
-/**
- * check to see if this is a branch we don't want to descend - this will
- * prevent creating geometry for animation control structures
- */
-void SoftNodeDesc::
-check_junk(bool parent_junk) {
-  const char *name = get_name().c_str();
-
-  if (parent_junk) {
-    _joint_type = JT_junk;
-    softegg_cat.spam() << "junk node " << get_name() << endl;
-  }
-  if ( (strstr(name, "con-") != nullptr) ||
-       (strstr(name, "con_") != nullptr) ||
-       (strstr(name, "fly_") != nullptr) ||
-       (strstr(name, "fly-") != nullptr) ||
-       (strstr(name, "camRIG") != nullptr) ||
-       (strstr(name, "cam_rig") != nullptr) ||
-       (strstr(name, "bars") != nullptr) )
-    {
-      _joint_type = JT_junk;
-      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);
-        softegg_cat.spam() << child->get_name() << ",";
-      }
-      softegg_cat.spam() << endl;
-    }
-  Children::const_iterator ci;
-  for (ci = _children.begin(); ci != _children.end(); ++ci) {
-    SoftNodeDesc *child = (*ci);
-    child->check_junk(parent_junk);
-  }
-}
-
-/**
- * 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) != nullptr) {
-    softegg_cat.debug() << "matched " << name << " ";
-    return false;
-  }
-  // if name is not search_prefix, look in its parent
-  if (strstr(name, search_prefix) == nullptr) {
-    softegg_cat.debug() << "node " << name << " ";
-    if (_parent)
-      return _parent->is_partial(search_prefix);
-  }
-  // neither name nor its parent is search_prefix
-  return true;
-}
-
-/**
- * Go through the ancestors and figure out who is the immediate _parentJoint
- * of this node
- */
-void SoftNodeDesc::
-set_parentJoint(SAA_Scene *scene, SoftNodeDesc *lastJoint) {
-  if (is_junk())
-    return;
-  // set its parent joint to the lastJoint
-  _parentJoint = lastJoint;
-  softegg_cat.spam() << get_name() << ": parent joint set to :" << lastJoint;
-  if (lastJoint)
-    softegg_cat.spam() << "(" << lastJoint->get_name() << ")";
-  softegg_cat.spam() << endl;
-
-  // is this node a joint?
-  SAA_Boolean isSkeleton = false;
-  if (has_model())
-    SAA_modelIsSkeleton( scene, get_model(), &isSkeleton );
-
-  // if  already a joint or name has "joint" in it
-  const char *name = get_name().c_str();
-  if (is_joint() || isSkeleton || strstr(name, "joint") != nullptr) {
-    lastJoint = this;
-  }
-  if ( _parentJoint && strstr( _parentJoint->get_name().c_str(), "scale" ) != nullptr ) {
-    // make sure _parentJoint didn't have the name "joint" in it
-    if (strstr(_parentJoint->get_name().c_str(), "joint") == nullptr) {
-      _parentJoint = nullptr;
-      // _parentJoint = lastJoint = NULL;
-      softegg_cat.spam() << "scale joint flag set!\n";
-    }
-  }
-
-  // look in the children
-  Children::const_iterator ci;
-  for (ci = _children.begin(); ci != _children.end(); ++ci) {
-    SoftNodeDesc *child = (*ci);
-    child->set_parentJoint(scene, lastJoint);
-  }
-}
-
-/**
- * Walks the hierarchy, looking for non-joint nodes that are both children and
- * parents of a joint.  These nodes are deemed to be pseudo joints, since the
- * converter must treat them as joints.
- */
-void SoftNodeDesc::
-check_pseudo_joints(bool joint_above) {
-  if (_joint_type == JT_joint_parent && joint_above) {
-    // This is one such node: it is the parent of a joint (JT_joint_parent is
-    // set), and it is the child of a joint (joint_above is set).
-    _joint_type = JT_pseudo_joint;
-    softegg_cat.debug() << "pseudo " << get_name() << " case1\n";
-  }
-
-  if (_joint_type == JT_joint) {
-    // If this node is itself a joint, then joint_above is true for all child
-    // nodes.
-    joint_above = true;
-  }
-
-  // Don't bother traversing further if _joint_type is none or junk, since
-  // that means this node has no joint children.
-  if (_joint_type != JT_none && _joint_type != JT_junk) {
-
-    bool any_joints = false;
-    Children::const_iterator ci;
-    for (ci = _children.begin(); ci != _children.end(); ++ci) {
-      SoftNodeDesc *child = (*ci);
-      child->check_pseudo_joints(joint_above);
-      if (child->is_joint()) {
-        softegg_cat.spam() << get_name() << " any_joint true by " << child->get_name() << endl;
-        any_joints = true;
-      }
-    }
-
-    // If any children qualify as joints, then any sibling nodes that are
-    // parents of joints are also elevated to joints.
-    if (any_joints) {
-      bool all_joints = true;
-      for (ci = _children.begin(); ci != _children.end(); ++ci) {
-        SoftNodeDesc *child = (*ci);
-        if (child->_joint_type == JT_joint_parent) {
-          child->_joint_type = JT_pseudo_joint;
-          softegg_cat.debug() << "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;
-        }
-      }
-
-      if (all_joints || any_joints) {
-        // 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;
-          softegg_cat.debug() << "pseudo " << get_name() << " case3\n";
-        }
-      }
-    }
-  }
-  else
-    softegg_cat.spam() << "found null joint " << get_name() << endl;
-}
-
-/**
- * Extracts the transform on the indicated Soft node, and applies it to the
- * corresponding Egg node.
- */
-void SoftNodeDesc::
-get_transform(SAA_Scene *scene, EggGroup *egg_group, bool global) {
-  // Get the model's matrix
-  int scale_joint = 0;
-
-  if (!global && _parentJoint && !stec.flatten && !scale_joint) {
-
-    SAA_modelGetMatrix( scene, get_model(), SAA_COORDSYS_LOCAL,  matrix );
-    softegg_cat.debug() << get_name() << " using local matrix :parent ";
-
-  } else {
-
-    SAA_modelGetMatrix( scene, get_model(), SAA_COORDSYS_GLOBAL,  matrix );
-    softegg_cat.debug() << get_name() << " using global matrix :parent ";
-
-  }
-
-  if (_parentJoint && !stec.flatten)
-    softegg_cat.debug() << _parentJoint->get_name() << endl;
-  else
-    softegg_cat.debug() << _parentJoint << endl;
-
-
-  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],
-                  matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],
-                  matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],
-                  matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]);
-    if (!m4d.almost_equal(LMatrix4d::ident_mat(), 0.0001)) {
-      egg_group->set_transform3d(m4d);
-      softegg_cat.spam() << "set transform in egg_group\n";
-    }
-  }
-  return;
-}
-
-/**
- * Extracts the transform on the indicated Soft node, as appropriate for a
- * joint in an animated character, and applies it to the indicated node.  This
- * is different from get_transform() in that it does not respect the
- * _transform_type flag, and it does not consider the relative transforms
- * within the egg file.  more added functionality: now fills in components of
- * anim (EffXfmSAnim) class (masad).
- */
-void SoftNodeDesc::
-get_joint_transform(SAA_Scene *scene,  EggGroup *egg_group, EggXfmSAnim *anim, bool global) {
-  // SI_Error result;
-  SAA_Elem *skeletonPart = _model;
-  const char *name = get_name().c_str();
-
-  if ( skeletonPart != nullptr ) {
-    PN_stdfloat i,j,k;
-    PN_stdfloat h,p,r;
-    PN_stdfloat x,y,z;
-    int scale_joint = 0;
-
-    softegg_cat.spam() << "\n\nanimating child " << name << endl;
-
-    if (_parentJoint && !stec.flatten && !scale_joint ) {
-      softegg_cat.debug() << "using local matrix\n";
-
-      // get SAA orientation
-      SAA_modelGetRotation( scene, skeletonPart, SAA_COORDSYS_LOCAL,
-                            &p, &h, &r );
-
-      // get SAA translation
-      SAA_modelGetTranslation( scene, skeletonPart, SAA_COORDSYS_LOCAL,
-                               &x, &y, &z );
-
-      // get SAA scaling
-      SAA_modelGetScaling( scene, skeletonPart, SAA_COORDSYS_LOCAL,
-                           &i, &j, &k );
-    } else {
-      softegg_cat.debug() << " using global matrix\n";
-
-      // get SAA orientation
-      SAA_modelGetRotation( scene, skeletonPart, SAA_COORDSYS_GLOBAL,
-                            &p, &h, &r );
-
-      // get SAA translation
-      SAA_modelGetTranslation( scene, skeletonPart, SAA_COORDSYS_GLOBAL,
-                               &x, &y, &z );
-
-      // get SAA scaling
-      SAA_modelGetScaling( scene, skeletonPart, SAA_COORDSYS_GLOBAL,
-                           &i, &j, &k );
-    }
-
-    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;
-
-    // Encode the component multiplication ordering in the egg file.
-    // SoftImage always uses this order, regardless of the setting of temp-
-    // hpr-fix.
-    anim->set_order("sphrt");
-
-    // Add each component by their names
-    anim->add_component_data("i", i);
-    anim->add_component_data("j", j);
-    anim->add_component_data("k", k);
-    anim->add_component_data("p", p);
-    anim->add_component_data("h", h);
-    anim->add_component_data("r", r);
-    anim->add_component_data("x", x);
-    anim->add_component_data("y", y);
-    anim->add_component_data("z", z);
-  }
-  else {
-    softegg_cat.debug() << "Cannot build anim table - no skeleton\n";
-  }
-}
-
-/**
- * Converts the indicated Soft polyset to a bunch of EggPolygons and parents
- * them to the indicated egg group.
- */
-void SoftNodeDesc::
-load_poly_model(SAA_Scene *scene, SAA_ModelType type) {
-  SI_Error result;
-  const char *name = get_name().c_str();
-
-  int i;
-  int id = 0;
-
-  // if making a pose - get deformed geometry
-  if ( stec.make_pose )
-    gtype = SAA_GEOM_DEFORMED;
-
-  // 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);
-  softegg_cat.spam() << "triangles: " << numTri << "\n";
-
-  if ( result != SI_SUCCESS ) {
-    softegg_cat.spam() << "Error: couldn't get number of triangles!\n";
-    softegg_cat.debug() << "\tbailing on model: " << name << "\n";
-    return;
-  }
-
-  // check to see if surface is also skeleton...
-  SAA_Boolean isSkeleton = FALSE;
-
-  SAA_modelIsSkeleton( scene, _model, &isSkeleton );
-
-  // check to see if this surface is used as a skeleton or is animated via
-  // constraint only ( these nodes are tagged by the animator with the keyword
-  // "joint" somewhere in the nodes name)
-  softegg_cat.spam() << "is Skeleton? " << isSkeleton << "\n";
-
-  /*************************************************************************************/
-
-  // model is not a null and has no triangles!
-  if ( !numTri ) {
-    softegg_cat.spam() << "no triangles!\n";
-  }
-  else {
-    // allocate array of triangles
-    triangles = (SAA_SubElem *) new SAA_SubElem[numTri];
-    if (!triangles) {
-      softegg_cat.info() << "Not enough Memory for triangles...\n";
-      exit(1);
-    }
-    // triangulate model and read the triangles into array
-    SAA_modelGetTriangles( scene, _model, gtype, id, numTri, triangles );
-    softegg_cat.spam() << "got triangles\n";
-
-    /***********************************************************************************/
-
-    // allocate array of materials (Asad: it gives a warning if try to get one
-    // triangle at a time...investigate later read each triangle's material
-    // into array
-    materials = (SAA_Elem*) new SAA_Elem[numTri];
-    SAA_triangleGetMaterials( scene, _model, numTri, triangles, materials );
-    if (!materials) {
-      softegg_cat.info() << "Not enough Memory for materials...\n";
-      exit(1);
-    }
-    softegg_cat.spam() << "got materials\n";
-
-    /***********************************************************************************/
-
-    // allocate array of textures per triangle
-    numTexTri = new int[numTri];
-    const void *relinfo;
-
-    // find out how many local textures per triangle
-    for (i = 0; i < numTri; i++) {
-      result = SAA_materialRelationGetT2DLocNbElements( scene, &materials[i], FALSE,
-                                                        &relinfo, &numTexTri[i] );
-      // polytex
-      if ( result == SI_SUCCESS )
-        numTexLoc += numTexTri[i];
-    }
-
-    // don't need this anymore... free( numTexTri );
-
-    // get local textures if present
-    if ( numTexLoc ) {
-      softegg_cat.spam() << "numTexLoc = " << numTexLoc << endl;
-
-      // allocate arrays of texture info
-      uScale = new PN_stdfloat[numTri];
-      vScale = new PN_stdfloat[numTri];
-      uOffset = new PN_stdfloat[numTri];
-      vOffset = new PN_stdfloat[numTri];
-      texNameArray = new char *[numTri];
-      uRepeat = new int[numTri];
-      vRepeat = new int[numTri];
-
-      // ASSUME only one texture per material
-      textures = new SAA_Elem[numTri];
-
-      for ( i = 0; i < numTri; i++ ) {
-        // and read all referenced local textures into array
-        SAA_materialRelationGetT2DLocElements( scene, &materials[i],
-                                               TEX_PER_MAT , &textures[i] );
-
-        // initialize the array value
-        texNameArray[i] = nullptr;
-        // initialize the repeats
-        uRepeat[i] = vRepeat[i] = 0;
-
-        // see if this triangle has texture info
-        if (numTexTri[i] == 0)
-          continue;
-
-        // check to see if texture is present
-        result = SAA_elementIsValid( scene, &textures[i], &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[i] = stec.GetTextureName(scene, &textures[i]);
-
-          softegg_cat.spam() << " tritex[" << i << "] named: " << texNameArray[i] << endl;
-
-          SAA_texture2DGetUVSwap( scene, &textures[i], &uv_swap );
-
-          if ( uv_swap == TRUE )
-            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] );
-
-          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[i], &vRepeat[i] );
-          softegg_cat.spam() << "uRepeat = " << uRepeat[i] << ", vRepeat = " << vRepeat[i] << endl;
-        }
-        else {
-          softegg_cat.spam() << "Invalid texture...\n";
-          softegg_cat.spam() << " tritex[" << i << "] named: (null)\n";
-        }
-      }
-    }
-    else { // if no local textures, try to get global textures
-      SAA_modelRelationGetT2DGlbNbElements( scene, _model,
-                                            FALSE, &relinfo, &numTexGlb );
-      if ( numTexGlb ) {
-        // ASSUME only one texture per model
-        textures = new SAA_Elem;
-        // get the referenced texture
-        SAA_modelRelationGetT2DGlbElements( scene, _model,
-                                            TEX_PER_MAT, textures );
-        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 )
-            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);
-
-          uRepeat = new int;
-          vRepeat = new int;
-
-          softegg_cat.spam() << " global tex named: " << *texNameArray << endl;
-
-          // allocate arrays of texture info
-          uScale = new PN_stdfloat;
-          vScale = new PN_stdfloat;
-          uOffset = new PN_stdfloat;
-          vOffset = new PN_stdfloat;
-
-          SAA_texture2DGetUScale( scene, textures, uScale );
-          SAA_texture2DGetVScale( scene, textures, vScale );
-          SAA_texture2DGetUOffset( scene, textures, uOffset );
-          SAA_texture2DGetVOffset( scene, textures, vOffset );
-
-          softegg_cat.spam() << " global tex uScale: " << *uScale << " vScale: " << *vScale << endl;
-          softegg_cat.spam() << "            uOffset: " << *uOffset << " vOffset: " << *vOffset << endl;
-
-          SAA_texture2DGetRepeats(  scene, textures, uRepeat, vRepeat );
-          softegg_cat.spam() << "uRepeat = " << *uRepeat << ", vRepeat = " << *vRepeat << endl;
-        }
-        else {
-          softegg_cat.spam() << "Invalid Texture...\n";
-        }
-      }
-    }
-  }
-  softegg_cat.spam() << "got textures" << endl;
-}
-
-/**
- * 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.info() << "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 PN_stdfloat;
-      vScale = new PN_stdfloat;
-      uOffset = new PN_stdfloat;
-      vOffset = new PN_stdfloat;
-      uRepeat = new int;
-      vRepeat = new int;
-
-      // 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 );
-        SAA_texture2DGetVScale( scene, &textures[0], vScale );
-        SAA_texture2DGetUOffset( scene, &textures[0], uOffset );
-        SAA_texture2DGetVOffset( scene, &textures[0], vOffset );
-
-        softegg_cat.spam() << "tritex[0] uScale: " << *uScale << " vScale: " << *vScale << endl;
-        softegg_cat.spam() << " uOffset: " << *uOffset << " vOffset: " << *vOffset << 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";
-  }
-}
-
-/**
- * given a vertex, find its corresponding shape vertex and return its index.
- */
-int SoftNodeDesc::
-find_shape_vert(LPoint3d p3d, SAA_DVector *vertices, int numVert) {
-  int i, found = 0;
-
-  for (i = 0; i < numVert && !found ; i++) {
-    if ((p3d[0] == vertices[i].x) &&
-        (p3d[1] == vertices[i].y) &&
-        (p3d[2] == vertices[i].z)) {
-      found = 1;
-      softegg_cat.spam() << "found shape vert at index " << i << endl;
-    }
-  }
-
-  if (!found )
-    i = -1;
-  else
-    i--;
-
-  return i;
-}
-
-/**
- * Given a scene, a model , the vertices of its original shape and its name
- * find the difference between the geometry of its key shapes and the models
- * original geometry and add morph vertices to the egg data to reflect these
- * changes.
- */
-void SoftNodeDesc::
-make_vertex_offsets(int numShapes) {
-  int i, j;
-  int offset;
-  int numCV;
-  char tableName[_MAX_PATH];
-  SAA_DVector *shapeVerts = nullptr;
-  SAA_DVector *uniqueVerts = nullptr;
-  SAA_Elem *model = get_model();
-  SAA_Scene *scene = &stec.scene;
-
-  EggVertexPool *vpool = nullptr;
-  std::string vpool_name = get_name() + ".verts";
-  EggNode *t = stec._tree.get_egg_root()->find_child(vpool_name);
-  if (t)
-    DCAST_INTO_V(vpool, t);
-
-  int numOrigVert = (int) vpool->size();
-  EggVertexPool::iterator vi;
-
-  if ((type == SAA_MNSRF) && stec.make_nurbs)
-    SAA_nurbsSurfaceSetStep( scene, model, stec.nurbs_step, stec.nurbs_step );
-
-  SAA_modelGetNbVertices( scene, model, &numCV );
-
-  // get the shape verts
-  uniqueVerts = new SAA_DVector[numCV];
-  SAA_modelGetVertices( scene, model, SAA_GEOM_ORIGINAL, 0,
-                        numCV, uniqueVerts );
-
-  softegg_cat.spam() << numCV << " CV's\n";
-
-  for ( i = 0; i < numCV; i++ )
-    // convert vertices to global
-    _VCT_X_MAT( uniqueVerts[i], uniqueVerts[i], matrix);
-    softegg_cat.spam() << "uniqueVerts[" << i << "] = " << uniqueVerts[i].x << " " << uniqueVerts[i].y
-         << " " << uniqueVerts[i].z << " " << uniqueVerts[i].w << endl;
-
-  // iterate through for each key shape (except original)
-  for ( i = 1; i < numShapes; i++ ) {
-
-    sprintf(tableName, "%s.%d", get_name().c_str(), i);
-
-    softegg_cat.spam() << "\nMaking geometry offsets for " << tableName << "...\n";
-
-    if ((type == SAA_MNSRF) && stec.make_nurbs)
-      softegg_cat.spam() << "calculating NURBS morphs...\n";
-    else
-      softegg_cat.spam() << "calculating triangle morphs...\n";
-
-    // get the shape verts
-    shapeVerts = new SAA_DVector[numCV];
-    SAA_modelGetVertices( scene, model, SAA_GEOM_SHAPE, i+1, numCV, shapeVerts );
-
-    for ( j=0; j < numCV; j++ ) {
-      // convert vertices to global
-      _VCT_X_MAT( shapeVerts[j], shapeVerts[j], matrix);
-
-      softegg_cat.spam() << "shapeVerts[" << j << "] = " << shapeVerts[j].x << " "
-           << shapeVerts[j].y << " " << shapeVerts[j].z << endl;
-    }
-    softegg_cat.spam() << endl;
-
-    // for every original vertex, compare to the corresponding key shape
-    // vertex and see if a vertex offset is needed
-    j = 0;
-    for (vi = vpool->begin(); vi != vpool->end(); ++vi, ++j) {
-
-      double dx, dy, dz;
-      EggVertex *vert = (*vi);
-      LPoint3d p3d = vert->get_pos3();
-
-      softegg_cat.spam() << "oVert[" << j << "] = " <<  p3d[0] << " " <<  p3d[1] << " " <<  p3d[2] << endl;
-      if ((type == SAA_MNSRF) && stec.make_nurbs) {
-        dx = shapeVerts[j].x - p3d[0];
-        dy = shapeVerts[j].y - p3d[1];
-        dz = shapeVerts[j].z - p3d[2];
-
-        softegg_cat.spam() << "global shapeVerts[" << j << "] = " << shapeVerts[j].x << " "
-             << shapeVerts[j].y << " " << shapeVerts[j].z << " " << shapeVerts[j].w << endl;
-      }
-      else {
-        // we need to map from original vertices to triangle shape vertices
-        // here
-        offset = find_shape_vert(p3d, uniqueVerts, numCV);
-
-        dx = shapeVerts[offset].x - p3d[0];
-        dy = shapeVerts[offset].y - p3d[1];
-        dz = shapeVerts[offset].z - p3d[2];
-
-        softegg_cat.spam() << "global shapeVerts[" << offset << "] = " << shapeVerts[offset].x << " "
-             << shapeVerts[offset].y << " " << shapeVerts[offset].z << endl;
-      }
-
-      softegg_cat.spam() << j << ": dx = " << dx << ", dy = " << dy << ", dz = " << dz << endl;
-
-      // if change isn't negligible, make a morph vertex entry
-      double total = fabs(dx)+fabs(dy)+fabs(dz);
-      if ( total > 0.00001 ) {
-        if ( vpool != nullptr ) {
-          // create offset
-          LVector3d p(dx, dy, dz);
-          EggMorphVertex *dxyz = new EggMorphVertex(tableName, p);
-          // add the offset to the vertex
-          vert->_dxyzs.insert(*dxyz);
-        }
-        else
-          softegg_cat.spam() << "Error: couldn't find vertex pool " << vpool_name << endl;
-
-      } // if total
-    } //for j
-  } //for i
-}
-
-/**
- * Given a scene, a model, a name and a frame time, determine what type of
- * shape interpolation is used and call the appropriate function to extract
- * the shape weight info for this frame...
- */
-void SoftNodeDesc::
-make_morph_table(  PN_stdfloat time ) {
-  int numShapes;
-  SAA_Elem *model = nullptr;
-  SAA_AnimInterpType type;
-  SAA_Scene *scene = &stec.scene;
-
-  if (has_model())
-    model = get_model();
-  else
-    return;
-
-  // Get the number of key shapes
-  SAA_modelGetNbShapes( scene, model, &numShapes );
-
-  if ( numShapes <= 0 ) {
-    return;
-  }
-
-  stec.has_morph = true;
-
-  softegg_cat.spam() << "make_morph_table: " << get_name() << " : num shapes: " << numShapes << endl;
-
-  SAA_modelGetShapeInterpolation( scene, model, &type );
-
-  if ( type == SAA_ANIM_LINEAR || type == SAA_ANIM_CARDINAL ) {
-    softegg_cat.spam() << "linear morph" << endl;
-    make_linear_morph_table( numShapes, time );
-  }
-  else {    // must be weighted...
-    // check first for expressions
-    softegg_cat.spam() << "expression morph" << endl;
-    make_expression_morph_table( numShapes, time );
-  }
-}
-
-/**
- * Given a scene, a model, its name, and the time, get the shape fcurve for
- * the model and determine the shape weights for the given time and use them
- * to populate the morph table.
- */
-void SoftNodeDesc::
-make_linear_morph_table(int numShapes, PN_stdfloat time) {
-  int i;
-  PN_stdfloat curveVal;
-  char tableName[_MAX_PATH];
-  SAA_Elem fcurve;
-  // SAnimTable *thisTable;
-  EggSAnimData *anim;
-  SAA_Elem *model = get_model();
-  SAA_Scene *scene = &stec.scene;
-
-  softegg_cat.spam() << "linear interp, getting fcurve\n";
-
-  SAA_modelFcurveGetShape( scene, model, &fcurve );
-
-  SAA_fcurveEval( scene, &fcurve, time, &curveVal );
-
-  softegg_cat.spam() << "at time " << time << ", fcurve for " << get_name() << " = " << curveVal << endl;
-
-  PN_stdfloat nextVal = 0.0f;
-
-  // populate morph table values for this frame
-  for ( i = 1; i < numShapes; i++ ) {
-    // derive table name from the model name
-    sprintf(tableName, "%s.%d", get_name().c_str(), i);
-
-    softegg_cat.spam() << "Linear: looking for table '" << tableName << "'\n";
-
-    // find the morph table associated with this key shape
-    anim = stec.find_morph_table(tableName);
-
-    if ( anim != nullptr ) {
-      if ( i == (int)curveVal ) {
-        if ( curveVal - i == 0 ) {
-          anim->add_data(1.0f );
-          softegg_cat.spam() << "adding element 1.0f\n";
-        }
-        else {
-          anim->add_data(1.0f - (curveVal - i));
-          nextVal = curveVal - i;
-          softegg_cat.spam() << "adding element " << 1.0f - (curveVal - i) << endl;
-        }
-      }
-      else {
-        if ( nextVal ) {
-          anim->add_data(nextVal );
-          nextVal = 0.0f;
-          softegg_cat.spam() << "adding element " << nextVal << endl;
-        }
-        else {
-          anim->add_data(0.0f);
-          softegg_cat.spam() << "adding element 0.0f\n";
-        }
-      }
-
-      softegg_cat.spam() <<" to '" << tableName << "'\n";
-    }
-    else
-      softegg_cat.spam() << i << " : Couldn't find table '" << tableName << "'\n";
-  }
-}
-
-/**
- * Given a scene, a model, a list of all models in the scene, the number of
- * models in the scece, the number of key shapes for this model, the name of
- * the model and the current time, determine what method of controlling the
- * shape weights is used and call the appropriate routine.
- */
-void SoftNodeDesc::
-make_weighted_morph_table(int numShapes, PN_stdfloat time) {
-  PN_stdfloat curveVal;
-  SI_Error result;
-  char tableName[_MAX_PATH];
-  SAA_Elem *weightCurves;
-  // SAnimTable *thisTable;
-  EggSAnimData *anim;
-  SAA_Elem *model = get_model();
-  SAA_Scene *scene = &stec.scene;
-
-  // allocate array of weight curves (one for each shape)
-  weightCurves = new SAA_Elem[numShapes];
-
-  result = SAA_modelFcurveGetShapeWeights(scene, model, numShapes, weightCurves);
-
-  if ( result == SI_SUCCESS ) {
-    for ( int i = 1; i < numShapes; i++ ) {
-      SAA_fcurveEval( scene, &weightCurves[i], time, &curveVal );
-
-      // make sure soft gave us a reasonable number if (!isNum(curveVal))
-      // curveVal = 0.0f;
-
-      softegg_cat.spam() << "at time " << time << ", weightCurve[" << i << "] for " << get_name() << " = " << curveVal << endl;
-
-      // derive table name from the model name
-      sprintf(tableName, "%s.%d", get_name().c_str(), i);
-
-      // find and populate shape table
-      softegg_cat.spam() << "Weight: looking for table '" << tableName << "'\n";
-
-      // find the morph table associated with this key shape
-      anim = stec.find_morph_table(tableName);
-
-      if ( anim != nullptr ) {
-        anim->add_data(curveVal);
-        softegg_cat.spam() << "adding element " << curveVal << endl;
-      }
-      else
-        softegg_cat.spam() << i << " : Couldn't find table '" << tableName << "'\n";
-    }
-  }
-}
-
-/**
- * Given a scene, a model and its number of key shapes generate a morph table
- * describing transitions btwn the key shapes by evaluating the positions of
- * the controlling sliders.
- */
-void SoftNodeDesc::
-make_expression_morph_table(int numShapes, PN_stdfloat time)
-{
-  // int j;
-  int numExp;
-  char *track;
-  // PN_stdfloat expVal; PN_stdfloat sliderVal; char *tableName; char
-  // *sliderName; SAnimTable *thisTable;
-  SAA_Elem *expressions;
-  SI_Error result;
-
-  SAA_Elem *model = get_model();
-  SAA_Scene *scene = &stec.scene;
-
-  // populate morph table values for this frame
-
-  // compose track name
-  track = nullptr;
-
-  // find how many expressions for this shape
-  SAA_elementGetNbExpressions( scene, model, track, FALSE, &numExp );
-
-  softegg_cat.spam() << get_name() << " has " << numExp << " RHS expressions\n";
-
-  if ( numExp ) {
-    // get the expressions for this shape
-    expressions = new SAA_Elem[numExp];
-    softegg_cat.spam() << "getting " << numExp << " RHS expressions...\n";
-
-    result = SAA_elementGetExpressions( scene, model, track, FALSE,
-                                        numExp, expressions );
-    /*
-    if ( !result ) {
-      for ( j = 1; j < numExp; j++ ) {
-        if ( verbose >= 2 )
-                {
-                // debug see what we got
-                int numvars;
-
-                SAA_expressionGetNbVars( scene, &expressions[j], &numvars );
-
-                int *varnamelen;
-                int *varstrlen;
-                int  expstrlen;
-
-                varnamelen = (int *)malloc(sizeof(int)*numvars);
-                varstrlen = (int *)malloc(sizeof(int)*numvars);
-
-                SAA_expressionGetStringLengths( scene, &expressions[j],
-                    numvars, varnamelen, varstrlen, &expstrlen );
-
-                int *varnamesizes;
-                int *varstrsizes;
-
-                varnamesizes = (int *)malloc(sizeof(int)*numvars);
-                varstrsizes = (int *)malloc(sizeof(int)*numvars);
-
-                for ( int k = 0; k < numvars; k++ )
-                {
-                    varnamesizes[k] = varnamelen[k] + 1;
-                    varstrsizes[k] = varstrlen[k] + 1;
-                }
-
-                int expstrsize = expstrlen + 1;
-
-                char **varnames;
-                char **varstrs;
-
-                varnames = (char **)malloc(sizeof(char *)*numvars);
-                varstrs = (char **)malloc(sizeof(char *)*numvars);
-
-                for ( k = 0; k < numvars; k++ )
-                {
-                    varnames[k] = (char *)malloc(sizeof(char)*
-                        varnamesizes[k]);
-
-                    varstrs[k] = (char *)malloc(sizeof(char)*
-                        varstrsizes[k]);
-                }
-
-                char *expstr = (char *)malloc(sizeof(char)* expstrsize );
-
-                SAA_expressionGetStrings( scene, &expressions[j], numvars,
-                    varnamesizes, varstrsizes, expstrsize, varnames,
-                    varstrs, expstr );
-
-                if ( verbose >= 2 )
-                {
-                    fprintf( outStream, "expression = '%s'\n", expstr );
-                    fprintf( outStream, "has %d variables\n", numvars );
-                }
-                } //if verbose
-
-                if ( verbose >= 2 )
-                    fprintf( outStream, "evaling expression...\n" );
-
-                SAA_expressionEval( scene, &expressions[j], time, &expVal );
-
-                if ( verbose >= 2 )
-                    fprintf( outStream, "time %f: exp val %f\n",
-                        time, expVal );
-
-                // derive table name from the model name
-                tableName = MakeTableName( name, j );
-
-                if ( verbose >= 2 )
-                    fprintf( outStream, "Exp: looking for table '%s'\n",
-                        tableName );
-
-                // find the morph table associated with this key shape
-                anim = (SAnimTable *)
-                    (morphRoot->FindDescendent( tableName ));
-
-                if ( anim != NULL )
-                {
-                    anim->AddElement( expVal );
-                    if ( verbose >= 1 )
-                        fprintf( outStream, "%d: adding element %f to %s\n",
-                            j, expVal, tableName );
-                    fflush( outStream );
-                }
-                else
-                {
-                    fprintf( outStream, "%d: Couldn't find table '%s'", j,
-                            tableName );
-
-                    fprintf( outStream, " for value %f\n", expVal );
-                }
-            }
-        }
-        else
-            fprintf( outStream, "couldn't get expressions!!!\n" );
-    */
-  }
-  else {
-    softegg_cat.spam() << "weighted morph" << endl;
-    // no expression, use weight curves
-    make_weighted_morph_table(numShapes, time );
-  }
-}

+ 0 - 159
pandatool/src/softegg/softNodeDesc.h

@@ -1,159 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file softNodeDesc.h
- * @author masad
- * @date 2003-10-03
- */
-
-#ifndef SOFTNODEDESC_H
-#define SOFTNODEDESC_H
-
-#ifdef _MIN
-#undef _MIN
-#endif
-#ifdef _MAX
-#undef _MAX
-#endif
-
-#include "pandatoolbase.h"
-
-#include "eggVertex.h"
-#include "eggVertexPool.h"
-#include "referenceCount.h"
-#include "pointerTo.h"
-#include "namable.h"
-
-#include <SAA.h>
-
-class EggGroup;
-class EggTable;
-class EggXfmSAnim;
-
-/**
- * Describes a single instance of a node aka element in the Soft scene graph,
- * relating it to the corresponding egg structures (e.g.  node, group, or
- * table entry) that will be created.
- */
-class SoftNodeDesc : public ReferenceCount, public Namable {
-public:
-  SoftNodeDesc(SoftNodeDesc *parent=nullptr, const std::string &name = std::string());
-  ~SoftNodeDesc();
-
-  void set_parent(SoftNodeDesc *parent);
-  void force_set_parent(SoftNodeDesc *parent);
-  void set_model(SAA_Elem *model);
-  bool has_model() const;
-  SAA_Elem *get_model() const;
-
-  bool is_joint() const;
-  bool is_junk() const;
-  void set_joint();
-  bool is_joint_parent() const;
-  bool is_partial(char *search_prefix);
-
-  SoftNodeDesc *_parent;
-  SoftNodeDesc *_parentJoint; // keep track of who is your parent joint
-  typedef pvector< PT(SoftNodeDesc) > Children;
-  Children _children;
-
-private:
-  void clear_egg();
-  void mark_joint_parent();
-  void check_joint_parent();
-  void check_junk(bool parent_junk);
-  void check_pseudo_joints(bool joint_above);
-
-  void set_parentJoint(SAA_Scene *scene, SoftNodeDesc *lastJoint);
-
-  SAA_ModelType type;
-
-  SAA_Elem *_model;
-
-  EggGroup *_egg_group;
-  EggTable *_egg_table;
-  EggXfmSAnim *_anim;
-
-  enum JointType {
-    JT_none,         // Not a joint.
-    JT_joint,        // An actual joint in Soft.
-    JT_pseudo_joint, // Not a joint in Soft, but treated just like a
-                     // joint for the purposes of the converter.
-    JT_joint_parent, // A parent or ancestor of a joint or pseudo joint.
-    JT_junk,         // originated from con-/fly-/car_rig/bars etc.
-  };
-  JointType _joint_type;
-
-public:
-
-  char **texNameArray;
-  int *uRepeat, *vRepeat;
-  PN_stdfloat matrix[4][4];
-
-  const char *fullname;
-
-  int numTri;
-  // int numShapes;
-  int numTexLoc;
-  int numTexGlb;
-  int *numTexTri;
-
-  // if the node is a MNSRF
-  int numNurbTexLoc;
-  int numNurbTexGlb;
-  int numNurbMats;
-
-  PN_stdfloat *uScale;
-  PN_stdfloat *vScale;
-  PN_stdfloat *uOffset;
-  PN_stdfloat *vOffset;
-
-  SAA_Boolean valid;
-  SAA_Boolean uv_swap;
-  // SAA_Boolean visible;
-  SAA_Elem *textures;
-  SAA_Elem *materials;
-  SAA_SubElem *triangles;
-  SAA_GeomType gtype;
-
-  EggGroup *get_egg_group()const {return _egg_group;}
-
-  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_poly_model(SAA_Scene *scene, SAA_ModelType type);
-  void load_nurbs_model(SAA_Scene *scene, SAA_ModelType type);
-
-  void make_morph_table(PN_stdfloat time);
-  void make_linear_morph_table(int numShapes, PN_stdfloat time);
-  void make_weighted_morph_table(int numShapes, PN_stdfloat time);
-  void make_expression_morph_table(int numShapes, PN_stdfloat time);
-
-  void make_vertex_offsets(int numShapes);
-  int find_shape_vert(LPoint3d p3d, SAA_DVector *vertices, int numVert);
-
-  static TypeHandle get_class_type() {
-    return _type_handle;
-  }
-  static void init_type() {
-    ReferenceCount::init_type();
-    Namable::init_type();
-    register_type(_type_handle, "SoftNodeDesc",
-                  ReferenceCount::get_class_type(),
-                  Namable::get_class_type());
-  }
-
-private:
-  static TypeHandle _type_handle;
-
-  friend class SoftNodeTree;
-};
-
-class SoftToEggConverter;
-extern SoftToEggConverter stec;
-
-#endif

+ 0 - 561
pandatool/src/softegg/softNodeTree.cxx

@@ -1,561 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file softNodeTree.cxx
- * @author masad
- * @date 2003-09-26
- */
-
-// Includes
-
-#include "softNodeTree.h"
-#include "softEggGroupUserData.h"
-#include "config_softegg.h"
-#include "eggGroup.h"
-#include "eggTable.h"
-#include "eggXfmSAnim.h"
-#include "eggData.h"
-#include "softToEggConverter.h"
-#include "dcast.h"
-
-#include <SAA.h>
-
-using std::endl;
-
-/**
- *
- */
-SoftNodeTree::
-SoftNodeTree() {
-  _root = new SoftNodeDesc(nullptr, "----root");
-  _root->fullname = "----root";
-  _fps = 0.0;
-  _use_prefix = 0;
-  _search_prefix = nullptr;
-  _egg_data = nullptr;
-  _egg_root = nullptr;
-  _skeleton_node = nullptr;
-}
-/**
- * Given an element, return a copy of the element's name WITHOUT prefix.
- */
-char *SoftNodeTree::
-GetName( SAA_Scene *scene, SAA_Elem *element ) {
-  int nameLen;
-  char *name;
-
-  // get the name
-  SAA_elementGetNameLength( scene, element, &nameLen );
-  name = new char[++nameLen];
-  SAA_elementGetName( scene, element, nameLen, name );
-
-  return name;
-}
-
-/**
- * Given an element, return a copy of the element's name complete with prefix.
- */
-char *SoftNodeTree::
-GetFullName( SAA_Scene *scene, SAA_Elem *element )
-{
-  int nameLen, prefixLen;
-  char *name, *prefix;
-
-  // get the name length
-  SAA_elementGetNameLength( scene, element, &nameLen );
-  // get the prefix length
-  SAA_elementGetPrefixLength( scene, element, &prefixLen );
-  // allocate the array to hold name
-  name = new char[++nameLen];
-  // allocate the array to hold prefix and length + hyphen
-  prefix = new char[++prefixLen + nameLen + 4];
-  // get the name
-  SAA_elementGetName( scene, element, nameLen, name );
-  // get the prefix
-  SAA_elementGetPrefix( scene, element, prefixLen, prefix );
-  // add 'em together
-  strcat(prefix, "-");
-  strcat(prefix, name);
-
-  // return string
-  return prefix;
-}
-
-/**
- * Given an element, return a string containing the contents of its MODEL NOTE
- * entry
- */
-char *SoftNodeTree::
-GetModelNoteInfo( SAA_Scene *scene, SAA_Elem *model ) {
-  int size;
-  char *modelNote = nullptr;
-  SAA_Boolean bigEndian;
-
-  SAA_elementGetUserDataSize( scene, model, "MNOT", &size );
-
-  if ( size != 0 ) {
-    // allocate modelNote string
-    modelNote = new char[size + 1];
-
-    // get ModelNote data from this model
-    SAA_elementGetUserData( scene, model, "MNOT", size,
-                            &bigEndian, (void *)modelNote );
-
-    // strip off newline, if present
-    char *eol = (char *)memchr( modelNote, '\n', size );
-    if ( eol != nullptr)
-      *eol = '\0';
-    else
-      modelNote[size] = '\0';
-
-    softegg_cat.spam() << "\nmodelNote = " << modelNote << endl;
-  }
-
-  return modelNote;
-}
-
-/**
- * Given a string, return a copy of the string up to the first occurence of
- * '-'.
- */
-char *SoftNodeTree::
-GetRootName( const char *name ) {
-  const char *hyphen;
-  char *root;
-  int len;
-
-  hyphen = strchr( name, '-' );
-  len = hyphen-name;
-
-  if ( (hyphen != nullptr) && len ) {
-    root = new char[len+1];
-    strncpy( root, name, len );
-    root[len] = '\0';
-  }
-  else {
-    root = new char[strlen(name)+1];
-    strcpy( root, name );
-  }
-  return( root );
-}
-
-/**
- * Walks through the complete Soft hierarchy and builds up the corresponding
- * tree.
- */
-bool SoftNodeTree::
-build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database) {
-  SI_Error status;
-  SoftNodeDesc *node;
-
-  // Get the entire Soft scene.
-  int numModels;
-  SAA_Elem *models;
-
-  SAA_sceneGetNbModels( &scene, &numModels );
-  softegg_cat.spam() << "Scene has " << numModels << " model(s)...\n";
-
-  // This while loop walks through the entire Soft hierarchy, one node at a
-  // time.
-  bool all_ok = true;
-  if ( numModels ) {
-    // allocate array of models
-    models = (SAA_Elem *) new SAA_Elem[numModels];
-    if ( models != nullptr ) {
-      if ((status = SAA_sceneGetModels( &scene, numModels, models )) != SI_SUCCESS) {
-        return false;
-      }
-      for ( int i = 0; i < numModels; i++ ) {
-        int level;
-        status = SAA_elementGetHierarchyLevel( &scene, &models[i], &level );
-        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)
-          node->set_parent(_root);
-      }
-    }
-  }
-
-  softegg_cat.spam() << "jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj\n";
-
-  // check the nodes that are junk for animationartist control purposes
-  _root->check_junk(false);
-
-  softegg_cat.spam() << "jpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjpjp\n";
-
-  // check the nodes that are parent of ancestors of a joint
-  _root->check_joint_parent();
-
-  softegg_cat.spam() << "pppppppppppppppppppppppppppppppppppppppppppppppppppppppp\n";
-
-  // check the nodes that are pseudo joints
-  _root->check_pseudo_joints(false);
-
-  softegg_cat.spam() << "========================================================\n";
-
-  // find _parentJoint for each node
-  _root->set_parentJoint(&scene, nullptr);
-
-  return all_ok;
-}
-#if 0
-/**
- * Walks through the selected subset of the Soft hierarchy (or the complete
- * hierarchy, if nothing is selected) and builds up the corresponding tree.
- */
-bool SoftNodeTree::
-build_selected_hierarchy(char *scene_name) {
-  MStatus status;
-
-  MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
-  if (!status) {
-    status.perror("MItDag constructor");
-    return false;
-  }
-
-  // Get only the selected geometry.
-  MSelectionList selection;
-  status = MGlobal::getActiveSelectionList(selection);
-  if (!status) {
-    status.perror("MGlobal::getActiveSelectionList");
-    return false;
-  }
-
-  // Get the selected geometry only if the selection is nonempty; otherwise,
-  // get the whole scene anyway.
-  if (selection.isEmpty()) {
-    softegg_cat.info()
-      << "Selection list is empty.\n";
-    return build_complete_hierarchy();
-  }
-
-  bool all_ok = true;
-  unsigned int length = selection.length();
-  for (unsigned int i = 0; i < length; i++) {
-    MDagPath root_path;
-    status = selection.getDagPath(i, root_path);
-    if (!status) {
-      status.perror("MSelectionList::getDagPath");
-    } else {
-      // Now traverse through the selected dag path and all nested dag paths.
-      dag_iterator.reset(root_path);
-      while (!dag_iterator.isDone()) {
-        MDagPath dag_path;
-        status = dag_iterator.getPath(dag_path);
-        if (!status) {
-          status.perror("MItDag::getPath");
-        } else {
-          build_node(dag_path);
-        }
-
-        dag_iterator.next();
-      }
-    }
-  }
-
-  if (all_ok) {
-    _root->check_pseudo_joints(false);
-  }
-
-  return all_ok;
-}
-#endif
-/**
- * Returns the total number of nodes in the hierarchy, not counting the root
- * node.
- */
-int SoftNodeTree::
-get_num_nodes() const {
-  return _nodes.size();
-}
-
-/**
- * Returns the nth node in the hierarchy, in an arbitrary ordering.
- */
-SoftNodeDesc *SoftNodeTree::
-get_node(int n) const {
-  nassertr(n >= 0 && n < (int)_nodes.size(), nullptr);
-  return _nodes[n];
-}
-
-/**
- * Returns the node named 'name' in the hierarchy, in an arbitrary ordering.
- */
-SoftNodeDesc *SoftNodeTree::
-get_node(std::string name) const {
-  NodesByName::const_iterator ni = _nodes_by_name.find(name);
-  if (ni != _nodes_by_name.end())
-    return (*ni).second;
-  return nullptr;
-}
-
-/**
- * Removes all of the references to generated egg structures from the tree,
- * and prepares the tree for generating new egg structures.
- */
-void SoftNodeTree::
-clear_egg(EggData *egg_data, EggGroupNode *egg_root,
-          EggGroupNode *skeleton_node) {
-  _root->clear_egg();
-  _egg_data = egg_data;
-  _egg_root = egg_root;
-  _skeleton_node = skeleton_node;
-}
-
-/**
- * Returns the EggGroupNode corresponding to the group or joint for the
- * indicated node.  Creates the group node if it has not already been created.
- */
-EggGroup *SoftNodeTree::
-get_egg_group(SoftNodeDesc *node_desc) {
-  nassertr(_egg_root != nullptr, nullptr);
-
-  // lets print some relationship
-  softegg_cat.spam() << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
-  if (node_desc->_parent)
-    softegg_cat.spam() << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
-  else
-    softegg_cat.spam() << " parent " << node_desc->_parent;
-  softegg_cat.spam() << endl;
-
-  if (node_desc->_egg_group == nullptr) {
-    // We need to make a new group node.
-    EggGroup *egg_group;
-
-    egg_group = new EggGroup(node_desc->get_name());
-    if (node_desc->is_joint()) {
-      egg_group->set_group_type(EggGroup::GT_joint);
-    }
-
-    if (stec.flatten || (!node_desc->_parentJoint || node_desc->_parentJoint == _root)) {
-      // The parent is the root.
-      softegg_cat.spam() << "came hereeeee\n";
-      _egg_root->add_child(egg_group);
-    } else {
-      // The parent is another node.
-      EggGroup *parent_egg_group = get_egg_group(node_desc->_parentJoint);
-      parent_egg_group->add_child(egg_group);
-    }
-
-    node_desc->_egg_group = egg_group;
-  }
-
-  return node_desc->_egg_group;
-}
-
-/**
- * Returns the EggTable corresponding to the joint for the indicated node.
- * Creates the table node if it has not already been created.
- */
-EggTable *SoftNodeTree::
-get_egg_table(SoftNodeDesc *node_desc) {
-  nassertr(_skeleton_node != nullptr, nullptr);
-  nassertr(node_desc->is_joint(), nullptr);
-
-  // lets print some relationship
-  softegg_cat.spam() << " group " << node_desc->get_name() << "(" << node_desc->_egg_group << ")";
-  if (node_desc->_parent)
-    softegg_cat.spam() << " parent " << node_desc->_parent->get_name() << "(" << node_desc->_parent << ")";
-  else
-    softegg_cat.spam() << " parent " << node_desc->_parent;
-  softegg_cat.spam() << endl;
-
-  if (node_desc->_egg_table == nullptr) {
-    softegg_cat.spam() << "creating a new table\n";
-    // We need to make a new table node.  nassertr(node_desc->_parent !=
-    // (SoftNodeDesc *)NULL, NULL);
-
-    EggTable *egg_table = new EggTable(node_desc->get_name());
-    node_desc->_anim = new EggXfmSAnim("xform", _egg_data->get_coordinate_system());
-    node_desc->_anim->set_fps(_fps);
-    egg_table->add_child(node_desc->_anim);
-
-    if (stec.flatten || (!node_desc->_parentJoint || node_desc->_parentJoint == _root)) {
-      // if (!node_desc->_parent->is_joint()) { The parent is not a joint; put
-      // it at the top.
-      _skeleton_node->add_child(egg_table);
-    } else {
-      // The parent is another joint.
-      EggTable *parent_egg_table = get_egg_table(node_desc->_parentJoint);
-      parent_egg_table->add_child(egg_table);
-    }
-
-    node_desc->_egg_table = egg_table;
-  }
-
-  return node_desc->_egg_table;
-}
-
-/**
- * Returns the anim table corresponding to the joint for the indicated node.
- * Creates the table node if it has not already been created.
- */
-EggXfmSAnim *SoftNodeTree::
-get_egg_anim(SoftNodeDesc *node_desc) {
-  get_egg_table(node_desc);
-  return node_desc->_anim;
-}
-
-/**
- * Sets joint information for MNILL node
- */
-void SoftNodeTree::
-handle_null(SAA_Scene *scene, SoftNodeDesc *node_desc, const char *node_name) {
-  const char *name = node_name;
-  SAA_AlgorithmType    algo;
-  SAA_Elem *model = node_desc->get_model();
-
-  SAA_modelGetAlgorithm( scene, model, &algo );
-  softegg_cat.spam() << " null algorithm: " << algo << endl;
-
-  if ( algo == SAA_ALG_INV_KIN ) {
-    // MakeJoint( &scene, lastJoint, lastAnim,  model, name );
-    node_desc->set_joint();
-    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();
-    softegg_cat.spam() << " encountered IK leaf: " << name << endl;
-  }
-  else if ( algo == SAA_ALG_STANDARD ) {
-    SAA_Boolean isSkeleton = FALSE;
-    softegg_cat.spam() << " encountered Standard null: " << name << endl;
-
-    SAA_modelIsSkeleton( scene, model, &isSkeleton );
-
-    // check to see if this NULL is used as a skeleton or is animated via
-    // constraint only ( these nodes are tagged by the animator with the
-    // keyword "joint" somewhere in the nodes name)
-    if ( isSkeleton || (strstr( name, "joint" ) != nullptr) ) {
-      // MakeJoint( &scene, lastJoint, lastAnim, model, name );
-      node_desc->set_joint();
-      softegg_cat.spam() << " animating Standard null!!!\n";
-      softegg_cat.spam() << "isSkeleton: " << isSkeleton << endl;
-    }
-  }
-  else
-    softegg_cat.spam() << " encountered some other NULL: " << algo << endl;
-}
-
-/**
- * Returns a pointer to the node corresponding to the indicated dag_path
- * object, creating it first if necessary.
- */
-SoftNodeDesc *SoftNodeTree::
-build_node(SAA_Scene *scene, SAA_Elem *model) {
-  char *name, *fullname;
-  std::string node_name;
-  int numChildren;
-  int thisChild;
-  SAA_Elem *children;
-  SAA_ModelType type;
-  SAA_Boolean isSkeleton = FALSE;
-
-  fullname = GetFullName(scene, model);
-  if (_use_prefix)
-    name = fullname;
-  else
-    name = GetName(scene, model);
-
-  node_name = name;
-
-  SoftNodeDesc *node_desc = r_build_node(nullptr, node_name);
-
-  node_desc->fullname = fullname;
-  node_desc->set_model(model);
-  SAA_modelIsSkeleton( scene, model, &isSkeleton );
-
-  // find out what type of node we're dealing with
-  SAA_modelGetType( scene, node_desc->get_model(), &type );
-
-  if (type == SAA_MJNT || isSkeleton || (strstr(node_desc->get_name().c_str(), "joint") != nullptr))
-    node_desc->set_joint();
-
-  // treat the MNILL differently, because it needs to detect and set some
-  // joints
-  if (type == SAA_MNILL)
-    handle_null(scene, node_desc, name);
-
-  if (node_desc->is_joint())
-    softegg_cat.spam() << "type: " << type << " isSkeleton: " << isSkeleton << endl;
-
-  // get to the children
-  SAA_modelGetNbChildren( scene, model, &numChildren );
-  softegg_cat.spam() << " Model " << node_name << " children: " << numChildren << endl;
-
-  if ( numChildren ) {
-    children = new SAA_Elem[numChildren];
-    SAA_modelGetChildren( scene, model, numChildren, children );
-    if (!children)
-      softegg_cat.info() << "Not enough Memory for children...\n";
-
-    for ( thisChild = 0; thisChild < numChildren; thisChild++ ) {
-      fullname = GetFullName(scene, &children[thisChild]);
-      if (_use_prefix)
-        node_name = fullname;
-      else
-        node_name = GetName(scene, &children[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]);
-      SAA_modelIsSkeleton( scene, &children[thisChild], &isSkeleton );
-
-      // find out what type of node we're dealing with
-      SAA_modelGetType( scene, node_child->get_model(), &type );
-
-      if (type == SAA_MJNT || isSkeleton || (strstr(node_child->get_name().c_str(), "joint") != nullptr))
-        node_child->set_joint();
-
-      // treat the MNILL differently, because it needs to detect and set some
-      // joints
-      if (type == SAA_MNILL)
-        handle_null(scene, node_child, node_name.c_str());
-
-      if (node_child->is_joint())
-        softegg_cat.spam() << "type: " << type << " isSkeleton: " << isSkeleton << endl;
-    }
-  }
-  return node_desc;
-}
-
-/**
- * The recursive implementation of build_node().
- */
-SoftNodeDesc *SoftNodeTree::
-r_build_node(SoftNodeDesc *parent_node, const std::string &name) {
-  SoftNodeDesc *node_desc;
-
-  // If we have already encountered this pathname, return the corresponding
-  // SoftNodeDesc immediately.
-  NodesByName::const_iterator ni = _nodes_by_name.find(name);
-  if (ni != _nodes_by_name.end()) {
-    softegg_cat.spam() << "  already built node " << (*ni).first;
-    node_desc = (*ni).second;
-    node_desc->set_parent(parent_node);
-    return node_desc;
-  }
-
-  // Otherwise, we have to create it.  Do this recursively, so we create each
-  // node along the path.
-  node_desc = new SoftNodeDesc(parent_node, name);
-
-  softegg_cat.spam() << " node name : " << name << endl;
-  _nodes.push_back(node_desc);
-
-  _nodes_by_name.insert(NodesByName::value_type(name, node_desc));
-
-  return node_desc;
-}

+ 0 - 78
pandatool/src/softegg/softNodeTree.h

@@ -1,78 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file softNodeTree.h
- * @author masad
- * @date 2003-10-03
- */
-
-#ifndef SOFTNODETREE_H
-#define SOFTNODETREE_H
-
-#include "pandatoolbase.h"
-#include "softNodeDesc.h"
-
-#include <SAA.h>
-
-class EggGroup;
-class EggTable;
-class EggXfmSAnim;
-class EggData;
-class EggGroupNode;
-
-
-/**
- * Describes a complete tree of soft nodes for conversion.
- */
-class SoftNodeTree {
-public:
-  SoftNodeTree();
-  SoftNodeDesc *build_node(SAA_Scene *scene, SAA_Elem *model);
-  bool build_complete_hierarchy(SAA_Scene &scene, SAA_Database &database);
-  void handle_null(SAA_Scene *scene, SoftNodeDesc *node_desc, const char *node_name);
-  // bool build_selected_hierarchy(SAA_Scene *s, SAA_Database *d, char
-  // *scene_name);
-
-  int get_num_nodes() const;
-  SoftNodeDesc *get_node(int n) const;
-  SoftNodeDesc *get_node(std::string name) const;
-
-  char *GetRootName(const char *);
-  char *GetModelNoteInfo(SAA_Scene *, SAA_Elem *);
-  char *GetName(SAA_Scene *scene, SAA_Elem *element);
-  char *GetFullName(SAA_Scene *scene, SAA_Elem *element);
-
-  EggGroupNode *get_egg_root() {return _egg_root;}
-  EggGroup *get_egg_group(SoftNodeDesc *node_desc);
-  EggTable *get_egg_table(SoftNodeDesc *node_desc);
-  EggXfmSAnim *get_egg_anim(SoftNodeDesc *node_desc);
-
-  void clear_egg(EggData *egg_data, EggGroupNode *egg_root, EggGroupNode *skeleton_node);
-
-  PT(SoftNodeDesc) _root;
-  PN_stdfloat _fps;
-  int _use_prefix;
-  char *_search_prefix;
-
-
-private:
-
-  EggData *_egg_data;
-  EggGroupNode *_egg_root;
-  EggGroupNode *_skeleton_node;
-
-  SoftNodeDesc *r_build_node(SoftNodeDesc *parent_node, const std::string &path);
-
-  typedef pmap<std::string, SoftNodeDesc *> NodesByName;
-  NodesByName _nodes_by_name;
-
-  typedef pvector<SoftNodeDesc *> Nodes;
-  Nodes _nodes;
-};
-
-#endif

+ 0 - 2122
pandatool/src/softegg/softToEggConverter.cxx

@@ -1,2122 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file softToEggConverter.cxx
- * @author masad
- * @date 2003-09-25
- */
-
-#include "softToEggConverter.h"
-#include "config_softegg.h"
-#include "softEggGroupUserData.h"
-
-#include "eggData.h"
-#include "eggGroup.h"
-#include "eggTable.h"
-#include "eggVertex.h"
-#include "eggComment.h"
-#include "eggVertexPool.h"
-#include "eggNurbsSurface.h"
-#include "eggNurbsCurve.h"
-#include "eggPolygon.h"
-#include "eggPrimitive.h"
-#include "eggTexture.h"
-#include "eggTextureCollection.h"
-#include "eggXfmSAnim.h"
-#include "eggSAnimData.h"
-#include "string_utils.h"
-#include "dcast.h"
-
-using std::endl;
-using std::string;
-
-SoftToEggConverter stec;
-
-const int    TEX_PER_MAT = 1;
-
-/**
- *
- */
-SoftToEggConverter::
-SoftToEggConverter(const string &program_name) :
-  _program_name(program_name)
-{
-  _from_selection = false;
-  _polygon_output = false;
-  _polygon_tolerance = 0.01;
-  /*
-  _respect_maya_double_sided = maya_default_double_sided;
-  _always_show_vertex_color = maya_default_vertex_color;
-  */
-  _transform_type = TT_model;
-
-  database_name = nullptr;
-  scene_name = nullptr;
-  model_name = nullptr;
-  animFileName = nullptr;
-  eggFileName = nullptr;
-  tex_path = nullptr;
-  eggGroupName = nullptr;
-  tex_filename = nullptr;
-  search_prefix = nullptr;
-  result = SI_SUCCESS;
-
-  // skeleton = new EggGroup();
-  foundRoot = FALSE;
-  // animRoot = NULL; morphRoot = NULL;
-  geom_as_joint = 0;
-  make_anim = 0;
-  make_nurbs = 0;
-  make_poly = 0;
-  make_soft = 0;
-  make_morph = 1;
-  make_duv = 1;
-  make_dart = TRUE;
-  has_morph = 0;
-  make_pose = 0;
-  // animData.is_z_up = FALSE;
-  nurbs_step = 1;
-  anim_start = -1000;
-  anim_end = -1000;
-  anim_rate = 24;
-  pose_frame = -1;
-  verbose = 0;
-  flatten = 0;
-  shift_textures = 0;
-  ignore_tex_offsets = 0;
-  use_prefix = 0;
-}
-
-/**
- *
- */
-SoftToEggConverter::
-SoftToEggConverter(const SoftToEggConverter &copy) :
-  _from_selection(copy._from_selection),
-  /*
-  _maya(copy._maya),
-  */
-  _polygon_output(copy._polygon_output),
-  _polygon_tolerance(copy._polygon_tolerance),
-  /*
-  _respect_maya_double_sided(copy._respect_maya_double_sided),
-  _always_show_vertex_color(copy._always_show_vertex_color),
-  */
-  _transform_type(copy._transform_type)
-{
-}
-
-/**
- *
- */
-SoftToEggConverter::
-~SoftToEggConverter() {
-  /*
-  close_api();
-  */
-}
-/**
- * Displays the "what is this program" message, along with the usage message.
- * Should be overridden in base classes to describe the current program.
- */
-void SoftToEggConverter::
-Help()
-{
-    softegg_cat.info() <<
-      "soft2egg takes a SoftImage scene or model\n"
-      "and outputs its contents as an egg file\n";
-
-    Usage();
-}
-
-/**
- * Displays the usage message.
- */
-void SoftToEggConverter::
-Usage() {
-  softegg_cat.info()
-    << "\nUsage:\n"
-    // << _commandName << " [opts] (must specify -m or -s)\n\n"
-    << "soft" << " [opts] (must specify -m or -s)\n\n"
-    << "Options:\n";
-
-  ShowOpts();
-  softegg_cat.info() << "\n";
-}
-
-/**
- * Displays the valid options.  Should be extended in base classes to show
- * additional options relevant to the current program.
- */
-void SoftToEggConverter::
-ShowOpts()
-{
-  softegg_cat.info() <<
-    "  -r <path>  - Used to provide soft with the resource\n"
-    "               Defaults to '/ful/ufs/soft371_mips2/3D/rsrc'.\n"
-    "  -d <path>  - Database path.\n"
-    "  -s <scene> - Indicates that a scene will be converted.\n"
-    "  -m <model> - Indicates that a model will be converted.\n"
-    "  -t <path>  - Specify path to place converted textures.\n"
-    "  -T <name>  - Specify filename for texture map listing.\n"
-    "  -S <step>  - Specify step for nurbs surface triangulation.\n"
-    "  -M <name>  - Specify model output filename. Defaults to scene name.\n"
-    "  -A <name>  - Specify anim output filename. Defaults to scene name.\n"
-    "  -N <name>  - Specify egg group name.\n"
-    "  -k         - Enable soft assignment for geometry.\n"
-    "  -n         - Specify egg NURBS representation instead of poly's.\n"
-    "  -p         - Specify egg polygon output for geometry.\n"
-    "  -P <frame> - Specify frame number for static pose.\n"
-    "  -b <frame> - Specify starting frame for animation (default = first).\n"
-    "  -e <frame> - Specify ending frame for animation (default = last).\n"
-    "  -f <fps>   - Specify frame rate for animation playback.\n"
-    "  -a         - Compile animation tables if animation present.\n"
-    "  -F         - Ignore hierarchy and build a completely flat skeleton.\n"
-    "  -v <level> - Set debug level.\n"
-    "  -x         - Shift NURBS parameters to preserve Alias textures.\n"
-    "  -i         - Ignore Soft texture uv offsets.\n"
-    "  -u         - Use Soft prefix in model names.\n"
-    "  -c         - Cancel morph conversion.\n"
-    "  -C         - Cancel duv conversion.\n"
-    "  -D         - Don't make the output model a character.\n"
-    "  -o <prefix>- Convert only models with given prefix.\n";
-
-  // EggBase::ShowOpts();
-}
-
-/**
- * Calls getopt() to parse the command-line switches.  Calls HandleGetopts()
- * to interpret each switch.  Returns true if the parsing was successful;
- * false if there was an error.  Adjusts argc and argv to remove the switches
- * from the parameter list.
- */
-bool SoftToEggConverter::
-DoGetopts(int &argc, char **&argv) {
-  bool okflag = true;
-  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) && (argv[i][0] == '-') && okflag) {
-    softegg_cat.info() << "arg " << i << " is " << argv[i] << "\n";
-    okflag = HandleGetopts(i, argc, argv);
-  }
-  return okflag;
-}
-
-/**
- * increment idx based on what kind of option parsed Supported options are as
- * follows: r:d:s:m:t:P:b:e:f:T:S:M:A:N:v:o:FhknpaxiucCD
- */
-bool SoftToEggConverter::
-HandleGetopts(int &idx, int argc, char **argv)
-{
-  bool okflag = true;
-
-  char flag = argv[idx][1];    // skip the '-' from option
-
-  switch (flag)
-    {
-    case 'r':       // Set the resource path for soft.
-      if ( strcmp( argv[idx+1], "" ) ) {
-        // Get the path.
-        rsrc_path = argv[idx+1];
-        softegg_cat.info() << "using rsrc path " << rsrc_path << "\n";
-      }
-      ++idx;
-      break;
-
-    case 'd':       // Set the database path.
-      if ( strcmp( argv[idx+1], "" ) ) {
-        // Get the path.
-        database_name = argv[idx+1];
-        softegg_cat.info() << "using database " << database_name << "\n";
-      }
-      ++idx;
-      break;
-
-    case 's':     // Check if its a scene.
-      if ( strcmp( argv[idx+1], "" ) ) {
-        // Get scene name.
-        scene_name = argv[idx+1];
-        softegg_cat.info() << "loading scene " << scene_name << "\n";
-      }
-      ++idx;
-      break;
-
-    case 'm':     // Check if its a model.
-      if ( strcmp( argv[idx+1], "" ) ) {
-        // Get model name.
-        model_name = argv[idx+1];
-        softegg_cat.info() << "loading model " <<  model_name << endl;
-      }
-      ++idx;
-      break;
-
-    case 't':     // Get converted texture path.
-      if ( strcmp( argv[idx+1], "" ) ) {
-        // Get tex path name.
-        tex_path = argv[idx+1];
-        softegg_cat.info() << "texture path:  " << tex_path << endl;
-      }
-      ++idx;
-      break;
-
-    case 'T':      // Specify texture list filename.
-      if ( strcmp( argv[idx+1], "") ) {
-        // Get the name.
-        tex_filename = argv[idx+1];
-        softegg_cat.info() << "creating texture list file: " << tex_filename << endl;
-      }
-      ++idx;
-      break;
-
-    case 'S':     // Set NURBS step.
-      if ( strcmp( argv[idx+1], "" ) ) {
-        nurbs_step = atoi(argv[idx+1]);
-        softegg_cat.info() << "NURBS step:  " << nurbs_step << endl;
-      }
-      ++idx;
-      break;
-
-    case 'M':     // Set model output file name.
-      if ( strcmp( argv[idx+1], "" ) ) {
-        eggFileName = argv[idx+1];
-        softegg_cat.info() << "Model output filename:  " << eggFileName << endl;
-      }
-      ++idx;
-      break;
-
-    case 'A':     // Set anim output file name.
-      if ( strcmp( argv[idx+1], "" ) ) {
-        animFileName = argv[idx+1];
-        softegg_cat.info() << "Anim output filename:  " << animFileName << endl;
-      }
-      ++idx;
-      break;
-
-    case 'N':     // Set egg model name.
-      if ( strcmp( argv[idx+1], "" ) ) {
-        eggGroupName = argv[idx+1];
-        softegg_cat.info() << "Egg group name:  " << eggGroupName << endl;
-      }
-      ++idx;
-      break;
-
-    case 'o':     // Set search_prefix.
-      if ( strcmp( argv[idx+1], "" ) ) {
-        search_prefix = argv[idx+1];
-        softegg_cat.info() << "Only converting models with prefix:  " << search_prefix << endl;
-      }
-      ++idx;
-      break;
-
-    case 'h':    // print help message
-      Help();
-      exit(1);
-      break;
-
-    case 'c':    // Cancel morph animation conversion
-      make_morph = FALSE;
-      softegg_cat.info() << "canceling morph conversion\n";
-      break;
-
-    case 'C':    // Cancel uv animation conversion
-      make_duv = FALSE;
-      softegg_cat.info() << "canceling uv animation conversion\n";
-      break;
-
-    case 'D':    // Omit the Dart flag
-      make_dart = FALSE;
-      softegg_cat.info() << "making a non-character model\n";
-      break;
-
-    case 'k':    // Enable soft skinning
-      // make_soft = TRUE; fprintf( outStream, "enabling soft skinning\n" );
-      softegg_cat.info() << "-k flag no longer necessary\n";
-      break;
-
-    case 'n':    // Generate egg NURBS output
-      make_nurbs = TRUE;
-      softegg_cat.info() << "outputting egg NURBS info\n";
-      break;
-
-    case 'p':    // Generate egg polygon output
-      make_poly = TRUE;
-      softegg_cat.info() << "outputting egg polygon info\n";
-      break;
-
-    case 'P':    // Generate static pose from given frame
-      if ( strcmp( argv[idx+1], "" ) ) {
-        make_pose = TRUE;
-        pose_frame = atoi(argv[idx+1]);
-        softegg_cat.info() << "generating static pose from frame " << pose_frame << endl;
-      }
-      ++idx;
-      break;
-
-    case 'a':     // Compile animation tables.
-      make_anim = TRUE;
-      softegg_cat.info() << "attempting to compile anim tables\n";
-      break;
-
-    case 'F':     // Build a flat skeleton.
-      flatten = TRUE;
-      softegg_cat.info() << "building a flat skeleton!!!\n";
-      break;
-
-    case 'x':     // Shift NURBS parameters to preserve Alias textures.
-      shift_textures = TRUE;
-      softegg_cat.info() << "shifting NURBS parameters...\n";
-      break;
-
-    case 'i':     // Ignore Soft uv texture offsets
-      ignore_tex_offsets = TRUE;
-      softegg_cat.info() << "ignoring texture offsets...\n";
-      break;
-
-    case 'u':     // Use Soft prefix in model names
-      use_prefix = TRUE;
-      softegg_cat.info() << "using prefix in model names...\n";
-      break;
-
-
-    case 'v':     // print debug messages.
-      if ( strcmp( argv[idx+1], "" ) ) {
-        verbose = atoi(argv[idx+1]);
-        softegg_cat.info() << "using debug level " << verbose << endl;
-      }
-      ++idx;
-      break;
-
-    case 'b':     // Set animation start frame.
-      anim_start = atoi(argv[idx]+2);
-      softegg_cat.info() << "animation starting at frame:  " << anim_start << endl;
-      break;
-
-    case 'e':     /// Set animation end frame.
-      anim_end = atoi(argv[idx]+2);
-      softegg_cat.info() << "animation ending at frame:  " << anim_end << endl;
-      break;
-
-    case 'f':     /// Set animation frame rate.
-      if ( strcmp( argv[idx+1], "" ) ) {
-        anim_rate = atoi(argv[idx+1]);
-        softegg_cat.info() << "animation frame rate:  " << anim_rate << endl;
-      }
-      ++idx;
-      break;
-
-    default:
-      softegg_cat.info() << flag << " flag not supported\n";
-      okflag = false;
-    }
-  idx++;
-  return (okflag);
-}
-
-/**
- * Allocates and returns a new copy of the converter.
- */
-SomethingToEggConverter *SoftToEggConverter::
-make_copy() {
-  return new SoftToEggConverter(*this);
-}
-
-/**
- * Returns the English name of the file type this converter supports.
- */
-string SoftToEggConverter::
-get_name() const {
-  return "Soft";
-}
-
-/**
- * Returns the common extension of the file type this converter supports.
- */
-string SoftToEggConverter::
-get_extension() const {
-  return "mb";
-}
-
-/**
- * Returns the English name of the file type this converter supports.
- */
-SoftNodeDesc *SoftToEggConverter::
-find_node(string name) {
-  return _tree.get_node(name);
-}
-
-/**
- * Given a texture element, return texture name with given tex_path
- */
-char *SoftToEggConverter::
-GetTextureName( SAA_Scene *scene, SAA_Elem *texture ) {
-  char *fileName = new char[_MAX_PATH];
-  char tempName[_MAX_PATH];
-  SAA_texture2DGetPicName( scene, texture, _MAX_PATH, tempName );
-
-  if (tex_path) {
-    // softegg_cat.spam() << "tempName :" << tempName << endl;
-    strcpy(fileName, tex_path);
-
-    // do some processing on the name string
-    char *tmpName = nullptr;
-    tmpName = strrchr(tempName, '/');
-    if (tmpName)
-      tmpName++;
-    else
-      tmpName = tempName;
-
-    // softegg_cat.spam() << "tmpName : " << tmpName << endl;
-    strcat(fileName, "/");
-    strcat(fileName, tmpName);
-  }
-  else {
-    strcpy(fileName, tempName);
-  }
-
-  strcat(fileName, ".pic");
-  // softegg_cat.spam() << "fileName : " << fileName << endl;
-
-  return fileName;
-}
-
-/**
- * Handles the reading of the input file and converting it to egg.  Returns
- * true if successful, false otherwise.
- *
- * This is designed to be as generic as possible, generally in support of run-
- * time loading.  Also see convert_soft().
- */
-bool SoftToEggConverter::
-convert_file(const Filename &filename) {
-  if (!open_api()) {
-    softegg_cat.error()
-      << "Soft is not available.\n";
-    return false;
-  }
-  if (_character_name.empty()) {
-    _character_name = filename.get_basename_wo_extension();
-  }
-  return convert_soft(false);
-}
-
-/**
- * Fills up the egg_data structure according to the global soft model data.
- * Returns true if successful, false if there is an error.  If from_selection
- * is true, the converted geometry is based on that which is selected;
- * otherwise, it is the entire Soft scene.
- */
-bool SoftToEggConverter::
-convert_soft(bool from_selection) {
-  bool all_ok = true;
-
-  _from_selection = from_selection;
-  _textures.clear();
-
-  PT(EggData) egg_data = new EggData;
-  set_egg_data(egg_data);
-  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) {
-    softegg_cat.spam() << "coordinate system is not default\n";
-    exit(1);
-  }
-
-  _tree._use_prefix = use_prefix;
-  _tree._search_prefix = search_prefix;
-  all_ok = _tree.build_complete_hierarchy(scene, database);
-
-  // Lets see if we have gotten the hierarchy right _tree.print_hierarchy();
-  // exit(1);
-
-  char *root_name = _tree.GetRootName( eggFileName );
-
-  softegg_cat.debug() << "main group name: " << root_name << endl;
-  if (root_name)
-    _character_name = root_name;
-
-  if (make_poly || make_nurbs) {
-    // Specify that the texture names should be relative to the output file.
-    Filename output_filename(eggFileName);
-    _path_replace->_path_store = PS_relative;
-    _path_replace->_path_directory = output_filename.get_dirname();
-
-    if (!convert_char_model()) {
-      all_ok = false;
-    }
-
-    // generate soft skinning assignments if desired
-    if (!make_soft_skin()) {
-      all_ok = false;
-    }
-
-    // sometimes you need to hard assign some vertices
-    if (!cleanup_soft_skin()) {
-      all_ok = false;
-    }
-
-    // reparent_decals(get_egg_data());
-    softegg_cat.info() << "Converted Softimage file\n";
-
-    // write out the egg model file
-    _egg_data->write_egg(output_filename);
-    softegg_cat.info() << "Wrote Egg file " << output_filename << endl;
-  }
-  if (make_anim) {
-    if (!convert_char_chan()) {
-      all_ok = false;
-    }
-
-    // reparent_decals(get_egg_data());
-    softegg_cat.info() << "Converted Softimage file\n";
-
-    // write out the egg model file
-    _egg_data->write_egg(Filename(animFileName));
-    softegg_cat.info() << "Wrote Anim file " << animFileName << endl;
-  }
-  return all_ok;
-}
-
-/**
- * Attempts to open the Soft API if it was not already open, and returns true
- * if successful, or false if there is an error.
- */
-bool SoftToEggConverter::
-open_api() {
-  if ((scene_name == nullptr && model_name == nullptr) || database_name == nullptr) {
-    Usage();
-    exit( 1 );
-  }
-  if ((result = SAA_Init(rsrc_path, FALSE)) != SI_SUCCESS) {
-    softegg_cat.info() << "Error: Couldn't get resource path!\n";
-    exit( 1 );
-  }
-  // cout << "got past init" << endl;
-  if ((result = SAA_databaseLoad(database_name, &database)) != SI_SUCCESS) {
-    softegg_cat.info() << "Error: Couldn't load database!\n";
-    exit( 1 );
-  }
-  // cout << "got past database load" << endl;
-  if ((result = SAA_sceneGetCurrent(&scene)) != SI_SUCCESS) {
-    softegg_cat.info() << "Error: Couldn't get current scene!\n";
-    exit( 1 );
-  }
-  // cout << "got past get current" << endl;
-  if ((result = SAA_sceneLoad( &database, scene_name, &scene )) != SI_SUCCESS) {
-    softegg_cat.info() << "Error: Couldn't load scene " << scene_name << "!\n";
-    exit( 1 );
-  }
-  // cout << "got past scene load" << endl;
-  if ( SAA_updatelistGet( &scene ) == SI_SUCCESS ) {
-    PN_stdfloat time;
-
-    softegg_cat.info() << "setting Scene to frame " << pose_frame << "...\n";
-    // SAA_sceneSetPlayCtrlCurrentFrame( &scene, pose_frame );
-    SAA_frame2Seconds( &scene, pose_frame, &time );
-    SAA_updatelistEvalScene( &scene, time );
-    if ( make_pose )
-      SAA_sceneFreeze(&scene);
-  }
-
-  // if no egg filename specified, make up a name
-  if ( eggFileName == nullptr ) {
-    string madeName;
-    string tempName(scene_name);
-    string::size_type end = tempName.find(".dsc");
-    if (end != string::npos) {
-      madeName.assign(tempName.substr(0,end));
-      if ( make_nurbs )
-        madeName.insert(madeName.size(), "-nurb");
-      madeName.insert(madeName.size(), ".egg" );
-    }
-    eggFileName = new char[madeName.size()+1];
-    strcpy(eggFileName, madeName.c_str());
-
-    // if no anim filename specified, make up a name
-    if ( animFileName == nullptr ) {
-      madeName.assign(tempName.substr(0,end));
-      madeName.insert(madeName.size(), "-chan.egg");
-      animFileName = new char[strlen(scene_name)+ 10];
-      strcpy(animFileName, madeName.c_str());
-    }
-  }
-
-  return true;
-}
-
-/**
- * Closes the Soft API, if it was previously opened.  Caution!  Soft appears
- * to call exit() when its API is closed.
- */
-void SoftToEggConverter::
-close_api() {
-  // don't know yet
-}
-
-/**
- * Converts the file as an animatable character model, with joints and vertex
- * membership.
- */
-bool SoftToEggConverter::
-convert_char_model() {
-  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);
-
-  return convert_hierarchy(char_node);
-}
-
-/**
- * Given a tablename, it either creates a new eggSAnimData structure (if
- * doesn't exist) or locates it.
- */
-EggSAnimData *SoftToEggConverter::
-find_morph_table(char *name) {
-  EggSAnimData *anim = nullptr;
-  MorphTable::iterator mt;
-  for (mt = _morph_table.begin(); mt != _morph_table.end(); ++mt) {
-    anim = (*mt);
-    if (!strcmp(anim->get_name().c_str(), name))
-      return anim;
-  }
-
-  // create an entry
-  anim = new EggSAnimData(name);
-  anim->set_fps(_tree._fps);
-  _morph_table.push_back(anim);
-  morph_node->add_child(anim);
-  return anim;
-}
-
-/**
- * Converts the animation as a series of tables to apply to the character
- * model, as retrieved earlier via AC_model.
- */
-bool SoftToEggConverter::
-convert_char_chan() {
-  int start_frame = -1;
-  int end_frame = -1;
-  int frame_inc, frame;
-  double output_frame_rate = anim_rate;
-
-  PN_stdfloat time;
-
-  EggTable *root_table_node = new EggTable();
-  get_egg_data()->add_child(root_table_node);
-  EggTable *bundle_node = new EggTable(eggGroupName);
-  bundle_node->set_table_type(EggTable::TT_bundle);
-  root_table_node->add_child(bundle_node);
-  EggTable *skeleton_node = new EggTable("<skeleton>");
-  bundle_node->add_child(skeleton_node);
-
-  morph_node = new EggTable("morph");
-
-  // Set the frame rate before we start asking for anim tables to be created.
-  SAA_sceneGetPlayCtrlStartFrame(&scene, &start_frame);
-  SAA_sceneGetPlayCtrlEndFrame(&scene, &end_frame);
-  SAA_sceneGetPlayCtrlFrameStep( &scene, &frame_inc );
-  if (frame_inc != 1) // Hmmm...some files gave me frame_inc of 0, that can't be good
-    frame_inc = 1;
-
-  softegg_cat.info() << "animation start frame: " << start_frame << " end frame: " << end_frame << endl;
-  softegg_cat.info() << "animation frame inc: " << frame_inc << endl;
-
-  _tree._fps = output_frame_rate / frame_inc;
-  // _tree.clear_egg(get_egg_data(), NULL, root_node);
-  _tree.clear_egg(get_egg_data(), nullptr, skeleton_node);
-
-  // Now we can get the animation data by walking through all of the frames,
-  // one at a time, and getting the joint angles at each frame.
-
-  // This is just a temporary EggGroup to receive the transform for each joint
-  // each frame.
-  PT(EggGroup) tgroup = new EggGroup;
-
-  int num_nodes = _tree.get_num_nodes();
-  int i;
-
-  // MTime frame(start_frame, MTime::uiUnit()); MTime frame_stop(end_frame,
-  // MTime::uiUnit()); start at first frame and go to last
-  if (make_pose) {
-    start_frame = pose_frame;
-    end_frame = pose_frame;
-  }
-  if (anim_start > 0)
-    start_frame = anim_start;
-  if (anim_end > 0)
-    end_frame = anim_end;
-  for ( frame = start_frame; frame <= end_frame; frame += frame_inc) {
-    SAA_frame2Seconds( &scene, frame, &time );
-    // softegg_cat.spam() << "got time " << time << endl;
-    if (!make_pose) {
-      SAA_updatelistEvalScene( &scene, time );
-    }
-    softegg_cat.spam() << "\n> animating frame " << frame << endl;
-
-    // if (softegg_cat.is_debug()) { softegg_cat.debug(false)
-    softegg_cat.info() << "frame " << time << "\n";
-    // } else { We have to write to cerr instead of softegg_cat to allow
-    // flushing without writing a newline.  std::cerr << "." << std::flush; }
-    // MGlobal::viewFrame(frame);
-
-    for (i = 0; i < num_nodes; i++) {
-      SoftNodeDesc *node_desc = _tree.get_node(i);
-
-      if (node_desc->is_partial(search_prefix)) {
-        softegg_cat.debug() << endl;
-        continue;
-      }
-      if (make_morph) {
-        node_desc->make_morph_table(time);
-      }
-      if (node_desc->is_joint()) {
-        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);
-      }
-    }
-
-    // frame += frame_inc;
-  }
-
-  if (has_morph)
-    bundle_node->add_child(morph_node);
-
-  // Now optimize all of the tables we just filled up, for no real good
-  // reason, except that it makes the resulting egg file a little easier to
-  // read.
-  for (i = 0; i < num_nodes; i++) {
-    SoftNodeDesc *node_desc = _tree.get_node(i);
-    if (node_desc->is_partial(search_prefix))
-      continue;
-
-    if (node_desc->is_joint()) {
-      _tree.get_egg_anim(node_desc)->optimize();
-    }
-  }
-
-  softegg_cat.info(false)
-    << "\n";
-
-  return true;
-}
-
-/**
- * Generates egg structures for each node in the Soft hierarchy.
- */
-bool SoftToEggConverter::
-convert_hierarchy(EggGroupNode *egg_root) {
-  int num_nodes = _tree.get_num_nodes();
-
-  _tree.clear_egg(get_egg_data(), egg_root, nullptr);
-  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;
-    }
-    softegg_cat.debug() << i << endl;
-  }
-  return true;
-}
-
-/**
- * Converts the indicated Soft node (given a MDagPath, similar in concept to
- * Panda's NodePath) to the corresponding Egg structure.  Returns true if
- * successful, false if an error was encountered.
- */
-bool SoftToEggConverter::
-process_model_node(SoftNodeDesc *node_desc) {
-  EggGroup *egg_group = nullptr;
-  const char *name = nullptr;
-  char *fullname = nullptr;
-  SAA_ModelType type;
-
-  name = node_desc->get_name().c_str();
-  softegg_cat.debug() << "element name <" << name << ">\n";
-
-  if (node_desc->is_junk()) {
-    softegg_cat.spam() << "no processing, it is junk\n";
-    return true;
-  }
-
-  // split
-  if (node_desc->is_partial(search_prefix)) {
-    softegg_cat.debug() << endl;
-    return true;
-  }
-  else
-    softegg_cat.debug() << 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 );
-
-  softegg_cat.debug() << "encountered ";
-  switch(type){
-  case SAA_MNILL:
-    softegg_cat.debug() << "null\n";
-    break;
-  case SAA_MPTCH:
-    softegg_cat.debug() << "patch\n";
-    break;
-  case SAA_MFACE:
-    softegg_cat.debug() << "face\n";
-    // break;
-  case SAA_MSMSH:
-    softegg_cat.debug() << "mesh\n";
-    node_desc->get_transform(&scene, egg_group, TRUE);
-    make_polyset(node_desc, egg_group, type);
-    break;
-  case SAA_MJNT:
-    softegg_cat.debug() << "joint";
-    softegg_cat.debug() << " joint type " << node_desc->is_joint() << endl;
-    break;
-  case SAA_MSPLN:
-    softegg_cat.debug() << "spline\n";
-    break;
-  case SAA_MMETA:
-    softegg_cat.debug() << "meta element\n";
-    break;
-  case SAA_MBALL:
-    softegg_cat.debug() << "meta ball\n";
-    break;
-  case SAA_MNCRV:
-    softegg_cat.debug() << "nurbs curve\n";
-    break;
-  case SAA_MNSRF:
-    softegg_cat.debug() << "nurbs surf\n";
-    node_desc->get_transform(&scene, egg_group, TRUE);
-    make_nurb_surface(node_desc, egg_group, type);
-    break;
-  default:
-    softegg_cat.debug() << "unknown type: " << type << "\n";
-  }
-
-  if (node_desc->is_joint())
-    node_desc->get_transform(&scene, egg_group, FALSE);
-
-  return true;
-}
-
-/**
- * Converts the indicated Soft polyset to a bunch of EggPolygons and parents
- * them to the indicated egg group.
- */
-void SoftToEggConverter::
-make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type) {
-  int id = 0;
-  int i, idx;
-  int numShapes;
-  SAA_Boolean valid;
-  SAA_Boolean visible;
-  PN_stdfloat *uCoords = nullptr;
-  PN_stdfloat *vCoords = nullptr;
-  string name = node_desc->get_name();
-
-  SAA_modelGetNodeVisibility( &scene, node_desc->get_model(), &visible );
-  softegg_cat.spam() << "model visibility: " << visible << endl;
-
-  // Only create egg polygon data if: the node is visible, and its not a NULL
-  // or a Joint, and we're outputing polys (or if we are outputing NURBS and
-  // the model is a poly mesh or a face)
-  if ( visible &&
-       (type != SAA_MNILL) &&
-       (type != SAA_MJNT) &&
-       ((make_poly ||
-         (make_nurbs && ((type == SAA_MSMSH) || (type == SAA_MFACE )) )) ||
-        (!make_poly && !make_nurbs && make_duv &&
-         ((type == SAA_MSMSH) || (type == SAA_MFACE )) ))
-       )
-    {
-      // Get the number of key shapes
-      SAA_modelGetNbShapes( &scene, node_desc->get_model(), &numShapes );
-      softegg_cat.spam() << "process_model_node: num shapes: " << numShapes << endl;
-
-      // load all node data from soft for this node_desc
-      node_desc->load_poly_model(&scene, type);
-
-      string vpool_name = name + ".verts";
-      EggVertexPool *vpool = new EggVertexPool(vpool_name);
-      vpool->set_highest_index(0);
-
-      // add the vertices in the _tree._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()->insert(_tree.get_egg_root()->begin(), vpool);
-
-      // 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 will be
-      // identity; but if the node is under an instance (particularly, for
-      // instance, a billboard) then the vertex space will be different from
-      // world space.
-      LMatrix4d vertex_frame_inv = egg_group->get_vertex_frame_inv();
-
-      // Asad: change from soft2egg.c.  Here I am trying to get one triangles
-      // vertices not all
-      for (idx=0; idx<node_desc->numTri; ++idx) {
-        EggPolygon *egg_poly = new EggPolygon;
-        egg_group->add_child(egg_poly);
-
-        softegg_cat.spam() << "processing polygon " << idx << endl;
-
-        // Is this a double sided polygon?  meaning check for back face flag
-        char *modelNoteStr = _tree.GetModelNoteInfo( &scene, node_desc->get_model() );
-        if ( modelNoteStr != nullptr ) {
-          if ( strstr( modelNoteStr, "bface" ) != nullptr )
-            egg_poly->set_bface_flag(TRUE);
-        }
-
-        // read each triangle's control vertices into array
-        SAA_SubElem cvertices[3];
-        SAA_triangleGetCtrlVertices( &scene, node_desc->get_model(), node_desc->gtype, id, 1, node_desc->triangles+idx, cvertices );
-
-        // read control vertices in this triangle
-        SAA_DVector cvertPos[3];
-        SAA_ctrlVertexGetPositions( &scene, node_desc->get_model(), 3, cvertices, cvertPos);
-
-        // read indices of each vertices in this triangle
-        int indices[3];
-        indices[0] = indices[1] = indices[2] = 0;
-        SAA_ctrlVertexGetIndices( &scene, node_desc->get_model(), 3, cvertices, indices );
-
-        // read each control vertex's normals into an array
-        SAA_DVector normals[3];
-        SAA_ctrlVertexGetNormals( &scene, node_desc->get_model(), 3, cvertices, normals );
-        for (i=0; i<3; ++i)
-          softegg_cat.spam() << "normals[" << i <<"] = " << normals[i].x << " " <<  normals[i].y
-               << " " << normals[i].z << " " <<  normals[i].w << "\n";
-
-        // allocate arrays for u & v coords
-        if (node_desc->textures) {
-          if (node_desc->numTexLoc && node_desc->numTexTri[idx]) {
-            // allocate arrays for u & v coords I think there are one texture
-            // per triangle hence we need only 3 corrdinates
-            uCoords = new PN_stdfloat[3];
-            vCoords = new PN_stdfloat[3];
-
-            // read the u & v coords into the arrays
-            if ( uCoords != nullptr && vCoords != nullptr) {
-              for ( i = 0; i < 3; i++ )
-                uCoords[i] = vCoords[i] = 0.0f;
-
-              // TODO: investigate the coord_cnt parameter...
-              SAA_ctrlVertexGetUVTxtCoords( &scene, node_desc->get_model(), 3, cvertices,
-                                            3, uCoords, vCoords );
-            }
-            else
-              softegg_cat.info() << "Not enough Memory for texture coords...\n";
-
-#if 1
-            for ( i=0; i<3; i++ )
-              softegg_cat.spam() << "texcoords[" << i << "] = ( " << uCoords[i] << " , " << vCoords[i] <<" )\n";
-#endif
-          }
-          else if (node_desc->numTexGlb) {
-            // allocate arrays for u & v coords
-            uCoords = new PN_stdfloat[node_desc->numTexGlb*3];
-            vCoords = new PN_stdfloat[node_desc->numTexGlb*3];
-
-            for ( i = 0; i < node_desc->numTexGlb*3; i++ ) {
-              uCoords[i] = vCoords[i] = 0.0f;
-            }
-
-            // read the u & v coords into the arrays
-            if ( uCoords != nullptr && vCoords != nullptr) {
-              SAA_triCtrlVertexGetGlobalUVTxtCoords( &scene, node_desc->get_model(), 3, cvertices,
-                                                     node_desc->numTexGlb, node_desc->textures, uCoords, vCoords );
-            }
-            else
-              softegg_cat.info() << "Not enough Memory for texture coords...\n";
-          }
-        }
-
-        for ( i=0; i < 3; i++ ) {
-          EggVertex vert;
-
-          // There are some conversions needed from local matrix to global
-          // coords
-          SAA_DVector local = cvertPos[i];
-          SAA_DVector global = {0};
-
-          _VCT_X_MAT( global, local, node_desc->matrix );
-
-          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";
-          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);
-          LPoint3d p3d(global.x, global.y, global.z);
-          p3d = p3d * vertex_frame_inv;
-          vert.set_pos(p3d);
-
-          local = normals[i];
-          _VCT_X_MAT( global, local, node_desc->matrix );
-
-          softegg_cat.spam() << "normals[" << i <<"] = " << normals[i].x << " " <<  normals[i].y
-               << " " << normals[i].z << " " <<  normals[i].w << "\n";
-          softegg_cat.spam() << " global normals[" << i <<"] = " << global.x << " " <<  global.y
-               << " " << global.z << " " <<  global.w << "\n";
-
-          LVector3d n3d(global.x, global.y, global.z);
-          n3d = n3d * vertex_frame_inv;
-          vert.set_normal(n3d);
-
-          // if texture present set the texture coordinates
-          if (node_desc->textures) {
-            PN_stdfloat u, v;
-
-            if (uCoords && vCoords) {
-              u = uCoords[i];
-              v = 1.0f - vCoords[i];
-              softegg_cat.spam() << "texcoords[" << i << "] = " << u << " "
-                                 << v << endl;
-
-              vert.set_uv(LTexCoordd(u, v));
-              // vert.set_uv(LTexCoordd(uCoords[i], vCoords[i]));
-            }
-          }
-          vert.set_external_index(indices[i]);
-          egg_poly->add_vertex(vpool->create_unique_vertex(vert));
-
-          // check to see if material is present
-          PN_stdfloat r,g,b,a;
-          SAA_elementIsValid( &scene, &node_desc->materials[idx], &valid );
-          // material present - get the color
-          if ( valid ) {
-            SAA_materialGetDiffuse( &scene, &node_desc->materials[idx], &r, &g, &b );
-            SAA_materialGetTransparency( &scene, &node_desc->materials[idx], &a );
-            egg_poly->set_color(LColor(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
-            egg_poly->set_color(LColor(1.0, 1.0, 1.0, 1.0));
-            softegg_cat.spam() << "default color\n";
-          }
-
-          /*
-          // keep a one to one copy in this node's vpool
-          EggVertex *t_vert = new EggVertex(vert);
-          if (!t_vert) {
-            softegg_cat.spam() << "out of memeory " << endl;
-            nassertv(t_vert != NULL);
-          }
-          node_desc->get_vpool()->add_vertex(t_vert, indices[i]);
-          */
-
-          softegg_cat.spam() << "\n";
-        }
-
-        // Now apply the shader.
-        if (node_desc->textures != nullptr) {
-          if (node_desc->numTexLoc && node_desc->numTexTri[idx]) {
-            if (!strstr(node_desc->texNameArray[idx], "noIcon"))
-              set_shader_attributes(node_desc, *egg_poly, idx);
-            else
-              softegg_cat.spam() << "texname :" << node_desc->texNameArray[idx] << endl;
-          }
-          else {
-            if (!strstr(node_desc->texNameArray[0], "noIcon"))
-              set_shader_attributes(node_desc, *egg_poly, 0);
-            else
-              softegg_cat.spam() << "texname :" << node_desc->texNameArray[0] << endl;
-        }
-      }
-      }
-      // if model has key shapes, generate vertex offsets
-      if ( numShapes > 0 && make_morph )
-        node_desc->make_vertex_offsets( numShapes);
-    }
-}
-
-/**
- * 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) {
-  int id = 0;
-  int i, j, k;
-  int numShapes;
-  SAA_Boolean valid;
-  SAA_Boolean visible;
-  PN_stdfloat *uCoords = nullptr;
-  PN_stdfloat *vCoords = nullptr;
-  string name = node_desc->get_name();
-
-  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 )) )
-    {
-      // Get the number of key shapes
-      SAA_modelGetNbShapes( &scene, node_desc->get_model(), &numShapes );
-      softegg_cat.spam() << "process_model_node: num shapes: " << numShapes << endl;
-
-      // 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);
-      vpool->set_highest_index(0);
-
-      // 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 != nullptr ) {
-        if ( strstr( modelNoteStr, "bface" ) != nullptr ) {
-          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 = nullptr;
-      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) {
-          PN_stdfloat 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(LColor(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(LColor(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 != nullptr) {
-        if (!strstr(node_desc->texNameArray[0], "noIcon"))
-          set_shader_attributes(node_desc, *eggNurbs, 0);
-        else
-          softegg_cat.spam() << "texname :" << node_desc->texNameArray[0] << endl;
-      }
-
-      // if model has key shapes, generate vertex offsets
-      if ( numShapes > 0 && make_morph )
-        node_desc->make_vertex_offsets( numShapes);
-    }
-}
-
-/**
- * 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;
-  }
-}
-
-/**
- * Given an egg vertex pool, map each vertex therein to a vertex within an
- * array of SAA model vertices of size numVert.  Mapping is done by closest
- * proximity.
- */
-int *SoftToEggConverter::
-FindClosestTriVert( EggVertexPool *vpool, SAA_DVector *vertices, int numVert ) {
-  int i,j;
-  int *vertMap = nullptr;
-  int vpoolSize = (int)vpool->size();
-  PN_stdfloat closestDist;
-  PN_stdfloat thisDist;
-  int closest;
-
-  vertMap = new int[vpoolSize];
-  i = 0;
-  EggVertexPool::iterator vi;
-  for (vi = vpool->begin(); vi != vpool->end(); ++vi, ++i) {
-    EggVertex *vert = (*vi);
-    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
-    for ( j = 0; j < numVert; j++ ) {
-      // calculate distance
-      thisDist = sqrtf(
-                       powf( p3d[0] - vertices[j].x , 2 ) +
-                       powf( p3d[1] - vertices[j].y , 2 ) +
-                       powf( p3d[2] - vertices[j].z , 2 ) );
-
-      // remember this if its the closest so far
-      if ( !j || ( thisDist < closestDist ) ) {
-        closest = j;
-        closestDist = thisDist;
-      }
-    }
-
-    vertMap[i] = closest;
-    softegg_cat.spam() << "mapping v " << i << " of " << vpoolSize-1 << ":( "
-                       << p3d[0] << " "
-                       << p3d[1] << " "
-                       << p3d[2] << ")\n";
-
-    softegg_cat.spam() << "    to cv " << closest << " of " << numVert-1 << ":( "
-                       << vertices[closest].x << " "
-                       << vertices[closest].y << " "
-                       << vertices[closest].z << " )\tdelta = " << closestDist << endl;
-  }
-  return vertMap;
-}
-
-/**
- * make soft skin assignments to the mesh finally call cleanup_soft_skin to
- * clean it up
- */
-bool SoftToEggConverter::
-make_soft_skin() {
-  int num_nodes = _tree.get_num_nodes();
-  SoftNodeDesc *node_desc;
-  SAA_Boolean isSkeleton;
-
-  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 );
-
-    softegg_cat.spam() << "??checking node " << node_desc->get_name() << " isSkel " << isSkeleton << " isJoint " << node_desc->is_joint() << endl;
-    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.
-
-      // check for envelops
-      int numEnv;
-      SAA_ModelType type;
-      SAA_Elem *envelopes;
-      SAA_Elem *model = node_desc->get_model();
-      EggGroup *joint = nullptr;
-      EggVertexPool *vpool;
-
-      SAA_skeletonGetNbEnvelopes( &scene, model, &numEnv );
-      if ( numEnv == 0 ) {
-        softegg_cat.spam() << "no soft skinning for joint " << node_desc->get_name() << endl;
-        continue;
-      }
-
-      // it's got envelopes - must be soft skinned
-      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 == nullptr ) {
-        softegg_cat.info() << "Out Of Memory" << endl;
-        exit(1);
-      }
-      int thisEnv;
-      SAA_EnvType envType;
-      bool hasEnvVertices = 0;
-
-      SAA_skeletonGetEnvelopes( &scene, model, numEnv, envelopes );
-      for ( thisEnv = 0; thisEnv < numEnv; thisEnv++ ) {
-        softegg_cat.spam() << "env[" << thisEnv << "]: ";
-        SAA_envelopeGetType( &scene, &envelopes[thisEnv], &envType );
-
-        if ( envType == SAA_ENVTYPE_NONE ) {
-          softegg_cat.spam() << "envType = none\n";
-        }
-        else if ( envType == SAA_ENVTYPE_FLXLCL ) {
-          softegg_cat.spam() << "envType = flexible, local\n";
-          hasEnvVertices = 1;
-        }
-        else if ( envType == SAA_ENVTYPE_FLXGLB ) {
-          softegg_cat.spam() << "envType = flexible, global\n";
-          hasEnvVertices = 1;
-        }
-        else if ( envType == SAA_ENVTYPE_RGDGLB ) {
-          softegg_cat.spam() << "envType = rigid, global\n";
-          hasEnvVertices = 1;
-        }
-        else {
-          softegg_cat.spam() << "envType = unknown\n";
-        }
-
-      }
-      if ( !hasEnvVertices )
-        continue;
-
-      SAA_SubElem *envVertices = nullptr;
-      int *numEnvVertices;
-      int i,j,k;
-
-      numEnvVertices = new int[numEnv];
-
-      if ( numEnvVertices != nullptr ) {
-        SAA_envelopeGetNbCtrlVertices( &scene, model, numEnv, envelopes, numEnvVertices );
-        int totalEnvVertices = 0;
-        for( i = 0; i < numEnv; i++ ) {
-          totalEnvVertices += numEnvVertices[i];
-          softegg_cat.spam() << "numEnvVertices[" << i << "] = " << numEnvVertices[i] << endl;
-        }
-        softegg_cat.spam() << "total env verts = " << totalEnvVertices << endl;
-        if ( totalEnvVertices == 0 )
-          continue;
-
-        envVertices = new SAA_SubElem[totalEnvVertices];
-        if ( envVertices != nullptr ) {
-          result = SAA_envelopeGetCtrlVertices( &scene, model,
-                                                numEnv, envelopes, numEnvVertices, envVertices);
-          if (result != SI_SUCCESS) {
-            softegg_cat.spam() << "error: GetCtrlVertices\n";
-            exit(1);
-          }
-          // loop through for each envelope
-          for ( i = 0; i < numEnv; i++ ) {
-            PN_stdfloat *weights = nullptr;
-            int vertArrayOffset = 0;
-            softegg_cat.spam() << "envelope[" << i << "]: ";
-            weights = new PN_stdfloat[numEnvVertices[i]];
-            if ( weights ) {
-              char *envName;
-              int *vpoolMap = nullptr;
-              for ( j = 0; j < i; j++ )
-                vertArrayOffset += numEnvVertices[j];
-              softegg_cat.spam() << "envVertArray offset = " << vertArrayOffset;
-
-              /*
-              if (vertArrayOffset == totalEnvVertices) {
-                softegg_cat.spam() << endl;                  vpoolMap = FindClosestTriVert( vpool, globalModelVertices, modelNumVert );
-
-                break;
-              }
-              */
-
-              // get the weights of the envelope vertices
-              result = SAA_ctrlVertexGetEnvelopeWeights( &scene, model, &envelopes[i],
-                                                         numEnvVertices[i],
-                                                         &envVertices[vertArrayOffset], weights );
-
-              // Get the name of the envelope model
-              if ( use_prefix ) {
-                // Get the FULL name of the envelope
-                envName = _tree.GetFullName( &scene, &envelopes[i] );
-              }
-              else {
-                // Get the name of the envelope
-                envName = _tree.GetName( &scene, &envelopes[i] );
-              }
-
-              softegg_cat.spam() << " envelop name is [" << envName << "]" << endl;
-
-              if (result != SI_SUCCESS) {
-                softegg_cat.spam() << "warning: this envelop doesn't have any weights\n";
-                continue;
-              }
-
-              result = SAA_modelGetType( &scene, &envelopes[i], &type );
-              if (result != SI_SUCCESS) {
-                softegg_cat.debug() << "choked on get type\n";
-                exit(1);
-              }
-
-              softegg_cat.spam() << "envelope model type ";
-              if ( type == SAA_MSMSH )
-                softegg_cat.spam() << "MESH\n";
-              else if ( type == SAA_MNSRF )
-                softegg_cat.spam() << "NURBS\n";
-              else
-                softegg_cat.spam() << "OTHER\n";
-
-              int *envVtxIndices = nullptr;
-              envVtxIndices = new int[numEnvVertices[i]];
-
-              // Get the envelope vertex indices
-              result = SAA_ctrlVertexGetIndices( &scene, &envelopes[i], numEnvVertices[i],
-                                                 &envVertices[vertArrayOffset], envVtxIndices );
-
-              if (result != SI_SUCCESS) {
-                softegg_cat.debug() << "error: choked on get indices\n";
-                exit(1);
-              }
-
-              // find out how many vertices the model has
-              int modelNumVert;
-
-              SAA_modelGetNbVertices( &scene, &envelopes[i], &modelNumVert );
-
-              SAA_DVector *modelVertices = nullptr;
-              modelVertices = new SAA_DVector[modelNumVert];
-
-              // get the model vertices
-              SAA_modelGetVertices( &scene, &envelopes[i],
-                                    SAA_GEOM_ORIGINAL, 0, modelNumVert,
-                                    modelVertices );
-
-              // create array of global model coords
-              SAA_DVector *globalModelVertices = nullptr;
-              globalModelVertices = new SAA_DVector[modelNumVert];
-              PN_stdfloat matrix[4][4];
-
-              // tranform local model vert coords to global
-
-              // first get the global matrix
-              SAA_modelGetMatrix( &scene, &envelopes[i], SAA_COORDSYS_GLOBAL,  matrix );
-
-              // populate array of global model verts
-              for ( j = 0; j < modelNumVert; j++ ) {
-                _VCT_X_MAT( globalModelVertices[j],
-                            modelVertices[j], matrix );
-              }
-
-              // Get the vpool
-              string s_name = envName;
-              SoftNodeDesc *mesh_node = find_node(s_name);
-              if (!mesh_node) {
-                softegg_cat.debug() << "error: node " << s_name << " not found in tree\n";
-                exit(1);
-              }
-              string vpool_name = s_name + ".verts";
-              EggNode *t = _tree.get_egg_root()->find_child(vpool_name);
-              if (t)
-                DCAST_INTO_R(vpool, t, nullptr);
-
-              // find the mapping of the vertices that match this envelop
-              if (vpool) {
-                softegg_cat.spam() << "found vpool of size " << vpool->size() << endl;
-                if ( !make_nurbs || (type == SAA_MSMSH) ) {
-                  vpoolMap = FindClosestTriVert( vpool, globalModelVertices, modelNumVert );
-                }
-              }
-              else {
-                softegg_cat.debug() << "warning: vpool " << vpool_name << " not found\n";
-                continue; // could be because of not visible
-              }
-
-              joint = node_desc->get_egg_group();
-              // for every envelope vertex
-              for (j = 0; j < numEnvVertices[i]; j++) {
-                double scaledWeight =  weights[j]/ 100.0f;
-
-                // make sure its in legal range
-                if (( envVtxIndices[j] < modelNumVert )
-                    && ( envVtxIndices[j] >= 0 )) {
-                  if ( (type == SAA_MNSRF) && make_nurbs ) {
-                    // assign all referenced control vertices
-                    EggVertex *vert = vpool->get_vertex(envVtxIndices[j]);
-                    if (!vert) {
-                      softegg_cat.debug() << "possible error: index " << envVtxIndices[j] << ": vert is " << vert << endl;
-                      continue;
-                    }
-                    joint->ref_vertex( vert, scaledWeight );
-                    softegg_cat.spam() << j << ": adding vref to cv " << envVtxIndices[j]
-                         << " with weight " << scaledWeight << endl;
-
-                    /*
-                    envPool->Vertex(envVtxIndices[j])->AddJoint( joint, scaledWeight );
-                    // set flag to show this vertex has been assigned
-                    envPool->Vertex(envVtxIndices[j])->multipleJoints = 1;
-                    */
-                  }
-                  else {
-                    // assign all the tri verts associated with this control
-                    // vertex to joint
-                    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) {
-                          softegg_cat.debug() << "possible error: index " << k+1 << ": vert is " << vert << endl;
-                          break;
-                        }
-
-                        joint->ref_vertex(vert, scaledWeight);
-                        softegg_cat.spam() << j << ": adding vref from cv " << envVtxIndices[j]
-                             << " to vert " << k+1 << " with weight " << scaledWeight
-                             << "(vpool)\n";
-                        /*
-                          envPool->Vertex(k)->AddJoint( joint, scaledWeight );
-                          // set flag to show this vertex has been assigned
-                          envPool->Vertex(k)->multipleJoints = 1;
-                        */
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-  return true;
-}
-/**
- * Given a model, make sure all its vertices have been soft assigned.  If not
- * hard assign to the last joint we saw.
- */
-bool SoftToEggConverter::
-cleanup_soft_skin()
-{
-  int num_nodes = _tree.get_num_nodes();
-  SoftNodeDesc *node_desc;
-
-  softegg_cat.spam() << endl << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
-
-  for (int i = 0; i < num_nodes; i++) {
-    node_desc = _tree.get_node(i);
-    if (node_desc->is_partial(search_prefix))
-      continue;
-
-    SAA_Elem *model = node_desc->get_model();
-    EggGroup *joint = nullptr;
-    EggVertexPool *vpool = nullptr;
-    SAA_ModelType type;
-
-    // find out what type of node we're dealing with
-
-    SAA_modelGetType( &scene, model, &type );
-
-    softegg_cat.debug() << "Cleaning up model------- " << node_desc->get_name() << endl;
-
-    // this step is weird - I think I want it here but it seems to break some
-    // models.  Files like props-props_wh_cookietime.3-0 in
-    // fulrndpubvrmlchipchips_adventurecharzone1roomswarehouse_final need to
-    // do the "if (skel)" bit.
-
-    // find the vpool for this model
-    string vpool_name = node_desc->get_name() + ".verts";
-    EggNode *t = _tree.get_egg_root()->find_child(vpool_name);
-    if (t)
-      DCAST_INTO_R(vpool, t, nullptr);
-
-    if (!vpool) {
-      // softegg_cat.spam() << "couldn't find vpool " << vpool_name << endl;
-      continue;
-    }
-
-    int numVerts = (int)vpool->size();
-    softegg_cat.spam() << "found vpool " << vpool_name << " w/ " << numVerts << " verts\n";
-
-    // if this node is a joint, then these vertices belong to this joint
-    if (node_desc->is_joint())
-      joint = node_desc->get_egg_group();
-    else {
-      // find the closest _parentJoint
-      SoftNodeDesc *parentJ = node_desc;
-      while( parentJ && !parentJ->_parentJoint) {
-        if ( parentJ->_parent) {
-          SAA_Boolean isSkeleton;
-          // softegg_cat.spam() << " checking parent " <<
-          // parentJ->_parent->get_name() << endl;
-          if (parentJ->_parent->has_model())
-            SAA_modelIsSkeleton( &scene, parentJ->_parent->get_model(), &isSkeleton );
-
-          if (isSkeleton) {
-            joint = parentJ->_parent->get_egg_group();
-            softegg_cat.spam() << "parent to " << parentJ->_parent->get_name() << endl;
-            break;
-          }
-
-          parentJ = parentJ->_parent;
-        }
-        else
-          break;
-      }
-      if (!joint && (!parentJ || !parentJ->_parentJoint)) {
-        softegg_cat.spam() << node_desc->get_name() << " has no _parentJoint?!" << endl;
-        continue;
-      }
-
-      if (!joint) {
-        softegg_cat.spam() << "parent joint to " << parentJ->_parentJoint->get_name() << endl;
-        joint = parentJ->_parentJoint->get_egg_group();
-      }
-    }
-    EggVertexPool::iterator vi;
-    double membership = 1.0f;
-    for ( vi = vpool->begin(); vi != vpool->end(); ++vi) {
-      EggVertex *vert = (*vi);
-
-      // if this vertex has not been soft assigned, then hard assign it to the
-      // parentJoint
-      if ( vert->gref_size() == 0 ) {
-
-        softegg_cat.spam() << "vert " << vert->get_external_index() << " not assigned!\n";
-
-        // hard skin this vertex
-        joint->ref_vertex( vert, 1.0f );
-      }
-    }
-  }
-  return true;
-}
-
-/**
- * Applies the known shader attributes to the indicated egg primitive.
- */
-void SoftToEggConverter::
-set_shader_attributes(SoftNodeDesc *node_desc, EggPrimitive &primitive, int idx) {
-  char *texName = node_desc->texNameArray[idx];
-  EggTexture tex(texName, "");
-
-  Filename filename = Filename::from_os_specific(texName);
-  Filename fullpath = _path_replace->match_path(filename, get_model_path());
-  tex.set_filename(_path_replace->store_path(fullpath));
-  tex.set_fullpath(fullpath);
-  // tex.set_format(EggTexture::F_rgb);
-  apply_texture_properties(tex, node_desc->uRepeat[idx], node_desc->vRepeat[idx]);
-
-  EggTexture *new_tex = _textures.create_unique_texture(tex, ~EggTexture::E_tref_name);
-  primitive.set_texture(new_tex);
-}
-
-/**
- * Applies all the appropriate texture properties to the EggTexture object,
- * including wrap modes and texture matrix.
- */
-void SoftToEggConverter::
-apply_texture_properties(EggTexture &tex, int uRepeat, int vRepeat) {
-  // Let's mipmap all textures by default.
-  tex.set_minfilter(EggTexture::FT_linear_mipmap_linear);
-  tex.set_magfilter(EggTexture::FT_linear);
-
-  EggTexture::WrapMode wrap_u = uRepeat > 0 ? EggTexture::WM_repeat : EggTexture::WM_clamp;
-  EggTexture::WrapMode wrap_v = vRepeat > 0 ? EggTexture::WM_repeat : EggTexture::WM_clamp;
-
-  tex.set_wrap_u(wrap_u);
-  tex.set_wrap_v(wrap_v);
-  /*
-  LMatrix3d mat = color_def.compute_texture_matrix();
-  if (!mat.almost_equal(LMatrix3d::ident_mat())) {
-    tex.set_transform(mat);
-  }
-  */
-}
-#if 0
-/**
- * Compares the texture properties already on the texture (presumably set by a
- * previous call to apply_texture_properties()) and returns false if they
- * differ from that specified by the indicated color_def object, or true if
- * they match.
- */
-bool SoftToEggConverter::
-compare_texture_properties(EggTexture &tex,
-                           const SoftShaderColorDef &color_def) {
-  bool okflag = true;
-
-  EggTexture::WrapMode wrap_u = color_def._wrap_u ? EggTexture::WM_repeat : EggTexture::WM_clamp;
-  EggTexture::WrapMode wrap_v = color_def._wrap_v ? EggTexture::WM_repeat : EggTexture::WM_clamp;
-
-  if (wrap_u != tex.determine_wrap_u()) {
-    // Choose the more general of the two.
-    if (wrap_u == EggTexture::WM_repeat) {
-      tex.set_wrap_u(wrap_u);
-    }
-    okflag = false;
-  }
-  if (wrap_v != tex.determine_wrap_v()) {
-    if (wrap_v == EggTexture::WM_repeat) {
-      tex.set_wrap_v(wrap_v);
-    }
-    okflag = false;
-  }
-
-  LMatrix3d mat = color_def.compute_texture_matrix();
-  if (!mat.almost_equal(tex.get_transform())) {
-    okflag = false;
-  }
-
-  return okflag;
-}
-#endif
-/**
- * Recursively walks the egg hierarchy, reparenting "decal" type nodes below
- * their corresponding "decalbase" type nodes, and setting the flags.
- *
- * Returns true on success, false if some nodes were incorrect.
- */
-bool SoftToEggConverter::
-reparent_decals(EggGroupNode *egg_parent) {
-  bool okflag = true;
-
-  // First, walk through all children of this node, looking for the one decal
-  // base, if any.
-  EggGroup *decal_base = nullptr;
-  pvector<EggGroup *> decal_children;
-
-  EggGroupNode::iterator ci;
-  for (ci = egg_parent->begin(); ci != egg_parent->end(); ++ci) {
-    EggNode *child =  (*ci);
-    if (child->is_of_type(EggGroup::get_class_type())) {
-      EggGroup *child_group = DCAST(EggGroup, child);
-      if (child_group->has_object_type("decalbase")) {
-        if (decal_base != nullptr) {
-          softegg_cat.error()
-            << "Two children of " << egg_parent->get_name()
-            << " both have decalbase set: " << decal_base->get_name()
-            << " and " << child_group->get_name() << "\n";
-          okflag = false;
-        }
-        child_group->remove_object_type("decalbase");
-        decal_base = child_group;
-
-      } else if (child_group->has_object_type("decal")) {
-        child_group->remove_object_type("decal");
-        decal_children.push_back(child_group);
-      }
-    }
-  }
-
-  if (decal_base == nullptr) {
-    if (!decal_children.empty()) {
-      softegg_cat.warning()
-        << decal_children.front()->get_name()
-        << " has decal, but no sibling node has decalbase.\n";
-    }
-
-  } else {
-    if (decal_children.empty()) {
-      softegg_cat.warning()
-        << decal_base->get_name()
-        << " has decalbase, but no sibling nodes have decal.\n";
-
-    } else {
-      // All the decal children get moved to be a child of decal base.  This
-      // usually will not affect the vertex positions, but it could if the
-      // decal base has a transform and the decal child is an instance node.
-      // So don't do that.
-      pvector<EggGroup *>::iterator di;
-      for (di = decal_children.begin(); di != decal_children.end(); ++di) {
-        EggGroup *child_group = (*di);
-        decal_base->add_child(child_group);
-      }
-
-      // Also set the decal state on the base.
-      decal_base->set_decal_flag(true);
-    }
-  }
-
-  // Now recurse on each of the child nodes.
-  for (ci = egg_parent->begin(); ci != egg_parent->end(); ++ci) {
-    EggNode *child =  (*ci);
-    if (child->is_of_type(EggGroupNode::get_class_type())) {
-      EggGroupNode *child_group = DCAST(EggGroupNode, child);
-      if (!reparent_decals(child_group)) {
-        okflag = false;
-      }
-    }
-  }
-
-  return okflag;
-}
-
-/**
- * Returns the TransformType value corresponding to the indicated string, or
- * TT_invalid.
- */
-SoftToEggConverter::TransformType SoftToEggConverter::
-string_transform_type(const string &arg) {
-  if (cmp_nocase(arg, "all") == 0) {
-    return TT_all;
-  } else if (cmp_nocase(arg, "model") == 0) {
-    return TT_model;
-  } else if (cmp_nocase(arg, "dcs") == 0) {
-    return TT_dcs;
-  } else if (cmp_nocase(arg, "none") == 0) {
-    return TT_none;
-  } else {
-    return TT_invalid;
-  }
-}
-
-/**
- * Invokes the softToEggConverter class
- */
-extern "C" int init_soft2egg(int argc, char **argv) {
-  stec._commandName = argv[0];
-  stec.rsrc_path = "c:\\Softimage\\SOFT3D_3.9.2\\3D\\rsrc";
-
-  if (stec.DoGetopts(argc, argv)) {
-    // Create a Filename object and convert the file
-    Filename softFile(argv[1]);
-    stec.convert_file(softFile);
-  }
-
-  return 0;
-}

+ 0 - 179
pandatool/src/softegg/softToEggConverter.h

@@ -1,179 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file softToEggConverter.h
- * @author masad
- * @date 2003-09-25
- */
-
-#ifndef SOFTTOEGGCONVERTER_H
-#define SOFTTOEGGCONVERTER_H
-
-#include "pandatoolbase.h"
-#include "somethingToEggConverter.h"
-#include "softNodeTree.h"
-
-#include "eggTextureCollection.h"
-#include "distanceUnit.h"
-#include "coordinateSystem.h"
-
-#ifdef _MIN
-#undef _MIN
-#endif
-#ifdef _MAX
-#undef _MAX
-#endif
-
-#include <SAA.h>
-#include <SI_macros.h>
-
-class EggData;
-class EggGroup;
-class EggTable;
-class EggVertexPool;
-class EggNurbsCurve;
-class EggPrimitive;
-class EggXfmSAnim;
-class EggSAnimData;
-
-
-/**
- * This class supervises the construction of an EggData structure from a
- * single Softimage file, or from the data already in th    cout << "egg name
- * = " << eggFilename << endl;e global Softimage model space.
- *
- */
-class SoftToEggConverter : public SomethingToEggConverter {
-public:
-  SoftToEggConverter(const std::string &program_name = "");
-  SoftToEggConverter(const SoftToEggConverter &copy);
-  virtual ~SoftToEggConverter();
-
-  void Help();
-  void Usage();
-  void ShowOpts();
-
-  bool HandleGetopts(int &idx, int argc, char **argv);
-  bool DoGetopts(int &argc, char **&argv);
-
-  SoftNodeDesc *find_node(std::string name);
-  int *FindClosestTriVert( EggVertexPool *vpool, SAA_DVector *vertices, int numVert );
-
-  virtual SomethingToEggConverter *make_copy();
-  virtual std::string get_name() const;
-  virtual std::string get_extension() const;
-
-  virtual bool convert_file(const Filename &filename);
-  bool convert_soft(bool from_selection);
-  bool open_api();
-  void close_api();
-
-private:
-  bool convert_flip(double start_frame, double end_frame,
-                    double frame_inc, double output_frame_rate);
-
-  bool make_soft_skin();
-  bool cleanup_soft_skin();
-  bool convert_char_chan();
-  bool convert_char_model();
-  bool convert_hierarchy(EggGroupNode *egg_root);
-  bool process_model_node(SoftNodeDesc *node_desc);
-
-  void make_polyset(SoftNodeDesc *node_desc, EggGroup *egg_group, SAA_ModelType type);
-  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, int idx);
-  void apply_texture_properties(EggTexture &tex, int uRepeat, int vRepeat);
-
-  bool reparent_decals(EggGroupNode *egg_parent);
-
-  std::string _program_name;
-  bool _from_selection;
-
-  SI_Error            result;
-  SAA_Elem            model;
-  SAA_Database        database;
-
-public:
-
-  SoftNodeTree _tree;
-
-  SAA_Scene           scene;
-
-  char *_getopts;
-
-  // This is argv[0].
-  const char *_commandName;
-
-  // This is the entire command line.
-  char _commandLine[4096];
-
-  char        *rsrc_path;
-  char        *database_name;
-  char        *scene_name;
-  char        *model_name;
-  char        *eggFileName;
-  char        *animFileName;
-  char        *eggGroupName;
-  char        *tex_path;
-  char        *tex_filename;
-  char        *search_prefix;
-
-  int                    nurbs_step;
-  int                    anim_start;
-  int                    anim_end;
-  int                    anim_rate;
-  int                    pose_frame;
-  int                    verbose;
-  int                    flatten;
-  int                    shift_textures;
-  int                    ignore_tex_offsets;
-  int                    use_prefix;
-
-  bool                foundRoot;
-  bool                geom_as_joint;
-  bool                make_anim;
-  bool                make_nurbs;
-  bool                make_poly;
-  bool                make_soft;
-  bool                make_morph;
-  bool                make_duv;
-  bool                make_dart;
-  bool                has_morph;
-  bool                make_pose;
-
-
-  char *GetTextureName( SAA_Scene *scene, SAA_Elem *texture );
-
-  EggTextureCollection _textures;
-
-  bool _polygon_output;
-  double _polygon_tolerance;
-
-  enum TransformType {
-    TT_invalid,
-    TT_all,
-    TT_model,
-    TT_dcs,
-    TT_none,
-  };
-  TransformType _transform_type;
-
-  static TransformType string_transform_type(const std::string &arg);
-
-  typedef pvector<EggSAnimData *> MorphTable;
-  MorphTable _morph_table;
-
-  EggTable *morph_node;
-  EggSAnimData *find_morph_table(char *name);
-};
-
-extern const int TEX_PER_MAT;
-
-#endif

+ 0 - 588
pandatool/src/softprogs/softCVS.cxx

@@ -1,588 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file softCVS.cxx
- * @author drose
- * @date 2000-11-10
- */
-
-#include "softCVS.h"
-
-#include "pnotify.h"
-#include "multifile.h"
-
-#include <algorithm>
-
-using std::string;
-
-/**
- *
- */
-SoftCVS::
-SoftCVS() {
-  _cvs_binary = "cvs";
-
-  set_program_brief("prepare a SoftImage database directory for adding to CVS");
-  set_program_description
-    ("softcvs is designed to prepare a directory hierarchy "
-     "representing a SoftImage database for adding to CVS.  "
-     "First, it eliminates SoftImage's silly filename-based "
-     "versioning system by renaming versioned filenames higher "
-     "than 1-0 back to version 1-0.  Then, it rolls up all the "
-     "files for each scene except the texture images into a Panda "
-     "multifile, which is added to CVS; the texture images are "
-     "directly added to CVS where they are.\n\n"
-
-     "The reduction of hundreds of SoftImage files per scene down to one "
-     "multifile and a handle of texture images should greatly improve "
-     "the update and commit times of CVS.\n\n"
-
-     "You must run this from within the root of a SoftImage database "
-     "directory; e.g. the directory that contains SCENES, PICTURES, MODELS, "
-     "and so on.");
-
-  clear_runlines();
-  add_runline("[opts]");
-
-  add_option
-    ("nc", "", 80,
-     "Do not attempt to add newly-created files to CVS.  The default "
-     "is to add them.",
-     &SoftCVS::dispatch_none, &_no_cvs);
-
-  add_option
-    ("cvs", "cvs_binary", 80,
-     "Specify how to run the cvs program for adding newly-created files.  "
-     "The default is simply \"cvs\".",
-     &SoftCVS::dispatch_string, nullptr, &_cvs_binary);
-}
-
-
-/**
- *
- */
-void SoftCVS::
-run() {
-  // First, check for the scenes directory.  If it doesn't exist, we must not
-  // be in the root of a soft database.
-  Filename scenes = "SCENES/.";
-  if (!scenes.exists()) {
-    nout << "No SCENES directory found; you are not in the root of a "
-      "SoftImage database.\n";
-    exit(1);
-  }
-
-  // Also, if we're expecting to use CVS, make sure the CVS directory exists.
-  Filename cvs_entries = "CVS/Entries";
-  if (!_no_cvs && !cvs_entries.exists()) {
-    nout << "You do not appear to be within a CVS-controlled source "
-      "directory.\n";
-    exit(1);
-  }
-
-  // Scan all the files in the database.
-  traverse_root();
-
-  // Collapse out the higher-versioned scene files.
-  collapse_scene_files();
-
-  // Now determine which element files are actually referenced by at least one
-  // of the scene files.
-  if (!get_scenes()) {
-    exit(1);
-  }
-
-  // Finally, remove all the element files that are no longer referenced by
-  // any scenes.
-  remove_unused_elements();
-
-  // Now do all the cvs adding and removing we need.
-  if (!_no_cvs) {
-    cvs_add_or_remove("remove", _cvs_remove);
-    cvs_add_or_remove("add -kb", _cvs_add);
-  }
-}
-
-/**
- * Reads all of the toplevel directory names, e.g.  SCENES, MATERIALS, etc.,
- * and traverses them.
- */
-void SoftCVS::
-traverse_root() {
-  Filename root(".");
-
-  // Get the list of subdirectories.
-  vector_string subdirs;
-  if (!root.scan_directory(subdirs)) {
-    nout << "Unable to scan directory.\n";
-    return;
-  }
-
-  vector_string::const_iterator di;
-  for (di = subdirs.begin(); di != subdirs.end(); ++di) {
-    Filename subdir = (*di);
-    if (subdir.is_directory() && subdir != "CVS") {
-      traverse_subdir(subdir);
-    }
-  }
-}
-
-/**
- * Reads the directory indicated by prefix and identifies all of the SoftImage
- * files stored there.
- */
-void SoftCVS::
-traverse_subdir(const Filename &directory) {
-  // Get the list of files in the directory.
-  vector_string files;
-  if (!directory.scan_directory(files)) {
-    nout << "Unable to scan directory " << directory << "\n";
-    return;
-  }
-
-  // We need to know the set of files in this directory that are CVS elements.
-  pset<string> cvs_elements;
-  bool in_cvs = false;
-  if (!_no_cvs) {
-    in_cvs = scan_cvs(directory, cvs_elements);
-  }
-
-  bool is_scenes = false;
-  bool keep_all = false;
-  bool wants_cvs = false;
-
-  // Now make some special-case behavior based on the particular SoftImage
-  // subdirectory we're in.
-  string dirname = directory.get_basename();
-  if (dirname == "SCENES") {
-    is_scenes = true;
-
-  } else if (dirname == "CAMERAS") {
-    // We don't want anything in the cameras directory.  These may change
-    // arbitrarily and have no bearing on the model or animation that we will
-    // extract, so avoid them altogether.
-    return;
-
-  } else if (dirname == "PICTURES") {
-    // In the pictures directory, we must keep everything, since the scene
-    // files don't explicitly reference these but they're still important.
-    // Textures that are no longer used will pile up; we leave this as the
-    // user's problem.
-
-    // We not only keep the textures, but we also move them into CVS, since
-    // (again) they're not part of the scene files and thus won't get added to
-    // the multifiles.  Also, some textures are shared between different
-    // scenes, and it would be wasteful to add them to each scene multifile;
-    // furthermore, some scenes are used for animation only, and we don't want
-    // to modify these multifiles when the textures change.
-
-    keep_all = true;
-    wants_cvs = !_no_cvs;
-  }
-
-  vector_string::const_iterator fi;
-  for (fi = files.begin(); fi != files.end(); ++fi) {
-    const string &filename = (*fi);
-    if (filename == "CVS") {
-      // This special filename is not to be considered.
-
-    } else if (filename == "Chapter.rsrc") {
-      // This special filename should not be considered, except to add it to
-      // the multifiles.
-      _global_files.push_back(Filename(directory, filename));
-
-    } else {
-      SoftFilename soft(directory, filename);
-
-      if (cvs_elements.count(filename) != 0) {
-        // This file is known to be in CVS.
-        soft.set_in_cvs(true);
-      }
-
-      if (keep_all) {
-        soft.increment_use_count();
-      }
-      if (wants_cvs && !in_cvs) {
-        // Try to CVSify the directory.
-        cvs_add(directory);
-        in_cvs = true;
-      }
-      soft.set_wants_cvs(wants_cvs);
-
-      if (is_scenes && soft.has_version() && soft.get_extension() == ".dsc") {
-        _scene_files.push_back(soft);
-      } else {
-        _element_files.insert(soft);
-      }
-    }
-  }
-}
-
-/**
- * Walks through the list of scene files found, and renames the higher-
- * versioned ones to version 1-0, removing the intervening versions.
- */
-void SoftCVS::
-collapse_scene_files() {
-  // Get a copy of the scene files vector so we can modify it.  Also empty out
-  // the _scene_files at the same time so we can fill it up again.
-  SceneFiles versions;
-  versions.swap(_scene_files);
-
-  // And sort them into order so we can easily compare higher and lower
-  // versions.
-  sort(versions.begin(), versions.end());
-
-  SceneFiles::iterator vi;
-  vi = versions.begin();
-  while (vi != versions.end()) {
-    SoftFilename &file = (*vi);
-
-    if (!file.is_1_0()) {
-      // Here's a file that needs to be renamed.  But first, identify all the
-      // other versions of the same file.
-      SceneFiles::iterator start_vi;
-      start_vi = vi;
-      while (vi != versions.end() && (*vi).is_same_file(file)) {
-        ++vi;
-      }
-
-      rename_file(start_vi, vi);
-
-    } else {
-      ++vi;
-    }
-
-    file.make_1_0();
-    _scene_files.push_back(file);
-  }
-}
-
-/**
- * Walks through the list of scene files and looks for the set of element
- * files referenced by each one, updating multifile accordingly.
- */
-bool SoftCVS::
-get_scenes() {
-  bool okflag = true;
-
-  // We will be added the multifiles to CVS if they're not already added, so
-  // we have to know which files are in CVS already.
-  pset<string> cvs_elements;
-  if (!_no_cvs) {
-    scan_cvs(".", cvs_elements);
-  }
-
-  SceneFiles::const_iterator vi;
-  for (vi = _scene_files.begin(); vi != _scene_files.end(); ++vi) {
-    const SoftFilename &sf = (*vi);
-    Filename file(sf.get_dirname(), sf.get_filename());
-
-    file.set_text();
-    std::ifstream in;
-    if (!file.open_read(in)) {
-      nout << "Unable to read " << file << "\n";
-    } else {
-      nout << "Scanning " << file << "\n";
-
-      Multifile multifile;
-      Filename multifile_name = sf.get_base() + "mf";
-
-      if (!multifile.open_read_write(multifile_name)) {
-        nout << "Unable to open " << multifile_name << " for updating.\n";
-        okflag = false;
-
-      } else {
-        if (!scan_scene_file(in, multifile)) {
-          okflag = false;
-        }
-
-        // Add all the global files to the multifile too.  These probably
-        // can't take compression (since in SoftImage they're just the
-        // Chapter.rsrc files, each very tiny).
-        vector_string::const_iterator gi;
-        for (gi = _global_files.begin(); gi != _global_files.end(); ++gi) {
-          if (multifile.update_subfile((*gi), (*gi), 0).empty()) {
-            nout << "Unable to add " << (*gi) << "\n";
-            okflag = false;
-          }
-        }
-
-        // Also add the scene file itself.
-        if (multifile.update_subfile(file, file, 6).empty()) {
-          nout << "Unable to add " << file << "\n";
-          okflag = false;
-        }
-
-        bool flushed = false;
-        if (multifile.needs_repack()) {
-          flushed = multifile.repack();
-        } else {
-          flushed = multifile.flush();
-        }
-        if (!flushed) {
-          nout << "Failed to write " << multifile_name << ".\n";
-          okflag = false;
-        } else {
-          nout << "Wrote " << multifile_name << ".\n";
-
-          if (!_no_cvs && cvs_elements.count(multifile_name) == 0) {
-            // Add the multifile to CVS.
-            _cvs_add.push_back(multifile_name);
-          }
-        }
-      }
-    }
-  }
-
-  return okflag;
-}
-
-
-/**
- * Remove all the element files that weren't referenced by any scene file.
- * Also plan to cvs add all those that were referenced.
- */
-void SoftCVS::
-remove_unused_elements() {
-  ElementFiles::const_iterator fi;
-  for (fi = _element_files.begin(); fi != _element_files.end(); ++fi) {
-    const SoftFilename &sf = (*fi);
-    Filename file(sf.get_dirname(), sf.get_filename());
-
-    if (sf.get_use_count() == 0) {
-      nout << file << " is unused.\n";
-
-      if (!file.unlink()) {
-        nout << "Unable to remove " << file << ".\n";
-
-      } else if (sf.get_in_cvs()) {
-        _cvs_remove.push_back(file);
-      }
-
-    } else if (sf.get_wants_cvs() && !sf.get_in_cvs()) {
-      _cvs_add.push_back(file);
-    }
-  }
-}
-
-
-/**
- * Renames the first file in the indicated list to a version 1-0 filename,
- * superceding all the other files in the list.  Returns true if the file is
- * renamed, false otherwise.
- */
-bool SoftCVS::
-rename_file(SoftCVS::SceneFiles::iterator begin,
-            SoftCVS::SceneFiles::iterator end) {
-  int length = end - begin;
-  nassertr(length > 0, false);
-
-  SoftFilename &orig = (*begin);
-
-  string dirname = orig.get_dirname();
-  string source_filename = orig.get_filename();
-  string dest_filename = orig.get_1_0_filename();
-
-  if (length > 2) {
-    nout << source_filename << " supercedes:\n";
-    SceneFiles::const_iterator p;
-    for (p = begin + 1; p != end; ++p) {
-      nout << "  " << (*p).get_filename() << "\n";
-    }
-
-  } else if (length == 2) {
-    nout << source_filename << " supercedes "
-         << (*(begin + 1)).get_filename() << ".\n";
-
-  } else {
-    nout << source_filename << " renamed.\n";
-  }
-
-  // Now remove all of the "wrong" files.
-
-  SceneFiles::const_iterator p;
-  for (p = begin + 1; p != end; ++p) {
-    Filename file((*p).get_dirname(), (*p).get_filename());
-    if (!file.unlink()) {
-      nout << "Unable to remove " << file << ".\n";
-    }
-  }
-
-  // And rename the good one.
-  Filename source(dirname, source_filename);
-  Filename dest(dirname, dest_filename);
-
-  if (!source.rename_to(dest)) {
-    nout << "Unable to rename " << source << " to " << dest_filename << ".\n";
-    exit(1);
-  }
-
-  return true;
-}
-
-/**
- * Scans the CVS repository in the indicated directory to determine which
- * files are already versioned elements.  Returns true if the directory is
- * CVS-controlled, false otherwise.
- */
-bool SoftCVS::
-scan_cvs(const string &dirname, pset<string> &cvs_elements) {
-  Filename cvs_entries = dirname + "/CVS/Entries";
-  if (!cvs_entries.exists()) {
-    return false;
-  }
-
-  std::ifstream in;
-  cvs_entries.set_text();
-  if (!cvs_entries.open_read(in)) {
-    nout << "Unable to read CVS directory.\n";
-    return true;
-  }
-
-  string line;
-  std::getline(in, line);
-  while (!in.fail() && !in.eof()) {
-    if (!line.empty() && line[0] == '/') {
-      size_t slash = line.find('/', 1);
-      if (slash != string::npos) {
-        string filename = line.substr(1, slash - 1);
-
-        if (line.substr(slash + 1, 2) == "-1") {
-          // If the first number after the slash is -1, the file used to be
-          // here but was recently cvs removed.  It counts as no longer being
-          // an element.
-        } else {
-          cvs_elements.insert(filename);
-        }
-      }
-    }
-
-    std::getline(in, line);
-  }
-
-  return true;
-}
-
-/**
- * Reads a scene file, looking for references to element files.  For each
- * reference found, increments the appropriate element file's reference count.
- */
-bool SoftCVS::
-scan_scene_file(std::istream &in, Multifile &multifile) {
-  bool okflag = true;
-
-  int c = in.get();
-  while (!in.eof() && !in.fail()) {
-    // Skip whitespace.
-    while (isspace(c) && !in.eof() && !in.fail()) {
-      c = in.get();
-    }
-
-    // Now begin a word.
-    string word;
-    while (!isspace(c) && !in.eof() && !in.fail()) {
-      word += c;
-      c = in.get();
-    }
-
-    if (!word.empty()) {
-      SoftFilename v("", word);
-
-      // Increment the use count on all matching elements of the multiset.
-      std::pair<ElementFiles::iterator, ElementFiles::iterator> range;
-      range = _element_files.equal_range(v);
-
-      ElementFiles::iterator ei;
-      for (ei = range.first; ei != range.second; ++ei) {
-        // We cheat and get a non-const reference to the filename out of the
-        // set.  We can safely do this because incrementing the use count
-        // won't change its position in the set.
-        SoftFilename &sf = (SoftFilename &)(*ei);
-        sf.increment_use_count();
-
-        Filename file(sf.get_dirname(), sf.get_filename());
-        if (multifile.update_subfile(file, file, 6).empty()) {
-          nout << "Unable to add " << file << "\n";
-          okflag = false;
-        }
-      }
-    }
-  }
-
-  return okflag;
-}
-
-/**
- * Invokes CVS to add just the named file to the repository.  Returns true on
- * success, false on failure.
- */
-bool SoftCVS::
-cvs_add(const string &path) {
-  string command = _cvs_binary + " add -kb " + path;
-  nout << command << "\n";
-  int result = system(command.c_str());
-
-  if (result != 0) {
-    nout << "Failure invoking cvs.\n";
-    return false;
-  }
-  return true;
-}
-
-/**
- * Invokes CVS to add (or remove) all of the files in the indicated vector.
- * Returns true on success, false on failure.
- */
-bool SoftCVS::
-cvs_add_or_remove(const string &cvs_command, const vector_string &paths) {
-  static const int max_command = 4096;
-
-  if (!paths.empty()) {
-    string command = _cvs_binary + " " + cvs_command;
-    vector_string::const_iterator pi;
-    pi = paths.begin();
-    while (pi != paths.end()) {
-      const string &path = (*pi);
-
-      if ((int)command.length() + 1 + (int)path.length() >= max_command) {
-        // Fire off the command now.
-        nout << command << "\n";
-        int result = system(command.c_str());
-
-        if (result != 0) {
-          nout << "Failure invoking cvs.\n";
-          return false;
-        }
-
-        command = _cvs_binary + " " + cvs_command;
-      }
-
-      command += ' ';
-      command += path;
-
-      ++pi;
-    }
-    nout << command << "\n";
-    int result = system(command.c_str());
-
-    if (result != 0) {
-      nout << "Failure invoking cvs.\n";
-      return false;
-    }
-  }
-  return true;
-}
-
-
-int main(int argc, char *argv[]) {
-  SoftCVS prog;
-  prog.parse_command_line(argc, argv);
-  prog.run();
-  return 0;
-}

+ 0 - 70
pandatool/src/softprogs/softCVS.h

@@ -1,70 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file softCVS.h
- * @author drose
- * @date 2000-11-10
- */
-
-#ifndef SOFTCVS_H
-#define SOFTCVS_H
-
-#include "pandatoolbase.h"
-
-#include "softFilename.h"
-
-#include "programBase.h"
-#include "vector_string.h"
-#include "filename.h"
-
-#include "pvector.h"
-#include "pset.h"
-
-class Multifile;
-
-/**
- * This program prepares a SoftImage database for CVS by renaming everything
- * to version 1-0, and adding new files to CVS.
- */
-class SoftCVS : public ProgramBase {
-public:
-  SoftCVS();
-
-  void run();
-
-private:
-  typedef pvector<SoftFilename> SceneFiles;
-  typedef pmultiset<SoftFilename> ElementFiles;
-
-  void traverse_root();
-  void traverse_subdir(const Filename &directory);
-
-  void collapse_scene_files();
-  bool get_scenes();
-  void remove_unused_elements();
-
-  bool rename_file(SceneFiles::iterator begin, SceneFiles::iterator end);
-  bool scan_cvs(const std::string &dirname, pset<std::string> &cvs_elements);
-  bool scan_scene_file(std::istream &in, Multifile &multifile);
-
-  bool cvs_add(const std::string &path);
-  bool cvs_add_or_remove(const std::string &cvs_command,
-                         const vector_string &paths);
-
-  SceneFiles _scene_files;
-  ElementFiles _element_files;
-  vector_string _global_files;
-
-  vector_string _cvs_add;
-  vector_string _cvs_remove;
-
-  bool _no_cvs;
-  std::string _cvs_binary;
-};
-
-#endif

+ 0 - 291
pandatool/src/softprogs/softFilename.cxx

@@ -1,291 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file softFilename.cxx
- * @author drose
- * @date 2000-11-10
- */
-
-#include "softFilename.h"
-
-#include "pnotify.h"
-
-using std::string;
-
-/**
- *
- */
-SoftFilename::
-SoftFilename(const string &dirname, const string &filename) :
-  _dirname(dirname),
-  _filename(filename)
-{
-  _has_version = false;
-  _major = 0;
-  _minor = 0;
-  _in_cvs = false;
-  _wants_cvs = false;
-  _use_count = 0;
-
-  _base = _filename;
-
-  // Scan for a version number and an optional extension after each dot in the
-  // filename.
-  size_t dot = _filename.find('.');
-  while (dot != string::npos) {
-    size_t m = dot + 1;
-    const char *fstr = _filename.c_str();
-    char *endptr;
-    // Check for a numeric version number.
-    int major = strtol(fstr + m , &endptr, 10);
-    if (endptr != fstr + m && *endptr == '-') {
-      // We got a major number, is there a minor number?
-      m = (endptr - fstr) + 1;
-      int minor = strtol(fstr + m, &endptr, 10);
-      if (endptr != fstr + m && (*endptr == '.' || *endptr == '\0')) {
-        // We got a minor number too!
-        _has_version = true;
-        _base = _filename.substr(0, dot + 1);
-        _major = major;
-        _minor = minor;
-        _ext = endptr;
-        return;
-      }
-    }
-
-    // That wasn't a version number.  Is there more?
-    dot = _filename.find('.', dot + 1);
-  }
-}
-
-/**
- *
- */
-SoftFilename::
-SoftFilename(const SoftFilename &copy) :
-  _dirname(copy._dirname),
-  _filename(copy._filename),
-  _has_version(copy._has_version),
-  _base(copy._base),
-  _major(copy._major),
-  _minor(copy._minor),
-  _ext(copy._ext),
-  _in_cvs(copy._in_cvs),
-  _wants_cvs(copy._wants_cvs),
-  _use_count(copy._use_count)
-{
-}
-
-/**
- *
- */
-void SoftFilename::
-operator = (const SoftFilename &copy) {
-  _dirname = copy._dirname;
-  _filename = copy._filename;
-  _has_version = copy._has_version;
-  _base = copy._base;
-  _major = copy._major;
-  _minor = copy._minor;
-  _ext = copy._ext;
-  _in_cvs = copy._in_cvs;
-  _wants_cvs = copy._wants_cvs;
-  _use_count = copy._use_count;
-}
-
-/**
- * Returns the name of the directory this file was found in.
- */
-const string &SoftFilename::
-get_dirname() const {
-  return _dirname;
-}
-
-/**
- * Returns the actual filename as found in the directory.
- */
-const string &SoftFilename::
-get_filename() const {
-  return _filename;
-}
-
-/**
- * Returns true if the filename had a version number, false otherwise.
- */
-bool SoftFilename::
-has_version() const {
-  return _has_version;
-}
-
-/**
- * Returns what the filename would be if it were version 1-0.
- */
-string SoftFilename::
-get_1_0_filename() const {
-  nassertr(_has_version, string());
-  return _base + "1-0" + _ext;
-}
-
-/**
- * Returns the base part of the filename.  This is everything before the
- * version number.
- */
-const string &SoftFilename::
-get_base() const {
-  nassertr(_has_version, _filename);
-  return _base;
-}
-
-/**
- * Returns the major version number.
- */
-int SoftFilename::
-get_major() const {
-  nassertr(_has_version, 0);
-  return _major;
-}
-
-/**
- * Returns the minor version number.
- */
-int SoftFilename::
-get_minor() const {
-  nassertr(_has_version, 0);
-  return _minor;
-}
-
-/**
- * Returns the extension part of the filename.  This is everything after the
- * version number.
- */
-const string &SoftFilename::
-get_extension() const {
-  nassertr(_has_version, _ext);
-  return _ext;
-}
-
-/**
- * Returns the filename part, without the extension.
- */
-string SoftFilename::
-get_non_extension() const {
-  nassertr(_has_version, _filename);
-  nassertr(_ext.length() < _filename.length(), _filename);
-  return _filename.substr(0, _filename.length() - _ext.length());
-}
-
-/**
- * Returns true if this is a version 1_0 filename, false otherwise.
- */
-bool SoftFilename::
-is_1_0() const {
-  nassertr(_has_version, false);
-  return (_major == 1 && _minor == 0);
-}
-
-/**
- * Makes this a 1_0 filename.
- */
-void SoftFilename::
-make_1_0() {
-  _has_version = true;
-  _major = 1;
-  _minor = 0;
-  _filename = get_1_0_filename();
-}
-
-/**
- * Returns true if this file has the same base and extension as the other,
- * disregarding the version number; false otherwise.
- */
-bool SoftFilename::
-is_same_file(const SoftFilename &other) const {
-  return _base == other._base && _ext == other._ext;
-}
-
-/**
- * Puts filenames in order such that the files with the same base are sorted
- * together, ignoring extension; and within files with the same base, files
- * are sorted in decreasing version number order so that the most recent
- * version appears first.
- */
-bool SoftFilename::
-operator < (const SoftFilename &other) const {
-  if (_base != other._base) {
-    return _base < other._base;
-  }
-
-  if (_has_version != other._has_version) {
-    // If one has a version and the other one doesn't, the one without a
-    // version comes first.
-    return _has_version < other._has_version;
-  }
-
-  if (_has_version) {
-    if (_major != other._major) {
-      return _major > other._major;
-    }
-    if (_minor != other._minor) {
-      return _minor > other._minor;
-    }
-  }
-
-  return false;
-}
-
-/**
- * Sets the flag that indicates whether this file is known to be entered into
- * the CVS database.
- */
-void SoftFilename::
-set_in_cvs(bool in_cvs) {
-  _in_cvs = in_cvs;
-}
-
-/**
- * Returns true if this file is known to be entered in the CVS database, false
- * if it is not.
- */
-bool SoftFilename::
-get_in_cvs() const {
-  return _in_cvs;
-}
-
-/**
- * Sets the flag that indicates whether this file should be entered into the
- * CVS database.
- */
-void SoftFilename::
-set_wants_cvs(bool wants_cvs) {
-  _wants_cvs = wants_cvs;
-}
-
-/**
- * Returns true if this file should be entered into the CVS database, false
- * otherwise.
- */
-bool SoftFilename::
-get_wants_cvs() const {
-  return _wants_cvs;
-}
-
-/**
- * Indicates that this filename is referenced by one more scene file.
- */
-void SoftFilename::
-increment_use_count() {
-  _use_count++;
-}
-
-/**
- * Returns the number of scene files that referenced this filename.
- */
-int SoftFilename::
-get_use_count() const {
-  return _use_count;
-}

+ 0 - 73
pandatool/src/softprogs/softFilename.h

@@ -1,73 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University.  All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license.  You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file softFilename.h
- * @author drose
- * @date 2000-11-10
- */
-
-#ifndef SOFTFILENAME_H
-#define SOFTFILENAME_H
-
-#include "pandatoolbase.h"
-
-/**
- * This encapsulates a SoftImage versioned filename, of the form base.v-v.ext:
- * it consists of a directory name, a base, a major and minor version number,
- * and an optional extension.
- *
- * It also keeps track of whether the named file has been added to CVS, and
- * how many scene files it is referenced by,
- */
-class SoftFilename {
-public:
-  SoftFilename(const std::string &dirname, const std::string &filename);
-  SoftFilename(const SoftFilename &copy);
-  void operator = (const SoftFilename &copy);
-
-  const std::string &get_dirname() const;
-  const std::string &get_filename() const;
-  bool has_version() const;
-
-  std::string get_1_0_filename() const;
-
-  const std::string &get_base() const;
-  int get_major() const;
-  int get_minor() const;
-  const std::string &get_extension() const;
-  std::string get_non_extension() const;
-
-  bool is_1_0() const;
-  void make_1_0();
-
-  bool is_same_file(const SoftFilename &other) const;
-  bool operator < (const SoftFilename &other) const;
-
-  void set_in_cvs(bool in_cvs);
-  bool get_in_cvs() const;
-
-  void set_wants_cvs(bool wants_cvs);
-  bool get_wants_cvs() const;
-
-  void increment_use_count();
-  int get_use_count() const;
-
-private:
-  std::string _dirname;
-  std::string _filename;
-  bool _has_version;
-  std::string _base;
-  int _major;
-  int _minor;
-  std::string _ext;
-  bool _in_cvs;
-  bool _wants_cvs;
-  int _use_count;
-};
-
-#endif