DynamicMesh.h

Go to the documentation of this file.
00001 
00011 #ifndef  _DYNAMIC_MESH_H_
00012 #define  _DYNAMIC_MESH_H_
00013 
00014 #include <map>
00015 #include <vector>
00016 #include <queue>
00017 
00018 #include "Mesh/BaseMesh.h"
00019 #include "Mesh/boundary.h"
00020 #include "Mesh/iterators.h"
00021 
00022 
00023 namespace MeshLib
00024 {
00025   
00026 /*-------------------------------------------------------------------------------------------------------------------------------------
00027 
00028         Dynamic Mesh Class
00029 
00030 --------------------------------------------------------------------------------------------------------------------------------------*/
00035 template<typename V, typename E, typename F, typename H>
00036 class CDynamicMesh : public CBaseMesh<V,E,F,H>
00037 {
00038 public:
00040         CDynamicMesh(){ m_vertex_id = 0; m_face_id = 0; };
00042         ~CDynamicMesh();
00043 
00044         //dynamic mesh editing
00048         V *  splitFace( F * pFace );
00052         V *  splitEdge( E * pEdge );
00056         void swapEdge( E * edge );
00057 
00058 protected:
00063         void __attach_halfedge_to_edge( H * he0, H * he1, E * e );
00065         int  m_vertex_id;
00067         int  m_face_id;
00068 };
00069 
00070 /*---------------------------------------------------------------------------*/
00071 
00072 template<typename V, typename E, typename F, typename H>
00073 CDynamicMesh<V,E,F,H>::~CDynamicMesh()
00074 {
00075 }
00076 
00077 
00078 /*---------------------------------------------------------------------------*/
00079 
00080 //insert a vertex in the center of a face, split the face to 3 faces
00081 
00082 template<typename CVertex, typename CEdge, typename CFace, typename CHalfEdge>
00083 CVertex * CDynamicMesh<CVertex,CEdge,CFace,CHalfEdge>::splitFace( CFace * pFace )
00084 {
00085 
00086         CVertex * pV = createVertex( ++m_vertex_id );
00087         
00088         CVertex   *  v[3];
00089     CHalfEdge *  h[3];
00090         CHalfEdge *  hs[3];
00091         
00092         CEdge     *  eg[3];
00093 
00094         h[0] =  faceHalfedge( pFace );
00095         h[1] =  faceNextCcwHalfEdge( h[0] );
00096         h[2] =  faceNextCcwHalfEdge( h[1] );
00097 
00098         for( int i = 0; i < 3; i ++ )
00099         {
00100                 v[i] = halfedgeTarget( h[i] );
00101                 eg[i] = halfedgeEdge( h[i] );
00102                 hs[i] = halfedgeSym( h[i] );
00103         }
00104         
00105 
00106         CFace * f = new CFace();
00107         assert( f != NULL );
00108         f->id() = ++m_face_id;
00109         m_faces.push_back( f );
00110 
00111         //create halfedges
00112         tHalfEdge hes[3];
00113         for(int i = 0; i < 3; i ++ )
00114         {
00115                 hes[i] = new CHalfEdge;
00116                 assert( hes[i] );
00117         }
00118 
00119         //linking to each other
00120         for(int i = 0; i < 3; i ++ )
00121         {
00122                 hes[i]->he_next() = hes[(i+1)%3];
00123                 hes[i]->he_prev() = hes[(i+2)%3];
00124         }
00125 
00126         //linking to face
00127         for(int i = 0; i < 3; i ++ )
00128         {
00129                 hes[i]->face()   = f;
00130                 f->halfedge()    = hes[i];
00131         }
00132 
00133 
00134         f = new CFace();
00135         assert( f != NULL );
00136         f->id() = ++m_face_id;
00137         m_faces.push_back( f );
00138 
00139         //create halfedges
00140         tHalfEdge hes2[3];
00141 
00142         for(int i = 0; i < 3; i ++ )
00143         {
00144                 hes2[i] = new CHalfEdge;
00145                 assert( hes2[i] );
00146         }
00147 
00148         //linking to each other
00149         for(int i = 0; i < 3; i ++ )
00150         {
00151                 hes2[i]->he_next() = hes2[(i+1)%3];
00152                 hes2[i]->he_prev() = hes2[(i+2)%3];
00153         }
00154 
00155         //linking to face
00156         for(int i = 0; i < 3; i ++ )
00157         {
00158                 hes2[i]->face()   = f;
00159                 f->halfedge()    = hes2[i];
00160         }
00161 
00162         CEdge * e[3];
00163         for( int i = 0; i < 3; i ++ )
00164         {
00165                 e[i] = new CEdge();
00166                 assert( e[i] );
00167                 m_edges.push_back( e[i] );
00168         }
00169 
00170         __attach_halfedge_to_edge( h[1], hes[0], e[0] );
00171         __attach_halfedge_to_edge( hes[2], hes2[1], e[1] );
00172         __attach_halfedge_to_edge( h[2], hes2[0], e[2] );
00173         __attach_halfedge_to_edge( h[0], hs[0], eg[0] );
00174         __attach_halfedge_to_edge( hes[1], hs[1], eg[1] );
00175         __attach_halfedge_to_edge( hes2[2], hs[2], eg[2] );
00176         
00177 
00178 
00179         pV->halfedge() = h[1];
00180 
00181 
00182         h[1]->vertex() = pV;
00183         h[2]->vertex() = v[2];
00184 
00185         hes[0]->vertex() = v[0];
00186         hes[1]->vertex() = v[1];
00187         hes[2]->vertex() = pV;
00188 
00189         hes2[0]->vertex() = pV;
00190         hes2[1]->vertex() = v[1];
00191         hes2[2]->vertex() = v[2];
00192 
00193         for( int i = 0; i < 3; i ++ )
00194         {
00195                 v[i]->halfedge() = hs[i]->he_sym();
00196         }
00197         return pV;
00198 
00199 };
00200 /*---------------------------------------------------------------------------*/
00201 
00202 template<typename CVertex, typename CEdge, typename CFace, typename CHalfEdge>
00203 void CDynamicMesh<CVertex,CEdge,CFace,CHalfEdge>::swapEdge( CEdge * edge )
00204 {
00205 
00206   CHalfEdge * he_left   = edgeHalfedge( edge, 0 );
00207   CHalfEdge * he_right  = edgeHalfedge( edge, 1 );
00208 
00209   if( he_right == NULL )  return;
00210   
00211   CHalfEdge * ph[6];
00212 
00213   ph[0] = he_left;
00214   ph[1] = faceNextCcwHalfEdge( ph[0] );
00215   ph[2] = faceNextCcwHalfEdge( ph[1] );
00216 
00217 
00218   ph[3] = he_right;
00219   ph[4] = faceNextCcwHalfEdge( ph[3] );
00220   ph[5] = faceNextCcwHalfEdge( ph[4] );
00221 
00222   CVertex * pv[4];
00223 
00224   pv[0] = halfedgeTarget( ph[0]);
00225   pv[1] = halfedgeTarget( ph[1]);
00226   pv[2] = halfedgeTarget( ph[2]);
00227   pv[3] = halfedgeTarget( ph[4]);
00228 
00229   bool boundary[4];
00230 
00231   for( int i = 0; i < 4; i ++ )
00232   {
00233     boundary[i] = pv[0]->boundary();
00234   }
00235 
00236   int pi[6];
00237   CEdge * pe[6];
00238   for( int i = 0; i < 6; i ++ )
00239   {
00240     CHalfEdge * he = ph[i];
00241     CEdge        *   e= halfedgeEdge( he );
00242     pe[i] = e;
00243 
00244     if( e->halfedge(0) == he )
00245     {
00246       pi[i] = 0;
00247     }
00248     else
00249     {
00250       assert( e->halfedge(1) == he );
00251       pi[i] = 1;
00252     }
00253   }
00254 
00255   //relink the vertices
00256 
00257   ph[0]->target() = pv[1];
00258   if( !boundary[1] )
00259   {
00260     pv[1]->halfedge() = ph[0];
00261   }
00262   ph[1]->target() = pv[2];
00263   if( !boundary[2] )
00264   {
00265     pv[2]->halfedge() = ph[1];
00266   }
00267   
00268   ph[2]->target() = pv[3];
00269   if( !boundary[3] )
00270   {
00271     pv[3]->halfedge() = ph[2];
00272   }
00273   
00274   ph[3]->target() = pv[3];
00275   if( !boundary[3] )
00276   {
00277     pv[3]->halfedge() = ph[3];
00278   }
00279   
00280   ph[4]->target() = pv[0];
00281   if( !boundary[0] )
00282   {
00283     pv[0]->halfedge() = ph[4];
00284   }
00285   
00286   ph[5]->target() = pv[1];
00287   if( !boundary[1] )
00288   {
00289     pv[1]->halfedge() = ph[5];
00290   }
00291   
00292   //relink the edge-halfedge pointers
00293 
00294   ph[1]->edge() = pe[2];
00295   pe[2]->halfedge( pi[2] ) = ph[1];
00296 
00297   ph[2]->edge() = pe[4];
00298   pe[4]->halfedge( pi[4] ) = ph[2];
00299 
00300   ph[4]->edge() = pe[5];
00301   pe[5]->halfedge( pi[5] ) = ph[4];
00302 
00303   ph[5]->edge() = pe[1];
00304   pe[1]->halfedge( pi[1] ) = ph[5];
00305   
00306 
00307   for(int i = 0; i < 6; i ++ )
00308   {
00309       CHalfEdge * he = ph[i];
00310       CHalfEdge * sh = halfedgeSym( he );
00311       assert( he->target() == sh->he_prev()->target() );
00312       assert( he->he_prev()->target() == sh->target() );
00313   }
00314 
00315 };
00316 
00317 /*---------------------------------------------------------------------------*/
00318 
00319 
00320 //insert a vertex in the center of an edge, split each neighboring face into 2 faces
00321 
00322 template<typename CVertex, typename CEdge, typename CFace, typename CHalfEdge>
00323 CVertex * CDynamicMesh<CVertex,CEdge,CFace,CHalfEdge>::splitEdge( CEdge * pEdge )
00324 {
00325 
00326         CVertex * pV = createVertex( ++ m_vertex_id );
00327 
00328 
00329         CHalfEdge *  h[12];
00330         CHalfEdge *  s[6];
00331         CVertex   *  v[6];
00332         CEdge     * eg[6];
00333         
00334         h[0] = edgeHalfedge( pEdge, 0 );
00335         h[1] = faceNextCcwHalfEdge( h[0] );
00336         h[2] = faceNextCcwHalfEdge( h[1] );
00337 
00338         h[3] = edgeHalfedge( pEdge, 1 );
00339         h[4] = faceNextCcwHalfEdge( h[3] );
00340         h[5] = faceNextCcwHalfEdge( h[4] );
00341 
00342 
00343         CFace * f[4];
00344         f[0] = halfedgeFace( h[0] );
00345         f[1] = halfedgeFace( h[3] );
00346 
00347         for( int i = 0; i < 6; i ++ )
00348         {
00349                 eg[i] = halfedgeEdge( h[i] );
00350                 v[i] = halfedgeVertex(h[i]);
00351                 s[i] = halfedgeSym( h[i] );
00352         }
00353 
00354         f[2] = new CFace();
00355         assert( f[2] != NULL );
00356         f[2]->id() = ++ m_face_id;
00357         m_faces.push_back( f[2] );
00358 
00359         //create halfedges
00360         for(int i = 6; i < 9; i ++ )
00361         {
00362                 h[i] = new CHalfEdge;
00363                 assert( h[i] );
00364         }
00365 
00366         //linking to each other
00367         for(int i = 0; i < 3; i ++ )
00368         {
00369                 h[i+6]->he_next() = h[6+(i+1)%3];
00370                 h[i+6]->he_prev() = h[6+(i+2)%3];
00371         }
00372 
00373         //linking to face
00374         for(int i = 6; i < 9; i ++ )
00375         {
00376                 h[i]->face()   = f[2];
00377                 f[2]->halfedge()= h[i];
00378         }
00379 
00380 
00381         f[3] = new CFace();
00382         assert( f[3] != NULL );
00383         f[3]->id() = ++m_face_id;
00384         m_faces.push_back( f[3] );
00385 
00386         //create halfedges
00387         for(int i = 9; i < 12; i ++ )
00388         {
00389                 h[i] = new CHalfEdge;
00390                 assert( h[i] );
00391         }
00392 
00393         //linking to each other
00394         for(int i = 0; i < 3; i ++ )
00395         {
00396                 h[i+9]->he_next() = h[9+(i+1)%3];
00397                 h[i+9]->he_prev() = h[9+(i+2)%3];
00398         }
00399 
00400         //linking to face
00401         for(int i = 9; i < 12; i ++ )
00402         {
00403                 h[i]->face()   = f[3];
00404                 f[3]->halfedge()    = h[i];
00405         }
00406 
00407         CEdge * e[3];
00408 
00409         for( int i = 0; i < 3; i ++ )
00410         {
00411                 e[i] = new CEdge();
00412                 m_edges.push_back( e[i] );
00413                 assert( e[i] );
00414         }
00415         
00416         __attach_halfedge_to_edge(h[2], h[6] , e[0]);
00417         __attach_halfedge_to_edge(h[8], h[9] , e[1]);
00418         __attach_halfedge_to_edge(h[4], h[11], e[2]);
00419 
00420         __attach_halfedge_to_edge(h[0], h[3], eg[0]);
00421         __attach_halfedge_to_edge(h[1], s[1], eg[1]);
00422         __attach_halfedge_to_edge(h[5], s[5], eg[5]);
00423 
00424         __attach_halfedge_to_edge(h[7],  s[2], eg[2]);
00425         __attach_halfedge_to_edge(h[10], s[4], eg[4]);
00426 
00427 
00428         h[0]->vertex() = v[0];
00429         h[1]->vertex() = v[1];
00430         h[2]->vertex() = pV;
00431         h[3]->vertex() = pV;
00432         h[4]->vertex() = v[4];
00433         h[5]->vertex() = v[5];
00434         h[6]->vertex() = v[1];
00435         h[7]->vertex() = v[2];
00436         h[8]->vertex() = pV;
00437         h[9]->vertex() = v[2];
00438         h[10]->vertex()= v[4];
00439         h[11]->vertex()= pV;
00440 
00441         
00442 
00443         v[0]->halfedge() = h[0];
00444         v[1]->halfedge() = h[1];
00445         v[2]->halfedge() = h[7];
00446         v[4]->halfedge() = h[4];
00447         pV->halfedge()   = h[3];
00448 
00449         for( int k = 0; k < 4; k ++ )
00450         {
00451                 CHalfEdge * pH = faceHalfedge( f[k] );
00452                 for( int i = 0; i < 3; i ++ )
00453                 {
00454                         assert( pH->vertex() == pH->he_sym()->he_prev()->vertex() );
00455                         pH = faceNextCcwHalfEdge( pH );
00456                 }
00457         }
00458         return pV;      
00459 
00460 };
00461 
00462 /*---------------------------------------------------------------------------*/
00463 
00464 template<typename CVertex, typename CEdge, typename CFace, typename CHalfEdge>
00465 void CDynamicMesh<CVertex,CEdge,CFace,CHalfEdge>::__attach_halfedge_to_edge( CHalfEdge * he0, CHalfEdge * he1, CEdge * e )
00466 {
00467         e->halfedge(0 ) = he0;
00468         e->halfedge(1 ) = he1;
00469 
00470         he0->edge() = e;
00471         he1->edge() = e;
00472 
00473 }
00474 
00475 
00476 }
00477 #endif  _DYNAMIC_MESH_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Defines