CGAL光线与点云重建网格求交AABB树编译及结果异常问题求解
问题1:编译错误原因及解决
核心原因
你对AABB树的内核要求理解有误,Fast Intersection and Distance Computation包完全支持EPICK内核,不需要单独用Simple_cartesian<double>内核,编译错误的根本原因是你混用了两套内核对应的网格类型:
- 曲面重建用的
Mesh是基于Exact_predicates_inexact_constructions_kernel定义的 - AABB树绑定的
meshCGAL是基于Simple_cartesian<double>定义的
两种不同的网格类型不兼容,初始化AABB树时传入的sv是Mesh类型,和AABB树要求的meshCGAL类型不匹配,因此触发类型转换报错。
修复方法
直接删除所有Simple_cartesian<double>相关的类型定义,全局统一使用Exact_predicates_inexact_constructions_kernel即可:
// 删掉这部分代码 // typedef CGAL::Simple_cartesian<double> K; // typedef K::FT FT; // typedef K::Point_3 pointCGAL; // typedef K::Vector_3 vectorCGAL; // typedef K::Ray_3 rayCGAL; // typedef CGAL::Surface_mesh<pointCGAL> meshCGAL; // 替换为以下定义,和重建用的内核完全对齐 typedef Kernel::FT FT; typedef Kernel::Point_3 pointCGAL; typedef Kernel::Vector_3 vectorCGAL; typedef Kernel::Ray_3 rayCGAL; typedef Mesh meshCGAL;
修改后重新编译即可解决类型转换报错。
问题2:求交结果错误原因及解决
错误原因
出现大量不符合预期的交点,是因为你重建得到的网格存在无效结构,AABB树将退化面、非流形边、重叠面的相交都判定为有效交点:
advancing_front_surface_reconstruction对噪声点、点云密度不均匀的情况很容易生成退化三角面(零面积、顶点共线)、重叠面、破洞- 你没有对重建后的网格做有效性清洗就直接构建AABB树,无效面会产生大量错误的相交判定
- 当射线穿过多条边/顶点时,相邻的多个三角面会分别返回相同位置的交点,也会造成重复计数
修复方法
在重建完成后、构建AABB树前添加网格清洗步骤:
CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), construct); // 新增清洗逻辑 PMP::remove_degenerate_faces(sv); // 删除所有零面积退化面 PMP::remove_isolated_vertices(sv); if (!CGAL::is_triangle_mesh(sv)) { std::cerr << "重建结果不是合法三角网格" << std::endl; return -1; } if (!PMP::is_outward_oriented(sv)) PMP::reverse_face_orientations(sv);
构建AABB树后主动触发树结构构建,避免延迟初始化带来的问题:
Tree tree(faces(sv).first, faces(sv).second, sv); tree.accelerate_intersection_queries(); // 强制完成AABB树构建,加速查询同时避免异常
如果仍有少量重复交点,可对返回的交点做距离阈值去重,将坐标差小于1e-6的交点合并即可。
内容的提问来源于stack exchange,提问作者wenzaifou
相关产品推荐
相关产品推荐

