The Whole Reason for C++ in Maya

Maya C++ API quick guide

  • example code: maya/devkit/plug-ins
  • maya environment variable inside Maya.env file (check using `getenv MAYA_APP_DIR`), for version specif, add “./6.0” like:
    • MAYA_LOCATION
    • MAYA_SCRIPT_PATH
    • MAYA_PLUG_IN_PATH
    • XBMLANGPATH
  • other variable:
    • LD_LIBRARY_PATH (lib path)
  • method 1: edit MAYA_PLUG_IN_PATH variable value;
  • method 2: loadPlugin “hello”; unloadPlugin “hello”;
  • note: option to start maya in debug mode
    maya -d debuggerName
    • and in env to use user catch
      setenv MAYA_DEBUG_NO_SIGNAL_HANDLERS 1
  • compile based on Linux, example for Linux64
    c++ -c -I/apps/Linux64/aw/maya2012/include -m64 -O3 -pthread -pipe -D_BOOL -DLINUX_64 -DREQUIRE_IOSTREAM -fPIC -Wno-deprecated -fno-gnu-keywords hellow.cpp   
     
    c++ -shared -m64 -O3 -pthread -pipe -D_BOOL -DLINUX -DREQUIRE_IOSTREAM -Wno-deprecated -fno-gnu-keywords -Wl,-Bsymbolic -shared -o hellow.so hellow.o -L/apps/Linux64/aw/maya2012/lib -lOpenMaya -lFoundation -lOpenMayaAnim
     
    // explain:
    -m64 means processor is 64bit
    -O3 means optimize at level 3
    -pthread means support multi thread
    -pipe means compile method
    -D_BOOL and -DLINUX_64 means it is bool and linux64
    -rest are just standard compiler stuff
    -shared means linking
    -L means include directory and link directory
    -l means module to use
  • compile based on Mac, build guide:
  • compile based on Windows, build guide
  • quick mel commands to do it (linux verison)
    string $src="yourCPPFileName";
    string $mayaV="2015";
    string $cmd="cd /pathToYourCPPFileDir/;";
    $cmd+="c++ -c -I/apps/Linux64/aw/maya"+$mayaV+"/include -m64 -O3 -pthread -pipe -D_BOOL -DLINUX_64 -DREQUIRE_IOSTREAM -fPIC -Wno-deprecated -fno-gnu-keywords "+$src+".cpp;";
    $cmd+="c++ -shared -m64 -O3 -pthread -pipe -D_BOOL -DLINUX -DREQUIRE_IOSTREAM -Wno-deprecated -fno-gnu-keywords -Wl,-Bsymbolic -shared -o "+$src+".so "+$src+".o -L/apps/Linux64/aw/maya"+$mayaV+"/lib -lOpenMaya -lFoundation -lOpenMayaAnim";
    system($cmd);
     
    loadPlugin("/pathToYourCPPFileDir/"+$src+".so");
    unloadPlugin $src;
  • the C++ output goes into the shell output in which Maya runs from.
  • to make C++ output goes into Script Editor, use code MGlobal::displayInfo/Warning/Error

Note: MGlobal provides methods for selection, 3d-views, setting the global time, adding to the DAG, and executing MEL commands from within the API.

  • selection related
    MSelectionList list;
    MGlobal::getActiveSelectionList( list ); // list = `ls -sl`;
     
    clearSelectionList(); // select -cl
  • DAG (directed acyclic graph) hierarchy related (transform, shape)
    // MFnDagNode: parents; (< MDagPath)
    //  - .name() .typeName()
    // MFnTransform: get.set translate, rotate, scale;
    // MFnNurbsSurface: get, set CVs
    // MDagPath: path of node location, world space operation, MFn class input
    //  - fullPathName() hasFn(MFn::k"Type")
    //  - MDagPath::extendToShape()
    //  - MDagPath::child() and MDagPath::childCount() 
    // MObject: MFn class input
    MObject transformNode = dagPath.transform(&status);
    MFnDagNode transform(transformNode, &status);
     
    MTransformationMatrix matrix(transform.transformationMatrix());
    matrix.translation(MSpace::kWorld); // output translation
     
    double threeDoubles[3]; MTransformationMatrix::RotationOrder rOrder;
    matrix.getRotation (threeDoubles, rOrder, MSpace::kWorld);
    matrix.getScale (threeDoubles, MSpace::kWorld);
  • MFnSkinCluster related
    • get MFnSkinCluster instance
      # get the MFnSkinCluster for clusterName
      selList = OpenMaya.MSelectionList()
      selList.add(clusterName)
      clusterNode = OpenMaya.MObject()
      selList.getDependNode(0, clusterNode)
      skinFn = OpenMayaAnim.MFnSkinCluster(clusterNode)
       
      # get the MDagPath for all influence
      infDags = OpenMaya.MDagPathArray()
      skinFn.influenceObjects(infDags)
    • access weight data
      weightListPlug = skinFn.findPlug('weightList')
      weightPlug = skinFn.findPlug('weights')
      wl=[]
      for i in range(weightListPlug.numElements()):
          weightListRow = weightListPlug.elementByLogicalIndex(i)
          weightListRowData=weightListRow.child(0)
          w=[]
          for j in range(weightListRowData.numElements()):
              weightItem = weightListRowData.elementByLogicalIndex(j)
              tmp=weightItem.asDouble()
              #weightItem.setFloat(0.8)
              w.append(tmp)
          wl.append(w)
       
      # discussion about elementByLogicalIndex, elementByPhysicalIndex
        * elementByLogicalIndex : The logical indexes are used by MEL, and are sparse.; 
        * elementByPhysicalIndex : on the other hand, are not sparse. It is guaranteed that the physical indexes will range from 0 to numElements() - 1. 
       
      #weightListRowData.elementByPhysicalIndex(1).logicalIndex() ## only allow call for data not 0. Physical Indexed Array. with non-0 value data
      #weightListRowData.elementByPhysicalIndex(1).asDouble()
      #weightListRowData.elementByLogicalIndex(2).logicalIndex() ## allow empty array data call. The weight Data table, vtxCnt by jntCnt
      #weightListRowData.elementByLogicalIndex(2).asDouble()
      #weightListRowData.numElements() # each vtx, by physical used influence amount

C++ Maya API reference

Maya Dev PDFs

Maya Dev Blog