算法参考:
几种网格平滑算法的实现
数学基础:
重心坐标
//给网格添加一个Point类型的cogs属性,用来保存每一个顶点的重心位置
//VPropHandleT字面上的理解就是顶点属性的句柄
OpenMesh::VPropHandleT<Mesh::Point> cogs;
src_mesh_->add_property(cogs);//给网格中每个点添加一个属性cogs
实现上cogs并不属于顶点,所以使用property的方法访问cogs,而不是使用句柄的方式,存储器重心信息到动态属性cogs中
意思就是不能直接通过*v_it访问这个重心,而是要通过property(cogs, v_it)将值传入到cog中,当前的cog是和当前迭代器指示的v_it对应的
//遍历cogs点的所有邻点
for (vv_it = src_mesh_->vv_iter(*v_it); vv_it.is_valid(); ++vv_it)
{
src_mesh_->property(cogs, *v_it) += src_mesh_->point(*vv_it);
++valence;
}
src_mesh_->property(cogs, *v_it) /= valence;
一些openmesh函数的使用
vectorize(0.0f);//应该是点的初始化
/*
Property management - get property value for an item
*/
template<typename T >
T & property (VPropHandleT< T > _ph, VertexHandle _vh)
Get value for item represented by the handle.
具体的程序
//定义cogs,并给网格src中每一个点添加动态属性
OpenMesh::VPropHandleT<Mesh::Point> cogs;
src_mesh_->add_property(cogs);
src_mesh_->property(cogs, *v_it);//是通过property()提取与*v_it相对应的重心坐标
set_point(*v_it, src_mesh_->property(cogs, *v_it));
Mesh::VertexIter v_it;//顶点的迭代器
Mesh::VertexVertexIter vv_it;//与点有关的邻点的迭代器
Mesh::Point cog;
Mesh::Scalar valence;
unsigned int N(1);
for (int i = 0; i < N; i++)
{
for (v_it = src_mesh_->vertices_begin(); v_it != src_mesh_->vertices_end(); ++v_it)
{
src_mesh_->property(cogs, *v_it).vectorize(0.0f);
valence = 0.0;
for (vv_it = src_mesh_->vv_iter(*v_it); vv_it.is_valid(); ++vv_it)
{
src_mesh_->property(cogs, *v_it) += src_mesh_->point(*vv_it);
++valence;
}
src_mesh_->property(cogs, *v_it) /= valence;
}
//更新顶点
for (v_it = src_mesh_->vertices_begin(); v_it != src_mesh_->vertices_end(); ++v_it)
{
if (!src_mesh_->is_boundary(*v_it))
{
src_mesh_->set_point(*v_it, src_mesh_->property(cogs, *v_it));
}
}
}