zoukankan      html  css  js  c++  java
  • [zz]Maya C++ API Programming Tips

    Maya C++ API Programming Tips

    source : http://wanochoi.com/?page_id=1588

    How to handle the multiple outputs of a DG node

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    MStatus MyNode::initialize()
    {
       MFnNumericAttribute nAttr;
     
       outputsObj = nAttr.create( "outputs", "outputs", MFnNumericData.kFloat, 0.f );
       nAttr.setArray( true );
       addAttribute( outputsObj );
       ...
    }
     
    MStatus MyNode::compute( const MPlug& plug, MDataBlock& data )
    {
       if( plug != outputsObj ) { return MS::kUnknownParameter; }
     
       MArrayDataHandle outputsHnd = data.outputArrayValue( outputsObj );
     
       const int nOutputs = (int)outputsHnd.elementCount();
     
       for( int i=0; i<100; ++i )
       {
          outputsHnd.jumpToElement( i );
          outputsHnd.outputValue().set( i );
       }
     
       outputsHnd.setAllClean();
       return MS::kSuccess;  
    }

    How to capture the current viewport as an image file

    1
    2
    3
    4
    MImage image;
    M3dView view = M3dView::active3dView();
    view.readColorBuffer( image, true );
    image.writeToFile( "snapshot.jpg", "jpg" );

    How to save the current frame buffer to a JPG file

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    GLint viewport[4];
    glGetIntegerv( GL_VIEWPORT, viewport );
     
    int width = viewport[2];
    int height = viewport[3];
    int depth = 4;
     
    unsigned char* pixels = new unsigned int[width*height*depth];
     
    glReadBuffer( GL_FRONT );
    glReadPixels( 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels );
     
    MImage image;
    image.setPixels( pixels, width, height );
    image.writeToFile( "snapshot.jopg", "jpg" );
     
    delete[] pixels;

    How to set the names of a custom DG node and its parent node

    1
    2
    3
    4
    5
    6
    7
    8
    9
    void myNode::postConstructor()
    {
       MPxNode::postConstructor();
     
       MObject thisMObj = thisMObject();
       MFnDependencyNode nodeFn;
       nodeFn.setObject( thisMObj );
       nodeFn.setName( "myNodeShape#" );
    }

    How to compile my source code conditionally according to the Maya API version

    1
    2
    3
    4
    5
    6
    7
    #if MAYA_API_VERSION &amp;gt;= 201300
    ...
    #elif MAYA_API_VERSION &amp;gt;= 201400
    ...
    #elif MAYA_API_VERSION &amp;gt;= 201500
    ...
    #endif

    How to get the current Maya version

    1
    2
    MString mayaVer = MGlobal::mayaVersion();
    int apiVer = MGlobal::apiVersion();

    How to avoid the conflict with Cuda

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    ...
    #define short2  MAYA_short2
    #define short3  MAYA_short3
    #define long2   MAYA_long2
    #define long3   MAYA_long3
    #define int2    MAYA_int2
    #define int3    MAYA_int3
    #define float2  MAYA_float2
    #define float3  MAYA_float3
    #define double2 MAYA_double2
    #define double3 MAYA_double3
    #define double4 MAYA_double4
     
    #include &amp;lt;cuda.h&amp;gt;
    ...

    How to set the MFloatPoint from a MPoint

    1
    2
    3
    MPoint dp; // double type
    MFloatPoint fp; // float type
    fp.setCast( dp );

    How to get the pixel values of an image

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    MImage img;
    img.readFromFile( "filePathName" ); // load from a file
     
    int w=0, h=0; // image width, height
    img.getSize( w, h );
    int d = img.depth(); // image depth
     
    unsigned char* c = (unsigned char*)NULL;
     
    if( img.pixelType() == MImage::kByte )
    {
       c = img.pixels();
    }
     
    for( int j=0; j&amp;lt;h; ++j )
    for( int i=0; i&amp;lt;w; ++i )
    {{
       int idx = d*(i+j*w);
     
       unsigned char pixelVal[4]; // RGB(d=3) or RGBA(d=4)
     
       for( int k=0; k&amp;lt;d; ++k )
       {
          pixelVal[k] = c[idx++];
       }
     
       ...
    }}

    How to get the DAG path from a node name

    1
    2
    3
    4
    5
    6
    7
    MString nodeName( "nodeName" );
    MDagPath dagPath;
    MSelectionList sList;
    if( MGlobal::getSelectionListByName( nodeName, sList ) )
    {
       sList.getDagPath( 0, dagPath );
    }

    How to get the DG node object from a node name

    1
    2
    3
    4
    5
    6
    7
    MString nodeName( "nodeName" );
    MObject nodeObj;
    MSelectionList sList;
    if( MGLobal::getSelectionListByName( nodeName, sList ) )
    {
       sList.getDependNode( 0, nodeObj );
    }

    How to get the DAG path from a DAG node object

    1
    2
    3
    4
    MObject dagNodeObj = ...;
    MDagPath dagPath;
    MFnDagNode dagFn( dagNodeObj );
    dagFn.getPath( dagPath );

    How to get the node name from a node object

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    MObject nodeObj = ...;
    MString nodeName;
     
    if( nodeObj.hasFn( MFn::kDagNode ) ) {
       MFnDagNode dagNodeFn( nodeObj );
       nodeName = dagNode.fullPathName();
    } else if( nodeObj.hasFn( MFn::kDependencyNode ) ) {
       MFnDependencyNode dgNodeFn( nodeObj );
       nodeName = dgNodeFn.name();
    }

    How to get the parent DAG node object

    1
    2
    3
    4
    5
    6
    7
    MObject parentDagNodeObj;
    MFnDagNode dagFn( thisMObject() );
    MObject obj = dagFn.parent( 0 );
    if( !obj.isNull() )
    {
       parentDagNodeObj = obj;
    }

    How to get the shape node DAG path from a transform DAG path

    1
    2
    3
    MDagPath xformDagPath = ...
    MDagPath shapeDagPath = xformDagPath;
    shapeDagPath.extendToShape();

    How to get the DAG paths of selected mesh shape nodes

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    MDagPathArray dagPaths;
     
    MSelectionList sList;
    MGlobal::getActiveSelectionList( sList );
     
    MItSelectionList itr( sList, MFn::kMesh );
    for( ; !itr.isDone(); itr.next() )
    {
       MDagPath dagPath;
       itr.getDagPath( dagPath );
       MFnDagNode dagFn( dagPath );
       if( dagFn.isIntermediateObject() ) { continue; }
       dagPaths.append( dagPath );
    }

    How to get the all of NURBS curve node objects in the current scene

    1
    2
    3
    4
    5
    6
    MObjectArray curveObjs;
    MItDag itr( MItDag::kDepthFirst, MFn::kNurbsCurve );
    for( ; !itr.isDone(); itr.next() )
    {
       curveObjs.append( itr.item() );
    }

    How to get the list of a selected mesh polygons

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    MIntArray selectedPolygonList;
     
    MSelectionList sList;
    MGlobal::getActiveSelectionList( sList );
    MItSelectionList sItr( sList, MFn::kMeshPolygonComponent );
     
    MDagPath dagPath;
    MObject componentObj;
    sItr.getDagPath( dagPath, componentObj );
     
    MFnSingleIndexedComponent sCompFn( componentObj );
    sCompFn.getElements( selectedPolygonList );

    How to get the all of fields in the current scene

    1
    2
    3
    4
    5
    6
    MItDag itr( MItDag::kDepthFirst, MFn::kField );
    for( ; !itr.isDone(); itr.next() )
    {
       MFnField fieldFn( itr.item() );
       ...
    }

    How to get the world matrix of the current DAG node

    1
    2
    3
    4
    5
    6
    7
    8
    MObject thisNodeObj = thisMObject();
    MFnDependencyNode thisNodeFn( thisNodeObj );
    MObject worldMatrixObj = thisNodeFn.attribute( "worldMatrix" );
    MPlug worldMatrixPlg( thisNodeObj, worldMatrixObj );
    worldMatrixPlg = worldMatrixPlg.elementByLogicalIndex( 0 );
    worldMatrixPlg.getValue( worldMatrixObj );
    MFnMatrixData worldMatrixData( worldMatrixObj );
    Matrix worldMatrix = worldMatrixData.matrix();

    How to connect the output plug to the parent automatically when a custom locator node is created

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    class MyLocator
    {
       ...
       bool connected;
       ...
    };
     
    MyLocator::MyLocator()
    {
       connected = false;
    }
     
    void MyLocator::draw( M3dView&amp;amp; view, ...)
    {
       if( !connected )
       {
          MObject thisNodeObj = thisMObject();
          MFnDagNode dagFn( thisNodeObj );
          MObject parentNodeObj = dagFn.parent( 0 );
          dagFn.setObject( parentNodeObj );
          MPlug parentPlg = dagFn.findPlug( "plugName" );
          MPlug outputPlg = MPlug( thisNodeObj, outputObj );
          if( !outputPlg.isConnected() )
          {
             MDGModifier dgMod;
             dgMod.connect( outputPlg, parentPlg );
             dgMod.doIt();
             connected = true;
          }
       }
       ...
    }

    How to make a custom locator node un-selectable

    1
    2
    3
    4
    5
    void MyLocator::draw( M3dView&amp;amp; view, ...)
    {
       if( view.selectMode() ) { return; }
       ...
    }

    How to detect which input attribute is changed

    1
    2
    3
    4
    5
    6
    7
    8
    9
    MStatus MyCustomNode::compute( const MPlug&amp;amp; plug, MDataBlock&amp;amp; data )
    {
       if( plug != outputObj ) { return MS::kUnknownParameter; }
     
       bool inputIsChanged = !data.isClean( inputObj );
       float input = data.inputValue( inputObj ).asFloat();
     
       ...
    }

    Note) It doesn’t work when inputObj is array type.

    How to detect whether the current state is batch mode

    1
    2
    3
    4
    if( MGlobal::mayaState() == MGlobal::kBatch )
    {
       ...
    }

    How to detect whether the current viewport is Viewport 2.0

    1
    2
    3
    4
    5
    M3dView view = M3dView::active3dView();
    if( view.getRendererName() == M3dView::kViewport2Renderer )
    {
       ...
    }

    How not to draw a custom locator node while mouse interactions (>=2015)

    1
    2
    3
    4
    5
    6
    7
    8
    void MyLocator::draw( M3dView&amp;amp; view, ...)
    {
       if( MHWRender::MFrameContext::inUserInteraction()
        || MHWRender::MFrameContext::userChangingViewContext() )
       {
          ...
       }
    }

    How to draw a text in draw() of a custom locator node

    1
    2
    3
    4
    5
    6
    7
    8
    void MyLocator::draw( M3dView&amp;amp; view, ...)
    {
       ...
       view.beginGL();
       view.drawText( MString("text"), MPoint(0,0,0), M3dView::kLeft );
       view.endGL();
       ...
    }

    How to copy the input mesh to the output mesh in compute() of a custom node

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    MStatus MyNode::compute( const MPlug&amp;amp; plug, MDataBlock&amp;amp; data )
    {
       ...
       MFnMesh newMeshFn;
       MFnMeshData dataCreator;
       MObject newMeshData = dataCreator.create();
       newMeshFn.copy( data.inputValue( inMeshObj ).asMeshTransformed(), newMeshData );
       data.outputValue( outMeshObj ).set( newMeshData );
       ...
    }

    How to deform the input mesh in compute() of a custom node like such a deformer

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    MStatus MyNode::compute( const MPlug&amp;amp; plug, MDataBlock&amp;amp; data )
    {
       ...
     
       MPointArray deformedPoints = ...
     
       MFnMesh newMeshFn;
       MFnMeshData dataCreator;
       MObject newMeshData = dataCreator.create();
       newMeshFn.copy( data.inputValue( inMeshObj ).asMeshTransformed(), newMeshData );
       newMeshFn.setPoints( deformedPoints );
       data.outputValue( outMeshObj ).set( newMeshData );
     
       ...
    }

    How to handle array attribute

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    class MyCustomNode
    {
       ...
       MObject valuesObj;
       ...
       MDoubleArray values;
    };
     
    MObject MyCustomNode::valuesObj;
     
    MStatus MyCustomNode::initialize()
    {
       ...
       valuesObj = tAttr.create( "values", "values", MFnData::kDoubleArray );
       ...
    }
     
    MStatus MyCustomNode::compute( const MPlug&amp;amp; plug, MDataBlock&amp;amp; data )
    {
       ...
     
       // get
       MFnDoubleArrayData arrayData;
       MObject dataObj = data.inputValue( valuesObj ).data();
       arrayData.setObject( dataObj );
     
       int numValues = 100;
     
       // set
       if( arrayData.length() != numValues )
       {
          MDoubleArray array( numValues, 0.0 );
          dataObj = arrayData.create( array );
          data.outputValue( valuesObj ).set( dataObj );
       }
     
       ...
    }
     
    // MEL
    makePaintable -at doubleArray MyCustomNode values;
    setAttr MyCustomNode1.values -type doubleArray 3 1.0 2.0 3.0;

    How to get the value of an attribute anywhere in a custom node

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    MObject thisNodeObj = thisMObject();
     
    double  v0 = MPlug( thisNodeObj, attr0Obj ).asDouble();
    float   v1 = MPlug( thisNodeObj, attr1Obj ).asFloat();
    int     v2 = MPlug( thisNodeObj, attr2Obj ).asInt();
    short   v3 = MPlug( thisNodeObj, attr3Obj ).asShort();
    bool    v4 = MPlug( thisNodeObj, attr4Obj ).asBool();
    MTime   v5 = MPlug( thisNodeObj, attr5Obj ).asMTime();
    char    v6 = MPlug( thisNodeObj, attr6Obj ).asChar();
    MString v7 = MPlug( thisNodeObj, attr7Obj ).asString();
     
    MColor c;
    MPlug plg( thisNodeObj, attrObj );
    plg.child(0).getValue( c.r );
    plg.child(1).getValue( c.g );
    plg.child(2).getValue( c.b );

    How to get the pointer of the other connected node

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    OtherNodeClassName* otherNodePtr = (OtherNodeClassName*)NULL;
     
    MObject thisNodeObj = thisMObject();
    MFnDependencyNode thisNodeFn( thisNodeObj );
    MPlug plg = thisNodeFn.findPlug( inputAttrObj );
     
    MPlugArray connectedPlgs;
    if( plg.isConnected() )
    {
       if( plg.isSource() ) {
          plg.connectedTo( connectedPlgs, false, true );
       } else if( plg.isDestination() ) {
          plg.connectedTo( connectedPlgs, true, false );
       }
     
       MFnDependencyNode otherNodeFn( connectedPlgs[0].node() );
     
       if( otherNodeFn.typeId() == OtherNodeClassName::id )
       {
          otherNodePtr = (OtherNodeClassName*)otherNodeFn.userNode();
       }
    }

    How to restore GL states in draw() of a custom locator node

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    void MyLocator::draw( M3dView&amp;amp; view, ...)
    {
       float lastPointSize=0; glGetFloatv( GL_POINT_SIZE, &amp;amp;lastPointSize );
       float lastLineWidth=0; glGetFloatv( GL_LINE_WIDTH, &amp;amp;lastLineWidth );
       bool lightingWasOn = glIsEnabled( GL_LIGHTING ) ? true : false;
     
       if( lightingWasOn ) { glDisable( GL_LIGHTING ); }
     
       view.beginGL();
       ...
       view.endGL();
     
       glPointSize( lastPointSize );
       glLineWidth( lastLineWidth );
       if( lightingWasOn ) { glEnable( GL_LIGHTING ); }
    }

    How to call compute() of a custom locator without output connection

    1
    2
    3
    4
    5
    6
    7
    void MyLocator::draw( M3dView&amp;amp; view, ...)
    {
       MObject thisNodeObj = thisMObject();
       MObject obj = MPlug( thisNodeObj, outputObj ).asMObject();
     
       ...
    }

    How to get the normal vector of a current camera

    1
    2
    3
    4
    M3dView view = M3dView::active3dView();
    MDagPath camDagPath;
    view.getCamera( camDagPath );
    MVector cameraZ = MVector(0,0,1) * camDagPath.inclusiveMatrix();

    How to create attributes in initialize() of a custom node

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    MStatus MyLocator::initialize()
    {
       MRampAttribute      rAttr;
       MFnEnumAttribute    eAttr;
       MFnUnitAttribute    uAttr;
       MFnTypedAttribute   tAttr;
       MFnNumericAttribute nAttr;
       MFnMessageAttribute gAttr;
     
       timeObj = uAttr.create( "time", "time", MFnUnitAttribute::kTime, 0.0 );
       addAttribute( timeObj );
     
       angleObj = uAttr.create( "angle", "angle", MFnUnitAttribute::kAngle, 0.0 );
       addAttribute( angleObj );
     
       boolObj = nAttr.create( "bool", "bool", MFnNumericData::kBoolean, false );
       addAttribute( boolObj );
     
       intObj = nAttr.create( "int", "int", MFnNumericData::kInt, 0 );
       addAttribute( intObj );
     
       floatObj = nAttr.create( "float", "float", MFnNumericData::kFloat, 0.f );
       addAttribute( floatObj );
     
       doubleObj = nAttr.create( "double", "double", MFnNumericData::kDouble, 0.0 );
       addAttribute( doubleObj );
     
       int2Obj = nAttr.create( "int2", "int2", MFnNumericData::k2Int, 0 );
       addAttribute( int2Obj );
     
       int3Obj = nAttr.create( "int3", "int3", MFnNumericData::k3Int, 0 );
       addAttribute( int3Obj );
     
       float2Obj = nAttr.create( "float2", "float2", MFnNumericData::k2Float, 0.f );
       addAttribute( float2Obj );
     
       float3Obj = nAttr.create( "float3", "float3", MFnNumericData::k3Float, 0.f );
       addAttribute( float3Obj );
     
       double2Obj = nAttr.create( "double2", "double2", MFnNumericData::k2Double, 0.0 );
       addAttribute( double2Obj );
     
       double3Obj = nAttr.create( "double3", "double3", MFnNumericData::k3Double, 0.0 );
       addAttribute( double3Obj );
     
       stringObj = tAttr.create( "string", "string", MFnData::kString, "abc" );
       addAttribute( stringObj );
     
       matrixObj = tAttr.create( "matrix", "matrix", MFnMatrixAttribute::kDouble );
       addAttribute( matrixObj );
     
       curveObj = tAttr.create( "curve", "curve", MFnData::kNurbsCurve );
       addAttribute( curveObj );
     
       meshObj = tAttr.create( "mesh", "mesh", MFnData::kMesh );
       addAttribute( meshObj );
     
       iaObj = tAttr.create( "iArray", "iArray", MFnData::kIntArray );
       addAttribute( iaObj );
     
       faObj = tAttr.create( "fArray", "fArray", MFnData::kFloatArray );
       addAttribute( faObj );
     
       daObj = tAttr.create( "dArray", "dArray", MFnData::kDoubleArray );
       addAttribute( daObj );
     
       paObj = tAttr.create( "pArray", "pArray", MFnData::kPointArray );
       addAttribute( paObj );
     
       vaObj = tAttr.create( "vArray", "vArray", MFnData::kVectorArray );
       addAttribute( vaObj );
     
       saObj = tAttr.create( "sArray", "sArray", MFnData::kStringArray );
       addAttribute( saObj );
     
       msgObj = gAttr.create( "message", "message" );
       addAttribute( msgObj );
     
       clrObj = nAttr.createColor( "color", "color" );
       addAttribute( clrObj );
     
       pntObj = nAttr.createPoint( "point", "point" );
       addAttribute( pntObj );
     
       enumObj = eAttr.create( "enum", "enum" 0 );
          eAttr.addField( "A", 0 );
          eAttr.addField( "B", 0 );
       addAttribute( enumObj );
     
       crvRmpObj = rAttr.createCurveRampAttr( "crvRamp", "crvRamp" );
       addAttribute( crvRmpObj );
     
       clrRmpObj = rAttr.createColorRampAttr( "clrRamp", "clrRamp" );
       addAttribute( clrRmpObj );
     
       fileNameObj = tAttr.create( "fileName", "fileName", MFnData::kString );
       tAttr.setUsedAsFilename( true );
       addAttribute( fileNameObj );
     
       ...
    }

    end,

  • 相关阅读:
    C++多线程二
    C++多线程一
    定义抽象数据类型
    泛型函数
    关联容器(map):支持高效查找的容器,一种键值对的集合。
    字符串拆成单词的另一种实现
    将字符串拆成单词,并算最长的长度
    重载,排序,集合实例
    程序调用动态链接库中的方法,位图,类
    用bosybox制作文件系统
  • 原文地址:https://www.cnblogs.com/yaoyansi/p/5538178.html
Copyright © 2011-2022 走看看