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
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
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
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
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
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
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
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
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
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
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
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
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
00360 for(int i = 6; i < 9; i ++ )
00361 {
00362 h[i] = new CHalfEdge;
00363 assert( h[i] );
00364 }
00365
00366
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
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
00387 for(int i = 9; i < 12; i ++ )
00388 {
00389 h[i] = new CHalfEdge;
00390 assert( h[i] );
00391 }
00392
00393
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
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_