主要内容
- Libigl基本知识
- 离散几何参量与算子
Libigl基本知识
Libigl设计原则
- 没有复杂的数据类型。只使用矩阵和向量;
- 尽可能减少对外部库的依赖
- 只有头文件(也可以做一个静态编译库)
- 函数封装性
下载Libigl
git clone https://github.com/libigl/libigl.git
Ligigl核心功能只依赖C++标准库和Eigen
但是编译起来还是挺费劲的,哈!
Mesh表示
Libigl使用Eigen库编码向量和矩阵
Eigen参考指南: Dense matrix和Spase matrix
一个三角网格编码为一对矩阵:
Eigen::MatrixXd V;
Eigen::MatrixXi F;
- V是#N*3的矩阵,每一行存储一个顶点(xyz);
- F是连通关系,每一行存储组成三角形的三个顶点的下标
- F中顶点的下标顺序决定了三角形的朝向
这种编码方式的好处是:
- 节约内存和缓冲
- 使用下标而不是指针,调试起来很简约
- 数据很容易复制和序列化
Libigl提供从用网格格式的I/O函数
例如,读取off文件并写出obj文件
igl::readOFF(path, V, F);
igl::writeOBJ(name, V, F);
可视化表面
Libigl使用glfw-based OpenGL 3.2 viewer来可视化surface。同时提供了glfw的相关性质
// Plot a mesh
igl::opengl::glfw::Viewer viewer;
viewer.data().set_mesh(V, F);
viewer.launch();
set_mesh()把网格数据拷贝给viewer,launch()创建一个glfw的窗口- 默认相机模式是2-axis,可以改成3-axis trackboall模式:
viewer.core().set_rotation_type(igl::opengl::ViewerCore::ROTATION_TYPE_TRACKBALL);
- 可以使用标准OpenGL代码来扩展Viewer
使用键鼠进行交互
通过在Viewer中注册事件触发器的回调函数,实现键鼠交互。支持以下几种类型:
bool (*callback_pre_draw)(Viewer& viewer);
bool (*callback_post_draw)(Viewer& viewer);
bool (*callback_mouse_down)(Viewer& viewer, int button, int modifier);
bool (*callback_mouse_up)(Viewer& viewer, int button, int modifier);
bool (*callback_mouse_move)(Viewer& viewer, int mouse_x, int mouse_y);
bool (*callback_mouse_scroll)(Viewer& viewer, float delta_y);
bool (*callback_key_down)(Viewer& viewer, unsigned char key, int modifiers);
bool (*callback_key_up)(Viewer& viewer, unsigned char key, int modifiers);
- 使用键盘的最简单的例子就是通过按键,在不同网格模型之间切换
- 在初始化Viewer后,注册回调函数
viewer.callback_key_down = &key_down;
- 按键事件,在绘制新的mesh前记得要先清楚之前的mesh
bool key_down(igl::opengl::glfw::Viewer& viewer, unsigned char key, int modifier)
{
if (key == '1')
{
viewer.data().clear();
viewer.data().set_mesh(V1, F1);
viewer.core.align_camera_center(V1,F1);
}
else if (key == '2')
{
viewer.data().clear();
viewer.data().set_mesh(V2, F2);
viewer.core.align_camera_center(V2,F2);
}
return false;
}
标量场的可视化
通过set_colors()可以为顶点或者面附着颜色
viewer.data().set_colors(C);
- C是一个#C*3的矩阵,每一行是RGB值;C的行数必须和面片的数目或顶点的数据相等。viewer根据数量自动决定是把颜色加到顶点还是面片上
逐顶点的标量场可以直接使用set_data
viewer.data().set_data(D);
- D是#V*1的向量,每个顶点一个值;
set_data会在三角形内线性插值出颜色;这个颜色是通过一个colormap查找得到的;默认的colormap是igl::COLOR_MAP_TYPE_VIRIDIS,有21个离散区间;可以自定义colormapset_colormap
Overlays (勉强翻译成图示)
Viewer还支持点、线和文本标签的可视化
viwer.data().add_points(P, Eigen::RowVector3d(r,g,b));
- 绘制点,坐标是P的每一行,颜色统一是rgb;点的大小可以统一设置
viewer.data().point_size
viewer.data().add_edges(P1,P2,Eigen::RowVector3d(r,g,b));
- 绘制线,连接P1和P2的对应行的坐标,P1和P2必须是同大小
viewer.data().add_label(p, str);
- 绘制标签,在位置p,字符串是str
例子105:使用Eigen快速找到模型的bounding box
Viewer菜单
Libigl使用Dear ImGui实现了默认菜单;也可以自制新的界面
例子106:自制菜单
多个网格
Libigl的Viewer提供绘制多个网格的功能。通过viewer.selected_data_index选择网格;默认index是0
例子107:绘制多个网格,使用键盘切换
多个视图
Libigl的Viewer提供基本的多视点绘制网格的功能
- 通过
View::append_core()可以添加view core。最多可以添加31个cores,每个core指派了一个unsigned int的id,通过Viewer::core(id)可以访问到 - 如果有多于一个的view core,用户需要指定每个视窗的大小、位置。还需要明确当窗口大小变化时,这个视窗怎么跟着变
举个栗子:左右俩窗口

Libigl是一个轻量级的C++库,专注于离散几何处理,包括网格表示、法向量计算、可视化等功能。它使用Eigen库编码向量和矩阵,仅依赖C++标准库和Eigen。Libigl的可视化模块基于OpenGL,提供了一个glfw-based Viewer,支持多网格、多视图和交互操作。此外,库中还包括了标量场的可视化、键盘鼠标交互、高斯曲率和平均曲率的计算。该库对于几何建模和计算非常有用。
最低0.47元/天 解锁文章
1483

被折叠的 条评论
为什么被折叠?



