00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mayaCopy.h"
00020 #include "config_maya.h"
00021 #include "cvsSourceDirectory.h"
00022 #include "mayaShader.h"
00023 #include "dcast.h"
00024
00025 #include "pre_maya_include.h"
00026 #include <maya/MStringArray.h>
00027 #include <maya/MFileIO.h>
00028 #include <maya/MItDag.h>
00029 #include <maya/MFnDagNode.h>
00030 #include <maya/MFnNurbsSurface.h>
00031 #include <maya/MFnMesh.h>
00032 #include <maya/MObject.h>
00033 #include <maya/MDagPath.h>
00034 #include <maya/MIntArray.h>
00035 #include "post_maya_include.h"
00036
00037
00038
00039
00040
00041
00042 MayaCopy::
00043 MayaCopy() {
00044 set_program_description
00045 ("mayacopy copies one or more Maya .mb files into a "
00046 "CVS source hierarchy. "
00047 "Rather than copying the named files immediately into the current "
00048 "directory, it first scans the entire source hierarchy, identifying all "
00049 "the already-existing files. If the named file to copy matches the "
00050 "name of an already-existing file in the current directory or elsewhere "
00051 "in the hierarchy, that file is overwritten. Other .mb files, as "
00052 "well as texture files, that are externally referenced by the "
00053 "named .mb file(s) are similarly copied.");
00054
00055 clear_runlines();
00056 add_runline("[opts] file.mb [file.mb ... ]");
00057
00058 add_option
00059 ("keepver", "", 0,
00060 "Don't attempt to strip the Maya version number from the tail of the "
00061 "source filename before it is copied into the tree.",
00062 &CVSCopy::dispatch_none, &_keep_ver);
00063
00064 add_path_replace_options();
00065 }
00066
00067
00068
00069
00070
00071
00072 void MayaCopy::
00073 run() {
00074 _maya = MayaApi::open_api(_program_name);
00075 if (!_maya->is_valid()) {
00076 nout << "Unable to initialize Maya.\n";
00077 exit(1);
00078 }
00079
00080 SourceFiles::iterator fi;
00081 for (fi = _source_files.begin(); fi != _source_files.end(); ++fi) {
00082 ExtraData ed;
00083 ed._type = FT_maya;
00084
00085 CVSSourceDirectory *dest = import(*fi, &ed, _model_dir);
00086 if (dest == (CVSSourceDirectory *)NULL) {
00087 nout << "\nUnable to copy, aborting!\n\n";
00088 exit(1);
00089 }
00090 }
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 bool MayaCopy::
00102 copy_file(const Filename &source, const Filename &dest,
00103 CVSSourceDirectory *dir, void *extra_data, bool new_file) {
00104 ExtraData *ed = (ExtraData *)extra_data;
00105 switch (ed->_type) {
00106 case FT_maya:
00107 return copy_maya_file(source, dest, dir);
00108
00109 case FT_texture:
00110 return copy_texture(source, dest, dir);
00111 }
00112
00113 nout << "Internal error: invalid type " << (int)ed->_type << "\n";
00114 return false;
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 string MayaCopy::
00127 filter_filename(const string &source) {
00128 if (_keep_ver) {
00129 return source;
00130 }
00131
00132 size_t dot = source.rfind('.');
00133 size_t underscore = source.rfind("_v", dot);
00134
00135 string extension = source.substr(dot);
00136 if (extension == ".ma") {
00137
00138
00139 extension = ".mb";
00140 }
00141
00142 if (underscore == string::npos) {
00143
00144 return source.substr(0, dot) + extension;
00145 } else {
00146 return source.substr(0, underscore) + extension;
00147 }
00148 }
00149
00150
00151
00152
00153
00154
00155 bool MayaCopy::
00156 copy_maya_file(const Filename &source, const Filename &dest,
00157 CVSSourceDirectory *dir) {
00158 if (!_maya->read(source)) {
00159 maya_cat.error()
00160 << "Unable to read " << source << "\n";
00161 return false;
00162 }
00163
00164
00165 _shaders.clear();
00166 collect_shaders();
00167 int num_shaders = _shaders.get_num_shaders();
00168 for (int i = 0; i < num_shaders; i++) {
00169 MayaShader *shader = _shaders.get_shader(i);
00170 if (!extract_texture(shader->_color, dir)) {
00171 return false;
00172 }
00173 if (!extract_texture(shader->_transparency, dir)) {
00174 return false;
00175 }
00176 }
00177
00178
00179 MStringArray refs;
00180 MStatus status = MFileIO::getReferences(refs);
00181 if (!status) {
00182 status.perror("MItDag constructor");
00183 return false;
00184 }
00185
00186
00187 if (!_maya->write(dest)) {
00188 maya_cat.error()
00189 << "Cannot write " << dest << "\n";
00190 return false;
00191 }
00192
00193
00194 unsigned int num_refs = refs.length();
00195 if (num_refs != 0) {
00196 maya_cat.warning()
00197 << "External references are not yet properly supported by mayacopy!\n";
00198 }
00199 for (unsigned int ref_index = 0; ref_index < num_refs; ref_index++) {
00200 Filename filename =
00201 _path_replace->convert_path(refs[ref_index].asChar());
00202 maya_cat.warning()
00203 << "External ref: " << filename << "\n";
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 }
00214
00215 return true;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 bool MayaCopy::
00227 extract_texture(MayaShaderColorDef &color_def, CVSSourceDirectory *dir) {
00228 if (color_def._has_texture) {
00229 Filename texture_filename =
00230 _path_replace->convert_path(color_def._texture);
00231 if (!texture_filename.exists()) {
00232 nout << "*** Warning: texture " << texture_filename
00233 << " does not exist.\n";
00234 } else if (!texture_filename.is_regular_file()) {
00235 nout << "*** Warning: texture " << texture_filename
00236 << " is not a regular file.\n";
00237 } else {
00238 ExtraData ed;
00239 ed._type = FT_texture;
00240
00241 CVSSourceDirectory *texture_dir =
00242 import(texture_filename, &ed, _map_dir);
00243 if (texture_dir == (CVSSourceDirectory *)NULL) {
00244 return false;
00245 }
00246
00247
00248
00249 Filename new_filename = dir->get_rel_to(texture_dir) + "/" +
00250 texture_filename.get_basename();
00251 color_def.reset_maya_texture(new_filename);
00252 }
00253 }
00254
00255 return true;
00256 }
00257
00258
00259
00260
00261
00262
00263 bool MayaCopy::
00264 copy_texture(const Filename &source, const Filename &dest,
00265 CVSSourceDirectory *dir) {
00266 if (!copy_binary_file(source, dest)) {
00267 return false;
00268 }
00269
00270 return true;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279 bool MayaCopy::
00280 collect_shaders() {
00281 MStatus status;
00282
00283 MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
00284 if (!status) {
00285 status.perror("MItDag constructor");
00286 return false;
00287 }
00288
00289
00290
00291
00292 bool all_ok = true;
00293 while (!dag_iterator.isDone()) {
00294 MDagPath dag_path;
00295 status = dag_iterator.getPath(dag_path);
00296 if (!status) {
00297 status.perror("MItDag::getPath");
00298 } else {
00299 if (!collect_shader_for_node(dag_path)) {
00300 all_ok = false;
00301 }
00302 }
00303
00304 dag_iterator.next();
00305 }
00306
00307 if (!all_ok) {
00308 nout << "Errors encountered in traversal.\n";
00309 return false;
00310 }
00311
00312 return true;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321 bool MayaCopy::
00322 collect_shader_for_node(const MDagPath &dag_path) {
00323 MStatus status;
00324 MFnDagNode dag_node(dag_path, &status);
00325 if (!status) {
00326 status.perror("MFnDagNode constructor");
00327 return false;
00328 }
00329
00330 if (dag_path.hasFn(MFn::kNurbsSurface)) {
00331 MFnNurbsSurface surface(dag_path, &status);
00332 if (status) {
00333 _shaders.find_shader_for_node(surface.object());
00334 }
00335
00336 } else if (dag_path.hasFn(MFn::kMesh)) {
00337 MFnMesh mesh(dag_path, &status);
00338 if (status) {
00339
00340 MObjectArray shaders;
00341 MIntArray poly_shader_indices;
00342
00343 status = mesh.getConnectedShaders(dag_path.instanceNumber(),
00344 shaders, poly_shader_indices);
00345 if (status) {
00346 unsigned int num_shaders = shaders.length();
00347 for (unsigned int shader_index = 0;
00348 shader_index < num_shaders;
00349 shader_index++) {
00350 MObject engine = shaders[shader_index];
00351 _shaders.find_shader_for_shading_engine(engine);
00352 }
00353 }
00354 }
00355
00356 } else {
00357
00358 }
00359
00360 return true;
00361 }
00362
00363
00364 int main(int argc, char *argv[]) {
00365 MayaCopy prog;
00366 prog.parse_command_line(argc, argv);
00367 prog.run();
00368 return 0;
00369 }