add mayacopy

This commit is contained in:
David Rose 2002-05-15 16:19:20 +00:00
parent 59b4efd18f
commit 06181a343d
16 changed files with 439 additions and 125 deletions

View File

@ -317,7 +317,7 @@ copy_binary_file(Filename source, Filename dest) {
c = in.get(); c = in.get();
} }
if (in.fail()) { if (!in.eof() && in.fail()) {
nout << "Error reading " << source << "\n"; nout << "Error reading " << source << "\n";
return false; return false;
} }
@ -342,6 +342,8 @@ cvs_add(const Filename &filename) {
return true; return true;
} }
Filename canon = filename;
if (!CVSSourceTree::temp_chdir(filename.get_dirname())) { if (!CVSSourceTree::temp_chdir(filename.get_dirname())) {
nout << "Invalid directory: " << filename.get_dirname() << "\n"; nout << "Invalid directory: " << filename.get_dirname() << "\n";
return false; return false;

View File

@ -186,7 +186,7 @@ find_relpath(const string &relpath) {
return (CVSSourceDirectory *)NULL; return (CVSSourceDirectory *)NULL;
} }
// Check for a child named "first". // Check for a child with the name indicated by first.
Children::const_iterator ci; Children::const_iterator ci;
for (ci = _children.begin(); ci != _children.end(); ++ci) { for (ci = _children.begin(); ci != _children.end(); ++ci) {
if ((*ci)->get_dirname() == first) { if ((*ci)->get_dirname() == first) {
@ -247,6 +247,7 @@ scan(const Filename &directory, const string &key_filename) {
// Is this possibly a subdirectory name? // Is this possibly a subdirectory name?
Filename next_path(directory, filename); Filename next_path(directory, filename);
Filename key(next_path, key_filename); Filename key(next_path, key_filename);
if (key.exists()) { if (key.exists()) {
CVSSourceDirectory *subdir = CVSSourceDirectory *subdir =
new CVSSourceDirectory(_tree, this, filename); new CVSSourceDirectory(_tree, this, filename);

View File

@ -19,8 +19,8 @@
#ifndef CVSSOURCEDIRECTORY_H #ifndef CVSSOURCEDIRECTORY_H
#define CVSSOURCEDIRECTORY_H #define CVSSOURCEDIRECTORY_H
#include <pandatoolbase.h> #include "pandatoolbase.h"
#include <filename.h> #include "filename.h"
#include "pvector.h" #include "pvector.h"

View File

@ -19,21 +19,21 @@
#include "cvsSourceTree.h" #include "cvsSourceTree.h"
#include "cvsSourceDirectory.h" #include "cvsSourceDirectory.h"
#include <filename.h> #include "filename.h"
#include <executionEnvironment.h> #include "executionEnvironment.h"
#include <notify.h> #include "notify.h"
#include <algorithm> #include <algorithm>
#include <ctype.h> #include <ctype.h>
#include <stdio.h> // for perror #include <stdio.h> // for perror
#include <errno.h> #include <errno.h>
#if defined(WIN32_VC) #ifdef WIN32_VC
#include <direct.h> #include <direct.h> // for chdir
#endif #endif
bool CVSSourceTree::_got_start_fullpath = false; bool CVSSourceTree::_got_start_fullpath = false;
string CVSSourceTree::_start_fullpath; Filename CVSSourceTree::_start_fullpath;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: CVSSourceTree::Constructor // Function: CVSSourceTree::Constructor
@ -66,7 +66,7 @@ CVSSourceTree::
// than once. // than once.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CVSSourceTree:: void CVSSourceTree::
set_root(const string &root_path) { set_root(const Filename &root_path) {
nassertv(_path.empty()); nassertv(_path.empty());
_path = root_path; _path = root_path;
} }
@ -80,7 +80,7 @@ set_root(const string &root_path) {
// is an error. // is an error.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool CVSSourceTree:: bool CVSSourceTree::
scan(const string &key_filename) { scan(const Filename &key_filename) {
nassertr(_root == (CVSSourceDirectory *)NULL, false); nassertr(_root == (CVSSourceDirectory *)NULL, false);
Filename root_fullpath = get_root_fullpath(); Filename root_fullpath = get_root_fullpath();
_root = new CVSSourceDirectory(this, NULL, root_fullpath.get_basename()); _root = new CVSSourceDirectory(this, NULL, root_fullpath.get_basename());
@ -105,7 +105,7 @@ get_root() const {
// the source tree. // the source tree.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CVSSourceDirectory *CVSSourceTree:: CVSSourceDirectory *CVSSourceTree::
find_directory(const string &path) { find_directory(const Filename &path) {
string root_fullpath = get_root_fullpath(); string root_fullpath = get_root_fullpath();
string fullpath = get_actual_fullpath(path); string fullpath = get_actual_fullpath(path);
@ -118,7 +118,7 @@ find_directory(const string &path) {
} }
// The relative name is the part of fullpath not in root_fullpath. // The relative name is the part of fullpath not in root_fullpath.
string relpath = fullpath.substr(root_fullpath.length()); Filename relpath = fullpath.substr(root_fullpath.length());
return _root->find_relpath(relpath); return _root->find_relpath(relpath);
} }
@ -141,8 +141,8 @@ find_relpath(const string &relpath) {
// Check for the root dirname at the front of the path, and remove // Check for the root dirname at the front of the path, and remove
// it if it's there. // it if it's there.
size_t slash = relpath.find('/'); size_t slash = relpath.find('/');
string first = relpath.substr(0, slash); Filename first = relpath.substr(0, slash);
string rest; Filename rest;
if (slash != string::npos) { if (slash != string::npos) {
rest = relpath.substr(slash + 1); rest = relpath.substr(slash + 1);
} }
@ -177,7 +177,7 @@ find_dirname(const string &dirname) {
// directory, or uses suggested_dir. // directory, or uses suggested_dir.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
CVSSourceDirectory *CVSSourceTree:: CVSSourceDirectory *CVSSourceTree::
choose_directory(const string &filename, CVSSourceDirectory *suggested_dir, choose_directory(const Filename &filename, CVSSourceDirectory *suggested_dir,
bool force, bool interactive) { bool force, bool interactive) {
static Directories empty_dirs; static Directories empty_dirs;
@ -202,9 +202,9 @@ choose_directory(const string &filename, CVSSourceDirectory *suggested_dir,
// Description: Returns the full path from the root to the top of // Description: Returns the full path from the root to the top of
// the source hierarchy. // the source hierarchy.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
string CVSSourceTree:: Filename CVSSourceTree::
get_root_fullpath() { get_root_fullpath() {
nassertr(!_path.empty(), string()); nassertr(!_path.empty(), Filename());
if (!_got_root_fullpath) { if (!_got_root_fullpath) {
_root_fullpath = get_actual_fullpath(_path); _root_fullpath = get_actual_fullpath(_path);
_got_root_fullpath = true; _got_root_fullpath = true;
@ -218,9 +218,9 @@ get_root_fullpath() {
// Description: Returns the local directory name of the root of the // Description: Returns the local directory name of the root of the
// tree. // tree.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
string CVSSourceTree:: Filename CVSSourceTree::
get_root_dirname() const { get_root_dirname() const {
nassertr(_root != (CVSSourceDirectory *)NULL, string()); nassertr(_root != (CVSSourceDirectory *)NULL, Filename());
return _root->get_dirname(); return _root->get_dirname();
} }
@ -232,7 +232,7 @@ get_root_dirname() const {
// should not be called directly by the user. // should not be called directly by the user.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CVSSourceTree:: void CVSSourceTree::
add_file(const string &filename, CVSSourceDirectory *dir) { add_file(const Filename &filename, CVSSourceDirectory *dir) {
_filenames[filename].push_back(dir); _filenames[filename].push_back(dir);
} }
@ -245,12 +245,13 @@ add_file(const string &filename, CVSSourceDirectory *dir) {
// original directory later. // original directory later.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool CVSSourceTree:: bool CVSSourceTree::
temp_chdir(const string &path) { temp_chdir(const Filename &path) {
// We have to call this first to guarantee that we have already // We have to call this first to guarantee that we have already
// determined our starting directory. // determined our starting directory.
get_start_fullpath(); get_start_fullpath();
if (chdir(path.c_str()) < 0) { string os_path = path.to_os_specific();
if (chdir(os_path.c_str()) < 0) {
return false; return false;
} }
return true; return true;
@ -264,11 +265,12 @@ temp_chdir(const string &path) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void CVSSourceTree:: void CVSSourceTree::
restore_cwd() { restore_cwd() {
string start_fullpath = get_start_fullpath(); Filename start_fullpath = get_start_fullpath();
string os_path = start_fullpath.to_os_specific();
if (chdir(start_fullpath.c_str()) < 0) { if (chdir(os_path.c_str()) < 0) {
// Hey! We can't get back to the directory we started from! // Hey! We can't get back to the directory we started from!
perror(start_fullpath.c_str()); perror(os_path.c_str());
nout << "Can't continue, aborting.\n"; nout << "Can't continue, aborting.\n";
exit(1); exit(1);
} }
@ -498,21 +500,13 @@ prompt(const string &message) {
// Function: CVSSourceTree::get_actual_fullpath // Function: CVSSourceTree::get_actual_fullpath
// Access: Private, Static // Access: Private, Static
// Description: Determines the actual full path from the root to the // Description: Determines the actual full path from the root to the
// named directory. It does this essentially by cd'ing // named directory.
// to the directory and doing pwd, then cd'ing back.
// Returns the empty string if the directory is invalid
// or cannot be cd'ed into.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
string CVSSourceTree:: Filename CVSSourceTree::
get_actual_fullpath(const string &path) { get_actual_fullpath(const Filename &path) {
if (!temp_chdir(path)) { Filename canon = path;
return string(); canon.make_canonical();
} return canon;
string cwd = ExecutionEnvironment::get_cwd();
restore_cwd();
return cwd;
} }
@ -522,11 +516,11 @@ get_actual_fullpath(const string &path) {
// Description: Returns the full path from the root to the directory // Description: Returns the full path from the root to the directory
// in which the user started the program. // in which the user started the program.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
string CVSSourceTree:: Filename CVSSourceTree::
get_start_fullpath() { get_start_fullpath() {
if (!_got_start_fullpath) { if (!_got_start_fullpath) {
_start_fullpath = ExecutionEnvironment::get_cwd(); Filename cwd = ExecutionEnvironment::get_cwd();
_got_start_fullpath = true; _start_fullpath = cwd.to_os_specific();
} }
return _start_fullpath; return _start_fullpath;
} }

View File

@ -19,10 +19,11 @@
#ifndef CVSSOURCETREE_H #ifndef CVSSOURCETREE_H
#define CVSSOURCETREE_H #define CVSSOURCETREE_H
#include <pandatoolbase.h> #include "pandatoolbase.h"
#include "pvector.h" #include "pvector.h"
#include "pmap.h" #include "pmap.h"
#include "filename.h"
class CVSSourceDirectory; class CVSSourceDirectory;
@ -36,26 +37,26 @@ public:
CVSSourceTree(); CVSSourceTree();
~CVSSourceTree(); ~CVSSourceTree();
void set_root(const string &root_path); void set_root(const Filename &root_path);
bool scan(const string &key_filename); bool scan(const Filename &key_filename);
CVSSourceDirectory *get_root() const; CVSSourceDirectory *get_root() const;
CVSSourceDirectory *find_directory(const string &path); CVSSourceDirectory *find_directory(const Filename &path);
CVSSourceDirectory *find_relpath(const string &relpath); CVSSourceDirectory *find_relpath(const string &relpath);
CVSSourceDirectory *find_dirname(const string &dirname); CVSSourceDirectory *find_dirname(const string &dirname);
CVSSourceDirectory *choose_directory(const string &filename, CVSSourceDirectory *choose_directory(const Filename &filename,
CVSSourceDirectory *suggested_dir, CVSSourceDirectory *suggested_dir,
bool force, bool interactive); bool force, bool interactive);
string get_root_fullpath(); Filename get_root_fullpath();
string get_root_dirname() const; Filename get_root_dirname() const;
static bool temp_chdir(const string &path); static bool temp_chdir(const Filename &path);
static void restore_cwd(); static void restore_cwd();
public: public:
void add_file(const string &filename, CVSSourceDirectory *dir); void add_file(const Filename &filename, CVSSourceDirectory *dir);
private: private:
typedef pvector<CVSSourceDirectory *> Directories; typedef pvector<CVSSourceDirectory *> Directories;
@ -74,20 +75,20 @@ private:
string prompt(const string &message); string prompt(const string &message);
static string get_actual_fullpath(const string &path); static Filename get_actual_fullpath(const Filename &path);
static string get_start_fullpath(); static Filename get_start_fullpath();
private: private:
string _path; Filename _path;
CVSSourceDirectory *_root; CVSSourceDirectory *_root;
typedef pmap<string, Directories> Filenames; typedef pmap<Filename, Directories> Filenames;
Filenames _filenames; Filenames _filenames;
static bool _got_start_fullpath; static bool _got_start_fullpath;
static string _start_fullpath; static Filename _start_fullpath;
bool _got_root_fullpath; bool _got_root_fullpath;
string _root_fullpath; Filename _root_fullpath;
}; };
#endif #endif

View File

@ -161,7 +161,7 @@ read(const Filename &filename) {
MStatus stat = MFileIO::open(os_filename.c_str()); MStatus stat = MFileIO::open(os_filename.c_str());
if (!stat) { if (!stat) {
stat.perror(filename.c_str()); stat.perror(os_filename.c_str());
return false; return false;
} }
return true; return true;
@ -175,8 +175,6 @@ read(const Filename &filename) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool MayaApi:: bool MayaApi::
write(const Filename &filename) { write(const Filename &filename) {
MFileIO::newFile(true);
maya_cat.info() << "Writing " << filename << "\n"; maya_cat.info() << "Writing " << filename << "\n";
string os_filename = filename.to_os_specific(); string os_filename = filename.to_os_specific();
#ifdef WIN32 #ifdef WIN32
@ -191,7 +189,7 @@ write(const Filename &filename) {
MStatus stat = MFileIO::saveAs(os_filename.c_str(), type, true); MStatus stat = MFileIO::saveAs(os_filename.c_str(), type, true);
if (!stat) { if (!stat) {
stat.perror(filename.c_str()); stat.perror(os_filename.c_str());
return false; return false;
} }
return true; return true;

View File

@ -57,6 +57,8 @@ MayaShader(MObject engine) {
_offset.set(0.0, 0.0); _offset.set(0.0, 0.0);
_rotate_uv = 0.0; _rotate_uv = 0.0;
_color_object = (MObject *)NULL;
MFnDependencyNode engine_fn(engine); MFnDependencyNode engine_fn(engine);
_name = engine_fn.name().asChar(); _name = engine_fn.name().asChar();
@ -79,6 +81,18 @@ MayaShader(MObject engine) {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: MayaShader::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
MayaShader::
~MayaShader() {
if (_color_object != (MObject *)NULL) {
delete _color_object;
}
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: MayaShader::compute_texture_matrix // Function: MayaShader::compute_texture_matrix
// Access: Public // Access: Public
@ -126,6 +140,32 @@ output(ostream &out) const {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: MayaShader::reset_maya_texture
// Access: Public
// Description: Changes the texture filename stored in the Maya file
// for this particular shader.
////////////////////////////////////////////////////////////////////
bool MayaShader::
reset_maya_texture(const Filename &texture) {
if (_color_object != (MObject *)NULL) {
_has_texture = set_string_attribute(*_color_object, "fileTextureName",
texture);
_texture = texture;
if (!_has_texture) {
maya_cat.error()
<< "Unable to reset texture filename.\n";
}
return _has_texture;
}
maya_cat.error()
<< "Attempt to reset texture on Maya object that has no color set.\n";
return false;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: MayaShader::read_surface_shader // Function: MayaShader::read_surface_shader
// Access: Public // Access: Public
@ -185,6 +225,8 @@ read_surface_shader(MObject shader) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void MayaShader:: void MayaShader::
read_surface_color(MObject color) { read_surface_color(MObject color) {
_color_object = new MObject(color);
if (color.hasFn(MFn::kFileTexture)) { if (color.hasFn(MFn::kFileTexture)) {
string filename; string filename;
_has_texture = get_string_attribute(color, "fileTextureName", filename); _has_texture = get_string_attribute(color, "fileTextureName", filename);

View File

@ -37,10 +37,12 @@ class MObject;
class MayaShader { class MayaShader {
public: public:
MayaShader(MObject engine); MayaShader(MObject engine);
~MayaShader();
LMatrix3d compute_texture_matrix() const; LMatrix3d compute_texture_matrix() const;
void output(ostream &out) const; void output(ostream &out) const;
bool reset_maya_texture(const Filename &texture);
string _name; string _name;
@ -65,6 +67,8 @@ public:
double _rotate_uv; double _rotate_uv;
private: private:
MObject *_color_object;
bool read_surface_shader(MObject shader); bool read_surface_shader(MObject shader);
void read_surface_color(MObject color); void read_surface_color(MObject color);
}; };

View File

@ -125,9 +125,33 @@ find_shader_for_shading_engine(MObject engine) {
// Record this for the future. // Record this for the future.
_shaders.insert(Shaders::value_type(engine_name, shader)); _shaders.insert(Shaders::value_type(engine_name, shader));
_shaders_in_order.push_back(shader);
return shader; return shader;
} }
////////////////////////////////////////////////////////////////////
// Function: MayaShaders::get_num_shaders
// Access: Public
// Description: Returns the number of unique MayaShaders that have
// been discovered so far.
////////////////////////////////////////////////////////////////////
int MayaShaders::
get_num_shaders() const {
return _shaders_in_order.size();
}
////////////////////////////////////////////////////////////////////
// Function: MayaShaders::get_shader
// Access: Public
// Description: Returns the nth MayaShader that has been discovered
// so far.
////////////////////////////////////////////////////////////////////
MayaShader *MayaShaders::
get_shader(int n) const {
nassertr(n >= 0 && n < (int)_shaders_in_order.size(), NULL);
return _shaders_in_order[n];
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: MayaShaders::clear // Function: MayaShaders::clear
// Access: Public // Access: Public
@ -136,10 +160,11 @@ find_shader_for_shading_engine(MObject engine) {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void MayaShaders:: void MayaShaders::
clear() { clear() {
Shaders::iterator si; ShadersInOrder::iterator si;
for (si = _shaders.begin(); si != _shaders.end(); ++si) { for (si = _shaders_in_order.begin(); si != _shaders_in_order.end(); ++si) {
delete (*si).second; delete (*si);
} }
_shaders.clear(); _shaders.clear();
_shaders_in_order.clear();
} }

View File

@ -22,6 +22,7 @@
#include "pandatoolbase.h" #include "pandatoolbase.h"
#include "pmap.h" #include "pmap.h"
#include "pvector.h"
class MayaShader; class MayaShader;
class MObject; class MObject;
@ -38,11 +39,16 @@ public:
MayaShader *find_shader_for_node(MObject node); MayaShader *find_shader_for_node(MObject node);
MayaShader *find_shader_for_shading_engine(MObject engine); MayaShader *find_shader_for_shading_engine(MObject engine);
int get_num_shaders() const;
MayaShader *get_shader(int n) const;
void clear(); void clear();
private: private:
typedef pmap<string, MayaShader *> Shaders; typedef pmap<string, MayaShader *> Shaders;
Shaders _shaders; Shaders _shaders;
typedef pvector<MayaShader *> ShadersInOrder;
ShadersInOrder _shaders_in_order;
}; };
#endif #endif

View File

@ -27,32 +27,32 @@ template<class ValueType>
bool bool
get_maya_attribute(MObject &node, const string &attribute_name, get_maya_attribute(MObject &node, const string &attribute_name,
ValueType &value) { ValueType &value) {
MStatus status; bool status = false;
MFnDependencyNode node_fn(node, &status);
if (!status) {
maya_cat.error()
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
return false;
}
MObject attr = node_fn.attribute(attribute_name.c_str(), &status); MPlug plug;
if (!status) { if (get_maya_plug(node, attribute_name, plug)) {
maya_cat.error() status = plug.getValue(value);
<< "Object " << node_fn.name() << " does not support attribute " }
<< attribute_name << "\n";
return false; return status;
}
////////////////////////////////////////////////////////////////////
// Function: set_maya_attribute
// Description: A generic function to set an attribute of some
// type on an MObject. This is used to implement
// set_bool_attribute(), etc.
////////////////////////////////////////////////////////////////////
template<class ValueType>
bool
set_maya_attribute(MObject &node, const string &attribute_name,
ValueType &value) {
bool status = false;
MPlug plug;
if (get_maya_plug(node, attribute_name, plug)) {
status = plug.setValue(value);
} }
MFnAttribute attr_fn(attr, &status);
if (!status) {
maya_cat.error()
<< "Attribute " << attribute_name << " on " << node_fn.name()
<< " is a " << attr.apiTypeStr() << ", not an Attribute.\n";
return false;
}
MPlug plug(node, attr);
status = plug.getValue(value);
return status; return status;
} }

View File

@ -27,6 +27,40 @@
#include <maya/MFnNumericData.h> #include <maya/MFnNumericData.h>
#include "post_maya_include.h" #include "post_maya_include.h"
////////////////////////////////////////////////////////////////////
// Function: get_maya_plug
// Description: Gets the named MPlug associated, if any.
////////////////////////////////////////////////////////////////////
bool
get_maya_plug(MObject &node, const string &attribute_name, MPlug &plug) {
MStatus status;
MFnDependencyNode node_fn(node, &status);
if (!status) {
maya_cat.error()
<< "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
return false;
}
MObject attr = node_fn.attribute(attribute_name.c_str(), &status);
if (!status) {
maya_cat.error()
<< "Object " << node_fn.name() << " does not support attribute "
<< attribute_name << "\n";
return false;
}
MFnAttribute attr_fn(attr, &status);
if (!status) {
maya_cat.error()
<< "Attribute " << attribute_name << " on " << node_fn.name()
<< " is a " << attr.apiTypeStr() << ", not an Attribute.\n";
return false;
}
plug = MPlug(node, attr);
return true;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: get_bool_attribute // Function: get_bool_attribute
// Description: Extracts the named boolean attribute from the // Description: Extracts the named boolean attribute from the
@ -170,6 +204,52 @@ get_string_attribute(MObject &node, const string &attribute_name,
return true; return true;
} }
////////////////////////////////////////////////////////////////////
// Function: set_string_attribute
// Description: Sets the named string attribute on the
// MObject.
////////////////////////////////////////////////////////////////////
bool
set_string_attribute(MObject &node, const string &attribute_name,
const string &value) {
MStatus status;
// First, we get the string_object, then we set its string.
MObject string_object;
if (!get_maya_attribute(node, attribute_name, string_object)) {
maya_cat.error()
<< "Attribute " << attribute_name
<< " does not have an string object value.\n";
describe_maya_attribute(node, attribute_name);
return false;
}
MFnStringData data(string_object, &status);
if (!status) {
maya_cat.error()
<< "Attribute " << attribute_name << " is of type "
<< string_object.apiTypeStr() << ", not a StringData.\n";
return false;
}
MString mstring_value(value.data(), value.length());
status = data.set(mstring_value);
if (!status) {
status.perror(attribute_name.c_str());
return false;
}
// And it appears we now need to set the string object back.
if (!set_maya_attribute(node, attribute_name, string_object)) {
maya_cat.error()
<< "Attribute " << attribute_name
<< " suddenly does not have an string object value.\n";
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: describe_maya_attribute // Function: describe_maya_attribute
// Description: Writes some error output about the indicated Maya // Description: Writes some error output about the indicated Maya

View File

@ -35,11 +35,19 @@
class MObject; class MObject;
bool
get_maya_plug(MObject &node, const string &attribute_name, MPlug &plug);
template<class ValueType> template<class ValueType>
bool bool
get_maya_attribute(MObject &node, const string &attribute_name, get_maya_attribute(MObject &node, const string &attribute_name,
ValueType &value); ValueType &value);
template<class ValueType>
bool
set_maya_attribute(MObject &node, const string &attribute_name,
ValueType &value);
bool bool
get_bool_attribute(MObject &node, const string &attribute_name, get_bool_attribute(MObject &node, const string &attribute_name,
bool &value); bool &value);
@ -60,6 +68,10 @@ bool
get_string_attribute(MObject &node, const string &attribute_name, get_string_attribute(MObject &node, const string &attribute_name,
string &value); string &value);
bool
set_string_attribute(MObject &node, const string &attribute_name,
const string &value);
void void
describe_maya_attribute(MObject &node, const string &attribute_name); describe_maya_attribute(MObject &node, const string &attribute_name);

View File

@ -40,3 +40,18 @@
#end bin_target #end bin_target
#begin bin_target
#define USE_MAYA yes
#define TARGET mayacopy
#define LOCAL_LIBS cvscopy maya progbase
#define OTHER_LIBS \
linmath:c panda:m \
express:c pandaexpress:m \
dtoolutil:c dtoolbase:c dconfig:c dtoolconfig:m dtool:m pystub
#define SOURCES \
mayaCopy.cxx mayaCopy.h
#end bin_target

View File

@ -17,10 +17,23 @@
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
#include "mayaCopy.h" #include "mayaCopy.h"
#include "config_maya.h"
#include "cvsSourceDirectory.h" #include "cvsSourceDirectory.h"
#include "mayaShader.h"
#include "dcast.h" #include "dcast.h"
#include "pre_maya_include.h"
#include <maya/MStringArray.h>
#include <maya/MFileIO.h>
#include <maya/MItDag.h>
#include <maya/MFnDagNode.h>
#include <maya/MFnNurbsSurface.h>
#include <maya/MFnMesh.h>
#include <maya/MObject.h>
#include <maya/MDagPath.h>
#include <maya/MIntArray.h>
#include "post_maya_include.h"
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: MayaCopy::Constructor // Function: MayaCopy::Constructor
// Access: Public // Access: Public
@ -50,6 +63,12 @@ MayaCopy() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void MayaCopy:: void MayaCopy::
run() { run() {
_maya = MayaApi::open_api(_program_name);
if (!_maya->is_valid()) {
nout << "Unable to initialize Maya.\n";
exit(1);
}
SourceFiles::iterator fi; SourceFiles::iterator fi;
for (fi = _source_files.begin(); fi != _source_files.end(); ++fi) { for (fi = _source_files.begin(); fi != _source_files.end(); ++fi) {
ExtraData ed; ExtraData ed;
@ -95,17 +114,78 @@ bool MayaCopy::
copy_maya_file(const Filename &source, const Filename &dest, copy_maya_file(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir) { CVSSourceDirectory *dir) {
if (!_maya->read(source)) { if (!_maya->read(source)) {
mayaegg_cat.error() maya_cat.error()
<< "Unable to read " << source << "\n"; << "Unable to read " << source << "\n";
return false; return false;
} }
// Get all the shaders so we can determine the set of textures.
_shaders.clear();
collect_shaders();
int num_shaders = _shaders.get_num_shaders();
for (int i = 0; i < num_shaders; i++) {
MayaShader *shader = _shaders.get_shader(i);
if (shader->_has_texture) {
Filename texture_filename = shader->_texture;
if (!texture_filename.exists()) {
nout << "*** Warning: texture " << texture_filename
<< " does not exist.\n";
} else {
ExtraData ed;
ed._type = FT_texture;
CVSSourceDirectory *texture_dir =
import(texture_filename, &ed, _map_dir);
if (texture_dir == (CVSSourceDirectory *)NULL) {
return false;
}
// Update the texture reference to point to the new texture
// filename, relative to the flt file. Not sure how to do
// this right now.
Filename new_filename = dir->get_rel_to(texture_dir) + "/" +
texture_filename.get_basename();
shader->reset_maya_texture(new_filename);
}
}
}
// Get the set of externally referenced Maya files.
MStringArray refs;
MStatus status = MFileIO::getReferences(refs);
if (!status) {
status.perror("MItDag constructor");
return false;
}
// Now write out the Maya file.
if (!_maya->write(dest)) { if (!_maya->write(dest)) {
mayaegg_cat.error() maya_cat.error()
<< "Cannot write " << dest << "\n"; << "Cannot write " << dest << "\n";
return false; return false;
} }
// Finally, copy in any referenced Maya files. This is untested code.
unsigned int num_refs = refs.length();
if (num_refs != 0) {
maya_cat.warning()
<< "External references are not yet properly supported by mayacopy!\n";
}
for (unsigned int ref_index = 0; ref_index < num_refs; ref_index++) {
Filename filename = refs[ref_index].asChar();
maya_cat.warning()
<< "External ref: " << filename << "\n";
/*
ExtraData ed;
ed._type = FT_maya;
CVSSourceDirectory *dest = import(filename, &ed, _model_dir);
if (dest == (CVSSourceDirectory *)NULL) {
exit(1);
}
*/
}
return true; return true;
} }
@ -124,42 +204,95 @@ copy_texture(const Filename &source, const Filename &dest,
return true; return true;
} }
/*
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: MayaCopy::scan_maya // Function: MayaCopy::collect_shaders
// Access: Private // Access: Private
// Description: Recursively walks through the maya file hierarchy, // Description: Recursively walks through the maya scene graph
// looking for texture references and external maya file // hierarchy, looking for shaders.
// references.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void MayaCopy:: bool MayaCopy::
scan_maya(MayaRecord *record, MayaCopy::Refs &refs, MayaCopy::Textures &textures) { collect_shaders() {
if (record->is_of_type(MayaFace::get_class_type())) { MStatus status;
MayaFace *face;
DCAST_INTO_V(face, record); MItDag dag_iterator(MItDag::kDepthFirst, MFn::kTransform, &status);
if (face->has_texture()) { if (!status) {
textures.insert(face->get_texture()); status.perror("MItDag constructor");
return false;
}
// This while loop walks through the entire Maya hierarchy, one node
// at a time. Maya's MItDag object automatically performs a
// depth-first traversal of its scene graph.
bool all_ok = true;
while (!dag_iterator.isDone()) {
MDagPath dag_path;
status = dag_iterator.getPath(dag_path);
if (!status) {
status.perror("MItDag::getPath");
} else {
if (!collect_shader_for_node(dag_path)) {
all_ok = false;
}
} }
} else if (record->is_of_type(MayaExternalReference::get_class_type())) { dag_iterator.next();
MayaExternalReference *ref;
DCAST_INTO_V(ref, record);
refs.insert(ref);
} }
int i; if (!all_ok) {
int num_subfaces = record->get_num_subfaces(); nout << "Errors encountered in traversal.\n";
for (i = 0; i < num_subfaces; i++) { return false;
scan_maya(record->get_subface(i), refs, textures);
} }
int num_children = record->get_num_children(); return true;
for (i = 0; i < num_children; i++) { }
scan_maya(record->get_child(i), refs, textures);
} ////////////////////////////////////////////////////////////////////
// Function: MayaCopy::collect_shader_for_node
// Access: Private
// Description: Gets the relevant shader on the current node, if it
// has one.
////////////////////////////////////////////////////////////////////
bool MayaCopy::
collect_shader_for_node(const MDagPath &dag_path) {
MStatus status;
MFnDagNode dag_node(dag_path, &status);
if (!status) {
status.perror("MFnDagNode constructor");
return false;
}
if (dag_path.hasFn(MFn::kNurbsSurface)) {
MFnNurbsSurface surface(dag_path, &status);
if (status) {
_shaders.find_shader_for_node(surface.object());
}
} else if (dag_path.hasFn(MFn::kMesh)) {
MFnMesh mesh(dag_path, &status);
if (status) {
// Meshes may have multiple different shaders.
MObjectArray shaders;
MIntArray poly_shader_indices;
status = mesh.getConnectedShaders(dag_path.instanceNumber(),
shaders, poly_shader_indices);
if (status) {
unsigned int num_shaders = shaders.length();
for (unsigned int shader_index = 0;
shader_index < num_shaders;
shader_index++) {
MObject engine = shaders[shader_index];
_shaders.find_shader_for_shading_engine(engine);
}
}
}
} else {
// Ignoring other kinds of node.
}
return true;
} }
*/
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {

View File

@ -20,15 +20,16 @@
#define MAYACOPY_H #define MAYACOPY_H
#include "pandatoolbase.h" #include "pandatoolbase.h"
#include "cvsCopy.h" #include "cvsCopy.h"
#include "mayaApi.h"
#include "mayaShaders.h"
#include "dSearchPath.h" #include "dSearchPath.h"
#include "pointerTo.h" #include "pointerTo.h"
#include "pset.h" #include "pset.h"
class MayaShader; class MayaShader;
class MDagPath;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : MayaCopy // Class : MayaCopy
@ -63,11 +64,11 @@ private:
bool copy_texture(const Filename &source, const Filename &dest, bool copy_texture(const Filename &source, const Filename &dest,
CVSSourceDirectory *dir); CVSSourceDirectory *dir);
bool collect_shaders();
bool collect_shader_for_node(const MDagPath &dag_path);
typedef pset< PT(MayaExternalReference) > Refs; PT(MayaApi) _maya;
typedef pset< PT(MayaTexture) > Textures; MayaShaders _shaders;
void scan_maya(MayaRecord *record, Refs &refs, Textures &textures);
}; };
#endif #endif