本例子说明以下问题:
1.如何声明你自己的mesh类型MyMesh
2.如何向mesh对象添加节点和面
3.如何通过IO函数将mesh写至硬盘
利用OpenMesh进行开发,首先需要定义你自己的mesh类型MyMesh。OpenMesh支持一般的多边形mesh和特殊的三角面mesh。在这个例子中,我们希望使用留个四边形建立一个立方体,所以,我们选择多边形mesh。
OpenMesh也支持不同的mesh内核,指明所有的节点、边缘和面在内部如何存储,这样,内存必须提供数组形式的接口。本例中,我们使用内建的ArrayKernel。OpenMesh/src/OpenMesh/Core/Mesh中预定义了TriMesh/PolyMesh及其内核,我们使用PolyMesh_ArrayKernelT模板。
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
typedef OpenMesh::PolyMesh_ArrayKernelT<>MyMesh;
现在,我们已经声明了我们自己的mesh类型MyMesh,下面,为了建立立方体,我们还需要添加8个节点和6个四边形,使用add_vertex函数实现。这个函数输入坐标,输出为节点句柄。由于需要使用它们来指定表面,我们使用数组存储所有的句柄。
vhandle[0] = mesh.add_vertex(MyMesh::Point(-1,-1, 1));
vhandle[1] = mesh.add_vertex(MyMesh::Point(1, -1, 1));
vhandle[2] = mesh.add_vertex(MyMesh::Point(1, 1, 1));
vhandle[3] = mesh.add_vertex(MyMesh::Point(-1,1, 1));
为了在mesh中添加表面,我们不得不建立一个vector,来存储面的节点的索引。这个vector将被传递给add_face函数。下面的代码使用前四个节点创建表面。
std::vector<MyMesh::VertexHandle>face_vhandles;
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[3]);
mesh.add_face(face_vhandles);
面的方向由vector中存储节点的顺序指定:如果你从面的“前面”看,节点排列顺序是逆时针的。创建完所有的6个面后,我们希望将我们刚刚创建的mesh进行标准化输出。OpenMesh在命名空间OpenMesh::IO中提供了一些基本的输入/输出函数。
if ( !OpenMesh::IO::write_mesh(mesh,"output.off") )
使用OpenMesh::IO前,应当首先包含MeshIO.hh文件。.
#include <OpenMesh/Core/IO/MeshIO.hh>
#include<OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
完整的代码如下:
/*========================================================================= *
* *
* OpenMesh *
* Copyright (c) 2001-2015, RWTH-AachenUniversity *
* Department of Computer Graphics andMultimedia *
* All rights reserved. *
* www.openmesh.org *
* *
*---------------------------------------------------------------------------*
* This file is part of OpenMesh. *
*---------------------------------------------------------------------------*
* *
* Redistribution and use in source andbinary forms, with or without *
* modification, are permitted provided thatthe following conditions *
* are met: *
* *
* 1. Redistributions of source code mustretain the above copyright notice, *
* this list of conditions and the followingdisclaimer. *
* *
* 2. Redistributions in binary form mustreproduce the above copyright *
* notice, this list of conditions and thefollowing disclaimer in the *
* documentation and/or other materialsprovided with the distribution. *
* *
* 3. Neither the name of the copyrightholder nor the names of its *
* contributors may be used to endorse orpromote products derived from *
* this software without specific priorwritten permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHTHOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS ORIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OFMERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NOEVENT SHALL THE COPYRIGHT HOLDER *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, *
* PROCUREMENT OF SUBSTITUTE GOODS ORSERVICES; LOSS OF USE, DATA, OR *
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVERCAUSED AND ON ANY THEORY OF *
* LIABILITY, WHETHER IN CONTRACT, STRICTLIABILITY, OR TORT (INCLUDING *
* NEGLIGENCE OR OTHERWISE) ARISING IN ANYWAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF SUCH DAMAGE. *
* *
*========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#include <iostream>
// -------------------- OpenMesh
#include <OpenMesh/Core/IO/MeshIO.hh>
#include<OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
// ----------------------------------------------------------------------------
typedef OpenMesh::PolyMesh_ArrayKernelT<>MyMesh;
//----------------------------------------------------------------------------
// Build a simple cube and write it tostd::cout
int main()
{
MyMesh mesh;
// generate vertices
MyMesh::VertexHandlevhandle[8];
vhandle[0] = mesh.add_vertex(MyMesh::Point(-1,-1, 1));
vhandle[1] = mesh.add_vertex(MyMesh::Point(1, -1, 1));
vhandle[2] = mesh.add_vertex(MyMesh::Point(1, 1, 1));
vhandle[3] = mesh.add_vertex(MyMesh::Point(-1,1, 1));
vhandle[4] = mesh.add_vertex(MyMesh::Point(-1,-1, -1));
vhandle[5] = mesh.add_vertex(MyMesh::Point(1, -1, -1));
vhandle[6] = mesh.add_vertex(MyMesh::Point(1, 1, -1));
vhandle[7] = mesh.add_vertex(MyMesh::Point(-1,1, -1));
// generate (quadrilateral) faces
std::vector<MyMesh::VertexHandle>face_vhandles;
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[3]);
mesh.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[7]);
face_vhandles.push_back(vhandle[6]);
face_vhandles.push_back(vhandle[5]);
face_vhandles.push_back(vhandle[4]);
mesh.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[4]);
face_vhandles.push_back(vhandle[5]);
mesh.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[1]);
face_vhandles.push_back(vhandle[5]);
face_vhandles.push_back(vhandle[6]);
mesh.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[2]);
face_vhandles.push_back(vhandle[6]);
face_vhandles.push_back(vhandle[7]);
mesh.add_face(face_vhandles);
face_vhandles.clear();
face_vhandles.push_back(vhandle[0]);
face_vhandles.push_back(vhandle[3]);
face_vhandles.push_back(vhandle[7]);
face_vhandles.push_back(vhandle[4]);
mesh.add_face(face_vhandles);
// write mesh to output.obj
try
{
if ( !OpenMesh::IO::write_mesh(mesh,"output.off") )
{
std::cerr << "Cannot write mesh to file'output.off'"<< std::endl;
return 1;
}
}
catch( std::exception& x )
{
std::cerr << x.what() <<std::endl;
return 1;
}
return 0;
}