pybind11 绑定CGAL几何算法(numpy数据交换)
[TOC]
一 前言
对于CGAL,前段时间也用过相关的Python绑定,详情见文章:【CGAL+Python】安装CGAL的Python绑定。如果我们想要调用[Polygon Mesh Processing](CGAL 5.5.1 - Polygon Mesh Processing: User Manual)中的算法,在不就地读取网格文件的前提下,需要在Python代码中构建CGAL的多边形网格对象,显得非常的不方便和蹩脚。正好,我在之前使用过libigl库的Python绑定,其数据通过numpy进行交换,即输入和输出都是numpy数组。于是,在对pybind11进行了一段时间的学习后,我开始尝试通过pybind11对CGAL的相关函数进行绑定生成Python调用接口,更重要的是使用numpy数组进行数据交换。
二 numpy数据交换
2.1 pybind11对numpy的支持
在pybind11/numpy.h
头文件中,提供了对Numpy array的支持。我们可以通过py::array_t<T>
来实现一个Numpy array。
py::array_t
支持一些基于Numpy的API:
.dtype()
返回数组元素的类型。.strides()
返回数组strides的指针。.reshape({i, j, ...})
返回指定shape的数组视图。.resize({})
也可以。.index_at(i, j, ...)
获取数组指定索引的元素。
为了更高效地访问大型数组,pybind11提供了不带检查的代理类unchecked<N>
和mutable_unchecked<N>
,其中N
为数组所需的维数。
1 |
|
这两个代理类的区别就是:当只用从一个array_t<T>
对象中读取数据时,我们使用unchecked<N>
对它进行代理访问;当我们需要修改一个array_t<T>
对象中的数据时,我们使用mutable_unchecked<N>
对它进行代理访问。
同时Numpy array支持缓冲协议(buffer protocol),因此我们也可以通过.request()
对其的缓冲区信息进行访问。
1 |
|
其他详细信息参见文档:NumPy - pybind11 documentation。
2.2 Numpy VF(py::array_t)与CGAL mesh(Surface Mesh)之间的转换
1 |
|
三 绑定CGAL算法示例
3.1 示例函数
在本文中我们尝试绑定[Polygon Mesh Processing](CGAL 5.5.1 - Polygon Mesh Processing: User Manual)中的isotropic_remeshing
函数。
1 |
|
3.2 绑定部分代码
1 |
|
3.3 示例完整代码
1 |
|
这里为了图方便将所有代码全写在了一个源文件里,正常来说应当将绑定代码和绑定对象分开。
四 编译生成和测试
4.1 编译生成pyd文件
在这个示例中,我是直接使用Visual Studio编译生成pyd文件。操作很简单,首先是按照这篇文章:pybind11学习 | VS2022下安装配置在VS中配置好pybind11,然后按照这篇文章:CGAL的安装与在VS中的配置在VS中配置好CGAL。在pybind11和CGAL都配置成功的前提下,生成解决方案即可得到pyd文件。如果电脑上没装Visual Studio,也可以尝试使用CMake进行构建,也是十分简单的,只需在这篇文章:pybind11学习 | 使用CMake构建系统并生成pyd文件的示例基础上在CMakeLists.txt
中添加CGAL的库文件和头文件即可。
4.2 Python调用测试
测试代码如下:
1 |
|
其中,第一个isotropic_remeshing_off
函数是通过文章【CGAL+Python】安装CGAL的Python绑定中提到的绑定加上读写off文件实现的CGAL重新网格化算法调用。第二个isotropic_remeshing_bindings
函数是通过调用pybind11生成的Python拓展模块(即本文的方法,numpy_cgal.pyd为上一小节生成的pyd文件)实现的。
调试结果如下:
可以看到,函数输入为ndarray类型,输出仍然为ndarray类型,且成功重新网格化,测试完毕。
五 总结
本文主要介绍一种在Python代码中调用C++第三方库API的思路。主要目的是抛砖引玉,本文的方法不一定是最好的,仅供大家参考学习。
参考和拓展
[1] CGAL 5.5.1 - Surface Mesh: User Manual
[2] CGAL 5.5.1 - Polygon Mesh Processing: User Manual
[4] pybind11—opencv图像处理(numpy数据交换) - 简书 (jianshu.com)
[5] pybind11-wrapped CGAL (github.com)
[6] cmpute/cgal.py: Pybind11 binding of cgal. Aimed at extending and easy use (github.com)
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!