c++ - 如何使用 Polygon_mesh_slicer 的输出来控制 Surface_mesh_deformation CGAL 中的点?

标签 c++ stl cgal boost-graph

我正在从事一个网格处理项目,该项目需要识别与平面相交的点,然后使用这些点使网格变形。我正在使用 CGAL::Polygon_mesh_slicer<> 查找兴趣点,并希望将这些点用作 CGAL::Surface_mesh_deformation<> 中变形的控制点。

我一直在搜索文档和论坛以找到可以帮助我入门的内容。在文档中,它表明过去到 Polygon_mesh_slicer 以获取多段线的迭代器必须属于 std::vector< traits::Point_3> reference manual 类型。 ,而 Surface_mesh_deformation 中的顶点输入必须是来自 reference manual 的 boost::graph_traits< Triangle_mesh >::vertex_descriptor
我不知道如何将信息从 Point_3 关联到 vertex_descriptor。

这是我拼凑起来用来说明问题的一个函数。我已经使用带有 typedef 的多面体网格运行它:

CGAL::Polyhedron_3< CGAL::Exact_predicates_inexact_constructions_kernel >

和一架飞机使用:

CGAL::Exact_predicates_inexact_constructions_kernel::Plane_3

非常感谢您的帮助,谢谢!

 template  <typename cgalMesh, typename cgalPlane, typename K>
 void functionForSOforum(cgalMesh& Mesh, cgalPlane& plane, K kernel)
 {
     typedef typename K::Point_3                                                     Point_3;
     typedef typename CGAL::Polyhedron_3<K>                                       Polyhedron;
     typedef typename K::Plane_3                                                    Plane;
     typedef typename K::Triangle_3                                              Triangle;

     typedef typename boost::graph_traits<cgalMesh>::vertex_descriptor     vertex_descriptor;
     typedef typename boost::graph_traits<cgalMesh>::vertex_iterator         vertex_iterator;
     typedef typename boost::graph_traits<cgalMesh>::halfedge_descriptor halfedge_descriptor;
     typedef typename boost::graph_traits<cgalMesh>::halfedge_iterator     halfedge_iterator;

     // Define the maps
     typedef std::map<vertex_descriptor, std::size_t>                   Vertex_id_map;
     typedef std::map<halfedge_descriptor, std::size_t>                  Hedge_id_map;
     typedef boost::associative_property_map<Vertex_id_map>            Vertex_id_pmap;
     typedef boost::associative_property_map<Hedge_id_map>              Hedge_id_pmap;

     typedef std::vector<Point_3>                                       Polyline_type;
     typedef std::list< Polyline_type>                                      Polylines;

     typedef CGAL::Polygon_mesh_slicer<Polyhedron, K>   Slicer;

     typedef CGAL::Surface_mesh_deformation<Polyhedron, Vertex_id_pmap, Hedge_id_pmap> Surface_mesh_deformation;

     // Get the least square plane describing the mesh
     linear_least_squares_fitting_3(Mesh.points_begin(),Mesh.points_end(), plane, CGAL::Dimension_tag<0>());

     // Find the intersection of the plane and the mesh
     Slicer slicer(Mesh);

      Polylines polylines;
      slicer(plane, std::back_inserter(polylines));

      // Set up the Region of interest as the whole mesh
      // *** from the CGAL docs ***
      Vertex_id_map vertex_index_map;
      vertex_iterator vb, ve;
      std::size_t counter = 0;
      for(boost::tie(vb, ve) = vertices(Mesh); vb != ve; ++vb, ++counter)
        vertex_index_map[*vb]=counter;

      Hedge_id_map hedge_index_map;
      counter = 0;
      halfedge_iterator eb, ee;
      for(boost::tie(eb, ee) = halfedges(Mesh); eb != ee; ++eb, ++counter)
        hedge_index_map[*eb]=counter;

      Surface_mesh_deformation deform_mesh( Mesh,
                                            Vertex_id_pmap(vertex_index_map),
                                            Hedge_id_pmap(hedge_index_map) );
      // Insert the whole mesh as region of interest
        boost::tie(vb, ve) = vertices(Mesh);
        deform_mesh.insert_roi_vertices(vb, ve);

      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      // ~~~~~     Want to put the points from the slicer here    ~~~~~~~~~

        int randomPoint = 200;

        // Insert a control vertex using the
         deform_mesh.insert_control_vertex(*std::next(vb, randomPoint));

 }

最佳答案

第一步是使用网格与平面的交点细化输入网格。这可以使用 AABB-tree package 来完成。更具体地说,通过使用类 AABB_halfedge_graph_segment_primitive 将网格的边缘视为基元,就像在这个 example 中一样(请注意,您可以将 Polyhedron_3 替换为 Surface_mesh)。 然后从 AABB 树调用 all_intersections() 方法将为您提供所有要细化的交点和边。

要分割一条边,您可以使用函数 split_edge() 。请注意,您必须保留变形过程函数返回的顶点描述符。

然后调用 triangulate_faces() 将恢复网格的三角属性。 (您可能可以使用 split_face 代替,但这需要一些内务处理并首先对每条边的交点进行排序)。

完成后,您可以使用之前保存在变形算法中的顶点描述符。

请注意,相交边不会出现在网格中。如果您需要它们,则需要额外的步骤(或直接使用带有平面网格的函数 corefine

关于c++ - 如何使用 Polygon_mesh_slicer 的输出来控制 Surface_mesh_deformation CGAL 中的点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56919844/

相关文章:

c++ - Perl 与 Ultraedit 脚本

c++ - 在 std::map 中存储结构实例

c++ less 运算符重载,用什么方法?

c++ - 我可以在 VS 中使用 GCC/LLVM 的 STL header 吗?

c++ - 返回交点和对象相交

c++ - 有没有办法让这个最短路径算法更快?

c++ - 如何在boost中打开一个文件

c++ - 链表词频和排序C++

c++ - Qt:这段代码中的QBuffer线程安全吗?

c++ - 使用 CGAL 将多面体投影到 xy 平面