Surface mesh结构学习

CGAL 5.6 - Surface Mesh: User Manual

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结构

cpp 复制代码
#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都要求是非自相交的模型。现在来检查以下上述模型是否自相交

cpp 复制代码
#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的所有点

cpp 复制代码
#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点、边、面的关联点

cpp 复制代码
#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;
}

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

相关推荐
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意5 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码5 天前
嵌入式学习路线
学习
毛小茛5 天前
计算机系统概论——校验码
学习
babe小鑫5 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms5 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下5 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。5 天前
2026.2.25监控学习
学习
im_AMBER5 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J5 天前
从“Hello World“ 开始 C++
c语言·c++·学习