Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

pandatool/src/maya/maya_funcs.cxx

Go to the documentation of this file.
00001 // Filename: maya_funcs.cxx
00002 // Created by:  drose (16Feb00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "maya_funcs.h"
00020 
00021 #include "pre_maya_include.h"
00022 #include <maya/MObject.h>
00023 #include <maya/MAngle.h>
00024 #include <maya/MFnDependencyNode.h>
00025 #include <maya/MStatus.h>
00026 #include <maya/MFnStringData.h>
00027 #include <maya/MFnNumericData.h>
00028 #include <maya/MPlugArray.h>
00029 #include <maya/MPlug.h>
00030 #include <maya/MFnAttribute.h>
00031 #include <maya/MFnTypedAttribute.h>
00032 #include <maya/MFnEnumAttribute.h>
00033 #include <maya/MFnMatrixData.h>
00034 #include <maya/MMatrix.h>
00035 #include "post_maya_include.h"
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //     Function: get_maya_plug
00039 //  Description: Gets the named MPlug associated, if any.
00040 ////////////////////////////////////////////////////////////////////
00041 bool
00042 get_maya_plug(MObject &node, const string &attribute_name, MPlug &plug) {
00043   MStatus status;
00044   MFnDependencyNode node_fn(node, &status);
00045   if (!status) {
00046     maya_cat.error()
00047       << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
00048     return false;
00049   }
00050 
00051   MObject attr = node_fn.attribute(attribute_name.c_str(), &status);
00052   if (!status) {
00053     maya_cat.debug()
00054       << "Object " << node_fn.name() << " does not support attribute "
00055       << attribute_name << "\n";
00056     return false;
00057   }
00058 
00059   MFnAttribute attr_fn(attr, &status);
00060   if (!status) {
00061     maya_cat.error()
00062       << "Attribute " << attribute_name << " on " << node_fn.name()
00063       << " is a " << attr.apiTypeStr() << ", not an Attribute.\n";
00064     return false;
00065   }
00066 
00067   plug = MPlug(node, attr);
00068   return true;
00069 }
00070 
00071 ////////////////////////////////////////////////////////////////////
00072 //     Function: has_attribute
00073 //  Description: Returns true if the node has the indicated attribute,
00074 //               false otherwise.
00075 ////////////////////////////////////////////////////////////////////
00076 bool
00077 has_attribute(MObject &node, const string &attribute_name) { 
00078   MStatus status;
00079   MFnDependencyNode node_fn(node, &status);
00080   if (!status) {
00081     maya_cat.error()
00082       << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
00083     return false;
00084   }
00085 
00086   node_fn.attribute(attribute_name.c_str(), &status);
00087   if (!status) {
00088     // No such attribute.
00089     return false;
00090   }
00091   return true;
00092 }
00093 
00094 ////////////////////////////////////////////////////////////////////
00095 //     Function: get_bool_attribute
00096 //  Description: Extracts the named boolean attribute from the
00097 //               MObject.
00098 ////////////////////////////////////////////////////////////////////
00099 bool
00100 get_bool_attribute(MObject &node, const string &attribute_name,
00101                    bool &value) {
00102   if (!has_attribute(node, attribute_name)) {
00103     // For bool attributes only, we assume if the attribute is absent
00104     // it's the same thing as being false.
00105     return false;
00106   }
00107 
00108   if (!get_maya_attribute(node, attribute_name, value)) {
00109     maya_cat.error()
00110       << "Attribute " << attribute_name
00111       << " does not have a bool value.\n";
00112     describe_maya_attribute(node, attribute_name);
00113     return false;
00114   }
00115   return true;
00116 }
00117 
00118 ////////////////////////////////////////////////////////////////////
00119 //     Function: get_bool_attribute
00120 //  Description: Extracts the named angle in degrees from the
00121 //               MObject.
00122 ////////////////////////////////////////////////////////////////////
00123 bool
00124 get_angle_attribute(MObject &node, const string &attribute_name,
00125                     double &value) {
00126   MAngle maya_value;
00127   if (!get_maya_attribute(node, attribute_name, maya_value)) {
00128     maya_cat.error()
00129       << "Attribute " << attribute_name
00130       << " does not have an angle value.\n";
00131     describe_maya_attribute(node, attribute_name);
00132     return false;
00133   }
00134   value = maya_value.asDegrees();
00135   return true;
00136 }
00137 
00138 ////////////////////////////////////////////////////////////////////
00139 //     Function: get_vec2f_attribute
00140 //  Description: Extracts the named two-component vector from the
00141 //               MObject.
00142 ////////////////////////////////////////////////////////////////////
00143 bool
00144 get_vec2f_attribute(MObject &node, const string &attribute_name,
00145                     LVecBase2f &value) {
00146   MStatus status;
00147 
00148   MObject vec2f_object;
00149   if (!get_maya_attribute(node, attribute_name, vec2f_object)) {
00150     maya_cat.error()
00151       << "Attribute " << attribute_name
00152       << " does not have a vec2f object value.\n";
00153     describe_maya_attribute(node, attribute_name);
00154     return false;
00155   }
00156 
00157   MFnNumericData data(vec2f_object, &status);
00158   if (!status) {
00159     maya_cat.error()
00160       << "Attribute " << attribute_name << " is of type "
00161       << vec2f_object.apiTypeStr() << ", not a NumericData.\n";
00162     return false;
00163   }
00164 
00165   status = data.getData(value[0], value[1]);
00166   if (!status) {
00167     maya_cat.error()
00168       << "Unable to extract 2 floats from " << attribute_name
00169       << ", of type " << vec2f_object.apiTypeStr() << "\n";
00170   }
00171 
00172   return true;
00173 }
00174 
00175 ////////////////////////////////////////////////////////////////////
00176 //     Function: get_vec3f_attribute
00177 //  Description: Extracts the named three-component vector from the
00178 //               MObject.
00179 ////////////////////////////////////////////////////////////////////
00180 bool
00181 get_vec3f_attribute(MObject &node, const string &attribute_name,
00182                     LVecBase3f &value) {
00183   MStatus status;
00184 
00185   MObject vec3f_object;
00186   if (!get_maya_attribute(node, attribute_name, vec3f_object)) {
00187     maya_cat.error()
00188       << "Attribute " << attribute_name
00189       << " does not have a vec3f object value.\n";
00190     describe_maya_attribute(node, attribute_name);
00191     return false;
00192   }
00193 
00194   MFnNumericData data(vec3f_object, &status);
00195   if (!status) {
00196     maya_cat.error()
00197       << "Attribute " << attribute_name << " is of type "
00198       << vec3f_object.apiTypeStr() << ", not a NumericData.\n";
00199     return false;
00200   }
00201 
00202   status = data.getData(value[0], value[1], value[2]);
00203   if (!status) {
00204     maya_cat.error()
00205       << "Unable to extract 3 floats from " << attribute_name
00206       << ", of type " << vec3f_object.apiTypeStr() << "\n";
00207   }
00208 
00209   return true;
00210 }
00211 
00212 ////////////////////////////////////////////////////////////////////
00213 //     Function: get_vec2d_attribute
00214 //  Description: Extracts the named two-component vector from the
00215 //               MObject.
00216 ////////////////////////////////////////////////////////////////////
00217 bool
00218 get_vec2d_attribute(MObject &node, const string &attribute_name,
00219                     LVecBase2d &value) {
00220   MStatus status;
00221 
00222   MObject vec2d_object;
00223   if (!get_maya_attribute(node, attribute_name, vec2d_object)) {
00224     maya_cat.error()
00225       << "Attribute " << attribute_name
00226       << " does not have a vec2d object value.\n";
00227     describe_maya_attribute(node, attribute_name);
00228     return false;
00229   }
00230 
00231   MFnNumericData data(vec2d_object, &status);
00232   if (!status) {
00233     maya_cat.error()
00234       << "Attribute " << attribute_name << " is of type "
00235       << vec2d_object.apiTypeStr() << ", not a NumericData.\n";
00236     return false;
00237   }
00238 
00239   status = data.getData(value[0], value[1]);
00240   if (!status) {
00241     maya_cat.error()
00242       << "Unable to extract 2 doubles from " << attribute_name
00243       << ", of type " << vec2d_object.apiTypeStr() << "\n";
00244   }
00245 
00246   return true;
00247 }
00248 
00249 ////////////////////////////////////////////////////////////////////
00250 //     Function: get_vec3d_attribute
00251 //  Description: Extracts the named three-component vector from the
00252 //               MObject.
00253 ////////////////////////////////////////////////////////////////////
00254 bool
00255 get_vec3d_attribute(MObject &node, const string &attribute_name,
00256                     LVecBase3d &value) {
00257   MStatus status;
00258 
00259   MObject vec3d_object;
00260   if (!get_maya_attribute(node, attribute_name, vec3d_object)) {
00261     maya_cat.error()
00262       << "Attribute " << attribute_name
00263       << " does not have a vec3d object value.\n";
00264     describe_maya_attribute(node, attribute_name);
00265     return false;
00266   }
00267 
00268   MFnNumericData data(vec3d_object, &status);
00269   if (!status) {
00270     maya_cat.error()
00271       << "Attribute " << attribute_name << " is of type "
00272       << vec3d_object.apiTypeStr() << ", not a NumericData.\n";
00273     return false;
00274   }
00275 
00276   status = data.getData(value[0], value[1], value[2]);
00277   if (!status) {
00278     maya_cat.error()
00279       << "Unable to extract 3 doubles from " << attribute_name
00280       << ", of type " << vec3d_object.apiTypeStr() << "\n";
00281   }
00282 
00283   return true;
00284 }
00285 
00286 ////////////////////////////////////////////////////////////////////
00287 //     Function: get_mat4d_attribute
00288 //  Description: Extracts the named 4x4 matrix from the MObject.
00289 ////////////////////////////////////////////////////////////////////
00290 bool
00291 get_mat4d_attribute(MObject &node, const string &attribute_name,
00292                     LMatrix4d &value) {
00293   MStatus status;
00294   MObject matrix;
00295   if (!get_maya_attribute(node, attribute_name, matrix)) {
00296     return false;
00297   }
00298 
00299   MFnMatrixData matrix_data(matrix, &status);
00300   if (!status) {
00301     maya_cat.error()
00302       << "Attribute " << attribute_name << " is of type "
00303       << node.apiTypeStr() << ", not a Matrix.\n";
00304     return false;
00305   }
00306     
00307   const MMatrix &mat = matrix_data.matrix();
00308   for (int i = 0; i < 4; i++) {
00309     for (int j = 0; j < 4; j++) {
00310       value(i, j) = mat(i, j);
00311     }
00312   }
00313   return true;
00314 }
00315 
00316 ////////////////////////////////////////////////////////////////////
00317 //     Function: get_enum_attribute
00318 //  Description: Extracts the enum attribute from the MObject as a
00319 //               string value.
00320 ////////////////////////////////////////////////////////////////////
00321 bool
00322 get_enum_attribute(MObject &node, const string &attribute_name,
00323                    string &value) {
00324   MStatus status;
00325 
00326   MPlug plug;
00327   if (!get_maya_plug(node, attribute_name.c_str(), plug)) {
00328     return false;
00329   }
00330 
00331   MFnEnumAttribute enum_attrib(plug.attribute(), &status);
00332   if (!status) {
00333     maya_cat.error()
00334       << "Not an enum attribute: " << attribute_name << "\n";
00335     return false;
00336   }
00337 
00338   short index;
00339   status = plug.getValue(index);
00340   if (!status) {
00341     maya_cat.error()
00342       << "Could not get numeric value of " << attribute_name << "\n";
00343     status.perror("MPlug::getValue(short)");
00344     return false;
00345   }
00346 
00347   MString name = enum_attrib.fieldName(index, &status);
00348   if (!status) {
00349     maya_cat.error()
00350       << "Invalid value for " << attribute_name << ": " << index << "\n";
00351     status.perror("MFnEnumAttribute::fieldName()");
00352     return false;
00353   }
00354 
00355   value = name.asChar();
00356   return true;
00357 }
00358 
00359 ////////////////////////////////////////////////////////////////////
00360 //     Function: get_string_attribute
00361 //  Description: Extracts the named string attribute from the
00362 //               MObject.
00363 ////////////////////////////////////////////////////////////////////
00364 bool
00365 get_string_attribute(MObject &node, const string &attribute_name,
00366                      string &value) {
00367   MStatus status;
00368 
00369   MObject string_object;
00370   if (!get_maya_attribute(node, attribute_name, string_object)) {
00371     maya_cat.error()
00372       << "Attribute " << attribute_name
00373       << " does not have an string object value.\n";
00374     describe_maya_attribute(node, attribute_name);
00375     return false;
00376   }
00377 
00378   MFnStringData data(string_object, &status);
00379   if (!status) {
00380     maya_cat.error()
00381       << "Attribute " << attribute_name << " is of type "
00382       << string_object.apiTypeStr() << ", not a StringData.\n";
00383     return false;
00384   }
00385 
00386   value = data.string().asChar();
00387   return true;
00388 }
00389 
00390 ////////////////////////////////////////////////////////////////////
00391 //     Function: set_string_attribute
00392 //  Description: Sets the named string attribute on the
00393 //               MObject.
00394 ////////////////////////////////////////////////////////////////////
00395 bool
00396 set_string_attribute(MObject &node, const string &attribute_name,
00397                      const string &value) {
00398   MStatus status;
00399 
00400   // First, we get the string_object, then we set its string.
00401   MObject string_object;
00402   if (!get_maya_attribute(node, attribute_name, string_object)) {
00403     maya_cat.error()
00404       << "Attribute " << attribute_name
00405       << " does not have a string object value.\n";
00406     describe_maya_attribute(node, attribute_name);
00407     return false;
00408   }
00409 
00410   MFnStringData data(string_object, &status);
00411   if (!status) {
00412     maya_cat.error()
00413       << "Attribute " << attribute_name << " is of type "
00414       << string_object.apiTypeStr() << ", not a StringData.\n";
00415     return false;
00416   }
00417 
00418   MString mstring_value(value.data(), value.length());
00419   status = data.set(mstring_value);
00420   if (!status) {
00421     status.perror(attribute_name.c_str());
00422     return false;
00423   }
00424 
00425   // And it appears we now need to set the string object back.
00426   if (!set_maya_attribute(node, attribute_name, string_object)) {
00427     maya_cat.error()
00428       << "Attribute " << attribute_name
00429       << " suddenly does not have a string object value.\n";
00430     return false;
00431   }
00432 
00433   return true;
00434 }
00435 
00436 ////////////////////////////////////////////////////////////////////
00437 //     Function: describe_maya_attribute
00438 //  Description: Writes some error output about the indicated Maya
00439 //               attribute.
00440 ////////////////////////////////////////////////////////////////////
00441 void
00442 describe_maya_attribute(MObject &node, const string &attribute_name) {
00443   MStatus status;
00444   MFnDependencyNode node_fn(node, &status);
00445   if (!status) {
00446     maya_cat.error()
00447       << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
00448     return;
00449   }
00450 
00451   MObject attr = node_fn.attribute(attribute_name.c_str(), &status);
00452   if (!status) {
00453     maya_cat.error()
00454       << "Object " << node_fn.name() << " does not support attribute "
00455       << attribute_name << "\n";
00456     return;
00457   }
00458 
00459   maya_cat.error()
00460     << "Attribute " << attribute_name << " on object "
00461     << node_fn.name() << " has type " << attr.apiTypeStr() << "\n";
00462 }
00463 
00464 string
00465 string_mfndata_type(MFnData::Type type) {
00466   switch (type) {
00467   case MFnData::kInvalid:
00468     return "kInvalid";
00469     break;
00470   case MFnData::kNumeric:
00471     return "kNumeric";
00472     break;
00473   case MFnData::kPlugin:
00474     return "kPlugin";
00475     break;
00476   case MFnData::kPluginGeometry:
00477     return "kPluginGeometry";
00478     break;
00479   case MFnData::kString:
00480     return "kString";
00481     break;
00482   case MFnData::kMatrix:
00483     return "kMatrix";
00484     break;
00485   case MFnData::kStringArray:
00486     return "kStringArray";
00487     break;
00488   case MFnData::kDoubleArray:
00489     return "kDoubleArray";
00490     break;
00491   case MFnData::kIntArray:
00492     return "kIntArray";
00493     break;
00494   case MFnData::kPointArray:
00495     return "kPointArray";
00496     break;
00497   case MFnData::kVectorArray:
00498     return "kVectorArray";
00499     break;
00500   case MFnData::kComponentList:
00501     return "kComponentList";
00502     break;
00503   case MFnData::kMesh:
00504     return "kMesh";
00505     break;
00506   case MFnData::kLattice:
00507     return "kLattice";
00508     break;
00509   case MFnData::kNurbsCurve:
00510     return "kNurbsCurve";
00511     break;
00512   case MFnData::kNurbsSurface:
00513     return "kNurbsSurface";
00514     break;
00515   case MFnData::kSphere:
00516     return "kSphere";
00517     break;
00518   case MFnData::kDynArrayAttrs:
00519     return "kDynArrayAttrs";
00520     break;
00521   case MFnData::kDynSweptGeometry:
00522     return "kDynSweptGeometry";
00523     break;
00524   case MFnData::kSubdSurface:
00525     return "kSubdSurface";
00526     break;
00527   case MFnData::kLast:
00528     return "kLast";
00529     break;
00530   }
00531 
00532   return "**invalid**";
00533 }
00534 
00535 ////////////////////////////////////////////////////////////////////
00536 //     Function: list_maya_attributes
00537 //  Description: Writes some info output showing all the attributes on
00538 //               the given dependency node.  Primarily useful during
00539 //               development, to figure out where the heck Maya hides
00540 //               some of the connected properties.
00541 ////////////////////////////////////////////////////////////////////
00542 void
00543 list_maya_attributes(MObject &node) {
00544   MStatus status;
00545   MFnDependencyNode node_fn(node, &status);
00546   if (!status) {
00547     maya_cat.error()
00548       << "Object is a " << node.apiTypeStr() << ", not a DependencyNode.\n";
00549     return;
00550   }
00551 
00552   string name = node_fn.name().asChar();
00553   unsigned i;
00554 
00555   MPlugArray connections;
00556   status = node_fn.getConnections(connections);
00557   if (!status) {
00558     status.perror("MFnDependencyNode::getConnections");
00559 
00560   } else {
00561     maya_cat.info()
00562       << name << " has " << connections.length() << " connections.\n";
00563     for (i = 0; i < connections.length(); i++) {
00564       MPlug plug = connections[i];
00565       maya_cat.info(false)
00566         << "  " << i << ". " << plug.name().asChar() << ", "
00567         << plug.attribute().apiTypeStr() << ", " 
00568         << plug.node().apiTypeStr() << "\n";
00569     }
00570   }
00571     
00572   maya_cat.info()
00573     << name << " has " << node_fn.attributeCount() << " attributes.\n";
00574   for (i = 0; i < node_fn.attributeCount(); i++) {
00575     MObject attr = node_fn.attribute(i, &status);
00576     if (status) {
00577       MFnTypedAttribute typed_attrib(attr, &status);
00578       if (status) {
00579         // It's a typed attrib.
00580           maya_cat.info(false) 
00581             << "  " << i << ". " << typed_attrib.name().asChar()
00582             << " [" << attr.apiTypeStr() << ", "
00583             << string_mfndata_type(typed_attrib.attrType()) << "]\n";
00584       } else {
00585         MFnAttribute attrib(attr, &status);
00586         if (status) {
00587           // It's a generic attrib.
00588           maya_cat.info(false) 
00589             << "  " << i << ". " << attrib.name().asChar()
00590             << " [" << attr.apiTypeStr() << "]\n";
00591         } else {
00592           // Don't know what it is.
00593           maya_cat.info(false)
00594             << "  " << i << ". [" << attr.apiTypeStr() << "]\n";
00595         }
00596       }
00597     }
00598   }
00599 }
00600 

Generated on Fri May 2 03:21:15 2003 for Panda-Tool by doxygen1.3