如何获取网格的可见顶点和线段列表 [英] How to get a list the visible vertices and segments of a mesh

查看:140
本文介绍了如何获取网格的可见顶点和线段列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究3d对象的姿态估计.我正在使用该对象的CAD模型来生成其姿势的所有可能假设. 我正在使用pyopengl从特定的POV渲染对象的视图.谁能解释一下如何获得所有可见边缘的列表?

I work on pose estimation of a 3d objects. I am using CAD model of that object to generate all the possible hypothesis of its pose. I am using pyopengl to render the view of the object from a specific POV. Can anyone explain how to get a list of all the visible edges?

因此,我使用人脸剔除来消除被遮挡的人脸,但是我不知道如何将可见边缘(索引和线段)传递给其他python函数.

So I use face culling to eliminate the occluded faces, but I don't know how to pass the visible edges(indices and segments) to other python functions.

如果还有其他方法(不使用OpenGL),我将不胜感激.

If there are any other approaches (not using OpenGL), I would really appreciate it.

所以我想在渲染的图像"中获取绘制的边缘:

So I want to get the drawn edges in the The rendered image:

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

I don't really want the image to be displayed. In summary, I have a CAD model, and I want a function that can return the visible segments out of a specific POV.

谢谢

推荐答案

人脸剔除

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

This works only for single convex strict winding rule mesh without holes!

这个想法是2个向量的点积符号会告诉您向量是否相反.因此,如果我们有正常的指向和查看方向,则朝向相机/查看器的脸部的点应为负.

The idea is that sign of dot product of 2 vectors will tell you if the vectors are opposite or not. So if we have a normal pointing out and view direction their dot should be negative for faces turned towards camera/viewer.

由于您不希望仅选择可见的平面/边线,因此可以完全在 CPU 侧上进行此操作.您需要的是使您的网格具有平面形状(无论三角形,四边形或其他形状都没有关系),因此让我们假设三角形(对于更多点,您只需将它们添加到_face中,但对于计算仍然仅使用v0,v1,v2) ...每张脸都应该有顶点和法线.

As you do not want to render just select visible planar faces/edges you can do this on CPU side entirely. What you need is to have your mesh in form of planar faces (does not matter if triangles,quads or whatever) so let assume triangles (for more points you just add them to _face but for computation still use only v0,v1,v2) ... Each face should have the vertexes and normal.

struct _face
 {
 double v0[3],v1[3],v2[3],n[3];
 };

List<_face> mesh;

现在您已经拥有顶点v0,v1,v2.所有这些都应按照严格的缠绕规则进行订购.这意味着,如果您从外部看任何点,则这些点应仅形成 CW (顺时针)循环(或仅 CCW (逆时针)循环).要计算法线,您只需利用叉积即可返回垂直于两个操作数的向量:

Now the vertexes v0,v1,v2 you already have. All of them should be ordered in strict winding rule. That means if you look at any face from outside the points should form only CW (clockwise) loop (or only CCW (counter-clockwise) loop). To compute normal you simply exploit cross product which returns vector perpendicular to both operands:

n = cross(v1-v0,v2-v1) // cross product
n = n / |n|            // optional normalize to unit vector

如果您需要向量数学,请参见

If you need the vector math see

底部是如何计算该值...还有相机方向所需的整个答案,所以请阅读...

On the bottom is how to compute this... Also the whole answer you will need for the camera direction so read it...

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

Now if your mesh has strict winding rule than all the computed normals are pointing out of mesh (or inwards depends on your coordinate system, CW/CCW and order of operands in cross product). Let assume they all pointing out (if not just negate normal).

如果没有严格的绕线规则,请计算网格的平均点(将所有顶点求和并除以它们的数量),这将是对象的中心c.现在只需计算

In case you do not have strict winding rule compute avg point of your mesh (sum all vertexes and divide by their count) this will be the center c of your object. Now just compute

dot(n,(v0+v1+v2)/3 - c)

,如果不是正数,则将n取反.这将修复您的法线(您也可以反转v0,v1,v2来修复网格.

and if not positive negate the n. This will repair your normals (you can also reverse the v0,v1,v2 to repair the mesh.

现在,相机和网格通常具有自己的4x4变换矩阵.一个从网格 LCS (局部坐标系)转换为 GCS (世界"全局坐标系),另一个从 GCS 转换为相机 LCS (屏幕).我们不需要投影,因为我们不需要渲染...因此,我们需要为每个面孔做的事情是:

Now the camera and mesh usually has its own 4x4 transform matrix. one transfroms from mesh LCS (local coordinate system) to GCS ("world" global coordinate system) and the other from GCS to camera LCS (screen). We do not need projections for this as we do not render ... So what we need to do for each face is:

  1. n转换为 GCS
  2. 计算dot(n,camera_view_direction)

  1. convert n to GCS
  2. compute dot(n,camera_view_direction)

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

where camera_view_direction is GCS vector pointing in view direction. You can take it from direct camera matrix directly. It is usually the Z axis vector (in OpenGL Perspective view it is -Z). Beware camera matrix used for rendering is inverse matrix so if the case either compute inverse first or transpose it as we do not need the offset anyway ...

确定是否可以从#2

所有数学都在上面的链接中说明...

Again all the math is explained in the link above...

如果没有网格矩阵(位置或方向没有变化),则可以假定其矩阵为1单位,表示GCS = mesh LCS,因此无需进行变换.

In case you do not have mesh matrix (does not have changing position or orientation) you can assume its matrix is unit one which means GCS = mesh LCS so no need for transformations.

在某些情况下,没有摄像头,只有网格矩阵(我怀疑您是这种情况),然后类似,您只是忽略了摄像头变换,而是使用(0,0,-1)(0,0,+1)作为查看方向.

In some cases there is no camera and only mesh matrix (I suspect your case) then it is similar you just ignore the camera transforms and use (0,0,-1) or (0,0,+1) as view direction.

也请参见:

它应该在正常主题上大放光彩.

It should shine some light on the normals topic.

这篇关于如何获取网格的可见顶点和线段列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆