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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何关闭iPhone 14或14 Pro Max,这里有详细步骤

你刚买了新的iphone 14或iphone 14 pro max&#xff0c;迫不及待地想开始使用它。但如果你需要关闭它怎么办&#xff1f;有几种方法可以用来关闭这两种设备。 如何关闭iPhone 14 你可以通过每个人都熟悉的老式侧按钮轻松关闭iPhone 14&#xff0c;也可以通过面部识别关闭它。 …

Unity之角色控制器

PS:公司终于给我派任务了&#xff0c;最近几天都没学Unity&#x1f927;。 一、角色控制器的实现方式 目前小编知道的角色控制器实现方式有三种&#xff1a; 应用商店的角色控制系统Unity自己的角色控制器通过物理系统去做角色控制器 本篇介绍的是第二种Unity自己的角色控制…

电商新趋势:解析养号的必要性及海外云手机运用攻略

在电商领域&#xff0c;什么最为关键&#xff1f;答案无疑是流量&#xff01;然而&#xff0c;如何以较低成本获取大量流量成为了许多电商从业者头疼的问题。虽然直接投放广告是一种方式&#xff0c;但在内卷的情况下效果越来越难以令人满意&#xff0c;高昂的广告费用也原来越…

Java零基础教学文档第三篇:JDBC

今日新篇章 【JDBC】 【主要内容】 JDBC概述 使用JDBC完成添加操作 使用JDBC完成更新和删除 DBUtils的简单封装 使用JDBC完成查询 使用JDBC完成分页查询 常用接口详解 JDBC批处理 SQL注入问题 事务处理解决转账问题 连接池 使用反射对DBUtils再次的封装 BaseDAO的封…

供水管网动态模型分类及应用分析

当供水管网中发生启停泵、快速关阀等事件时, 延时时段模拟 (即准稳态模型) 不能准确预测系统的瞬时动态变化, 而需要采用更为准确复杂的瞬变流动态模型。为明确多种动态模型之间的差异, 探讨和分析了供水管网动态模型的分类、模型理论以及在管网运行管理中的应用。结果表明, 准…

react 项目结构配置

1 项目整体目录结构的搭建 如下图&#xff1a; 2 重置css样式: normalize.css reset.less ; 第一步 安装 npm i normalize.css 入口文件index.tsx导入&#xff1a;import ‘noremalize.css’ 第二步 创建自己的css样式&#xff1a;在assets文件夹中创建css…

关于mysql OR使用的细节,加上()避免OR扩大sql查询范围

错误场景描述&#xff1a;现在在我的预约订单里面截止日期明明已经超过了当前时间却还显示&#xff0c;这个时候正常逻辑是只显示在历史订单中的。 错误归因&#xff1a;关于下面这段查询中 这一组条件加上&#xff08;&#xff09;与不加上括号天差地别&#xff0c;也是导致业…

网络安全全栈培训笔记(WEB攻防-51-WEB攻防-通用漏洞验证码识别复用调用找回密码重定向状态值)

第51天 WEB攻防-通用漏洞&验证码识别&复用&调用&找回密码重定向&状态值 知识点&#xff1a; 1、找回密码逻辑机制-回显&验证码&指向 2、验证码验证安全机制-爆破&复用&识别 3、找回密码客户端回显&Response状态值&修改重定向 4、…

使用nginx+HTML2canvas将任意html网页转为png图片自定义张数

文章目录 概述网页的转换html2canvas的使用导入导入HTML2canvas库函数定义 nginx部署编写控制截图网页代码iframe 网页控制代码 测试说明 概述 本文简述如何使用nginxhtml2canvas将任意网页html转为png图片 网页的转换 如果是本地网页&#xff0c;直接进行nginx反向代理就行…

DFT中的SCAN、BIST、ATPG基本概念

DFT中的SCAN、BIST、ATPG基本概念 SCAN 定义 扫描路径法是一种针对时序电路芯片的DFT方案&#xff0c;目标是在不影响正常功能的情况下来能够提高可控性和可观测性。 原理 原理是将时序电路可以模型化为一个组合电路网络和带触发器(Flip-Flop&#xff0c;简称FF)的时序电路…

vue开发H5 实现滑动图片获取验证码

<template><div><van-button type"primary" click"sendVerification">获取验证码</van-button><van-popupv-model"captchaVisible"closeableposition"bottom"class"login-captcha":close-on-cli…

Java接入Apache Spark(入门环境搭建、常见问题)

Java接入Apache Spark&#xff08;环境搭建、常见问题&#xff09; 背景介绍 Apache Spark 是一个快速的&#xff0c;通用的集群计算系统。它对 Java&#xff0c;Scala&#xff0c;Python 和 R 提供了的高层 API&#xff0c;并有一个经优化的支持通用执行图计算的引擎。它还支…

腾讯云服务器建站教程——2024更新部署网站教程

使用腾讯云服务器搭建网站全流程&#xff0c;包括轻量应用服务器和云服务器CVM建站教程&#xff0c;轻量可以使用应用镜像一键建站&#xff0c;云服务器CVM可以通过安装宝塔面板的方式来搭建网站&#xff0c;腾讯云服务器网txyfwq.com分享使用腾讯云服务器建站教程&#xff0c;…

UCB Data100:数据科学的原理和技巧:第二十一章到第二十六章

二十一、SQL II 原文&#xff1a;SQL II 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 学习成果 介绍过滤组的能力 在 SQL 中执行数据清理和文本操作 跨表连接数据 在本讲座中&#xff0c;我们将继续上次的工作&#xff0c;介绍一些高级的 SQL 语法。 首先&…

【kafka】记录用-----------1

主题&#xff08;topic&#xff09;&#xff1a;消息的第一次分类 根据人为的划分条件将消息分成不同的主题 主题的划分是人为的根据不同的任务情景去划分 比如&#xff0c;我们有两个主题&#xff0c;一个是"订单"&#xff0c;另一个是"库存"。每个主题代…

eureka-server项目工程搭建、linux集群部署

Eureka是Netflix开发的服务发现框架&#xff0c;本身是一个基于REST的服务&#xff0c;主要用于定位运行在AWS域中的中间层服务&#xff0c;以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中&#xff0c;以实现SpringCloud的服…

与纸质合同相比,电子合同有哪些优势?

在无纸化办公的当下&#xff0c;电子合同软件成为了企业数字化转型必不可少的工具。而随着国内电子合同软件功能的完善&#xff0c;电子合同拥有便捷&#xff0c;安全&#xff0c;功能等要素&#xff0c;因此&#xff0c;电子合同是更多人的选择方式。 电子合同指的是双方或者多…

antd时间选择器,设置显示中文

需求 在实现react&#xff0c;里面引入antd时间选择器&#xff0c;默认显示为英文 思路 入口处使用ConfigProvider全局化配置&#xff0c;设置 locale 属性为中文来实现。官方文档介绍全局化配置 ConfigProvider - Ant Design 代码 import React from react; import { Prov…

Shutter Encoder多媒体转换v17.8

软件介绍 多媒体包含种类繁多的各种文件格式&#xff0c;每种格式都有其不同的特征和所谓的“怪癖”。 因此&#xff0c;如果使用多种图像、视频或音频格式&#xff0c;找到一个集中的软件来从一个地方处理所有这些格式可能会非常棘手。 这就是 Shutter Encoder 基本上允许做的…

Git的安装

1、下载 官网地址&#xff1a; https://git-scm.com/或https://github.com/git-for-windows/git/releases 百度网盘链接&#xff1a;链接&#xff1a;https://pan.baidu.com/s/13_asGO-XQb5KWWH_V7rq6g?pwd0630 2、安装 ①查看GNU协议&#xff0c;可以直接点击下一步。 ②…