views:

512

answers:

1

Hello,

I need a C# code snippet calculating the surface and vertex normals. Kind of surface is triangulated 3D closed mesh. The required code snippet must be able to use a vertex set and triangleindices. These are ready to use at the moment. The surface of 3D mesh object is not smooth, so it needs to be smoothed.

Could you help me.

Thanks.

Wolfgang

+1  A: 

It sounds like you're trying to display your 3D mesh and apply a smooth shading appearance by interpolating surface normals, such as in Phong shading, and you need to calculate the normals first. This is different from smoothing the surface of the mesh itself, since that implies altering the positions of its vertices.

Surface normals can be calculated by getting the vector cross product of two edges of a triangle.

As far as code, I'm unaware of any C# examples, but here is one in C++ that should be easy to port. It is taken from the popular NeHe tutorials for OpenGL:

void calcNormal(float v[3][3], float out[3])       // Calculates Normal For A Quad Using 3 Points
{
    float v1[3],v2[3];      // Vector 1 (x,y,z) & Vector 2 (x,y,z)
    static const int x = 0;      // Define X Coord
    static const int y = 1;      // Define Y Coord
    static const int z = 2;      // Define Z Coord

    // Finds The Vector Between 2 Points By Subtracting
    // The x,y,z Coordinates From One Point To Another.

    // Calculate The Vector From Point 1 To Point 0
    v1[x] = v[0][x] - v[1][x];     // Vector 1.x=Vertex[0].x-Vertex[1].x
    v1[y] = v[0][y] - v[1][y];     // Vector 1.y=Vertex[0].y-Vertex[1].y
    v1[z] = v[0][z] - v[1][z];     // Vector 1.z=Vertex[0].y-Vertex[1].z
    // Calculate The Vector From Point 2 To Point 1
    v2[x] = v[1][x] - v[2][x];     // Vector 2.x=Vertex[0].x-Vertex[1].x
    v2[y] = v[1][y] - v[2][y];     // Vector 2.y=Vertex[0].y-Vertex[1].y
    v2[z] = v[1][z] - v[2][z];     // Vector 2.z=Vertex[0].z-Vertex[1].z
    // Compute The Cross Product To Give Us A Surface Normal
    out[x] = v1[y]*v2[z] - v1[z]*v2[y];    // Cross Product For Y - Z
    out[y] = v1[z]*v2[x] - v1[x]*v2[z];    // Cross Product For X - Z
    out[z] = v1[x]*v2[y] - v1[y]*v2[x];    // Cross Product For X - Y

    ReduceToUnit(out);      // Normalize The Vectors
}

The normalization function ReduceToUnit() can be found there as well.

Note that this calculates a surface normal for a single triangle. Since you give no information about how your vertices and indices are stored, I will leave it up to you to derive the set of triangles you need to pass to this function.

EDIT: As an additional note, I think the "winding direction" of your triangles is significant. Winding in the wrong direction will cause the normal to point in the opposite direction as well.

Andy West