PDA

View Full Version : api: node, multiple output


mfg
08-13-2009, 05:06 AM
so while i was researching nodes i came upon this site http://www.cgdna.com/cms/archives/170 , morteza wrote a polyInfo node.

so i checked out the source code and i am interested in understanding how he sets the datahandle's for the output.

...

MDataHandle vertexCountDataHandle = data.outputValue(cgdnaPolyinfo::vertexCount);
int &vertexCount_Output = getvertexCount;
vertexCountDataHandle.set( vertexCount_Output );
vertexCountDataHandle.setClean();

MDataHandle wsVertexPositionDataHandle = data.outputValue(cgdnaPolyinfo::wsVertexPosition);
MFloatVector &wsVertexPosition_Output = getwsVertexPosition;
wsVertexPositionDataHandle.set( wsVertexPosition_Output );
wsVertexPositionDataHandle.setClean();

...


so i tired to copy this approach. here is the compute part of my very simplified node

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

if( plug == vertexCount || plug == wsVertexPosition )
{

MDataHandle inMeshHandle = data.inputValue( inMesh, &returnStatus );
if( returnStatus != MS::kSuccess )
MGlobal::displayError( "Node myVertexInfo cannot get value\n" );

MDataHandle inVertexIdHandle = data.inputValue(inVertexId, &returnStatus );
if( returnStatus != MS::kSuccess )
MGlobal::displayError( "Node myVertexInfo cannot get value\n" );


else
{

int inVertex = inVertexIdHandle.asInt();
MFnMesh meshFn = inMeshHandle.asMesh();

int Vcount = meshFn.numVertices();

MPoint pt;
meshFn.getPoint(inVertex,pt,MSpace::kWorld);

MVector Vpos = pt;

////
MDataHandle wsVertexPositionHandle = data.outputValue( myVertexInfo::wsVertexPosition );
MVector &wsVertexPosition_Output = Vpos;
wsVertexPositionHandle.set( wsVertexPosition_Output );
wsVertexPositionHandle.setClean();

MDataHandle vertexCountHandle = data.outputValue( myVertexInfo::vertexCount );
int &getvertexCount_Output = Vcount;
vertexCountHandle.set( getvertexCount_Output );
vertexCountHandle.setClean();

}
} else {
return MS::kUnknownParameter;
}

return MS::kSuccess;
}


so in maya i connect the outmesh of a polygon to the inmesh of the node.
(getAttr myVertexInfo1.vertexCount) returns the correct result
(getAttr myVertexInfo1.wsVertexPosition) the return here looks kinda like this (239487358239 -3 09478568947523)

so what am i doing wrong?

ty, for your time.

Robert Bateman
08-13-2009, 12:27 PM
MSpace::kWorld is invalid in this context. You have not initialised the MFnMesh using an MDagPath to the mesh, so it has no concept of it's parenting information. It's impossible to do this from the compute method (IIRC), however you can connect a matrix for the mesh instance to your node to get a WS matrix to transform the local space point into world space.

Alternatively, are you sure the vertex index is actually valid for the mesh?

\edit

Looking at the link you provided:

Name: worldMatrix (iwm)
Type: matrix
Default: —
Note: The worldMatrix instanced attribute is the 4×4 transformation matrix that transforms the object to world-space. Tip: connect worldMatrix of polygon mesh to worldMatrix of polyInfo node.

mfg
08-15-2009, 06:59 PM
ty Robert,

MSpace::kWorld is invalid in this context. You have not initialised the MFnMesh using an MDagPath to the mesh, so it has no concept of it's parenting information. It's impossible to do this from the compute method (IIRC),
this comment has helped me alot.

looking through the devkit i found "pointOnMesh". In this example they get all the info they cant get from inside the compute from a defined function. So i did the same thing for my node and it worked :D.

so just to recap what i have been trying to do; i wanted to write a node with
input: polygon, vertexID
output: vertex position, vertex count


here is my function to get the ws position of a vertex and the total vertex count of the polygon:

void getPoint(MDagPath meshDagPath, int faceIndex, MPoint &point, int &vIndex, MObject theMesh)

{

MFnMesh meshFn(meshDagPath);
if (theMesh!=MObject::kNullObj)
meshFn.setObject(theMesh);


vIndex = meshFn.numVertices();
meshFn.getPoint(faceIndex, point, MSpace::kWorld);

}


the function is called from the compute:

MStatus mypolyInfoNode::compute(const MPlug &plug, MDataBlock &data)
{

if ((plug == Position) || (plug == PositionX) || (plug == PositionY) || (plug == PositionZ))
{

MDataHandle inMeshDataHandle = data.inputValue(InMesh);
MObject inMesh = inMeshDataHandle.asMesh();

MDataHandle faceIndexDataHandle = data.inputValue(vertexID);
int faceIndex = faceIndexDataHandle.asLong();



int vIndex;
MPoint point;
MVector normal;
MDagPath dummyDagPath;
getPoint(dummyDagPath, faceIndex, point, vIndex, inMesh);



MDataHandle pointDataHandle = data.outputValue(Position);
pointDataHandle.set(point.x, point.y, point.z);
data.setClean(plug);

MDataHandle aVertexDataHandle = data.outputValue(vertexCount);
aVertexDataHandle.set(vIndex);
data.setClean(plug);

}
else
return MS::kUnknownParameter;

return MS::kSuccess;
}


The big question i have for all the api pro's out there , is this the best way to do this ? ...
what problems could i potentially run into doing it like this?




PS: i uploaded my source files and a .mll for 2008. maybe it will help someone else.

CGTalk Moderation
08-15-2009, 06:59 PM
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.