Algorithm 基于法线和中心位置固定网格中翻转面的算法

Algorithm 基于法线和中心位置固定网格中翻转面的算法,algorithm,unity3d,3d,mesh,normals,Algorithm,Unity3d,3d,Mesh,Normals,在我的应用程序(基于Unity3D)中,网格是在运行时加载的。在某些网格中,所有面都是翻转的(见图1)。 我试图实现一个简单的算法,计算所有顶点的中心,并检查法线是否指向中心。如果是这种情况,则应翻转此面。 问题是(如图2所示),当所有面都指向错误方向时,算法只翻转了几个面。 翻转的网格几乎完全是楼梯(如果有帮助的话) 如果有人告诉我我的错误或知道更好的方法,我将不胜感激。 在Blender中有一个函数“重新计算法线”,但我没有正确理解它,可能这对于我的问题来说是一个太复杂的解决方案 这里是算法

在我的应用程序(基于Unity3D)中,网格是在运行时加载的。在某些网格中,所有面都是翻转的(见图1)。 我试图实现一个简单的算法,计算所有顶点的中心,并检查法线是否指向中心。如果是这种情况,则应翻转此面。 问题是(如图2所示),当所有面都指向错误方向时,算法只翻转了几个面。 翻转的网格几乎完全是楼梯(如果有帮助的话)

如果有人告诉我我的错误或知道更好的方法,我将不胜感激。 在Blender中有一个函数“重新计算法线”,但我没有正确理解它,可能这对于我的问题来说是一个太复杂的解决方案

这里是算法(C#)和图片:

公共静态类FixMeshUtil
{
公共静态空心固定法线(网格)
{
if(mesh.vertexCount!=mesh.normals.Length)
mesh.normals();
Vector3[]法线=mesh.normals;
Vector3[]顶点=网格顶点;
int[]三角形=网格三角形;
矢量3中心=中心点(顶点);
对于(int i=0;inormal.magnity>0.001f;
专用静态布尔值向内(矢量3正常,矢量3中心)=>
向量3.点((法线-中心)。归一化,法线。归一化)<0f;
专用静态向量3计算异常(向量3 a、向量3 b、向量3 c)
{
向量3 v1=b-a;
向量3 v2=c-a;
返回新矢量3
(
(v1.y*v2.z)-(v1.z*v2.y),
(v1.z*v2.x)-(v1.x*v2.z),
(v1.x*v2.y)-(v1.y*v2.x)
).正常化;
}
}
更新: 多亏了Thibault Cimic,该代码通过将iFacingInwards功能更改为:

Vector3中点=中心-((v1+v2+v3)/3);
//...
如果(朝内(校准,中点))
//...
专用静态布尔值向内(矢量3法线,矢量3方向)=>
矢量3.点(方向.归一化,法线.归一化)>0f;


我不确定你给IsFacingInwards()的数学对象是否正确


将IsFacingInwards(calcNormal,center-p)放在其中,p是构成边缘的垂直线之一,您可能希望从中获得向外的法线?

我也尝试过(仅使用第一个法线)。但结果是一样的。圆心是内圈的圆心吗?它是2D有限元?中心是所有顶点的中心(基本上是“内点”)。每个指向“内点”的法线都朝内。这就是为什么我要计算(法向中心)以得到指向“内点”的方向。如果方向与法线匹配,则其指向内部。我希望这是可以理解和正确的。是的,但是法线是一个向量,而圆心是一个点(坐标的平均值),所以你应该取圆心-p,这是一个pst从p到圆心的向量。圆心-p进入元素内部,例如你想计算向外法线的边的一个顶点没有问题;)如果它真的是二维有限元编码,我通常做的是,在搜索边界边时,我还存储第三个垂直的索引,使其成为三角形,然后使用它来确保计算向外的法线