#include "smoothFalloffNode.h"
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnFalloffData.h>
#include <maya/MFnMesh.h>
#include <maya/MIndexMapper.h>
#include <vector>
const MTypeId SmoothFalloffNode::id(0x0008006F);
const MString SmoothFalloffNode::typeName(
"exampleSmoothFalloff");
MObject SmoothFalloffNode::aSmoothFactor;
MObject SmoothFalloffNode::aFalloffInput;
MObject SmoothFalloffNode::aFalloffOutput;
MObject SmoothFalloffNode::aIteration;
MObject SmoothFalloffNode::aSyncId;
SmoothFalloffNode::SmoothFalloffNode(){}
SmoothFalloffNode::~SmoothFalloffNode(){}
void* SmoothFalloffNode::creator()
{
return new SmoothFalloffNode{};
}
MStatus SmoothFalloffNode::initialize()
{
status = attributeAffects( aFalloffInput, aFalloffOutput );
status = attributeAffects( aSmoothFactor, aFalloffOutput );
status = attributeAffects( aIteration, aFalloffOutput );
}
MStatus SmoothFalloffNode::uninitialize()
{
}
{
public:
struct VertInfo{
unsigned int vertId;
double weight;
};
SmoothFalloff(
MPxNode* node,
MObject inputFalloff,
double smoothFactor,
int iter,
int syncId)
:mNode(node)
,mInput(inputFalloff)
,mSmoothFactor(smoothFactor)
,mIter(iter)
,mSyncId(syncId)
{}
{
std::vector<std::vector<VertInfo>> vertConnections(mapper.
affectCount());
for(int i = 0; i < numEdges; ++i){
int2 vs;
auto v0 = mapper.
fullToAffect(vs[0]);
auto v1 = mapper.fullToAffect(vs[1]);
if(v0 != MIndexMapper::InvalidIndex && v1 != MIndexMapper::InvalidIndex){
vertConnections[v0].emplace_back(VertInfo{v1, invert_d});
vertConnections[v1].emplace_back(VertInfo{v0, invert_d});
}
}
for(auto &v : vertConnections){
double sumWeight = 0;
for(auto& info: v){
sumWeight += info.weight;
}
for(auto& info: v){
info.weight /= sumWeight;
}
}
const auto OneMinusFactor = 1.0 - mSmoothFactor;
if (mIter < 0) mIter = 0;
if (mIter > 20) mIter = 20;
for(int iteration = 0; iteration < mIter; ++iteration){
initial = inOut;
for(
unsigned i = 0; i < initial.
length(); ++i){
double averageNeighbours = 0.0;
for(const auto& vertInfo : vertConnections[i]){
averageNeighbours += initial[vertInfo.vertId] * vertInfo.weight;
}
if(vertConnections[i].size() > 0)
inOut[i] = (initial[i] * OneMinusFactor) + (mSmoothFactor * averageNeighbours);
}
}
}
auto rv = inputFoff.call(accessor);
rv.getCachedIndicator() == MFalloffFunction::ReturnValue::Cached &&
accessor.
isSync(mSyncId,bufferId))
{
return ReturnValue{bufferId, rv.getRequirement(), ReturnValue::Cached};
}
return rv;
}
if(mIter > 0 && mSmoothFactor > 0.0)
doSmooth(initial, mesh, mapper);
accessor.
sync(mSyncId, bufferId);
return ReturnValue{bufferId, rv.getRequirement(), ReturnValue::NotCached};
}
double mSmoothFactor;
int mIter;
int mSyncId;
};
{
}
return MS::kSuccess;
}