网格的补洞操作

简介

网格补洞操作,里面有有奖征集答案,欢迎大家踊跃回答。第一个留言为有效留言
那个horse.off请到github下载

算法描述

找到网格的所有的边界半边。

for循环选定一个孔洞的关键点

以来点来遍历整个孔洞
补洞

代码

// 网格 补洞的操作#include <iostream>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <cmath>
#include <vector>
#include <map>
#define pi 3.1415926using namespace std;
typedef OpenMesh::TriMesh_ArrayKernelT<> MyMesh;int main() {MyMesh mesh;map<MyMesh::HalfedgeHandle, int>holeHalfedgeHandle;// 半边 对应的 intvector<MyMesh::HalfedgeHandle> halfedgeHandle;//选定的孔洞集合MyMesh::VertexHandle vertexHandle;if (!OpenMesh::IO::read_mesh(mesh, "horse.off")) {std::cerr << "Cannot read mesh to file ' horse.off ' " << std::endl;return 1;}for (auto he_it = mesh.halfedges_begin(); he_it != mesh.halfedges_end(); ++he_it) {if (mesh.is_boundary(*he_it)) {holeHalfedgeHandle.insert(make_pair(*he_it, 0));// 在有边界半边加入到集合中}}for (map<MyMesh::HalfedgeHandle, int>::iterator mh_it = holeHalfedgeHandle.begin(); mh_it != holeHalfedgeHandle.end(); ++mh_it) {if (mh_it->second == 0) {//将这个集合中还没处理过的边界点halfedgeHandle.clear();// 临时处理的半边钩子清空halfedgeHandle.push_back(mh_it->first);// 将边界的半边钩子放入其中holeHalfedgeHandle[mh_it->first] = 1;// 将边界的半边钩子设定为已经处理vertexHandle = mesh.from_vertex_handle(mh_it->first);//把正在处理的半边的来点找到//选定孔洞for (map<MyMesh::HalfedgeHandle, int>::iterator mit = holeHalfedgeHandle.begin(); mit != holeHalfedgeHandle.end(); ++mit) {//再次遍历整个边界集  是对应  上一层的for循环的选定的孔洞。if (mesh.to_vertex_handle(mit->first) == vertexHandle) {// 如果这个边界集合中的某个点的去点是这个关键点halfedgeHandle.push_back(mit->first);// 将这个去点关键点加入半边集合中holeHalfedgeHandle[mit->first] = 1;// 将整个半边集合中去掉求点关键点所在的半边vertexHandle = mesh.from_vertex_handle(mit->first);// 将这个去点作为来点成为一个钩子关键点if (mesh.from_vertex_handle(mit->first) == mesh.to_vertex_handle(mh_it->first))// 当遍历这个孔洞// 如果上一层选定的孔洞的半边的去点 等于 此时的选定的半边的来点 说明整个孔洞已经遍历完毕了break;mit = holeHalfedgeHandle.begin();// 感觉效率有点低,如果找到了这个关键点,可能要重新遍历所有空洞元素  }else {continue;}}vector<MyMesh::VertexHandle>ver;vector<MyMesh::VertexHandle>face;// 将这个孔洞的边界点都加入的数组ver中for (vector<MyMesh::HalfedgeHandle>::iterator halfe = halfedgeHandle.begin(); halfe != halfedgeHandle.end(); ++halfe) {vertexHandle = mesh.from_vertex_handle(*halfe);ver.push_back(vertexHandle);}// 设定第一个点为角点(ver.end() - 1),然后构成一个平面for (vector<MyMesh::VertexHandle>::iterator v_it = ver.begin() + 1; v_it != ver.end() - 1; ++v_it) {face.clear();face.push_back(*(ver.end() - 1));face.push_back(*(v_it));face.push_back(*(v_it - 1));mesh.add_face(face);}}}// 将生成的新网格输出if (!OpenMesh::IO::write_mesh(mesh, "rocker_result.off")) {std::cerr << "Cannot write mesh to file ' rocker_result.off ' " << std::endl;return 1;}return 0;
}

代码二

采用下一条半边来构建整个模型,但是有bug,为了应对bug不得已加了一些代码,大的孔洞已经填补,但是小得多孔洞没有填补,不知道为什么?
任何人找到我的bug,解决我的bug,留下支付宝号(在留言中),本人将会转1元人民币。

// 网格 补洞的操作#include <iostream>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <cmath>
#include <vector>
#include <map>
#define pi 3.1415926using namespace std;
typedef OpenMesh::TriMesh_ArrayKernelT<> MyMesh;int main() {MyMesh mesh;map<MyMesh::HalfedgeHandle, int>holeHalfedgeHandle;// 半边 对应的 intvector<MyMesh::HalfedgeHandle> halfedgeHandle;//选定的孔洞集合MyMesh::VertexHandle vertexHandle;if (!OpenMesh::IO::read_mesh(mesh, "horse.off")) {std::cerr << "Cannot read mesh to file ' horse.off ' " << std::endl;return 1;}for (auto he_it = mesh.halfedges_begin(); he_it != mesh.halfedges_end(); ++he_it) {if (mesh.is_boundary(*he_it)) {holeHalfedgeHandle.insert(make_pair(*he_it, 0));// 在有边界半边加入到集合中}}for (map<MyMesh::HalfedgeHandle, int>::iterator mh_it = holeHalfedgeHandle.begin(); mh_it != holeHalfedgeHandle.end(); ++mh_it) {if (mh_it->second == 0) {//将这个集合中还没处理过的边界点halfedgeHandle.clear();// 临时处理的半边钩子清空halfedgeHandle.push_back(mh_it->first);// 将边界的半边钩子放入其中holeHalfedgeHandle[mh_it->first] = 1;// 将边界的半边钩子设定为已经处理vertexHandle = mesh.to_vertex_handle(mh_it->first);//把正在处理的半边的来点找到OpenMesh::ArrayKernel::VertexHandle to_v;//选定孔洞bool check = false;// 重写了寻找孔洞的代码,但是有bugdo {for (auto vh_it = mesh.voh_begin(vertexHandle); vh_it != mesh.voh_end(vertexHandle); ++vh_it) // 半边迭代器{OpenMesh::ArrayKernel::HalfedgeHandle h = mesh.next_halfedge_handle(*vh_it);// 这个顶点的下一条半边if (mesh.is_boundary(h)) {if (holeHalfedgeHandle[h] == 1) {check = true;break;}halfedgeHandle.push_back(h);holeHalfedgeHandle[h] = 1;vertexHandle = mesh.to_vertex_handle(h);// 下一条半边的来点(handle)break;}else {continue;}// 如果下一条半边的来点等于最初选定点的去点,那么整个孔洞已经遍历完毕++vh_it;if (vh_it == mesh.voh_end(vertexHandle))check = true;}if (check == true) {break;}} while (vertexHandle != mesh.to_vertex_handle(mh_it->first));// 如果上一层选定的孔洞的半边的去点 等于 此时的选定的半边的来点 说明整个孔洞已经遍历完毕了vector<MyMesh::VertexHandle>ver;vector<MyMesh::VertexHandle>face;// 将这个孔洞的边界点都加入的数组ver中for (vector<MyMesh::HalfedgeHandle>::iterator halfe = halfedgeHandle.begin(); halfe != halfedgeHandle.end(); ++halfe) {vertexHandle = mesh.from_vertex_handle(*halfe);ver.push_back(vertexHandle);}// 设定第一个点为角点(ver.end() - 1),然后构成一个平面if (ver.size() <= 3) {break;}for (vector<MyMesh::VertexHandle>::iterator v_it = ver.begin() + 1; v_it != ver.end() - 1; ++v_it) {face.clear();face.push_back(*(ver.end() - 1));face.push_back(*(v_it - 1));face.push_back(*(v_it));mesh.add_face(face);}}}// 将生成的新网格输出if (!OpenMesh::IO::write_mesh(mesh, "rocker_result.off")) {std::cerr << "Cannot write mesh to file ' rocker_result.off ' " << std::endl;return 1;}return 0;
}

转载于:https://www.cnblogs.com/eat-too-much/p/11177089.html

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

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

相关文章

SQL Server 2005 Hierarchies WITH Common Table Expressions

代码 1 createtableEmployee2 (3 Id INTIDENTITY(1,1) PRIMARYKEY, 4 [Name]varchar(30) null, 5 JobTitle varchar(30) null, 6 Manager intnull7 )8 9 insertEmployee10 selectincf, IT Director,nullunionall11 selectinc3, Finance Director,nullunionall12 select…

aspx repeater 用法_ASP.NET-----Repeater数据控件的用法总结

一、Repeater控件的用法流程及实例&#xff1a;1、首先建立一个网站&#xff0c;新建一个网页index.aspx。2、添加或者建立APP_Data数据文件&#xff0c;然后将用到的数据库文件放到APP_Data文件夹中。3、打开数据库企业管理器&#xff0c;数据库服务器为local(.)&#xff0c;然…

服务器通过响应头向浏览器设置cookie,http响应包括设置cookie jession id,但随后发送请求,请求标头中没有cookie信息...

第一请求响应&#xff1a;cache: no-cacheConnection: keep-aliveContent-Type: image/pngDate: Tue, 10 May 2016 10:47:43 GMTServer: Tengine/2.1.1Set-Cookie: _uidCiMDa1cxvEjjDeFAw56Ag; path/Set-Cookie: _uideff37cac39ac062caba9b5ec2c8a00f4;Path/Set-Cookie: JSESSI…

Csharp 两个DataTable或DataView互换,可以用来加密解密

/// <summary>/// 涂聚文 geovindu.blog.163.com/// www.dusystem.com www.dupcit.com/// 2011-05-28/// </summary>/// <param name"table"></param>/// <returns></returns>static DataTable GetDecTable(DataTable table){i…

网络切片技术缺点_一文读懂网络切片 - 技术综合版块 - 通信人家园 - Powered by C114...

在各种新兴业务不断涌现的今天&#xff0c;现有的4G LTE网络已经无法满足日益增多的业务需求&#xff0c;因此未来的网络需要通过网络切片技术从“one size fits all”向“one size per service”过渡。在《网络切片“火锅论”&#xff1a;同一口锅&#xff0c;不同的梦想》一文…

安卓导航无信号无服务器,无信号导航能用否

● 出发前测试为解析导航不准的原因&#xff0c;我们先来了解一下GPS导航原理。导航仪是通过接受GPS信号来确定位置所在&#xff0c;再通过存储于内存中的地图数据规划路线。在车辆行驶时&#xff0c;导航仪通过不断接受GPS信号来检测车辆所在地状态&#xff0c;从而提示指引信…

python并发编程之semaphore(信号量)_浅谈Python并发编程之进程(守护进程、锁、信号量)...

前言&#xff1a;本博文是对Python并发编程之进程的知识延伸&#xff0c;主要讲解&#xff1a;守护进程、锁、信号量。友情链接&#xff1a;一、守护进程(daemon)1.1 守护进程概念首先我们都知道&#xff1a;正常情况下&#xff0c;主进程默认等待子进程调用结束之后再结束&…

csharp: Flash Player play *.flv file in winform

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; using System.Xml; using AxShockwaveFlashObjects;/** VS2005在添加Shockwave时…

ad文件服务器部署,AD 集成 – 配置 ADFS 登陆 - Seafile 服务器用户手册

要求要想使用 ADFS 登陆到 Seafile&#xff0c;需要以下组件&#xff1a;1、安装了 ADFS 的windows服务器。安装 ADFS 和相关配置详情请参考 本文。2、对于 ADFS 服务器的SSL有效证书&#xff0c;在这里我们使用 adfs-server.adfs.com 作为域名示例。3、对于 seafile 服务器的S…

win7映射网络驱动器消失了_win7怎么映射网络驱动器|win7设置网络驱动器的方法...

2015-08-21 15:57:15近来&#xff0c;有一些刚刚升级windows10系统的用户向小编咨询在新系统中该如何创建映射网络驱动器。其实&#xff0c;方法非常简单&#xff0c;接下来&#xff0c;小编就向大家分享win10系统创建映射网络驱动器的具体方法...2015-05-15 19:27:26Win7系统怎…

NTC热敏电阻基础以及应用和选择(转)

源&#xff1a;NTC热敏电阻基础以及应用和选择 NTC被称为负温度系数热敏电阻&#xff0c;是由Mn-Co-Ni的氧化物充分混合后烧结而成的陶瓷材料制备而来&#xff0c;它在实现小型化的同时&#xff0c;还具有电阻值-温度特性波动小、对各种温度变化响应快的特点&#xff0c;可被用…

graphic头文件函数_graphics.h头文件

graphics.h头文件是一款tc操作必备组件。graphics.h头文件主要是运行在win8、win7操作系统上&#xff0c;为用户提供了非常多函数类型&#xff0c;用户只需使用tc编译就可以使用这个软件&#xff0c;是用户进行tc编辑时不可缺少的操作工具。graphics.h头文件函数范围&#xff1…

homeomorphic 同胚 释义

简介 在拓扑学中&#xff0c;两个流形&#xff0c;如果可以通过弯曲、延展、剪切(只要最终完全沿着当初剪开的缝隙再重新粘贴起来)等操作把其中一个变为另一个&#xff0c;则认为两者是同胚的。如&#xff1a;圆和正方形是同胚的&#xff0c;而球面和环面就不是同胚的。 参考链…

流形 非流形 释义

非流形边 A non-manifold edge has more than two incident triangles. 就是一个边由超过两个三角形相交。就是非流形边。 非流形顶点 比如两个三棱锥相接触的那个顶点就是非流形顶点。 以此可以逆推出流形是什么意思。 参考 书籍 [Polygon mesh processing] 转载于:https://ww…

mysql 插入数据 自增长_如何在MYSQL插数据 ID自增

2种解决办法1.修改你的数据库表&#xff0c;将ID设为自增长&#xff0c;注&#xff1a;只有主键才可以设置为自增长例&#xff1a;CREATE TABLE message (id INT(8) NOT NULL AUTO_INCREMENT, PRIMARY KEY(id));2.代码中进行处理Statement ps;ResultSet rs;int id 0;........…

MSN无法登陆,服务暂时不可用(错误码:80048051)

好几次MSN突然就登陆不了&#xff0c;一次是改了系统时间&#xff0c;这个好办&#xff0c;你改成当前日期时间即可&#xff1b; 还有一个可能就是脱机工作&#xff1a; 請依照以下步驟進行除錯&#xff1a; 1. 關閉Windows Live Messenger 先關閉你的MSN&#xff0c;在右下角找…

drawboard pdf拆分文件_请收藏!这是一份最全的PDF问题解决方案。

晚上好呀&#xff0c;我是大梦。最近因为赶书稿和论文缘故&#xff0c;时常要翻看许多PDF文件&#xff0c;复制摘录写东西&#xff0c;忽然发现好不方便&#xff0c;从PDF复制过来的文字到Word中变成了乱码&#xff1f;一些扫描版PDF根本无法复制而且还留有许多白边&#xff0c…

Java基础教程——线程通信

线程通信&#xff1a;等待、唤醒 Object方法这些方法在拥有资源时才能调用notify唤醒某个线程。唤醒后不是立马执行&#xff0c;而是等CPU分配wait等待&#xff0c;释放锁&#xff0c;不占用CPU资源notifyAll唤醒全部等待的线程重点&#xff1a;资源的有效利用 生产一个&#x…

python requests cookies请求_python+requests实现接口测试 - cookies的使用

在很多时候&#xff0c;发送请求后&#xff0c;服务端会对发送请求方进行身份识别&#xff0c;如果请求中缺少识别信息或存在错误的识别信息&#xff0c;会造成识别失败。 如一些需要用户登录以后才能访问的页面。import requestsmyaddress_urlhttp://xxx.com/api/v1/myaddress…

kafka命令及启动

默认内网访问&#xff0c;要在外网访问的话&#xff0c;需要在修改config/server.properties中的配置 将listeners和advertised.listeners的值用主机名进行替换&#xff0c;在外用使用java进行生产者或消费者连接的时候&#xff0c;不填写具体的IP&#xff0c;填写安装kafka的主…