我需要在一个场景中加载几个STL文件,其中一些具有颠倒/翻转的面孔。可以使用双面材料轻松地(视觉上)修复此问题,但是我尝试的是可视化错误的面孔,将材料索引从蓝色切换为红色。
据我了解,镜像/翻转/反面是顺时针而非逆时针绘制的。但是我们在谈论构成脸部的三个向量吗?如果是这样,则缠绕顺序是在face.a,face.b和face.c中设置的顺序?还是我必须比较人脸索引值才能知道人脸的绘制顺序?
我设置了 JSFiddle 来解决此问题:此STL模型具有10个面,其中3个面反转或翻转。使用FaceNormalsHelper,您可以看到这三个法线助手指向模型的内部,而不是外部。我尝试了6种不同的方法进行检查,其中一些是从computeFaceNormals()的代码中提取的,没有运气。我还检查了FaceNormalsHelper,以了解其工作原理,但它只是沿法线方向从脸形质心画一条线,但无法计算它是指向内部还是指向外部。
(注意:要从一种方法更改为另一种方法,必须在脚本开始时更改变量。方法1手动覆盖这三个面的材质索引,只是为了可视化错误的面(如验证所有其他方法)。没有其他方法可以得到很好的结果。但是方法2和3确实非常接近,尽管以某种方式检测到另外两个人脸都被翻转了。我想知道人脸角度是否与这个)
编辑:@manthrax建议的方法可以完美地将每个面的边缘与其他所有面的边缘进行比较。如果以相同的方式绘制边缘(例如:面1的边a-b与面2的边a-b匹配,而不是b-a),则它被翻转。基本上,如果一张脸有两个或多个标记为翻转的边缘,我们可以说整个脸都是翻转的。检查JSFiddle以查看它是否有效。
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;
}
}
}
答案 0 :(得分:1)
首先,“翻转”的面孔完全是主观的。您需要确定一些参数。 对于凸对象,存在非主观定义。例如,点有一个面顶点的面法线> 0。
对于非凸对象,您可以根据顶点的缠绕顺序以及是否有2条边包含相同的顺序进行猜测,这意味着您有1个正面三角形和1个背面三角形共享一条边。 (这些三角形中的哪个三角形是翻转的,但在非凸情况下不一定可以识别。)
首先,您必须在几何图形上合并顶点,以便在面之间共享顶点...我认为stl为每个三角形定义了唯一的顶点,因此没有由两个共享的“边”的概念脸。
然后,您可以遍历每个面..基本上,任何两个共享相同2个顶点的边都应具有相反的顺序,或者面彼此相对。.
因此,如果2个面的边线分别为3,2和2,3,则它们都朝向相同的方向。并且这些面是一致的。
如果两个不同的面都具有分别为3,2和3,2的边,则它们面向相反的方向,则可以将两个面标记为可能被翻转。被标记次数最多的人脸实际上可能是被翻转的人。
这些是我可以用来确定内部/外部的最佳猜测测试,但这是一个棘手的问题。
Blender有几种“重新计算法线”方法来重新计算“内部” /“外部”,我认为它们的工作原理类似。.所以您也可以看看这些方法。