CGAL的三维曲面细分方法

news2025/1/29 14:08:32

1、介绍

        细分方法是从任意多边形网格生成平滑曲面的简单而强大的方法。与基于样条曲面的方法(如NURBS)或其他基于数字的建模技术不同,细分方法的使用者不需要掌握细分方法的数学知识。几何的直观性足以控制细分方法。

        Subdivision_method_3适用于Polyhedron_3和Surface_mesh类,因为它们是MutatableFaceGraph概念的模型,并且旨在易于使用和扩展。 Subdivision_method_3不是一个类,而是一个包含四种流行细分方法及其细化函数的命名空间。 这些方法包括Catmull-Clark、Loop、Doo-Sabin和3-√细分。 通过替换细化规则的几何计算,可以很容易地扩展这些方法的变体。

2、细分方法

       在拓扑学中,流形是局部具有欧几里得空间性质的空间。如果一个拓扑空间是可微的,那么它就是一个流形。如果一个流形只有有限个不相交的连通组件,那么它就是一个流形。2-流形是一个二维的流形。

        在本章中,我们解释了细分方法的一些基本原理。我们只关注那些有助于你理解这个包的设计的主题。本节中介绍的一些术语将在后面的章节中再次使用。

        细分方法递归细化粗糙网格,并生成与光滑曲面越来越接近的近似值。粗糙网格可以有任意形状,但它必须是2-流形。在2-流形中,每个内部点都有一个与2D圆盘同胚的邻域。非流形上的细分方法已经开发出来,但在Subdivision_method_3中没有考虑。本章的预告片展示了CAD模型上Catmull-Clark细分的步骤。粗糙网格通过四分模式反复细化,并生成新点以近似光滑曲面。

        实践中使用了许多细分模式。 Subdivision_method_3支持四种最流行的模式,每种模式都由Catmull-Clark、Loop、Doo-Sabin和3-√细分(下图从左到右)使用。我们根据拓扑特征而不是相关的细分方法来命名这些模式。PQQ表示原始四边形四等分。PTQ表示原始三角形四等分。DQQ表示对偶四边形四等分。3-√表示三角剖分向细分曲面的收敛速度。

        这个图表展示了这四种细分模式的应用,下面的源网格展示了细分的网格。细分网格上的点是通过平均源网格上的相邻点来生成的。一个称为模板的图形决定了源邻域,该邻域的点有助于确定细分点的位置。细分模式通常定义了多个模板。例如,PQQ细分具有一个顶点模板,它定义了输入顶点的1-ring;一个边模板,它定义了输入边的1-ring;以及一个面模板,它定义了输入面。PQQ细分的模板在下图中显示。顶部的蓝色区域表示红色细分节点的相应模板。 

        带权重的模板被称为几何掩码。细分方法为每个模板定义一个几何掩码,并通过加权掩码的源点平均值来生成新点。几何掩码是精心选择的,以满足特定表面平滑度和形状质量的要求。Catmull-Clark细分方法的几何掩码如下所示。 

 

        此处显示的权重未标准化,n是顶点的权重。生成的点(红色)是通过加权点的求和计算出来的。例如,Catmull-Clark面节点是通过其模板上每个点的1/4求和计算出来的。

        模板可以具有无限数量的几何掩模。例如,PQQ细分的面节点可以通过每个模板节点的1/5的总和来计算,而不是1/4。虽然在Subdivision_method_3中可以使用任何类型的几何掩模,但结果表面可能是奇数、不光滑或甚至不存在的。 

3、Catmull-Clark细分

Subdivision_method_3::CatmullClark_subdivision(pmesh, params::number_of_iterations(d));

        subdivision_method_3 指定细分函数的名称空间。 CatmullClark_subdivision(P, params::number_of_iterations(d)) 计算多边形网格 pmesh 在 d 次细化迭代后的 Catmull-Clark 细分曲面。 多边形网格 pmesh 通过引用传递,并由细分函数修改(即细分)。

       应用程序定义的多边形网格可能使用专门的内核和/或专门的内部容器。使用 Subdivision_method_3 的应用程序定义的多边形网格有一个主要限制:内部容器中的基元(如顶点、半边和面)是按顺序排列的(例如 std::vector 和 std::list)。这意味着迭代器按创建/插入顺序遍历基元。

        Subdivision_method_3 旨在允许对细分方法进行定制。下面该实现演示了将 PQQ 细化定制到 Catmull-Clark 细分。

        开发细分方法时,选择细化模式,然后开发一组几何掩模来定位新点。实现细分方法有三个关键组成部分:能够表示任意2流形的网格数据结构,一种优化网格数据结构的过程,以及计算新点的几何权重。

        下面选择了PQQ细化作为他们的细分方法,并开发了一套几何掩模,用于从控制网格生成(或更精确地近似)B样条曲面。 Subdivision_method_3提供了一个函数,可以粘合Catmull-Clark细分方法的所有三个组件。

template <class PolygonMesh, class Mask, class NamedParameters>
void PQQ(PolygonMesh& p, Mask mask, NamedParameters np)

        PolygonMesh 必须是 Polyhedron_3、Surface_mesh 或 MutableFaceGraph 概念的其他模型的实例。它是用于任意二维流形的通用网格数据结构。PQQ() 是一个细化的控制网格 p,它使用策略类 Mask<PolygonMesh> 作为其几何计算的一部分。在细化过程中,PQQ() 通过与掩模合作来计算和分配新点。要实现 Catmull-Clark 细分,掩模、几何策略必须实现 Catmull-Clark 细分的几何掩模。迭代次数和顶点映射可以使用命名参数 np 指定。

        为了实现几何掩模,我们需要知道细化主体如何与其几何掩模进行通信。PQQ细化定义了三个模板,因此Catmull-Clark细分需要三个几何掩模。以下类定义了PQQ细化的模板接口。 

template <class PolygonMesh>
class PQQMask_3 {
  void face_node(boost::graph_traits<PolygonMesh>::face_descriptor face, Point_3& pt);
  void edge_node(boost::graph_traits<PolygonMesh>::halfedge_descriptor edge, Point_3& pt);
  void vertex_node(boost::graph_traits<PolygonMesh>::vertex_descriptor vertex, Point_3& pt);
};

         PQQMask_3中的每个类函数都根据基元描述符的邻域计算一个新的点,并将该新点分配给Point_3& pt。

        我们使用Catmull-Clark细分的几何掩模来实现每个类函数。

        要调用 Catmull-Clark 细分方法,我们使用刚刚定义的 Catmull-Clark 掩码调用 PQQ()。

PQQ(pmesh, CatmullClark_mask_3(pmesh), params::number_of_iterations(depth));

        Loop、Doo-Sabin 和 3-√ 分段使用类似的过程实现:选择一个细化宿主并实现几何策略。开发自己的细分方法的关键是实现细化宿主和几何策略的正确组合。

4、细分主体

        细化主体是多边形网格类和几何体遮罩类的模板函数。它细化输入多边形网格,并通过几何体遮罩计算新点。Subdivision_method_3支持四个细化主体:原始四边形四边形(PQQ)、原始三角形四边形(PTQ)、对偶四边形四边形状(DQQ)和3–√三角测细化。分别由Catmull Clark、Loop、Doo Sabin和3–√细分使用。

        mesh类必须是MutatableFaceGraph的模型,它必须是三角形网格或多边形网格,而mask是一个实现细分方法的几何掩模的策略类。

        细化主体细化输入多边形网格,维护模板(即控制网格和细化网格之间的映射),并调用几何权重来计算新点。在 Subdivision_method_3 中,细化是通过一系列连接操作(主要是欧拉操作)实现的。连接操作的顺序在维护模板时起着关键作用。通过将源子网格的顺序与细化顶点相匹配,不需要在基元中标记模板。这避免了细化主体对多边形网格类的数据依赖。

        为了使排序技巧起作用,多边形网格类必须有一个顺序容器,如向量或链表,作为内部存储。顺序容器保证多边形网格的迭代器始终按插入顺序遍历基元。非顺序结构不提供所需的顺序,因此不能与 Subdivision_method_3 一起使用。

        虽然 Subdivision_method_3 不需要标记来支持细化和模板,但它仍然需要知道如何计算和存储几何数据(即点)。 Subdivision_method_3 的类有一个可选的模板参数,即一个顶点属性映射,它提供了顶点和点之间的映射。

        细分主体 PQQ 和 DQQ 在普通多边形网格上工作,PTQ 和 Sqrt3 在三角化多边形网格上工作。 PTQ 和 Sqrt3 在非三角化多边形网格上的结果未定义。 Subdivision_method_3 在细分之前不验证网格特性的先决条件。

5、几何策略

        几何策略定义了一组几何权重。每个几何掩码都实现为计算细分曲面新点的成员函数。

        每个几何掩模接收控制网格的图元描述符(例如 halfedge_descriptor),并向细分的顶点返回 Point_3。该函数收集图元描述符的顶点邻居(即模板上的节点),并根据邻居和掩模(即模板权重)计算新点。

        此图显示了 Catmull-Clark 细分的几何掩码。此处显示的权重未标准化,n 是顶点的化合价。新点是通过在其模板上加权点的总和来计算的。以下代码显示了面节点的几何掩码的实现。

template <class PolygonMesh, class VertexPointMap>
class CatmullClark_mask_3 {
  typedef boost::graph_traits<PolygonMesh>::face_descriptor face_descriptor;
  typedef boost::property_traits<VertexPointMap>::value_type Point_3;
  CatmullClark_mask_3(PolygonMesh &pmesh, VertexPointMap vpm);
  void face_node(face_descriptor face, Point_3& pt) {
    int n = 0;
    Point_3 p(0,0,0);
    for(halfedge_descriptor hd : halfedges_around_face(face,pmesh)){
      p = p + get(vpm, (target(hd,pmesh)) - ORIGIN);
      ++n;
    }
    pt = ORIGIN + (p - ORIGIN)/FT(n);
  }
};

        Catmull-Clark细分的细化主体需要三个几何掩码,用于没有开放边界的多边形网格:顶点节点掩码、边节点掩码和面节点掩码。为了支持有边界的多边形网格,还需要边界节点掩码。Catmull-Clark细分的边界节点掩码如下,其中ept返回新的点分割边,vpt返回边指向的顶点上的新点。 

        下面列出了所有四个细化主体的掩模接口。 DQQMask_3 没有边界节点模板,因为 DQQ 细化的细化主机在当前版本中不支持全局边界。

template <class PolygonMesh>
class PQQMask_3 {
  void face_node(boost::graph_traits<PolygonMesh>::face_descriptor, Point_3&);
  void edge_node(boost::graph_traits<PolygonMesh>::halfedge_descriptor, Point_3&);
  void vertex_node(boost::graph_traits<PolygonMesh>::vertex_descriptor, Point_3&);
  void border_node(boost::graph_traits<PolygonMesh>::halfedge_descriptor, Point_3&, Point_3&);
};
template <class PolygonMesh>
class PTQMask_3 {
  void edge_node(boost::graph_traits<PolygonMesh>::halfedge_descriptor, Point_3&);
  void vertex_node(boost::graph_traits<PolygonMesh>::vertex_descriptor, Point_3&);
  void border_node(boost::graph_traits<PolygonMesh>::halfedge_descriptor, Point_3&, Point_3_&);
};
template <class PolygonMesh>
class DQQMask_3 {
public:
  void corner_node(boost::graph_traits<PolygonMesh>::halfedge_descriptor edge, Point_3& pt);
};
template <class PolygonMesh>
class Sqrt3Mask_3 {
public:
  void vertex_node(boost::graph_traits<PolygonMesh>::vertex_descriptor vertex, Point_3& pt);
};

6、四种细分方法

        Subdivision_method_3 通过专门化其各自的细化规则来支持 Catmull-Clark、Loop、Doo-Sabin 和 3-√ 细分。它们旨在用于 MutableFaceGraph 的任何模型,如 Polyhedron_3 和 Surface_mesh。如果您的应用程序使用具有专用几何内核的多边形网格,则需要使用基于该内核的几何策略来专门化细化规则。

namespace Subdivision_method_3 {
  template <class PolygonMesh, class NamedParameters>
  void CatmullClark_subdivision(PolygonMesh& pmesh, NamedParameters np) {
    PQQ(pmesh, CatmullClark_mask_3<PolygonMesh>(pmesh), np);
  }
  template <class PolygonMesh, class NamedParameters>
  void Loop_subdivision(PolygonMesh& pmesh, NamedParameters np) {
    PTQ(pmesh, Loop_mask_3<PolygonMesh>(pmesh) , np);
  }
  template <class PolygonMesh, class NamedParameters>
  void DooSabin_subdivision(PolygonMesh& pmesh, NamedParameters np) {
    DQQ(pmesh, DooSabin_mask_3<PolygonMesh>(pmesh), np);
  }
  template <class PolygonMesh, class NamedParameters>
  void Sqrt3_subdivision(PolygonMesh& pmesh, NamedParameters np) {
    Sqrt3(pmesh, Sqrt3_mask_3<PolygonMesh>(pmesh), np);
  }
}

7、自定义细分方法

        Subdivision_method_3 支持在具有笛卡尔坐标点的 Polyhedron_3 上使用四种实用的细分方法。通过使用自定义几何掩模对细化规则进行专门化,可以支持更多的细分方法。

        有四个已经定义好的细分方法,还有四个接受几何掩膜的细分主体。

CGAL 5.6 - 3D Surface Subdivision Methods: User Manual

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

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

相关文章

【U8+】用友U8删除固定资产卡片,提示:当前卡片不是本月录入的卡片,不能删除。

【问题描述】 用友U8软件&#xff0c;参照已有账套新建账套的时候&#xff0c;选择结转期初余额。 例如&#xff1a;参照已有账套的2022年新建2023年的账套。 结转期初的时候勾选了固定资产模块&#xff0c; 建立成功后登录23年新的账套后&#xff0c;删除固定资产卡片&#xf…

CSS 滚动捕获 scroll-margin

CSS滚动捕获 scroll-margin 非滚动捕获容器语法兼容性 CSS滚动捕获 scroll-margin 设置元素的滚动外边距 非滚动捕获容器 之前在 scroll-padding 中说过如何用 scroll-padding 避免锚点定位时元素贴着容器边缘的问题, 现在我们尝试用 scroll-margin 解决 <body><ma…

electerm下载和安装

electerm下载和安装 一、概述 electerm 是一款免费开源、基于electron/ssh2/node-pty/xterm/antd/ subx等libs的终端/ssh/sftp客户端(linux, mac, win)。 而且个人觉得electerm界面更好看一些&#xff0c;操作都是类似的。 二、下载安装 下载地址&#xff1a;https://elec…

opencv知识库:基于cv2.flip()函数对图像进行随机翻转(水平/垂直)

需求场景 欲对RGB格式的lena图像进行随机翻转&#xff0c;要求这些图像不翻转、水平翻转、垂直翻转的概率都为1/3。 功能代码 import cv2 import random# 读取并展示图像 img cv2.imread("lena.jpg") cv2.imshow(lena, img) cv2.waitKey(0)for i in range(6): #…

react之ReactRouter的使用

react之ReactRouter的使用 一、环境搭建二、抽象路由模块三、路由导航3.1 声明式导航3.2 编程式导航 四、导航传参4.1 searchParams 传参4.2 params 传参 五 、嵌套路由配置六、默认二级路由七、404页面配置八、俩种路由模式 一、环境搭建 1.创建项目安装依赖 npx create-rea…

【每日OJ —— 226. 翻转二叉树】

每日OJ —— 226. 翻转二叉树 1.题目&#xff1a;226. 翻转二叉树2.解法2.1.算法讲解2.2.代码实现2.3.代码提交通过展示 1.题目&#xff1a;226. 翻转二叉树 2.解法 2.1.算法讲解 我们从根节点开始&#xff0c;递归地对树进行遍历&#xff0c;并从叶子节点先开始翻转。如果当前…

Spring是怎么解决循环依赖的?

什么是循环依赖 循坏依赖就是字面意思&#xff0c;A 依赖了 B&#xff0c;B 同时也依赖了 A。 如下所示 Component public class A {// A中注入了BAutowiredprivate B b; }Component public class B {// B中也注入了AAutowiredprivate A a;又或者是下面这种 // 自己依赖自己…

Zabbix监控接收SNMPTrap消息与SNMPTT结合

一.SNMP 协议 1.协议介绍 snmp 协议是日常使用的较多的一种协议&#xff0c;绝大多数网络设备/存储等都支持 snmp 协议&#xff0c;通过此协议可以实现设备状态的监控及管理。 2.主要组成 SNMP 协议包括以下三个部分: SNMP Agent&#xff1a;负责处理 snmp 请求&#xff0c…

Python实战:批量加密Excel文件指南

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是彭涛&#xff0c;今天为大家分享 Python实战&#xff1a;批量加密Excel文件指南&#xff0c;全文3800字&#xff0c;阅读大约10分钟。 在日常工作中&#xff0c;保护敏感数据是至关重要的。本文将引导你通过…

ARP安全综合功能示例

ARP安全简介 定义 ARP&#xff08;Address Resolution Protocol&#xff09;安全是针对ARP攻击的一种安全特性&#xff0c;它通过一系列对ARP表项学习和ARP报文处理的限制、检查等措施来保证网络设备的安全性。ARP安全特性不仅能够防范针对ARP协议的攻击&#xff0c;还可以防…

在国内Facebook广告怎么解决充值渠道问题?

怎么解决Facebook预充值跑广告营销的付款方式问题呢&#xff1f; Facebook跑广告是很多做出口营销的公司或团队喜欢的平台之一&#xff0c;那就避免不了需要支付给Facebook平台广告费用了&#xff0c;那到底用什么方式去充值到FB号上去解决呢&#xff1f;FB预充值有什么咔可以…

使用极限网关助力 ES 集群无缝升级、迁移上/下云

在工作中大家可能会遇到以下这些场景&#xff1a; 自建 ES 集群需要平滑迁移到 XX 云&#xff1b;从 XX 云将 ES 集群迁移到自建机房&#xff1b;ES 集群进行跨版本升级&#xff0c;同时保留回退能力&#xff1b; 这些场景往往都还有个共同的需求&#xff1a;迁移过程要保证业…

面试 Java 基础八股文十问十答第三期

面试 Java 基础八股文十问十答第三期 作者&#xff1a;程序员小白条&#xff0c;个人博客 ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 21.说下Java8的Stream流的常用方法 答: forEach遍历、find、match进行匹配reduce进行归约&#xff0c;比如求和&#xff0c;乘&#xff0c;除聚合…

前端项目打包和自动化部署(jenkins+gitee+nginx)

项目打包和自动化部署 一. 项目部署和DevOps 1. 传统的开发模式 在传统的开发模式中&#xff0c;开发的整个过程是按部就班就行&#xff1a; 但是这种模式存在很大的弊端&#xff1a; 工作的不协调&#xff1a;开发人员在开发阶段&#xff0c;测试和运维人员其实是处于等待…

基于SpringBoot + vue的在线视频教育平台

qq&#xff08;2829419543&#xff09;获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;springboot 前端&#xff1a;采用vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xf…

优化你的计算机性能:如何根据 CPU 占用率决定硬件升级

优化你的计算机性能&#xff1a;如何根据 CPU 占用率决定硬件升级 一、引言二、CPU 占用率的意义与影响三、监测和评估 CPU 占用率四、判断硬件升级需求的依据五、硬件升级方案和建议六、总结 一、引言 计算机性能优化是提升计算机系统整体效能的过程&#xff0c;它对于用户和…

etlbox.3.1.0 for NET 轻量级 ETL数据集成库 Crack

适用于 .NET 的轻量级 ETL&#xff08;提取、转换、加载&#xff09;工具箱和数据集成库 高度可定制 厌倦了使用几乎不可能实现复杂需求的用户界面&#xff1f;使用 ETLBox&#xff0c;可以轻松编写适合您独特需求的代码。插入您自己的逻辑或修改现有行为以满足您的特定要求。 …

数据库表的管理

表的基本概念 表是包含数据库中所有数据的数据库对象。数据在表中的组织方式与在电子表格中相似&#xff0c;都是 按行和列的格式组织的。每行代表一条唯一的记录&#xff0c;每列代表记录中的一个字段。例如&#xff0c;在包含公 司员工信息的表中&#xff0c;每行代表一名员工…

VMware安装Debian12.2作为服务器(无桌面)

[TOC]VMware安装Debian12.2作为服务器&#xff08;无桌面&#xff09; 下载Debian系统 官方网站&#xff1a;https://www.debian.org/index.zh-cn.html 创建新的虚拟机 打开VMware Workstation&#xff0c;点击创建新的虚拟机 向导虚拟机类型选择 一般我会选择典型&…

UVA1368 DNA Consensus String

DNA Consensus String The Hamming distance is the number of different characters at each position from two strings of equal length. For example, assume we are given the two strings “AGCAT” and “GGAAT.” The Hamming distance of these two strings is 2 bec…