CGAL 3D 表面网格生成后法线可能不一致
Normals probably not consistent after CGAL 3D Surface Mesh Generation
我使用 CGAL 的包,3D 表面网格生成。
http://doc.cgal.org/latest/Surface_mesher/index.html#Chapter_3D_Surface_Mesh_Generation
我从示例代码开始:
现在尝试从 C2t3 类型的变量 c2t3 中提取要显示的相关面(=三角形)。
中有一个很好的解释如何做到这一点
http://wiki.schmid.dk/wiki/index.php/CGAL
我按照我在
中找到的解释做了一点修改
http://cgal-discuss.949826.n4.nabble.com/normal-vector-of-a-facet-td1580004.html
现在,当我通过下面的代码片段将三角形提供给 OpenGL 时,显示的表面是黄色(我的照明颜色)和黑色三角形的马赛克 - 我断定这是因为表面法线不一致。但这怎么可能呢?如果有人遵循上面最后 link 中的论点,它应该是正确的。任何对 CGAL 和 3D 表面网格生成及其数据结构更熟悉的人都可以给我一些指导吗? (我还尝试了以下代码的几种明显替代方案,但没有任何效果正常)。
for (C2t3::Facet_iterator fit = c2t3.facets_begin(); fit != c2t3.facets_end(); ++fit) {
const Point_3& p0 = fit->first->vertex((fit->second))->point();
// points on the facet
const Point_3& p1 = fit->first->vertex((fit->second+1)&3)->point();
const Point_3& p2 = fit->first->vertex((fit->second+2)&3)->point();
const Point_3& p3 = fit->first->vertex((fit->second+3)&3)->point();
Vector_3 n = ( fit->second % 2 == 1) ?
CGAL::normal(p1, p2, p3) :
CGAL::normal(p1, p3, p2);
n = n /sqrt(n * n);
glNormal3d(n.x(), n.y(), n.z());
glVertex3d(p1.x(), p1.y(), p1.z());
glVertex3d(p2.x(), p2.y(), p2.z());
glVertex3d(p3.x(), p3.y(), p3.z());
++cnt2;
}
您提取小平面的方式是正确的,如果您从相同的 "side" 表面考虑它们,就会为您提供一致的小平面方向。例如,考虑一个嵌入到 c2t3 中的球体。如果您只考虑在球体内使用四面体的小平面,那么您的函数将执行您想要的操作。但是由于对面的迭代并不能保证你不会在球体之外有四面体,所以你的函数将显示方向不正确的面。
一个简单的解决方案是使用函数 CGAL::output_surface_facets_to_polyhedron
首先从 c2t3 中创建一个多面体并将其用于显示。
或者,您也可以查看不那么复杂的实现并模仿已完成的操作。
我使用 CGAL 的包,3D 表面网格生成。
http://doc.cgal.org/latest/Surface_mesher/index.html#Chapter_3D_Surface_Mesh_Generation
我从示例代码开始:
现在尝试从 C2t3 类型的变量 c2t3 中提取要显示的相关面(=三角形)。
中有一个很好的解释如何做到这一点http://wiki.schmid.dk/wiki/index.php/CGAL
我按照我在
中找到的解释做了一点修改http://cgal-discuss.949826.n4.nabble.com/normal-vector-of-a-facet-td1580004.html
现在,当我通过下面的代码片段将三角形提供给 OpenGL 时,显示的表面是黄色(我的照明颜色)和黑色三角形的马赛克 - 我断定这是因为表面法线不一致。但这怎么可能呢?如果有人遵循上面最后 link 中的论点,它应该是正确的。任何对 CGAL 和 3D 表面网格生成及其数据结构更熟悉的人都可以给我一些指导吗? (我还尝试了以下代码的几种明显替代方案,但没有任何效果正常)。
for (C2t3::Facet_iterator fit = c2t3.facets_begin(); fit != c2t3.facets_end(); ++fit) {
const Point_3& p0 = fit->first->vertex((fit->second))->point();
// points on the facet
const Point_3& p1 = fit->first->vertex((fit->second+1)&3)->point();
const Point_3& p2 = fit->first->vertex((fit->second+2)&3)->point();
const Point_3& p3 = fit->first->vertex((fit->second+3)&3)->point();
Vector_3 n = ( fit->second % 2 == 1) ?
CGAL::normal(p1, p2, p3) :
CGAL::normal(p1, p3, p2);
n = n /sqrt(n * n);
glNormal3d(n.x(), n.y(), n.z());
glVertex3d(p1.x(), p1.y(), p1.z());
glVertex3d(p2.x(), p2.y(), p2.z());
glVertex3d(p3.x(), p3.y(), p3.z());
++cnt2;
}
您提取小平面的方式是正确的,如果您从相同的 "side" 表面考虑它们,就会为您提供一致的小平面方向。例如,考虑一个嵌入到 c2t3 中的球体。如果您只考虑在球体内使用四面体的小平面,那么您的函数将执行您想要的操作。但是由于对面的迭代并不能保证你不会在球体之外有四面体,所以你的函数将显示方向不正确的面。
一个简单的解决方案是使用函数 CGAL::output_surface_facets_to_polyhedron
首先从 c2t3 中创建一个多面体并将其用于显示。
或者,您也可以查看不那么复杂的实现并模仿已完成的操作。