最近开始做网格重建与优化方面的工作,这里就不得不提到Isotropic Remeshing. 部分内容参考自:https://zhuanlan.zhihu.com/p/104107745#ref_3

在之前的博客中,我们已经提到了一种非常好的Isotropic Remeshing方法,即基于CVT(Centroidal Voronoi Tessellation)的网格重建方法,链接:https://blog.csdn.net/aliexken/article/details/106746560。该方法能够基于点云得到一个非常好的isotopic mesh。但是,该方法存在两个问题,第一,基于劳埃德优化与Delaunay三角化的点位置更新速度太慢;第二,在曲率变化比较显著的区域,可能会产生错误的三角化结果。

为了解决该问题,可以把网格重建分成两步:第一步,获取一个几何正确的三角网格,但是不保证网格内部三角形的质量,第二步,对网格的三角形进行优化,在保持几何一致的前提下,优化三角网格的质量。这里,我们就来介绍一下如何对三角网格进行优化,即isotropic remeshing.

1. 优化步骤

Botsch [Botsch 2004] 在2004年的文章中介绍了一种实现简单,结果优秀的优化方法。其具体的思路就是设定一个目标边长,并优化网格中所有的边长向目标边长靠近,并最终得到优化结果。那么,这里主要分为三个步骤,来实现向目标边长的优化,即分割Split,塌缩Collapse和翻转Flip,如下图:

Split:

Flip:

Collapse:

算法的步骤可以归纳为:

第四步具体步骤:

获取目标优化边长L。

1. Split所有长度大于4/3L的边。

2. Collapse所有长度效益4/5L的边。

3. 对所有边进行Flip,以优化度数,内点为6,边界为4. 一个点的度数为连接该点的边的总数。

4. 映射所有新加入的点到切平面。

在进行各种操作的时候,需要注意一点,那就是不能产生二度点和重边的情况,如图所示:

2. 优化实现

CGAL库封装了该方法:https://doc.cgal.org/latest/Polygon_mesh_processing/index.html#title7

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/remesh.h>
#include <CGAL/Polygon_mesh_processing/border.h>
#include <boost/function_output_iterator.hpp>
#include <fstream>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
typedef boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
typedef boost::graph_traits<Mesh>::edge_descriptor     edge_descriptor;
namespace PMP = CGAL::Polygon_mesh_processing;
struct halfedge2edge
{halfedge2edge(const Mesh& m, std::vector<edge_descriptor>& edges): m_mesh(m), m_edges(edges){}void operator()(const halfedge_descriptor& h) const{m_edges.push_back(edge(h, m_mesh));}const Mesh& m_mesh;std::vector<edge_descriptor>& m_edges;
};
int main(int argc, char* argv[])
{const char* filename = (argc > 1) ? argv[1] : "data/pig.off";std::ifstream input(filename);Mesh mesh;if (!input || !(input >> mesh) || !CGAL::is_triangle_mesh(mesh)) {std::cerr << "Not a valid input file." << std::endl;return 1;}double target_edge_length = 0.04;unsigned int nb_iter = 3;std::cout << "Split border...";std::vector<edge_descriptor> border;PMP::border_halfedges(faces(mesh),mesh,boost::make_function_output_iterator(halfedge2edge(mesh, border)));PMP::split_long_edges(border, target_edge_length, mesh);std::cout << "done." << std::endl;std::cout << "Start remeshing of " << filename<< " (" << num_faces(mesh) << " faces)..." << std::endl;PMP::isotropic_remeshing(faces(mesh),target_edge_length,mesh,PMP::parameters::number_of_iterations(nb_iter).protect_constraints(true)//i.e. protect border, here);std::cout << "Remeshing done." << std::endl;return 0;
}

为了将来对该方法进行进一步优化,我也在尝试自己重建全部的代码,包括维护一个近似半边结构,以及对应的优化操作(在完成后,我将更新该帖子,发布代码)。

3. 优化结果

参考文献:

[Botsch 2004] A Remeshing Approach to Multiresolution Modeling.

[Botsch 2013] Adaptive Remeshing for Real-Time Mesh Deformation.

Isotropic Remeshing:各向同性网格重建介绍与实现相关推荐

  1. 【CGAL_网格处理】Isotropic Remeshing均匀化网格

    原理 算法伪代码如下: remesh(target_edge_length)low = 4/5 * target_edge_lengthhigh = 4/3 * target_edge_lengthf ...

  2. 无监督特定类别的网格重建(U-CMR) | ECCV

    项目.代码地址:在公众号「3D视觉工坊」,后台回复「U-CMR」,即可直接下载. 概述 本文主要介绍了一个学习框架,学习从单一图像中恢复物体的三维形状.姿态和纹理,训练集是没有任何真实三维形状.多视角 ...

  3. Total3DUnderstanding: 单图像室内场景的联合布局、物体姿态和网格重建

    文章目录 摘要 1.简介 2.相关工作 3.方法 3.1.3D目标检测与布局估计 3.2. 室内物体的网格生成 3.3. Total 3D Understanding 的联合学习 4.结果与评价 4. ...

  4. [UGUI源码剖析]—Rebuild 网格重建(画布刷新)系统

    几个比较重要的类和接口: Canvas.CanvasUpdateRegistry.ClipperRegistry.LayoutRebuilder.LayoutGroup.Graphics.Maskab ...

  5. Planar Isotropic平面各向同性

    Isotropic各向同性 简单的说各向同性就是说物质在各个方向保持同样性质的特性,就想一根金属导线无论是正接反接还是侧接,都能导电,而且电阻等电性参数保持相同. Planar Isotropic平面 ...

  6. 详细解读!Isotropic Remeshing的详细介绍与实现

    学习remeshing,今天看了知乎大佬的一篇文章,给大家共同总结学习一下,真的不错. 1. 问题 对于三角网格,可能顶点分布不均,这会影响很多网格应用的效果(如数值模拟,几何建模等),因此需要将网格 ...

  7. OpenFOAM动网格技术介绍【转载】

    转载自:http://blog.sina.com.cn/s/blog_e256415d0101nfhp.html Chalmers大学的Andreu Oliver González对OpenFOAM中 ...

  8. GMesh网格选项介绍

    GMesh网格介绍 2D mesh algorithm MeshAdapt:这是一种自适应网格算法,可在需要更大的精度或在某些区域需要更密集的网格时自动添加额外的网格.该算法的优点包括较高的收敛性和灵 ...

  9. CSS3中的display:grid网格布局介绍

    1.网格布局(grid): 它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局; 2.基本概念: 容器和项目,如图所示: <div class="content&qu ...

最新文章

  1. [AlwaysOn Availability Groups]排查:Primary上的修改无法在Secondary体现
  2. 惊闻VeryCD的电驴下载部分即将关闭
  3. 专属自己的二维游戏引擎【二】
  4. C++trie树的多重搜索算法的实现(附完整源码)
  5. java server模式 设置_JVM client模式和Server模式的区别
  6. Visual Editor插件下载、安装问题(Eclipse3.1.1)
  7. n2n内网穿透打洞部署全过程 + nginx公网端口映射
  8. 分层和分段用什么符号_小编带你学直播——后牙树脂分层堆塑
  9. asyncio oracle 异步,带有asyncio futures和RuntimeError的InvalidStateError与aiohttp时使用期货回调...
  10. 网页下载CAB文件总结
  11. KVM详解(三)——KVM创建虚拟机
  12. Linux学习笔记(13)
  13. 3.1_21 JavaSE入门 P20 【正则】Pattern模式类、Matcher匹配器、元字符、分组捕获、反向引用
  14. 【IIOT】欧姆龙PLC数采之CP2E
  15. 超宽带 DWM1000模块 简介
  16. 据说这是一堂价值300万元的课。有空看下,不要错过
  17. Springboot中下划线转驼峰配置
  18. SAP 标准成本、计划成本、目标成本、实际成本解析
  19. 修改Chromium源码实现HEVC/H.265 4K视频播放
  20. php 抽象工厂模式,PHP设计模式(三)抽象工厂模式(Abstract Factory)

热门文章

  1. 职场四象限法则:时间管理四象限与职场沟通四象限
  2. English Learning - L2 语音作业打卡 小元音 [ʌ] [ɒ] Day9 2023.3.1 周三
  3. 21点纸牌游戏完整代码
  4. C++:string 截取字符串
  5. String 截取字符串方法——subString()
  6. js遍历一段html,JS遍历HTML元素
  7. 如何使用 SQL GROUP BY 分组和排序数据
  8. 各种音频视频编码方法
  9. 反射率(表观反射率、地表反射率)
  10. ubuntu虚拟机配置