Explorar el Código

split out maya into mayaegg and mayaprogs

David Rose hace 24 años
padre
commit
133f94b253

+ 0 - 156
pandatool/src/maya/maya_funcs.cxx

@@ -1,156 +0,0 @@
-// Filename: maya_funcs.cxx
-// Created by:  drose (16Feb00)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
-//
-// All use of this software is subject to the terms of the Panda 3d
-// Software license.  You should have received a copy of this license
-// along with this source code; you will also find a current copy of
-// the license at http://www.panda3d.org/license.txt .
-//
-// To contact the maintainers of this program write to
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#include "maya_funcs.h"
-
-#include "pre_maya_include.h"
-#include <maya/MObject.h>
-#include <maya/MAngle.h>
-#include <maya/MFnDependencyNode.h>
-#include <maya/MStatus.h>
-#include <maya/MFnStringData.h>
-#include <maya/MFnNumericData.h>
-#include "post_maya_include.h"
-
-bool
-get_bool_attribute(MObject &node, const string &attribute_name,
-                   bool &value) {
-  if (!get_maya_attribute(node, attribute_name, value)) {
-    nout << "Attribute " << attribute_name
-         << " does not have an bool value.\n";
-    describe_maya_attribute(node, attribute_name);
-    return false;
-  }
-  return true;
-}
-
-bool
-get_angle_attribute(MObject &node, const string &attribute_name,
-                    double &value) {
-  MAngle maya_value;
-  if (!get_maya_attribute(node, attribute_name, maya_value)) {
-    nout << "Attribute " << attribute_name
-         << " does not have an angle value.\n";
-    describe_maya_attribute(node, attribute_name);
-    return false;
-  }
-  value = maya_value.asDegrees();
-  return true;
-}
-
-bool
-get_vec2f_attribute(MObject &node, const string &attribute_name,
-                    LVecBase2f &value) {
-  MStatus status;
-
-  MObject vec2f_object;
-  if (!get_maya_attribute(node, attribute_name, vec2f_object)) {
-    nout << "Attribute " << attribute_name
-         << " does not have a vec2f object value.\n";
-    describe_maya_attribute(node, attribute_name);
-    return false;
-  }
-
-  MFnNumericData data(vec2f_object, &status);
-  if (!status) {
-    nout << "Attribute " << attribute_name << " is of type "
-         << vec2f_object.apiTypeStr() << ", not a NumericData.\n";
-    return false;
-  }
-
-  status = data.getData(value[0], value[1]);
-  if (!status) {
-    nout << "Unable to extract 2 floats from " << attribute_name
-         << ", of type " << vec2f_object.apiTypeStr() << "\n";
-  }
-
-  return true;
-}
-
-bool
-get_vec2d_attribute(MObject &node, const string &attribute_name,
-                    LVecBase2d &value) {
-  MStatus status;
-
-  MObject vec2d_object;
-  if (!get_maya_attribute(node, attribute_name, vec2d_object)) {
-    nout << "Attribute " << attribute_name
-         << " does not have a vec2d object value.\n";
-    describe_maya_attribute(node, attribute_name);
-    return false;
-  }
-
-  MFnNumericData data(vec2d_object, &status);
-  if (!status) {
-    nout << "Attribute " << attribute_name << " is of type "
-         << vec2d_object.apiTypeStr() << ", not a NumericData.\n";
-    return false;
-  }
-
-  status = data.getData(value[0], value[1]);
-  if (!status) {
-    nout << "Unable to extract 2 doubles from " << attribute_name
-         << ", of type " << vec2d_object.apiTypeStr() << "\n";
-  }
-
-  return true;
-}
-
-bool
-get_string_attribute(MObject &node, const string &attribute_name,
-                     string &value) {
-  MStatus status;
-
-  MObject string_object;
-  if (!get_maya_attribute(node, attribute_name, string_object)) {
-    nout << "Attribute " << attribute_name
-         << " does not have an string object value.\n";
-    describe_maya_attribute(node, attribute_name);
-    return false;
-  }
-
-  MFnStringData data(string_object, &status);
-  if (!status) {
-    nout << "Attribute " << attribute_name << " is of type "
-         << string_object.apiTypeStr() << ", not a StringData.\n";
-    return false;
-  }
-
-  value = data.string().asChar();
-  return true;
-}
-
-void
-describe_maya_attribute(MObject &node, const string &attribute_name) {
-  MStatus status;
-  MFnDependencyNode node_fn(node, &status);
-  if (!status) {
-    nout << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
-    return;
-  }
-
-  MObject attr = node_fn.attribute(attribute_name.c_str(), &status);
-  if (!status) {
-    nout << "Object " << node_fn.name() << " does not support attribute "
-         << attribute_name << "\n";
-    return;
-  }
-
-  nout << "Attribute " << attribute_name << " on object "
-       << node_fn.name() << " has type " << attr.apiTypeStr() << "\n";
-}

+ 28 - 0
pandatool/src/mayaegg/Sources.pp

@@ -0,0 +1,28 @@
+#define DIRECTORY_IF_MAYA yes
+
+#begin ss_lib_target
+  #define USE_MAYA yes
+  #define TARGET mayaegg
+  #define LOCAL_LIBS \
+    converter pandatoolbase
+  #define OTHER_LIBS \
+    egg:c pandaegg:m \
+    linmath:c putil:c panda:m \
+    express:c pandaexpress:m \
+    dtoolutil:c dtoolbase:c dconfig:c dtoolconfig:m dtool:m pystub
+
+  #define UNIX_SYS_LIBS \
+    m
+
+  #define SOURCES \
+    config_mayaegg.cxx config_mayaegg.h \
+    mayaApi.cxx mayaApi.h \
+    mayaParameters.cxx mayaParameters.h \
+    mayaShader.cxx mayaShader.h \
+    mayaShaders.cxx mayaShaders.h \
+    mayaToEggConverter.cxx mayaToEggConverter.h \
+    maya_funcs.I maya_funcs.cxx maya_funcs.h \
+    post_maya_include.h pre_maya_include.h
+
+#end ss_lib_target
+

+ 46 - 0
pandatool/src/mayaegg/config_mayaegg.cxx

@@ -0,0 +1,46 @@
+// Filename: config_mayaegg.cxx
+// Created by:  drose (15Apr02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "config_mayaegg.h"
+
+#include <dconfig.h>
+
+Configure(config_mayaegg);
+NotifyCategoryDef(mayaegg, "");
+
+ConfigureFn(config_mayaegg) {
+  init_libmayaegg();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: init_libmayaegg
+//  Description: 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_libmayaegg() {
+  static bool initialized = false;
+  if (initialized) {
+    return;
+  }
+  initialized = true;
+}
+

+ 8 - 9
pandatool/src/maya/global_parameters.h → pandatool/src/mayaegg/config_mayaegg.h

@@ -1,5 +1,5 @@
-// Filename: global_parameters.h
-// Created by:  drose (16Feb00)
+// Filename: config_mayaegg.h
+// Created by:  drose (15Apr02)
 //
 ////////////////////////////////////////////////////////////////////
 //
@@ -16,15 +16,14 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#ifndef GLOBAL_PARAMETERS_H
-#define GLOBAL_PARAMETERS_H
+#ifndef CONFIG_MAYAEGG_H
+#define CONFIG_MAYAEGG_H
 
 #include "pandatoolbase.h"
+#include "notifyCategoryProxy.h"
 
-extern int verbose;
-extern bool polygon_output;
-extern double polygon_tolerance;
-extern bool ignore_transforms;
+NotifyCategoryDeclNoExport(mayaegg);
 
-#endif
+extern void init_libmayaegg();
 
+#endif

+ 207 - 0
pandatool/src/mayaegg/mayaApi.cxx

@@ -0,0 +1,207 @@
+// Filename: mayaApi.cxx
+// Created by:  drose (15Apr02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "mayaApi.h"
+#include "config_mayaegg.h"
+
+#include "pre_maya_include.h"
+#include <maya/MGlobal.h>
+#include <maya/MDistance.h>
+#include <maya/MFileIO.h>
+#include <maya/MLibrary.h>
+#include <maya/MStatus.h>
+#include "post_maya_include.h"
+
+MayaApi *MayaApi::_global_api = (MayaApi *)NULL;
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaApi::Constructor
+//       Access: Protected
+//  Description: Don't attempt to create this object directly;
+//               instead, use the open_api() method.
+////////////////////////////////////////////////////////////////////
+MayaApi::
+MayaApi(const string &program_name) {
+  MStatus stat = MLibrary::initialize((char *)program_name.c_str());
+  if (!stat) {
+    stat.perror("MLibrary::initialize");
+    _is_valid = false;
+  } else {
+    _is_valid = true;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaApi::Copy Constructor
+//       Access: Protected
+//  Description: Don't attempt to copy MayaApi objects.  There should
+//               be only one of these in the world at a time.
+////////////////////////////////////////////////////////////////////
+MayaApi::
+MayaApi(const MayaApi &copy) {
+  nassertv(false);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaApi::Copy Assignment Operator
+//       Access: Protected
+//  Description: Don't attempt to copy MayaApi objects.  There should
+//               be only one of these in the world at a time.
+////////////////////////////////////////////////////////////////////
+void MayaApi::
+operator = (const MayaApi &copy) {
+  nassertv(false);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaApi::Destructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+MayaApi::
+~MayaApi() {
+  nassertv(_global_api == this);
+  if (_is_valid) {
+    MLibrary::cleanup();
+  }
+  _global_api = (MayaApi *)NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaApi::open_api
+//       Access: Public, Static
+//  Description: Opens the Maya API, if it is not already open, and
+//               returns a pointer representing this connection.  When
+//               you are done using the Maya API, let the pointer
+//               destruct.
+//
+//               If program_name is supplied, it is passed to Maya as
+//               the name of the currently-executing program.
+//               Otherwise, the current program name is extracted from
+//               the execution environment, if possible.
+////////////////////////////////////////////////////////////////////
+PT(MayaApi) MayaApi::
+open_api(string program_name) {
+  if (_global_api == (MayaApi *)NULL) {
+    // We need to create a new MayaApi object.
+    if (program_name.empty()) {
+      program_name = ExecutionEnvironment::get_binary_name();
+      if (program_name.empty()) {
+        program_name = "Panda";
+      }
+    }
+
+    _global_api = new MayaApi(program_name);
+  }
+
+  return _global_api;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaApi::is_valid
+//       Access: Public
+//  Description: Returns true if the API has been successfully opened
+//               and may be used, or false if there is some problem.
+////////////////////////////////////////////////////////////////////
+bool MayaApi::
+is_valid() const {
+  return _is_valid;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaApi::read
+//       Access: Public
+//  Description: Reads the indicated maya file into the global model
+//               space.  Returns true if successful, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool MayaApi::
+read(const Filename &filename) {
+  MFileIO::newFile(true);
+
+  mayaegg_cat.info() << "Reading " << filename << "\n";
+  // Load the file into Maya
+  string os_filename = filename.to_os_specific();
+  MStatus stat = MFileIO::open(os_filename.c_str());
+  if (!stat) {
+    stat.perror(filename.c_str());
+    return false;
+  }
+  mayaegg_cat.info() << "done.\n";
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaApi::clear
+//       Access: Public
+//  Description: Resets the global model space to the empty state, for
+//               instance in preparation for building a new file.
+//               Returns true if successful, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool MayaApi::
+clear() {
+  MStatus stat = MFileIO::newFile(true);
+  if (!stat) {
+    stat.perror("clear");
+    return false;
+  }
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaApi::get_units
+//       Access: Public
+//  Description: Returns Maya's internal units in effect.
+////////////////////////////////////////////////////////////////////
+DistanceUnit MayaApi::
+get_units() {
+  switch (MDistance::internalUnit()) {
+  case MDistance::kInches:
+    return DU_inches;
+  case MDistance::kFeet:
+    return DU_feet;
+  case MDistance::kYards:
+    return DU_yards;
+  case MDistance::kMiles:
+    return DU_statute_miles;
+  case MDistance::kMillimeters:
+    return DU_millimeters;
+  case MDistance::kCentimeters:
+    return DU_centimeters;
+  case MDistance::kKilometers:
+    return DU_kilometers;
+  case MDistance::kMeters:
+    return DU_meters;
+
+  default:
+    return DU_invalid;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaApi::get_coordinate_system
+//       Access: Public
+//  Description: Returns Maya's internal coordinate system in effect.
+////////////////////////////////////////////////////////////////////
+CoordinateSystem MayaApi::
+get_coordinate_system() {
+  if (MGlobal::isYAxisUp()) {
+    return CS_yup_right;
+  } else {
+    return CS_zup_right;
+  }
+}

+ 60 - 0
pandatool/src/mayaegg/mayaApi.h

@@ -0,0 +1,60 @@
+// Filename: mayaApi.h
+// Created by:  drose (15Apr02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef MAYAAPI_H
+#define MAYAAPI_H
+
+#include "pandatoolbase.h"
+#include "distanceUnit.h"
+#include "coordinateSystem.h"
+#include "referenceCount.h"
+#include "pointerTo.h"
+
+class Filename;
+
+////////////////////////////////////////////////////////////////////
+//       Class : MayaApi
+// Description : This class presents a wrapper around the global
+//               Maya interface.  While the reference count it held,
+//               it keeps the Maya interface open, and closes the
+//               interface when the object destructs.
+////////////////////////////////////////////////////////////////////
+class MayaApi : public ReferenceCount {
+protected:
+  MayaApi(const string &program_name);
+  MayaApi(const MayaApi &copy);
+  void operator = (const MayaApi &copy);
+
+public:
+  ~MayaApi();
+
+  static PT(MayaApi) open_api(string program_name = "");
+  bool is_valid() const;
+
+  bool read(const Filename &filename);
+  bool clear();
+
+  DistanceUnit get_units();
+  CoordinateSystem get_coordinate_system();
+
+private:
+  bool _is_valid;
+  static MayaApi *_global_api;
+};
+
+#endif

+ 5 - 6
pandatool/src/maya/global_parameters.cxx → pandatool/src/mayaegg/mayaParameters.cxx

@@ -1,4 +1,4 @@
-// Filename: global_parameters.cxx
+// Filename: mayaParameters.cxx
 // Created by:  drose (16Feb00)
 //
 ////////////////////////////////////////////////////////////////////
@@ -16,9 +16,8 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#include "global_parameters.h"
+#include "mayaParameters.h"
 
-int verbose = 0;
-bool polygon_output = false;
-double polygon_tolerance = 0.01;
-bool ignore_transforms = false;
+bool MayaParameters::polygon_output = false;
+double MayaParameters::polygon_tolerance = 0.01;
+bool MayaParameters::ignore_transforms = false;

+ 38 - 0
pandatool/src/mayaegg/mayaParameters.h

@@ -0,0 +1,38 @@
+// Filename: mayaParameters.h
+// Created by:  drose (16Feb00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef MAYAPARAMETERS_H
+#define MAYAPARAMETERS_H
+
+#include "pandatoolbase.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : MayaParameters
+// Description : This class is just used as a scope to hold the global
+//               parameters for the Maya converter.
+////////////////////////////////////////////////////////////////////
+class MayaParameters {
+public:
+  static bool polygon_output;
+  static double polygon_tolerance;
+  static bool ignore_transforms;
+};
+
+
+#endif
+

+ 68 - 22
pandatool/src/maya/mayaShader.cxx → pandatool/src/mayaegg/mayaShader.cxx

@@ -18,8 +18,8 @@
 
 #include "mayaShader.h"
 #include "maya_funcs.h"
-#include "mayaFile.h"
-#include "global_parameters.h"
+#include "mayaToEggConverter.h"
+#include "config_mayaegg.h"
 
 #include "eggPrimitive.h"
 #include "eggTexture.h"
@@ -35,8 +35,16 @@
 #include <maya/MStatus.h>
 #include "post_maya_include.h"
 
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShader::Constructor
+//       Access: Public
+//  Description: Reads the Maya "shading engine" to determine the
+//               relevant shader properties.
+////////////////////////////////////////////////////////////////////
 MayaShader::
-MayaShader(MObject engine) {
+MayaShader(MObject engine, MayaToEggConverter *converter) :
+  _converter(converter)
+{
   _has_color = false;
   _transparency = 0.0;
 
@@ -59,8 +67,9 @@ MayaShader(MObject engine) {
 
   _name = engine_fn.name().asChar();
 
-  if (verbose >= 2) {
-    nout << "Reading shading engine " << _name << "\n";
+  if (mayaegg_cat.is_debug()) {
+    mayaegg_cat.debug()
+      << "Reading shading engine " << _name << "\n";
   }
 
   bool found_shader = false;
@@ -76,14 +85,25 @@ MayaShader(MObject engine) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShader::set_attributes
+//       Access: Public
+//  Description: Applies the known shader attributes to the indicated
+//               egg primitive.
+////////////////////////////////////////////////////////////////////
 void MayaShader::
-set_attributes(EggPrimitive &primitive, MayaFile &file) {
+set_attributes(EggPrimitive &primitive, MayaToEggConverter &conv) {
+  // In Maya, a polygon is either textured or colored.  The texture,
+  // if present, replaces the color.
+
   if (_has_texture) {
-    EggTextureCollection &textures = file._textures;
-    EggTexture tex(_name, _texture);
+    EggTextureCollection &textures = conv._textures;
+
+    Filename pathname = _converter->convert_texture_path(_texture);
+    EggTexture tex(_name, pathname);
     tex.set_wrap_u(_wrap_u ? EggTexture::WM_repeat : EggTexture::WM_clamp);
     tex.set_wrap_v(_wrap_v ? EggTexture::WM_repeat : EggTexture::WM_clamp);
-
+ 
     // Let's mipmap all textures by default.
     tex.set_minfilter(EggTexture::FT_linear_mipmap_linear);
     tex.set_magfilter(EggTexture::FT_linear);
@@ -103,6 +123,12 @@ set_attributes(EggPrimitive &primitive, MayaFile &file) {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShader::compute_texture_matrix
+//       Access: Public
+//  Description: Returns a texture matrix corresponding to the texture
+//               transforms indicated by the shader.
+////////////////////////////////////////////////////////////////////
 LMatrix3d MayaShader::
 compute_texture_matrix() {
   LVector2d scale(_repeat_uv[0] / _coverage[0],
@@ -118,7 +144,11 @@ compute_texture_matrix() {
     LMatrix3d::translate_mat(trans);
 }
 
-
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShader::output
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
 void MayaShader::
 output(ostream &out) const {
   out << "Shader " << _name << ":\n";
@@ -140,13 +170,20 @@ output(ostream &out) const {
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShader::read_surface_shader
+//       Access: Public
+//  Description: Extracts out the shading information from the Maya
+//               surface shader.
+////////////////////////////////////////////////////////////////////
 bool MayaShader::
 read_surface_shader(MObject shader) {
   MStatus status;
   MFnDependencyNode shader_fn(shader);
 
-  if (verbose >= 3) {
-    nout << "  Reading surface shader " << shader_fn.name() << "\n";
+  if (mayaegg_cat.is_spam()) {
+    mayaegg_cat.spam()
+      << "  Reading surface shader " << shader_fn.name() << "\n";
   }
 
   // First, check for a connection to the color attribute.  This could
@@ -175,13 +212,21 @@ read_surface_shader(MObject shader) {
   }
 
   if (!_has_color && !_has_texture) {
-    if (verbose >= 2) {
-      nout << "  Color definition not found.\n";
+    if (mayaegg_cat.is_spam()) {
+      mayaegg_cat.spam()
+        << "  Color definition not found.\n";
     }
   }
   return true;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShader::read_surface_color
+//       Access: Public
+//  Description: Determines the surface color specified by the shader.
+//               This includes texturing and other advanced shader
+//               properties.
+////////////////////////////////////////////////////////////////////
 void MayaShader::
 read_surface_color(MObject color) {
   if (color.hasFn(MFn::kFileTexture)) {
@@ -199,21 +244,22 @@ read_surface_color(MObject color) {
     get_vec2f_attribute(color, "repeatUV", _repeat_uv);
     get_vec2f_attribute(color, "offset", _offset);
     get_angle_attribute(color, "rotateUV", _rotate_uv);
+
   } else {
     // This shader wasn't understood.
-    if (verbose >= 2) {
-      nout << "**Don't know how to interpret color attribute type "
-           << color.apiTypeStr() << "\n";
+    if (mayaegg_cat.is_debug()) {
+      mayaegg_cat.info()
+        << "**Don't know how to interpret color attribute type "
+        << color.apiTypeStr() << "\n";
+
     } else {
       // If we don't have a heavy verbose count, only report each type
       // of unsupportted shader once.
       static pset<MFn::Type> bad_types;
       if (bad_types.insert(color.apiType()).second) {
-        if (verbose == 1) {
-          nout << "\n";
-        }
-        nout << "Don't know how to interpret color attribute type "
-             << color.apiTypeStr() << "\n";
+        mayaegg_cat.info()
+          << "**Don't know how to interpret color attribute type "
+          << color.apiTypeStr() << "\n";
       }
     }
   }

+ 12 - 4
pandatool/src/maya/mayaShader.h → pandatool/src/mayaegg/mayaShader.h

@@ -25,14 +25,20 @@
 #include "lmatrix.h"
 
 class MObject;
-class MayaFile;
+class MayaToEggConverter;
 class EggPrimitive;
 
+////////////////////////////////////////////////////////////////////
+//       Class : MayaShader
+// Description : Corresponds to a single "shader" in Maya.  This
+//               extracts out all the parameters of a Maya shader that
+//               are meaningful to egg.
+////////////////////////////////////////////////////////////////////
 class MayaShader {
 public:
-  MayaShader(MObject engine);
+  MayaShader(MObject engine, MayaToEggConverter *converter);
 
-  void set_attributes(EggPrimitive &primitive, MayaFile &file);
+  void set_attributes(EggPrimitive &primitive, MayaToEggConverter &conv);
   LMatrix3d compute_texture_matrix();
 
   void output(ostream &out) const;
@@ -59,9 +65,11 @@ public:
   LVector2f _offset;
   double _rotate_uv;
 
-protected:
+private:
   bool read_surface_shader(MObject shader);
   void read_surface_color(MObject color);
+
+  MayaToEggConverter *_converter;
 };
 
 inline ostream &operator << (ostream &out, const MayaShader &shader) {

+ 56 - 7
pandatool/src/maya/mayaShaders.cxx → pandatool/src/mayaegg/mayaShaders.cxx

@@ -18,8 +18,8 @@
 
 #include "mayaShaders.h"
 #include "mayaShader.h"
-#include "global_parameters.h"
 #include "maya_funcs.h"
+#include "config_mayaegg.h"
 
 #include "pre_maya_include.h"
 #include <maya/MStatus.h>
@@ -30,6 +30,32 @@
 #include <maya/MFn.h>
 #include "post_maya_include.h"
 
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShaders::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+MayaShaders::
+MayaShaders(MayaToEggConverter *converter) :
+  _converter(converter)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShaders::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+MayaShaders::
+~MayaShaders() {
+  clear();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShaders::find_shader_for_node
+//       Access: Public
+//  Description: Extracts the shader assigned to the indicated node.
+////////////////////////////////////////////////////////////////////
 MayaShader *MayaShaders::
 find_shader_for_node(MObject node) {
   MStatus status;
@@ -39,7 +65,8 @@ find_shader_for_node(MObject node) {
   MObject iog_attr = node_fn.attribute("instObjGroups", &status);
   if (!status) {
     // The node is not renderable.  What are you thinking?
-    nout << node_fn.name() << " : not a renderable object.\n";
+    mayaegg_cat.error()
+      << node_fn.name() << " : not a renderable object.\n";
     return (MayaShader *)NULL;
   }
 
@@ -52,7 +79,8 @@ find_shader_for_node(MObject node) {
   iog_plug.elementByLogicalIndex(0).connectedTo(iog_pa, false, true, &status);
   if (!status) {
     // No shading group defined for this object.
-    nout << node_fn.name() << " : no shading group defined.\n";
+    mayaegg_cat.error()
+      << node_fn.name() << " : no shading group defined.\n";
     return (MayaShader *)NULL;
   }
 
@@ -69,12 +97,19 @@ find_shader_for_node(MObject node) {
   }
 
   // Well, we didn't find a ShadingEngine after all.  Huh.
-  if (verbose >= 2) {
-    nout << node_fn.name() << " : no shading engine found.\n";
-  }
+  mayaegg_cat.info()
+    << node_fn.name() << " : no shading engine found.\n";
   return (MayaShader *)NULL;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShaders::find_shader_for_shading_engine
+//       Access: Public
+//  Description: Returns the MayaShader object associated with the
+//               indicated "shading engine".  This will create a new
+//               MayaShader object if this is the first time we have
+//               encountered the indicated engine.
+////////////////////////////////////////////////////////////////////
 MayaShader *MayaShaders::
 find_shader_for_shading_engine(MObject engine) {
   MFnDependencyNode engine_fn(engine);
@@ -88,11 +123,25 @@ find_shader_for_shading_engine(MObject engine) {
 
   // All right, this is a newly encountered shading engine.  Create a
   // new MayaShader object to represent it.
-  MayaShader *shader = new MayaShader(engine);
+  MayaShader *shader = new MayaShader(engine, _converter);
 
   // Record this for the future.
   _shaders.insert(Shaders::value_type(engine_name, shader));
   return shader;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: MayaShaders::clear
+//       Access: Public
+//  Description: Frees all of the previously-defined MayaShader
+//               objects associated with this set.
+////////////////////////////////////////////////////////////////////
+void MayaShaders::
+clear() {
+  Shaders::iterator si;
+  for (si = _shaders.begin(); si != _shaders.end(); ++si) {
+    delete (*si).second;
+  }
 
+  _shaders.clear();
+}

+ 12 - 1
pandatool/src/maya/mayaShaders.h → pandatool/src/mayaegg/mayaShaders.h

@@ -24,17 +24,28 @@
 #include "pmap.h"
 
 class MayaShader;
+class MayaToEggConverter;
 class MObject;
 
+////////////////////////////////////////////////////////////////////
+//       Class : MayaShaders
+// Description : Collects the set of MayaShaders that have been
+//               encountered so far.
+////////////////////////////////////////////////////////////////////
 class MayaShaders {
 public:
+  MayaShaders(MayaToEggConverter *converter);
+  ~MayaShaders();
   MayaShader *find_shader_for_node(MObject node);
   MayaShader *find_shader_for_shading_engine(MObject engine);
 
-protected:
+  void clear();
 
+private:
   typedef pmap<string, MayaShader *> Shaders;
   Shaders _shaders;
+
+  MayaToEggConverter *_converter;
 };
 
 #endif

+ 288 - 183
pandatool/src/maya/mayaFile.cxx → pandatool/src/mayaegg/mayaToEggConverter.cxx

@@ -1,4 +1,4 @@
-// Filename: mayaFile.cxx
+// Filename: mayaToEggConverter.cxx
 // Created by:  drose (10Nov99)
 //
 ////////////////////////////////////////////////////////////////////
@@ -16,10 +16,11 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#include "mayaFile.h"
+#include "mayaToEggConverter.h"
 #include "mayaShader.h"
-#include "global_parameters.h"
+#include "mayaParameters.h"
 #include "maya_funcs.h"
+#include "config_mayaegg.h"
 
 #include "eggData.h"
 #include "eggGroup.h"
@@ -28,14 +29,12 @@
 #include "eggNurbsSurface.h"
 #include "eggNurbsCurve.h"
 #include "eggPolygon.h"
+#include "string_utils.h"
 
 #include "pre_maya_include.h"
-#include <maya/MGlobal.h>
-#include <maya/MDistance.h>
 #include <maya/MArgList.h>
 #include <maya/MColor.h>
 #include <maya/MDagPath.h>
-#include <maya/MFileIO.h>
 #include <maya/MFnCamera.h>
 #include <maya/MFnDagNode.h>
 #include <maya/MFnLight.h>
@@ -61,95 +60,110 @@
 #include <maya/MTesselationParams.h>
 #include "post_maya_include.h"
 
-MayaFile::
-MayaFile() {
-  verbose = 0;
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+MayaToEggConverter::
+MayaToEggConverter(const string &program_name) :
+  _shaders(this)
+{
+  _maya = MayaApi::open_api(program_name);
 }
 
-MayaFile::
-~MayaFile() {
-  MLibrary::cleanup();
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::Copy Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+MayaToEggConverter::
+MayaToEggConverter(const MayaToEggConverter &copy) :
+  _shaders(this),
+  _maya(copy._maya)
+{
 }
 
-bool MayaFile::
-init(const string &program) {
-  MStatus stat = MLibrary::initialize((char *)program.c_str());
-  if (!stat) {
-    stat.perror("MLibrary::initialize");
-    return false;
-  }
-  return true;
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::Destructor
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+MayaToEggConverter::
+~MayaToEggConverter() {
+  // We have to clear the shaders before we release the Maya API.
+  _shaders.clear();
+  _maya.clear();
 }
 
-
-bool MayaFile::
-read(const string &filename) {
-  MFileIO::newFile(true);
-
-  nout << "Loading \"" << filename << "\" ... " << flush;
-  // Load the file into Maya
-  MStatus stat = MFileIO::open(filename.c_str());
-  if (!stat) {
-    stat.perror(filename.c_str());
-    return false;
-  }
-  nout << " done.\n";
-  return true;
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::make_copy
+//       Access: Public, Virtual
+//  Description: Allocates and returns a new copy of the converter.
+////////////////////////////////////////////////////////////////////
+SomethingToEggConverter *MayaToEggConverter::
+make_copy() {
+  return new MayaToEggConverter(*this);
 }
 
-
-void MayaFile::
-make_egg(EggData &data) {
-  traverse(data);
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::get_name
+//       Access: Public, Virtual
+//  Description: Returns the English name of the file type this
+//               converter supports.
+////////////////////////////////////////////////////////////////////
+string MayaToEggConverter::
+get_name() const {
+  return "Maya";
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: MayaFile::get_units
-//       Access: Public, Static
-//  Description: Returns Maya's internal units in effect.
-////////////////////////////////////////////////////////////////////
-DistanceUnit MayaFile::
-get_units() {
-  switch (MDistance::internalUnit()) {
-  case MDistance::kInches:
-    return DU_inches;
-  case MDistance::kFeet:
-    return DU_feet;
-  case MDistance::kYards:
-    return DU_yards;
-  case MDistance::kMiles:
-    return DU_statute_miles;
-  case MDistance::kMillimeters:
-    return DU_millimeters;
-  case MDistance::kCentimeters:
-    return DU_centimeters;
-  case MDistance::kKilometers:
-    return DU_kilometers;
-  case MDistance::kMeters:
-    return DU_meters;
-
-  default:
-    return DU_invalid;
-  }
+//     Function: MayaToEggConverter::get_extension
+//       Access: Public, Virtual
+//  Description: Returns the common extension of the file type this
+//               converter supports.
+////////////////////////////////////////////////////////////////////
+string MayaToEggConverter::
+get_extension() const {
+  return "mb";
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: MayaFile::get_coordinate_system
-//       Access: Public, Static
-//  Description: Returns Maya's internal coordinate system in effect.
+//     Function: MayaToEggConverter::convert_file
+//       Access: Public, Virtual
+//  Description: 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.
+//               Command-line converters may choose to use
+//               convert_maya() instead, as it provides more control.
 ////////////////////////////////////////////////////////////////////
-CoordinateSystem MayaFile::
-get_coordinate_system() {
-  if (MGlobal::isYAxisUp()) {
-    return CS_yup_right;
-  } else {
-    return CS_zup_right;
+bool MayaToEggConverter::
+convert_file(const Filename &filename) {
+  if (!_maya->is_valid()) {
+    mayaegg_cat.error()
+      << "Maya is not available.\n";
+    return false;
   }
+  if (!_maya->read(filename)) {
+    mayaegg_cat.error()
+      << "Unable to read " << filename << "\n";
+    return false;
+  }
+  return convert_maya();
 }
 
-
-bool MayaFile::
-traverse(EggData &data) {
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::convert_maya
+//       Access: Public
+//  Description: Fills up the egg_data structure according to the
+//               global maya model data.  Returns true if successful,
+//               false if there is an error.
+////////////////////////////////////////////////////////////////////
+bool MayaToEggConverter::
+convert_maya() {
   MStatus status;
 
   MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
@@ -158,32 +172,49 @@ traverse(EggData &data) {
     return false;
   }
 
-  if (verbose >= 1) {
-    nout << "Traversing scene graph.\n";
+  if (mayaegg_cat.is_debug()) {
+    mayaegg_cat.debug()
+      << "Traversing scene graph.\n";
   }
 
-  //    Scan the entire DAG and output the name and depth of each node
+  // This while loop walks through the entire Maya hierarchy, one node
+  // at a time.  Maya's MItDag object automatically performs a
+  // depth-first traversal of its scene graph.
+  bool all_ok = true;
   while (!dag_iterator.isDone()) {
     MDagPath dag_path;
     status = dag_iterator.getPath(dag_path);
     if (!status) {
       status.perror("MItDag::getPath");
     } else {
-      process_node(dag_path, data);
+      if (!process_node(dag_path, get_egg_data())) {
+        all_ok = false;
+      }
     }
 
     dag_iterator.next();
   }
 
-  if (verbose == 1) {
-    nout << "\nDone.\n";
+  if (all_ok) {
+    mayaegg_cat.info()
+      << "\nDone, no errors.\n";
+  } else {
+    mayaegg_cat.info()
+      << "\nDone, errors encountered.\n";
   }
 
-  return true;
+  return all_ok;
 }
 
-
-bool MayaFile::
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::process_node
+//       Access: Private
+//  Description: Converts the indicated Maya 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 MayaToEggConverter::
 process_node(const MDagPath &dag_path, EggData &data) {
   MStatus status;
   MFnDagNode dag_node(dag_path, &status);
@@ -192,21 +223,22 @@ process_node(const MDagPath &dag_path, EggData &data) {
     return false;
   }
 
-  if (verbose == 1) {
-    nout << "." << flush;
-  } else if (verbose >= 2) {
-    nout << dag_node.name() << ": " << dag_node.typeName() << "\n"
-         << "  dag_path: " << dag_path.fullPathName() << "\n";
+  if (mayaegg_cat.is_debug()) {
+    mayaegg_cat.debug()
+      << dag_node.name() << ": " << dag_node.typeName() << "\n"
+      << "  dag_path: " << dag_path.fullPathName() << "\n";
   }
 
   if (dag_path.hasFn(MFn::kCamera)) {
-    if (verbose >= 2) {
-      nout << "Ignoring camera node " << dag_path.fullPathName() << "\n";
+    if (mayaegg_cat.is_debug()) {
+      mayaegg_cat.debug()
+        << "Ignoring camera node " << dag_path.fullPathName() << "\n";
     }
 
   } else if (dag_path.hasFn(MFn::kLight)) {
-    if (verbose >= 2) {
-      nout << "Ignoring light node " << dag_path.fullPathName() << "\n";
+    if (mayaegg_cat.is_debug()) {
+      mayaegg_cat.debug()
+        << "Ignoring light node " << dag_path.fullPathName() << "\n";
     }
 
   } else if (dag_path.hasFn(MFn::kNurbsSurface)) {
@@ -214,17 +246,18 @@ process_node(const MDagPath &dag_path, EggData &data) {
       get_egg_group(dag_path.fullPathName().asChar(), data);
 
     if (egg_group == (EggGroup *)NULL) {
-      nout << "Cannot determine group node.\n";
+      mayaegg_cat.error()
+        << "Cannot determine group node.\n";
+      return false;
 
     } else {
       get_transform(dag_path, egg_group);
 
       MFnNurbsSurface surface(dag_path, &status);
       if (!status) {
-        if (verbose >= 2) {
-          nout << "Error in node " << dag_path.fullPathName() << ":\n"
-               << "  it appears to have a NURBS surface, but does not.\n";
-        }
+        mayaegg_cat.info()
+          << "Error in node " << dag_path.fullPathName() << ":\n"
+          << "  it appears to have a NURBS surface, but does not.\n";
       } else {
         make_nurbs_surface(dag_path, surface, egg_group);
       }
@@ -242,10 +275,9 @@ process_node(const MDagPath &dag_path, EggData &data) {
 
       MFnNurbsCurve curve(dag_path, &status);
       if (!status) {
-        if (verbose >= 2) {
-          nout << "Error in node " << dag_path.fullPathName() << ":\n"
-               << "  it appears to have a NURBS curve, but does not.\n";
-        }
+        mayaegg_cat.info()
+          << "Error in node " << dag_path.fullPathName() << ":\n"
+          << "  it appears to have a NURBS curve, but does not.\n";
       } else {
         make_nurbs_curve(dag_path, curve, egg_group);
       }
@@ -256,18 +288,18 @@ process_node(const MDagPath &dag_path, EggData &data) {
       get_egg_group(dag_path.fullPathName().asChar(), data);
 
     if (egg_group == (EggGroup *)NULL) {
-      nout << "Cannot determine group node.\n";
+      mayaegg_cat.error()
+        << "Cannot determine group node.\n";
+      return false;
 
     } else {
       get_transform(dag_path, egg_group);
 
       MFnMesh mesh(dag_path, &status);
-
       if (!status) {
-        if (verbose >= 2) {
-          nout << "Error in node " << dag_path.fullPathName() << ":\n"
-               << "  it appears to have a polygon mesh, but does not.\n";
-        }
+        mayaegg_cat.info()
+          << "Error in node " << dag_path.fullPathName() << ":\n"
+          << "  it appears to have a polygon mesh, but does not.\n";
       } else {
         make_polyset(dag_path, mesh, egg_group);
       }
@@ -286,17 +318,24 @@ process_node(const MDagPath &dag_path, EggData &data) {
   return true;
 }
 
-void MayaFile::
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::get_transform
+//       Access: Private
+//  Description: Extracts the transform on the indicated Maya node,
+//               and applies it to the corresponding Egg node.
+////////////////////////////////////////////////////////////////////
+void MayaToEggConverter::
 get_transform(const MDagPath &dag_path, EggGroup *egg_group) {
-  if (ignore_transforms) {
+  if (MayaParameters::ignore_transforms) {
     return;
   }
 
   MStatus status;
   MObject transformNode = dag_path.transform(&status);
   // This node has no transform - i.e., it's the world node
-  if (!status && status.statusCode() == MStatus::kInvalidParameter)
+  if (!status && status.statusCode() == MStatus::kInvalidParameter) {
     return;
+  }
 
   MFnDagNode transform(transformNode, &status);
   if (!status) {
@@ -306,22 +345,25 @@ get_transform(const MDagPath &dag_path, EggGroup *egg_group) {
 
   MTransformationMatrix matrix(transform.transformationMatrix());
 
-  if (verbose >= 3) {
-    nout << "  translation: " << matrix.translation(MSpace::kWorld)
-         << "\n";
+  if (mayaegg_cat.is_spam()) {
+    mayaegg_cat.spam()
+      << "  translation: " << matrix.translation(MSpace::kWorld)
+      << "\n";
     double d[3];
     MTransformationMatrix::RotationOrder rOrder;
 
     matrix.getRotation(d, rOrder, MSpace::kWorld);
-    nout << "  rotation: ["
-         << d[0] << ", "
-         << d[1] << ", "
-         << d[2] << "]\n";
+    mayaegg_cat.spam()
+      << "  rotation: ["
+      << d[0] << ", "
+      << d[1] << ", "
+      << d[2] << "]\n";
     matrix.getScale(d, MSpace::kWorld);
-    nout << "  scale: ["
-         << d[0] << ", "
-         << d[1] << ", "
-         << d[2] << "]\n";
+    mayaegg_cat.spam()
+      << "  scale: ["
+      << d[0] << ", "
+      << d[1] << ", "
+      << d[2] << "]\n";
   }
 
   MMatrix mat = matrix.asMatrix();
@@ -337,40 +379,49 @@ get_transform(const MDagPath &dag_path, EggGroup *egg_group) {
   }
 }
 
-void MayaFile::
-make_nurbs_surface(const MDagPath &dag_path, 
-                   MFnNurbsSurface &surface,
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::make_nurbs_surface
+//       Access: Private
+//  Description: Converts the indicated Maya NURBS surface to a
+//               corresponding egg structure, and attaches it to the
+//               indicated egg group.
+////////////////////////////////////////////////////////////////////
+void MayaToEggConverter::
+make_nurbs_surface(const MDagPath &dag_path, MFnNurbsSurface &surface,
                    EggGroup *egg_group) {
   MStatus status;
   string name = surface.name().asChar();
 
-  if (verbose >= 3) {
-    nout << "  numCVs: "
-         << surface.numCVsInU()
-         << " * "
-         << surface.numCVsInV()
-         << "\n";
-    nout << "  numKnots: "
-         << surface.numKnotsInU()
-         << " * "
-         << surface.numKnotsInV()
-         << "\n";
-    nout << "  numSpans: "
-         << surface.numSpansInU()
-         << " * "
-         << surface.numSpansInV()
-         << "\n";
+  if (mayaegg_cat.is_spam()) {
+    mayaegg_cat.spam()
+      << "  numCVs: "
+      << surface.numCVsInU()
+      << " * "
+      << surface.numCVsInV()
+      << "\n";
+    mayaegg_cat.spam()
+      << "  numKnots: "
+      << surface.numKnotsInU()
+      << " * "
+      << surface.numKnotsInV()
+      << "\n";
+    mayaegg_cat.spam()
+      << "  numSpans: "
+      << surface.numSpansInU()
+      << " * "
+      << surface.numSpansInV()
+      << "\n";
   }
 
   MayaShader *shader = _shaders.find_shader_for_node(surface.object());
 
-  if (polygon_output) {
+  if (MayaParameters::polygon_output) {
     // If we want polygon output only, tesselate the NURBS and output
     // that.
     MTesselationParams params;
     params.setFormatType(MTesselationParams::kStandardFitFormat);
     params.setOutputType(MTesselationParams::kQuads);
-    params.setStdFractionalTolerance(polygon_tolerance);
+    params.setStdFractionalTolerance(MayaParameters::polygon_tolerance);
 
     // We'll create the tesselation as a sibling of the NURBS surface.
     // That way we inherit all of the transformations.
@@ -416,8 +467,11 @@ make_nurbs_surface(const MDagPath &dag_path,
     return;
   }
 
+  /*
+    We don't use these variables currently.
   MFnNurbsSurface::Form u_form = surface.formInU();
   MFnNurbsSurface::Form v_form = surface.formInV();
+  */
 
   int u_degree = surface.degreeU();
   int v_degree = surface.degreeV();
@@ -536,20 +590,31 @@ make_nurbs_surface(const MDagPath &dag_path,
   }
 }
 
-EggNurbsCurve *MayaFile::
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::make_trim_curve
+//       Access: Private
+//  Description: Converts the indicated Maya NURBS trim curve to a
+//               corresponding egg structure, and returns it, or NULL
+//               if there is a problem.
+////////////////////////////////////////////////////////////////////
+EggNurbsCurve *MayaToEggConverter::
 make_trim_curve(const MFnNurbsCurve &curve, const string &nurbs_name,
                 EggGroupNode *egg_group, int trim_curve_index) {
-  if (verbose >= 3) {
-    nout << "Trim curve:\n";
-    nout << "  numCVs: "
-         << curve.numCVs()
-         << "\n";
-    nout << "  numKnots: "
-         << curve.numKnots()
-         << "\n";
-    nout << "  numSpans: "
-         << curve.numSpans()
-         << "\n";
+  if (mayaegg_cat.is_spam()) {
+    mayaegg_cat.spam()
+      << "Trim curve:\n";
+    mayaegg_cat.spam()
+      << "  numCVs: "
+      << curve.numCVs()
+      << "\n";
+    mayaegg_cat.spam()
+      << "  numKnots: "
+      << curve.numKnots()
+      << "\n";
+    mayaegg_cat.spam()
+      << "  numSpans: "
+      << curve.numSpans()
+      << "\n";
   }
 
   MStatus status;
@@ -567,7 +632,9 @@ make_trim_curve(const MFnNurbsCurve &curve, const string &nurbs_name,
     return (EggNurbsCurve *)NULL;
   }
 
+  /*
   MFnNurbsCurve::Form form = curve.form();
+  */
 
   int degree = curve.degree();
   int cvs = curve.numCVs();
@@ -575,10 +642,7 @@ make_trim_curve(const MFnNurbsCurve &curve, const string &nurbs_name,
 
   assert(knots == cvs + degree - 1);
 
-  char trim_str[20];
-  sprintf(trim_str, "trim%d", trim_curve_index);
-  assert(strlen(trim_str) < 20);
-  string trim_name = trim_str;
+  string trim_name = "trim" + format_string(trim_curve_index);
 
   string vpool_name = nurbs_name + "." + trim_name;
   EggVertexPool *vpool = new EggVertexPool(vpool_name);
@@ -610,22 +674,32 @@ make_trim_curve(const MFnNurbsCurve &curve, const string &nurbs_name,
   return egg_curve;
 }
 
-void MayaFile::
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::make_nurbs_curve
+//       Access: Private
+//  Description: Converts the indicated Maya NURBS curve (a standalone
+//               curve, not a trim curve) to a corresponding egg
+//               structure and attaches it to the indicated egg group.
+////////////////////////////////////////////////////////////////////
+void MayaToEggConverter::
 make_nurbs_curve(const MDagPath &, const MFnNurbsCurve &curve,
                  EggGroup *egg_group) {
   MStatus status;
   string name = curve.name().asChar();
 
-  if (verbose >= 3) {
-    nout << "  numCVs: "
-         << curve.numCVs()
-         << "\n";
-    nout << "  numKnots: "
-         << curve.numKnots()
-         << "\n";
-    nout << "  numSpans: "
-         << curve.numSpans()
-         << "\n";
+  if (mayaegg_cat.is_spam()) {
+    mayaegg_cat.spam()
+      << "  numCVs: "
+      << curve.numCVs()
+      << "\n";
+    mayaegg_cat.spam()
+      << "  numKnots: "
+      << curve.numKnots()
+      << "\n";
+    mayaegg_cat.spam()
+      << "  numSpans: "
+      << curve.numSpans()
+      << "\n";
   }
 
   MPointArray cv_array;
@@ -641,7 +715,9 @@ make_nurbs_curve(const MDagPath &, const MFnNurbsCurve &curve,
     return;
   }
 
+  /*
   MFnNurbsCurve::Form form = curve.form();
+  */
 
   int degree = curve.degree();
   int cvs = curve.numCVs();
@@ -683,24 +759,34 @@ make_nurbs_curve(const MDagPath &, const MFnNurbsCurve &curve,
   }
 }
 
-void MayaFile::
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::make_polyset
+//       Access: Private
+//  Description: Converts the indicated Maya polyset to a bunch of
+//               EggPolygons and parents them to the indicated egg
+//               group.
+////////////////////////////////////////////////////////////////////
+void MayaToEggConverter::
 make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
              EggGroup *egg_group, MayaShader *default_shader) {
   MStatus status;
   string name = mesh.name().asChar();
 
-  if (verbose >= 3) {
-    nout << "  numPolygons: "
-         << mesh.numPolygons()
-         << "\n";
-    nout << "  numVertices: "
-         << mesh.numVertices()
-         << "\n";
+  if (mayaegg_cat.is_spam()) {
+    mayaegg_cat.spam()
+      << "  numPolygons: "
+      << mesh.numPolygons()
+      << "\n";
+    mayaegg_cat.spam()
+      << "  numVertices: "
+      << mesh.numVertices()
+      << "\n";
   }
 
   if (mesh.numPolygons() == 0) {
-    if (verbose >= 2) {
-      nout << "Ignoring empty mesh " << name << "\n";
+    if (mayaegg_cat.is_debug()) {
+      mayaegg_cat.debug()
+        << "Ignoring empty mesh " << name << "\n";
     }
     return;
   }
@@ -797,13 +883,29 @@ make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
 }
 
 
-EggGroup *MayaFile::
+////////////////////////////////////////////////////////////////////
+//     Function: MayaToEggConverter::get_egg_group
+//       Access: Private
+//  Description: Returns the EggGroup corresponding to the indicated
+//               fully-qualified Maya path name.  If there is not
+//               already an EggGroup corresponding to this Maya path,
+//               creates one and returns it.
+//
+//               In this way we generate a unique EggGroup for each
+//               Maya node we care about about, and also preserve the
+//               Maya hierarchy sensibly.
+////////////////////////////////////////////////////////////////////
+EggGroup *MayaToEggConverter::
 get_egg_group(const string &name, EggData &data) {
+  // If we have already encountered this pathname, return the
+  // corresponding EggGroup immediately.
   Groups::const_iterator gi = _groups.find(name);
   if (gi != _groups.end()) {
     return (*gi).second;
   }
 
+  // Otherwise, we have to create it.  Do this recursively, so we
+  // create each node along the path.
   EggGroup *egg_group;
 
   if (name.empty()) {
@@ -811,6 +913,9 @@ get_egg_group(const string &name, EggData &data) {
     egg_group = (EggGroup *)NULL;
 
   } else {
+    // Maya uses vertical bars to separate path components.  Remove
+    // everything from the rightmost bar on; this will give us the
+    // parent's path name.
     size_t bar = name.rfind("|");
     string parent_name, local_name;
     if (bar != string::npos) {

+ 31 - 14
pandatool/src/maya/mayaFile.h → pandatool/src/mayaegg/mayaToEggConverter.h

@@ -1,4 +1,4 @@
-// Filename: mayaFile.h
+// Filename: mayaToEggConverter.h
 // Created by:  drose (10Nov99)
 //
 ////////////////////////////////////////////////////////////////////
@@ -16,10 +16,13 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#ifndef MAYAFILE_H
-#define MAYAFILE_H
+#ifndef MAYATOEGGCONVERTER_H
+#define MAYATOEGGCONVERTER_H
 
 #include "pandatoolbase.h"
+#include "somethingToEggConverter.h"
+
+#include "mayaApi.h"
 #include "mayaShaders.h"
 #include "eggTextureCollection.h"
 #include "distanceUnit.h"
@@ -36,20 +39,31 @@ class MFnNurbsCurve;
 class MFnMesh;
 class MPointArray;
 
-class MayaFile {
+////////////////////////////////////////////////////////////////////
+//       Class : MayaToEggConverter
+// Description : This class supervises the construction of an EggData
+//               structure from a single Maya file, or from the data
+//               already in the global Maya model space.
+//
+//               Note that since the Maya API presents just one global
+//               model space, it is not possible to simultaneously
+//               load two distinct Maya files.
+////////////////////////////////////////////////////////////////////
+class MayaToEggConverter : public SomethingToEggConverter {
 public:
-  MayaFile();
-  ~MayaFile();
+  MayaToEggConverter(const string &program_name = "");
+  MayaToEggConverter(const MayaToEggConverter &copy);
+  virtual ~MayaToEggConverter();
+
+  virtual SomethingToEggConverter *make_copy();
 
-  bool init(const string &program);
-  bool read(const string &filename);
-  void make_egg(EggData &data);
+  virtual string get_name() const;
+  virtual string get_extension() const;
 
-  static DistanceUnit get_units();
-  static CoordinateSystem get_coordinate_system();
+  virtual bool convert_file(const Filename &filename);
+  bool convert_maya();
 
 private:
-  bool traverse(EggData &data);
   bool process_node(const MDagPath &dag_path, EggData &data);
   void get_transform(const MDagPath &dag_path, EggGroup *egg_group);
 
@@ -63,9 +77,11 @@ private:
                                  const string &nurbs_name,
                                  EggGroupNode *egg_group,
                                  int trim_curve_index);
-  void make_nurbs_curve(const MDagPath &dag_path, const MFnNurbsCurve &curve,
+  void make_nurbs_curve(const MDagPath &dag_path, 
+                        const MFnNurbsCurve &curve,
                         EggGroup *group);
-  void make_polyset(const MDagPath &dag_path, const MFnMesh &mesh,
+  void make_polyset(const MDagPath &dag_path,
+                    const MFnMesh &mesh,
                     EggGroup *egg_group,
                     MayaShader *default_shader = NULL);
 
@@ -77,6 +93,7 @@ private:
 public:
   MayaShaders _shaders;
   EggTextureCollection _textures;
+  PT(MayaApi) _maya;
 };
 
 

+ 34 - 0
pandatool/src/mayaegg/maya_funcs.I

@@ -0,0 +1,34 @@
+// Filename: maya_funcs.I
+// Created by:  drose (15Apr02)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: MString output operator
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE ostream &operator << (ostream &out, const MString &str) {
+  return out << str.asChar();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MVector output operator
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE ostream &operator << (ostream &out, const MVector &vec) {
+  return out << vec.x << " " << vec.y << " " << vec.z;
+}

+ 15 - 5
pandatool/src/maya/maya_funcs.I → pandatool/src/mayaegg/maya_funcs.T

@@ -16,6 +16,13 @@
 //
 ////////////////////////////////////////////////////////////////////
 
+
+////////////////////////////////////////////////////////////////////
+//     Function: get_maya_attribute
+//  Description: A generic function to extract an attribute of some
+//               type from an MObject.  This is used to implement
+//               get_bool_attribute(), etc.
+////////////////////////////////////////////////////////////////////
 template<class ValueType>
 bool
 get_maya_attribute(MObject &node, const string &attribute_name,
@@ -23,21 +30,24 @@ get_maya_attribute(MObject &node, const string &attribute_name,
   MStatus status;
   MFnDependencyNode node_fn(node, &status);
   if (!status) {
-    nout << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
+    mayaegg_cat.error()
+      << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
     return false;
   }
 
   MObject attr = node_fn.attribute(attribute_name.c_str(), &status);
   if (!status) {
-    nout << "Object " << node_fn.name() << " does not support attribute "
-         << attribute_name << "\n";
+    mayaegg_cat.error()
+      << "Object " << node_fn.name() << " does not support attribute "
+      << attribute_name << "\n";
     return false;
   }
 
   MFnAttribute attr_fn(attr, &status);
   if (!status) {
-    nout << "Attribute " << attribute_name << " on " << node_fn.name()
-         << " is a " << attr.apiTypeStr() << ", not an Attribute.\n";
+    mayaegg_cat.error()
+      << "Attribute " << attribute_name << " on " << node_fn.name()
+      << " is a " << attr.apiTypeStr() << ", not an Attribute.\n";
     return false;
   }
 

+ 199 - 0
pandatool/src/mayaegg/maya_funcs.cxx

@@ -0,0 +1,199 @@
+// Filename: maya_funcs.cxx
+// Created by:  drose (16Feb00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://www.panda3d.org/license.txt .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "maya_funcs.h"
+
+#include "pre_maya_include.h"
+#include <maya/MObject.h>
+#include <maya/MAngle.h>
+#include <maya/MFnDependencyNode.h>
+#include <maya/MStatus.h>
+#include <maya/MFnStringData.h>
+#include <maya/MFnNumericData.h>
+#include "post_maya_include.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: get_bool_attribute
+//  Description: Extracts the named boolean attribute from the
+//               MObject.
+////////////////////////////////////////////////////////////////////
+bool
+get_bool_attribute(MObject &node, const string &attribute_name,
+                   bool &value) {
+  if (!get_maya_attribute(node, attribute_name, value)) {
+    mayaegg_cat.error()
+      << "Attribute " << attribute_name
+      << " does not have an bool value.\n";
+    describe_maya_attribute(node, attribute_name);
+    return false;
+  }
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: get_bool_attribute
+//  Description: Extracts the named angle in degrees from the
+//               MObject.
+////////////////////////////////////////////////////////////////////
+bool
+get_angle_attribute(MObject &node, const string &attribute_name,
+                    double &value) {
+  MAngle maya_value;
+  if (!get_maya_attribute(node, attribute_name, maya_value)) {
+    mayaegg_cat.error()
+      << "Attribute " << attribute_name
+      << " does not have an angle value.\n";
+    describe_maya_attribute(node, attribute_name);
+    return false;
+  }
+  value = maya_value.asDegrees();
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: get_vec2f_attribute
+//  Description: Extracts the named two-component vector from the
+//               MObject.
+////////////////////////////////////////////////////////////////////
+bool
+get_vec2f_attribute(MObject &node, const string &attribute_name,
+                    LVecBase2f &value) {
+  MStatus status;
+
+  MObject vec2f_object;
+  if (!get_maya_attribute(node, attribute_name, vec2f_object)) {
+    mayaegg_cat.error()
+      << "Attribute " << attribute_name
+      << " does not have a vec2f object value.\n";
+    describe_maya_attribute(node, attribute_name);
+    return false;
+  }
+
+  MFnNumericData data(vec2f_object, &status);
+  if (!status) {
+    mayaegg_cat.error()
+      << "Attribute " << attribute_name << " is of type "
+      << vec2f_object.apiTypeStr() << ", not a NumericData.\n";
+    return false;
+  }
+
+  status = data.getData(value[0], value[1]);
+  if (!status) {
+    mayaegg_cat.error()
+      << "Unable to extract 2 floats from " << attribute_name
+      << ", of type " << vec2f_object.apiTypeStr() << "\n";
+  }
+
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: get_vec2d_attribute
+//  Description: Extracts the named two-component vector from the
+//               MObject.
+////////////////////////////////////////////////////////////////////
+bool
+get_vec2d_attribute(MObject &node, const string &attribute_name,
+                    LVecBase2d &value) {
+  MStatus status;
+
+  MObject vec2d_object;
+  if (!get_maya_attribute(node, attribute_name, vec2d_object)) {
+    mayaegg_cat.error()
+      << "Attribute " << attribute_name
+      << " does not have a vec2d object value.\n";
+    describe_maya_attribute(node, attribute_name);
+    return false;
+  }
+
+  MFnNumericData data(vec2d_object, &status);
+  if (!status) {
+    mayaegg_cat.error()
+      << "Attribute " << attribute_name << " is of type "
+      << vec2d_object.apiTypeStr() << ", not a NumericData.\n";
+    return false;
+  }
+
+  status = data.getData(value[0], value[1]);
+  if (!status) {
+    mayaegg_cat.error()
+      << "Unable to extract 2 doubles from " << attribute_name
+      << ", of type " << vec2d_object.apiTypeStr() << "\n";
+  }
+
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: get_string_attribute
+//  Description: Extracts the named string attribute from the
+//               MObject.
+////////////////////////////////////////////////////////////////////
+bool
+get_string_attribute(MObject &node, const string &attribute_name,
+                     string &value) {
+  MStatus status;
+
+  MObject string_object;
+  if (!get_maya_attribute(node, attribute_name, string_object)) {
+    mayaegg_cat.error()
+      << "Attribute " << attribute_name
+      << " does not have an string object value.\n";
+    describe_maya_attribute(node, attribute_name);
+    return false;
+  }
+
+  MFnStringData data(string_object, &status);
+  if (!status) {
+    mayaegg_cat.error()
+      << "Attribute " << attribute_name << " is of type "
+      << string_object.apiTypeStr() << ", not a StringData.\n";
+    return false;
+  }
+
+  value = data.string().asChar();
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: describe_maya_attribute
+//  Description: Writes some error output about the indicated Maya
+//               attribute.
+////////////////////////////////////////////////////////////////////
+void
+describe_maya_attribute(MObject &node, const string &attribute_name) {
+  MStatus status;
+  MFnDependencyNode node_fn(node, &status);
+  if (!status) {
+    mayaegg_cat.error()
+      << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
+    return;
+  }
+
+  MObject attr = node_fn.attribute(attribute_name.c_str(), &status);
+  if (!status) {
+    mayaegg_cat.error()
+      << "Object " << node_fn.name() << " does not support attribute "
+      << attribute_name << "\n";
+    return;
+  }
+
+  mayaegg_cat.error()
+    << "Attribute " << attribute_name << " on object "
+    << node_fn.name() << " has type " << attr.apiTypeStr() << "\n";
+}

+ 4 - 7
pandatool/src/maya/maya_funcs.h → pandatool/src/mayaegg/maya_funcs.h

@@ -21,6 +21,7 @@
 
 #include "pandatoolbase.h"
 #include "luse.h"
+#include "config_mayaegg.h"
 
 #include "pre_maya_include.h"
 #include <maya/MFnAttribute.h>
@@ -65,14 +66,10 @@ describe_maya_attribute(MObject &node, const string &attribute_name);
 // Also, we must define some output functions for Maya objects, since
 // we can't use those built into Maya (which forward-defines the
 // ostream type incorrectly).
-INLINE ostream &operator << (ostream &out, const MString &str) {
-  return out << str.asChar();
-}
-INLINE ostream &operator << (ostream &out, const MVector &vec) {
-  return out << vec.x << " " << vec.y << " " << vec.z;
-}
-
+INLINE ostream &operator << (ostream &out, const MString &str);
+INLINE ostream &operator << (ostream &out, const MVector &vec);
 
 #include "maya_funcs.I"
+#include "maya_funcs.T"
 
 #endif

+ 0 - 0
pandatool/src/maya/post_maya_include.h → pandatool/src/mayaegg/post_maya_include.h


+ 0 - 0
pandatool/src/maya/pre_maya_include.h → pandatool/src/mayaegg/pre_maya_include.h


+ 2 - 5
pandatool/src/maya/Sources.pp → pandatool/src/mayaprogs/Sources.pp

@@ -25,7 +25,7 @@
   #define USE_MAYA yes
   #define TARGET $[binary_name]
   #define LOCAL_LIBS \
-    eggbase progbase
+    mayaegg eggbase progbase
   #define OTHER_LIBS \
     egg:c pandaegg:m \
     linmath:c putil:c panda:m \
@@ -36,10 +36,7 @@
     m
 
   #define SOURCES \
-    global_parameters.cxx global_parameters.h mayaFile.cxx mayaFile.h \
-    mayaShader.cxx mayaShader.h mayaShaders.cxx mayaShaders.h \
-    mayaToEgg.cxx mayaToEgg.h maya_funcs.I maya_funcs.cxx maya_funcs.h \
-    post_maya_include.h pre_maya_include.h
+    mayaToEgg.cxx mayaToEgg.h
 
 #end bin_target
 

+ 0 - 0
pandatool/src/maya/maya2egg_script → pandatool/src/mayaprogs/maya2egg_script


+ 32 - 18
pandatool/src/maya/mayaToEgg.cxx → pandatool/src/mayaprogs/mayaToEgg.cxx

@@ -17,7 +17,9 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "mayaToEgg.h"
-#include "global_parameters.h"
+#include "mayaParameters.h"
+#include "mayaToEggConverter.h"
+#include "config_mayaegg.h"
 
 ////////////////////////////////////////////////////////////////////
 //     Function: MayaToEgg::Constructor
@@ -31,9 +33,9 @@ MayaToEgg() :
   add_units_options();
   add_normals_options();
   add_transform_options();
-  //  add_texture_path_options();
-  //  add_rel_dir_options();
-  //  add_search_path_options(false);
+  add_texture_path_options();
+  add_rel_dir_options();
+  add_search_path_options(false);
 
   set_program_description
     ("This program converts Maya model files to egg.  Nothing fancy yet.");
@@ -43,14 +45,14 @@ MayaToEgg() :
      "Generate polygon output only.  Tesselate all NURBS surfaces to "
      "polygons via the built-in Maya tesselator.  The tesselation will "
      "be based on the tolerance factor given by -ptol.",
-     &MayaToEgg::dispatch_none, &polygon_output);
+     &MayaToEgg::dispatch_none, &MayaParameters::polygon_output);
 
   add_option
     ("ptol", "tolerance", 0,
      "Specify the fit tolerance for Maya polygon tesselation.  The smaller "
      "the number, the more polygons will be generated.  The default is "
      "0.01.",
-     &MayaToEgg::dispatch_double, NULL, &polygon_tolerance);
+     &MayaToEgg::dispatch_double, NULL, &MayaParameters::polygon_tolerance);
 
   add_option
     ("notrans", "", 0,
@@ -59,13 +61,13 @@ MayaToEgg() :
      "one big transform space.  Using this option doesn't change the "
      "position of objects in the scene, just the number of explicit "
      "transforms appearing in the resulting egg file.",
-     &MayaToEgg::dispatch_none, &ignore_transforms);
+     &MayaToEgg::dispatch_none, &MayaParameters::ignore_transforms);
 
   add_option
     ("v", "", 0,
      "Increase verbosity.  More v's means more verbose.",
-     &MayaToEgg::dispatch_count, NULL, &verbose);
-  verbose = 0;
+     &MayaToEgg::dispatch_count, NULL, &_verbose);
+  _verbose = 0;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -75,31 +77,43 @@ MayaToEgg() :
 ////////////////////////////////////////////////////////////////////
 void MayaToEgg::
 run() {
-  nout << "Initializing Maya.\n";
-  if (!_maya.init(_program_name)) {
-    nout << "Unable to initialize Maya.\n";
-    exit(1);
+  // Set the verbose level by using Notify.
+  if (_verbose >= 3) {
+    mayaegg_cat->set_severity(NS_spam);
+  } else if (_verbose >= 2) {
+    mayaegg_cat->set_severity(NS_debug);
+  } else if (_verbose >= 1) {
+    mayaegg_cat->set_severity(NS_info);
   }
 
-  if (!_maya.read(_input_filename.c_str())) {
-    nout << "Error reading " << _input_filename << ".\n";
+  nout << "Initializing Maya.\n";
+  MayaToEggConverter converter(_program_name);
+  if (!converter._maya->is_valid()) {
+    nout << "Unable to initialize Maya.\n";
     exit(1);
   }
 
   // Set the coordinate system to match Maya's.
   if (!_got_coordinate_system) {
-    _coordinate_system = MayaFile::get_coordinate_system();
+    _coordinate_system = converter._maya->get_coordinate_system();
   }
   _data.set_coordinate_system(_coordinate_system);
 
   // Get the units from the Maya file, if the user didn't override.
   if (_input_units == DU_invalid) {
-    _input_units = MayaFile::get_units();
+    _input_units = converter._maya->get_units();
   }
 
-  _maya.make_egg(_data);
+  converter.set_egg_data(&_data, false);
+  converter.set_texture_path_convert(_texture_path_convert, _make_rel_dir);
+
+  if (!converter.convert_file(_input_filename)) {
+    nout << "Errors in conversion.\n";
+    exit(1);
+  }
 
   write_egg_file();
+  nout << "\n";
 }
 
 

+ 2 - 2
pandatool/src/maya/mayaToEgg.h → pandatool/src/mayaprogs/mayaToEgg.h

@@ -20,7 +20,6 @@
 #define MAYATOEGG_H
 
 #include "pandatoolbase.h"
-#include "mayaFile.h"
 #include "somethingToEgg.h"
 
 ////////////////////////////////////////////////////////////////////
@@ -30,10 +29,11 @@
 class MayaToEgg : public SomethingToEgg {
 public:
   MayaToEgg();
+  ~MayaToEgg();
 
   void run();
 
-  MayaFile _maya;
+  int _verbose;
 };
 
 #endif

+ 5 - 1
pandatool/src/ptloader/Sources.pp

@@ -1,7 +1,8 @@
 #begin lib_target
   #define TARGET ptloader
   #define BUILDING_DLL BUILDING_PTLOADER
-  #define LOCAL_LIBS xfile fltegg flt lwoegg lwo converter pandatoolbase
+  #define LOCAL_LIBS \
+    xfile fltegg flt lwoegg lwo mayaegg converter pandatoolbase
   #define OTHER_LIBS \
     egg2pg:c builder:c egg:c pandaegg:m \
     mathutil:c linmath:c putil:c panda:m \
@@ -16,6 +17,9 @@
     #define USE_DX yes
   #endif
 
+  // If we've got Maya, link in the Maya libraries.
+  #define USE_MAYA yes
+
   #define SOURCES \
     config_ptloader.cxx config_ptloader.h \
     loaderFileTypePandatool.cxx loaderFileTypePandatool.h

+ 11 - 0
pandatool/src/ptloader/config_ptloader.cxx

@@ -29,6 +29,11 @@
 #include "xFileToEggConverter.h"
 #endif
 
+#ifdef HAVE_MAYA
+#include "config_mayaegg.h"
+#include "mayaToEggConverter.h"
+#endif
+
 #include "dconfig.h"
 #include "loaderFileTypeRegistry.h"
 #include "eggData.h"
@@ -72,4 +77,10 @@ init_libptloader() {
   XFileToEggConverter *xfile = new XFileToEggConverter;
   reg->register_type(new LoaderFileTypePandatool(xfile));
 #endif
+
+#ifdef HAVE_MAYA
+  init_libmayaegg();
+  MayaToEggConverter *maya = new MayaToEggConverter;
+  reg->register_type(new LoaderFileTypePandatool(maya));
+#endif
 }