#include <maya/MPxDeformerNode.h>
#include <maya/MItGeometry.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnPlugin.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MPoint.h>
#include <maya/MPxGPUStandardDeformer.h>
#include <maya/MGPUDeformerRegistry.h>
#include <maya/MOpenCLBuffer.h>
#include <maya/MOpenCLInfo.h>
#include <maya/MOpenCLUtils.h>
#include <clew/clew.h>
{
public:
testFailure();
~testFailure() override;
static void* creator();
unsigned int multiIndex) override;
public:
private:
};
MTypeId testFailure::id( 0x0000007D );
MObject testFailure::aFailureTrigger;
MObject testFailure::aForceDifference;
testFailure::testFailure() {}
testFailure::~testFailure() {}
void* testFailure::creator()
{
return new testFailure();
}
{
addAttribute( aOffset );
addAttribute( aFailureTrigger );
addAttribute( aForceDifference );
attributeAffects( testFailure::aOffset, testFailure::outputGeom );
attributeAffects( testFailure::aFailureTrigger, testFailure::outputGeom );
attributeAffects( testFailure::aForceDifference, testFailure::outputGeom );
}
unsigned int multiIndex)
{
if (MS::kSuccess != returnStatus)
return returnStatus;
float3& offsetVal = offsetData.
asFloat3();
float e = env*weightValue(block,multiIndex,iter.
index());
}
return returnStatus;
}
{
public:
testFailureGPUDeformer();
~testFailureGPUDeformer() override;
private:
float3 fOffset;
bool fForceDifference{false};
};
{
public:
testFailureNodeGPUDeformerInfo() {}
~testFailureNodeGPUDeformerInfo() override{}
{
return new testFailureGPUDeformer();
}
{
return true;
}
{
return true;
}
};
{
static testFailureNodeGPUDeformerInfo theOne;
return &theOne;
}
testFailureGPUDeformer::testFailureGPUDeformer()
{
}
testFailureGPUDeformer::~testFailureGPUDeformer()
{
terminate();
}
cl_int testFailureGPUDeformer::enqueueDeformation(
{
cl_int err = CL_SUCCESS;
unsigned int count = affectCount();
MGPUEventList eventList;
eventList.
add(syncInputEvent);
cl_float3 offset;
offset.s[0] = fOffset[0] + (fForceDifference ? 1.0 : 0.0);
offset.s[1] = fOffset[1];
offset.s[2] = fOffset[2];
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_float>(parameterId++, envelope(), err);
err = fKernelInfo.setKernelArg<cl_float3>(parameterId++, offset, err);
err = fKernelInfo.setKernelArg<cl_uint>(parameterId++, count, err);
return CL_SUCCESS == err ? fKernelInfo.enqueueKernel(eventList, syncEvent) : err;
}
MPxGPUDeformer::DeformerStatus testFailureGPUDeformer::evaluate(
)
{
MPxGPUDeformer::DeformerStatus ds = prepareEvaluation(block, evaluationNode, plug, inputPlugs, inputData, outputData, syncEvent);
if (ds != MPxGPUDeformer::kDeformerSuccess)
return ds;
prepareAffectMapBuffer();
prepareWeightsBuffer(evaluationNode);
const float3& val = offsetData.
asFloat3();
fOffset[0] = val[0];
fOffset[1] = val[1];
fOffset[2] = val[2];
float failureTrigger = (MS::kSuccess != status) ? 0.0 : failureTriggerData.
asFloat();
fForceDifference = block.
inputValue(testFailure::aForceDifference, &status ).
asBool();
if (failureTrigger <= -1.0) {
return MPxGPUDeformer::kDeformerRetryMainThread;
} else if (failureTrigger >= 1.0) {
return MPxGPUDeformer::kDeformerFailure;
}
MString openCLKernelFile = testFailure::pluginPath +
"/testFailure.cl";
MString openCLKernelName(
"testFailure");
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 testFailureGPUDeformer::terminate()
{
fKernelInfo.reset();
}
{
MFnPlugin plugin( obj, PLUGIN_COMPANY,
"3.0",
"Any");
result = plugin.registerNode( "testFailure", testFailure::id, testFailure::creator,
MString nodeClassName(
"testFailure");
MString registrantId(
"mayaPluginExample");
nodeClassName,
registrantId,
testFailureGPUDeformer::getGPUDeformerInfo());
testFailure::pluginPath = plugin.loadPath();
return result;
}
{
MString nodeClassName(
"testFailure");
MString registrantId(
"mayaPluginExample");
nodeClassName,
registrantId);
result = plugin.deregisterNode(testFailure::id);
return result;
}