OpenMesh中如何利用CGAL提供的API定位距离给定点最近的面(不使用AABB tree)
关键代码核心逻辑
step 1 - 将OpenMesh:TriMesh的mesh转化为CGAL:Surface_mesh<Point_3>的mesh
step 2 - 将三个轴上的坐标转化成CGAL:Point
step 3 - 调用PMP::locate()
step 4 - CGAL:Face_location转化为OpenMesh:faceHandle
remark : 输入的是OpenMesh类型的mesh,输出的是OpenMesh类型的FaceHandle,在过程中用到了CGAL的mesh。
locateVertexInFace.cpp
#include <string> #include <fstream> #include <OpenMesh/Core/Mesh/DefaultTriMesh.hh> #include <OpenMesh/Core/Mesh/PolyConnectivity.hh> #include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Polyhedron_3.h> #include <CGAL/Polygon_mesh_processing/locate.h> #include <CGAL/boost/graph/copy_face_graph.h> #include <CGAL/Surface_mesh.h> #include "locateVertexInFace.h" boost::unordered_map<tm_vertex_descriptor, pm_vertex_descriptor> v2v; boost::unordered_map<tm_halfedge_descriptor, pm_halfedge_descriptor> h2h; boost::unordered_map< tm_face_descriptor, pm_face_descriptor> f2f; FaceHandle locateVertexInFace(TriMesh& _OM_mesh, const double& _x, const double& _y, const double& _z) { //1. OpenMesh:TriMesh的mesh转化为CGAL:Surface_mesh<Point_3>的mesh PolyMesh CGAL_mesh; CGAL::copy_face_graph(_OM_mesh, CGAL_mesh, CGAL::parameters::vertex_to_vertex_map(boost::make_assoc_property_map(v2v)). halfedge_to_halfedge_output_iterator(std::inserter(h2h,h2h.end())). face_to_face_map(boost::make_assoc_property_map(f2f)) ); //2. 将三个轴上的坐标转化成CGAL:Point const Point_3 query(_x, _y, _z); //3. 调用PMP::locate() Face_location query_location = PMP::locate(query, CGAL_mesh); //4. CGAL:Face_location转化为OpenMesh:faceHandle FaceHandle faceHandle_(query_location.first); //std::clog << faceHandle_ << std::endl; return faceHandle_; }
locateVertexInFace.h
#ifndef LOCATEVERTEXINFACE_H #define LOCATEVERTEXINFACE_H #include <OpenMesh/Core/Mesh/DefaultTriMesh.hh> #include <OpenMesh/Core/Mesh/PolyConnectivity.hh> #include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Polyhedron_3.h> #include <CGAL/Polygon_mesh_processing/locate.h> #include <CGAL/boost/graph/copy_face_graph.h> #include <boost/unordered_map.hpp> #include <CGAL/Surface_mesh.h> #include <CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h> #include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h> typedef OpenMesh::TriMesh TriMesh; typedef TriMesh::FaceHandle FaceHandle; typedef TriMesh::Point Point; typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point_3; typedef CGAL::Surface_mesh<Point_3> PolyMesh; namespace PMP = CGAL::Polygon_mesh_processing; typedef PMP::Face_location<PolyMesh, Kernel::FT> Face_location; typedef boost::graph_traits<TriMesh>::vertex_descriptor tm_vertex_descriptor; typedef boost::graph_traits<TriMesh>::halfedge_descriptor tm_halfedge_descriptor; typedef boost::graph_traits<TriMesh>::face_descriptor tm_face_descriptor; typedef boost::graph_traits<PolyMesh>::vertex_descriptor pm_vertex_descriptor; typedef boost::graph_traits<PolyMesh>::halfedge_descriptor pm_halfedge_descriptor; typedef boost::graph_traits<PolyMesh>::face_descriptor pm_face_descriptor; FaceHandle locateVertexInFace(TriMesh& mesh, const double& _x, const double& _y, const double& _z); #endif
main.cpp
#include <iostream> #include <OpenMesh/Core/IO/MeshIO.hh> #include <OpenMesh/Core/Mesh/DefaultTriMesh.hh> #include <OpenMesh/Core/Mesh/PolyConnectivity.hh> #include "locateVertexInFace.h" int main() { TriMesh mesh; //读入文件 OpenMesh::IO::read_mesh(mesh, "E:\\3d_model_files\\1160382.off"); locateVertexInFace(mesh, 289, 302, 98); return 0; }