#include <maya/MPxDeformerNode.h>
#include <maya/MItGeometry.h>
#include <maya/MPxLocatorNode.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnMatrixAttribute.h>
#include <maya/MFnMatrixData.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MPoint.h>
#include <maya/MPointArray.h>
#include <maya/MVector.h>
#include <maya/MMatrix.h>
#include <maya/MDagModifier.h>
#include <maya/MPxGPUStandardDeformer.h>
#include <maya/MGPUDeformerRegistry.h>
#include <maya/MOpenCLBuffer.h>
#include <maya/MOpenCLInfo.h>
#include <maya/MOpenCLUtils.h>
#include <cassert>
{
public:
simpleDeformer();
~simpleDeformer() override;
static void* creator();
unsigned int multiIndex) override;
public:
private:
};
MTypeId simpleDeformer::id( 0x8000f );
MObject simpleDeformer::locatorMatrix;
MString simpleDeformer::pluginPath;
simpleDeformer::simpleDeformer() {}
simpleDeformer::~simpleDeformer() {}
void* simpleDeformer::creator()
{
return new simpleDeformer();
}
MStatus simpleDeformer::initialize()
{
locatorMatrix=mAttr.
create(
"locatorMatrix",
"lm");
addAttribute( locatorMatrix);
attributeAffects( simpleDeformer::locatorMatrix, simpleDeformer::outputGeom );
}
unsigned int multiIndex)
{
if (MS::kSuccess != returnStatus)
return returnStatus;
float deformerEnvelope = envData.
asFloat();
if (MS::kSuccess != returnStatus) return returnStatus;
unsigned int numWeights;
const float* vertWeights = envelopeWeights(block, multiIndex, &numWeights);
assert(
nullptr == vertWeights || numWeights == mapper.
affectCount());
unsigned int aid = 0;
for (aid = 0; aid < affectCount; ++aid) {
float weight = (vertWeights ? vertWeights[aid]*deformerEnvelope : deformerEnvelope);
pt += weight * (newPt - pt);
}
return returnStatus;
}
simpleDeformer::accessoryAttribute() const
{
return simpleDeformer::locatorMatrix;
}
{
&result);
if (MS::kSuccess == result) {
MObject attrMat = fnLoc.attribute(attrName);
result = cmd.
connect(objLoc,attrMat,this->thisMObject(),simpleDeformer::locatorMatrix);
}
return result;
}
{
public:
simpleGPUDeformer();
~simpleGPUDeformer() override;
private:
cl_float16 fLocatorMatrix;
};
{
public:
simpleDeformerNodeGPUDeformerInfo() {}
~simpleDeformerNodeGPUDeformerInfo() override{}
{
return new simpleGPUDeformer();
}
{
return simpleGPUDeformer::validateNodeInGraph(block, evaluationNode, plug, messages);
}
{
return simpleGPUDeformer::validateNodeValues(block, evaluationNode, plug, messages);
}
};
{
static simpleDeformerNodeGPUDeformerInfo theOne;
return &theOne;
}
simpleGPUDeformer::simpleGPUDeformer()
{
}
simpleGPUDeformer::~simpleGPUDeformer()
{
terminate();
}
{
return true;
}
{
return true;
}
bool simpleGPUDeformer::extractLocatorMatrix(
MDataBlock& block)
{
if (MS::kSuccess != status)
return false;
float matrixData[4][4];
if( !omat.
get( matrixData ) )
return false;
memcpy( fLocatorMatrix.s, matrixData, sizeof(matrixData));
return true;
}
cl_int simpleGPUDeformer::enqueueDeformation(
{
cl_int err = CL_SUCCESS;
unsigned int count = affectCount();
MGPUEventList eventList;
eventList.
add(syncInputEvent);
unsigned int parameterId = 0;
err = fKernelInfo.setKernelArgBuffer(parameterId++, outputPositions.
buffer(), err);
err = fKernelInfo.setKernelArgBuffer(parameterId++, inputPositions.
buffer(), err);
err = fKernelInfo.setKernelArgBuffer(parameterId++, weightsBuffer(), err, hasEnvelopeWeights());
err = fKernelInfo.setKernelArgBuffer(parameterId++, affectMapBuffer(), err, !isIdentityMap());
err = fKernelInfo.setKernelArg<cl_float16>(parameterId++, fLocatorMatrix, err);
err = fKernelInfo.setKernelArg<cl_float>(parameterId++, envelope(), err);
err = fKernelInfo.setKernelArg<cl_uint>(parameterId++, count, err);
return CL_SUCCESS == err ? fKernelInfo.enqueueKernel(eventList, syncEvent) : err;
}
MPxGPUDeformer::DeformerStatus simpleGPUDeformer::evaluate(
)
{
MPxGPUDeformer::DeformerStatus ds = prepareEvaluation(block, evaluationNode, plug, inputPlugs, inputData, outputData, syncEvent);
if (ds != MPxGPUDeformer::kDeformerSuccess)
return ds;
prepareAffectMapBuffer();
prepareWeightsBuffer(evaluationNode);
if (!extractLocatorMatrix(block))
return MPxGPUDeformer::kDeformerFailure;
MString openCLKernelFile = simpleDeformer::pluginPath +
"/simpleDeformer.cl";
MString openCLKernelName(
"simpleDeformer");
if (!fKernelInfo.loadOrUpdate(openCLKernelFile, openCLKernelName, affectCount()))
return MPxGPUDeformer::kDeformerFailure;
cl_int err = CL_SUCCESS;
err = initializeOutputPositions(syncEvent);
if ( err != CL_SUCCESS )
return MPxGPUDeformer::kDeformerFailure;
err = enqueueDeformation(syncEvent, inputPositions(), outputPositions());
if ( err != CL_SUCCESS )
return MPxGPUDeformer::kDeformerFailure;
return finishEvaluation(syncEvent, outputData);
}
void simpleGPUDeformer::terminate()
{
fKernelInfo.reset();
}
{
MFnPlugin plugin( obj, PLUGIN_COMPANY,
"3.0",
"Any");
result = plugin.registerNode( "simpleDeformer", simpleDeformer::id, simpleDeformer::creator,
MString nodeClassName(
"simpleDeformer");
MString registrantId(
"mayaPluginExample");
nodeClassName,
registrantId,
simpleGPUDeformer::getGPUDeformerInfo());
simpleDeformer::pluginPath = plugin.loadPath();
return result;
}
{
MString nodeClassName(
"simpleDeformer");
MString registrantId(
"mayaPluginExample");
nodeClassName,
registrantId);
result = plugin.deregisterNode(simpleDeformer::id);
return result;
}