boundary.h

Go to the documentation of this file.
00001 
00010 #ifndef _BOUNDARY_H_
00011 #define _BOUNDARY_H_
00012 
00013 #include <algorithm>
00014 #include <vector>
00015 #include <list>
00016 #include <set>
00017 
00018 #include "../Mesh/BaseMesh.h"
00019 #include "../Mesh/iterators.h"
00020 
00021 namespace MeshLib
00022 {
00031 template<typename CVertex, typename CEdge, typename CFace, typename CHalfEdge>
00032 class CLoop
00033 {
00034 public:
00040          CLoop( CBaseMesh<CVertex, CEdge,CFace, CHalfEdge> * pMesh, CHalfEdge * pH );
00044         ~CLoop();
00045         
00049         std::list<CHalfEdge*>  & halfedges() 
00050         {
00051                 return m_halfedges;
00052         }
00053         
00057         double length() 
00058         { 
00059                 return m_length; 
00060         }
00061 
00062 protected:
00066         CBaseMesh<CVertex,CEdge,CFace,CHalfEdge>                * m_pMesh;
00069         double                                                                                    m_length;
00073         CHalfEdge                                                                               * m_pHalfedge;
00077         std::list<CHalfEdge*>                                                     m_halfedges;
00078 
00079 };
00080 
00089 template<typename CVertex, typename CEdge, typename CFace, typename CHalfEdge>
00090 class CBoundary
00091 {
00092         typedef CLoop<CVertex,CEdge, CFace, CHalfEdge> TLoop;
00093 
00094 public:
00099         CBoundary( CBaseMesh<CVertex,CEdge,CFace,CHalfEdge> * pMesh );
00103         ~CBoundary();
00107         std::vector<TLoop*> & loops() 
00108         { 
00109                 return m_loops; 
00110         } 
00111 
00112 protected:
00116         CBaseMesh<CVertex,CEdge,CFace,CHalfEdge> * m_pMesh;
00120         typename std::vector<TLoop*> m_loops;
00125         void _bubble_sort( std::vector<CLoop<CVertex, CEdge, CFace, CHalfEdge>*> & loops);
00126 };
00127 
00133 template<typename CVertex, typename CEdge, typename CFace, typename CHalfEdge>
00134 CLoop<CVertex, CEdge, CFace, CHalfEdge>::CLoop( CBaseMesh<CVertex, CEdge, CFace, CHalfEdge> * pMesh, CHalfEdge * pH )
00135 {
00136         m_pMesh     = pMesh;
00137         m_pHalfedge = pH;
00138 
00139         m_length = 0;
00140         CHalfEdge * he = pH;
00141         //trace the boundary loop
00142         do{
00143                 CVertex * v = (CVertex*)he->target();
00144                 he = m_pMesh->vertexMostClwOutHalfEdge( v );
00145                 m_halfedges.push_back( he );
00146     m_length += m_pMesh->edgeLength( (CEdge*)he->edge() );
00147         }while( he != m_pHalfedge );
00148 }
00149 
00153 template<typename CVertex, typename CEdge, typename CFace, typename CHalfEdge>
00154 CLoop<CVertex, CEdge, CFace, CHalfEdge>::~CLoop()
00155 {
00156         m_halfedges.clear();
00157 }
00158 
00159 
00165 template<typename CVertex, typename CEdge, typename CFace, typename CHalfEdge>
00166 void CBoundary<CVertex, CEdge, CFace, CHalfEdge>::_bubble_sort( std::vector<CLoop<CVertex, CEdge, CFace, CHalfEdge>*> & loops)
00167 {
00168       int i, j, flag = 1;    // set flag to 1 to start first pass
00169       CLoop<CVertex,CEdge,CFace,CHalfEdge> * temp;             // holding variable
00170       int numLength = (int)loops.size( ); 
00171       for(i = 1; (i <= numLength) && flag; i++)
00172      {
00173           flag = 0;
00174           for (j=0; j < (numLength -1); j++)
00175          {
00176                if (loops[j+1]->length() > loops[j]->length() )      // ascending order simply changes to <
00177               { 
00178                     temp = loops[j];                                                            // swap elements
00179                     loops[j] = loops[j+1];
00180                     loops[j+1] = temp;
00181                     flag = 1;                                                                           // indicates that a swap occurred.
00182                }
00183           }
00184      }
00185 }
00186 
00191 template<typename CVertex, typename CEdge, typename CFace, typename CHalfEdge>
00192 CBoundary<CVertex, CEdge, CFace, CHalfEdge>::CBoundary( CBaseMesh<CVertex, CEdge, CFace, CHalfEdge> * pMesh )
00193 {
00194         m_pMesh = pMesh;
00195         //collect all boundary halfedges
00196         std::set<CHalfEdge*> boundary_hes;
00197         for( MeshEdgeIterator<CVertex, CEdge, CFace, CHalfEdge> eiter( m_pMesh); !eiter.end(); eiter ++ )
00198         {
00199                 CEdge * e = *eiter;
00200                 if( !m_pMesh->isBoundary(e) ) continue;
00201 
00202                 CHalfEdge * he = m_pMesh->edgeHalfedge( e, 0);
00203                 boundary_hes.insert( he );
00204         }
00205         //trace all the boundary loops
00206         while( !boundary_hes.empty() )
00207         {
00208                 //get the first boundary halfedge
00209                 std::set<CHalfEdge*>::iterator siter = boundary_hes.begin();
00210                 CHalfEdge * he = *siter;
00211                 //trace along this boundary halfedge
00212                 CLoop<CVertex, CEdge, CFace, CHalfEdge> * pL = new CLoop<CVertex, CEdge, CFace, CHalfEdge>( m_pMesh, he );
00213                 assert(pL);
00214                 m_loops.push_back( pL );
00215                 //remove all the boundary halfedges, which are in the same boundary loop as the head, from the halfedge list
00216                 for( std::list<CHalfEdge*>::iterator hiter = pL->halfedges().begin(); 
00217                         hiter != pL->halfedges().end(); hiter ++ )
00218                 {
00219                         CHalfEdge * he = *hiter;
00220                         siter = boundary_hes.find( he );
00221                         if( siter == boundary_hes.end() ) continue;
00222                         boundary_hes.erase( siter );
00223                 }
00224         }
00225         
00226         //std::sort( vlps.begin(), vlps.end(), loop_compare<CVertex,CFace,CEdge,CHalfEdge> );
00227         _bubble_sort( m_loops );
00228 }
00229 
00232 template<typename CVertex, typename CEdge, typename CFace, typename CHalfEdge>
00233 CBoundary<CVertex, CEdge, CFace, CHalfEdge>::~CBoundary()
00234 {
00235         for( int i = 0; i < (int)m_loops.size(); i ++ )
00236         {
00237                 CLoop<CVertex, CEdge, CFace, CHalfEdge> * pL = m_loops[i];
00238                 delete pL;
00239         }
00240 }
00241 
00242 }
00243 #endif
00244 
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Defines