diff --git a/pandatool/src/mayaegg/mayaNodeDesc.cxx b/pandatool/src/mayaegg/mayaNodeDesc.cxx index 4205c7594d..50dabc013a 100755 --- a/pandatool/src/mayaegg/mayaNodeDesc.cxx +++ b/pandatool/src/mayaegg/mayaNodeDesc.cxx @@ -20,6 +20,7 @@ #include "mayaNodeTree.h" #include "mayaBlendDesc.h" #include "maya_funcs.h" +#include "config_mayaegg.h" #include "pre_maya_include.h" #include @@ -375,25 +376,31 @@ check_blend_shapes(const MFnDagNode &node, const string &attrib_name) { MFnBlendShapeDeformer blends(c_node, &status); if (!status) { status.perror("MFnBlendShapeDeformer constructor"); - } else { - MObjectArray base_objects; - status = blends.getBaseObjects(base_objects); - if (!status) { - status.perror("MFnBlendShapeDeformer::getBaseObjects"); - } else { - for (unsigned int oi = 0; oi < base_objects.length(); oi++) { - MObject base_object = base_objects[oi]; - MIntArray index_list; - status = blends.weightIndexList(index_list); - if (!status) { - status.perror("MFnBlendShapeDeformer::weightIndexList"); - } else { - for (unsigned int i = 0; i < index_list.length(); i++) { - int wi = index_list[i]; - PT(MayaBlendDesc) blend_desc = new MayaBlendDesc(blends, wi); - blend_desc = _tree->add_blend_desc(blend_desc); - _blend_descs.push_back(blend_desc); + } else { + if (_tree->ignore_slider(blends.name().asChar())) { + _tree->report_ignored_slider(blends.name().asChar()); + + } else { + MObjectArray base_objects; + status = blends.getBaseObjects(base_objects); + if (!status) { + status.perror("MFnBlendShapeDeformer::getBaseObjects"); + } else { + for (unsigned int oi = 0; oi < base_objects.length(); oi++) { + MObject base_object = base_objects[oi]; + + MIntArray index_list; + status = blends.weightIndexList(index_list); + if (!status) { + status.perror("MFnBlendShapeDeformer::weightIndexList"); + } else { + for (unsigned int i = 0; i < index_list.length(); i++) { + int wi = index_list[i]; + PT(MayaBlendDesc) blend_desc = new MayaBlendDesc(blends, wi); + blend_desc = _tree->add_blend_desc(blend_desc); + _blend_descs.push_back(blend_desc); + } } } } diff --git a/pandatool/src/mayaegg/mayaNodeTree.cxx b/pandatool/src/mayaegg/mayaNodeTree.cxx index 6335b4c6fa..1ebfe90c6d 100755 --- a/pandatool/src/mayaegg/mayaNodeTree.cxx +++ b/pandatool/src/mayaegg/mayaNodeTree.cxx @@ -19,6 +19,7 @@ #include "mayaNodeTree.h" #include "mayaBlendDesc.h" #include "mayaEggGroupUserData.h" +#include "mayaToEggConverter.h" #include "config_mayaegg.h" #include "maya_funcs.h" #include "eggGroup.h" @@ -41,7 +42,9 @@ // Description: //////////////////////////////////////////////////////////////////// MayaNodeTree:: -MayaNodeTree() { +MayaNodeTree(MayaToEggConverter *converter) : + _converter(converter) +{ _root = new MayaNodeDesc(this); _fps = 0.0; _egg_data = (EggData *)NULL; @@ -461,6 +464,31 @@ get_egg_slider(MayaBlendDesc *blend_desc) { return blend_desc->_anim; } +//////////////////////////////////////////////////////////////////// +// Function: MayaNodeTree::ignore_slider +// Access: Public +// Description: Returns true if the indicated name is on the list of +// sliders to ignore, false otherwise. +//////////////////////////////////////////////////////////////////// +bool MayaNodeTree:: +ignore_slider(const string &name) const { + return _converter->ignore_slider(name); +} + +//////////////////////////////////////////////////////////////////// +// Function: MayaNodeTree::report_ignored_slider +// Access: Public +// Description: Outputs a message to the user reporting that a slider +// was ignored. Each slider is only reported once. +//////////////////////////////////////////////////////////////////// +void MayaNodeTree:: +report_ignored_slider(const string &name) { + if (_ignored_slider_names.insert(name).second) { + mayaegg_cat.info() + << "Ignoring slider " << name << "\n"; + } +} + //////////////////////////////////////////////////////////////////// // Function: MayaNodeTree::add_blend_desc // Access: Public diff --git a/pandatool/src/mayaegg/mayaNodeTree.h b/pandatool/src/mayaegg/mayaNodeTree.h index 73f31c536b..d07e541866 100755 --- a/pandatool/src/mayaegg/mayaNodeTree.h +++ b/pandatool/src/mayaegg/mayaNodeTree.h @@ -26,7 +26,9 @@ #include "globPattern.h" #include "indirectCompareNames.h" #include "ordered_vector.h" +#include "pset.h" +class MayaToEggConverter; class EggData; class EggGroupNode; class EggTable; @@ -40,7 +42,7 @@ class EggSAnimData; //////////////////////////////////////////////////////////////////// class MayaNodeTree { public: - MayaNodeTree(); + MayaNodeTree(MayaToEggConverter *converter); MayaNodeDesc *build_node(const MDagPath &dag_path); bool build_hierarchy(); @@ -59,6 +61,9 @@ public: EggXfmSAnim *get_egg_anim(MayaNodeDesc *node_desc); EggSAnimData *get_egg_slider(MayaBlendDesc *blend_desc); + bool ignore_slider(const string &name) const; + void report_ignored_slider(const string &name); + MayaBlendDesc *add_blend_desc(MayaBlendDesc *blend_desc); int get_num_blend_descs() const; MayaBlendDesc *get_blend_desc(int n) const; @@ -72,6 +77,8 @@ public: private: MayaNodeDesc *r_build_node(const string &path); + MayaToEggConverter *_converter; + EggData *_egg_data; EggGroupNode *_egg_root; EggGroupNode *_skeleton_node; @@ -85,6 +92,9 @@ private: typedef ov_set > BlendDescs; BlendDescs _blend_descs; + + typedef pset Strings; + Strings _ignored_slider_names; }; #endif diff --git a/pandatool/src/mayaegg/mayaToEggConverter.cxx b/pandatool/src/mayaegg/mayaToEggConverter.cxx index f125d6334b..3417b6a059 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.cxx +++ b/pandatool/src/mayaegg/mayaToEggConverter.cxx @@ -85,12 +85,25 @@ //////////////////////////////////////////////////////////////////// MayaToEggConverter:: MayaToEggConverter(const string &program_name) : - _program_name(program_name) + _program_name(program_name), + _tree(this) { // Make sure the library is properly initialized. init_libmayaegg(); _from_selection = false; + + // By default, we ignore any sliders whose name begins with + // "parallelBlender". This is because sliders of this name are + // created automatically by the parallel blend system, and while + // they do not directly control the geometry, they are often + // inadvertently linked to the sliders that do (so that, for + // instance, dialing them down to zero will also dial down the + // effect of the true sliders to zero). We don't want to monkey + // with them. The user can change this list with the -ignore-slider + // command-line option to maya2egg. + _ignore_sliders.push_back(GlobPattern("parallelBlender*")); + _polygon_output = false; _polygon_tolerance = 0.01; _respect_maya_double_sided = maya_default_double_sided; @@ -105,8 +118,11 @@ MayaToEggConverter(const string &program_name) : //////////////////////////////////////////////////////////////////// MayaToEggConverter:: MayaToEggConverter(const MayaToEggConverter ©) : + _program_name(copy._program_name), _from_selection(copy._from_selection), _subsets(copy._subsets), + _ignore_sliders(copy._ignore_sliders), + _tree(this), _maya(copy._maya), _polygon_output(copy._polygon_output), _polygon_tolerance(copy._polygon_tolerance), @@ -234,6 +250,51 @@ add_subset(const GlobPattern &glob) { _subsets.push_back(glob); } +//////////////////////////////////////////////////////////////////// +// Function: MayaToEggConverter::clear_ignore_sliders +// Access: Public +// Description: Empties the list of ignore_sliders added via +// add_ignore_slider(). No sliders will be ignored. +//////////////////////////////////////////////////////////////////// +void MayaToEggConverter:: +clear_ignore_sliders() { + _ignore_sliders.clear(); +} + +//////////////////////////////////////////////////////////////////// +// Function: MayaToEggConverter::add_ignore_slider +// Access: Public +// Description: Adds a name pattern to the list of ignore_sliders. +// Any slider (blend shape deformer) that matches a name +// on the list will not be converted or otherwise +// molested by the converter. This is occasionally +// necessary to filter out automatically-created sliders +// that are not intended to be used directly, but +// instead have an indirect effect on other sliders. +//////////////////////////////////////////////////////////////////// +void MayaToEggConverter:: +add_ignore_slider(const GlobPattern &glob) { + _ignore_sliders.push_back(glob); +} + +//////////////////////////////////////////////////////////////////// +// Function: MayaToEggConverter::ignore_slider +// Access: Public +// Description: Returns true if the indicated name is on the list of +// sliders to ignore, false otherwise. +//////////////////////////////////////////////////////////////////// +bool MayaToEggConverter:: +ignore_slider(const string &name) const { + Globs::const_iterator gi; + for (gi = _ignore_sliders.begin(); gi != _ignore_sliders.end(); ++gi) { + if ((*gi).matches(name)) { + return true; + } + } + + return false; +} + //////////////////////////////////////////////////////////////////// // Function: MayaToEggConverter::set_from_selection // Access: Public @@ -325,11 +386,11 @@ convert_maya() { all_ok = _tree.tag_selected(); } else if (!_subsets.empty()) { - Subsets::const_iterator si; - for (si = _subsets.begin(); si != _subsets.end(); ++si) { - if (!_tree.tag_named(*si)) { + Globs::const_iterator gi; + for (gi = _subsets.begin(); gi != _subsets.end(); ++gi) { + if (!_tree.tag_named(*gi)) { mayaegg_cat.info() - << "No node matching " << *si << " found.\n"; + << "No node matching " << *gi << " found.\n"; } } diff --git a/pandatool/src/mayaegg/mayaToEggConverter.h b/pandatool/src/mayaegg/mayaToEggConverter.h index 27473db11e..0df4b6ae2c 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.h +++ b/pandatool/src/mayaegg/mayaToEggConverter.h @@ -79,6 +79,11 @@ public: void clear_subsets(); void add_subset(const GlobPattern &glob); + + void clear_ignore_sliders(); + void add_ignore_slider(const GlobPattern &glob); + bool ignore_slider(const string &name) const; + void set_from_selection(bool from_selection); bool convert_maya(); @@ -136,8 +141,9 @@ private: string _program_name; bool _from_selection; - typedef pvector Subsets; - Subsets _subsets; + typedef pvector Globs; + Globs _subsets; + Globs _ignore_sliders; MayaNodeTree _tree; diff --git a/pandatool/src/mayaprogs/mayaToEgg.cxx b/pandatool/src/mayaprogs/mayaToEgg.cxx index 350b6e1b60..c5c1d0ae2f 100644 --- a/pandatool/src/mayaprogs/mayaToEgg.cxx +++ b/pandatool/src/mayaprogs/mayaToEgg.cxx @@ -94,6 +94,19 @@ MayaToEgg() : "converted.", &MayaToEgg::dispatch_vector_string, NULL, &_subsets); + add_option + ("ignore-slider", "name", 0, + "Specifies the name of a slider (blend shape deformer) that maya2egg " + "should not process. The slider will not be adjusted and it will not " + "become a part of the animation. Since maya2egg will normally reset " + "all slider values to 0 before converting an animated character, this " + "option may be necessary in order to tell maya2egg to ignore sliders " + "for which doing this may cause an undesired side effect. This " + "parameter may including globbing characters, and it may be repeated " + "as needed. If the parameter does not appear at all, the default is " + "to ignore sliders named 'parallelBlender*'.", + &MayaToEgg::dispatch_vector_string, NULL, &_ignore_sliders); + add_option ("v", "", 0, "Increase verbosity. More v's means more verbose.", @@ -151,8 +164,18 @@ run() { converter._transform_type = _transform_type; vector_string::const_iterator si; - for (si = _subsets.begin(); si != _subsets.end(); ++si) { - converter.add_subset(GlobPattern(*si)); + if (!_subsets.empty()) { + converter.clear_subsets(); + for (si = _subsets.begin(); si != _subsets.end(); ++si) { + converter.add_subset(GlobPattern(*si)); + } + } + + if (!_ignore_sliders.empty()) { + converter.clear_ignore_sliders(); + for (si = _ignore_sliders.begin(); si != _ignore_sliders.end(); ++si) { + converter.add_ignore_slider(GlobPattern(*si)); + } } // Copy in the path and animation parameters. diff --git a/pandatool/src/mayaprogs/mayaToEgg.h b/pandatool/src/mayaprogs/mayaToEgg.h index 067a41a1db..3eccab52a0 100644 --- a/pandatool/src/mayaprogs/mayaToEgg.h +++ b/pandatool/src/mayaprogs/mayaToEgg.h @@ -43,6 +43,7 @@ protected: bool _suppress_vertex_color; MayaToEggConverter::TransformType _transform_type; vector_string _subsets; + vector_string _ignore_sliders; }; #endif