当前位置: 首页 > news >正文

CGAL CGAL::Polygon_mesh_processing::self_intersections解析

CGAL::Polygon_mesh_processing::self_intersections 是用于检测多边形网格(Polygon Mesh)中的自相交的函数。自相交是指网格中的某些面(例如三角形)与同一网格中的其他面交叉的情况。这种情况通常是不期望的,因为它会导致网格的不一致性和潜在的几何错误。

    std::vector<std::pair<Mesh::face_index, Mesh::face_index>> self_intersections;CGAL::Polygon_mesh_processing::self_intersections(mesh,std::back_inserter(self_intersections));

关键代码:


// Checks for 'real' intersections, i.e. not simply a shared vertex or edge
template <class GT, class TM, class VPM>
bool do_faces_intersect(typename Triangle_mesh_and_triangle_soup_wrapper<TM>::face_descriptor fh,typename Triangle_mesh_and_triangle_soup_wrapper<TM>::face_descriptor fg,const TM& tmesh,const VPM vpmap,const typename GT::Construct_segment_3& construct_segment,const typename GT::Construct_triangle_3& construct_triangle,const typename GT::Do_intersect_3& do_intersect)
{typedef Triangle_mesh_and_triangle_soup_wrapper<TM>       Wrapper;typedef typename Wrapper::vertex_descriptor     vertex_descriptor;typedef typename GT::Segment_3                            Segment;typedef typename GT::Triangle_3                          Triangle;std::array<vertex_descriptor, 3> hv, gv;Wrapper::get_face_vertices(fh, hv, tmesh);Wrapper::get_face_vertices(fg, gv, tmesh);// check for shared edgestd::array<vertex_descriptor, 4> verts;if (Wrapper::faces_have_a_shared_edge(fh, fg, verts, tmesh)){if (verts[2]==verts[3]) return false; // only for a soup of triangles// there is an intersection if the four points are coplanar and the triangles overlapif(CGAL::coplanar(get(vpmap, verts[0]),get(vpmap, verts[1]),get(vpmap, verts[2]),get(vpmap, verts[3])) &&CGAL::coplanar_orientation(get(vpmap, verts[0]),get(vpmap, verts[1]),get(vpmap, verts[2]),get(vpmap, verts[3]))== CGAL::POSITIVE){return true;}else{// there is a shared edge but no intersectionreturn false;}}// check for shared vertex --> maybe intersection, maybe notint i(0), j(0);bool shared = false;for(; i<3 && (! shared); ++i){for(j=0; j<3 && (! shared); ++j){if(hv[i] == gv[j]){shared = true;break;}}if(shared)break;}if(shared){// found shared vertex:CGAL_assertion(hv[i] == gv[j]);// geometric check if the opposite segments intersect the trianglesconst Triangle t1 = construct_triangle(get(vpmap, hv[0]), get(vpmap, hv[1]), get(vpmap, hv[2]));const Triangle t2 = construct_triangle(get(vpmap, gv[0]), get(vpmap, gv[1]), get(vpmap, gv[2]));const Segment s1 = construct_segment(get(vpmap, hv[(i+1)%3]), get(vpmap, hv[(i+2)%3]));const Segment s2 = construct_segment(get(vpmap, gv[(j+1)%3]), get(vpmap, gv[(j+2)%3]));if(do_intersect(t1, s2))return true;else if(do_intersect(t2, s1))return true;return false;}// check for geometric intersectionconst Triangle th = construct_triangle(get(vpmap, hv[0]), get(vpmap, hv[1]), get(vpmap, hv[2]));const Triangle tg = construct_triangle(get(vpmap, gv[0]), get(vpmap, gv[1]), get(vpmap, gv[2]));if(do_intersect(th, tg))return true;return false;
}

解析:

1.初步筛选

将每个三角形的Bbox计算出来,再调用CGAL::box_self_intersection_d,使用分段树算法,快速筛选两两相交的Bbox对,此时得到的三角形对有可能相交,有可能只是相邻但不相交

//self_intersections_impltypedef internal::Strict_intersect_faces<Box, TM, VPM, GT, FacePairOutputIterator> Intersecting_faces_filter;Intersecting_faces_filter intersect_faces(tmesh, vpmap, gt, out);//省略......CGAL::box_self_intersection_d<CGAL::Sequential_tag>(box_ptr.begin(), box_ptr.end(), intersect_faces, cutoff);

2.精确判断

当检测到两个Bbox相交,box_self_intersection_d函数会调用函数对象(第三个参数Intersecting_faces_filter)的成员 void operator()(const Box* b, const Box* c)进一步判断

template <class Box, class TM, class VPM, class GT,class OutputIterator>
struct Strict_intersect_faces // "strict" as in "not sharing a subface"
{//省略.......void operator()(const Box* b, const Box* c) const{if(do_faces_intersect<GT>(b->info(), c->info(), m_tmesh, m_vpmap, m_construct_segment,         m_construct_triangle, m_do_intersect))*m_iterator++ = std::make_pair(b->info(), c->info());}
};

do_faces_intersect的流程分三种情况,即有公共边,公共点的,没有公共边和公共顶点。

  • ① t1和t2有公共边

1.若t1和t2不共面则不相交

2.若t1和t2共面,则判断v2是否在v0v1左边,若在左边则t1和 t2相交,否则不相交

  • ② t1和t2有公共的顶点

1.判断边s1和三角形t2是否相交

2.判断边s2和三角形t1是否相交

  • ③ t1和t2没有公共边和公共顶点

调用do_intersect碰撞检测,判断是否相交

步骤②步骤③中,判断边与三角形相交、三角形与三角形相交具体看CGAL\Intersections_3里面的实现

相关文章:

CGAL CGAL::Polygon_mesh_processing::self_intersections解析

CGAL::Polygon_mesh_processing::self_intersections 是用于检测多边形网格&#xff08;Polygon Mesh&#xff09;中的自相交的函数。自相交是指网格中的某些面&#xff08;例如三角形&#xff09;与同一网格中的其他面交叉的情况。这种情况通常是不期望的&#xff0c;因为它会…...

esp32触发相机

esp32触发相机&#xff0c;测试成功上升沿触发 串口发送命令 up 20000 1 20000 触发 #include <Arduino.h>const int outputPin 12; // 输出引脚 String inputCommand ""; // 串口输入缓冲区// 解析命令参数&#xff0c;例如 "up 10 5" 解析为…...

webrtc支持h265

Webrtc播放H265的技术探索(datachannelwasm) - 飞翔天空energy - 博客园 https://github.com/ZLMediaKit/ZLMediaKit/issues/3589 [技术咨询]addStreamProxy 添加拉流代理之后&#xff0c;webrtc协议无法播放&#xff0c;其它协议正常 Issue #1808 ZLMediaKit/ZLMediaKit G…...

macos 14.0 Monoma 修改顶部菜单栏颜色

macos 14.0 设置暗色后顶部菜单栏还维持浅色&#xff0c;与整体不协调。 修改方式如下&#xff1a;...

在 Mac(ARM 架构)上安装 JDK 8 环境

文章目录 步骤 1&#xff1a;检查系统版本步骤 2&#xff1a;下载支持 ARM 的 JDK 8步骤 3&#xff1a;安装 JDK步骤 4&#xff1a;配置环境变量步骤 5&#xff1a;验证安装步骤 6&#xff1a;注意事项步骤7&#xff1a;查看Java的安装路径 在 Mac&#xff08;ARM 架构&#xf…...

Linux高阶——1123—

1、服务器版本介绍及实现 1、单进程单任务服务器&#xff08;阻塞IO&#xff09; 单进程模型&#xff0c;阻塞IO冲突&#xff0c;等待连接时无法读取数据&#xff0c;读取数据时无法连接 比较适合处理单任务&#xff0c;排队处理业务 伪代码 while(true) {addrlensizeof(c…...

VOLO实战:使用VOLO实现图像分类任务(二)

文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度&#xff0c;DP多卡&#xff0c;EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…...

【kafka02】消息队列与微服务之Kafka部署

Kafka 部署 Kafka 部署说明 kafka 版本选择 kafka 基于scala语言实现,所以使用kafka需要指定scala的相应的版本.kafka 为多个版本的Scala构建。这仅在使用 Scala 时才重要&#xff0c;并且希望为使用的相同 Scala 版本构建一个版本。否则&#xff0c;任何版本都可以 kafka下…...

MySQL系列之数据类型(Numeric)

导览 前言一、数值类型综述二、数值类型详解1. NUMERIC1.1 UNSIGNED或SIGNED1.2 数据类型划分 2. Integer类型取值和存储要求3. Fixed-Point类型取值和存储要求4. Floating-Point类型取值和存储要求 结语精彩回放 前言 MySQL系列最近三篇均关注了和我们日常工作或学习密切相关…...

BERT简单理解;双向编码器优势

目录 BERT简单理解 一、BERT模型简单理解 二、BERT模型使用举例 三、BERT模型的优势 双向编码器优势 BERT简单理解 (Bidirectional Encoder Representations from Transformers)模型是一种预训练的自然语言处理(NLP)模型,由Google于2018年推出。以下是对BERT模型的简…...

LLamafactory 批量推理与异步 API 调用效率对比实测

背景 在阅读 LLamafactory 的文档时候&#xff0c;发现它支持批量推理: 推理.https://llamafactory.readthedocs.io/zh-cn/latest/getting_started/inference.html 。 于是便想测试一下&#xff0c;它的批量推理速度有多快。本文实现了 下述两种的大模型推理&#xff0c;并对…...

spf算法、三类LSA、区间防环路机制/规则、虚连接

1.构建spf树&#xff1a; 路由器将自己作为最短路经树的树根根据Router-LSA和Network-LSA中的拓扑信息,依次将Cost值最小的路由器添加到SPF树中。路由器以Router ID或者DR标识。广播网络中DR和其所连接路由器的Cost值为0。SPF树中只有单向的最短路径,保证了OSPF区域内路由计管不…...

C语言学习 12(指针学习1)

一.内存和地址 1.内存 在讲内存和地址之前&#xff0c;我们想有个⽣活中的案例&#xff1a; 假设有⼀栋宿舍楼&#xff0c;把你放在楼⾥&#xff0c;楼上有100个房间&#xff0c;但是房间没有编号&#xff0c;你的⼀个朋友来找你玩&#xff0c;如果想找到你&#xff0c;就得挨…...

TypeError: issubclass() arg 1 must be a class

TypeError: issubclass() arg 1 must be a class 报错代码&#xff1a; import spacy 原因&#xff1a; 库版本错误&#xff0c; 解决方法&#xff1a; pip install typing-inspect0.8.0 typing_extensions4.5.0 感谢作者&#xff1a; langchain TypeError: issubclass() …...

Java面试题、八股文学习之JVM篇

1.对象一定分配在堆中吗&#xff1f;有没有了解逃逸分析技术&#xff1f; 对象不一定总是分配在堆中。在Java等一些高级编程语言中&#xff0c;对象的分配位置可以通过编译器或运行时系统的优化来决定。其中&#xff0c;逃逸分析&#xff08;Escape Analysis&#xff09;是用于…...

【eNSP】动态路由协议RIP和OSPF

动态路由RIP&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;和OSPF&#xff08;Open Shortest Path First&#xff0c;开放式最短路径优先&#xff09;是两种常见的动态路由协议&#xff0c;它们各自具有不同的特点和使用场景。本篇会对这两种协…...

春秋云境 CVE 复现

CVE-2022-4230 靶标介绍 WP Statistics WordPress 插件13.2.9之前的版本不会转义参数&#xff0c;这可能允许经过身份验证的用户执行 SQL 注入攻击。默认情况下&#xff0c;具有管理选项功能 (admin) 的用户可以使用受影响的功能&#xff0c;但是该插件有一个设置允许低权限用…...

Linux入门攻坚——39、Nginx入门

Nginx&#xff1a;engine X Tengine&#xff1a;淘宝改进维护的版本 Registry&#xff1a; 使用了libevent库&#xff1a;高性能的网络库 epoll()函数 Nginx特性&#xff1a; 模块化设计、较好的扩展性&#xff1b;&#xff08;但不支持动态加载模块功能&#…...

计算机网络的类型

目录 按覆盖范围分类 个人区域网&#xff08;PAN&#xff09; 局域网&#xff08;LAN&#xff09; 城域网&#xff08;MAN&#xff09; 4. 广域网&#xff08;WAN&#xff09; 按使用场景和性质分类 公网&#xff08;全球网络&#xff09; 外网 内网&#xff08;私有网…...

解决 MySQL 5.7 安装中的常见问题及解决方案

目录 前言1. 安装MySQL 5.7时的常见错误分析1.1 错误原因及表现1.2 错误的根源 2. 解决方案2.1 修改YUM仓库配置2.2 重新尝试安装2.3 处理GPG密钥错误2.4 解决依赖包问题 3. 安装成功后的配置3.1 启动MySQL服务3.2 获取临时密码3.3 修改root密码 4. 结语 前言 在Linux服务器上…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...