I'm working on an STL file importer and thought I'd make use of the normal given to determine the triangle winding order. Sample data with 4 triangles is included below (original data has over 70k triangles). My code's logic computes the normal assuming the vertices are specified anticlockwise, then does a dot product of this calculated normal with the supplied normal. If the result is positive, then I assume anticlockwise, else clockwise.
tm.SetCCW(Dot(Cross(facet.getVertex2() - facet.getVertex1(),facet.getVertex3() - facet.getVertex1()),facet.getNormal()) > 0.0);
This logic fails on a set of files from a particular 3D scanner. When I load these files into Rhino3D though, and issue "Dir" to look at the normal direction, Rhino has the direction correct! Same with a couple of other STL viewers I've tried.
My code deduces that the vertices are supplied in clockwise order on the sample data, but when using that winding order, the model is inside-out, implying the supplied normals are wrong.
This leads me to the conclusion that it is convention for STL importers to ignore the supplied normal, and assume anticlockwise winding order. I'm looking for people with more experience in the STL file format to weigh in on whether my assumption is correct.
solid object_name
facet normal -0.651094 0.733745 -0.194150
outer loop
vertex 30.335684 -40.893806 -68.126500
vertex 31.155055 -39.911656 -67.162500
vertex 30.263726 -40.702583 -67.162500
endloop
endfacet
facet normal -0.654292 0.732059 -0.189714
outer loop
vertex 30.335684 -40.893806 -68.126500
vertex 31.225185 -40.098797 -68.126500
vertex 31.155055 -39.911656 -67.162500
endloop
endfacet
facet normal -0.711866 0.677947 -0.183397
outer loop
vertex 31.225185 -40.098797 -68.126500
vertex 31.980540 -39.044870 -67.162500
vertex 31.155055 -39.911656 -67.162500
endloop
endfacet
facet normal -0.714326 0.676343 -0.179716
outer loop
vertex 31.225185 -40.098797 -68.126500
vertex 32.048799 -39.228928 -68.126500
vertex 31.980540 -39.044870 -67.162500
endloop
endfacet
endsolid
EDIT: My calculations for the first facet:
p1 = {30.335684, -40.893806, -68.126500}
p2 = {31.155055, -39.911656, -67.162500}
p3 = {30.263726, -40.702583, -67.162500}
u = p2 - p1 = {0.819371, 0.98215, 0.964}
w = p3 - p1 = {-0.071958, 0.191223, 0.964}
u x w = {0.762454, -0.859241, 0.227356} (calculated normal)
given normal = {-0.651094, 0.733745, -0.194150}
calculated_normal <dot> given_normal = -1.17103
verdict: 90 < theta < 270 where theta is the angle between the calculated and given normals