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博客

相关推荐
阿伟来咯~19 分钟前
记录学习react的一些内容
javascript·学习·react.js
Suckerbin41 分钟前
Hms?: 1渗透测试
学习·安全·网络安全
水豚AI课代表1 小时前
分析报告、调研报告、工作方案等的提示词
大数据·人工智能·学习·chatgpt·aigc
聪明的墨菲特i1 小时前
Python爬虫学习
爬虫·python·学习
Diamond技术流1 小时前
从0开始学习Linux——网络配置
linux·运维·网络·学习·安全·centos
斑布斑布1 小时前
【linux学习2】linux基本命令行操作总结
linux·运维·服务器·学习
Chef_Chen2 小时前
从0开始学习机器学习--Day13--神经网络如何处理复杂非线性函数
神经网络·学习·机器学习
lulu_gh_yu2 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
Re.不晚3 小时前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
幼儿园老大*4 小时前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go