Young87

SmartCat's Blog

So happy to code my life!

游戏开发交流QQ群号60398951

当前位置:首页 >跨站数据测试

Openmesh中的mesh结构的基本使用

Openmesh中的网格模型相比于PCL中的网格模型复杂很多,除了常见的坐标、纹理坐标、法线、颜色信息之外,增加了边、半边以及相关的边折叠、边拆分等操作,使用起来就非常简单了,所以在这里,简单介绍一下里面一些基本的操作;

 

半边结构
半边数据结构​​

 

1、从文件中读取的普通的点面mesh

//openmesh
#include <OpenMesh/Core/Mesh/TriConnectivity.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/Handles.hh>
#include <OpenMesh/Core/Mesh/ArrayKernel.hh>

typedef OpenMesh::TriMesh_ArrayKernelT<> meshT;

int main(){
    std::string meshFile = "./data/17_ofm_64.obj";
	meshT mesh;
	OpenMesh::IO::read_mesh(mesh, meshFile);

    return 0;
}

这里定义的网格模型只包含一下几个默认的属性,

struct DefaultTraits
{
  /// The default coordinate type is OpenMesh::Vec3f.
  typedef Vec3f  Point;

  /// The default normal type is OpenMesh::Vec3f.
  typedef Vec3f  Normal;

  /// The default 1D texture coordinate type is float.
  typedef float  TexCoord1D;
  /// The default 2D texture coordinate type is OpenMesh::Vec2f.
  typedef Vec2f  TexCoord2D;
  /// The default 3D texture coordinate type is OpenMesh::Vec3f.
  typedef Vec3f  TexCoord3D;

  /// The default texture index type
  typedef int TextureIndex;

  /// The default color type is OpenMesh::Vec3uc.
  typedef Vec3uc Color;

#ifndef DOXY_IGNORE_THIS
  VertexTraits    {};
  HalfedgeTraits  {};
  EdgeTraits      {};
  FaceTraits      {};
#endif

  VertexAttributes(0);
  HalfedgeAttributes(Attributes::PrevHalfedge);
  EdgeAttributes(0);
  FaceAttributes(0);
};

2、统计网格模型中点边面的个数及其遍历

int nV = mesh.n_vertices(), nE = mesh.n_edges(), nF = mesh.n_faces(),
			nHe = mesh.n_halfedges();
meshT::EdgeIter eIt , eEnd = mesh.edges_end();
	for (eIt = mesh.edges_begin(); eIt != eEnd; ++eIt){
		

		meshT::HalfedgeHandle & hh = mesh.halfedge_handle(*eIt, 0);

		meshT::VertexHandle & v0 = mesh.from_vertex_handle(hh);
		meshT::VertexHandle & v1 = mesh.to_vertex_handle(hh);

		meshT::Point vec = mesh.point(v1) - mesh.point(v0);//得到边向量
		
        meshT::VOHIter vhIt;//顶点相关的半边iter
		for (vhIt = mesh.voh_iter(v0); vhIt.is_valid(); ++vhIt)
			//遍历从Vo出发的每一条半边,进行操作
			}
		}
	}

 

2、顶点的法线的计算

读取的网格模型默认只读取顶点和面片信息,如果模型中存在法线信息或者中没有法线信息,需要重新计算,必须首先计算face的信息,才能计算顶点的法线信息,后者计算利用了前者的信息

mesh.request_face_normals();
mesh.request_vertex_normals();
mesh.request_halfedge_normals();

mesh.update_normals();//该函数中依次计算了面法线、顶点法线、半边的法线,后两个均利用了面法线的信息

//也可以依次计算face、顶点的法线信息
mesh.update_face_normals();
mesh.update_vertex_normals();
mesh.update_halfedge_normals();

mesh.release_face_normals();
mesh.release_vertex_normals();
mesh.release_halfedge_normals();

3、在mesh模型中增加其他的成员属性

OpenMesh::VPropHandleT< meshT::Point > q;//质心属性,增加一个质心坐标(周围顶点的平均坐标)
	if (!mesh.get_property_handle(q, "q Property"))
		mesh.add_property(q, "q Property");
meshT::ConstVertexIter vIt=mesh.vertices_sbegin();
meshT::Point tmp(0.0, 0.0, 0.0);
uint N = 0;
meshT::VVIter vvIt;//与该操作顶点的相邻顶点
for (vvIt = mesh.vv_iter(*vIt); vvIt.is_valid(); ++vvIt){
	tmp += mesh.point(*vvIt);
	N++;
}
if (N > 0)
    tmp /= (double)N;
mesh.property(q, *vIt) = tmp;

新增属性使用完毕后记得需要对应的删除

mesh.remove_property(q);

 

除特别声明,本站所有文章均为原创,如需转载请以超级链接形式注明出处:SmartCat's Blog

上一篇: 辞旧迎新又一年(18年年终总结)

下一篇: Lerna包管理

精华推荐