如何获取网格的可见顶点和段的列表

时间:2018-02-13 12:42:19

标签: python opengl

我从事三维物体的姿态估计。我正在使用该对象的CAD模型来生成其姿势的所有可能假设。 我正在使用pyopengl从特定的POV渲染对象的视图。任何人都可以解释如何获得所有可见边的列表吗?

所以我使用面部剔除来消除被遮挡的面,但我不知道如何将可见边(索引和段)传递给其他python函数。

如果有其他方法(不使用OpenGL),我会非常感激。

所以我想在渲染图像中得到绘制的边缘:

img

我真的不希望显示图像。 总之,我有一个CAD模型,我想要一个可以从特定POV中返回可见段的函数。

由于

1 个答案:

答案 0 :(得分:1)

面部剔除

这仅适用于没有孔的单凸严格缠绕规则网格!

这个想法是2个向量的点积的符号将告诉你向量是否相反。因此,如果我们有一个正常的指向和查看方向,那么对于转向相机/查看器的面部,它们的点应该是负的。

由于您不想渲染只选择可见的平面/边缘,您可以完全在 CPU 侧执行此操作。你需要的是让你的网格以平面的形式存在(无论三角形,四边形或其他什么都没关系)所以假设三角形(对于更多的点,你只需将它们添加到_face但是为了计算仍然只使用{{ 1}})...每个面都应该有顶点和正常。

v0,v1,v2

现在你已经有了顶点struct _face { double v0[3],v1[3],v2[3],n[3]; }; List<_face> mesh; 。所有这些都应按严格的缠绕规则订购。这意味着如果您从外部观察任何面部,则应仅形成 CW (顺时针)循环(或仅 CCW (逆时针)循环)。要计算法线,您只需利用交叉积,它返回垂直于两个操作数的向量:

v0,v1,v2

如果你需要矢量数学,请参阅

在底部是如何计算这个...也是你需要的相机方向的整个答案所以阅读它...

现在,如果您的网格具有严格的缠绕规则,则所有计算的法线都指向网格外(或向内取决于您的坐标系, CW / CCW 和交叉积中的操作数顺序)。假设他们都指出了(如果不只是否定正常)。

如果您没有严格的缠绕规则计算网格的平均点(总和所有顶点并除以它们的计数),这将是您对象的中心n = cross(v1-v0,v2-v1) // cross product n = n / |n| // optional normalize to unit vector 。现在只需计算

c

如果不是肯定否定dot(n,(v0+v1+v2)/3 - c) 。这将修复你的法线(你也可以反转n来修复网格。

现在相机和网格通常有自己的4x4变换矩阵。从网格 LCS (局部坐标系)转移到 GCS (&#34;世界&#34;全球坐标系),另一个转移到 GCS 到相机 LCS (屏幕)。我们不需要对此进行预测,因为我们没有渲染......所以我们需要为每张脸做些什么:

  1. v0,v1,v2转换为 GCS
  2. 计算n

    其中dot(n,camera_view_direction) GCS 向量指向视图方向。您可以直接从直接相机矩阵中获取它。它通常是camera_view_direction轴向量(在 OpenGL 透视图中它是Z)。当心用于渲染的相机矩阵是逆矩阵,所以如果情况要先计算反转,要么转置它,因为我们不需要偏移......

  3. 根据#2

  4. 的标志判断面部是否可见

    同样,所有数学都在上面的链接中解释......

    如果你没有网格矩阵(没有改变位置或方向),你可以假设它的矩阵是单位一,这意味着-Z所以不需要转换。

    在某些情况下,没有摄像头,只有网格矩阵(我怀疑你的情况)然后它是相似的你只是忽略相机变换并使用GCS = mesh LCS(0,0,-1)作为视图方向。

    另见:

    它应该对法线主题有所启发。