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();
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();
