18 #include "config_maya.h"
19 #include "cvsSourceDirectory.h"
20 #include "mayaShader.h"
26 #include "pre_maya_include.h"
27 #include <maya/MStringArray.h>
28 #include <maya/MGlobal.h>
29 #include <maya/MFileIO.h>
30 #include <maya/MItDag.h>
31 #include <maya/MFnDagNode.h>
32 #include <maya/MFnNurbsSurface.h>
33 #include <maya/MFnMesh.h>
34 #include <maya/MObject.h>
35 #include <maya/MDagPath.h>
36 #include <maya/MIntArray.h>
37 #include "post_maya_include.h"
46 set_program_brief(
"copy Maya .mb files into a CVS source hierarchy");
47 set_program_description
48 (
"mayacopy copies one or more Maya .mb files into a "
49 "CVS source hierarchy. "
50 "Rather than copying the named files immediately into the current "
51 "directory, it first scans the entire source hierarchy, identifying all "
52 "the already-existing files. If the named file to copy matches the "
53 "name of an already-existing file in the current directory or elsewhere "
54 "in the hierarchy, that file is overwritten. Other .mb files, as "
55 "well as texture files, that are externally referenced by the "
56 "named .mb file(s) are similarly copied.");
59 add_runline(
"[opts] file.mb [file.mb ... ]");
63 "Don't attempt to strip the Maya version number from the tail of the "
64 "source filename before it is copied into the tree.",
65 &CVSCopy::dispatch_none, &_keep_ver);
77 "Character animation files do not need to copy the texures. "
78 "This option omits the textures of the models to be re-mayacopied",
79 &CVSCopy::dispatch_none, &_omit_tex);
83 "Character animation files do not need to copy internal file references. "
84 "This option omits the references of the models to be re-mayacopied",
85 &CVSCopy::dispatch_none, &_omit_ref);
89 "Write a .ma file instead of a .mb file (regardless of input type)",
90 &CVSCopy::dispatch_none, &_maya_ascii);
92 add_path_replace_options();
102 _maya = MayaApi::open_api(_program_name);
103 if (!_maya->is_valid()) {
104 nout <<
"Unable to initialize Maya.\n";
108 SourceFiles::iterator fi;
109 for (fi = _source_files.begin(); fi != _source_files.end(); ++fi) {
116 nout <<
"\nUnable to copy, aborting!\n\n";
133 ExtraData *ed = (ExtraData *)extra_data;
136 return copy_maya_file(source, dest, dir);
142 return copy_texture(source, dest, dir);
145 nout <<
"Internal error: invalid type " << (int)ed->_type <<
"\n";
159 filter_filename(
const string &source) {
164 size_t dot = source.rfind(
'.');
165 size_t underscore = source.rfind(
"_v", dot);
166 if ((underscore != string::npos) && !isdigit(source.at(underscore+2)))
167 underscore = string::npos;
169 string extension = source.substr(dot);
170 if (extension ==
".ma" || extension ==
".mb") {
181 if (underscore == string::npos) {
183 return source.substr(0, dot) + extension;
185 return source.substr(0, underscore) + extension;
197 if (!_maya->read(source)) {
199 <<
"Unable to read " << source <<
"\n";
205 MStatus status = MFileIO::getReferences(refs);
206 if (status != MStatus::kSuccess) {
207 status.perror(
"MItDag constructor");
212 unsigned int num_refs = refs.length();
214 unsigned int ref_index;
215 maya_cat.info() <<
"num_refs = " << num_refs << endl;
216 for (ref_index = 0; ref_index < num_refs; ref_index++) {
217 maya_cat.info() <<
"curr_idx " << _curr_idx << endl;
218 string lookup = refs[ref_index].asChar();
219 string blah =
"file -q -referenceNode \"" + lookup +
"\";";
220 maya_cat.info() << blah << endl;
222 status = MGlobal::executeCommand(MString(blah.c_str()), result);
223 maya_cat.info() <<
"result = " << result.asChar() << endl;
226 size_t dup = lookup.find(
'{');
227 if (dup != string::npos){
233 string refNode = result.asChar();
234 string refCheckCmd =
"file -rfn " + refNode +
" -q -dr;";
236 status = MGlobal::executeCommand(MString(refCheckCmd.c_str()), deferredRef);
237 maya_cat.info() <<
"deferredRef = " << deferredRef << endl;
238 if (deferredRef == 1) {
246 _tree.choose_directory(filename.
get_basename(), dir, _force, _interactive);
249 if (maya_cat.is_spam()) {
255 if (maya_cat.is_debug()) {
256 string cmdStr =
"pwd";
258 status = MGlobal::executeCommand(MString(cmdStr.c_str()), result3);
259 maya_cat.debug() <<
"result = " << result3.asChar() <<
"\n";
261 _exec_string.push_back(
"file -loadReference \"" +
string(result.asChar()) +
"\" -type \"mayaBinary\" -options \"v=0\" \"" + new_filename.
to_os_generic() +
"\";");
263 maya_cat.info() <<
"executing command: " << _exec_string[_curr_idx] <<
"\n";
264 status = MGlobal::executeCommand(MString(_exec_string[_curr_idx].c_str()));
265 if (status != MStatus::kSuccess) {
266 status.perror(
"loadReference failed");
277 for (
int i = 0; i < num_shaders; i++) {
279 for (
size_t j = 0; j < shader->_all_maps.size(); j++) {
280 if (!extract_texture(*shader->_all_maps[j], dir)) {
288 if (!_maya->write(dest)) {
290 <<
"Cannot write " << dest <<
"\n";
294 for (ref_index = 0; ref_index < num_refs; ref_index++) {
299 string lookup = refs[ref_index].asChar();
301 size_t dup = lookup.find(
'{');
302 if (dup != string::npos){
310 <<
"External ref: " << filename <<
"\n";
336 _path_replace->convert_path(color_def._texture_filename);
337 if (!texture_filename.
exists()) {
338 nout <<
"*** Error: texture " << texture_filename
339 <<
" does not exist.\n";
342 nout <<
"*** Error: texture " << texture_filename
343 <<
" is not a regular file.\n";
347 ed._type = FT_texture;
350 import(texture_filename, &ed, _map_dir);
373 if (!copy_binary_file(source, dest)) {
390 MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
391 if (status != MStatus::kSuccess) {
392 status.perror(
"MItDag constructor");
400 while (!dag_iterator.isDone()) {
402 status = dag_iterator.getPath(dag_path);
403 if (status != MStatus::kSuccess) {
404 status.perror(
"MItDag::getPath");
406 if (!collect_shader_for_node(dag_path)) {
415 nout <<
"Errors encountered in traversal.\n";
429 collect_shader_for_node(
const MDagPath &dag_path) {
431 MFnDagNode dag_node(dag_path, &status);
432 if (status != MStatus::kSuccess) {
433 status.perror(
"MFnDagNode constructor");
437 if (dag_path.hasFn(MFn::kNurbsSurface)) {
438 MFnNurbsSurface surface(dag_path, &status);
443 }
else if (dag_path.hasFn(MFn::kMesh)) {
444 MFnMesh mesh(dag_path, &status);
447 MObjectArray shaders;
448 MIntArray poly_shader_indices;
450 status = mesh.getConnectedShaders(dag_path.instanceNumber(),
451 shaders, poly_shader_indices);
453 unsigned int num_shaders = shaders.length();
454 for (
unsigned int shader_index = 0;
455 shader_index < num_shaders;
457 MObject engine = shaders[shader_index];
471 int main(
int argc,
char *argv[]) {
Filename get_fullpath() const
Returns the full path to this file.
MayaShader * get_shader(int n) const
Returns the nth MayaShader that has been discovered so far.
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_...
Filename get_rel_from(const CVSSourceDirectory *other) const
Returns the relative path to this file as seen from the indicated source directory.
int get_num_shaders() const
Returns the number of unique MayaShaders that have been discovered so far.
MayaShader * find_shader_for_node(MObject node, bool legacy_shader)
Extracts the shader assigned to the indicated node.
This represents one particular directory in the hierarchy of source directory files.
The name of a file, such as a texture file or an Egg file.
This defines the various attributes that Maya may associate with the "color" channel for a particular...
string to_os_generic() const
This is similar to to_os_specific(), but it is designed to generate a filename that can be understood...
Corresponds to a single "shader" in Maya.
MayaShader * find_shader_for_shading_engine(MObject engine, bool legacy_shader)
Returns the MayaShader object associated with the indicated "shading engine".
Filename get_fullpath() const
Returns the full pathname to this particular directory.
bool exists() const
Returns true if the filename exists on the disk, false otherwise.
bool is_valid() const
Returns true if this FilePath represents a valid file, or false if it represents an error return...
string get_basename() const
Returns the basename part of the filename.
bool is_regular_file() const
Returns true if the filename exists and is the name of a regular file (i.e.
void clear()
Frees all of the previously-defined MayaShader objects associated with this set.
bool reset_maya_texture(const Filename &texture)
Changes the texture filename stored in the Maya file for this particular shader.
A program to copy Maya .mb files into the cvs tree.
static Filename from_os_specific(const string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes, and no drive letter) based on the supplied filename string that describes a filename in the local system conventions (for instance, on Windows, it may use backslashes or begin with a drive letter and a colon).