Surface mesh结构学习

CGAL 5.6 - Surface Mesh: User Manual

目录

1、新建Surface_mesh结构

2、自相交判断

3、获取Surface_Mesh的所有点  

4、获取Surface_Mesh点、边、面的关联点

5、自定义点的名称


Surface_mesh 类是半边数据结构的实现,可用来表示多面体表面。它是半边数据结构(Halfedge Data Structures)和三维多面体表面(3D Polyhedral Surface)这两个 CGAL 软件包的替代品。其主要区别在于它是基于索引的,而不是基于指针的。此外,向顶点、半边、边和面添加信息的机制要简单得多,而且是在运行时而不是编译时完成的。

由于数据结构使用整数索引作为顶点、半边、边和面的描述符,因此它的内存占用比基于指针的 64 位版本更少。由于索引是连续的,因此可用作存储属性的向量索引。

当元素被移除时,它们只会被标记为已移除,必须调用垃圾回收函数才能真正移除它们。

Surface_mesh 提供了四个嵌套类,分别代表半边数据结构的基本元素:

Surface_mesh::Vertex_index曲面网格::顶点索引
Surface_mesh::Halfedge_index曲面网格::半边索引
Surface_mesh::Face_index曲面网格::面索引
Surface_mesh::Edge_index曲面网格::边索引

1、新建Surface_mesh结构

#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/self_intersections.h>

typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh; //mesh结构
typedef Mesh::Vertex_index vertex_descriptor;
typedef Mesh::Face_index face_descriptor;


int main()
{
	Mesh m;

	// Add the points as vertices
	vertex_descriptor u = m.add_vertex(K::Point_3(0, 1, 0));
	vertex_descriptor v = m.add_vertex(K::Point_3(0, 0, 0));
	vertex_descriptor w = m.add_vertex(K::Point_3(1, 1, 0));

	m.add_face(u, v, w);
	int num = num_faces(m); //结果num = 1

	return 0;
}

2、自相交判断

在很多算法中,对于输入的Mesh都要求是非自相交的模型。现在来检查以下上述模型是否自相交

#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/self_intersections.h>

typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh; //mesh结构
typedef Mesh::Vertex_index vertex_descriptor;
typedef Mesh::Face_index face_descriptor;


int main()
{
	Mesh m;

	// Add the points as vertices
	vertex_descriptor u = m.add_vertex(K::Point_3(0, 1, 0));
	vertex_descriptor v = m.add_vertex(K::Point_3(0, 0, 0));
	vertex_descriptor w = m.add_vertex(K::Point_3(1, 1, 0));
	vertex_descriptor x = m.add_vertex(K::Point_3(1, 0, 0));

	m.add_face(u, v, w);
	int num = num_faces(m); //结果num = 1

	face_descriptor f = m.add_face(u, v, x);
	if (f == Mesh::null_face())
	{
		std::cerr << "The face could not be added because of an orientation error." << std::endl;
		//结果intersect = true; 即当前模型为自相交模型
		bool intersect = CGAL::Polygon_mesh_processing::does_self_intersect(m);
		std::cout << "intersect:"<< intersect << std::endl;
		assert(f != Mesh::null_face());


		f = m.add_face(u, x, v);
		num = num_faces(m);
		//结果intersect = true; 即当前模型为自相交模型
		intersect = CGAL::Polygon_mesh_processing::does_self_intersect(m);
		std::cout << "intersect:" << intersect << std::endl;
		assert(f != Mesh::null_face());

	}
	std::cout << num << std::endl;
	return 0;
}

3、获取Surface_Mesh的所有点  

#include <vector>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>

typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
typedef Mesh::Vertex_index vertex_descriptor;
typedef Mesh::Face_index face_descriptor;
int main()
{
    Mesh m;

    // u            x
    // +------------+
    // |            |
    // |            |
    // |      f     |
    // |            |
    // |            |
    // +------------+
    // v            w

    // Add the points as vertices
    vertex_descriptor u = m.add_vertex(K::Point_3(0, 1, 0));
    vertex_descriptor v = m.add_vertex(K::Point_3(0, 0, 0));
    vertex_descriptor w = m.add_vertex(K::Point_3(1, 0, 0));
    vertex_descriptor x = m.add_vertex(K::Point_3(1, 1, 0));

    /* face_descriptor f = */ m.add_face(u, v, w, x);

    {
        std::cout << "all vertices " << std::endl;

        // The vertex iterator type is a nested type of the Vertex_range
        Mesh::Vertex_range::iterator  vb, ve;

        Mesh::Vertex_range r = m.vertices();
        // The iterators can be accessed through the C++ range API
        vb = r.begin();
        ve = r.end();

        // or with boost::tie, as the CGAL range derives from std::pair
        for (boost::tie(vb, ve) = m.vertices(); vb != ve; ++vb) {
            std::cout << *vb << std::endl;
        }
        // Instead of the classical for loop one can use
        // the boost macro for a range
        for (vertex_descriptor vd : m.vertices()) {
            std::cout << vd << std::endl;
        }


    }

    return 0;
}

4、获取Surface_Mesh点、边、面的关联点

#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>

#include <vector>

typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
typedef Mesh::Vertex_index vertex_descriptor;
typedef Mesh::Face_index face_descriptor;

int main()
{
    Mesh m;

    // u            x
    // +------------+
    // |            |
    // |            |
    // |      f     |
    // |            |
    // |            |
    // +------------+
    // v            w

    // Add the points as vertices
    vertex_descriptor u = m.add_vertex(K::Point_3(0, 1, 0));
    vertex_descriptor v = m.add_vertex(K::Point_3(0, 0, 0));
    vertex_descriptor w = m.add_vertex(K::Point_3(1, 0, 0));
    vertex_descriptor x = m.add_vertex(K::Point_3(1, 1, 0));

    face_descriptor f = m.add_face(u, v, w, x);

    {
        std::cout << "vertices around vertex " << v << std::endl;
        CGAL::Vertex_around_target_circulator<Mesh> vbegin(m.halfedge(v), m), done(vbegin);

        do {
            std::cout << *vbegin++ << std::endl;
        } while (vbegin != done);
    }

    {
        std::cout << "vertices around face " << f << std::endl;
        CGAL::Vertex_around_face_iterator<Mesh> vbegin, vend;
        for (boost::tie(vbegin, vend) = vertices_around_face(m.halfedge(f), m);
            vbegin != vend;
            ++vbegin) {
            std::cout << *vbegin << std::endl;
        }
    }
    std::cout << "=====" << std::endl;
    // or the same again, but directly with a range based loop
    for (vertex_descriptor vd : vertices_around_face(m.halfedge(f), m)) {
        std::cout << vd << std::endl;
    }


    return 0;
}

5、自定义点的名称

#include <string>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
typedef Mesh::Vertex_index vertex_descriptor;
typedef Mesh::Face_index face_descriptor;
int main()
{
    Mesh m;
    vertex_descriptor v0 = m.add_vertex(K::Point_3(0, 2, 0));
    vertex_descriptor v1 = m.add_vertex(K::Point_3(2, 2, 0));
    vertex_descriptor v2 = m.add_vertex(K::Point_3(0, 0, 0));
    vertex_descriptor v3 = m.add_vertex(K::Point_3(2, 0, 0));
    vertex_descriptor v4 = m.add_vertex(K::Point_3(1, 1, 0));

    m.add_face(v3, v1, v4);
    m.add_face(v0, v4, v1);
    m.add_face(v0, v2, v4);
    m.add_face(v2, v3, v4);
    // give each vertex a name, the default is empty
    Mesh::Property_map<vertex_descriptor, std::string> name;

    bool created;
    boost::tie(name, created) = m.add_property_map<vertex_descriptor, std::string>("v:name", "");
    assert(created);
    // add some names to the vertices
    name[v0] = "hello";
    name[v2] = "world";

    // retrieve the point property for which exists a convenience function
    Mesh::Property_map<vertex_descriptor, K::Point_3> location = m.points();
    for (vertex_descriptor vd : m.vertices()) {
        std::cout << name[vd] << " 点坐标: " << location[vd] << std::endl;
    }
    std::vector<std::string> props = m.properties<vertex_descriptor>();
    for (std::string p : props) {
        std::cout << p << std::endl;
    }
    // delete the string property again
    m.remove_property_map(name);
    return 0;
}

注意一下boost::tie

`boost::tie`是Boost库中的一个实用函数,它用于将多个变量绑定到一个tuple(元组)的各个元素上。这使得你可以一次性从一个tuple中分别获取多个值,而不需要逐一访问每个元素。`boost::tie`在处理那些返回多个值的函数时特别有用,尤其是当这些值被打包成一个tuple或pair时。

让我们来详细解释一下`boost::tie`的作用和如何使用它:

### 基本概念

- **Tuple**:一个tuple是一个可以存储不同类型值的固定大小的容器。例如,一个`std::pair`可以被视为一个两元素的tuple。
- **绑定(Tie)**:绑定的概念是指将多个变量关联到一个复合对象(如tuple或pair)的不同部分。

### 使用`boost::tie`

在不使用`boost::tie`的情况下,如果你想从一个返回tuple或pair的函数中获取多个值,你通常需要创建一个tuple或pair变量,然后分别访问它的元素。例如:

```cpp
std::pair<int, bool> result = some_function();
int value = result.first;
bool flag = result.second;
```

使用`boost::tie`可以使这个过程更简洁:

```cpp
int value;
bool flag;
boost::tie(value, flag) = some_function();
```

在这个示例中,`some_function`返回一个包含两个元素的pair(或tuple)。使用`boost::tie`,你可以直接将这两个元素分别绑定到`value`和`flag`变量上。

### 在CGAL中的应用

在CGAL中,`boost::tie`常用于处理那些返回pair或tuple的函数。例如,`add_property_map`函数返回一个pair,包含创建的属性映射和一个布尔值,指示映射是否是新创建的。通过`boost::tie`,你可以直接将这两个值分别绑定到两个变量上:

```cpp
Mesh::Property_map<vertex_descriptor, std::string> name;
bool created;
boost::tie(name, created) = m.add_property_map<vertex_descriptor, std::string>("v:name", "");
```

这里,`name`被绑定到属性映射上,而`created`被绑定到布尔标志上,表明映射是否新创建。

总之,`boost::tie`是一种在C++中同时处理多个返回值的便捷方式,特别是当这些值被打包在一个tuple或pair中时。

 

【CGAL系列】---了解Surface_Mesh-CSDN博客

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江河地笑

实践是检验真理的唯一标准

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值