Feedback

type to search

Maya plugin help/mentor?

Asked by [ Editor ]

Is there a forum to get Maya plugin help? I wrote a deformer plugin. Theoretically, it should be faster than the approach using current tools in Maya. But since it's my first attempt, I don't know if I'm using the most optimal functions/methods (deform vs. compute). My plugin is actually not much faster than using current tools in Maya. Is there a place to get advice? I was even thinking to pay someone, if it's not cost prohibitive, to write the plugin so I could learn from it.

It's conceptually analogous to a muscle system. But I haven't had time to play with muscles in Maya. Is that also slow?

Here's the compute portion of my code:

MStatus geoCluster::compute(const MPlug& plug, MDataBlock& data) { MStatus status;

//MString plugName;
//plugName = plug.name();
//cerr << "PLUG NAME: " << plugName.asChar() << endl;

if (plug.attribute() != outputGeom) {
    //printf("Ignoring requested plug\n");
    return status;
}
unsigned int index = plug.logicalIndex();
MObject thisNode = this->thisMObject();

// get input value
MPlug inPlug(thisNode,input);
inPlug.selectAncestorLogicalIndex(index,input);
MDataHandle hInput = data.inputValue(inPlug, &status);
//MCheckStatus(status, "ERROR getting input mesh\n");

// get the input geometry
MDataHandle inputData = hInput.child(inputGeom);
if (inputData.type() != MFnData::kMesh) {
    //printf("Incorrect input geometry type\n");
    return MStatus::kFailure;
}

MObject iSurf = inputData.asMesh() ;
MFnMesh inMesh;
inMesh.setObject( iSurf ) ;

MDataHandle outputData = data.outputValue(plug);
outputData.copy(inputData);
if (outputData.type() != MFnData::kMesh) {
    //printf("Incorrect output mesh type\n");
    return MStatus::kFailure;
}

MObject oSurf = outputData.asMesh() ;
if(oSurf.isNull()) {
    //printf("Output surface is NULL\n");
    return MStatus::kFailure;
}

MFnMesh outMesh;
outMesh.setObject( oSurf ) ;
//MCheckStatus(status, "ERROR setting points\n");

MDataHandle envData = data.inputValue(envelope, &status);
float env = envData.asFloat();  

MPlug gsPlug(thisNode,aGlobalScale);
MDataHandle globalScaleData = data.inputValue(gsPlug, &status);
float gScale = globalScaleData.asFloat();

//float gScale = 1.0;

// get the driver geometry
MArrayDataHandle driverArray = data.inputArrayValue(aDriverGeometry);
unsigned driverNum = driverArray.elementCount();
//cerr << "Number of driver geo: " << driverNum << endl;

// get all points at once for demo purposes. Really should get points from the current group using iterator
MFloatPointArray pts;
outMesh.getPoints(pts);

//  store Pnts attribute in an array data handle
MArrayDataHandle pntsArrayHandle = data.inputArrayValue(aPnts, &status);
unsigned pntsNum = pntsArrayHandle.elementCount();
//cerr << "Number of pnts attributes: " << pntsNum << endl;


//  loop through points to derive final positions
if(pntsNum)
{
    int nPoints = pts.length();

    // NOTE: Using MTimer and possibly other classes disables
    // autovectorization with Intel <=10.1 compiler on OSX and Linux!!
    // Must compile this function with -fno-exceptions on OSX and
    // Linux to guarantee autovectorization is done. Use -fvec_report2
    // to check for vectorization status messages with Intel compiler.
    //MTimer timer; timer.beginTimer();

    for(int i=0; i<nPoints; i++)
    {
        unsigned j;

        //  GET POINT POSITION IN WORLD SPACE
        MFloatPoint& pt = pts[i];

        pntsArrayHandle.jumpToArrayElement(i);

        //  store uvCoord attribute in an array data handle
        MDataHandle uvcHandle = pntsArrayHandle.inputValue(&status).child(aUVCoord);
        MArrayDataHandle uvcArrayHandle(uvcHandle, &status);
        //unsigned uvcNum = uvcArrayHandle.elementCount();
        //cerr << "Number of uvc attributes: " << uvcNum << endl;

        //  store offsets attribute in an array data handle
        MDataHandle offsetsHandle = pntsArrayHandle.inputValue(&status).child(aOffsets);
        MArrayDataHandle offsetsArrayHandle(offsetsHandle, &status);
        //unsigned offsetsNum = offsetsArrayHandle.elementCount();
        //cerr << "Number of offsets attributes: " << offsetsNum << endl;

        MPoint finalPt;
        for( j = 0; j < driverNum ; j++) 
        {
            //  get stored weights
            float weight = geoCluster::weightValue(data, i, j);

            if(weight != 0)
            {
                //  get uv coordinate
                uvcArrayHandle.jumpToArrayElement(j);
                double2& uv = uvcArrayHandle.inputValue(&status).asDouble2();
                float uCoord = uv[0];
                float vCoord = uv[1];
                //cerr << "UV Coord: " << uCoord << " " << vCoord << endl;
                //fprintf(stderr, "pnts[%d][%d] = %g, %g\n",i,j,uCoord,vCoord);

                //  get nurbsSurface world space position and normal from uv coordinates
                driverArray.jumpToArrayElement(j);
                MFnNurbsSurface nurbs = driverArray.inputValue(&status).asNurbsSurface();
                MPoint nurbsPt;
                nurbs.getPointAtParam(uCoord, vCoord, nurbsPt, MSpace::kWorld);
                MVector normal = nurbs.normal(uCoord, vCoord, MSpace::kWorld);

                //  get offset value
                offsetsArrayHandle.jumpToArrayElement(j);
                float offset = offsetsArrayHandle.inputValue(&status).asFloat();
                //cerr << "OFFSET: " << offset << endl;
                //fprintf(stderr, "pnts[%d][%d] = %g\n",i,j,offset);

                finalPt[0] += (nurbsPt[0] + (normal.x * offset * gScale)) * weight;
                finalPt[1] += (nurbsPt[1] + (normal.y * offset * gScale)) * weight;
                finalPt[2] += (nurbsPt[2] + (normal.z * offset * gScale)) * weight;
            }
        }
        //cerr << "\n" << endl;


        for(int k=0; k<3; k++)
        {
            pt[k] += env * (finalPt[k] - pt[k]);
        }

    }   //  end of pts loop


    //timer.endTimer(); 
    //printf("geoCluster, runtime %f\n", timer.elapsedTime());

    outMesh.setPoints(pts);

}   //  end of pnts attribute condition

return status;

}

NN comments
manny
-

Is anyone out there? :)

or Cancel

2 answers

0

julian [ Admin ]

Hi Manny,

In your code are you testing each point against many components of a piece of muscle geometry? That could slow it down. There are ways to optimize though. I'm sure if you can post some code up here - the deform() function - or link to the src, someone will he happy to have a look.

NN comments
manny
-

Hi Julian,

I’ll post some code when I get home tonight. There’s another issue with my first stab at a deformer. I used a Maya example and hacked at it to do what I wanted. But I only get one weight per vertex. I store a weight per influence but in Maya’s component editor, I can’t get to it. I was going to write my own editor but I’m sure there’s a way to do this correctly. This is what I mean by optimizing my approach. I just don’t know what all is in the API.

manny
-

I’m using nurbs with history to deform a mesh. I’ve been using skinClusters and adding my nurbs as influences for a long time. But it ends up being slow when more nurbs are used. So I thought it should be faster if I wrote my own that skipped the skinCluster all together. Also, I thought if I recorded/initialized uv values, then I wouldn’t have to look for closest point on the fly. But again, the resulting plugin was slower than my old skinCluster with nurbs influences. And I lost the ability to weight my influences.

manny
-

MStatus geoCluster::compute(const MPlug& plug, MDataBlock& data) {

MStatus status;

//MString plugName;
//plugName = plug.name();
//cerr << "PLUG NAME: " << plugName.asChar() << endl;

if (plug.attribute() != outputGeom) {
    //printf("Ignoring requested plug\n");
    return status;
}
unsigned int index = plug.logicalIndex();
MObject thisNode = this->thisMObject();

// get input value
MPlug inPlug(thisNode,input);
inPlug.selectAncestorLogicalIndex(index,input);
MDataHandle hInput = data.inputValue(inPlug, &status);
//MCheckStatus(status, "ERROR getting input mesh\n");
manny
-

Julian, you can see I just tried to post some lines of code but it’s missing the carriage returns. What’s the secret?

julian
-

You can edit the original question and post the coe there. Then you get the full syntax hi-lighting and everything.

julian
-

You can edit the original question and post the code there. Then you get the full syntax hi-lighting and everything.

or Cancel

Your answer

You need to join VFX Overflow to complete this action, click here to do so.