• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

/home/hauberg/Dokumenter/Capture/humim-tracker-0.1/src/OpenTissue/OpenTissue/core/containers/mesh/polymesh/kernels/polymesh_list_kernel.h

Go to the documentation of this file.
00001 #ifndef OPENTISSUE_CORE_CONTAINERS_MESH_POLYMESH_KERNELS_POLYMESH_LIST_KERNEL_H
00002 #define OPENTISSUE_CORE_CONTAINERS_MESH_POLYMESH_KERNELS_POLYMESH_LIST_KERNEL_H
00003 //
00004 // OpenTissue Template Library
00005 // - A generic toolbox for physics-based modeling and simulation.
00006 // Copyright (C) 2008 Department of Computer Science, University of Copenhagen.
00007 //
00008 // OTTL is licensed under zlib: http://opensource.org/licenses/zlib-license.php
00009 //
00010 #include <OpenTissue/configuration.h>
00011 
00012 #include <OpenTissue/core/containers/mesh/polymesh/polymesh.h>
00013 #include <OpenTissue/core/containers/mesh/polymesh/polymesh_vertex.h>
00014 #include <OpenTissue/core/containers/mesh/polymesh/polymesh_halfedge.h>
00015 #include <OpenTissue/core/containers/mesh/polymesh/polymesh_edge.h>
00016 #include <OpenTissue/core/containers/mesh/polymesh/polymesh_face.h>
00017 
00018 #include <boost/optional.hpp>
00019 #include <boost/none.hpp>
00020 
00021 #include <list>
00022 #include <vector>
00023 #include <cassert>
00024 
00025 namespace OpenTissue
00026 {
00027   namespace polymesh
00028   {
00029 
00053     template<
00054       typename V
00055       , typename H
00056       , typename E
00057       , typename F
00058     >
00059     class PolyMeshListKernel
00060     {
00061     public:
00062 
00063       typedef V   vertex_type;
00064       typedef H   halfedge_type;
00065       typedef E   edge_type;
00066       typedef F   face_type;
00067 
00068       typedef PolyMeshListKernel<V,H,E,F> kernel_type;
00069 
00070     public:
00071 
00072       typedef std::size_t                                        index_type;
00073       typedef typename std::list<vertex_type>::size_type         size_type;
00074 
00075       typedef typename std::list<vertex_type>::iterator          vertex_iterator;
00076       typedef typename std::list<halfedge_type>::iterator        halfedge_iterator;
00077       typedef typename std::list<edge_type>::iterator            edge_iterator;
00078       typedef typename std::list<face_type>::iterator            face_iterator;
00079 
00080       typedef typename std::list<vertex_type>::const_iterator    const_vertex_iterator;
00081       typedef typename std::list<halfedge_type>::const_iterator  const_halfedge_iterator;
00082       typedef typename std::list<edge_type>::const_iterator      const_edge_iterator;
00083       typedef typename std::list<face_type>::const_iterator      const_face_iterator;
00084 
00085       // This is what we store in the lookup-tables (...lut).
00086       // Allows us to model the concept of a "null"-iterator.
00087       // * It is implicitly convertible to bool, so one can test for a valid iterator
00088       //   simply by saying "if ( iter )".
00089       // * If it does contain a valid iterator, it can be retrieved by using "iter.get()". This is used
00090       //   when the iterator needs to be passed to a method.
00091       // * To reset an optional iterator, use "iter = boost::none"
00092       // * Otherwise, it acts just like an ordinary iterator.
00093       typedef typename boost::optional<vertex_iterator>          opt_vertex_iter;
00094       typedef typename boost::optional<halfedge_iterator>        opt_halfedge_iter;
00095       typedef typename boost::optional<edge_iterator>            opt_edge_iter;
00096       typedef typename boost::optional<face_iterator>            opt_face_iter;
00097 
00098     private:
00099 
00106       class Handle
00107       {
00108       protected:
00109 
00110         index_type m_idx;
00111 
00112       public:
00113 
00114         Handle()                        : m_idx(~0u)     {}
00115         explicit Handle(index_type idx) : m_idx(idx)     {}
00116         Handle(Handle const & h)        : m_idx(h.m_idx) {}
00117 
00118         Handle &   operator= (Handle const & h)       { m_idx = h.m_idx; return *this; }
00119         bool       operator< (Handle const & h) const { return m_idx < h.m_idx; }
00120         bool       operator==(Handle const & h) const { return (h.m_idx==m_idx); }
00121         bool       operator!=(Handle const & h) const { return (h.m_idx!=m_idx); }
00122         index_type get_idx() const { return m_idx; }
00123         bool       is_null() const { return (m_idx == ~0u); }
00124       };
00125 
00126     public:
00127 
00128       class vertex_handle : public Handle
00129       {
00130       public:
00131         vertex_handle()                        : Handle()    {}
00132         vertex_handle(index_type idx)          : Handle(idx) {}
00133         vertex_handle(vertex_handle const & v) : Handle(v)   {}
00134       };
00135 
00136       class halfedge_handle : public Handle
00137       {
00138       public:
00139         halfedge_handle()                          : Handle()    {}
00140         halfedge_handle(index_type idx)            : Handle(idx) {}
00141         halfedge_handle(halfedge_handle const & h) : Handle(h)   {}
00142       };
00143 
00144       class edge_handle : public Handle
00145       {
00146       public:
00147         edge_handle()                      : Handle()    {}
00148         edge_handle(index_type idx)        : Handle(idx) {}
00149         edge_handle(edge_handle const & e) : Handle(e)   {}
00150       };
00151 
00152       class face_handle : public Handle
00153       {
00154       public:
00155         face_handle()                      : Handle()    {}
00156         face_handle(index_type idx)        : Handle(idx) {}
00157         face_handle(face_handle const & f) : Handle(f)   {}
00158       };
00159 
00160     public:
00161 
00162       static vertex_handle const & null_vertex_handle()
00163       {
00164         static vertex_handle h;
00165         return h;
00166       }
00167       static halfedge_handle const & null_halfedge_handle()
00168       {
00169         static halfedge_handle h;
00170         return h;
00171       }
00172       static edge_handle const & null_edge_handle()
00173       {
00174         static edge_handle h;
00175         return h;
00176       }
00177       static face_handle const & null_face_handle()
00178       {
00179         static face_handle h;
00180         return h;
00181       }
00182 
00183     private:
00184 
00185       std::list< vertex_type   >       m_vertices;
00186       std::list< halfedge_type >       m_halfedges;
00187       std::list< edge_type     >       m_edges;
00188       std::list< face_type     >       m_faces;
00189 
00190       // This is our iterator lookup-tables, that can contain an empty optional, corresponding to
00191       // a "null"-iterator
00192       std::vector< opt_vertex_iter   > m_vertex_lut;
00193       std::vector< opt_halfedge_iter > m_halfedge_lut;
00194       std::vector< opt_edge_iter     > m_edge_lut;
00195       std::vector< opt_face_iter     > m_face_lut;
00196 
00197     public:
00198 
00199       vertex_iterator   vertex_begin()   { return m_vertices.begin(); }
00200       vertex_iterator   vertex_end()     { return m_vertices.end(); }
00201       halfedge_iterator halfedge_begin() { return m_halfedges.begin(); }
00202       halfedge_iterator halfedge_end()   { return m_halfedges.end(); }
00203       edge_iterator     edge_begin()     { return m_edges.begin(); }
00204       edge_iterator     edge_end()       { return m_edges.end(); }
00205       face_iterator     face_begin()     { return m_faces.begin(); }
00206       face_iterator     face_end()       { return m_faces.end(); }
00207 
00208       const_vertex_iterator   vertex_begin()   const { return m_vertices.begin(); }
00209       const_vertex_iterator   vertex_end()     const { return m_vertices.end(); }
00210       const_halfedge_iterator halfedge_begin() const { return m_halfedges.begin(); }
00211       const_halfedge_iterator halfedge_end()   const { return m_halfedges.end(); }
00212       const_edge_iterator     edge_begin()     const { return m_edges.begin(); }
00213       const_edge_iterator     edge_end()       const { return m_edges.end(); }
00214       const_face_iterator     face_begin()     const { return m_faces.begin(); }
00215       const_face_iterator     face_end()       const { return m_faces.end(); }
00216 
00217       size_type size_faces()     const { return m_faces.size(); }
00218       size_type size_halfedges() const { return m_halfedges.size(); }
00219       size_type size_edges()     const { return m_edges.size(); }
00220       size_type size_vertices()  const { return m_vertices.size(); }
00221 
00222     public:
00223 
00224       PolyMeshListKernel() {}
00225 
00226       explicit PolyMeshListKernel(PolyMeshListKernel const & other_kernel){ *this = other_kernel; }
00227 
00228     public:
00229 
00230       PolyMeshListKernel & operator=(PolyMeshListKernel const & rhs)
00231       {
00232         clear();
00233 
00234         //--- Brute force copy of lists
00235         std::copy( rhs.m_vertices.begin(),  rhs.m_vertices.end(),  std::back_inserter(m_vertices) );
00236         std::copy( rhs.m_halfedges.begin(), rhs.m_halfedges.end(), std::back_inserter(m_halfedges) );
00237         std::copy( rhs.m_edges.begin(),     rhs.m_edges.end(),     std::back_inserter(m_edges) );
00238         std::copy( rhs.m_faces.begin(),     rhs.m_faces.end(),     std::back_inserter(m_faces) );
00239         //--- Allocate storage for lookup tables (lut's)
00240         m_vertex_lut.resize  ( rhs.m_vertex_lut.size() );
00241         m_halfedge_lut.resize( rhs.m_halfedge_lut.size() );
00242         m_edge_lut.resize    ( rhs.m_edge_lut.size() );
00243         m_face_lut.resize    ( rhs.m_face_lut.size() );
00244         //--- Iterate lists, get self handles and update entries in lut's
00245         for(vertex_iterator v = vertex_begin(); v!=vertex_end(); ++v)
00246         {
00247           assert(v->get_handle().get_idx()<m_vertex_lut.size());
00248           m_vertex_lut[v->get_handle().get_idx()] = v;
00249         }
00250         for(halfedge_iterator h = halfedge_begin(); h!=halfedge_end(); ++h)
00251         {
00252           assert(h->get_handle().get_idx()<m_halfedge_lut.size());
00253           m_halfedge_lut[h->get_handle().get_idx()] = h;
00254         }
00255         for(edge_iterator e = edge_begin(); e!=edge_end(); ++e)
00256         {
00257           assert(e->get_handle().get_idx()<m_edge_lut.size());
00258           m_edge_lut[e->get_handle().get_idx()] = e;
00259         }
00260         for(face_iterator f = face_begin(); f!=face_end(); ++f)
00261         {
00262           assert(f->get_handle().get_idx()<m_face_lut.size());
00263           m_face_lut[f->get_handle().get_idx()] = f;
00264         }
00265         return (*this);
00266       }
00267 
00268     protected:
00269 
00270       vertex_handle create_vertex()
00271       {
00272         m_vertices.push_back(vertex_type());
00273         vertex_iterator last = m_vertices.end();
00274         --last;
00275         index_type new_idx = m_vertex_lut.size();
00276         m_vertex_lut.push_back(last);
00277 
00278         vertex_handle h(new_idx);
00279         polymesh_core_access::set_self_handle( last, h);
00280         return h;
00281       }
00282 
00283       halfedge_handle create_halfedge()
00284       {
00285         m_halfedges.push_back(halfedge_type());
00286         halfedge_iterator last = m_halfedges.end();
00287         --last;
00288         index_type new_idx = m_halfedge_lut.size();
00289         m_halfedge_lut.push_back(last);
00290 
00291         halfedge_handle h(new_idx);
00292         polymesh_core_access::set_self_handle( last, h);
00293         return h;
00294       }
00295 
00296       edge_handle create_edge()
00297       {
00298         m_edges.push_back(edge_type());
00299         edge_iterator last = m_edges.end();
00300         --last;
00301         index_type new_idx = m_edge_lut.size();
00302         m_edge_lut.push_back(last);
00303         edge_handle h(new_idx);
00304         polymesh_core_access::set_self_handle( last, h);
00305         return h;
00306       }
00307 
00308       face_handle create_face()
00309       {
00310         m_faces.push_back(face_type());
00311         face_iterator last = m_faces.end();
00312         --last;
00313         index_type new_idx = m_face_lut.size();
00314         m_face_lut.push_back(last);
00315         face_handle h(new_idx);
00316         polymesh_core_access::set_self_handle( last, h);
00317         return h;
00318       }
00319 
00320       void erase_vertex(vertex_handle const & v)
00321       {
00322         assert(v.get_idx()>=0);
00323         assert(v.get_idx()<m_vertex_lut.size());
00324 
00325         opt_vertex_iter vit = m_vertex_lut[v.get_idx()];
00326         if(vit)
00327         {
00328           m_vertices.erase(vit.get());
00329           m_vertex_lut[v.get_idx()] = boost::none;
00330         }
00331       }
00332 
00333       void erase_halfedge(halfedge_handle const & h)
00334       {
00335         assert(h.get_idx()>=0);
00336         assert(h.get_idx()<m_halfedge_lut.size());
00337 
00338         opt_halfedge_iter hit = m_halfedge_lut[h.get_idx()];
00339         if(hit)
00340         {
00341           m_halfedges.erase(hit.get());
00342           m_halfedge_lut[h.get_idx()] = boost::none;
00343         }
00344       }
00345 
00346       void erase_edge(edge_handle const & e)
00347       {
00348         assert(e.get_idx()>=0);
00349         assert(e.get_idx()<m_edge_lut.size());
00350 
00351         opt_edge_iter eit = m_edge_lut[e.get_idx()];
00352         if(eit)
00353         {
00354           m_edges.erase(eit.get());
00355           m_edge_lut[e.get_idx()] = boost::none;
00356         }
00357       }
00358 
00359       void erase_face(face_handle const & f)
00360       {
00361         assert(f.get_idx()>=0);
00362         assert(f.get_idx()<m_face_lut.size());
00363 
00364         opt_face_iter fit = m_face_lut[f.get_idx()];
00365         if(fit)
00366         {
00367           m_faces.erase(fit.get());
00368           m_face_lut[f.get_idx()] = boost::none;
00369         }
00370       }
00371 
00372     public:
00373 
00374       vertex_handle get_vertex_handle(index_type idx) const
00375       {
00376         assert(idx>=0);
00377         assert(idx<m_vertex_lut.size());
00378 
00379         opt_vertex_iter lut = m_vertex_lut[idx];
00380         return lut ? lut.get()->get_handle() : null_vertex_handle();
00381       }
00382 
00383       halfedge_handle get_halfedge_handle(index_type idx) const
00384       {
00385         assert(idx>=0);
00386         assert(idx<m_halfedge_lut.size());
00387 
00388         opt_halfedge_iter lut = m_halfedge_lut[idx];
00389         return lut ? lut.get()->get_handle() : null_halfedge_handle();
00390       }
00391 
00392       edge_handle get_edge_handle(index_type idx) const
00393       {
00394         assert(idx>=0);
00395         assert(idx<m_edge_lut.size());
00396 
00397         opt_edge_iter lut = m_edge_lut[idx];
00398         return lut ? lut.get()->get_handle() : null_edge_handle();
00399       }
00400 
00401       face_handle get_face_handle(index_type idx) const
00402       {
00403         assert(idx>=0);
00404         assert(idx<m_face_lut.size());
00405 
00406         opt_face_iter lut = m_face_lut[idx];
00407         return lut ? lut.get()->get_handle() : null_face_handle();
00408       }
00409 
00410       vertex_iterator get_vertex_iterator(vertex_handle const & v) /*const*/
00411       {
00412         if( v == null_vertex_handle() )
00413           return vertex_end();
00414 
00415         assert(v.get_idx()>=0);
00416         assert(v.get_idx()<m_vertex_lut.size());
00417 
00418         return m_vertex_lut[v.get_idx()].get();
00419         // TODO: henrikd 20060323
00420         //   Is it possible for a valid handle to point at a "null"-iterator?
00421         //   If yes, then we should perhaps do this instead:
00422         //   opt_vertex_iter lut = m_vertex_lut[v.get_idx()];
00423         //   return lut ? lut.get() : vertex_end();
00424         // 
00425         // Ahh, the user should first call is_valid_vertex_handle(v), right?
00426         // If yes, then the above sketched construct could be used instead,
00427         // eliminating the need for is_valid_vertex_handle(v).
00428         // Then the user should instead check if get_vertex_iterator(v) returns
00429         // the end-iterator. Ain't that pretty? :-)
00430       }
00431 
00432       halfedge_iterator get_halfedge_iterator(halfedge_handle const & h) /*const*/
00433       {
00434         if( h == null_halfedge_handle() )
00435           return halfedge_end();
00436 
00437         assert(h.get_idx()>=0);
00438         assert(h.get_idx()<m_halfedge_lut.size());
00439 
00440         return  m_halfedge_lut[h.get_idx()].get();
00441       }
00442 
00443       edge_iterator get_edge_iterator(edge_handle const & e) /*const*/
00444       {
00445         if( e == null_edge_handle() )
00446           return edge_end();
00447 
00448         assert(e.get_idx()>=0);
00449         assert(e.get_idx()<m_edge_lut.size());
00450 
00451         return  m_edge_lut[e.get_idx()].get();
00452       }
00453 
00454       face_iterator get_face_iterator(face_handle const & f) /*const*/
00455       {
00456         if( f == null_face_handle() )
00457           return face_end();
00458 
00459         assert(f.get_idx()>=0);
00460         assert(f.get_idx()<m_face_lut.size());
00461 
00462         return  m_face_lut[f.get_idx()].get();
00463       }
00464 
00465       void clear()
00466       {
00467         m_vertices.clear();
00468         m_halfedges.clear();
00469         m_edges.clear();
00470         m_faces.clear();
00471         m_vertex_lut.clear();
00472         m_halfedge_lut.clear();
00473         m_edge_lut.clear();
00474         m_face_lut.clear();
00475       }
00476 
00477     public:
00478 
00479       bool is_valid_vertex_handle(vertex_handle const & v) const
00480       {
00481         if(v == null_vertex_handle())
00482           return false;
00483 
00484         assert(v.get_idx()>=0);
00485         assert(v.get_idx()<m_vertex_lut.size());
00486 
00487         return 0 != m_vertex_lut[v.get_idx()];
00488       }
00489 
00490       bool is_valid_halfedge_handle(halfedge_handle const & h) const
00491       {
00492         if(h == null_halfedge_handle())
00493           return false;
00494 
00495         assert(h.get_idx()>=0);
00496         assert(h.get_idx()<m_halfedge_lut.size());
00497 
00498         return 0 != m_halfedge_lut[h.get_idx()];
00499       }
00500 
00501       bool is_valid_edge_handle(edge_handle const & e) const
00502       {
00503         if(e == null_edge_handle())
00504           return false;
00505 
00506         assert(e.get_idx()>=0);
00507         assert(e.get_idx()<m_edge_lut.size());
00508 
00509         return 0 != m_edge_lut[e.get_idx()];
00510       }
00511 
00512       bool is_valid_face_handle(face_handle const & f) const
00513       {
00514         if(f == null_face_handle())
00515           return false;
00516 
00517         assert(f.get_idx()>=0);
00518         assert(f.get_idx()<m_face_lut.size());
00519 
00520         return 0 != m_face_lut[f.get_idx()];
00521       }
00522 
00523     };
00524 
00525   } // namespace polymesh
00526 } // namespace OpenTissue
00527 
00528 //OPENTISSUE_CORE_CONTAINERS_MESH_POLYMESH_KERNELS_POLYMESH_LIST_KERNEL2_H
00529 #endif

Generated on Thu Dec 1 2011 12:51:16 for HUMIM Tracker by  doxygen 1.7.1