如何在 CGAL 中迭代人脸

发布于 2024-08-17 12:56:42 字数 1158 浏览 8 评论 0原文

我正在尝试使用 CGAL 进行一些 Delaunay 三角测量。我使用 CGAL 示例之一来计算包含高度场属性的三角测量。

我遇到的问题是我不知道如何获得最终的三角测量。我想出了如何获取face_iterator,但我不知道从那里做什么。我希望得到的是每个三角形上 3 个点的点数组的索引。

我在遍历所有嵌套模板时遇到问题:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Triangulation_euclidean_traits_xy_3.h>
#include <CGAL/Delaunay_triangulation_2.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_euclidean_traits_xy_3<K> Gt;
typedef CGAL::Delaunay_triangulation_2<Gt> Delaunay;
typedef K::Point_3 Point;

int main()
{
    //initialize the points with some trivial data
    std::vector<Point> pts;
    pts.push_back(Point(1., 2., 3.));
    pts.push_back(Point(2., 2., 3.));
    pts.push_back(Point(1., 3., 3.));
    pts.push_back(Point(4., 2., 3.));    

    //create a delaunay triangulation
    Delaunay dt;
    dt.insert(pts.begin(), pts.end());

    //iterate through the faces
    Delaunay::Finite_faces_iterator it;
    for (it = dt.finite_faces_begin(); it != dt.finite_faces_end(); it++)
    {
        //What do I do here??
    }

    return 0;
}

I am trying to use CGAL to do some Delaunay triangulation. I used one of the CGAL samples to compute a triangulation which includes a height field attribute.

The problem I have having is that I have no idea how to get the resulting triangulation. I figured out how to get the face_iterator, but I don't know what to do from there. What I'm hoping to get is an index into the point array for each of the 3 points on each triangle.

I'm having trouble wading through all of the nested templates:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Triangulation_euclidean_traits_xy_3.h>
#include <CGAL/Delaunay_triangulation_2.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_euclidean_traits_xy_3<K> Gt;
typedef CGAL::Delaunay_triangulation_2<Gt> Delaunay;
typedef K::Point_3 Point;

int main()
{
    //initialize the points with some trivial data
    std::vector<Point> pts;
    pts.push_back(Point(1., 2., 3.));
    pts.push_back(Point(2., 2., 3.));
    pts.push_back(Point(1., 3., 3.));
    pts.push_back(Point(4., 2., 3.));    

    //create a delaunay triangulation
    Delaunay dt;
    dt.insert(pts.begin(), pts.end());

    //iterate through the faces
    Delaunay::Finite_faces_iterator it;
    for (it = dt.finite_faces_begin(); it != dt.finite_faces_end(); it++)
    {
        //What do I do here??
    }

    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

肩上的翅膀 2024-08-24 12:56:42

您可以使用 Delaunay::triangle 将面(迭代器)转换为相应的三角形。这是在 CGAL 3.8 下测试的:

// points.cin contains point pairs, e.g.,
// 3 5 
// 0 0
// 1 9
// ...
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <fstream>

typedef CGAL::Exact_predicates_exact_constructions_kernel K;
typedef CGAL::Delaunay_triangulation_2<K> Delaunay;
typedef K::Point_2   Point;

int main()
{
  std::ifstream in("points.cin");
  std::istream_iterator<Point> begin(in);
  std::istream_iterator<Point> end;

  Delaunay dt;
  dt.insert(begin, end);

  Delaunay::Finite_faces_iterator it;
  for (it = dt.finite_faces_begin(); it != dt.finite_faces_end(); it++)
  {
    std::cout << dt.triangle(it) << std::endl;
  }

  return 0;
}

You can use Delaunay::triangle to convert from a face (iterator) to the corresponding triangle. This is tested under CGAL 3.8:

// points.cin contains point pairs, e.g.,
// 3 5 
// 0 0
// 1 9
// ...
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <fstream>

typedef CGAL::Exact_predicates_exact_constructions_kernel K;
typedef CGAL::Delaunay_triangulation_2<K> Delaunay;
typedef K::Point_2   Point;

int main()
{
  std::ifstream in("points.cin");
  std::istream_iterator<Point> begin(in);
  std::istream_iterator<Point> end;

  Delaunay dt;
  dt.insert(begin, end);

  Delaunay::Finite_faces_iterator it;
  for (it = dt.finite_faces_begin(); it != dt.finite_faces_end(); it++)
  {
    std::cout << dt.triangle(it) << std::endl;
  }

  return 0;
}
泪眸﹌ 2024-08-24 12:56:42

可以使用 dt.triangle(it)[idx] 访问三角形的顶点,其中 it 是面迭代器,idx 是顶点编号(0,1 或 2) )。在下面的示例中,顶点是 Point_2 对象,可以使用 x() 和 y() 方法访问其笛卡尔坐标。

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Triangulation_euclidean_traits_2.h>
#include <CGAL/Delaunay_triangulation_2.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_euclidean_traits_2<K> Gt;
typedef CGAL::Delaunay_triangulation_2<Gt> Delaunay;

typedef K::Point_2 Point_2;
typedef std::vector<Point_2> Points;

int main()
{
    Points points;
    points.push_back(Point_2(0,0));
    points.push_back(Point_2(0,7));
    points.push_back(Point_2(7,0));
    points.push_back(Point_2(7,7));

    Delaunay dt(points.begin(), points.end());

    // Print Cartesian coordinates of vertices of triangles in 2D Delaunay triangulation
    for (Delaunay::Finite_faces_iterator it = dt.finite_faces_begin(); it != dt.finite_faces_end(); it++)
    {
        std::cout << " " << dt.triangle(it)[0].x() << " " << dt.triangle(it)[0].y() << " ";
        std::cout << " " << dt.triangle(it)[1].x() << " " << dt.triangle(it)[1].y() << " ";
        std::cout << " " << dt.triangle(it)[2].x() << " " << dt.triangle(it)[2].y() << " ";
        std::cout << std::endl << "-------------------" << std::endl;
    }
    return 0;
}

A vertex of a triangle can be accessed using dt.triangle(it)[idx], where it is a faces iterator and idx is vertex number (0,1 or 2). In the example below, a vertex is a Point_2 object, its cartesian coordinates can be accessed using x() and y() methods.

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Triangulation_euclidean_traits_2.h>
#include <CGAL/Delaunay_triangulation_2.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_euclidean_traits_2<K> Gt;
typedef CGAL::Delaunay_triangulation_2<Gt> Delaunay;

typedef K::Point_2 Point_2;
typedef std::vector<Point_2> Points;

int main()
{
    Points points;
    points.push_back(Point_2(0,0));
    points.push_back(Point_2(0,7));
    points.push_back(Point_2(7,0));
    points.push_back(Point_2(7,7));

    Delaunay dt(points.begin(), points.end());

    // Print Cartesian coordinates of vertices of triangles in 2D Delaunay triangulation
    for (Delaunay::Finite_faces_iterator it = dt.finite_faces_begin(); it != dt.finite_faces_end(); it++)
    {
        std::cout << " " << dt.triangle(it)[0].x() << " " << dt.triangle(it)[0].y() << " ";
        std::cout << " " << dt.triangle(it)[1].x() << " " << dt.triangle(it)[1].y() << " ";
        std::cout << " " << dt.triangle(it)[2].x() << " " << dt.triangle(it)[2].y() << " ";
        std::cout << std::endl << "-------------------" << std::endl;
    }
    return 0;
}
(り薆情海 2024-08-24 12:56:42

这是谷歌的一个例子。 Finite_faces_iterator 是类型定义的。

  Interval_skip_list isl;
  for(Finite_faces_iterator fh = dt.finite_faces_begin();
      fh != dt.finite_faces_end();
      ++fh){
    isl.insert(Interval(fh));
  }
  std::list<Interval> level;
  isl.find_intervals(50, std::back_inserter(level));
  for(std::list<Interval>::iterator it = level.begin();
      it != level.end();
      ++it){
    std::cout << dt.triangle(it->face_handle()) << std::endl;
  }

这不会执行您想要的操作,但为您提供了一个可以使用迭代器执行的操作的示例。

Here is an example from Google. Finite_faces_iterator was typedefed.

  Interval_skip_list isl;
  for(Finite_faces_iterator fh = dt.finite_faces_begin();
      fh != dt.finite_faces_end();
      ++fh){
    isl.insert(Interval(fh));
  }
  std::list<Interval> level;
  isl.find_intervals(50, std::back_inserter(level));
  for(std::list<Interval>::iterator it = level.begin();
      it != level.end();
      ++it){
    std::cout << dt.triangle(it->face_handle()) << std::endl;
  }

This does not do what you want, but gives you an example of what can be done with an iterator.

烟雨扶苏 2024-08-24 12:56:42

如果您想要一个真正扩展的示例,了解如何准确地完成您想要的操作,请从此处查看 X-Plane 风景工具的源代码:http://scenery.x-plane.com/code.php

通过扩展示例,我的意思是几十万行,但是 CGAL 几乎可以使用所有内容处理 Delaunay 三角剖分和其中的扩展属性。

If you want a really extended example of how to do exactly what you want, take a look at the source to the X-Plane scenery tools from here: http://scenery.x-plane.com/code.php

By extended example, I mean a couple of hundred thousand lines, but there's uses of nearly everything CGAL can do with Delaunay triangulations and extended attributes in there.

只是一片海 2024-08-24 12:56:42

好吧,我刚刚遇到了类似的问题,我做了很多研究(主要是因为我对 C++ 没有任何了解)。我希望能够通过顶点整数表示来打印三角形。它的外观如下:

#include <CGAL/Surface_mesh_default_triangulation_3.h>
#include <CGAL/Complex_2_in_triangulation_3.h>
#include <CGAL/make_surface_mesh.h>
#include <CGAL/Implicit_surface_3.h>

// This is the file where you can look for an example of iterating, geting basic vertex positions, outputing triangles
// #include <CGAL/IO/Complex_2_in_triangulation_3_file_writer.h>

// default triangulation for Surface_mesher
typedef CGAL::Surface_mesh_default_triangulation_3 Tr;

// c2t3
typedef CGAL::Complex_2_in_triangulation_3<Tr> C2t3;

typedef Tr::Geom_traits GT;
typedef GT::Sphere_3 Sphere_3;
typedef GT::Point_3 Point_3;
typedef GT::FT FT;

typedef FT (*Function)(Point_3);

typedef CGAL::Implicit_surface_3<GT, Function> Surface_3;

// This already have been defined
//typedef typename C2t3::Triangulation Tr;
typedef typename Tr::Vertex_handle Vertex_handle;
typedef typename Tr::Finite_vertices_iterator Finite_vertices_iterator;
typedef typename Tr::Finite_facets_iterator Finite_facets_iterator;

typedef typename Tr::Point Point;


FT sphere_function (Point_3 p) {
  const FT x = p.x();
  const FT y = p.y();
  const FT z = p.z();

  //const FT x2=p.x()*p.x(), y2=p.y()*p.y(), z2=p.z()*p.z();
  const FT a = 2;
  const FT b = 1;
  const FT c = 1.5;
  return x*x/a/a + y*y/b/b + z*z/c/c -1;
}

int main() {
  Tr tr;            // 3D-Delaunay triangulation
  C2t3 c2t3 (tr);   // 2D-complex in 3D-Delaunay triangulation

  // defining the surface
  Surface_3 surface(sphere_function,             // pointer to function
                    Sphere_3(CGAL::ORIGIN, 2.)); // bounding sphere
  // Note that "2." above is the *squared* radius of the bounding sphere!

  // defining meshing criteria
  CGAL::Surface_mesh_default_criteria_3<Tr> criteria(30.,  // angular bound
                                                     0.1,  // radius bound
                                                     0.1); // distance bound
  // meshing surface
  CGAL::make_surface_mesh(c2t3, surface, criteria, CGAL::Non_manifold_tag());

  std::cout << "Final number of points: " << tr.number_of_vertices() << "\n";

  // Here should be the main code

  Tr& tr2 = c2t3.triangulation();

  std::map<Vertex_handle, int> V;
  int inum = 0;
  Finite_vertices_iterator vit = tr2.finite_vertices_begin();
  while(vit != tr2.finite_vertices_end()) {

    // making an integer representation of vertex pointers
    V[vit] = inum++;

    // obtaining vertex positions from vertex pointer vit
    Point p = static_cast<Point>(vit->point());
    std::cout << p.x() << " " << p.y() << " " << p.z() << std::endl;

    ++vit;
  }

  Finite_facets_iterator fit = tr2.finite_facets_begin();

  while (fit != tr2.finite_facets_end()) {

    typename Tr::Cell_handle cell = fit->first;
    const int& index = fit->second;

    int index1 = V[cell->vertex(tr.vertex_triple_index(index, 0))];
    int index2 = V[cell->vertex(tr.vertex_triple_index(index, 1))];
    int index3 = V[cell->vertex(tr.vertex_triple_index(index, 2))];

    std::cout << index1 << " " << index2 << " " << index3 << std::endl;
    ++fit;
  }

}

使用以下命令进行编译(如果mesh_implicit_function是源代码、目标文件和可执行文件):

c++   -DCGAL_USE_GMP -DCGAL_USE_MPFR -DCGAL_USE_ZLIB -frounding-math -o mesh_an_implicit_function.cpp.o -c mesh_an_implicit_function.cpp
c++ mesh_an_implicit_function.cpp.o  -o mesh_an_implicit_function -lmpfr -lgmp -lCGAL -lboost_thread

Well I just had a similar problem where I did a lot of research (mainly because I did not have any knowledge of C++). I wanted to be able to print triangles by it's vertex integer representation. Here it is how it looks:

#include <CGAL/Surface_mesh_default_triangulation_3.h>
#include <CGAL/Complex_2_in_triangulation_3.h>
#include <CGAL/make_surface_mesh.h>
#include <CGAL/Implicit_surface_3.h>

// This is the file where you can look for an example of iterating, geting basic vertex positions, outputing triangles
// #include <CGAL/IO/Complex_2_in_triangulation_3_file_writer.h>

// default triangulation for Surface_mesher
typedef CGAL::Surface_mesh_default_triangulation_3 Tr;

// c2t3
typedef CGAL::Complex_2_in_triangulation_3<Tr> C2t3;

typedef Tr::Geom_traits GT;
typedef GT::Sphere_3 Sphere_3;
typedef GT::Point_3 Point_3;
typedef GT::FT FT;

typedef FT (*Function)(Point_3);

typedef CGAL::Implicit_surface_3<GT, Function> Surface_3;

// This already have been defined
//typedef typename C2t3::Triangulation Tr;
typedef typename Tr::Vertex_handle Vertex_handle;
typedef typename Tr::Finite_vertices_iterator Finite_vertices_iterator;
typedef typename Tr::Finite_facets_iterator Finite_facets_iterator;

typedef typename Tr::Point Point;


FT sphere_function (Point_3 p) {
  const FT x = p.x();
  const FT y = p.y();
  const FT z = p.z();

  //const FT x2=p.x()*p.x(), y2=p.y()*p.y(), z2=p.z()*p.z();
  const FT a = 2;
  const FT b = 1;
  const FT c = 1.5;
  return x*x/a/a + y*y/b/b + z*z/c/c -1;
}

int main() {
  Tr tr;            // 3D-Delaunay triangulation
  C2t3 c2t3 (tr);   // 2D-complex in 3D-Delaunay triangulation

  // defining the surface
  Surface_3 surface(sphere_function,             // pointer to function
                    Sphere_3(CGAL::ORIGIN, 2.)); // bounding sphere
  // Note that "2." above is the *squared* radius of the bounding sphere!

  // defining meshing criteria
  CGAL::Surface_mesh_default_criteria_3<Tr> criteria(30.,  // angular bound
                                                     0.1,  // radius bound
                                                     0.1); // distance bound
  // meshing surface
  CGAL::make_surface_mesh(c2t3, surface, criteria, CGAL::Non_manifold_tag());

  std::cout << "Final number of points: " << tr.number_of_vertices() << "\n";

  // Here should be the main code

  Tr& tr2 = c2t3.triangulation();

  std::map<Vertex_handle, int> V;
  int inum = 0;
  Finite_vertices_iterator vit = tr2.finite_vertices_begin();
  while(vit != tr2.finite_vertices_end()) {

    // making an integer representation of vertex pointers
    V[vit] = inum++;

    // obtaining vertex positions from vertex pointer vit
    Point p = static_cast<Point>(vit->point());
    std::cout << p.x() << " " << p.y() << " " << p.z() << std::endl;

    ++vit;
  }

  Finite_facets_iterator fit = tr2.finite_facets_begin();

  while (fit != tr2.finite_facets_end()) {

    typename Tr::Cell_handle cell = fit->first;
    const int& index = fit->second;

    int index1 = V[cell->vertex(tr.vertex_triple_index(index, 0))];
    int index2 = V[cell->vertex(tr.vertex_triple_index(index, 1))];
    int index3 = V[cell->vertex(tr.vertex_triple_index(index, 2))];

    std::cout << index1 << " " << index2 << " " << index3 << std::endl;
    ++fit;
  }

}

compile it with (if mesh_implicit_function is source, object file, and executable):

c++   -DCGAL_USE_GMP -DCGAL_USE_MPFR -DCGAL_USE_ZLIB -frounding-math -o mesh_an_implicit_function.cpp.o -c mesh_an_implicit_function.cpp
c++ mesh_an_implicit_function.cpp.o  -o mesh_an_implicit_function -lmpfr -lgmp -lCGAL -lboost_thread
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文