Surface mesh结构学习

news2024/9/29 15:19:02

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

#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;
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1379074.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

竞赛保研 基于深度学的图像修复 图像补全

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学的图像修复 图像补全 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-se…

【二十】【动态规划】879. 盈利计划、377. 组合总和 Ⅳ、96. 不同的二叉搜索树 ,三道题目深度解析

动态规划 动态规划就像是解决问题的一种策略&#xff0c;它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题&#xff0c;并将每个小问题的解保存起来。这样&#xff0c;当我们需要解决原始问题的时候&#xff0c;我们就可以直接利…

Gauss消去法(C++)

文章目录 算法描述顺序Gauss消去法列选主元Gauss消去法全选主元Gauss消去法Gauss-Jordan消去法 算法实现顺序Gauss消去法列选主元Gauss消去法全选主元Gauss消去法列选主元Gauss-Jordan消去法 实例分析 Gauss消去法是求解线性方程组较为有效的方法, 它主要包括两个操作, 即消元和…

TypeScript学习笔记、鸿蒙开发学习笔记

变量定义方式 # 变量声明 let msg: string douzi console.log(msg) let num: number 20 console.log(num) let end: boolean true console.log("end" end) let a: any 10 a douzi console.log(a) let p {name:"douzi",age:20} console.log(p.name)…

30天精通Nodejs--第十七天:express-路由配置

目录 引言基础路由配置路由参数与查询参数路由前缀与子路由路由重定向结语 引言 上篇文章我们简单介绍了express的基础用法&#xff0c;包括express的安装、创建路由及项目启动&#xff0c;对express有了一个基础的了解&#xff0c;这篇开始我们将详细介绍express的一些高级用…

docker安装nacos+mysql+配置网络

一、配置网络 为什么要配置网络&#xff1f;因为 Nacos 内要连接MySQL数据库的&#xff0c;我的 MySQL 数据库也是用 Docker启动的&#xff0c;所以2个容器间要通信是需要配置他们使用相同的网络。这个操作要在启动Nacos容器之前。 注意&#xff1a;这里配置的网络只在镜像内部…

聚对苯二甲酸乙二醇酯PET的特性有哪些?UV胶水能够粘接聚对苯二甲酸乙二醇酯PET吗?又有哪些优势呢?

聚对苯二甲酸乙二醇酯&#xff08;Polyethylene Terephthalate&#xff0c;PET&#xff09;是一种常见的塑料材料&#xff0c;具有许多特性&#xff0c;包括&#xff1a; 1.化学式&#xff1a; PET的化学式为 (C10H8O4)n&#xff0c;其中n表示重复单元的数量。 2.透明度&#…

掌握 gRPC 和 RPC 的关键区别

一、远程过程调用协议简介 1、RPC 的本质 首先&#xff0c;我们探讨一下什么是 RPC。RPC&#xff0c;缩写为 Remote Procedure Call Protocol&#xff0c;直译来看就是远程过程调用协议。 讲得通俗一些&#xff1a; RPC 是一种通信机制RPC 实现了客户端/服务器通信模型 官…

【大厂秘籍】 - Redis持久化篇

创作不易&#xff0c;你的关注分享就是博主更新的最大动力&#xff0c; 每周持续更新 微信搜索【 企鹅君】关注还能领取学习资料喔&#xff0c;第一时间阅读(比博客早两到三篇) 求关注❤️ 求点赞❤️ 求分享❤️ 对博主真的非常重要 企鹅君原创&#xff5c;GitHub开源项目gith…

【算法】信使(最短路问题)

题目 战争时期&#xff0c;前线有 n 个哨所&#xff0c;每个哨所可能会与其他若干个哨所之间有通信联系。 信使负责在哨所之间传递信息&#xff0c;当然&#xff0c;这是要花费一定时间的&#xff08;以天为单位&#xff09;。 指挥部设在第一个哨所。 当指挥部下达一个命令…

<软考高项备考>《论文专题 - 63 质量管理(2) 》

2 过程1-规划质量管理 2.1 问题 4W1H过程做什么识别项目及其可交付成果的质量要求、标准&#xff0c;并书面描述项目将如何证明符合质量要求、标准的过程&#xff1b;作用&#xff1a;为在整个项目期间如何管理和核实质量提供指南和方向为什么做1、识别项目/产品质量要求和标…

debian 11 arm64 aarch64 D2000 平台编译 box86 box64 笔记

参考资料 https://github.com/ptitSeb/box86/blob/master/docs/COMPILE.md 源码地址 GitHub - ptitSeb/box86: Box86 - Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices deb在线源地址&#xff08;打不开&#xff09;&#xff1a; Itais box86…

两个阅读英文论文的免费AI工具

大家好啊&#xff0c;我是董董灿。 本文会介绍我平时用到的两个免费的基于GPT的论文阅读平台&#xff0c;很好用&#xff0c;对于有英文阅读困难症的小伙伴(比如我)是真的提效。 1、 英文阅读困难症 在我的工作以及业余学习中&#xff0c;会时不时的需要翻看一些英文论文&…

GitLab任意用户密码重置漏洞(CVE-2023-7028)

GitLab CVE-2023-7028 POC user[email][]validemail.com&user[email][]attackeremail.com 本文链接&#xff1a; https://www.黑客.wang/wen/47.html

JavaScript保留字和预定义的全局变量及函数汇总

保留字也称关键字&#xff0c;每种语言中都有该语言本身规定的一些关键字&#xff0c;这些关键字都是该语言的语法实现基础&#xff0c;JavaScript中规定了一些标识符作为现行版本的关键字或者将来版本中可能会用到的关键字&#xff0c;所以当我们定义标识符时就不能使用这些关…

【Git】本地仓库文件的创建、修改和删除

目录 一、基本信息设置 1、设置用户名2、设置用户名邮箱 二、Git仓库操作介绍 1、创建一个新的文件夹2、在文件内初始化git仓库&#xff08;创建git仓库&#xff09;3、向仓库中添加文件 1.创建一个文件2.将文件添加到暂存区3.将暂存区添加到仓库 4、修改仓库文件 1.修改文件2.…

汽车级线性电压稳压器LM317MBSTT3G:新能源汽车的理想之选

LM317MBSTT3G是一款可调三端子正向线性稳压器&#xff0c;能够在 1.2 V 至 37 V 的输出电压范围内提供 500 mA 以上的电流。此线性电压稳压器使用非常简便&#xff0c;仅需两个外部电阻即可设置输出电压。另外&#xff0c;它采用内部电流限制、高温关断和安全区域补偿&#xff…

边缘计算:连接实时数据的力量与未来发展之路

边缘计算是一种分布式计算范式&#xff0c;它旨在将数据处理、存储和应用服务带到数据源的近端&#xff0c;即网络的“边缘”。在边缘计算模型中&#xff0c;算力和存储资源距离末端用户或数据源更近&#xff0c;这减少了数据在网络中传输的距离&#xff0c;从而降低延迟&#…

【Web】token机制

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Web ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 机制基本&#xff1a; 优势&#xff1a; 结语 我的其他博客 前言 在当今互联网时代&#xff0c;安全、高效的用户身份验证和资源授…

关于Python里xlwings库对Excel表格的操作(三十二)

这篇小笔记主要记录如何【如何使用“Chart类”、“Api类"和“Axes函数”设置坐标轴标题文本内容】。 前面的小笔记已整理成目录&#xff0c;可点链接去目录寻找所需更方便。 【目录部分内容如下】【点击此处可进入目录】 &#xff08;1&#xff09;如何安装导入xlwings库…