PDA

View Full Version : Set vertex colors via DGNode


xcx
11-16-2012, 08:48 AM
I try to set vertex colors via a node by using MFnMesh::setVertexColors(). However when I do this via node it won't work, but if I do same thing as command it works.

Here's my code, sorry it's bit long.

#include "ErrorMappingNode.h"

#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnNumericData.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MArrayDataBuilder.h>
#include <maya/MDoubleArray.h>
#include <maya/MVector.h>
#include <maya/MPoint.h>
#include <maya/MFloatVector.h>
#include <maya/MColorArray.h>
#include <maya/MIntArray.h>
#include <maya/MColor.h>

#include <maya/MGlobal.h>

MTypeId ErrorMappingNode::m_iId( 0x0000000E );
MObject ErrorMappingNode::m_aInputMeshA;
MObject ErrorMappingNode::m_aInputMeshB;
MObject ErrorMappingNode::m_aVertexColors;
MObject ErrorMappingNode::m_aDifferenceValues;
MObject ErrorMappingNode::m_aOutputMesh;

ErrorMappingNode::ErrorMappingNode() {}
ErrorMappingNode::~ErrorMappingNode() {}

void ErrorMappingNode::meshDifference(MFnMesh& meshA, MFnMesh& meshB, MDoubleArray& errorList)
{
errorList.clear();
for (int i=0; i < meshA.numVertices(); i++)
{
MPoint v1;
meshA.getPoint(i, v1, MSpace::kObject);
MPoint v2;
meshB.getPoint(i, v2, MSpace::kObject);
errorList.append(v1.distanceTo(v2));
}
}

MStatus ErrorMappingNode::compute( const MPlug& plug, MDataBlock& data )
{
MStatus returnStatus;

if(plug == m_aVertexColors || plug == m_aDifferenceValues || plug == m_aOutputMesh)
{
// Difference values.
MFnMesh meshA = data.inputValue(m_aInputMeshA, &returnStatus).asMesh();
MFnMesh meshB = data.inputValue(m_aInputMeshB, &returnStatus).asMesh();
CHECK_MSTATUS(returnStatus);

if (meshA.numVertices() != meshB.numVertices())
{
MGlobal::displayError("Vertex count doesn't match.");
return MS::kFailure;
}

MDoubleArray errorList;
this->meshDifference(meshA, meshB, errorList);

MArrayDataHandle hDifferenceValues = data.outputArrayValue(m_aDifferenceValues);
MArrayDataBuilder bDifferenceValues = hDifferenceValues.builder();

for (unsigned int i=0; i < errorList.length(); i++)
{
MDataHandle hDiffValue = bDifferenceValues.addElement(i);
hDiffValue.set(errorList[i]);
}

hDifferenceValues.set(bDifferenceValues);
hDifferenceValues.setAllClean();

// Difference Coloring.
MArrayDataHandle hVertexColors = data.outputArrayValue(m_aVertexColors);
MArrayDataBuilder bVertexColors = hVertexColors.builder();
MIntArray indexList;
MColorArray colorList;
for (unsigned int i=0; i < errorList.length(); i++)
{
MDataHandle hColValue = bVertexColors.addElement(i);
MFloatVector c = hColValue.asFloatVector();
c.x = errorList[i];
c.y = errorList[i];
c.z = errorList[i];
hColValue.set(c.x, c.y, c.z);
hColValue.setClean();

indexList.append(i);
MColor col;
col.r = c.x; col.g = c.y; col.b = c.z; col.a = 1.0;
colorList.append(col);
}

MGlobal::displayInfo("Set vertex colors");
MDataHandle hOutputMesh = data.outputValue(m_aOutputMesh);
MFnMesh outputMesh = hOutputMesh.asMesh();
CHECK_MSTATUS(outputMesh.setVertexColors(colorList, indexList));
outputMesh.updateSurface();
hOutputMesh.setClean();

hVertexColors.set(bVertexColors);
hVertexColors.setAllClean();
}
data.setClean(plug);
return MS::kSuccess;
}

void* ErrorMappingNode::creator()
{
return new ErrorMappingNode();
}

MStatus ErrorMappingNode::initialize()

{
MFnTypedAttribute tAttr;
MFnNumericAttribute nAttr;

m_aInputMeshA = tAttr.create("inputMeshA", "ima", MFnData::kMesh);
tAttr.setReadable(false);
tAttr.setWritable(true);
addAttribute(m_aInputMeshA);

m_aInputMeshB = tAttr.create("inputMeshB", "imb", MFnData::kMesh);
tAttr.setReadable(false);
tAttr.setWritable(true);
addAttribute(m_aInputMeshB);

m_aVertexColors = nAttr.create("vertexColors", "vc", MFnNumericData::k3Float);
nAttr.setArray(true);
nAttr.setUsesArrayDataBuilder(true);
nAttr.setUsedAsColor(true);
nAttr.setKeyable(false);
//nAttr.setWritable(false);
nAttr.setReadable(true);
addAttribute(m_aVertexColors);

m_aDifferenceValues = nAttr.create("differenceValues", "dv", MFnNumericData::k3Double);
nAttr.setArray(true);
nAttr.setUsesArrayDataBuilder(true);
nAttr.setKeyable(false);
//nAttr.setWritable(false);
nAttr.setReadable(true);
addAttribute(m_aDifferenceValues);

m_aOutputMesh = tAttr.create("outputMesh", "om", MFnData::kMesh);
tAttr.setStorable(false);
tAttr.setKeyable(false);
tAttr.setWritable(false);
tAttr.setReadable(true);
addAttribute(m_aOutputMesh);

attributeAffects(m_aInputMeshA, m_aOutputMesh);
attributeAffects(m_aInputMeshB, m_aOutputMesh);
attributeAffects(m_aInputMeshA, m_aVertexColors);
attributeAffects(m_aInputMeshB, m_aVertexColors);
attributeAffects(m_aInputMeshA, m_aDifferenceValues);
attributeAffects(m_aInputMeshB, m_aDifferenceValues);

return MS::kSuccess;
}


This one also write vertex differences and colors as arrays, but actual vertex color thing is here.


MFnMesh outputMesh = hOutputMesh.asMesh();
CHECK_MSTATUS(outputMesh.setVertexColors(colorList, indexList));
outputMesh.updateSurface();
hOutputMesh.setClean();

xcx
11-19-2012, 07:30 AM
I solved this very hacky way.

I made setVertexColors command plugin and called that from my node via MGlobal::executeCommand() method. It works, but generating a string with C++ isn't exactly fun nor good solution in any sense. However it got me further for now, but if someone knows better way please let me know.

giordi
11-19-2012, 11:25 AM
I solved this very hacky way.

I made setVertexColors command plugin and called that from my node via MGlobal::executeCommand() method. It works, but generating a string with C++ isn't exactly fun nor good solution in any sense. However it got me further for now, but if someone knows better way please let me know.


what was the error? also can you explain a bit better your connestions setup?

xcx
11-20-2012, 07:06 AM
Sorry about bad problem description.

So problem is (or was) that I can't set vertex colors via node, but if I do my plugin as command MFnMesh::setVertexColors works just fine.

However, now I manged to find a solution for this.

First solution was to call command plugin from Node to change vertex colors. That was bad solution, unstable, ugly, not visible via DG connections, etc.

Second solution is much more elegant and make sense :). This is what I tried to do in the first place, but I didn't got it right at first time. Then I found this awesome blog post http://www.hodge.net.au/sam/blog/?p=156=1 and just typed same thing with CPP and it worked.


MDataHandle hOutMesh = data.outputValue(m_aOutMesh);
MObject inData = data.inputValue(m_aInputMeshB).data();
MFnMeshData meshData;
MObject newOutData = meshData.create();
MFnMesh outMesh = MFnMesh().copy(inData, newOutData);
outMesh.setVertexColors(colorList, indexList);
hOutMesh.setMObject(newOutData);
hOutMesh.setClean();

CGTalk Moderation
11-20-2012, 07:06 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.