#include <maya/MIOStream.h>
#include <maya/MPxGeometryFilter.h>
#include <maya/MItGeometry.h>
#include <maya/MFnPlugin.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MPoint.h>
#include <maya/MTimer.h>
#include <maya/MFnMesh.h>
#include <maya/MPointArray.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnMeshData.h>
#include <maya/MMeshIntersector.h>
#include <maya/MThreadUtils.h>
#include <tbb/blocked_range.h>
#include <tbb/parallel_for.h>
#define MCheckStatus(status,message) \
if( MStatus::kSuccess != status ) { \
cerr << message << "\n"; \
return status; \
}
{
public:
splatDeformer();
~splatDeformer() override;
static void* creator();
public:
private:
};
MTypeId splatDeformer::id( 0x8104D );
MObject splatDeformer::deformingMesh;
MObject splatDeformer::parallelEnabled;
splatDeformer::splatDeformer() {}
splatDeformer::~splatDeformer() {}
void* splatDeformer::creator()
{
return new splatDeformer();
}
MStatus splatDeformer::initialize()
{
status = addAttribute( deformingMesh );
MCheckStatus(status, "ERROR in addAttribute(deformingMesh)\n");
status = addAttribute( parallelEnabled );
MCheckStatus(status, "ERROR in addAttribute(parallelEnabled)\n");
status = attributeAffects( deformingMesh, outputGeom );
MCheckStatus(status, "ERROR in attributeAffects(deformingMesh)\n");
status = attributeAffects( parallelEnabled, outputGeom );
MCheckStatus(status, "ERROR in attributeAffects(parallelEnabled)\n");
}
{
MObject thisNode = this->thisMObject();
{
printf("Ignoring requested plug\n");
return status;
}
{
MPlug inPlug(thisNode,input);
MCheckStatus(status, "ERROR getting input mesh\n");
{
do
{
MCheckStatus(status, "ERROR getting input mesh element\n");
MCheckStatus(status, "ERROR getting input mesh element index\n");
computeOneOutput( inputIndex, data, hInputElement );
}
}
else
{
MPlug inPlug(thisNode,input);
inPlug.selectAncestorLogicalIndex(plug.
logicalIndex(),input);
MCheckStatus(status, "ERROR getting input mesh\n");
}
return status;
}
template<typename Value>
class cancelable_range {
tbb::blocked_range<Value> my_range;
volatile bool& my_stop;
public:
cancelable_range( int begin, int end, int grainsize, volatile bool& stop ) :
my_range(begin,end,grainsize),
my_stop(stop)
{}
cancelable_range( cancelable_range& r, tbb::split ) :
my_range(r.my_range,tbb::split()),
my_stop(r.my_stop)
{}
cancelable_range & operator=( const cancelable_range & );
void cancel() const {my_stop=true;}
bool empty() const {return my_stop || my_range.empty();}
bool is_divisible() const {return !my_stop && my_range.is_divisible();}
Value begin() const {return my_range.begin();}
Value end() const {return my_stop ? my_range.begin() : my_range.end();}
};
{
MObject thisNode = this->thisMObject();
MPlug outPlug(thisNode, outputGeom);
outPlug.selectAncestorLogicalIndex(index, outputGeom);
{
printf("Incorrect input geometry type\n");
}
unsigned int lGroupId = hGroup.
asInt();
MCheckStatus(status, "ERROR getting deforming mesh\n");
{
printf(
"Incorrect deformer geometry type %d\n", deformData.
type());
}
{
printf("Incorrect output mesh type\n");
}
{
printf("Input surface is NULL\n");
}
MCheckStatus(status, "ERROR setting points\n");
iter.allPositions(verts);
unsigned int nPoints = verts.
length();
volatile bool failed = false;
bool lParallelEnabled = (bool) parallelEnabledData.
asBool();
if( lParallelEnabled )
{
bool stop = false;
tbb::parallel_for( cancelable_range<unsigned int>(0,nPoints,nPoints/1000,stop),
[&](const cancelable_range<unsigned int>& r)
{
for(unsigned int i = r.begin(); i < r.end(); ++i)
{
{
failed = true;
r.cancel();
}
else
{
}
}
});
}
else
{
for(unsigned int i=0; i<nPoints; ++i )
{
{
failed = true;
break;
}
}
}
timer.
endTimer(); printf(
"Runtime for %s loop %f\n", lParallelEnabled ?
"parallel" :
"serial", timer.
elapsedTime() );
iter.setAllPositions(verts);
if(failed)
{
printf("Closest point failed\n");
}
return status;
}
{
MFnPlugin plugin( obj, PLUGIN_COMPANY,
"1.0",
"Any");
result = plugin.registerNode( "splatDeformer", splatDeformer::id, splatDeformer::creator,
return result;
}
{
result = plugin.deregisterNode( splatDeformer::id );
return result;
}