OpenMesh入门3(译自OpenMesh6.3 Documents)

使用(自定义)属性

本例主要说明以下问题:

1.如何添加和移除自定义属性

2.如何获取和设置自定义属性值

上一例,我们计算了每个节点的单环领域内所有节点的重心,从存储在一个外部数组中。而如果将数据存储在mesh中,由OpenMesh管理,将更不容易出错。如果能将这样的属性动态挂接到mesh中,那多好。

OpenMesh提供动态属性,利用动态属性,可以为每个mesh挂接实体数据(节点、面、边缘、半边甚至mesh本身)。区分是自定义属性还是标准属性是比较容易的,自定义属性可使用成员函数property(...),传入句柄和实体数据句柄来访问;而标准属性通过特殊的成员函数访问,例如,使用point(...)函数,传入节点句柄访问节点坐标数据。

在本例中,我们试图将额外的节点属性存储下来,区别于上一个例子的是,这里,我们使用自定义属性,而不是使用独立的外部数组。首先,需要定义一个所谓的属性句柄,这个句柄隶属特定的类型(MyMesh::Point),然后在mesh中注册这个句柄:

// this vertexproperty stores the computed centers of gravity

OpenMesh::VPropHandleTcogs;

mesh.add_property(cogs);

mesh将为这个自定义属性分配足够的内存空间,一遍容纳足够数量的Mesh::Point类型的数据,当然,在mesh进行自定义属性的插入和删除操作,mesh对所有节点的操作都可视为同步的。

一旦所需的属性注册完毕,我们将可以使用这个属性,用于存储每个节点的单环领域节点的重心数据。

for(vv_it=mesh.vv_iter( *v_it ); vv_it; ++vv_it)

{

mesh.property(cogs,*v_it)+= mesh.point( *vv_it );

++valence;

}

mesh.property(cogs,*v_it)/= valence;


最后,使用v_it迭代器,为每个节点设置新的位置坐标。

mesh.set_point( *v_it,mesh.property(cogs,*v_it) );

下面是完整的源代码:

#include

#include

//--------------------

#include

#include

typedef OpenMesh::TriMesh_ArrayKernelT<>MyMesh;

int main(int argc, char **argv)

{

MyMesh mesh;

// check commandline options

if (argc != 4)

{

std::cerr <<"Usage:"<< argv[0] << " #iterations infile outfile\n";

return 1;

}

// read mesh fromstdin

if ( ! OpenMesh::IO::read_mesh(mesh,argv[2]) )

{

std::cerr <<"Error:Cannot read mesh from " << argv[2] << std::endl;

return 1;

}

// this vertexproperty stores the computed centers of gravity

OpenMesh::VPropHandleTcogs;

mesh.add_property(cogs);

// smoothing meshargv[1] times

MyMesh::VertexIterv_it, v_end(mesh.vertices_end());

MyMesh::VertexVertexItervv_it;

MyMesh::Pointcog;

MyMesh::Scalarvalence;

unsignedint i,N(atoi(argv[1]));

for (i=0; i < N;++i)

{

for(v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it)

{

mesh.property(cogs,*v_it).vectorize(0.0f);

valence = 0.0;

for(vv_it=mesh.vv_iter( *v_it ); vv_it.is_valid(); ++vv_it)

{

mesh.property(cogs,*v_it)+= mesh.point( *vv_it );

++valence;

}

mesh.property(cogs,*v_it)/= valence;

}

for(v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it)

if (!mesh.is_boundary( *v_it ) )

mesh.set_point(*v_it, mesh.property(cogs,*v_it) );

}

// write mesh tostdout

if ( ! OpenMesh::IO::write_mesh(mesh,argv[3]) )

{

std::cerr <<"Error:cannot write mesh to " << argv[3] << std::endl;

return 1;

}

return 0;

}

 

你可能感兴趣的:(OpenMesh)