Panda3D

mayaToEgg.cxx

00001 // Filename: mayaToEgg.cxx
00002 // Created by:  drose (15Feb00)
00003 //
00004 // Additional Maintenance by the PandaSE team
00005 // Carnegie Mellon Entertainment Technology Center
00006 // Spring '10
00007 // Team Members:
00008 // Deepak Chandraskeran - producer / programmer
00009 // Andrew Gartner - programmer/technical artist
00010 // Federico Perazzi - programmer
00011 // Shuying Feng - programmer
00012 // Wei-Feng Huang - programmer
00013 // (Egger additions by Andrew Gartner and Wei-Feng Huang)
00014 // The egger can now support vertex color in a variety
00015 // of combinations with flat color and file color textures
00016 // (see set_vertex_color).  Also, there are two new 
00017 // command line options "legacy-shaders" and "texture-copy".
00018 // The first treats any Maya material/shader as if it were 
00019 // a legacy shader. Passing it through the legacy codepath.
00020 // This feature was originally intended to fix a bug where
00021 // flat-color was being ignored in the modern (Phong) codepath
00022 // However, with the new vertex and flat color functions it
00023 // may not be necessary.  Still, until the newer color functions
00024 // have been tried and tested more, the feature has been left in
00025 // to anticipate any problems that may arise. The texture copy
00026 // feature was added to provide a way to resolve build path issues
00027 // and can support both relative and absolute paths. The feature
00028 // will copy any file maps/textures to the specified directory
00029 // and update the egg file accordingly.
00030 //
00031 ////////////////////////////////////////////////////////////////////
00032 //
00033 // PANDA 3D SOFTWARE
00034 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00035 //
00036 // All use of this software is subject to the terms of the revised BSD
00037 // license.  You should have received a copy of this license along
00038 // with this source code in a file named "LICENSE."
00039 //
00040 ////////////////////////////////////////////////////////////////////
00041 
00042 #include "mayaToEgg.h"
00043 #include "mayaToEggConverter.h"
00044 #include "config_mayaegg.h"
00045 #include "config_maya.h"  // for maya_cat
00046 #include "globPattern.h"
00047 #ifdef _WIN32
00048   #include "pystub.h"
00049 #endif
00050 
00051 ////////////////////////////////////////////////////////////////////
00052 //     Function: MayaToEgg::Constructor
00053 //       Access: Public
00054 //  Description:
00055 ////////////////////////////////////////////////////////////////////
00056 MayaToEgg::
00057 MayaToEgg() :
00058   SomethingToEgg("Maya", ".mb")
00059 {
00060   add_path_replace_options();
00061   add_path_store_options();
00062   add_animation_options();
00063   add_units_options();
00064   add_normals_options();
00065   add_transform_options();
00066 
00067   set_program_description
00068     ("This program converts Maya model files to egg.  Static and animatable "
00069      "models can be converted, with polygon or NURBS output.  Animation tables "
00070      "can also be generated to apply to an animatable model.");
00071 
00072   add_option
00073     ("p", "", 0,
00074      "Generate polygon output only.  Tesselate all NURBS surfaces to "
00075      "polygons via the built-in Maya tesselator.  The tesselation will "
00076      "be based on the tolerance factor given by -ptol.",
00077      &MayaToEgg::dispatch_none, &_polygon_output);
00078 
00079   add_option
00080     ("ptol", "tolerance", 0,
00081      "Specify the fit tolerance for Maya polygon tesselation.  The smaller "
00082      "the number, the more polygons will be generated.  The default is "
00083      "0.01.",
00084      &MayaToEgg::dispatch_double, NULL, &_polygon_tolerance);
00085 
00086   add_option
00087     ("bface", "", 0,
00088      "Respect the Maya \"double sided\" rendering flag to indicate whether "
00089      "polygons should be double-sided or single-sided.  Since this flag "
00090      "is set to double-sided by default in Maya, it is often better to "
00091      "ignore this flag (unless your modelers are diligent in turning it "
00092      "off where it is not desired).  If this flag is not specified, the "
00093      "default is to treat all polygons as single-sided, unless an "
00094      "egg object type of \"double-sided\" is set.",
00095      &MayaToEgg::dispatch_none, &_respect_maya_double_sided);
00096 
00097   add_option
00098     ("suppress-vcolor", "", 0,
00099      "Ignore vertex color for geometry that has a texture applied.  "
00100      "(This is the way Maya normally renders internally.)  The egg flag "
00101      "'vertex-color' may be applied to a particular model to override "
00102      "this setting locally.",
00103      &MayaToEgg::dispatch_none, &_suppress_vertex_color);
00104 
00105   add_option
00106     ("keep-uvs", "", 0,
00107      "Convert all UV sets on all vertices, even those that do not appear "
00108      "to be referenced by any textures.",
00109      &MayaToEgg::dispatch_none, &_keep_all_uvsets);
00110 
00111   add_option
00112     ("round-uvs", "", 0,
00113      "round up uv coordinates to the nearest 1/100th. i.e. -0.001 becomes"
00114      "0.0; 0.444 becomes 0.44; 0.778 becomes 0.78.",
00115      &MayaToEgg::dispatch_none, &_round_uvs);
00116 
00117   add_option
00118     ("copytex","dir",0,
00119     "copy the textures to a ""Textures"" sub directory relative to the written out egg file."
00120     """dir"" is a sub directory in the same format as those used by -pr, etc." ,
00121      &MayaToEgg::dispatch_filename, &_texture_copy, &_texture_out_dir);
00122 
00123   add_option
00124     ("trans", "type", 0,
00125      "Specifies which transforms in the Maya file should be converted to "
00126      "transforms in the egg file.  The option may be one of all, model, "
00127      "dcs, or none.  The default is model, which means only transforms on "
00128      "nodes that have the model flag or the dcs flag are preserved.",
00129      &MayaToEgg::dispatch_transform_type, NULL, &_transform_type);
00130 
00131   add_option
00132     ("subroot", "name", 0,
00133      "Specifies that only a subroot of the geometry in the Maya file should "
00134      "be converted; specifically, the geometry under the node or nodes whose "
00135      "name matches the parameter (which may include globbing characters "
00136      "like * or ?).  This parameter may be repeated multiple times to name "
00137      "multiple roots.  If it is omitted altogether, the entire file is "
00138      "converted.",
00139      &MayaToEgg::dispatch_vector_string, NULL, &_subroots);
00140 
00141   add_option
00142     ("subset", "name", 0,
00143      "Specifies that only a subset of the geometry in the Maya file should "
00144      "be converted; specifically, the geometry under the node or nodes whose "
00145      "name matches the parameter (which may include globbing characters "
00146      "like * or ?).  This parameter may be repeated multiple times to name "
00147      "multiple roots.  If it is omitted altogether, the entire file is "
00148      "converted.",
00149      &MayaToEgg::dispatch_vector_string, NULL, &_subsets);
00150 
00151   add_option
00152     ("exclude", "name", 0,
00153      "Specifies that a subset of the geometry in the Maya file should "
00154      "not be converted; specifically, the geometry under the node or nodes whose "
00155      "name matches the parameter (which may include globbing characters "
00156      "like * or ?).  This parameter may be repeated multiple times to name "
00157      "multiple roots.",
00158      &MayaToEgg::dispatch_vector_string, NULL, &_excludes);
00159 
00160   add_option
00161     ("ignore-slider", "name", 0,
00162      "Specifies the name of a slider (blend shape deformer) that maya2egg "
00163      "should not process.  The slider will not be touched during conversion "
00164      "and it will not become a part of the animation.  This "
00165      "parameter may including globbing characters, and it may be repeated "
00166      "as needed.",
00167      &MayaToEgg::dispatch_vector_string, NULL, &_ignore_sliders);
00168 
00169   add_option
00170     ("force-joint", "name", 0,
00171      "Specifies the name of a DAG node that maya2egg "
00172      "should treat as a joint, even if it does not appear to be a Maya joint "
00173      "and does not appear to be animated.",
00174      &MayaToEgg::dispatch_vector_string, NULL, &_force_joints);
00175 
00176   add_option
00177     ("v", "", 0,
00178      "Increase verbosity.  More v's means more verbose.",
00179      &MayaToEgg::dispatch_count, NULL, &_verbose);
00180 
00181   add_option
00182     ("legacy-shaders", "", 0,
00183      "Use this flag to turn off modern (Phong) shader generation"
00184      "and treat all shaders as if they were Lamberts (legacy).",
00185      &MayaToEgg::dispatch_none, &_legacy_shader);
00186 
00187   // Unfortunately, the Maya API doesn't allow us to differentiate
00188   // between relative and absolute pathnames--everything comes out as
00189   // an absolute pathname, even if it is stored in the Maya file as a
00190   // relative path.  So we can't support -noabs.
00191   remove_option("noabs");
00192 
00193   _verbose = 0;
00194   _polygon_tolerance = 0.01;
00195   _transform_type = MayaToEggConverter::TT_model;
00196   _got_tbnauto = true;
00197 }
00198 
00199 ////////////////////////////////////////////////////////////////////
00200 //     Function: MayaToEgg::run
00201 //       Access: Public
00202 //  Description:
00203 ////////////////////////////////////////////////////////////////////
00204 void MayaToEgg::
00205 run() {
00206   // Set the verbose level by using Notify.
00207   if (_verbose >= 3) {
00208     maya_cat->set_severity(NS_spam);
00209     mayaegg_cat->set_severity(NS_spam);
00210   } else if (_verbose >= 2) {
00211     maya_cat->set_severity(NS_debug);
00212     mayaegg_cat->set_severity(NS_debug);
00213   } else if (_verbose >= 1) {
00214     maya_cat->set_severity(NS_info);
00215     mayaegg_cat->set_severity(NS_info);
00216   }
00217 
00218   // Let's convert the output file to a full path before we initialize
00219   // Maya, since Maya now has a nasty habit of changing the current
00220   // directory.
00221   if (_got_output_filename) {
00222     _output_filename.make_absolute();
00223     //conjunct the relative output path with output file's dir weifengh
00224     if (_texture_out_dir.is_local()) {
00225       Filename tempdir = _output_filename.get_dirname() + "/";
00226       _texture_out_dir = tempdir + _texture_out_dir;
00227     }
00228   }
00229 
00230   nout << "Initializing Maya.\n";
00231   MayaToEggConverter converter(_program_name);
00232   //reverting directories is really not needed for maya2egg.  It's
00233   //more needed for mayaeggloader and such
00234   if (!converter.open_api(false)) {
00235     nout << "Unable to initialize Maya.\n";
00236     exit(1);
00237   }
00238 
00239   // Copy in the command-line parameters.
00240   converter._polygon_output = _polygon_output;
00241   converter._polygon_tolerance = _polygon_tolerance;
00242   converter._respect_maya_double_sided = _respect_maya_double_sided;
00243   converter._always_show_vertex_color = !_suppress_vertex_color;
00244   converter._keep_all_uvsets = _keep_all_uvsets;
00245   converter._round_uvs = _round_uvs;
00246   converter._transform_type = _transform_type;
00247   converter._texture_copy = _texture_copy;
00248   converter._texture_out_dir = _texture_out_dir;
00249   converter._legacy_shader = _legacy_shader;
00250 
00251   vector_string::const_iterator si;
00252   if (!_subroots.empty()) {
00253     converter.clear_subroots();
00254     for (si = _subroots.begin(); si != _subroots.end(); ++si) {
00255       converter.add_subroot(GlobPattern(*si));
00256     }
00257   }
00258 
00259   if (!_subsets.empty()) {
00260     converter.clear_subsets();
00261     for (si = _subsets.begin(); si != _subsets.end(); ++si) {
00262       converter.add_subset(GlobPattern(*si));
00263     }
00264   }
00265 
00266   if (!_excludes.empty()) {
00267     converter.clear_excludes();
00268     for (si = _excludes.begin(); si != _excludes.end(); ++si) {
00269       converter.add_exclude(GlobPattern(*si));
00270     }
00271   }
00272 
00273   if (!_ignore_sliders.empty()) {
00274     converter.clear_ignore_sliders();
00275     for (si = _ignore_sliders.begin(); si != _ignore_sliders.end(); ++si) {
00276       converter.add_ignore_slider(GlobPattern(*si));
00277     }
00278   }
00279 
00280   if (!_force_joints.empty()) {
00281     converter.clear_force_joints();
00282     for (si = _force_joints.begin(); si != _force_joints.end(); ++si) {
00283       converter.add_force_joint(GlobPattern(*si));
00284     }
00285   }
00286 
00287   // Copy in the path and animation parameters.
00288   apply_parameters(converter);
00289 
00290   // Set the coordinate system to match Maya's.
00291   if (!_got_coordinate_system) {
00292     _coordinate_system = converter._maya->get_coordinate_system();
00293   }
00294   _data->set_coordinate_system(_coordinate_system);
00295 
00296   converter.set_egg_data(_data);
00297 
00298   if (!converter.convert_file(_input_filename)) {
00299     nout << "Errors in conversion.\n";
00300     exit(1);
00301   }
00302 
00303   // Use the standard Maya units, if the user didn't specify
00304   // otherwise.  This always returns centimeters, which is the way all
00305   // Maya files are stored internally (and is the units returned by
00306   // all of the API functions called here).
00307   if (_input_units == DU_invalid) {
00308     _input_units = converter.get_input_units();
00309   }
00310 
00311   write_egg_file();
00312   nout << "\n";
00313 }
00314 
00315 ////////////////////////////////////////////////////////////////////
00316 //     Function: MayaToEgg::dispatch_transform_type
00317 //       Access: Protected, Static
00318 //  Description: Dispatches a parameter that expects a
00319 //               MayaToEggConverter::TransformType option.
00320 ////////////////////////////////////////////////////////////////////
00321 bool MayaToEgg::
00322 dispatch_transform_type(const string &opt, const string &arg, void *var) {
00323   MayaToEggConverter::TransformType *ip = (MayaToEggConverter::TransformType *)var;
00324   (*ip) = MayaToEggConverter::string_transform_type(arg);
00325 
00326   if ((*ip) == MayaToEggConverter::TT_invalid) {
00327     nout << "Invalid type for -" << opt << ": " << arg << "\n"
00328          << "Valid types are all, model, dcs, and none.\n";
00329     return false;
00330   }
00331 
00332   return true;
00333 }
00334 
00335 int main(int argc, char *argv[]) {
00336   // We don't want pystub on linux, since it gives problems with Maya's python.
00337 #ifdef _WIN32
00338   // A call to pystub() to force libpystub.so to be linked in.
00339   pystub();
00340 #endif
00341 
00342   MayaToEgg prog;
00343   prog.parse_command_line(argc, argv);
00344   prog.run();
00345   return 0;
00346 }
00347 
 All Classes Functions Variables Enumerations