15 #include "mayaNodeDesc.h" 16 #include "mayaNodeTree.h" 17 #include "mayaBlendDesc.h" 18 #include "mayaToEggConverter.h" 19 #include "maya_funcs.h" 21 #include "config_mayaegg.h" 23 #include "pre_maya_include.h" 24 #include <maya/MFnBlendShapeDeformer.h> 25 #include <maya/MItDependencyGraph.h> 26 #include <maya/MFnNurbsSurface.h> 27 #include <maya/MFnMesh.h> 28 #include "post_maya_include.h" 34 static const char *transform_connections[] = {
44 static const int num_transform_connections =
sizeof(transform_connections) /
sizeof(
const char *);
57 _dag_path = (MDagPath *)NULL;
61 _joint_type = JT_none;
64 _joint_tagged =
false;
68 _parent->_children.push_back(
this);
79 if (_dag_path != (MDagPath *)NULL) {
94 if (_dag_path == (MDagPath *)NULL) {
95 _dag_path =
new MDagPath(dag_path);
98 MFnDagNode dag_node(dag_path, &status);
100 status.perror(
"MFnDagNode constructor");
102 name = dag_node.name().asChar();
105 if (_dag_path->hasFn(MFn::kJoint) || converter->
force_joint(name)) {
108 _joint_type = JT_joint;
110 _parent->mark_joint_parent();
117 bool transform_connected =
false;
120 MObject node = dag_path.node(&status);
123 i < num_transform_connections && !transform_connected;
125 if (is_connected(node, transform_connections[i])) {
126 transform_connected =
true;
131 if (transform_connected) {
132 _joint_type = JT_joint;
134 _parent->mark_joint_parent();
139 if (dag_path.hasFn(MFn::kNurbsSurface)) {
140 MFnNurbsSurface surface(dag_path, &status);
142 check_blend_shapes(surface,
"create");
144 }
else if (dag_path.hasFn(MFn::kMesh)) {
145 MFnMesh mesh(dag_path, &status);
147 check_blend_shapes(mesh,
"inMesh");
161 return (_dag_path != (MDagPath *)NULL);
173 nassertr(_dag_path != (MDagPath *)NULL, *_dag_path);
186 return _blend_descs.size();
197 nassertr(n >= 0 && n < (
int)_blend_descs.size(), NULL);
198 return _blend_descs[n];
210 return _joint_tagged && (_joint_type == JT_joint || _joint_type == JT_pseudo_joint);
221 return _joint_type == JT_joint_parent;
233 return _joint_tagged;
244 _joint_tagged =
true;
254 tag_joint_recursively() {
255 _joint_tagged =
true;
257 Children::const_iterator ci;
258 for (ci = _children.begin(); ci != _children.end(); ++ci) {
260 child->tag_joint_recursively();
307 Children::const_iterator ci;
308 for (ci = _children.begin(); ci != _children.end(); ++ci) {
310 child->tag_recursively();
321 untag_recursively() {
324 Children::const_iterator ci;
325 for (ci = _children.begin(); ci != _children.end(); ++ci) {
327 child->untag_recursively();
340 if ((_egg_group != (
EggGroup*) NULL)
362 Children::const_iterator ci;
363 for (ci = _children.begin(); ci != _children.end(); ++ci) {
376 mark_joint_parent() {
377 if (_joint_type == JT_none) {
378 _joint_type = JT_joint_parent;
380 _parent->mark_joint_parent();
394 check_pseudo_joints(
bool joint_above) {
395 static PN_uint32 space_count = 0;
397 for (PN_uint32 idx=0; idx<space_count; ++idx) {
400 if (mayaegg_cat.is_spam()) {
401 mayaegg_cat.spam() <<
"cpj:" << space << get_name() <<
" joint_type: " << _joint_type << endl;
403 if (_joint_type == JT_joint_parent && joint_above) {
407 _joint_type = JT_pseudo_joint;
410 if (_joint_type == JT_joint) {
418 if (_joint_type != JT_none) {
420 bool any_joints =
false;
421 Children::const_iterator ci;
422 for (ci = _children.begin(); ci != _children.end(); ++ci) {
424 if (mayaegg_cat.is_spam()) {
427 child->check_pseudo_joints(joint_above);
429 if (child->_joint_type == JT_joint || child->_joint_type == JT_pseudo_joint) {
437 bool all_joints =
true;
438 for (ci = _children.begin(); ci != _children.end(); ++ci) {
443 status.perror(
"MFnDagNode constructor");
445 string type_name = dag_node.typeName().asChar();
446 if (child->_joint_type == JT_joint_parent) {
447 child->_joint_type = JT_pseudo_joint;
448 }
else if (child->_joint_type == JT_none) {
449 if (mayaegg_cat.is_spam()) {
450 mayaegg_cat.spam() <<
"cpj: " << space <<
"jt_none for " << child->get_name() << endl;
452 if (type_name.find(
"transform") == string::npos) {
453 if (mayaegg_cat.is_spam()) {
454 mayaegg_cat.spam() <<
"cpj: " << space <<
"all_joints false for " << get_name() << endl;
463 if (_joint_type == JT_joint_parent) {
464 if (!get_name().empty()) {
465 _joint_type = JT_pseudo_joint;
471 if (mayaegg_cat.is_spam()) {
489 check_blend_shapes(
const MFnDagNode &node,
const string &attrib_name) {
492 MObject attr = node.attribute(attrib_name.c_str());
494 MPlug history(node.object(), attr);
495 MItDependencyGraph it(history, MFn::kDependencyNode,
496 MItDependencyGraph::kUpstream,
497 MItDependencyGraph::kDepthFirst,
498 MItDependencyGraph::kNodeLevel);
500 while (!it.isDone()) {
501 MObject c_node = it.thisNode();
503 if (c_node.hasFn(MFn::kBlendShape)) {
504 MFnBlendShapeDeformer blends(c_node, &status);
506 status.perror(
"MFnBlendShapeDeformer constructor");
512 MPlug plug = blends.findPlug(
"pb");
513 bool is_parallel_blender;
514 status = plug.getValue(is_parallel_blender);
516 status.perror(
"Could not get value of pb plug.");
517 is_parallel_blender =
false;
520 if (is_parallel_blender ||
525 MObjectArray base_objects;
526 status = blends.getBaseObjects(base_objects);
528 status.perror(
"MFnBlendShapeDeformer::getBaseObjects");
530 for (
unsigned int oi = 0; oi < base_objects.length(); oi++) {
531 MObject base_object = base_objects[oi];
533 MIntArray index_list;
534 status = blends.weightIndexList(index_list);
536 status.perror(
"MFnBlendShapeDeformer::weightIndexList");
538 for (
unsigned int i = 0; i < index_list.length(); i++) {
539 int wi = index_list[i];
542 _blend_descs.push_back(blend_desc);
569 Children::iterator ci;
570 for (ci = _children.begin(); ci != _children.end(); ++ci) {
576 if (_dag_path != (MDagPath *)NULL &&
577 _dag_path->hasFn(MFn::kLodGroup)) {
581 MFnDagNode dag_node(*_dag_path, &status);
583 status.perror(
"Couldn't get node from dag path for lodGroup");
587 MPlug plug = dag_node.findPlug(
"threshold", &status);
589 status.perror(
"Couldn't get threshold attributes on lodGroup");
595 unsigned int num_elements = plug.numElements();
596 unsigned int num_children = _children.size();
597 if (num_elements + 1 != num_children) {
598 mayaegg_cat.warning()
599 <<
"Node " << get_name() <<
" has " << num_elements
600 <<
" LOD entries, but " << num_children <<
" children.\n";
608 double switch_out = 0.0;
610 while (i < num_elements && i < num_children) {
611 MPlug element = plug.elementByLogicalIndex(i);
615 status = element.getValue(switch_in);
617 status.perror(
"Couldn't get double value from threshold.");
621 child->_is_lod =
true;
622 child->_switch_in = switch_in;
623 child->_switch_out = switch_out;
625 switch_out = switch_in;
629 while (i < num_children) {
634 child->_is_lod =
true;
635 child->_switch_in = switch_out * 4.0;
636 child->_switch_out = switch_out;
A handle to a Maya blend shape description.
void from_dag_path(const MDagPath &dag_path, MayaToEggConverter *converter)
Indicates an association between the MayaNodeDesc and some Maya instance.
bool has_object_type(string object_type) const
Returns true if this node or any of its parent has_object_type of object_type.
bool ignore_slider(const string &name) const
Returns true if the indicated name is on the list of sliders to ignore, false otherwise.
Describes a complete tree of maya nodes for conversion.
bool has_object_type(const string &object_type) const
Returns true if the indicated object type has been added to the group, or false otherwise.
bool has_dag_path() const
Returns true if a Maya dag path has been associated with this node, false otherwise.
MayaBlendDesc * get_blend_desc(int n) const
Returns the nth MayaBlendDesc object that affects the geometry in this node.
bool is_joint_parent() const
Returns true if the node is the parent or ancestor of a joint.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
A base class for all things which can have a name.
MayaBlendDesc * add_blend_desc(MayaBlendDesc *blend_desc)
Adds the indicated MayaBlendDesc object to the list of blends collected so far.
Describes a single instance of a node in the Maya scene graph, relating it to the corresponding egg s...
bool is_joint() const
Returns true if the node should be treated as a joint by the converter.
This corresponds to an <Xfm$Anim_S$> entry, which is a collection of up to nine <S$Anim> entries that...
bool is_joint_tagged() const
Returns true if the node has been joint_tagged to be converted, false otherwise.
const MDagPath & get_dag_path() const
Returns the dag path associated with this node.
bool is_tagged() const
Returns true if the node has been tagged to be converted, false otherwise.
bool force_joint(const string &name) const
Returns true if the indicated name is on the list of DAG nodes to treat as a joint, false otherwise.
This class supervises the construction of an EggData structure from a single Maya file...
void report_ignored_slider(const string &name)
Outputs a message to the user reporting that a slider was ignored.
TypeHandle is the identifier used to differentiate C++ class types.
int get_num_blend_descs() const
Returns the number of unique MayaBlendDesc objects (and hence the number of morph sliders) that affec...