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
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;
00169 CLoop<CVertex,CEdge,CFace,CHalfEdge> * temp;
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() )
00177 {
00178 temp = loops[j];
00179 loops[j] = loops[j+1];
00180 loops[j+1] = temp;
00181 flag = 1;
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
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
00206 while( !boundary_hes.empty() )
00207 {
00208
00209 std::set<CHalfEdge*>::iterator siter = boundary_hes.begin();
00210 CHalfEdge * he = *siter;
00211
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
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
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