Boost property_map 学习笔记及其与CGAL的关系
针对读者: 使用CGAL作研究的学生
Interior Properties 内部属性(这一点类似于我们在创建Polyhedron时候绑定的id) 2
Exterior Properties 外部属性(这一部分可以作为对应于特定算法中,对Vertex,Face等绑定的属性) 2
Boost::property_map提供了动态绑定元素的附加属性的功能,可以动态地为元素增加属性。提供类似功能的库有:Qt的Q_PROPERTY及OpenMesh。
我想使用此库的目的是模仿OpenMesh中提供的property功能,为CGAL的Polyhedron中的Vertex_handle,Halfedge_handle,Facet_handle等动态地添加属性。 使得在最基本的Polyhedron上,根据算法的不同,动态地将属性绑定给Vertex_handle,Facet_handle等以达到解耦的效果。
比较:
相较于Q_PROPERTY而言,boost::property_map更灵活,Qt的Property在类级别,我想应该也可以通过封装Vertex_handle等形成类来增加属性,但这样显得繁琐。boost::property_map不需要使用的具体的类,只需要有对应的左值供其使用即可。
Boost Property Map 的概念为将键对象映射至相应的值对象定义了一个通用的接口,从而对算法隐藏了如何实现映射的细节。
Boost::property_map如何使用?
Boost的库文档提供了如何使用boost::property_map的方法。这部分一开始看了好几次没有看明白,后来大概了解其用法了。
首先,需要自行创建map的对应关系,然后可以使用
boost::associate_property_map,boost::dynamic_maps等构建property_map(根据需要,你可以建立几种形式的property_map)。
而后,你可以对此property_map进行操作,如put,get,operator[]等操作。
Interior Properties 内部属性(这一点类似于我们在创建Polyhedron时候绑定的id)
are stored ``inside'' the graph object in some way, and the lifetime of the property value objects is the same as that of the graph object.
A trait class is defined that provides a generic way to deduce the property map type: property_map
Exterior Properties 外部属性(这一部分可以作为对应于特定算法中,对Vertex,Face等绑定的属性)
are stored ``outside'' of the graph object and the lifetime of the property value objects is independent of the graph. This is useful for properties that are only needed temporarily, perhaps for the duration of a particular algorithm such as the color property used in breadth_first_search(). When using exterior properties with a BGL algorithm a property map object for the exterior property must be passed as an argument to the algorithm.
The first method uses the adaptor class random_access_iterator_property_map. This class wraps a random access iterator, creating a property map out of it
CGAL与Boost Property_map
第一种使用方式
CGAL内部基于Property_map定义了几种Property_map,其中Unique_hash_map.h中定义的Unique_hash_map提供了快速访问的接口。在CGAL教程中有特别一章介绍CGAL与Boost::property_map之间的关系。
正如上一小节提到,创建外部属性的第一种方法是使用random_access_iterator_property_map ,这一点对应于CGAL中已经定义了Random_access_adaptor,可以很方便地建立index_to_vertex的map,而且这不需要另外定义map,示例如下:
#include <CGAL/iterator.h>
Typedef CGAL::Random_access_adaptor<Vertex_iterator> Random_access_index;
Random_access_index index_to_vertex_map;
之后,则可以通过定义两个成员函数来初始化并供id到Vertex_handle的获取了。如下:
Vertex_handle get_vertex_handle(int idx)
{
If(idx < size_of_vertices())
Return index_to_vertex_map[idx];
Return Vertex_handle();
}
Void init_index_to_vertex_map()
{
For(Vertex_iterator pVertex = vertices_begin();
pVertex != vertices_end(); pVertex++)
index_to_vertex_map.push_back(pVertex);
}
深入到<CGAL/iterator.h>,也可以发现CGAL中的Random_access_adaptor内部由vertor对元素进行存储并提供随机访问。
第二种使用方式
在CGAL中使用boost::property_map的第二种理想方式,是使用associate_property_map,这种使用方式与boost文档中的例子基本一致,只是我们可以在这里把Vertex_handle此类数据作为索引来存取与点或面相关联的数据
参考资料:
Boost.org Boost documentation
Cgal.org CGAL documentation
CGAL Subdivision tutorial