TAPs 0.7.7.3
TAPsHalfEdgeModel.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines