Panda3D
mayaToEgg.cxx
1 // Filename: mayaToEgg.cxx
2 // Created by: drose (15Feb00)
3 //
4 // Additional Maintenance by the PandaSE team
5 // Carnegie Mellon Entertainment Technology Center
6 // Spring '10
7 // Team Members:
8 // Deepak Chandraskeran - producer / programmer
9 // Andrew Gartner - programmer/technical artist
10 // Federico Perazzi - programmer
11 // Shuying Feng - programmer
12 // Wei-Feng Huang - programmer
13 // (Egger additions by Andrew Gartner and Wei-Feng Huang)
14 // The egger can now support vertex color in a variety
15 // of combinations with flat color and file color textures
16 // (see set_vertex_color). Also, there are two new
17 // command line options "legacy-shaders" and "texture-copy".
18 // The first treats any Maya material/shader as if it were
19 // a legacy shader. Passing it through the legacy codepath.
20 // This feature was originally intended to fix a bug where
21 // flat-color was being ignored in the modern (Phong) codepath
22 // However, with the new vertex and flat color functions it
23 // may not be necessary. Still, until the newer color functions
24 // have been tried and tested more, the feature has been left in
25 // to anticipate any problems that may arise. The texture copy
26 // feature was added to provide a way to resolve build path issues
27 // and can support both relative and absolute paths. The feature
28 // will copy any file maps/textures to the specified directory
29 // and update the egg file accordingly.
30 //
31 ////////////////////////////////////////////////////////////////////
32 //
33 // PANDA 3D SOFTWARE
34 // Copyright (c) Carnegie Mellon University. All rights reserved.
35 //
36 // All use of this software is subject to the terms of the revised BSD
37 // license. You should have received a copy of this license along
38 // with this source code in a file named "LICENSE."
39 //
40 ////////////////////////////////////////////////////////////////////
41 
42 #include "mayaToEgg.h"
43 #include "mayaToEggConverter.h"
44 #include "config_mayaegg.h"
45 #include "config_maya.h" // for maya_cat
46 #include "globPattern.h"
47 #ifdef _WIN32
48  #include "pystub.h"
49 #endif
50 
51 ////////////////////////////////////////////////////////////////////
52 // Function: MayaToEgg::Constructor
53 // Access: Public
54 // Description:
55 ////////////////////////////////////////////////////////////////////
56 MayaToEgg::
57 MayaToEgg() :
58  SomethingToEgg("Maya", ".mb")
59 {
60  add_path_replace_options();
61  add_path_store_options();
62  add_animation_options();
63  add_units_options();
64  add_normals_options();
65  add_transform_options();
66 
67  set_program_brief("convert Maya model files to .egg");
68  set_program_description
69  ("This program converts Maya model files to egg. Static and animatable "
70  "models can be converted, with polygon or NURBS output. Animation tables "
71  "can also be generated to apply to an animatable model.");
72 
73  add_option
74  ("p", "", 0,
75  "Generate polygon output only. Tesselate all NURBS surfaces to "
76  "polygons via the built-in Maya tesselator. The tesselation will "
77  "be based on the tolerance factor given by -ptol.",
78  &MayaToEgg::dispatch_none, &_polygon_output);
79 
80  add_option
81  ("ptol", "tolerance", 0,
82  "Specify the fit tolerance for Maya polygon tesselation. The smaller "
83  "the number, the more polygons will be generated. The default is "
84  "0.01.",
85  &MayaToEgg::dispatch_double, NULL, &_polygon_tolerance);
86 
87  add_option
88  ("bface", "", 0,
89  "Respect the Maya \"double sided\" rendering flag to indicate whether "
90  "polygons should be double-sided or single-sided. Since this flag "
91  "is set to double-sided by default in Maya, it is often better to "
92  "ignore this flag (unless your modelers are diligent in turning it "
93  "off where it is not desired). If this flag is not specified, the "
94  "default is to treat all polygons as single-sided, unless an "
95  "egg object type of \"double-sided\" is set.",
96  &MayaToEgg::dispatch_none, &_respect_maya_double_sided);
97 
98  add_option
99  ("suppress-vcolor", "", 0,
100  "Ignore vertex color for geometry that has a texture applied. "
101  "(This is the way Maya normally renders internally.) The egg flag "
102  "'vertex-color' may be applied to a particular model to override "
103  "this setting locally.",
104  &MayaToEgg::dispatch_none, &_suppress_vertex_color);
105 
106  add_option
107  ("convert-cameras", "", 0,
108  "Convert all camera nodes to locators. Will preserve position and rotation.",
109  &MayaToEgg::dispatch_none, &_convert_cameras);
110 
111  add_option
112  ("convert-lights", "", 0,
113  "Convert all light nodes to locators. Will preserve position and rotation only.",
114  &MayaToEgg::dispatch_none, &_convert_lights);
115 
116  add_option
117  ("keep-uvs", "", 0,
118  "Convert all UV sets on all vertices, even those that do not appear "
119  "to be referenced by any textures.",
120  &MayaToEgg::dispatch_none, &_keep_all_uvsets);
121 
122  add_option
123  ("round-uvs", "", 0,
124  "round up uv coordinates to the nearest 1/100th. i.e. -0.001 becomes"
125  "0.0; 0.444 becomes 0.44; 0.778 becomes 0.78.",
126  &MayaToEgg::dispatch_none, &_round_uvs);
127 
128  add_option
129  ("copytex", "dir", 41,
130  "Legacy option. Same as -pc.",
131  &MayaToEgg::dispatch_filename, &_legacy_copytex, &_legacy_copytex_dir);
132 
133  add_option
134  ("trans", "type", 0,
135  "Specifies which transforms in the Maya file should be converted to "
136  "transforms in the egg file. The option may be one of all, model, "
137  "dcs, or none. The default is model, which means only transforms on "
138  "nodes that have the model flag or the dcs flag are preserved.",
139  &MayaToEgg::dispatch_transform_type, NULL, &_transform_type);
140 
141  add_option
142  ("subroot", "name", 0,
143  "Specifies that only a subroot of the geometry in the Maya file should "
144  "be converted; specifically, the geometry under the node or nodes whose "
145  "name matches the parameter (which may include globbing characters "
146  "like * or ?). This parameter may be repeated multiple times to name "
147  "multiple roots. If it is omitted altogether, the entire file is "
148  "converted.",
149  &MayaToEgg::dispatch_vector_string, NULL, &_subroots);
150 
151  add_option
152  ("subset", "name", 0,
153  "Specifies that only a subset of the geometry in the Maya file should "
154  "be converted; specifically, the geometry under the node or nodes whose "
155  "name matches the parameter (which may include globbing characters "
156  "like * or ?). This parameter may be repeated multiple times to name "
157  "multiple roots. If it is omitted altogether, the entire file is "
158  "converted.",
159  &MayaToEgg::dispatch_vector_string, NULL, &_subsets);
160 
161  add_option
162  ("exclude", "name", 0,
163  "Specifies that a subset of the geometry in the Maya file should "
164  "not be converted; specifically, the geometry under the node or nodes whose "
165  "name matches the parameter (which may include globbing characters "
166  "like * or ?). This parameter may be repeated multiple times to name "
167  "multiple roots.",
168  &MayaToEgg::dispatch_vector_string, NULL, &_excludes);
169 
170  add_option
171  ("ignore-slider", "name", 0,
172  "Specifies the name of a slider (blend shape deformer) that maya2egg "
173  "should not process. The slider will not be touched during conversion "
174  "and it will not become a part of the animation. This "
175  "parameter may including globbing characters, and it may be repeated "
176  "as needed.",
177  &MayaToEgg::dispatch_vector_string, NULL, &_ignore_sliders);
178 
179  add_option
180  ("force-joint", "name", 0,
181  "Specifies the name of a DAG node that maya2egg "
182  "should treat as a joint, even if it does not appear to be a Maya joint "
183  "and does not appear to be animated.",
184  &MayaToEgg::dispatch_vector_string, NULL, &_force_joints);
185 
186  add_option
187  ("v", "", 0,
188  "Increase verbosity. More v's means more verbose.",
189  &MayaToEgg::dispatch_count, NULL, &_verbose);
190 
191  add_option
192  ("legacy-shaders", "", 0,
193  "Use this flag to turn off modern (Phong) shader generation"
194  "and treat all shaders as if they were Lamberts (legacy).",
195  &MayaToEgg::dispatch_none, &_legacy_shader);
196 
197  // Unfortunately, the Maya API doesn't allow us to differentiate
198  // between relative and absolute pathnames--everything comes out as
199  // an absolute pathname, even if it is stored in the Maya file as a
200  // relative path. So we can't support -noabs.
201  remove_option("noabs");
202 
203  _verbose = 0;
204  _polygon_tolerance = 0.01;
205  _transform_type = MayaToEggConverter::TT_model;
206  _got_tbnauto = true;
207 }
208 
209 ////////////////////////////////////////////////////////////////////
210 // Function: MayaToEgg::run
211 // Access: Public
212 // Description:
213 ////////////////////////////////////////////////////////////////////
214 void MayaToEgg::
215 run() {
216  // Set the verbose level by using Notify.
217  if (_verbose >= 3) {
218  maya_cat->set_severity(NS_spam);
219  mayaegg_cat->set_severity(NS_spam);
220  } else if (_verbose >= 2) {
221  maya_cat->set_severity(NS_debug);
222  mayaegg_cat->set_severity(NS_debug);
223  } else if (_verbose >= 1) {
224  maya_cat->set_severity(NS_info);
225  mayaegg_cat->set_severity(NS_info);
226  }
227 
228  if (_legacy_copytex && !_path_replace->_copy_files) {
229  _path_replace->_copy_files = true;
230  _path_replace->_copy_into_directory = _legacy_copytex_dir;
231  }
232 
233  // Let's convert the output file to a full path before we initialize
234  // Maya, since Maya now has a nasty habit of changing the current
235  // directory.
236  if (_got_output_filename) {
237  _output_filename.make_absolute();
238  _path_replace->_path_directory.make_absolute();
239  }
240 
241  nout << "Initializing Maya.\n";
242  MayaToEggConverter converter(_program_name);
243  //reverting directories is really not needed for maya2egg. It's
244  //more needed for mayaeggloader and such
245  if (!converter.open_api(false)) {
246  nout << "Unable to initialize Maya.\n";
247  exit(1);
248  }
249 
250  // Copy in the command-line parameters.
251  converter._polygon_output = _polygon_output;
252  converter._polygon_tolerance = _polygon_tolerance;
253  converter._respect_maya_double_sided = _respect_maya_double_sided;
254  converter._always_show_vertex_color = !_suppress_vertex_color;
255  converter._keep_all_uvsets = _keep_all_uvsets;
256  converter._convert_cameras = _convert_cameras;
257  converter._convert_lights = _convert_lights;
258  converter._round_uvs = _round_uvs;
259  converter._transform_type = _transform_type;
260  converter._legacy_shader = _legacy_shader;
261 
262  vector_string::const_iterator si;
263  if (!_subroots.empty()) {
264  converter.clear_subroots();
265  for (si = _subroots.begin(); si != _subroots.end(); ++si) {
266  converter.add_subroot(GlobPattern(*si));
267  }
268  }
269 
270  if (!_subsets.empty()) {
271  converter.clear_subsets();
272  for (si = _subsets.begin(); si != _subsets.end(); ++si) {
273  converter.add_subset(GlobPattern(*si));
274  }
275  }
276 
277  if (!_excludes.empty()) {
278  converter.clear_excludes();
279  for (si = _excludes.begin(); si != _excludes.end(); ++si) {
280  converter.add_exclude(GlobPattern(*si));
281  }
282  }
283 
284  if (!_ignore_sliders.empty()) {
285  converter.clear_ignore_sliders();
286  for (si = _ignore_sliders.begin(); si != _ignore_sliders.end(); ++si) {
287  converter.add_ignore_slider(GlobPattern(*si));
288  }
289  }
290 
291  if (!_force_joints.empty()) {
292  converter.clear_force_joints();
293  for (si = _force_joints.begin(); si != _force_joints.end(); ++si) {
294  converter.add_force_joint(GlobPattern(*si));
295  }
296  }
297 
298  // Copy in the path and animation parameters.
299  apply_parameters(converter);
300 
301  // Set the coordinate system to match Maya's.
302  if (!_got_coordinate_system) {
303  _coordinate_system = converter._maya->get_coordinate_system();
304  }
305  _data->set_coordinate_system(_coordinate_system);
306 
307  converter.set_egg_data(_data);
308 
309  if (!converter.convert_file(_input_filename)) {
310  nout << "Errors in conversion.\n";
311  exit(1);
312  }
313 
314  // Use the standard Maya units, if the user didn't specify
315  // otherwise. This always returns centimeters, which is the way all
316  // Maya files are stored internally (and is the units returned by
317  // all of the API functions called here).
318  if (_input_units == DU_invalid) {
319  _input_units = converter.get_input_units();
320  }
321 
322  write_egg_file();
323  nout << "\n";
324 }
325 
326 ////////////////////////////////////////////////////////////////////
327 // Function: MayaToEgg::dispatch_transform_type
328 // Access: Protected, Static
329 // Description: Dispatches a parameter that expects a
330 // MayaToEggConverter::TransformType option.
331 ////////////////////////////////////////////////////////////////////
332 bool MayaToEgg::
333 dispatch_transform_type(const string &opt, const string &arg, void *var) {
334  MayaToEggConverter::TransformType *ip = (MayaToEggConverter::TransformType *)var;
336 
337  if ((*ip) == MayaToEggConverter::TT_invalid) {
338  nout << "Invalid type for -" << opt << ": " << arg << "\n"
339  << "Valid types are all, model, dcs, and none.\n";
340  return false;
341  }
342 
343  return true;
344 }
345 
346 int main(int argc, char *argv[]) {
347  // We don't want pystub on linux, since it gives problems with Maya's python.
348 #ifdef _WIN32
349  // A call to pystub() to force libpystub.so to be linked in.
350  pystub();
351 #endif
352 
353  MayaToEgg prog;
354  prog.parse_command_line(argc, argv);
355  prog.run();
356  return 0;
357 }
358 
static TransformType string_transform_type(const string &arg)
Returns the TransformType value corresponding to the indicated string, or TT_invalid.
virtual void parse_command_line(int argc, char **argv)
Dispatches on each of the options on the command line, and passes the remaining parameters to handle_...
This class supervises the construction of an EggData structure from a single Maya file...
This is the general base class for a file-converter program that reads some model file format and gen...
This class can be used to test for string matches against standard Unix-shell filename globbing conve...
Definition: globPattern.h:37