PDA

View Full Version : api set normals question


davegreenwood
08-17-2009, 09:45 AM
Hi all,
from the api docs:
Per-polygon normals Polygonal objects store a normal for each polygon. These normals can be accessed via MItMeshPolygon::getNormal(normal) or MFnMesh::getPolygonNormal. So, a cube, which is comprised of 6 polygons would contain 6 such normals.

but the question is, how do you set per-polygon normals? There does not seem to be a MFnMesh::setPolygonNormal method... All the other set methods appear to be vertex normals, per-vertex or shared.

When I create my mesh the face normal depends on the direction I order my face vertices. I can set per vertex normals to produce correct shading, but the viewport displays face normals in the reverse direction (if the face is ordered so). It's not trivial for me to check the winding order for my mesh faces, and as I have to set normals anyway, it would be nice to do it in my plugin.

Of course creating meshes in the api is all quite new to me, so please don't assume I've considered the obvious... it probably isn't obvious to me:)

many thanks for any help
Dave.

Robert Bateman
08-17-2009, 10:32 AM
You cannot set polygon normals - they are computed by Maya, and as such you can't change them. The only thing you can explicitly set are the vertex-normals. If it's just a poly winding issue, change the index winding for the polys. If you want to set all vertex normals to be the same as the face normal, either set them manually using MFnMesh::setFaceVertexNormals, or just set the normal smoothing angle to zero.

It's not trivial for me to check the winding order for my mesh faces, and as I have to set normals anyway, it would be nice to do it in my plugin.

It is! Do a cross product between two edge vectors of each poly to get the face normal. Then do a dot product with one of your vertex normals. If the answer is less than zero, reverse the face winding.

davegreenwood
08-17-2009, 12:25 PM
Hi Rob, thanks for getting back.

I think you've given me the answer... If I set the smoothing angle to zero, I'm guessing this will give a normal for each vertex per face? eg if I create a cube without setting normals I think I get one normal per vertex that is shared across faces, a total of 8 normals. If I set smoothing to zero will I get 24 normals(4 for each face) without setting them explicitly?

I think this will be a less expensive way than calculating a normal and setting it for each vertex, as I'm doing currently, and as all my faces are wound in the wrong direction I can reverse the connects array elements for each face.

Cheers
Dave.

davegreenwood
08-17-2009, 04:30 PM
yes, that works nicely... just one caveat for anyone watching. Reversing the connect order is not quite right. eg. 0,1,2,3,4 should become 0,4,3,2,1.

here's my code:

MIntArray className::reverseFace(MIntArray& faceCounts, MIntArray& faceConnects)
{
MIntArray tempArray;
int i,j, count;

count=0;
tempArray.clear();

for (i=0; i<faceCounts.length(); i++) {
count=count+faceCounts[i];
for (j=0; j<faceCounts[i]; j++) {
if(j==0){
tempArray.append(faceConnects[count-faceCounts[i]]);
}else {
tempArray.append(faceConnects[count-j]);
}
}

}
return tempArray;
}

Robert Bateman
08-18-2009, 09:57 AM
yes, that works nicely... just one caveat for anyone watching. Reversing the connect order is not quite right. eg. 0,1,2,3,4 should become 0,4,3,2,1.


How is 4,3,2,1,0 any different to 0,4,3,2,1 ? Any reasons why you found that reversing didn't work?

glad it worked though!

davegreenwood
08-18-2009, 11:03 AM
Hi Rob, well the first vertex of the face would be different, but I can see you're suggesting this doesn't matter.
I probably didn't count correctly when I tried it the other way:)

But yes, it works well. Thanks.

Dave.

CGTalk Moderation
08-18-2009, 11:03 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.