Как использовать вывод Polygon_mesh_slicer для управления точками в Surface_mesh_deformation CGAL? - PullRequest
0 голосов
/ 07 июля 2019

Я работаю над проектом обработки сетки, который требует определения точек, которые пересекаются плоскостью, а затем деформации сетки с использованием этих точек. Я использую CGAL :: Polygon_mesh_slicer <>, чтобы найти точки интереса и хочу использовать эти точки в качестве контрольных точек для деформации в CGAL :: Surface_mesh_deformation <>.

Я искал документацию и форумы, чтобы найти что-то, чтобы начать меня. В документации показано, что итератор, прошедший к Polygon_mesh_slicer для получения полилиний, должен иметь тип std :: vector справочное руководство , а вход для вершин в Surface_mesh_deformation должен быть boost :: graph_traits :: vertex_descriptor из справочного руководства
Я не знаю, как получить информацию из Point_3 в vertex_descriptor.

Это функция, которую я собрал вместе, чтобы проиллюстрировать проблему. Я запустил его, используя сетку многогранника с typedef:

CGAL :: Многогранник_3

и самолет с использованием:

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));

 }

1 Ответ

1 голос
/ 08 июля 2019

Первым шагом является уточнение входной сетки с пересечением сетки с вашей плоскостью.Это можно сделать с помощью пакета AABB-tree .Более конкретно, рассмотрите края вашей сетки как примитивы, используя класс AABB_halfedge_graph_segment_primitive , как в этом примере (обратите внимание, что вы можете заменить Polyhedron_3 на Surface_mesh).Затем вызов метода all_intersections() из дерева AABB даст вам все точки пересечения и ребра, которые нужно уточнить.

Чтобы разбить ребро, вы можете использовать функцию split_edge().Обратите внимание, что вы должны сохранить дескрипторы вершин, возвращаемые функцией для процесса деформации.

Тогда вызов triangulate_faces() восстановит свойство триангулированной сетки.(Вы, вероятно, можете использовать split_face вместо этого, но для этого потребуется некоторое домашнее хозяйство и сначала отсортировать точки пересечения по ребру.)

Как только это будет сделано, вы можете использовать дескрипторы вершин, ранее сохраненные в алгоритме деформации.

Обратите внимание, что ребра пересечения не будут присутствовать в сетке.Если они вам нужны, тогда нужны дополнительные шаги (или напрямую используйте функцию corefine с плоской сеткой.

...