00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "mayaCopy.h"
00018 #include "config_maya.h"
00019 #include "cvsSourceDirectory.h"
00020 #include "mayaShader.h"
00021 #include "dcast.h"
00022 #ifdef _WIN32
00023 #include "pystub.h"
00024 #endif
00025
00026 #include "pre_maya_include.h"
00027 #include <maya/MStringArray.h>
00028 #include <maya/MGlobal.h>
00029 #include <maya/MFileIO.h>
00030 #include <maya/MItDag.h>
00031 #include <maya/MFnDagNode.h>
00032 #include <maya/MFnNurbsSurface.h>
00033 #include <maya/MFnMesh.h>
00034 #include <maya/MObject.h>
00035 #include <maya/MDagPath.h>
00036 #include <maya/MIntArray.h>
00037 #include "post_maya_include.h"
00038
00039
00040
00041
00042
00043
00044 MayaCopy::
00045 MayaCopy() {
00046 set_program_description
00047 ("mayacopy copies one or more Maya .mb files into a "
00048 "CVS source hierarchy. "
00049 "Rather than copying the named files immediately into the current "
00050 "directory, it first scans the entire source hierarchy, identifying all "
00051 "the already-existing files. If the named file to copy matches the "
00052 "name of an already-existing file in the current directory or elsewhere "
00053 "in the hierarchy, that file is overwritten. Other .mb files, as "
00054 "well as texture files, that are externally referenced by the "
00055 "named .mb file(s) are similarly copied.");
00056
00057 clear_runlines();
00058 add_runline("[opts] file.mb [file.mb ... ]");
00059
00060 add_option
00061 ("keepver", "", 0,
00062 "Don't attempt to strip the Maya version number from the tail of the "
00063 "source filename before it is copied into the tree.",
00064 &CVSCopy::dispatch_none, &_keep_ver);
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 add_option
00075 ("omittex", "", 0,
00076 "Character animation files do not need to copy the texures. "
00077 "This option omits the textures of the models to be re-mayacopied",
00078 &CVSCopy::dispatch_none, &_omit_tex);
00079
00080 add_option
00081 ("omitref", "", 0,
00082 "Character animation files do not need to copy internal file references. "
00083 "This option omits the references of the models to be re-mayacopied",
00084 &CVSCopy::dispatch_none, &_omit_ref);
00085
00086 add_option
00087 ("ma", "", 0,
00088 "Write a .ma file instead of a .mb file (regardless of input type)",
00089 &CVSCopy::dispatch_none, &_maya_ascii);
00090
00091 add_path_replace_options();
00092 }
00093
00094
00095
00096
00097
00098
00099 void MayaCopy::
00100 run() {
00101 _maya = MayaApi::open_api(_program_name);
00102 if (!_maya->is_valid()) {
00103 nout << "Unable to initialize Maya.\n";
00104 exit(1);
00105 }
00106
00107 SourceFiles::iterator fi;
00108 for (fi = _source_files.begin(); fi != _source_files.end(); ++fi) {
00109 _curr_idx = 0;
00110 ExtraData ed;
00111 ed._type = FT_maya;
00112
00113 CVSSourceTree::FilePath path = import(*fi, &ed, _model_dir);
00114 if (!path.is_valid()) {
00115 nout << "\nUnable to copy, aborting!\n\n";
00116 exit(1);
00117 }
00118 }
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 bool MayaCopy::
00130 copy_file(const Filename &source, const Filename &dest,
00131 CVSSourceDirectory *dir, void *extra_data, bool new_file) {
00132 ExtraData *ed = (ExtraData *)extra_data;
00133 switch (ed->_type) {
00134 case FT_maya:
00135 return copy_maya_file(source, dest, dir);
00136
00137 case FT_texture:
00138 if (_omit_tex) {
00139 return true;
00140 }
00141 return copy_texture(source, dest, dir);
00142 }
00143
00144 nout << "Internal error: invalid type " << (int)ed->_type << "\n";
00145 return false;
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 string MayaCopy::
00158 filter_filename(const string &source) {
00159 if (_keep_ver) {
00160 return source;
00161 }
00162
00163 size_t dot = source.rfind('.');
00164 size_t underscore = source.rfind("_v", dot);
00165 if ((underscore != string::npos) && !isdigit(source.at(underscore+2)))
00166 underscore = string::npos;
00167
00168 string extension = source.substr(dot);
00169 if (extension == ".ma" || extension == ".mb") {
00170
00171
00172
00173 if (_maya_ascii) {
00174 extension = ".ma";
00175 } else {
00176 extension = ".mb";
00177 }
00178 }
00179
00180 if (underscore == string::npos) {
00181
00182 return source.substr(0, dot) + extension;
00183 } else {
00184 return source.substr(0, underscore) + extension;
00185 }
00186 }
00187
00188
00189
00190
00191
00192
00193 bool MayaCopy::
00194 copy_maya_file(const Filename &source, const Filename &dest,
00195 CVSSourceDirectory *dir) {
00196 if (!_maya->read(source)) {
00197 maya_cat.error()
00198 << "Unable to read " << source << "\n";
00199 return false;
00200 }
00201
00202
00203 MStringArray refs;
00204 MStatus status = MFileIO::getReferences(refs);
00205 if (status != MStatus::kSuccess) {
00206 status.perror("MItDag constructor");
00207 return false;
00208 }
00209
00210
00211 unsigned int num_refs = refs.length();
00212
00213 unsigned int ref_index;
00214 maya_cat.info() << "num_refs = " << num_refs << endl;
00215 for (ref_index = 0; ref_index < num_refs; ref_index++) {
00216 maya_cat.info() << "curr_idx " << _curr_idx << endl;
00217 string lookup = refs[ref_index].asChar();
00218 string blah = "file -q -referenceNode \"" + lookup + "\";";
00219 maya_cat.info() << blah << endl;
00220 MString result;
00221 status = MGlobal::executeCommand(MString(blah.c_str()), result);
00222 maya_cat.info() << "result = " << result.asChar() << endl;
00223
00224
00225 size_t dup = lookup.find('{');
00226 if (dup != string::npos){
00227 lookup.erase(dup);
00228 }
00229
00230
00231
00232 string refNode = result.asChar();
00233 string refCheckCmd = "file -rfn " + refNode + " -q -dr;";
00234 int deferredRef;
00235 status = MGlobal::executeCommand(MString(refCheckCmd.c_str()), deferredRef);
00236 maya_cat.info() << "deferredRef = " << deferredRef << endl;
00237 if (deferredRef == 1) {
00238 continue;
00239 }
00240
00241 Filename filename =
00242 _path_replace->convert_path(Filename::from_os_specific(lookup));
00243
00244 CVSSourceTree::FilePath path =
00245 _tree.choose_directory(filename.get_basename(), dir, _force, _interactive);
00246 Filename new_filename = path.get_rel_from(dir);
00247
00248 if (maya_cat.is_spam()) {
00249 maya_cat.spam() << "cvs dir " << dir->get_fullpath().to_os_generic() << endl;
00250 maya_cat.spam() << "cvs path " << path.get_fullpath().to_os_generic() << endl;
00251 }
00252 MString result2;
00253
00254 if (maya_cat.is_debug()) {
00255 string cmdStr = "pwd";
00256 MString result3;
00257 status = MGlobal::executeCommand(MString(cmdStr.c_str()), result3);
00258 maya_cat.debug() << "result = " << result3.asChar() << "\n";
00259 }
00260 _exec_string.push_back("file -loadReference \"" + string(result.asChar()) + "\" -type \"mayaBinary\" -options \"v=0\" \"" + new_filename.to_os_generic() + "\";");
00261 if (!_omit_ref) {
00262 maya_cat.info() << "executing command: " << _exec_string[_curr_idx] << "\n";
00263 status = MGlobal::executeCommand(MString(_exec_string[_curr_idx].c_str()));
00264 if (status != MStatus::kSuccess) {
00265 status.perror("loadReference failed");
00266 }
00267 }
00268 _curr_idx++;
00269 }
00270
00271 if (!_omit_tex) {
00272
00273 _shaders.clear();
00274 collect_shaders();
00275 int num_shaders = _shaders.get_num_shaders();
00276 for (int i = 0; i < num_shaders; i++) {
00277 MayaShader *shader = _shaders.get_shader(i);
00278 for (size_t j = 0; j < shader->_all_maps.size(); j++) {
00279 if (!extract_texture(*shader->_all_maps[j], dir)) {
00280 return false;
00281 }
00282 }
00283 }
00284 }
00285
00286
00287 if (!_maya->write(dest)) {
00288 maya_cat.error()
00289 << "Cannot write " << dest << "\n";
00290 return false;
00291 }
00292
00293 for (ref_index = 0; ref_index < num_refs; ref_index++) {
00294 if (1) {
00295 continue;
00296 }
00297
00298 string lookup = refs[ref_index].asChar();
00299
00300 size_t dup = lookup.find('{');
00301 if (dup != string::npos){
00302 lookup.erase(dup);
00303 }
00304
00305 Filename filename =
00306 _path_replace->convert_path(Filename::from_os_specific(lookup));
00307
00308 maya_cat.info()
00309 << "External ref: " << filename << "\n";
00310
00311
00312 ExtraData ed;
00313 ed._type = FT_maya;
00314
00315 CVSSourceTree::FilePath path = import(filename, &ed, _model_dir);
00316 if (!path.is_valid()) {
00317 exit(1);
00318 }
00319 }
00320
00321 return true;
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 bool MayaCopy::
00333 extract_texture(MayaShaderColorDef &color_def, CVSSourceDirectory *dir) {
00334 Filename texture_filename =
00335 _path_replace->convert_path(color_def._texture_filename);
00336 if (!texture_filename.exists()) {
00337 nout << "*** Error: texture " << texture_filename
00338 << " does not exist.\n";
00339 return false;
00340 } else if (!texture_filename.is_regular_file()) {
00341 nout << "*** Error: texture " << texture_filename
00342 << " is not a regular file.\n";
00343 return false;
00344 } else {
00345 ExtraData ed;
00346 ed._type = FT_texture;
00347
00348 CVSSourceTree::FilePath texture_path =
00349 import(texture_filename, &ed, _map_dir);
00350
00351 if (!texture_path.is_valid()) {
00352 return false;
00353 }
00354
00355
00356
00357 Filename new_filename = texture_path.get_rel_from(dir);
00358 color_def.reset_maya_texture(new_filename);
00359 }
00360
00361 return true;
00362 }
00363
00364
00365
00366
00367
00368
00369 bool MayaCopy::
00370 copy_texture(const Filename &source, const Filename &dest,
00371 CVSSourceDirectory *dir) {
00372 if (!copy_binary_file(source, dest)) {
00373 return false;
00374 }
00375
00376 return true;
00377 }
00378
00379
00380
00381
00382
00383
00384
00385 bool MayaCopy::
00386 collect_shaders() {
00387 MStatus status;
00388
00389 MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
00390 if (status != MStatus::kSuccess) {
00391 status.perror("MItDag constructor");
00392 return false;
00393 }
00394
00395
00396
00397
00398 bool all_ok = true;
00399 while (!dag_iterator.isDone()) {
00400 MDagPath dag_path;
00401 status = dag_iterator.getPath(dag_path);
00402 if (status != MStatus::kSuccess) {
00403 status.perror("MItDag::getPath");
00404 } else {
00405 if (!collect_shader_for_node(dag_path)) {
00406 all_ok = false;
00407 }
00408 }
00409
00410 dag_iterator.next();
00411 }
00412
00413 if (!all_ok) {
00414 nout << "Errors encountered in traversal.\n";
00415 return false;
00416 }
00417
00418 return true;
00419 }
00420
00421
00422
00423
00424
00425
00426
00427 bool MayaCopy::
00428 collect_shader_for_node(const MDagPath &dag_path) {
00429 MStatus status;
00430 MFnDagNode dag_node(dag_path, &status);
00431 if (status != MStatus::kSuccess) {
00432 status.perror("MFnDagNode constructor");
00433 return false;
00434 }
00435
00436 if (dag_path.hasFn(MFn::kNurbsSurface)) {
00437 MFnNurbsSurface surface(dag_path, &status);
00438 if (status) {
00439 _shaders.find_shader_for_node(surface.object(), false);
00440 }
00441
00442 } else if (dag_path.hasFn(MFn::kMesh)) {
00443 MFnMesh mesh(dag_path, &status);
00444 if (status) {
00445
00446 MObjectArray shaders;
00447 MIntArray poly_shader_indices;
00448
00449 status = mesh.getConnectedShaders(dag_path.instanceNumber(),
00450 shaders, poly_shader_indices);
00451 if (status) {
00452 unsigned int num_shaders = shaders.length();
00453 for (unsigned int shader_index = 0;
00454 shader_index < num_shaders;
00455 shader_index++) {
00456 MObject engine = shaders[shader_index];
00457 _shaders.find_shader_for_shading_engine(engine, false);
00458 }
00459 }
00460 }
00461
00462 } else {
00463
00464 }
00465
00466 return true;
00467 }
00468
00469
00470 int main(int argc, char *argv[]) {
00471
00472 #ifdef _WIN32
00473
00474 pystub();
00475 #endif
00476
00477 MayaCopy prog;
00478 prog.parse_command_line(argc, argv);
00479 prog.run();
00480 return 0;
00481 }
00482