![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsHalfEdgeModel.cpp 00003 00004 A Polygonal Model based on half-edge data structure. 00005 (See HalfEdgeModel.hpp for details) 00006 00007 SUKITTI PUNAK (04/05/2005) 00008 UPDATE (12/03/2010) 00009 ******************************************************************************/ 00010 #include "TAPsHalfEdgeModel.hpp" 00011 // Using Inclusion Model (i.e. definitions are included in declarations) 00012 // (this name.cpp is included in name.hpp) 00013 // Each friend is defined directly inside its declaration. 00014 00015 //----------------------------------------------------------------------------- 00016 BEGIN_NAMESPACE_TAPs__OpenGL 00017 //============================================================================= 00018 //----------------------------------------------------------------------------- 00019 // default constructor 00020 template <typename T> 00021 HalfEdgeModel<T>::HalfEdgeModel () 00022 : OpenGLMeshModel<T>() 00023 { 00024 m_listVertex = new HEVertexList<T>(); 00025 m_listFace = new HEFaceList<T>(); 00026 m_listHoleFace = new HEFaceList<T>(); 00027 if ( m_listVertex == NULL 00028 || m_listFace == NULL 00029 || m_listHoleFace == NULL ) { 00030 00031 #ifdef TAPs_DEBUG_MODE 00032 std::cerr << "HalfEdgeModel ERROR: Can create an halfedge object." << std::endl; 00033 #endif//TAPs_DEBUG_MODE 00034 00035 exit(1); 00036 } 00037 00038 #ifdef TAPs_DEBUG_MODE 00039 std::cout << "HalfEdgeModel<" << typeid(T).name() << "> Constructor\n"; 00040 #endif//TAPs_DEBUG_MODE 00041 } 00042 //----------------------------------------------------------------------------- 00043 // destructor 00044 template <typename T> 00045 HalfEdgeModel<T>::~HalfEdgeModel () 00046 { 00047 delete m_listVertex; 00048 delete m_listFace; 00049 delete m_listHoleFace; 00050 //---------------------------------------------------------------- 00051 // For simulation 00052 //delete m_prODESolver; 00053 #ifdef TAPs_DEBUG_MODE 00054 std::cout << "HalfEdgeModel<" << typeid(T).name() << "> Destructor\n"; 00055 #endif//TAPs_DEBUG_MODE 00056 } 00057 //----------------------------------------------------------------------------- 00058 // Initialize 00059 // a virtual fn from Model class 00060 template <typename T> 00061 void HalfEdgeModel<T>::Initialize () 00062 { 00063 // Model Initialization 00064 CalAndSetNormals(); 00065 ApplyMaterial(); 00066 CalBoundingAABB(); 00067 CalBoundingEllipsoid(); 00068 CalBoundingSphere(); 00069 00070 // For Fast Access 00071 //SetListOfVertexPositionsAndNormals(); 00072 00073 /* 00074 std::cout << *this << std::endl; 00075 //*/ 00076 } 00077 //----------------------------------------------------------------------------- 00078 00079 00080 #ifdef TAPs_USE_DATA_POOL 00081 //----------------------------------------------------------------------------- 00082 template <typename T> 00083 void HalfEdgeModel<T>::SetNumVertices( int n ) 00084 { 00085 m_iNoVertices = n; 00086 GetArrayOfVertexPositions().Resize( n, 3 ); 00087 GetArrayOfVertexNormals().Resize( n, 3 ); 00088 } 00089 //----------------------------------------------------------------------------- 00090 template <typename T> 00091 void HalfEdgeModel<T>::SetNumFaces( int n ) 00092 { 00093 m_iNoFaces = n; 00094 GetArrayOfIndexFaces().Resize( n, 3 ); 00095 } 00096 //----------------------------------------------------------------------------- 00097 template <typename T> 00098 void HalfEdgeModel<T>::SetNumTexCoords( int n ) 00099 { 00100 m_iNoTexCoords = n; 00101 } 00102 //----------------------------------------------------------------------------- 00103 #endif//TAPs_USE_DATA_POOL 00104 00105 00106 //----------------------------------------------------------------------------- 00107 // Get Half Length 00108 template <typename T> 00109 T HalfEdgeModel<T>::GetMaxHalfLength () const 00110 { 00111 T maxHalfSize = 0.0; 00112 HEVertex<T> *ptr = m_listVertex->Head(); 00113 while ( ptr != NULL ) { 00114 if ( fabs( (*ptr)[0] ) > maxHalfSize ) 00115 maxHalfSize = fabs( (*ptr)[0] ); 00116 if ( fabs( (*ptr)[1] ) > maxHalfSize ) 00117 maxHalfSize = fabs( (*ptr)[1] ); 00118 if ( fabs( (*ptr)[2] ) > maxHalfSize ) 00119 maxHalfSize = fabs( (*ptr)[2] ); 00120 ptr = ptr->Next(); 00121 } 00122 return maxHalfSize; 00123 } 00124 //----------------------------------------------------------------------------- 00125 // Calculate and set the normals 00126 template <typename T> 00127 void HalfEdgeModel<T>::CalAndSetNormals () 00128 { 00129 CalAndSetFaceNormalsNotNormalized(); 00130 // DetermineFaceRings(); 00131 CalAndSetVertexNormals(); 00132 NormalizeFaceNormals(); 00133 } 00134 //----------------------------------------------------------------------------- 00135 // Calculate and set the face normals (without normalized) 00136 template <typename T> 00137 inline void HalfEdgeModel<T>::CalAndSetFaceNormalsNotNormalized () 00138 { 00139 // Calculate and set the normal of each face 00140 HEFace<T> * face = m_listFace->Head(); 00141 while ( face != NULL ) { 00142 Vector3<T> const & v0 = face->IncidentHalfEdge()->Prev()->Vertex()->GetPosition(); 00143 Vector3<T> const & v1 = face->IncidentHalfEdge()->Vertex()->GetPosition(); 00144 Vector3<T> const & v2 = face->IncidentHalfEdge()->Next()->Vertex()->GetPosition(); 00145 face->SetNormal( (v1 - v0) ^ (v2 - v1) ); 00146 face = face->Next(); 00147 } 00148 } 00149 //----------------------------------------------------------------------------- 00150 // Normalize the face normals 00151 template <typename T> 00152 inline void HalfEdgeModel<T>::NormalizeFaceNormals () 00153 { 00154 // Normalize the normal of each face 00155 HEFace<T> * face = m_listFace->Head(); 00156 while ( face != NULL ) { 00157 const_cast< Vector3<T> * >( &face->GetNormal() )->Normalized(); 00158 face = face->Next(); 00159 } 00160 } 00161 //----------------------------------------------------------------------------- 00162 // Calculate and set the vertex normals 00163 template <typename T> 00164 inline void HalfEdgeModel<T>::CalAndSetVertexNormals () 00165 { 00166 HEVertex<T> *vertex = m_listVertex->Head(); 00167 HEHalfEdge<T> *halfEdge; 00168 00169 #ifdef TAPs_DEBUG_MODE 00170 std::cout << "FIND VERTEX NORMAL" << std::endl; 00171 #endif//TAPs_DEBUG_MODE 00172 00173 while ( vertex ) { 00174 Vector3<T> vNormal; 00175 halfEdge = vertex->IncidentHalfEdge(); 00176 00177 #ifdef TAPs_DEBUG_MODE 00178 std::cout << *halfEdge << std::endl; 00179 #endif//TAPs_DEBUG_MODE 00180 00181 vNormal = Vector3<T>(0,0,0); 00182 int count1 = 0; 00183 int count2 = 0; 00184 do { 00185 vNormal += halfEdge->Face()->GetNormal(); 00186 halfEdge = halfEdge->Pair()->Next(); 00187 // Cannot use previous, because of half-edge data structure 00188 //halfEdge = halfEdge->Pair()->Prev(); 00189 //if ( halfEdge == NULL ) { 00190 // std::cout << "--------------------=================>>>>>>> NULL\n"; 00191 //assert( false ); 00192 // break; 00193 //} 00194 } while ( halfEdge != vertex->IncidentHalfEdge() ); 00195 00196 vertex->SetNormal( vNormal.Normalized() ); 00197 vertex = vertex->Next(); 00198 } 00199 } 00200 00201 //****************************************************************************** 00202 // ApplyAndResetTransform 00203 //****************************************************************************** 00204 //----------------------------------------------------------------------------- 00205 template <typename T> 00206 void HalfEdgeModel<T>::ApplyAndResetTransform () 00207 { 00208 HEVertex<T> * heVertex = GetVertexList()->Head(); 00209 //-------------------------------------------------------------------- 00210 while ( heVertex ) { 00211 heVertex->SetPosition( 00212 ( GetTransform().RefToMatrixTransform() 00213 * Vector4<T>( heVertex->GetPosition() ) 00214 ).GetVector3() 00215 ); 00216 heVertex = heVertex->Next(); 00217 } 00218 //-------------------------------------------------------------------- 00219 // Set Transformation to Identity Matrix 00220 GetTransform().MakeIdentity(); 00221 //-------------------------------------------------------------------- 00222 // Recalculate Bounding Volume(s) 00223 CalBoundingAABB(); 00224 CalBoundingEllipsoid(); 00225 CalBoundingSphere(); 00226 00227 // Update the bounding volume tree 00228 if ( GetBVHTree() ) { 00229 GetBVHTree()->Update(); 00230 } 00231 } 00232 //----------------------------------------------------------------------------- 00233 //****************************************************************************** 00234 00235 //****************************************************************************** 00236 // Virtual Fns from Collision Detection from ColDetSupport class 00237 //****************************************************************************** 00238 //----------------------------------------------------------------------------- 00239 template <typename T> 00240 void HalfEdgeModel<T>::CalBoundingAABB () 00241 { 00242 //int numOfVertices = m_listVertex->Size(); 00243 HEVertex<T> *vertex = m_listVertex->Head(); 00244 m_paBoundingAABB[0] = m_paBoundingAABB[1] = vertex->GetPosition(); 00245 //for ( int i = 0; i < numOfVertices; ++i ) { 00246 while ( vertex ) { 00247 // Find lowest x, y, and z 00248 if ( m_paBoundingAABB[0][0] > (*vertex)[0] ) 00249 m_paBoundingAABB[0][0] = (*vertex)[0]; 00250 if ( m_paBoundingAABB[0][1] > (*vertex)[1] ) 00251 m_paBoundingAABB[0][1] = (*vertex)[1]; 00252 if ( m_paBoundingAABB[0][2] > (*vertex)[2] ) 00253 m_paBoundingAABB[0][2] = (*vertex)[2]; 00254 // Find highest x, y, and z 00255 if ( m_paBoundingAABB[1][0] < (*vertex)[0] ) 00256 m_paBoundingAABB[1][0] = (*vertex)[0]; 00257 if ( m_paBoundingAABB[1][1] < (*vertex)[1] ) 00258 m_paBoundingAABB[1][1] = (*vertex)[1]; 00259 if ( m_paBoundingAABB[1][2] < (*vertex)[2] ) 00260 m_paBoundingAABB[1][2] = (*vertex)[2]; 00261 // Next vertex 00262 vertex = vertex->Next(); 00263 } 00264 // Find the bounding volume center 00265 m_pBoundingCenter[0] = ( m_paBoundingAABB[0][0] + m_paBoundingAABB[1][0] ) / 2.0; 00266 m_pBoundingCenter[1] = ( m_paBoundingAABB[0][1] + m_paBoundingAABB[1][1] ) / 2.0; 00267 m_pBoundingCenter[2] = ( m_paBoundingAABB[0][2] + m_paBoundingAABB[1][2] ) / 2.0; 00268 } 00269 //----------------------------------------------------------------------------- 00270 template <typename T> 00271 void HalfEdgeModel<T>::CalBoundingEllipsoid () 00272 { 00273 T x = m_paBoundingAABB[1][0] - m_pBoundingCenter[0]; 00274 x *= x; 00275 T y = m_paBoundingAABB[1][1] - m_pBoundingCenter[1]; 00276 y *= y; 00277 T z = m_paBoundingAABB[1][2] - m_pBoundingCenter[2]; 00278 z *= z; 00279 m_pBoundingEllipsoid[1] = sqrt( y + z ); 00280 m_pBoundingEllipsoid[2] = sqrt( z + x ); 00281 m_pBoundingEllipsoid[0] = sqrt( x + y ); 00282 } 00283 //----------------------------------------------------------------------------- 00284 template <typename T> 00285 void HalfEdgeModel<T>::CalBoundingSphere () 00286 { 00287 T squaredLength; 00288 m_pBoundingSphere = 0; 00289 HEVertex<T> *vertex = m_listVertex->Head(); 00290 while ( vertex ) { 00291 squaredLength = (vertex->GetPosition() - m_pBoundingCenter).SquaredLength(); 00292 if ( squaredLength > m_pBoundingSphere ) 00293 m_pBoundingSphere = squaredLength; 00294 // Next vertex 00295 vertex = vertex->Next(); 00296 } 00297 m_pBoundingSphere = sqrt( m_pBoundingSphere ); 00298 } 00299 //----------------------------------------------------------------------------- 00300 // Create BVHTree 00301 template <typename T> 00302 void HalfEdgeModel<T>::BuildBVHTree ( TAPs::Enum::CD treeType ) 00303 { 00304 //BVHTree<T>:: 00305 // Call a static fn from BVHTree class 00306 // m_pBVHTree is inherited from ColDetSupport class 00307 00308 //m_pBVHTree = BVHTree<T>::BuildBVHTree( GetTransform(), m_listFace, treeType, m_pBVHTree ); 00309 00310 m_pBVHTree = TAPs::CD::BuildBVHTree<T>( GetTransform(), m_listFace, treeType ); 00311 00312 //std::cout << "m_pVBHTree: " << m_pBVHTree << std::cout; 00313 } 00314 //----------------------------------------------------------------------------- 00315 //****************************************************************************** 00316 00317 //****************************************************************************** 00318 // For Fast Access (e.g. for OpenGL Drawing) 00319 //****************************************************************************** 00320 //----------------------------------------------------------------------------- 00321 // SetListOfVertexPositions 00322 //template <typename T> 00323 //void HalfEdgeModel<T>::SetListOfVertexPositionsAndNormals () 00324 //{ 00325 // m_vListOfVertexPositions.clear(); 00326 // m_vListOfVertexNormals.clear(); 00327 // HEVertex<T> * vertex = m_listVertex->Head(); 00328 // while ( vertex ) { 00329 // m_vListOfVertexPositions.push_back( &(vertex->GetPosition()) ); 00330 // m_vListOfVertexNormals.push_back( &(vertex->GetNormal()) ); 00331 // vertex = vertex->Next(); 00332 // } 00333 //} 00334 //----------------------------------------------------------------------------- 00335 //****************************************************************************** 00336 00337 //============================================================================= 00338 // Euler Opertator Fns 00339 //============================================================================= 00340 //----------------------------------------------------------------------------- 00341 // Insert Vertex Split Edge 00342 //------------------------------------- 00343 // O O 00344 // / IVSE( he ) / 00345 // / ===========> / 00346 // / V 00347 // / he newVertex (at pos, if pos != null) 00348 // / / 00349 // / / newHalfEdge (and newPairHalfEdge) 00350 // / / 00351 // V V 00352 template <typename T> 00353 void HalfEdgeModel<T>::IVSE ( HEHalfEdge<T> * he, Vector3<T> const * const pos ) 00354 { 00355 //--------------------------------------------------------------- 00356 // Crete New Vertex 00357 HEVertex<T> * newVertex; 00358 if ( pos != NULL ) { 00359 newVertex = new HEVertex<T>( *pos, he->Vertex()->GetNormal() ); 00360 } 00361 else { 00362 newVertex = new HEVertex<T>( he->Vertex()->GetPosition(), 00363 he->Vertex()->GetNormal() ); 00364 } 00365 //--------------------------------------------------------------- 00366 // Update Vertex List and Number of Vertices 00367 //GetVertexList()->Append( newVertex ); // or Append or Prepend 00368 GetVertexList()->InsertAfter( newVertex ); // or Append or Prepend 00369 SetNoVertices( GetVertexList()->Size() ); 00370 //SetNoVertices( GetNoVertices() + 1 ); 00371 //--------------------------------------------------------------- 00372 // Crete New HalfEdges 00373 HEHalfEdge<T> * newHalfEdge = new HEHalfEdge<T>( 00374 newVertex, // original vertex 00375 he->Face(), // incident face 00376 he, // previous halfedge 00377 he->Next(), // next halfedge 00378 he->Pair() ); // pair halfedge 00379 HEHalfEdge<T> * newPairHalfEdge = new HEHalfEdge<T>( 00380 newVertex, // original vertex 00381 he->Pair()->Face(), // incident face 00382 he->Pair(), // previous halfedge 00383 he->Pair()->Next(), // next halfedge 00384 he ); // pair halfedge 00385 //--------------------------------------------------------------- 00386 // Rearrange Pointers 00387 newHalfEdge->Pair()->Pair( newHalfEdge ); 00388 newHalfEdge->Prev()->Next( newHalfEdge ); 00389 newHalfEdge->Next()->Prev( newHalfEdge ); 00390 newPairHalfEdge->Pair()->Pair( newPairHalfEdge ); 00391 newPairHalfEdge->Prev()->Next( newPairHalfEdge ); 00392 newPairHalfEdge->Next()->Prev( newPairHalfEdge ); 00393 newVertex->IncidentHalfEdge( newHalfEdge ); 00394 } 00395 //----------------------------------------------------------------------------- 00396 // Split Vertex Make Edge 00397 //------------------------------------- 00398 // ^ / ^ / 00399 // \ / \ / he1 00400 // \ / \ V 00401 // \ / he1 O = pos1 00402 // \ V | 00403 // O SVME( he1, he2, pos1, pos 2 ) | newHalfEdge (and its pair) 00404 // ^ \ ==============================> V 00405 // / \ newVertex = pos2 00406 // he2 / \ ^ \ 00407 // / \ he2 / \ 00408 // / V / V 00409 template <typename T> 00410 void HalfEdgeModel<T>::SVME ( HEHalfEdge<T> * he1, HEHalfEdge<T> * he2, 00411 Vector3<T> const * const pos1, Vector3<T> const * const pos2 ) 00412 { 00413 //--------------------------------------------------------------- 00414 // Case the same halfedge, call Insert Vertex Split Edge 00415 if ( he1 == he2 ) { 00416 if ( pos2 != NULL ) { 00417 he1->Pair()->Vertex()->SetPosition( *pos2 ); 00418 } 00419 IVSE( he1, pos1 ); 00420 return; 00421 } 00422 //--------------------------------------------------------------- 00423 // Case two different vertices, cancel spliting 00424 if ( he1->Pair()->Vertex() != he2->Pair()->Vertex() ) { 00425 return; 00426 } 00427 //--------------------------------------------------------------- 00428 // Case one vertex, do spliting 00429 HEVertex<T> * vertex1, * newVertex; 00430 vertex1 = he1->Pair()->Vertex(); 00431 //----------------------------------------------------- 00432 // Create a New Vertex and set the old vertex 00433 if ( pos1 != NULL ) { 00434 vertex1->SetPosition( *pos1 ); 00435 } 00436 if ( pos2 != NULL ) { 00437 newVertex = new HEVertex<T>( *pos2, vertex1->GetNormal() ); 00438 } 00439 else { 00440 newVertex = new HEVertex<T>( vertex1->GetPosition(), 00441 vertex1->GetNormal() ); 00442 } 00443 //----------------------------------------------------- 00444 // Update Vertex List and Number of Vertices 00445 //GetVertexList()->Append( newVertex ); 00446 GetVertexList()->InsertAfter( newVertex ); 00447 SetNoVertices( GetVertexList()->Size() ); 00448 //SetNoVertices( GetNoVertices() + 1 ); 00449 //----------------------------------------------------- 00450 // Crete New HalfEdges 00451 HEHalfEdge<T> * newHalfEdge = new HEHalfEdge<T>( 00452 vertex1, // original vertex 00453 he1->Face(), // incident face 00454 he1, // previous halfedge 00455 he1->Next(), // next halfedge 00456 NULL ); // pair halfedge 00457 HEHalfEdge<T> * newPairHalfEdge = new HEHalfEdge<T>( 00458 newVertex, // original vertex 00459 he2->Face(), // incident face 00460 he2, // previous halfedge 00461 he2->Next(), // next halfedge 00462 newHalfEdge ); // pair halfedge 00463 newHalfEdge->Pair( newPairHalfEdge ); 00464 //----------------------------------------------------- 00465 // Rearrange Pointers 00466 newHalfEdge->Prev()->Next( newHalfEdge ); 00467 newHalfEdge->Next()->Prev( newHalfEdge ); 00468 newPairHalfEdge->Prev()->Next( newPairHalfEdge ); 00469 newPairHalfEdge->Next()->Prev( newPairHalfEdge ); 00470 newHalfEdge->Next()->Vertex( newVertex ); 00471 newVertex->IncidentHalfEdge( newPairHalfEdge ); 00472 //----------------------------------------------------- 00473 } 00474 //----------------------------------------------------------------------------- 00475 // Join Vertex Kill Edge 00476 //------------------------------------- 00477 // ^ / ^ / 00478 // \ / \ / he_prev 00479 // \ / \ V 00480 // \ / he_prev O 00481 // \ V | 00482 // O JVKE( he, pos ) | he 00483 // ^ \ <=============== V 00484 // / \ deleteVertex 00485 // / \ he_next ^ \ 00486 // / \ / \ he_next 00487 // / V / V 00488 template <typename T> 00489 void HalfEdgeModel<T>::JVKE ( HEHalfEdge<T> * he, Vector3<T> const * const pos ) 00490 { 00491 if ( pos != NULL ) he->Vertex()->SetPosition( *pos ); 00492 //----------------------------------------------------- 00493 // Change all halfedges that eminate from delete vertex to vertex of he 00494 // Except the starting halfedge, which is he->Pair(), 00495 // since we need to delete he->Pair()->Vertex(). 00496 HEHalfEdge<T> * pStartHalfEdge = he->Pair(); 00497 HEHalfEdge<T> * pCurrentHalfEdge = he->Next(); 00498 while ( pCurrentHalfEdge != pStartHalfEdge ) { 00499 pCurrentHalfEdge->Vertex( he->Vertex() ); 00500 pCurrentHalfEdge = pCurrentHalfEdge->Pair()->Next(); 00501 } 00502 //----------------------------------------------------- 00503 // Rearrange and Delete Pointers 00504 he->Vertex()->IncidentHalfEdge( he->Next() ); 00505 GetVertexList()->Delete( he->Pair()->Vertex() ); // delete the vertex 00506 he->Pair()->Face()->IncidentHalfEdge( he->Pair()->Next() ); 00507 he->Face()->IncidentHalfEdge( he->Next() ); 00508 he->Prev()->Next( he->Next() ); 00509 he->Next()->Prev( he->Prev() ); 00510 he->Pair()->Prev()->Next( he->Pair()->Next() ); 00511 he->Pair()->Next()->Prev( he->Pair()->Prev() ); 00512 delete he->Pair(); // delete the halfedge's pair 00513 delete he; // delete the halfedge 00514 //----------------------------------------------------- 00515 SetNoVertices( GetVertexList()->Size() ); 00516 //std::cout << "NoVertices: " << GetNoVertices() << "\n"; 00517 } 00518 //----------------------------------------------------------------------------- 00519 // Split Face Make Edge 00520 //------------------------------------- 00521 // O O 00522 // / ^ /|^ 00523 // / \ he1 / | \ he1 00524 // v \ v | \ 00525 // O O O g|h O 00526 // | ^ SFME( he1, he2 ) | | ^ h is a new halfedge (pair of g) 00527 // v f1 | =================> v f2| f1| f1 is the original face 00528 // O O O | O f2 is a new face 00529 // \ ^ \ | ^ g is a new halfedge (pair of h) 00530 // he2 \ / he2 \ | / 00531 // v / v|/ 00532 // O O 00533 template <typename T> 00534 void HalfEdgeModel<T>::SFME ( HEHalfEdge<T> * he1, HEHalfEdge<T> * he2 ) 00535 { 00536 //------------------------------------------------------------------ 00537 // Cancel if he1 and he2 are pointing to the same halfedge 00538 if ( he1 == he2 ) return; 00539 //------------------------------------------------------------------ 00540 // Cancel if he1 and he2 have different incident face 00541 if ( he1->Face() != he2->Face() ) return; 00542 //------------------------------------------------------------------ 00543 // Create a new face f2 00544 HEFace<T> * f1 = he1->Face(); 00545 HEFace<T> * f2 = new HEFace<T>( f1->GetNormal() ); 00546 //GetFaceList()->Append( f2 ); // append f2 to the face list 00547 GetFaceList()->InsertAfter( f2 ); // append f2 to the face list 00548 SetNoFaces( GetFaceList()->Size() ); // update face size 00549 //------------------------------------------------------------------ 00550 // Create new halfedges spliting f1 into f1 and f2 00551 HEHalfEdge<T> * h = new HEHalfEdge<T>( 00552 he1->Next()->Vertex(), // original vertex 00553 f1, // incident face 00554 he1, // previous halfedge 00555 he2->Next(), // next halfedge 00556 NULL ); // pair halfedge 00557 HEHalfEdge<T> * g = new HEHalfEdge<T>( 00558 he2->Next()->Vertex(), // original vertex 00559 f2, // incident face 00560 he2, // previous halfedge 00561 he1->Next(), // next halfedge 00562 h ); // pair halfedge 00563 h->Pair( g ); 00564 //------------------------------------------------------------------ 00565 // Rearrange all halfedges between h to g to have incident face f2 00566 HEHalfEdge<T> * pHalfEdge = he1->Next(); 00567 while ( pHalfEdge != he2 ) { 00568 pHalfEdge->Face( f2 ); 00569 pHalfEdge = pHalfEdge->Next(); 00570 } 00571 //------------------------------------------------------------------ 00572 // Rearrange pointers 00573 h->Prev()->Next( h ); 00574 h->Next()->Prev( h ); 00575 g->Prev()->Next( g ); 00576 g->Next()->Prev( g ); 00577 f2->IncidentHalfEdge( g ); 00578 } 00579 //----------------------------------------------------------------------------- 00580 // Join Face Kill Edge 00581 //------------------------------------- 00582 // O O 00583 // / ^ /|^ 00584 // / \ / | \ 00585 // v \ v /| \ 00586 // O O O g|he O 00587 // | ^ JFKE( he ) | |/ ^ he is the delete halfedge (pair of g) 00588 // v f1 | <============ v f2| f1| f1 is the face to be kept 00589 // O O O | O f2 is the delete face 00590 // \ ^ \ | ^ g is the delete halfedge (pair of h) 00591 // \ / \ | / 00592 // v / v|/ 00593 // O O 00594 template <typename T> 00595 void HalfEdgeModel<T>::JFKE ( HEHalfEdge<T> * he ) 00596 { 00597 //------------------------------------------------------------------ 00598 HEFace<T> * f1 = he->Face(); 00599 HEFace<T> * f2 = he->Pair()->Face(); 00600 //------------------------------------------------------------------ 00601 f1->IncidentHalfEdge( he->Prev() ); 00602 //------------------------------------------------------------------ 00603 // Rearrange all halfedges in f2 to have incident face f1 00604 int i = 0; 00605 HEHalfEdge<T> * pHalfEdge = he->Pair()->Next(); 00606 while ( pHalfEdge != he->Pair() ) { 00607 std::cout << ++i << std::endl; 00608 pHalfEdge->Face( f1 ); 00609 pHalfEdge = pHalfEdge->Next(); 00610 } 00611 00612 std::cout << "Start Rearranging Pointers" << std::endl; 00613 00614 //------------------------------------------------------------------ 00615 // Rearrange Pointers 00616 he->Vertex()->IncidentHalfEdge( he->Pair()->Next() ); 00617 he->Pair()->Vertex()->IncidentHalfEdge( he->Next() ); 00618 he->Prev()->Next( he->Pair()->Next() ); 00619 he->Next()->Prev( he->Pair()->Prev() ); 00620 he->Pair()->Prev()->Next( he->Next() ); 00621 he->Pair()->Next()->Prev( he->Prev() ); 00622 00623 std::cout << "Start Deleting Pointers" << std::endl; 00624 00625 //------------------------------------------------------------------ 00626 // Delete Pointers 00627 int count = 0; 00628 std::cout << ++count << std::endl; 00629 GetFaceList()->Delete( f2 ); // delete the face (f2) 00630 std::cout << ++count << std::endl; 00631 delete he->Pair(); // delete the halfedge's pair 00632 std::cout << ++count << std::endl; 00633 delete he; // delete the halfedge 00634 std::cout << ++count << std::endl; 00635 //----------------------------------------------------- 00636 std::cout << "SetNoFaces" << std::endl; 00637 SetNoFaces( GetFaceList()->Size() ); 00638 //------------------------------------------------------------------ 00639 std::cout << "Finish" << std::endl; 00640 } 00641 //----------------------------------------------------------------------------- 00642 //============================================================================= 00643 00644 00645 00646 00647 //============================================================================= 00648 #ifdef TAPs_ADD_STORED_POSITION 00649 //----------------------------------------------------------------------------- 00650 template <typename T> 00651 void HalfEdgeModel<T>::StoreCurrentPositionsToStoredPositions () 00652 { 00653 HEVertex<T> * pVertex = GetVertexList()->Head(); 00654 while ( pVertex != NULL ) { 00655 pVertex->RefToStoredPosition() = pVertex->RefToPosition(); 00656 pVertex = GetVertexList()->NextCurrent(); 00657 } 00658 } 00659 //----------------------------------------------------------------------------- 00660 template <typename T> 00661 void HalfEdgeModel<T>::RestorePositionsFromStoredPositions () 00662 { 00663 HEVertex<T> * pVertex = GetVertexList()->Head(); 00664 while ( pVertex != NULL ) { 00665 pVertex->RefToPosition() = pVertex->RefToStoredPosition(); 00666 pVertex = GetVertexList()->NextCurrent(); 00667 } 00668 } 00669 //----------------------------------------------------------------------------- 00670 #endif//TAPs_ADD_STORED_POSITION 00671 //============================================================================= 00672 00673 00674 00675 00676 //============================================================================= 00677 #if defined(__gl_h_) || defined(__GL_H__) 00678 //----------------------------------------------------------------------------- 00679 template <typename T> 00680 void HalfEdgeModel<T>::DrawPositions () const 00681 { 00682 glPushAttrib( GL_ALL_ATTRIB_BITS ); 00683 glPointSize( 3 ); 00684 glDisable( GL_LIGHTING ); 00685 //glDisable( GL_DEPTH_TEST ); 00686 glColor3f( 0, 1, 1 ); 00687 glBegin( GL_POINTS ); 00688 00689 HEVertex<T> * pVertex = GetVertexList()->Head(); 00690 while ( pVertex != NULL ) { 00691 glVertex3fv( pVertex->RefToPosition().GetDataFloat() ); 00692 pVertex = GetVertexList()->NextCurrent(); 00693 } 00694 00695 glEnd(); 00696 glPopAttrib(); 00697 } 00698 //----------------------------------------------------------------------------- 00699 #ifdef TAPs_ADD_STORED_POSITION 00700 template <typename T> 00701 void HalfEdgeModel<T>::DrawStoredPositions () const 00702 { 00703 glPushAttrib( GL_ALL_ATTRIB_BITS ); 00704 glPointSize( 3 ); 00705 glDisable( GL_LIGHTING ); 00706 //glDisable( GL_DEPTH_TEST ); 00707 glColor3f( 0, 1, 1 ); 00708 glBegin( GL_POINTS ); 00709 00710 HEVertex<T> * pVertex = GetVertexList()->Head(); 00711 while ( pVertex != NULL ) { 00712 glVertex3fv( pVertex->RefToStoredPosition().GetDataFloat() ); 00713 pVertex = GetVertexList()->NextCurrent(); 00714 } 00715 00716 glEnd(); 00717 glPopAttrib(); 00718 } 00719 #endif//TAPs_ADD_STORED_POSITION 00720 //----------------------------------------------------------------------------- 00721 #endif //#if defined(__gl_h_) || defined(__GL_H__) 00722 //============================================================================= 00723 00724 00725 00726 00727 //----------------------------------------------------------------------------- 00728 //============================================================================= 00729 END_NAMESPACE_TAPs__OpenGL 00730 //----------------------------------------------------------------------------- 00731 //345678901234567890123456789012345678901234567890123456789012345678901234567890 00732 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8