CBaseMesh, base class for all types of mesh classes. More...
#include <BaseMesh.h>
CBaseMesh, base class for all types of mesh classes.
This is the fundamental class for meshes. It includes a list of vertices, a list of edges, a list of faces. All the geometric objects are connected by pointers, vertex, edge, face are connected by halfedges. The mesh class has file IO functionalities, supporting .obj, .m and .off file formats. It offers Euler operators, each geometric primative can access its neighbors freely.
CVertex | vertex class, derived from MeshLib::CVertex class | |
CEdge | edge class, derived from MeshLib::CEdge class | |
CFace | face class, derived from MeshLib::CFace class | |
CHalfEdge | halfedge class, derived from MeshLib::CHalfEdge class |
Definition at line 44 of file BaseMesh.h.
typedef CEdge* MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::tEdge |
Definition at line 32 of file BaseMesh.h.
typedef CFace* MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::tFace |
Definition at line 33 of file BaseMesh.h.
typedef CHalfEdge* MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::tHalfEdge |
Definition at line 31 of file BaseMesh.h.
typedef CVertex* MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::tVertex |
Definition at line 30 of file BaseMesh.h.
MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::CBaseMesh | ( | ) | [inline] |
CBaseMesh constructor.
Definition at line 39 of file BaseMesh.h.
MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::~CBaseMesh | ( | ) |
CBasemesh destructor
CBaseMesh destructor
Definition at line 822 of file BaseMesh.h.
{ //remove vertices for( std::list<CVertex*>::iterator viter = m_verts.begin(); viter != m_verts.end(); viter ++ ) { CVertex * pV = *viter; delete pV; } m_verts.clear(); //remove faces for( std::list<CFace*>::iterator fiter = m_faces.begin(); fiter != m_faces.end(); fiter ++ ) { CFace * pF = *fiter; tHalfEdge he = faceHalfedge( pF ); std::list<CHalfEdge*> hes; do{ he = halfedgeNext( he ); hes.push_back( he ); }while( he != pF->halfedge() ); for( std::list<CHalfEdge*>::iterator hiter = hes.begin(); hiter != hes.end(); hiter ++) { CHalfEdge * pH = *hiter; delete pH; } hes.clear(); delete pF; } m_faces.clear(); //remove edges for( std::list<CEdge*>::iterator eiter = m_edges.begin(); eiter != m_edges.end(); eiter ++ ) { CEdge * pE = *eiter; delete pE; } m_edges.clear(); //clear all the maps m_map_vert.clear(); m_map_face.clear(); m_map_edge.clear();
void MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::copy | ( | CBaseMesh< CVertex, CEdge, CFace, CHalfEdge > & | mesh | ) |
Copy operator
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::corner | ( | tVertex | v, | |
tFace | f | |||
) |
Access a halfedge by its target vertex, and attaching face.
v | target vertex | |
f | attaching face |
Definition at line 702 of file BaseMesh.h.
{ CHalfEdge * he = faceMostCcwHalfEdge( f ); do{ if( he->vertex() == v ) return (CHalfEdge*) he; he = faceNextCcwHalfEdge( he ); }while( he != faceMostCcwHalfEdge(f) ); return NULL;
CEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::createEdge | ( | tVertex | v1, | |
tVertex | v2 | |||
) |
Create an edge
v1 | end vertex of the edge | |
v2 | end vertex of the edge |
Definition at line 1204 of file BaseMesh.h.
{ CEdgeKey key(v1->id(),v2->id()); CEdge * e = NULL; if( m_map_edge.find( key ) != m_map_edge.end() ) { e = m_map_edge[key]; assert( e!= NULL ); return e; } e = new CEdge; assert( e != NULL ); assert( e != NULL ); m_map_edge.insert( std::pair<CEdgeKey,CEdge *>(key,e) ); m_edges.push_back( e ); return e;
CFace * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::createFace | ( | tVertex | v[], | |
int | id | |||
) |
Create a face
v | an array of vertices | |
id | face id |
Definition at line 1096 of file BaseMesh.h.
{ CFace * f = new CFace(); assert( f != NULL ); f->id() = id; m_faces.push_back( f ); m_map_face.insert( std::pair<int,tFace>(id,f) ); //create halfedges tHalfEdge hes[3]; for(int i = 0; i < 3; i ++ ) { hes[i] = new CHalfEdge; assert( hes[i] ); CVertex * vert = v[i]; hes[i]->vertex() = vert; vert->halfedge() = hes[i]; } //linking to each other for(int i = 0; i < 3; i ++ ) { hes[i]->he_next() = hes[(i+1)%3]; hes[i]->he_prev() = hes[(i+2)%3]; } //linking to face for(int i = 0; i < 3; i ++ ) { hes[i]->face() = f; f->halfedge() = hes[i]; } //connecting with edge for(int i = 0; i < 3; i ++ ) { tEdge e = createEdge( v[i], v[(i+2)%3] ); if( e->halfedge(0) == NULL ) { e->halfedge(0) = hes[i]; } else { assert( e->halfedge(1) == NULL ); e->halfedge(1) = hes[i]; } hes[i]->edge() = e; } return f;
CVertex * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::createVertex | ( | int | id = 0 |
) |
Create a vertex
id | Vertex id |
Definition at line 893 of file BaseMesh.h.
{ CVertex * v = new CVertex(); assert( v != NULL ); v->id() = id; m_verts.push_back( v ); m_map_vert.insert( std::pair<int,CVertex*>(id,v)); return v;
void MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::deleteFace | ( | tFace | pFace | ) |
delete one face
pFace | the face to be deleted |
Definition at line 1725 of file BaseMesh.h.
{ std::map<int,tFace>::iterator fiter = m_map_face.find( pFace->id() ); if( fiter != m_map_face.end() ) { m_map_face.erase( fiter ); } m_faces.remove( pFace ); //create halfedges tHalfEdge hes[3]; hes[0] = faceHalfedge( pFace ); hes[1] = faceNextCcwHalfEdge( hes[0] ); hes[2] = faceNextCcwHalfEdge( hes[1] ); for(int i = 0; i < 3; i ++ ) { //connection with edge CHalfEdge * pH = hes[i]; //connection to target CVertex * pV = halfedgeTarget( pH ); if( pV->halfedge() == pH ) { if( pH->he_next()->he_sym() != NULL ) pV->halfedge() = pH->he_next()->he_sym(); else { assert( pH->he_sym() != NULL ); //otherwise the mesh is not a manifold pV->halfedge() = pH->he_sym()->he_prev(); } } } for(int i = 0; i < 3; i ++ ) { //connection with edge CHalfEdge * pH = hes[i]; CHalfEdge * pS = halfedgeSym( pH ); CEdge * pE = halfedgeEdge( pH ); pE->halfedge(0) = pS; pE->halfedge(1) = NULL; if( pS == NULL ) { //assert(0); m_edges.remove( pE ); CVertex * v0 = halfedgeSource( pH ); CVertex * v1 = halfedgeTarget( pH ); CEdgeKey key(v0->id(),v1->id()); std::map<CEdgeKey,tEdge>::iterator eiter = m_map_edge.find(key); if( eiter != m_map_edge.end() ) m_map_edge.erase( eiter ); delete pE; } } //remove half edges for(int i = 0; i < 3; i ++ ) { delete hes[i]; } delete pFace;
CFace * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::edgeFace1 | ( | tEdge | e | ) |
The first face attaching to an edge.
e | the input edge. |
Definition at line 476 of file BaseMesh.h.
{
assert( e->halfedge(0) != NULL );
return (CFace*) e->halfedge(0)->face();
CFace * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::edgeFace2 | ( | tEdge | e | ) |
The second face attaching to an edge.
e | the input edge. |
The second face attaching to an edge.
e | the input edge. |
Definition at line 504 of file BaseMesh.h.
{
assert( e->halfedge(1) != NULL );
return (CFace*) e->halfedge(1)->face();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::edgeHalfedge | ( | tEdge | e, | |
int | id | |||
) |
The halfedge attaching to an edge.
e | the input edge. | |
id | the index of the halfedge, either 0 or 1 |
Definition at line 491 of file BaseMesh.h.
{ return (CHalfEdge*)e->halfedge(id);
double MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::edgeLength | ( | tEdge | e | ) |
Edge length
e | the input edge |
Edge length
Definition at line 877 of file BaseMesh.h.
{ CVertex * v1 = edgeVertex1(e); CVertex * v2 = edgeVertex2(e); return ( v1->point() - v2->point() ).norm();
std::list<tEdge>& MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::edges | ( | ) | [inline] |
List of the edges of the mesh.
Definition at line 361 of file BaseMesh.h.
CVertex * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::edgeVertex1 | ( | tEdge | e | ) |
The first vertex of an edge.
e | the input edge. |
Definition at line 450 of file BaseMesh.h.
{
assert( e->halfedge(0 ) != NULL );
return (CVertex*)e->halfedge(0)->source();
CVertex * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::edgeVertex2 | ( | tEdge | e | ) |
The second vertex of an edge.
e | the input edge. |
The second vertex of an edge.
e | the input edge. |
Definition at line 463 of file BaseMesh.h.
{
assert( e->halfedge(0 ) != NULL );
return (CVertex*)e->halfedge(0)->target();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::faceHalfedge | ( | tFace | f | ) |
The first halfedge attaching to a face f.
f | the input face. |
Definition at line 530 of file BaseMesh.h.
{
return (CHalfEdge*)f->halfedge();
int MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::faceId | ( | tFace | f | ) |
The face id
f | the input face |
Definition at line 1193 of file BaseMesh.h.
{
return f->id();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::faceMostCcwHalfEdge | ( | tFace | face | ) |
The most Ccw HalfEdge of a face
face | the input face. |
Definition at line 805 of file BaseMesh.h.
{
return (CHalfEdge*)face->halfedge();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::faceMostClwHalfEdge | ( | tFace | face | ) |
The most Clw HalfEdge of a face
face | the input face. |
The most Clw HalfEdge in a face
face | the input face. |
Definition at line 814 of file BaseMesh.h.
{
return (CHalfEdge*)face->halfedge()->he_next();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::faceNextCcwHalfEdge | ( | tHalfEdge | he | ) |
The next Ccw HalfEdge of a halfedge in a face
he | the input halfedge. |
Definition at line 794 of file BaseMesh.h.
{
return (CHalfEdge*)he->he_next();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::faceNextClwHalfEdge | ( | tHalfEdge | he | ) |
The next Clw HalfEdge of a halfedge in a face
he | the input halfedge. |
Definition at line 784 of file BaseMesh.h.
{
return (CHalfEdge*)he->he_prev();
std::list<tFace>& MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::faces | ( | ) | [inline] |
List of the faces of the mesh.
Definition at line 365 of file BaseMesh.h.
CEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::halfedgeEdge | ( | tHalfEdge | he | ) |
The edge of a halfedge.
he | the input halfedge. |
Definition at line 580 of file BaseMesh.h.
{
return (CEdge*)he->edge();
CFace * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::halfedgeFace | ( | tHalfEdge | he | ) |
The face a halfedge attaching to.
he | the input halfedge |
Definition at line 517 of file BaseMesh.h.
{
return (CFace*)he->face();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::halfedgeNext | ( | tHalfEdge | he | ) |
The next halfedge of a halfedge.
he | the input halfedge. |
Definition at line 544 of file BaseMesh.h.
{
return (CHalfEdge*)he->he_next();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::halfedgePrev | ( | tHalfEdge | he | ) |
The previous halfedge of a halfedge.
he | the input halfedge. |
Definition at line 556 of file BaseMesh.h.
{
return (CHalfEdge*)he->he_prev();
CVertex * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::halfedgeSource | ( | tHalfEdge | he | ) |
The source vertex of a halfedge.
he | the input halfedge. |
Definition at line 616 of file BaseMesh.h.
{
return (CVertex*)he->he_prev()->vertex();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::halfedgeSym | ( | tHalfEdge | he | ) |
The dual halfedge of a halfedge.
he | the input halfedge. |
Definition at line 568 of file BaseMesh.h.
{
return (CHalfEdge*)he->he_sym();
CVertex * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::halfedgeTarget | ( | tHalfEdge | he | ) |
The target vertex of a halfedge.
he | the input halfedge. |
Definition at line 604 of file BaseMesh.h.
{
return (CVertex*)he->vertex();
CVertex * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::halfedgeVertex | ( | tHalfEdge | he | ) |
The target vertex of a halfedge.
he | the input halfedge. |
Definition at line 592 of file BaseMesh.h.
{
return (CVertex*)he->vertex();
CFace * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::idFace | ( | int | id | ) |
Access a face by its id
id | the face id |
Definition at line 1181 of file BaseMesh.h.
{ return m_map_face[id];
CVertex * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::idVertex | ( | int | id | ) |
Access a vertex by its id
id | the vertex id |
Definition at line 1157 of file BaseMesh.h.
{ return m_map_vert[id];
bool MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::isBoundary | ( | tVertex | v | ) |
whether a vertex is on the boundary
v | the pointer to the vertex |
Definition at line 624 of file BaseMesh.h.
{
return v->boundary();
bool MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::isBoundary | ( | tEdge | e | ) |
whether an edge is on the boundary
e | the pointer to the edge |
Definition at line 632 of file BaseMesh.h.
{ if( e->halfedge(0) == NULL || e->halfedge(1) == NULL ) return true; return false;
bool MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::isBoundary | ( | tHalfEdge | he | ) |
whether a halfedge is on the boundary
he | the pointer to the halfedge |
Definition at line 641 of file BaseMesh.h.
{ if( he->he_sym() == NULL ) return true; return false;
int MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::numEdges | ( | ) |
number of edges
Number of edges of the mesh
Definition at line 658 of file BaseMesh.h.
{ return (int) m_edges.size();
int MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::numFaces | ( | ) |
number of faces
Number of faces of the mesh
Definition at line 667 of file BaseMesh.h.
{ return (int) m_faces.size();
int MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::numVertices | ( | ) |
number of vertices
Number of vertices of the mesh
Definition at line 650 of file BaseMesh.h.
{ return (int) m_verts.size();
void MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::read_m | ( | const char * | input | ) |
Read an .m file.
input | the input obj file name |
Definition at line 1280 of file BaseMesh.h.
{ std::fstream is( input, std::fstream::in ); if( is.fail() ) { fprintf(stderr,"Error in opening file %s\n", input ); return; } char buffer[MAX_LINE]; int id; while( is.getline(buffer, MAX_LINE ) ) { std::string line( buffer ); line = strutil::trim( line ); strutil::Tokenizer stokenizer( line, " \r\n" ); stokenizer.nextToken(); std::string token = stokenizer.getToken(); if( token == "Vertex" ) { stokenizer.nextToken(); token = stokenizer.getToken(); id = strutil::parseString<int>(token); CPoint p; for( int i = 0 ; i < 3; i ++ ) { stokenizer.nextToken(); token = stokenizer.getToken(); p[i] = strutil::parseString<float>(token); } tVertex v = createVertex( id ); v->point() = p; v->id() = id; if( ! stokenizer.nextToken("\t\r\n") ) continue; token = stokenizer.getToken(); int sp = (int) token.find("{"); int ep = (int) token.find("}"); if( sp >= 0 && ep >= 0 ) { v->string() = token.substr( sp+1, ep-sp-1 ); } continue; } if( token == "Face" ) { stokenizer.nextToken(); token = stokenizer.getToken(); id = strutil::parseString<int>(token); CVertex * v[3]; for( int i = 0; i < 3; i ++ ) { stokenizer.nextToken(); token = stokenizer.getToken(); int vid = strutil::parseString<int>(token); v[i] = idVertex( vid ); } tFace f = createFace( v, id ); if( !stokenizer.nextToken() ) continue; token = stokenizer.getToken(); int sp = (int) token.find("{"); int ep = (int) token.find("}"); if( sp >= 0 && ep >= 0 ) { f->string() = token.substr( sp+1, ep-sp-1 ); } continue; } //read in edge attributes if( token == "Edge" ) { stokenizer.nextToken(); token = stokenizer.getToken(); int id0 = strutil::parseString<int>( token ); stokenizer.nextToken(); token = stokenizer.getToken(); int id1 = strutil::parseString<int>( token ); CVertex * v0 = idVertex( id0 ); CVertex * v1 = idVertex( id1 ); tEdge edge = vertexEdge( v0, v1 ); if( !stokenizer.nextToken("\t\r\n") ) continue; token = stokenizer.getToken(); int sp = (int) token.find("{"); int ep = (int) token.find("}"); if( sp >= 0 && ep >= 0 ) { edge->string() = token.substr( sp+1, ep-sp-1 ); } continue; } //read in edge attributes if( token == "Corner" ) { stokenizer.nextToken(); token = stokenizer.getToken(); int vid = strutil::parseString<int>( token ); stokenizer.nextToken(); token = stokenizer.getToken(); int fid = strutil::parseString<int>( token ); CVertex * v = idVertex( vid ); CFace * f = idFace( fid ); tHalfEdge he = corner( v, f ); if( !stokenizer.nextToken("\t\r\n") ) continue; token = stokenizer.getToken(); int sp = (int) token.find("{"); int ep = (int) token.find("}"); if( sp >= 0 && ep >= 0 ) { he->string() = token.substr( sp+1, ep-sp-1 ); } continue; } } //Label boundary edges for(std::list<CEdge*>::iterator eiter= m_edges.begin() ; eiter != m_edges.end() ; ++ eiter ) { CEdge * edge = *eiter; CHalfEdge * he[2]; he[0] = edgeHalfedge( edge, 0 ); he[1] = edgeHalfedge( edge, 1 ); assert( he[0] != NULL ); if( he[1] != NULL ) { assert( he[0]->target() == he[1]->source() && he[0]->source() == he[1]->target() ); if( he[0]->target()->id() < he[0]->source()->id() ) { edge->halfedge(0 ) = he[1]; edge->halfedge(1 ) = he[0]; } assert( edgeVertex1(edge)->id() < edgeVertex2(edge)->id() ); } else { he[0]->vertex()->boundary() = true; he[0]->he_prev()->vertex()->boundary() = true; } } std::list<CVertex*> dangling_verts; //Label boundary edges for(std::list<CVertex*>::iterator viter = m_verts.begin(); viter != m_verts.end() ; ++ viter ) { CVertex * v = *viter; if( v->halfedge() != NULL ) continue; dangling_verts.push_back( v ); } for( std::list<CVertex*>::iterator viter = dangling_verts.begin() ; viter != dangling_verts.end(); ++ viter ) { CVertex * v = *viter; m_verts.remove( v ); delete v; v = NULL; } //Arrange the boundary half_edge of boundary vertices, to make its halfedge //to be the most ccw in half_edge for(std::list<CVertex*>::iterator viter = m_verts.begin(); viter != m_verts.end() ; ++ viter ) { CVertex * v = *viter; if( !v->boundary() ) continue; CHalfEdge * he = vertexMostCcwInHalfEdge( v ); while( he->he_sym() != NULL ) { he = vertexNextCcwInHalfEdge ( he ); } v->halfedge() = he; } //read in the traits for(std::list<CVertex*>::iterator viter = m_verts.begin(); viter != m_verts.end() ; ++ viter ) { CVertex * v = *viter; v->_from_string(); } for(std::list<CEdge*>::iterator eiter = m_edges.begin(); eiter != m_edges.end() ; ++ eiter ) { CEdge * e = *eiter; e->_from_string(); } for(std::list<CFace*>::iterator fiter = m_faces.begin(); fiter != m_faces.end() ; ++ fiter ) { CFace * f = *fiter; f->_from_string(); } for( std::list<CFace*>::iterator fiter=m_faces.begin(); fiter != m_faces.end(); fiter ++ ) { CFace * pF = *fiter; CHalfEdge * pH = faceMostCcwHalfEdge( pF ); do{ pH->_from_string(); pH = faceNextCcwHalfEdge( pH ); }while( pH != faceMostCcwHalfEdge(pF ) ); }
void MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::read_obj | ( | const char * | filename | ) |
Read an .obj file.
filename | the input .obj file name |
Read an .obj file.
filename | the filename .obj file name |
Definition at line 910 of file BaseMesh.h.
{ std::fstream f(filename, std::fstream::in); if( f.fail() ) return; char cmd[1024]; int vid = 1; int fid = 1; bool with_uv = false; bool with_normal = false; std::vector<CPoint2> uvs; std::vector<CPoint> normals; while ( f.getline( cmd, 1024) ) { std::string line( cmd ); line = strutil::trim( line ); strutil::Tokenizer stokenizer( line, " \t\r\n" ); stokenizer.nextToken(); std::string token = stokenizer.getToken(); if( token == "v" ) { CPoint p; for( int i = 0; i < 3; i ++ ) { stokenizer.nextToken(); token = stokenizer.getToken(); p[i] = strutil::parseString<float>(token); } CVertex * v = createVertex( vid); v->point() = p; vid ++; continue; } if( token == "vt" ) { with_uv = true; CPoint2 uv; for( int i = 0; i < 2; i ++ ) { stokenizer.nextToken(); token = stokenizer.getToken(); uv[i] = strutil::parseString<float>(token); } uvs.push_back( uv ); continue; } if ( token == "vn" ) { with_normal = true; CPoint n; for( int i = 0; i < 3; i ++ ) { stokenizer.nextToken(); token = stokenizer.getToken(); n[i] = strutil::parseString<float>(token); } normals.push_back( n ); continue; } if ( token == "f" ) { CVertex* v[3]; for( int i = 0 ; i < 3; i ++ ) { stokenizer.nextToken(); token = stokenizer.getToken(); strutil::Tokenizer tokenizer( token, " /\t\r\n" ); int ids[3]; int k = 0; while( tokenizer.nextToken() ) { std::string token = tokenizer.getToken(); ids[k] = strutil::parseString<int>(token); k ++; } v[i] = m_map_vert[ ids[0] ]; if( with_uv ) v[i]->uv() = uvs[ ids[1]-1 ]; if( with_normal ) v[i]->normal() = normals[ ids[2]-1 ]; } createFace( v, fid++ ); } } f.close(); //Label boundary edges for(std::list<CEdge*>::iterator eiter= m_edges.begin() ; eiter != m_edges.end() ; ++ eiter ) { CEdge * edge = *eiter; CHalfEdge * he[2]; he[0] = edge->halfedge(0); he[1] = edge->halfedge(1); assert( he[0] != NULL ); if( he[1] != NULL ) { assert( he[0]->target() == he[1]->source() && he[0]->source() == he[1]->target() ); if( he[0]->target()->id() < he[0]->source()->id() ) { edge->halfedge(0 ) = he[1]; edge->halfedge(1 ) = he[0]; } assert( edgeVertex1(edge)->id() < edgeVertex2(edge)->id() ); } else { he[0]->vertex()->boundary() = true; he[0]->he_prev()->vertex()->boundary() = true; } } std::list<CVertex*> dangling_verts; //Label boundary edges for(std::list<CVertex*>::iterator viter = m_verts.begin(); viter != m_verts.end() ; ++ viter ) { tVertex v = *viter; if( v->halfedge() != NULL ) continue; dangling_verts.push_back( v ); } for( std::list<CVertex*>::iterator viter = dangling_verts.begin() ; viter != dangling_verts.end(); ++ viter ) { tVertex v = *viter; m_verts.remove( v ); delete v; v = NULL; } //Arrange the boundary half_edge of boundary vertices, to make its halfedge //to be the most ccw in half_edge for(std::list<CVertex*>::iterator viter = m_verts.begin(); viter != m_verts.end() ; ++ viter ) { tVertex v = *viter; if( !v->boundary() ) continue; CHalfEdge * he = v->halfedge(); while( he->he_sym() != NULL ) { he = vertexNextCcwInHalfEdge( he ); } v->halfedge() = he; }
void MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::read_off | ( | const char * | input | ) |
Read an .off file
input | the input .off filename |
Definition at line 1801 of file BaseMesh.h.
{ std::fstream is( input, std::fstream::in ); if( is.fail() ) { fprintf(stderr,"Error is opening file %s\n", input ); return; } char buffer[MAX_LINE]; //read in the first line "OFF" while( is.getline(buffer, MAX_LINE ) ) { std::string line( buffer ); strutil::Tokenizer stokenizer( line, " \r\n" ); stokenizer.nextToken(); std::string token = stokenizer.getToken(); if( token == "OFF" ) break; } int nVertices, nFaces, nEdges; //read in Vertex Number, Face Number, Edge Number is.getline(buffer, MAX_LINE ); std::string line( buffer ); strutil::Tokenizer stokenizer( line, " \r\n" ); stokenizer.nextToken(); std::string token = stokenizer.getToken(); nVertices = strutil::parseString<int>( token ); stokenizer.nextToken(); token = stokenizer.getToken(); nFaces = strutil::parseString<int>( token ); stokenizer.nextToken(); token = stokenizer.getToken(); nEdges = strutil::parseString<int>( token ); //printf("V %d F %d E %d\n" , nVertices, nFaces, nEdges); for( int id = 0; id < nVertices; id ++ ) { is.getline(buffer, MAX_LINE ); std::string line( buffer ); strutil::Tokenizer stokenizer( line, " \r\n" ); CPoint p; for( int j = 0; j < 3; j ++ ) { stokenizer.nextToken(); std::string token = stokenizer.getToken(); p[j] = strutil::parseString<float>( token ); } CVertex * v = createVertex( id + 1 ); v->point() = p; } for( int id = 0; id < nFaces; id ++ ) { is.getline(buffer, MAX_LINE ); std::string line( buffer ); strutil::Tokenizer stokenizer( line, " \r\n" ); stokenizer.nextToken(); std::string token = stokenizer.getToken(); int n = strutil::parseString<int>(token); assert( n == 3 ); CVertex * v[3]; for( int j = 0; j < 3; j ++ ) { stokenizer.nextToken(); std::string token = stokenizer.getToken(); int vid = strutil::parseString<int>( token ); v[j] = idVertex( vid + 1); } createFace( v, id + 1 ); } is.close(); //Label boundary edges for(std::list<CEdge*>::iterator eiter= m_edges.begin() ; eiter != m_edges.end() ; ++ eiter ) { CEdge * edge = *eiter; CHalfEdge * he[2]; he[0] = edge->halfedge(0); he[1] = edge->halfedge(1); assert( he[0] != NULL ); if( he[1] != NULL ) { assert( he[0]->target() == he[1]->source() && he[0]->source() == he[1]->target() ); if( he[0]->target()->id() < he[0]->source()->id() ) { edge->halfedge(0 ) = he[1]; edge->halfedge(1 ) = he[0]; } assert( edgeVertex1(edge)->id() < edgeVertex2(edge)->id() ); } else { he[0]->vertex()->boundary() = true; he[0]->he_prev()->vertex()->boundary() = true; } } std::list<CVertex*> dangling_verts; //Label boundary edges for(std::list<CVertex*>::iterator viter = m_verts.begin(); viter != m_verts.end() ; ++ viter ) { tVertex v = *viter; if( v->halfedge() != NULL ) continue; dangling_verts.push_back( v ); } for( std::list<CVertex*>::iterator viter = dangling_verts.begin() ; viter != dangling_verts.end(); ++ viter ) { tVertex v = *viter; m_verts.remove( v ); delete v; v = NULL; } //Arrange the boundary half_edge of boundary vertices, to make its halfedge //to be the most ccw in half_edge for(std::list<CVertex*>::iterator viter = m_verts.begin(); viter != m_verts.end() ; ++ viter ) { tVertex v = *viter; if( !v->boundary() ) continue; CHalfEdge * he = v->halfedge(); while( he->he_sym() != NULL ) { he = he->ccw_rotate_about_target(); } v->halfedge() = he; }
CEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::vertexEdge | ( | tVertex | v0, | |
tVertex | v1 | |||
) |
Access an edge by its two end vertices
v0 | one vertex of the edge | |
v1 | the other vertex of the edge |
Definition at line 1237 of file BaseMesh.h.
{ CEdgeKey key(v0->id(),v1->id()); return m_map_edge[key];
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::vertexHalfedge | ( | tVertex | v0, | |
tVertex | v1 | |||
) |
Access a halfedge by its two end vertices
v0 | one vertex of the halfedge | |
v1 | the other vertex of the halfedge |
Definition at line 1252 of file BaseMesh.h.
{ CEdge * e = vertexEdge( v0, v1 ); assert( e != NULL ); CHalfEdge * he = (CHalfEdge*) e->halfedge(0); if( he->vertex() == v1 && he->he_prev()->vertex() == v0 ) return he; he = (CHalfEdge*) e->halfedge(1); assert( he->vertex() == v1 && he->he_prev()->vertex() == v0 ); return he;
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::vertexHalfedge | ( | tVertex | v | ) |
The halfedge targeting at a vertex.
v | the input vertex. |
Definition at line 1270 of file BaseMesh.h.
{
return (CHalfEdge*) v->halfedge();
int MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::vertexId | ( | tVertex | v | ) |
The vertex id
v | the input vertex |
Definition at line 1169 of file BaseMesh.h.
{
return v->id();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::vertexMostCcwInHalfEdge | ( | tVertex | v | ) |
The most Ccw In HalfEdge of a vertex
v | the input vertex. |
The most Ccw In HalfEdge of a vertex
v | the input vertex. |
Definition at line 751 of file BaseMesh.h.
{
return (CHalfEdge*)v->most_ccw_in_halfedge();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::vertexMostCcwOutHalfEdge | ( | tVertex | v | ) |
The most Ccw Out HalfEdge of a vertex
v | the input vertex. |
The next Ccw Out HalfEdge
v | the input vertex. |
Definition at line 690 of file BaseMesh.h.
{
return (CHalfEdge*)v->most_ccw_out_halfedge();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::vertexMostClwInHalfEdge | ( | tVertex | v | ) |
The most Clw In HalfEdge of a vertex
v | the input vertex. |
Definition at line 740 of file BaseMesh.h.
{
return (CHalfEdge*)v->most_clw_in_halfedge();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::vertexMostClwOutHalfEdge | ( | tVertex | v | ) |
The most Clw Out HalfEdge of a vertex
v | the input vertex. |
Definition at line 680 of file BaseMesh.h.
{
return (CHalfEdge*)v->most_clw_out_halfedge();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::vertexNextCcwInHalfEdge | ( | tHalfEdge | he | ) |
The next Ccw In HalfEdge
he | the input halfedge . |
Definition at line 763 of file BaseMesh.h.
{
assert( he->he_sym() != NULL );
return (CHalfEdge*)he->ccw_rotate_about_target();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::vertexNextCcwOutHalfEdge | ( | tHalfEdge | he | ) |
The next Ccw Out HalfEdge
he | the input halfedge . |
Definition at line 718 of file BaseMesh.h.
{
return (CHalfEdge*) he->ccw_rotate_about_source();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::vertexNextClwInHalfEdge | ( | tHalfEdge | he | ) |
The next Clw In HalfEdge
he | the input halfedge . |
Definition at line 774 of file BaseMesh.h.
{
return (CHalfEdge*)he->clw_rotate_about_target();
CHalfEdge * MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::vertexNextClwOutHalfEdge | ( | tHalfEdge | he | ) |
The next Clw Out HalfEdge
he | the input halfedge . |
Definition at line 728 of file BaseMesh.h.
{
assert( he->he_sym() != NULL );
return (CHalfEdge*)he->clw_rotate_about_source();
std::list<tVertex>& MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::vertices | ( | ) | [inline] |
List of the vertices of the mesh.
Definition at line 369 of file BaseMesh.h.
void MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::write_m | ( | const char * | output | ) |
Write an .m file.
output | the output .m file name |
Definition at line 1530 of file BaseMesh.h.
{ //write traits to string for( std::list<CVertex*>::iterator viter=m_verts.begin(); viter != m_verts.end(); viter ++ ) { CVertex * pV = *viter; pV->_to_string(); } for( std::list<CEdge*>::iterator eiter=m_edges.begin(); eiter != m_edges.end(); eiter ++ ) { CEdge * pE = *eiter; pE->_to_string(); } for( std::list<CFace*>::iterator fiter=m_faces.begin(); fiter != m_faces.end(); fiter ++ ) { CFace * pF = *fiter; pF->_to_string(); } for( std::list<CFace*>::iterator fiter=m_faces.begin(); fiter != m_faces.end(); fiter ++ ) { CFace * pF = *fiter; CHalfEdge * pH = faceMostCcwHalfEdge( pF ); do{ pH->_to_string(); pH = faceNextCcwHalfEdge( pH ); }while( pH != faceMostCcwHalfEdge(pF ) ); } std::fstream _os( output, std::fstream::out ); if( _os.fail() ) { fprintf(stderr,"Error is opening file %s\n", output ); return; } //remove vertices for( std::list<CVertex*>::iterator viter = m_verts.begin(); viter != m_verts.end(); viter ++) { tVertex v = *viter; _os << "Vertex " << v->id(); for( int i = 0; i < 3; i ++ ) { _os << " " << v->point()[i]; } if( v->string().size() > 0 ) { _os << " " <<"{"<< v->string() << "}"; } _os << std::endl; } for( std::list<CFace*>::iterator fiter = m_faces.begin(); fiter != m_faces.end(); fiter ++ ) { tFace f = *fiter; _os << "Face " << f->id(); tHalfEdge he = faceHalfedge( f ); do{ _os << " " << he->target()->id(); he = halfedgeNext( he ); }while( he != f->halfedge() ); if( f->string().size() > 0 ) { _os << "{"<< f->string() << "}"; } _os << std::endl; } for( std::list<CEdge*>::iterator eiter = m_edges.begin(); eiter != m_edges.end(); eiter ++ ) { tEdge e = *eiter; if( e->string().size() > 0 ) { _os << "Edge "<< edgeVertex1(e)->id() <<" " << edgeVertex2(e)->id() << " "; _os << "{" << e->string() << "}" << std::endl; } } for( std::list<CFace*>::iterator fiter = m_faces.begin(); fiter != m_faces.end(); fiter ++ ) { tFace f = *fiter; tHalfEdge he = faceHalfedge( f ); do{ if( he->string().size() > 0 ) { _os << "Corner "<< he->vertex()->id() << " " << f->id() << " "; _os << "{" << he->string() << "}" << std::endl; } he = halfedgeNext( he ); }while( he != f->halfedge() ); } _os.close();
void MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::write_obj | ( | const char * | output | ) |
Write an .obj file.
output | the output .obj file name |
Definition at line 1643 of file BaseMesh.h.
{ std::fstream _os( output, std::fstream::out ); if( _os.fail() ) { fprintf(stderr,"Error is opening file %s\n", output ); return; } int vid = 1; for( std::list<CVertex*>::iterator viter = m_verts.begin(); viter != m_verts.end(); viter ++) { tVertex v = *viter; v->id() = vid ++; } for( std::list<CVertex*>::iterator viter = m_verts.begin(); viter != m_verts.end(); viter ++) { tVertex v = *viter; _os << "v"; for( int i = 0; i < 3; i ++ ) { _os << " " << v->point()[i]; } _os << std::endl; } for( std::list<CVertex*>::iterator viter = m_verts.begin(); viter != m_verts.end(); viter ++) { tVertex v = *viter; _os << "vt"; for( int i = 0; i < 2; i ++ ) { _os << " " << v->uv()[i]; } _os << std::endl; } for( std::list<CVertex*>::iterator viter = m_verts.begin(); viter != m_verts.end(); viter ++) { tVertex v = *viter; _os << "vn"; for( int i = 0; i < 3; i ++ ) { _os << " " << v->normal()[i]; } _os << std::endl; } for( std::list<CFace*>::iterator fiter = m_faces.begin(); fiter != m_faces.end(); fiter ++ ) { tFace f = *fiter; _os << "f"; tHalfEdge he = f->halfedge(); do{ int vid = he->target()->id(); _os << " " << vid << "/" << vid << "/" << vid; he = he->he_next(); }while( he != f->halfedge() ); _os << std::endl; } _os.close();
std::list<tEdge> MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::m_edges [protected] |
list of edges
Definition at line 369 of file BaseMesh.h.
std::list<tFace> MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::m_faces [protected] |
list of faces
Definition at line 381 of file BaseMesh.h.
std::map<CEdgeKey, tEdge> MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::m_map_edge [protected] |
map between edge and its edgekey
Definition at line 390 of file BaseMesh.h.
std::map<int, tFace> MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::m_map_face [protected] |
map between face and its id
Definition at line 388 of file BaseMesh.h.
std::map<int, tVertex> MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::m_map_vert [protected] |
map between vetex and its id
Definition at line 386 of file BaseMesh.h.
std::list<tVertex> MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::m_verts [protected] |
list of vertices
Definition at line 379 of file BaseMesh.h.
bool MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::m_with_normal |
whether the mesh is with normal
Definition at line 420 of file BaseMesh.h.
bool MeshLib::CBaseMesh< CVertex, CEdge, CFace, CHalfEdge >::m_with_texture |
whether the vertex is with texture coordinates
Definition at line 418 of file BaseMesh.h.