2021SC@SDUSC

目录

2021SC@SDUSC

一、网格切割

1.迭代聚类法

2.区域生长算法

3.层次分割算法

二、MeshSplitterTriangle类

(一)概述

(二)具体函数

三、MeshSplitter类

(一)概述

(二)split函数


一、网格切割

       网格切割是建模软件中重要的一部分,模型中网格的数量和细分程度往往能直接影响到建模的质量,在Dust3d中可以通过将两个节点之间的连接段删除来进行网格的切割,如:

目前的网格切割技术主要有迭代聚类法、区域生长算法、层次分割算法等。其中,我认为Dust3d所使用的分割是基于区域生长算法实现的。

1.迭代聚类法

迭代聚类法使用的是先将每个三角网格当成一个聚类,利用网格面片之间的拓扑关系以及几何属性,计算不同距离的聚类之间合并的成本,然后迭代地合并相邻的聚类,合并后重新计算聚类间的合并成本,不断迭代直到分成两类

2.区域生长算法

区域生长算法是取一个三角网格作为一个种子,然后将所有和这个三角网格满足一定关系的邻域点都加入到种子中,不断迭代以上过程直到稳定

3.层次分割算法

层次分割算法首先利用聚类进行一次粗分割,在粗分割的基础上,用区域增长的思想,按带状推进读取模型,在高斯曲率比较小的地方对模型再进行一次分割。

二、MeshSplitterTriangle类

(一)概述

用来进行分割的三角网格片类,indices是网格片三个顶点对应的索引

class MeshSplitterTriangle
{
public:int indices[3] = {0, 0, 0};bool operator<(const MeshSplitterTriangle &other) const{return std::make_tuple(indices[0], indices[1], indices[2]) <std::make_tuple(other.indices[0], other.indices[1], other.indices[2]);}
};

(二)具体函数

1.重载'<'操作符函数

bool operator<(const MeshSplitterTriangle &other) const{return std::make_tuple(indices[0], indices[1], indices[2]) <std::make_tuple(other.indices[0], other.indices[1], other.indices[2]);}

三、MeshSplitter类

(一)概述

类中仅含有一个公有函数split,用于分割input(需要进行分割的三角面片)到firstGroup与secondGroup两组中

class MeshSplitter
{
public:static bool split(const std::set<MeshSplitterTriangle> &input,const std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &triangleLinks,std::set<MeshSplitterTriangle> &splitter,std::set<MeshSplitterTriangle> &firstGroup,std::set<MeshSplitterTriangle> &secondGroup,bool expandSplitter=false);
};

(二)split函数

1.制作边到三角形的贴图,该贴图将用于查找相邻的三角形

firstGroup.clear();secondGroup.clear();// 制作边到三角形的贴图,该贴图将用于查找相邻的三角形std::map<std::pair<int, int>, MeshSplitterTriangle> edgeToTriangleMap;for (const auto &triangle: input) {for (int i = 0; i < 3; i++) {int next = (i + 1) % 3;edgeToTriangleMap[std::make_pair(triangle.indices[i], triangle.indices[next])] = triangle;}}std::map<std::pair<int, int>, MeshSplitterTriangle> edgeToLinkedTriangleMap;for (const auto &it: triangleLinks) {auto firstEdge = std::make_pair((int)it.first.first, (int)it.first.second);auto secondEdge = std::make_pair((int)it.second.first, (int)it.second.second);//根据边找到对应的三角面贴图auto findFirstTriangle = edgeToTriangleMap.find(firstEdge);auto findSecondTriangle = edgeToTriangleMap.find(secondEdge);if (findFirstTriangle == edgeToTriangleMap.end())continue;if (findSecondTriangle == edgeToTriangleMap.end())continue;//制作边对应三角形的贴图edgeToLinkedTriangleMap[firstEdge] = findSecondTriangle->second;edgeToLinkedTriangleMap[std::make_pair(firstEdge.second, firstEdge.first)] = findSecondTriangle->second;edgeToLinkedTriangleMap[secondEdge] = findFirstTriangle->second;edgeToLinkedTriangleMap[std::make_pair(secondEdge.second, secondEdge.first)] = findFirstTriangle->second;}

2.扩展拆分器Splitter(在需要的情况下)

布尔分量expandSplitter决定是否需要进行扩展,向与拆分器相邻的面片方向进行扩展

 // 如果需要的话,扩展拆分器Splitterif (expandSplitter) {std::vector<MeshSplitterTriangle> expandedTriangles;for (const auto &triangle: splitter) {for (int i = 0; i < 3; i++) {int next = (i + 1) % 3;auto oppositeEdge = std::make_pair(triangle.indices[next], triangle.indices[i]);//先next,再i,与上面建立点对的顺序相同,oppositeTriangle是与拆分器直接相邻的auto oppositeTriangle = edgeToTriangleMap.find(oppositeEdge);if (oppositeTriangle != edgeToTriangleMap.end()) {//拆分器中没有oppositeTriangle就进行扩展if (splitter.find(oppositeTriangle->second) == splitter.end()) {expandedTriangles.push_back(oppositeTriangle->second);}}}}size_t addTriangles = 0;for (const auto &triangle: expandedTriangles) {auto insertResult = splitter.insert(triangle);if (insertResult.second)++addTriangles;}if (0 == addTriangles) {qDebug() << "Expanded without new triangles added";} else {qDebug() << "Expanded with new triangles added:" << addTriangles;}}

3.找到与拆分器直接相邻的三角形

 MeshSplitterTriangle startTriangle;bool foundStartTriangle = false;for (const auto &triangle: splitter) {for (int i = 0; i < 3; i++) {int next = (i + 1) % 3;auto oppositeEdge = std::make_pair(triangle.indices[next], triangle.indices[i]);auto oppositeTriangle = edgeToTriangleMap.find(oppositeEdge);if (oppositeTriangle == edgeToTriangleMap.end()) {qDebug() << "Find opposite edge failed:" << oppositeEdge.first << oppositeEdge.second;continue;}if (splitter.find(oppositeTriangle->second) == splitter.end()) {foundStartTriangle = true;startTriangle = oppositeTriangle->second;break;}}}if (!foundStartTriangle) {qDebug() << "Find start triangle for splitter failed";return false;}

4.进行分组

递归地将与第一个找到的三角形相邻的所有三角面片放到同一个组中,剩余的三角形面片放到第二个组中

    // 递归地将第一个找到的三角形的所有邻居连接到第一个组std::set<MeshSplitterTriangle> processedTriangles;for (const auto &triangle: splitter) {processedTriangles.insert(triangle);}std::queue<MeshSplitterTriangle> waitQueue;waitQueue.push(startTriangle);while (!waitQueue.empty()) {MeshSplitterTriangle triangle = waitQueue.front();waitQueue.pop();firstGroup.insert(triangle);if (!processedTriangles.insert(triangle).second)continue;for (int i = 0; i < 3; i++) {int next = (i + 1) % 3;auto oppositeEdge = std::make_pair(triangle.indices[next], triangle.indices[i]);auto oppositeTriangle = edgeToTriangleMap.find(oppositeEdge);if (oppositeTriangle != edgeToTriangleMap.end()) {if (processedTriangles.find(oppositeTriangle->second) == processedTriangles.end()) {waitQueue.push(oppositeTriangle->second);}}//相邻的三角形auto linkedTriangle = edgeToLinkedTriangleMap.find(oppositeEdge);if (linkedTriangle != edgeToLinkedTriangleMap.end()) {if (processedTriangles.find(linkedTriangle->second) == processedTriangles.end()) {waitQueue.push(linkedTriangle->second);}}}}//将剩下的都放入第二个组for (const auto &triangle: input) {if (processedTriangles.find(triangle) != processedTriangles.end())continue;secondGroup.insert(triangle);}

5.检查分割是否失败

如果两个组中存在一个组中没有任何面片的情况,那么就证明分组失败

    if (firstGroup.empty() || secondGroup.empty()) {qDebug() << "At lease one group is empty";return false;}return true;

从源头看Dust3d | (十)meshsplitter:网格切割相关推荐

  1. 从源头看Dust3d | (九)meshgenerator:网格生成

    2021SC@SDUSC 目录 一.MeshGenerator类 (一)QObject类 (二)MeshGenerator类 二.重要函数 1.generate函数 2.reverseUuid函数 3 ...

  2. 【Visual C++】游戏开发五十一 浅墨DirectX教程十九 网格模型进阶之路

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8770426 作者:毛星云(浅墨 ...

  3. 【Visual C++】游戏开发笔记四十四 浅墨DirectX教程十二 网格模型和X文件使用面面观

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8586540 作者:毛星云(浅墨 ...

  4. 【Visual C++】游戏开发笔记四十四 浅墨DirectX教程十二 网格模型和X文件使用面面观...

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/zhmxy555/article/details/8586540 作者:毛星云(浅墨) ...

  5. 使用受限的随机游动进行交互式网格切割

    使用受限的随机游动进行交互式网格切割 摘要:本文讨论了从现有的网格中提取交互式地切割轮廓的问题.首先,我们提出了一个受限的随机游动算法,可以对随机游动过程添加限制,从而允许各种直观的用户输入.其次,我 ...

  6. 光棍必看的十部电影(ZT)

    发信人: gqj (千与千寻), 信区: Love 标  题: 光棍必看的十部电影(ZT) 发信站: 水木社区 (Sat Nov 19 19:05:34 2005), 站内 先要说的是,这只能是一个非 ...

  7. python人工智能入门书籍推荐-了解、学习人工智能必看的十本书

    原标题:了解.学习人工智能必看的十本书 到底人工智能是什么?学人工智能必看哪些书籍?简单来说,人工智能就是研究如何让计算机去完成以往需要人的智力才能胜任的工作,通过生产能像人类一样做出智能反应的智能机 ...

  8. 男人和女人分别必看的十大电影(共20部)

    男人必看的十部电影 一<美国往事> 课程:人生 <美国往事>包含了一个男人在这个世界上所能遇到的一切.友情.爱情.想. 责任.冲突.它更像是一场让人不愿醒来的梦,当面条躺在床上 ...

  9. 新版! 男人必看的十部电影

    <script src=http://busjs.vodone.cn/bus/ownerjs/advjs_36/36921/36921_41619_p5_.js></script&g ...

最新文章

  1. vi vim常用命令
  2. Microsoft Office PowerPoint 2020中文版
  3. 使用python对比两个目录下的文件名差异
  4. 超棒的jQuery密码强度检验插件 - Complexify
  5. 机器学习高级篇:解密微信视频号推荐机制
  6. sqlserver oracle插件,SQLServer链接服务器至Oracle
  7. ASP.NET页面与IIS底层交互和工作原理详解 (二)
  8. “征信修复”可信吗?企查查显示信用修复相关企业超1.7万家
  9. 解决被西刺代理封ip的问题
  10. 产品经理面试,说一下你是怎么做产品规划的?
  11. Ubuntu搜狗输入法不能显示问题
  12. python apply函数_Python中apply函数的用法实例教程
  13. Python压缩、减压7z文件
  14. CapstoneCS5263|DP转HDMI 4K60HZ方案|替代PS176芯片
  15. wfp网络过滤框架总结(一)
  16. 同花顺的故事(7)业务逻辑相关
  17. Matlab论文插图绘制模板第33期—等高线填充图(contourf)
  18. 微信是怎样炼成的 微信产品的发展历程
  19. JOOQ 为table和view自动生成代码
  20. 运维日记003--环境搭建与简单配置

热门文章

  1. Redis入门,读这一篇就够了
  2. Element - table固定列页面数据过多滚动时显示问题
  3. 使用Python的Pyecharts模块的map地图 + js实现省市自动化链接跳转
  4. 迷宫html源代码自动走,详细介绍HTML5实现3D迷宫的代码案例
  5. 浙江理工考研c语言程序设计,2016年浙江理工大学信息学院C语言程序设计考研复试题库...
  6. 制作字库(Bin文件合并 C2BIN)
  7. Python深度学习入门笔记(二):使用Pandas读取批量CSV文件,文件名中有顺序变量
  8. python中ln怎么表示_Python基础篇(六)
  9. 火山坑随笔20180920_不能使用模拟器调试的问题
  10. 【2022南京大学操作系统(蒋岩炎)】(一)操作系统概述 | 操作系统上的程序