#include "testMTopologyEvaluator.h"
#include <maya/MDataHandle.h>
#include <maya/MEvaluationNode.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MGraphNodeIterator.h>
#include <maya/MPlugArray.h>
#include <maya/MProfiler.h>
#include <maya/MString.h>
#include <maya/MFnPlugin.h>
#include <functional>
namespace
{
const unsigned _numberOfAttr = 100;
int _profilerCategory =
MProfiler::addCategory(
"testMTopologyEvaluator",
"Events related to the testMTopologyEvaluator");
{
MPlug thisPlug = testNode.findPlug(attrInput,
true, &stat);
if (thisPlug.isNull())
return ownerEvaluationNode;
return ownerEvaluationNode;
for(
int i = 0; i < ownerEvaluationNode.
parentCount(); i++)
{
if (srcPlug.
node() == parentNode.dependencyNode(&stat))
{
return parentNode;
}
}
return ownerEvaluationNode;
}
{
MPlug thisPlug = testNode.findPlug(attrOutput,
true, &stat);
if (thisPlug.isNull())
return ownerEvaluationNode;
if ( !thisPlug.destinationsWithConversions(dstPlugs) || dstPlugs.
length() != 1)
return ownerEvaluationNode;
MPlug dstPlug = dstPlugs[0];
for (
int i = 0; i < ownerEvaluationNode.
childCount(); i++)
{
if (dstPlug.
node() == childNode.dependencyNode(&stat))
{
return childNode;
}
}
return ownerEvaluationNode;
}
}
MTypeId TestMTopologyEvaluator_Node::id( 0x80000, 0x7d );
std::vector<MObject> TestMTopologyEvaluator_Node::attrInputs;
std::vector<MObject> TestMTopologyEvaluator_Node::attrOutputs;
MObject TestMTopologyEvaluator_Node::attrComputeCount;
MObject TestMTopologyEvaluator_Node::attrPushComputeCount;
MObject TestMTopologyEvaluator_Node::attrDoPushCompute;
{
}
{
for (int i = 0; i < attrOutputs.size(); i++)
{
auto& outputPlug = attrOutputs[i];
if (plug != outputPlug)
continue;
double inputOutputOffset = 5;
double outputVal = inputDouble.
asDouble();
outputVal += inputOutputOffset;
computeCount++;
return stat;
}
}
{
for (int i = 0; i < attrOutputs.size(); i++)
{
auto& outputPlug = attrOutputs[i];
if (plug != outputPlug)
continue;
computeCount = 0;
break;
}
return ParentClass::setDependentsDirty(plug, plugArray);
}
{
computeCount = 0;
return ParentClass::preEvaluation(context, evaluationNode);
}
bool TestMTopologyEvaluator_Node::setInternalValue(
const MPlug& plug,
const MDataHandle& handle)
{
if (plug == attrDoPushCompute)
{
doPushComputeOverride = handle.
asBool();
return true;
}
return ParentClass::setInternalValue(plug, handle);
}
bool TestMTopologyEvaluator_Node::getInternalValue(
const MPlug& plug,
MDataHandle& handle)
{
if (plug == attrComputeCount)
{
return true;
}
else if (plug == attrPushComputeCount) {
handle.
setInt(pushComputeCount);
return true;
}
else if (plug == attrDoPushCompute) {
handle.
setBool(doPushComputeOverride);
return true;
}
return ParentClass::getInternalValue(plug, handle);
}
void* TestMTopologyEvaluator_Node::creator()
{
return new TestMTopologyEvaluator_Node();
}
MStatus TestMTopologyEvaluator_Node::initialize() {
attrInputs.reserve(_numberOfAttr);
for (auto i = 0; i < _numberOfAttr; i++)
{
attrLongName = "input";
attrShortName = "in";
attrLongName += (i+1);
attrShortName += (i+1);
}
attrOutputs.reserve(_numberOfAttr);
for (auto i = 0; i < _numberOfAttr; i++)
{
attrLongName = "output";
attrShortName = "out";
attrLongName += (i+1);
attrShortName += (i+1);
}
attrLongName = "computeCount";
attrShortName = "cct";
attrLongName = "pushComputeCount";
attrShortName = "pcc";
attrLongName = "doPushCompute";
attrShortName = "dpc";
for (auto i = 0; i < _numberOfAttr; i++)
{
stat = addAttribute(attrInputs[i]);
stat = addAttribute(attrOutputs[i]);
stat = attributeAffects(attrInputs[i], attrOutputs[i]);
}
stat = addAttribute(attrComputeCount);
stat = addAttribute(attrPushComputeCount);
stat = addAttribute(attrDoPushCompute);
return MS::kSuccess;
}
{
MFnPlugin plugin( obj,
"Autodesk",
"3.0",
"Any");
status = plugin.registerNode( "TestMTopologyEvaluator_Node", TestMTopologyEvaluator_Node::id, TestMTopologyEvaluator_Node::creator, TestMTopologyEvaluator_Node::initialize );
if (!status) {
status.
perror(
"registerNode");
return status;
}
status = plugin.registerEvaluator("TestMTopologyEvaluator", 40 , TestMTopologyEvaluator_Evaluator::creator);
if (!status)
{
status.
perror(
"registerEvaluator");
return status;
}
return status;
}
{
status = plugin.deregisterEvaluator("TestMTopologyEvaluator");
if (!status)
{
status.
perror(
"deregisterEvaluator");
return status;
}
status = plugin.deregisterNode(TestMTopologyEvaluator_Node::id );
if (!status) {
status.
perror(
"deregisterNode");
return status;
}
return status;
}
TestMTopologyEvaluator_Evaluator::~TestMTopologyEvaluator_Evaluator()
{
}
bool TestMTopologyEvaluator_Evaluator::markIfSupported(
const MEvaluationNode* node)
{
MObject owner = node->dependencyNode(&stat);
{
return (depNode.typeId() == TestMTopologyEvaluator_Node::id);
}
return false;
}
void* TestMTopologyEvaluator_Evaluator::creator()
{
return new TestMTopologyEvaluator_Evaluator();
}
{
for (; (stat == MS::kSuccess) && !iterator.isDone(); iterator.next(&stat))
{
if (stat == MS::kSuccess)
{
TestMTopologyEvaluator_Node* testNode = static_cast<TestMTopologyEvaluator_Node*>(testNodeFn.userNode());
if (!testNode)
continue;
std::function<void()> initExecFn = [testNode, currEvalNode]()
{
MProfilingScope profilingScopeForInit(_profilerCategory, MProfiler::kColorD_L1,
"Reset counters");
testNode->computeCount = 0;
testNode->pushComputeCount = 0;
};
if (testNode->doPushComputeOverride)
{
for (int i = 0; i < TestMTopologyEvaluator_Node::attrOutputs.size(); i++)
{
MObject inputAttr = TestMTopologyEvaluator_Node::attrInputs[i];
MObject outputAttr = TestMTopologyEvaluator_Node::attrOutputs[i];
nodeName += (i + 1);
std::function<void()> pushComputeFn = [currEvalNode, inputAttr, outputAttr, testNode, nodeName]()
{
MStatus computeStat = MS::kSuccess;
MDataBlock data = currEvalNode.datablock(&computeStat);
double inputOutputOffsetForPush = 9;
double outputVal = inputDouble.
asDouble();
outputVal += inputOutputOffsetForPush;
computeStat = data.
setClean(outputAttr);
testNode->pushComputeCount++;
};
MEvaluationNode parentNode = getEvaluationNodeConnectedToInput(inputAttr, currEvalNode);
MEvaluationNode childNode = getEvaluationNodeConnectedToOutput(outputAttr, currEvalNode);
if (parentNode.dependencyNode() != currEvalNode.dependencyNode() && currEvalNode.dependencyNode() != childNode.dependencyNode())
{
MEvaluationNode inConnection = cluster->
connectionPort(parentNode, currEvalNode);
MEvaluationNode outConnection = cluster->connectionPort(childNode, currEvalNode);
inConnection.
connect(pushComputeExec);
pushComputeExec.
connect(outConnection);
}
}
}
else
{
for (int i = 0; i < TestMTopologyEvaluator_Node::attrOutputs.size(); i++)
{
MObject inputAttr = TestMTopologyEvaluator_Node::attrInputs[i];
MObject outputAttr = TestMTopologyEvaluator_Node::attrOutputs[i];
MString nodeName =
"FineGrainCompute_";
nodeName += (i+1);
std::function<void()> computeFn = [currEvalNode, outputAttr, nodeName]()
{
MStatus computeStat = MS::kSuccess;
MDataBlock data = currEvalNode.datablock(&computeStat);
};
MEvaluationNode parentNode = getEvaluationNodeConnectedToInput(inputAttr, currEvalNode);
MEvaluationNode childNode = getEvaluationNodeConnectedToOutput(outputAttr, currEvalNode);
if (parentNode.dependencyNode() != currEvalNode.dependencyNode() && currEvalNode.dependencyNode() != childNode.dependencyNode())
{
MEvaluationNode inConnection = cluster->connectionPort(parentNode, currEvalNode);
MEvaluationNode outConnection = cluster->connectionPort(childNode, currEvalNode);
computeExec.
connect(outConnection);
lastCompute = computeExec;
}
}
}
}
}
return true;
}