I need to load several STL files in a scene, some of which have reversed/flipped faces. This can be easily fixed (visually) using a double-sided material, but what I try is to visualize the wrong faces, switching the material index from blue to red.
If I understand, a mirrored/flipped/reversed face is being drawn clockwise instead of counter-clockwise. But are we talking about the three vectors that form the face? If so, the winding order is the order set at face.a, face.b and face.c? Or should I have to compare the face index value to know the order the face is drawn?
I set up a JSFiddle to ilustrate the problem: this STL model has 10 faces, and 3 of them are reversed or flipped. Using a FaceNormalsHelper you can see that those 3 normal helpers point to the inside of the model, instead outside. I´ve tried 6 different ways to check this, some of them are extracted from the code at computeFaceNormals(), with no luck. I´ve also examined the FaceNormalsHelper to see how it works, but it simply draws a line from the face centroid in the normals direction, but it never gets to calculate if it´s pointing inside or outside.
(Note: in order to change from one method to another, you must change the variable at the start of the script. Method 1 manually overrides these three faces material index, just to visualize the wrong ones (as a validation of all the other methods). No other one gets the good results.. But method 2 and 3 are really really close to it, although somehow two other faces are detected as flipped. I wonder if the face angle has something to do with this)
EDIT: The method suggested by @manthrax works perfectly, comparing edges of each face with all the other ones. If the edge is drawn the same way (example: face 1 edge a-b matches face 2 edge a-b, instead of b-a), it´s flipped. Basically, if a face has two or more edges marked as flipped, we can say the whole face is flipped. Check the JSFiddle to see it working.
function paintFlippedFaces(faceCheck){
for(var x=0; x<Object.keys(faceCheck).length; x++){
var flipCounter = 0;
if(faceCheck[x]['a-b']) flipCounter++;
if(faceCheck[x]['b-c']) flipCounter++;
if(faceCheck[x]['c-a']) flipCounter++;
console.log("face " + x + " has " +flipCounter+ " flipped edges" );
if(flipCounter >= 2){
geometry.faces[x].materialIndex = 1;
//geometry.faces.elementsNeedUpdate = true;
}
}
}