#include <string.h>
#include <maya/MIOStream.h>
#include <maya/MStringArray.h>
#include <math.h>
#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/MArrayDataHandle.h>
#include <maya/MPoint.h>
#include <maya/MVector.h>
#include <maya/MMatrix.h>
#include <maya/MDagModifier.h>
#include <maya/MPxGPUDeformer.h>
#include <maya/MGPUDeformerRegistry.h>
#include <maya/MOpenCLInfo.h>
#include <maya/MViewport2Renderer.h>
#include <maya/MFnMesh.h>
#include <clew/clew_cl.h>
#include <vector>
{
public:
offset();
~offset() override;
static void* creator();
unsigned int multiIndex) override;
public:
private:
};
offset::offset() {}
offset::~offset() {}
void* offset::creator()
{
return new offset();
}
{
offsetMatrix=mAttr.
create(
"locateMatrix",
"lm");
addAttribute( offsetMatrix);
attributeAffects( offset::offsetMatrix, offset::outputGeom );
}
unsigned int multiIndex)
{
if (MS::kSuccess != returnStatus) return returnStatus;
if (MS::kSuccess != returnStatus) return returnStatus;
pt *= omatinv;
float weight = weightValue(block,multiIndex,iter.
index());
pt.
y = pt.
y + env*weight;
pt *= omat;
}
return returnStatus;
}
offset::accessoryAttribute() const
{
return offset::offsetMatrix;
}
{
&result);
if (MS::kSuccess == result) {
MObject attrMat = fnLoc.attribute(attrName);
result = cmd.
connect(objLoc,attrMat,this->thisMObject(),offset::offsetMatrix);
}
return result;
}
{
public:
offsetGPUDeformer();
~offsetGPUDeformer() override;
private:
unsigned int fNumElements;
};
{
public:
offsetNodeGPUDeformerInfo(){}
~offsetNodeGPUDeformerInfo() override{}
{
return new offsetGPUDeformer();
}
{
return offsetGPUDeformer::validateNodeInGraph(block, evaluationNode, plug, messages);
}
{
return offsetGPUDeformer::validateNodeValues(block, evaluationNode, plug, messages);
}
};
{
static offsetNodeGPUDeformerInfo theOne;
return &theOne;
}
offsetGPUDeformer::offsetGPUDeformer()
{
}
offsetGPUDeformer::~offsetGPUDeformer()
{
terminate();
}
{
return true;
}
{
envelopePlug.getValue(envData);
{
MOpenCLInfo::appendMessage(messages,
"Offset %s not supported by deformer evaluator because envelope is not exactly 1.0.", fnNode.name().asChar());
return false;
}
return true;
}
MPxGPUDeformer::DeformerStatus offsetGPUDeformer::evaluate(
unsigned int numElements,
{
fNumElements = numElements;
extractWeightArray(block, evaluationNode, plug);
extractOffsetMatrix(block, evaluationNode, plug);
if (!fKernel.get())
{
char *maya_location = getenv( "MAYA_LOCATION" );
MString openCLKernelFile(maya_location);
openCLKernelFile +="/../Extra/devkitBase/devkit/plug-ins/offsetNode/offset.cl";
MString openCLKernelName(
"offset");
if (!fKernel) return MPxGPUDeformer::kDeformerFailure;
}
cl_int err = CL_SUCCESS;
unsigned int parameterId = 0;
err = clSetKernelArg(fKernel.get(), parameterId++, sizeof(cl_mem), (void*)outputBuffer.getReadOnlyRef());
err = clSetKernelArg(fKernel.get(), parameterId++, sizeof(cl_mem), (void*)inputBuffer.getReadOnlyRef());
err = clSetKernelArg(fKernel.get(), parameterId++, sizeof(cl_mem), (void*)fCLWeights.getReadOnlyRef());
err = clSetKernelArg(fKernel.get(), parameterId++, sizeof(cl_mem), (void*)fOffsetMatrix.getReadOnlyRef());
err = clSetKernelArg(fKernel.get(), parameterId++, sizeof(cl_uint), (void*)&fNumElements);
size_t workGroupSize;
size_t retSize;
err = clGetKernelWorkGroupInfo(
fKernel.get(),
CL_KERNEL_WORK_GROUP_SIZE,
sizeof(size_t),
&workGroupSize,
&retSize);
size_t localWorkSize = 256;
if (retSize > 0) localWorkSize = workGroupSize;
size_t globalWorkSize = (localWorkSize - fNumElements % localWorkSize) + fNumElements;
unsigned int numInputEvents = 0;
if (inputEvent.get())
{
numInputEvents = 1;
}
err = clEnqueueNDRangeKernel(
fKernel.get(),
1,
NULL,
&globalWorkSize,
&localWorkSize,
numInputEvents,
return MPxGPUDeformer::kDeformerSuccess;
}
void offsetGPUDeformer::terminate()
{
fCLWeights.reset();
fOffsetMatrix.reset();
fKernel.reset();
}
{
{
return;
}
std::vector<float> temp;
temp.reserve(fNumElements);
if (!status) return;
if (!status)
{
for(unsigned int i=0; i<fNumElements; i++)
temp.push_back(1.0f);
}
else
{
if (!status) return;
if (!status) return;
if (!status) return;
unsigned int weightIndex = 0;
for(
unsigned int i=0; i<numWeights; i++, weights.
next())
{
unsigned int weightsElementIndex = weights.
elementIndex(&status);
while (weightIndex < weightsElementIndex)
{
temp.push_back(0.0f);
weightIndex++;
}
weightIndex++;
}
while (weightIndex < fNumElements)
{
temp.push_back(0.0f);
weightIndex++;
}
}
cl_int err = CL_SUCCESS;
if (!fCLWeights.get())
{
fCLWeights.attach(clCreateBuffer(
MOpenCLInfo::getOpenCLContext(), CL_MEM_COPY_HOST_PTR | CL_MEM_READ_ONLY, fNumElements *
sizeof(
float), (
void*)&temp[0], &err));
}
else
{
}
}
{
if ((fOffsetMatrix.get() && !evaluationNode.
dirtyPlugExists(offset::offsetMatrix, &status)) || !status)
{
return;
}
if (MS::kSuccess != status) return;
unsigned int numFloat = 32;
float* temp = new float[numFloat];
unsigned int curr = 0;
for(unsigned int row = 0; row<4; row++)
{
for(unsigned int column = 0; column<4; column++)
{
temp[curr++] = (float)omat(row, column);
}
}
for(unsigned int row = 0; row<4; row++)
{
for(unsigned int column = 0; column<4; column++)
{
temp[curr++] = (float)omatinv(row, column);
}
}
cl_int err = CL_SUCCESS;
if (!fOffsetMatrix.get())
{
fOffsetMatrix.attach(clCreateBuffer(
MOpenCLInfo::getOpenCLContext(), CL_MEM_COPY_HOST_PTR | CL_MEM_READ_ONLY, numFloat *
sizeof(
float), (
void*) temp, &err));
}
else
{
}
delete [] temp;
}
{
MFnPlugin plugin( obj, PLUGIN_COMPANY,
"3.0",
"Any");
result = plugin.registerNode( "offset", offset::id, offset::creator,
MString registrantId(
"mayaPluginExample");
nodeClassName,
registrantId,
offsetGPUDeformer::getGPUDeformerInfo());
nodeClassName,
registrantId,
return result;
}
{
result = plugin.deregisterNode( offset::id );
MString registrantId(
"mayaPluginExample");
nodeClassName,
registrantId);
return result;
}