Panda3D
|
00001 // Filename: maya_funcs.cxx 00002 // Created by: drose (16Feb00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "maya_funcs.h" 00016 00017 #include "pre_maya_include.h" 00018 #include <maya/MObject.h> 00019 #include <maya/MAngle.h> 00020 #include <maya/MFnDependencyNode.h> 00021 #include <maya/MStatus.h> 00022 #include <maya/MFnStringData.h> 00023 #include <maya/MFnNumericData.h> 00024 #include <maya/MPlugArray.h> 00025 #include <maya/MPlug.h> 00026 #include <maya/MFnAttribute.h> 00027 #include <maya/MFnTypedAttribute.h> 00028 #include <maya/MFnNumericAttribute.h> 00029 #include <maya/MFnEnumAttribute.h> 00030 #include <maya/MFnCompoundAttribute.h> 00031 #include <maya/MFnMatrixData.h> 00032 #include <maya/MMatrix.h> 00033 #include "post_maya_include.h" 00034 00035 //////////////////////////////////////////////////////////////////// 00036 // Function: get_maya_plug 00037 // Description: Gets the named MPlug associated, if any. 00038 //////////////////////////////////////////////////////////////////// 00039 bool 00040 get_maya_plug(MObject &node, const string &attribute_name, MPlug &plug) { 00041 MStatus status; 00042 MFnDependencyNode node_fn(node, &status); 00043 if (!status) { 00044 maya_cat.error() 00045 << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n"; 00046 return false; 00047 } 00048 00049 MObject attr = node_fn.attribute(attribute_name.c_str(), &status); 00050 if (!status) { 00051 return false; 00052 } 00053 00054 MFnAttribute attr_fn(attr, &status); 00055 if (!status) { 00056 maya_cat.error() 00057 << "Attribute " << attribute_name << " on " << node_fn.name().asChar() 00058 << " is a " << attr.apiTypeStr() << ", not an Attribute.\n"; 00059 return false; 00060 } 00061 00062 plug = MPlug(node, attr); 00063 return true; 00064 } 00065 00066 //////////////////////////////////////////////////////////////////// 00067 // Function: is_connected 00068 // Description: Returns true if the named connection exists on the 00069 // node and is connected to anything, false otherwise. 00070 //////////////////////////////////////////////////////////////////// 00071 bool 00072 is_connected(MObject &node, const string &attribute_name) { 00073 MPlug plug; 00074 if (!get_maya_plug(node, attribute_name, plug)) { 00075 return false; 00076 } 00077 00078 return plug.isConnected(); 00079 } 00080 00081 //////////////////////////////////////////////////////////////////// 00082 // Function: has_attribute 00083 // Description: Returns true if the node has the indicated attribute, 00084 // false otherwise. 00085 //////////////////////////////////////////////////////////////////// 00086 bool 00087 has_attribute(MObject &node, const string &attribute_name) { 00088 MStatus status; 00089 MFnDependencyNode node_fn(node, &status); 00090 if (!status) { 00091 maya_cat.error() 00092 << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n"; 00093 return false; 00094 } 00095 00096 node_fn.attribute(attribute_name.c_str(), &status); 00097 if (!status) { 00098 // No such attribute. 00099 return false; 00100 } 00101 return true; 00102 } 00103 00104 //////////////////////////////////////////////////////////////////// 00105 // Function: remove_attribute 00106 // Description: Removes the named attribute from the indicated Maya 00107 // node. Returns true if successful, false otherwise. 00108 //////////////////////////////////////////////////////////////////// 00109 bool 00110 remove_attribute(MObject &node, const string &attribute_name) { 00111 MStatus status; 00112 MFnDependencyNode node_fn(node, &status); 00113 if (!status) { 00114 maya_cat.error() 00115 << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n"; 00116 return false; 00117 } 00118 00119 MObject attr = node_fn.attribute(attribute_name.c_str(), &status); 00120 if (!status) { 00121 return false; 00122 } 00123 00124 { 00125 // Just to prove the the attr is, in fact, an Attribute. 00126 // According to the Maya docs, we shouldn't leave the MFnAttribute 00127 // object around while we remove the attribute, though. 00128 MFnAttribute attr_fn(attr, &status); 00129 if (!status) { 00130 maya_cat.error() 00131 << "Attribute " << attribute_name << " on " << node_fn.name().asChar() 00132 << " is a " << attr.apiTypeStr() << ", not an Attribute.\n"; 00133 return false; 00134 } 00135 } 00136 00137 MFnDependencyNode::MAttrClass type = node_fn.attributeClass(attr, &status); 00138 if (!status) { 00139 maya_cat.error() 00140 << "Couldn't get class of attribute " << attribute_name << " on " 00141 << node_fn.name().asChar() << ".\n"; 00142 return false; 00143 } 00144 00145 status = node_fn.removeAttribute(attr, type); 00146 if (!status) { 00147 maya_cat.error() 00148 << "Couldn't remove attribute " << attribute_name << " from " 00149 << node_fn.name().asChar() << ".\n"; 00150 return false; 00151 } 00152 00153 return true; 00154 } 00155 00156 //////////////////////////////////////////////////////////////////// 00157 // Function: get_bool_attribute 00158 // Description: Extracts the named boolean attribute from the 00159 // MObject. 00160 //////////////////////////////////////////////////////////////////// 00161 bool 00162 get_bool_attribute(MObject &node, const string &attribute_name, 00163 bool &value) { 00164 if (!has_attribute(node, attribute_name)) { 00165 // For bool attributes only, we assume if the attribute is absent 00166 // it's the same thing as being false. 00167 return false; 00168 } 00169 00170 if (!get_maya_attribute(node, attribute_name, value)) { 00171 maya_cat.warning() 00172 << "Attribute " << attribute_name 00173 << " does not have a bool value.\n"; 00174 describe_maya_attribute(node, attribute_name); 00175 return false; 00176 } 00177 return true; 00178 } 00179 00180 //////////////////////////////////////////////////////////////////// 00181 // Function: get_bool_attribute 00182 // Description: Extracts the named angle in degrees from the 00183 // MObject. 00184 //////////////////////////////////////////////////////////////////// 00185 bool 00186 get_angle_attribute(MObject &node, const string &attribute_name, 00187 double &value) { 00188 MAngle maya_value; 00189 if (!get_maya_attribute(node, attribute_name, maya_value)) { 00190 maya_cat.warning() 00191 << "Attribute " << attribute_name 00192 << " does not have an angle value.\n"; 00193 describe_maya_attribute(node, attribute_name); 00194 return false; 00195 } 00196 value = maya_value.asDegrees(); 00197 return true; 00198 } 00199 00200 //////////////////////////////////////////////////////////////////// 00201 // Function: get_vec2_attribute 00202 // Description: Extracts the named two-component vector from the 00203 // MObject. 00204 //////////////////////////////////////////////////////////////////// 00205 bool 00206 get_vec2_attribute(MObject &node, const string &attribute_name, 00207 LVecBase2 &value) { 00208 MStatus status; 00209 00210 MObject vec2_object; 00211 if (!get_maya_attribute(node, attribute_name, vec2_object)) { 00212 maya_cat.warning() 00213 << "Attribute " << attribute_name 00214 << " does not have a vec2 object value.\n"; 00215 describe_maya_attribute(node, attribute_name); 00216 return false; 00217 } 00218 00219 MFnNumericData data(vec2_object, &status); 00220 if (!status) { 00221 maya_cat.warning() 00222 << "Attribute " << attribute_name << " is of type " 00223 << vec2_object.apiTypeStr() << ", not a NumericData.\n"; 00224 return false; 00225 } 00226 00227 status = data.getData(value[0], value[1]); 00228 if (!status) { 00229 maya_cat.warning() 00230 << "Unable to extract 2 floats from " << attribute_name 00231 << ", of type " << vec2_object.apiTypeStr() << "\n"; 00232 } 00233 00234 return true; 00235 } 00236 00237 //////////////////////////////////////////////////////////////////// 00238 // Function: get_vec3_attribute 00239 // Description: Extracts the named three-component vector from the 00240 // MObject. 00241 //////////////////////////////////////////////////////////////////// 00242 bool 00243 get_vec3_attribute(MObject &node, const string &attribute_name, 00244 LVecBase3 &value) { 00245 MStatus status; 00246 00247 MObject vec3_object; 00248 if (!get_maya_attribute(node, attribute_name, vec3_object)) { 00249 maya_cat.warning() 00250 << "Attribute " << attribute_name 00251 << " does not have a vec3 object value.\n"; 00252 describe_maya_attribute(node, attribute_name); 00253 return false; 00254 } 00255 00256 MFnNumericData data(vec3_object, &status); 00257 if (!status) { 00258 maya_cat.warning() 00259 << "Attribute " << attribute_name << " is of type " 00260 << vec3_object.apiTypeStr() << ", not a NumericData.\n"; 00261 return false; 00262 } 00263 00264 status = data.getData(value[0], value[1], value[2]); 00265 if (!status) { 00266 maya_cat.warning() 00267 << "Unable to extract 3 floats from " << attribute_name 00268 << ", of type " << vec3_object.apiTypeStr() << "\n"; 00269 } 00270 00271 return true; 00272 } 00273 00274 //////////////////////////////////////////////////////////////////// 00275 // Function: get_vec2d_attribute 00276 // Description: Extracts the named two-component vector from the 00277 // MObject. 00278 //////////////////////////////////////////////////////////////////// 00279 bool 00280 get_vec2d_attribute(MObject &node, const string &attribute_name, 00281 LVecBase2d &value) { 00282 MStatus status; 00283 00284 MObject vec2d_object; 00285 if (!get_maya_attribute(node, attribute_name, vec2d_object)) { 00286 maya_cat.warning() 00287 << "Attribute " << attribute_name 00288 << " does not have a vec2d object value.\n"; 00289 describe_maya_attribute(node, attribute_name); 00290 return false; 00291 } 00292 00293 MFnNumericData data(vec2d_object, &status); 00294 if (!status) { 00295 maya_cat.warning() 00296 << "Attribute " << attribute_name << " is of type " 00297 << vec2d_object.apiTypeStr() << ", not a NumericData.\n"; 00298 return false; 00299 } 00300 00301 status = data.getData(value[0], value[1]); 00302 if (!status) { 00303 maya_cat.warning() 00304 << "Unable to extract 2 doubles from " << attribute_name 00305 << ", of type " << vec2d_object.apiTypeStr() << "\n"; 00306 } 00307 00308 return true; 00309 } 00310 00311 //////////////////////////////////////////////////////////////////// 00312 // Function: get_vec3d_attribute 00313 // Description: Extracts the named three-component vector from the 00314 // MObject. 00315 //////////////////////////////////////////////////////////////////// 00316 bool 00317 get_vec3d_attribute(MObject &node, const string &attribute_name, 00318 LVecBase3d &value) { 00319 MStatus status; 00320 00321 MObject vec3d_object; 00322 if (!get_maya_attribute(node, attribute_name, vec3d_object)) { 00323 maya_cat.warning() 00324 << "Attribute " << attribute_name 00325 << " does not have a vec3d object value.\n"; 00326 describe_maya_attribute(node, attribute_name); 00327 return false; 00328 } 00329 00330 MFnNumericData data(vec3d_object, &status); 00331 if (!status) { 00332 maya_cat.warning() 00333 << "Attribute " << attribute_name << " is of type " 00334 << vec3d_object.apiTypeStr() << ", not a NumericData.\n"; 00335 return false; 00336 } 00337 00338 status = data.getData(value[0], value[1], value[2]); 00339 if (!status) { 00340 maya_cat.warning() 00341 << "Unable to extract 3 doubles from " << attribute_name 00342 << ", of type " << vec3d_object.apiTypeStr() << "\n"; 00343 } 00344 00345 return true; 00346 } 00347 00348 //////////////////////////////////////////////////////////////////// 00349 // Function: get_mat4d_attribute 00350 // Description: Extracts the named 4x4 matrix from the MObject. 00351 //////////////////////////////////////////////////////////////////// 00352 bool 00353 get_mat4d_attribute(MObject &node, const string &attribute_name, 00354 LMatrix4d &value) { 00355 MStatus status; 00356 MObject matrix; 00357 if (!get_maya_attribute(node, attribute_name, matrix)) { 00358 return false; 00359 } 00360 00361 MFnMatrixData matrix_data(matrix, &status); 00362 if (!status) { 00363 maya_cat.warning() 00364 << "Attribute " << attribute_name << " is of type " 00365 << node.apiTypeStr() << ", not a Matrix.\n"; 00366 return false; 00367 } 00368 00369 const MMatrix &mat = matrix_data.matrix(); 00370 for (int i = 0; i < 4; i++) { 00371 for (int j = 0; j < 4; j++) { 00372 value(i, j) = mat(i, j); 00373 } 00374 } 00375 return true; 00376 } 00377 00378 //////////////////////////////////////////////////////////////////// 00379 // Function: get_tag_attribute_names 00380 // Description: artists should be able to set arbitrary tags. 00381 // Query all the attributes on this object and return 00382 // the lists of attribute names that has "tag" prefix 00383 //////////////////////////////////////////////////////////////////// 00384 void 00385 get_tag_attribute_names(MObject &node, pvector<string> &tag_names) { 00386 MStatus status; 00387 MFnDependencyNode node_fn(node, &status); 00388 if (!status) { 00389 maya_cat.warning() 00390 << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n"; 00391 return; 00392 } 00393 00394 string name = node_fn.name().asChar(); 00395 unsigned i; 00396 00397 for (i = 0; i < node_fn.attributeCount(); i++) { 00398 MObject attr = node_fn.attribute(i, &status); 00399 if (status) { 00400 MFnAttribute attrib(attr, &status); 00401 if (status) { 00402 string attribute_name = attrib.name().asChar(); 00403 if (attribute_name.find("tag", 0) != string::npos) { 00404 maya_cat.info() << ":" << name << ":" << " is tagged with <" 00405 << attribute_name << ">" << endl; 00406 tag_names.push_back(attribute_name); 00407 } 00408 } 00409 } 00410 } 00411 } 00412 //////////////////////////////////////////////////////////////////// 00413 // Function: get_enum_attribute 00414 // Description: Extracts the enum attribute from the MObject as a 00415 // string value. 00416 //////////////////////////////////////////////////////////////////// 00417 bool 00418 get_enum_attribute(MObject &node, const string &attribute_name, 00419 string &value) { 00420 MStatus status; 00421 00422 MPlug plug; 00423 if (!get_maya_plug(node, attribute_name.c_str(), plug)) { 00424 return false; 00425 } 00426 00427 MObject attrib = plug.attribute(); 00428 MFnEnumAttribute enum_attrib(attrib, &status); 00429 if (!status) { 00430 maya_cat.warning() 00431 << "Not an enum attribute: " << attribute_name << "\n"; 00432 return false; 00433 } 00434 00435 short index; 00436 status = plug.getValue(index); 00437 if (!status) { 00438 maya_cat.warning() 00439 << "Could not get numeric value of " << attribute_name << "\n"; 00440 status.perror("MPlug::getValue(short)"); 00441 return false; 00442 } 00443 00444 MString name = enum_attrib.fieldName(index, &status); 00445 if (!status) { 00446 maya_cat.warning() 00447 << "Invalid value for " << attribute_name << ": " << index << "\n"; 00448 status.perror("MFnEnumAttribute::fieldName()"); 00449 return false; 00450 } 00451 00452 value = name.asChar(); 00453 return true; 00454 } 00455 00456 //////////////////////////////////////////////////////////////////// 00457 // Function: get_string_attribute 00458 // Description: Extracts the named string attribute from the 00459 // MObject. 00460 //////////////////////////////////////////////////////////////////// 00461 bool 00462 get_string_attribute(MObject &node, const string &attribute_name, 00463 string &value) { 00464 MStatus status; 00465 00466 MObject string_object; 00467 if (!get_maya_attribute(node, attribute_name, string_object)) { 00468 maya_cat.warning() 00469 << "Attribute " << attribute_name 00470 << " does not have an string object value.\n"; 00471 describe_maya_attribute(node, attribute_name); 00472 return false; 00473 } 00474 00475 MFnStringData data(string_object, &status); 00476 if (!status) { 00477 maya_cat.warning() 00478 << "Attribute " << attribute_name << " is of type " 00479 << string_object.apiTypeStr() << ", not a StringData.\n"; 00480 return false; 00481 } 00482 00483 value = data.string().asChar(); 00484 return true; 00485 } 00486 00487 //////////////////////////////////////////////////////////////////// 00488 // Function: set_string_attribute 00489 // Description: Sets the named string attribute on the 00490 // MObject. 00491 //////////////////////////////////////////////////////////////////// 00492 bool 00493 set_string_attribute(MObject &node, const string &attribute_name, 00494 const string &value) { 00495 MStatus status; 00496 00497 // First, we get the string_object, then we set its string. 00498 MObject string_object; 00499 if (!get_maya_attribute(node, attribute_name, string_object)) { 00500 maya_cat.warning() 00501 << "Attribute " << attribute_name 00502 << " does not have a string object value.\n"; 00503 describe_maya_attribute(node, attribute_name); 00504 return false; 00505 } 00506 00507 MFnStringData data(string_object, &status); 00508 if (!status) { 00509 maya_cat.warning() 00510 << "Attribute " << attribute_name << " is of type " 00511 << string_object.apiTypeStr() << ", not a StringData.\n"; 00512 return false; 00513 } 00514 00515 MString mstring_value(value.data(), value.length()); 00516 status = data.set(mstring_value); 00517 if (!status) { 00518 status.perror(attribute_name.c_str()); 00519 return false; 00520 } 00521 00522 // And it appears we now need to set the string object back. 00523 if (!set_maya_attribute(node, attribute_name, string_object)) { 00524 maya_cat.warning() 00525 << "Attribute " << attribute_name 00526 << " suddenly does not have a string object value.\n"; 00527 return false; 00528 } 00529 00530 return true; 00531 } 00532 00533 //////////////////////////////////////////////////////////////////// 00534 // Function: describe_compound_attribute 00535 // Description: Extracts the children of this attribute from the 00536 // MObject. test for now 00537 //////////////////////////////////////////////////////////////////// 00538 bool 00539 describe_compound_attribute(MObject &node) { 00540 MStatus status; 00541 00542 MFnCompoundAttribute comp_attr(node, &status); 00543 00544 maya_cat.info() << "comp_attr has:" << comp_attr.numChildren() << " children" << endl; 00545 for (size_t i = 0; i < comp_attr.numChildren(); i++) { 00546 MObject child = comp_attr.child(i, &status); 00547 if (child.apiType() == MFn::kAttribute3Float){ 00548 LRGBColor color; 00549 /* 00550 if (get_vec3_attribute(child, "color", color)) { 00551 maya_cat.info() << "color: " << color << endl; 00552 } 00553 */ 00554 } 00555 else if (child.apiType() == MFn::kNumericAttribute) { 00556 MFnNumericAttribute numeric(child, &status); 00557 if (status) { 00558 switch(numeric.unitType()) { 00559 case MFnNumericData::kFloat : 00560 PN_stdfloat alpha; 00561 status = numeric.getDefault(alpha); 00562 maya_cat.info() << "found a float :" << alpha << endl; 00563 break; 00564 case MFnNumericData::kBoolean : 00565 bool v; 00566 status = numeric.getDefault(v); 00567 maya_cat.info() << "found a bool :" << v << endl; 00568 default: 00569 maya_cat.info() << numeric.unitType() << endl; 00570 } 00571 } 00572 } 00573 else if (child.apiType() == MFn::kEnumAttribute) { 00574 MFnEnumAttribute enu(child, &status); 00575 if (status) { 00576 MString blah; 00577 status = enu.getDefault(blah); 00578 maya_cat.info() << "found a string :" << blah.asChar() << endl; 00579 MPlug plug = MPlug(node, child); 00580 maya_cat.info() << "plug name" << plug.name().asChar() << endl; 00581 } 00582 } 00583 } 00584 return true; 00585 } 00586 00587 //////////////////////////////////////////////////////////////////// 00588 // Function: describe_maya_attribute 00589 // Description: Writes some warning output about the indicated Maya 00590 // attribute. 00591 //////////////////////////////////////////////////////////////////// 00592 void 00593 describe_maya_attribute(MObject &node, const string &attribute_name) { 00594 MStatus status; 00595 MFnDependencyNode node_fn(node, &status); 00596 if (!status) { 00597 maya_cat.warning() 00598 << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n"; 00599 return; 00600 } 00601 00602 MObject attr = node_fn.attribute(attribute_name.c_str(), &status); 00603 if (!status) { 00604 maya_cat.warning() 00605 << "Object " << node_fn.name().asChar() << " does not support attribute " 00606 << attribute_name << "\n"; 00607 return; 00608 } 00609 00610 maya_cat.warning() 00611 << "Attribute " << attribute_name << " on object " 00612 << node_fn.name().asChar() << " has type " << attr.apiTypeStr() << "\n"; 00613 } 00614 00615 string 00616 string_mfndata_type(MFnData::Type type) { 00617 switch (type) { 00618 case MFnData::kInvalid: 00619 return "kInvalid"; 00620 00621 case MFnData::kNumeric: 00622 return "kNumeric"; 00623 00624 case MFnData::kPlugin: 00625 return "kPlugin"; 00626 00627 case MFnData::kPluginGeometry: 00628 return "kPluginGeometry"; 00629 00630 case MFnData::kString: 00631 return "kString"; 00632 00633 case MFnData::kMatrix: 00634 return "kMatrix"; 00635 00636 case MFnData::kStringArray: 00637 return "kStringArray"; 00638 00639 case MFnData::kDoubleArray: 00640 return "kDoubleArray"; 00641 00642 case MFnData::kIntArray: 00643 return "kIntArray"; 00644 00645 case MFnData::kPointArray: 00646 return "kPointArray"; 00647 00648 case MFnData::kVectorArray: 00649 return "kVectorArray"; 00650 00651 case MFnData::kComponentList: 00652 return "kComponentList"; 00653 00654 case MFnData::kMesh: 00655 return "kMesh"; 00656 00657 case MFnData::kLattice: 00658 return "kLattice"; 00659 00660 case MFnData::kNurbsCurve: 00661 return "kNurbsCurve"; 00662 00663 case MFnData::kNurbsSurface: 00664 return "kNurbsSurface"; 00665 00666 case MFnData::kSphere: 00667 return "kSphere"; 00668 00669 case MFnData::kDynArrayAttrs: 00670 return "kDynArrayAttrs"; 00671 00672 case MFnData::kDynSweptGeometry: 00673 return "kDynSweptGeometry"; 00674 00675 case MFnData::kSubdSurface: 00676 return "kSubdSurface"; 00677 00678 case MFnData::kLast: 00679 return "kLast"; 00680 } 00681 00682 return "**invalid**"; 00683 } 00684 00685 //////////////////////////////////////////////////////////////////// 00686 // Function: list_maya_attributes 00687 // Description: Writes some info output showing all the attributes on 00688 // the given dependency node. Primarily useful during 00689 // development, to figure out where the heck Maya hides 00690 // some of the connected properties. 00691 //////////////////////////////////////////////////////////////////// 00692 void 00693 list_maya_attributes(MObject &node) { 00694 MStatus status; 00695 MFnDependencyNode node_fn(node, &status); 00696 if (!status) { 00697 maya_cat.warning() 00698 << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n"; 00699 return; 00700 } 00701 00702 string name = node_fn.name().asChar(); 00703 unsigned i; 00704 00705 MPlugArray connections; 00706 status = node_fn.getConnections(connections); 00707 if (!status) { 00708 status.perror("MFnDependencyNode::getConnections"); 00709 00710 } else { 00711 maya_cat.info() 00712 << name << " has " << connections.length() << " connections.\n"; 00713 for (i = 0; i < connections.length(); i++) { 00714 MPlug plug = connections[i]; 00715 00716 maya_cat.info(false) 00717 << " " << i << ". " << plug.name().asChar() << ", " 00718 << plug.attribute().apiTypeStr() << ", " 00719 << plug.node().apiTypeStr(); 00720 if (plug.attribute().apiType() == MFn::kCompoundAttribute) { 00721 //maya_cat.info() << plug.info(); 00722 //describe_compound_attribute(plug.attribute()); 00723 } 00724 if (plug.isConnected()) { 00725 maya_cat.info(false) 00726 << " (*)"; 00727 } 00728 maya_cat.info(false) 00729 << "\n"; 00730 } 00731 } 00732 00733 maya_cat.info() 00734 << name << " has " << node_fn.attributeCount() << " attributes.\n"; 00735 for (i = 0; i < node_fn.attributeCount(); i++) { 00736 MObject attr = node_fn.attribute(i, &status); 00737 if (status) { 00738 MFnTypedAttribute typed_attrib(attr, &status); 00739 if (status) { 00740 // It's a typed attrib. 00741 maya_cat.info(false) 00742 << " " << i << ". " << typed_attrib.name().asChar() 00743 << " [" << attr.apiTypeStr() << ", " 00744 << string_mfndata_type(typed_attrib.attrType()) << "]\n"; 00745 } else { 00746 MFnAttribute attrib(attr, &status); 00747 if (status) { 00748 // It's a generic attrib. 00749 maya_cat.info(false) 00750 << " " << i << ". " << attrib.name().asChar() 00751 << " [" << attr.apiTypeStr() << "]\n"; 00752 } else { 00753 // Don't know what it is. 00754 maya_cat.info(false) 00755 << " " << i << ". [" << attr.apiTypeStr() << "]\n"; 00756 } 00757 } 00758 } 00759 } 00760 } 00761