23 #include <maya/MFnBlendShapeDeformer.h> 24 #include <maya/MItDependencyGraph.h> 25 #include <maya/MFnNurbsSurface.h> 26 #include <maya/MFnMesh.h> 34 static const char *transform_connections[] = {
44 static const int num_transform_connections =
sizeof(transform_connections) /
sizeof(
const char *);
59 _joint_type = JT_none;
62 _joint_tagged =
false;
65 if (_parent !=
nullptr) {
66 _parent->_children.push_back(
this);
75 if (_dag_path !=
nullptr) {
87 if (_dag_path ==
nullptr) {
88 _dag_path =
new MDagPath(dag_path);
91 MFnDagNode dag_node(dag_path, &status);
93 status.perror(
"MFnDagNode constructor");
95 name = dag_node.name().asChar();
98 if (_dag_path->hasFn(MFn::kJoint) || converter->
force_joint(name)) {
101 _joint_type = JT_joint;
102 if (_parent !=
nullptr) {
103 _parent->mark_joint_parent();
109 bool transform_connected =
false;
112 MObject node = dag_path.node(&status);
115 i < num_transform_connections && !transform_connected;
118 transform_connected =
true;
123 if (transform_connected) {
124 _joint_type = JT_joint;
125 if (_parent !=
nullptr) {
126 _parent->mark_joint_parent();
131 if (dag_path.hasFn(MFn::kNurbsSurface)) {
132 MFnNurbsSurface surface(dag_path, &status);
134 check_blend_shapes(surface,
"create");
136 }
else if (dag_path.hasFn(MFn::kMesh)) {
137 MFnMesh mesh(dag_path, &status);
139 check_blend_shapes(mesh,
"inMesh");
151 return (_dag_path !=
nullptr);
160 nassertr(_dag_path !=
nullptr, *_dag_path);
170 return _blend_descs.size();
179 nassertr(n >= 0 && n < (
int)_blend_descs.size(),
nullptr);
180 return _blend_descs[n];
189 return _joint_tagged && (_joint_type == JT_joint || _joint_type == JT_pseudo_joint);
197 return _joint_type == JT_joint_parent;
207 return _joint_tagged;
215 _joint_tagged =
true;
222 tag_joint_recursively() {
223 _joint_tagged =
true;
225 Children::const_iterator ci;
226 for (ci = _children.begin(); ci != _children.end(); ++ci) {
228 child->tag_joint_recursively();
263 Children::const_iterator ci;
264 for (ci = _children.begin(); ci != _children.end(); ++ci) {
266 child->tag_recursively();
274 untag_recursively() {
277 Children::const_iterator ci;
278 for (ci = _children.begin(); ci != _children.end(); ++ci) {
280 child->untag_recursively();
291 if ((_egg_group !=
nullptr)
295 if (_parent !=
nullptr) {
306 _egg_group =
nullptr;
307 _egg_table =
nullptr;
310 Children::const_iterator ci;
311 for (ci = _children.begin(); ci != _children.end(); ++ci) {
322 mark_joint_parent() {
323 if (_joint_type == JT_none) {
324 _joint_type = JT_joint_parent;
325 if (_parent !=
nullptr) {
326 _parent->mark_joint_parent();
337 check_pseudo_joints(
bool joint_above) {
338 static uint32_t space_count = 0;
340 for (uint32_t idx=0; idx<space_count; ++idx) {
343 if (mayaegg_cat.is_spam()) {
344 mayaegg_cat.spam() <<
"cpj:" << space << get_name() <<
" joint_type: " << _joint_type << std::endl;
346 if (_joint_type == JT_joint_parent && joint_above) {
349 _joint_type = JT_pseudo_joint;
352 if (_joint_type == JT_joint) {
360 if (_joint_type != JT_none) {
362 bool any_joints =
false;
363 Children::const_iterator ci;
364 for (ci = _children.begin(); ci != _children.end(); ++ci) {
366 if (mayaegg_cat.is_spam()) {
369 child->check_pseudo_joints(joint_above);
371 if (child->_joint_type == JT_joint || child->_joint_type == JT_pseudo_joint) {
379 bool all_joints =
true;
380 for (ci = _children.begin(); ci != _children.end(); ++ci) {
385 status.perror(
"MFnDagNode constructor");
387 string type_name = dag_node.typeName().asChar();
388 if (child->_joint_type == JT_joint_parent) {
389 child->_joint_type = JT_pseudo_joint;
390 }
else if (child->_joint_type == JT_none) {
391 if (mayaegg_cat.is_spam()) {
392 mayaegg_cat.spam() <<
"cpj: " << space <<
"jt_none for " << child->get_name() << std::endl;
394 if (type_name.find(
"transform") == string::npos) {
395 if (mayaegg_cat.is_spam()) {
396 mayaegg_cat.spam() <<
"cpj: " << space <<
"all_joints false for " << get_name() << std::endl;
405 if (_joint_type == JT_joint_parent) {
406 if (!get_name().empty()) {
407 _joint_type = JT_pseudo_joint;
413 if (mayaegg_cat.is_spam()) {
428 check_blend_shapes(
const MFnDagNode &node,
const string &attrib_name) {
431 MObject attr = node.attribute(attrib_name.c_str());
433 MPlug history(node.object(), attr);
434 MItDependencyGraph it(history, MFn::kDependencyNode,
435 MItDependencyGraph::kUpstream,
436 MItDependencyGraph::kDepthFirst,
437 MItDependencyGraph::kNodeLevel);
439 while (!it.isDone()) {
440 MObject c_node = it.thisNode();
442 if (c_node.hasFn(MFn::kBlendShape)) {
443 MFnBlendShapeDeformer blends(c_node, &status);
445 status.perror(
"MFnBlendShapeDeformer constructor");
451 MPlug plug = blends.findPlug(
"pb");
452 bool is_parallel_blender;
453 status = plug.getValue(is_parallel_blender);
455 status.perror(
"Could not get value of pb plug.");
456 is_parallel_blender =
false;
459 if (is_parallel_blender ||
464 MObjectArray base_objects;
465 status = blends.getBaseObjects(base_objects);
467 status.perror(
"MFnBlendShapeDeformer::getBaseObjects");
469 for (
unsigned int oi = 0; oi < base_objects.length(); oi++) {
470 MObject base_object = base_objects[oi];
472 MIntArray index_list;
473 status = blends.weightIndexList(index_list);
475 status.perror(
"MFnBlendShapeDeformer::weightIndexList");
477 for (
unsigned int i = 0; i < index_list.length(); i++) {
478 int wi = index_list[i];
481 _blend_descs.push_back(blend_desc);
504 Children::iterator ci;
505 for (ci = _children.begin(); ci != _children.end(); ++ci) {
511 if (_dag_path !=
nullptr &&
512 _dag_path->hasFn(MFn::kLodGroup)) {
515 MFnDagNode dag_node(*_dag_path, &status);
517 status.perror(
"Couldn't get node from dag path for lodGroup");
521 MPlug plug = dag_node.findPlug(
"threshold", &status);
523 status.perror(
"Couldn't get threshold attributes on lodGroup");
529 unsigned int num_elements = plug.numElements();
530 unsigned int num_children = _children.size();
531 if (num_elements + 1 != num_children) {
532 mayaegg_cat.warning()
533 <<
"Node " << get_name() <<
" has " << num_elements
534 <<
" LOD entries, but " << num_children <<
" children.\n";
541 double switch_out = 0.0;
543 while (i < num_elements && i < num_children) {
544 MPlug element = plug.elementByLogicalIndex(i);
548 status = element.getValue(switch_in);
550 status.perror(
"Couldn't get double value from threshold.");
554 child->_is_lod =
true;
555 child->_switch_in = switch_in;
556 child->_switch_out = switch_out;
558 switch_out = switch_in;
562 while (i < num_children) {
567 child->_is_lod =
true;
568 child->_switch_in = switch_out * 4.0;
569 child->_switch_out = switch_out;
A handle to a Maya blend shape description.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void from_dag_path(const MDagPath &dag_path, MayaToEggConverter *converter)
Indicates an association between the MayaNodeDesc and some Maya instance.
bool ignore_slider(const std::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 force_joint(const std::string &name) const
Returns true if the indicated name is on the list of DAG nodes to treat as a joint,...
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Describes a single instance of a node in the Maya scene graph, relating it to the corresponding egg s...
bool is_connected(MObject &node, const string &attribute_name)
Returns true if the named connection exists on the node and is connected to anything,...
void report_ignored_slider(const std::string &name)
Outputs a message to the user reporting that a slider was ignored.
bool is_joint() const
Returns true if the node should be treated as a joint by the converter.
bool has_object_type(const std::string &object_type) const
Returns true if the indicated object type has been added to the group, or false otherwise.
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.
This class supervises the construction of an EggData structure from a single Maya file,...
bool has_object_type(std::string object_type) const
Returns true if this node or any of its parent has_object_type of object_type.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.