contrib/brl/bbas/imesh/imesh_half_edge.h
Go to the documentation of this file.
00001 // This is brl/bbas/imesh/imesh_half_edge.h
00002 #ifndef imesh_half_edge_h_
00003 #define imesh_half_edge_h_
00004 
00005 //:
00006 // \file
00007 // \brief A simple indexed half-edge
00008 // \author Matt Leotta (mleotta@lems.brown.edu)
00009 // \date May 2, 2008
00010 
00011 #include <vcl_iterator.h>
00012 #include <vcl_vector.h>
00013 #include <vcl_cassert.h>
00014 
00015 #define imesh_invalid_idx (static_cast<unsigned int>(-1))
00016 
00017 class imesh_half_edge
00018 {
00019     friend class imesh_half_edge_set;
00020   public:
00021     imesh_half_edge(unsigned int e, unsigned int n, unsigned int v, unsigned int f)
00022     : next_(n), edge_(e), vert_(v), face_(f) {}
00023 
00024     //: return the next half-edge index
00025     unsigned int next_index() const { return next_; }
00026     //: return the pair half-edge index
00027     unsigned int pair_index() const { return edge_^1; }
00028 
00029     //: return the index of the full edge
00030     unsigned int edge_index() const { return edge_>>1; }
00031     //: return the index of the half-edge
00032     unsigned int half_edge_index() const { return edge_; }
00033 
00034     //: return the vertex index
00035     unsigned int vert_index() const { return vert_; }
00036     //: return the face index
00037     unsigned int face_index() const { return face_; }
00038 
00039     bool is_boundary() const { return face_ == imesh_invalid_idx; }
00040 
00041   private:
00042     unsigned int next_;
00043     unsigned int edge_;
00044 
00045     unsigned int vert_;
00046     unsigned int face_;
00047 };
00048 
00049 
00050 //: A collection of indexed half edges
00051 class imesh_half_edge_set
00052 {
00053   public:
00054     //: Default Constructor
00055     imesh_half_edge_set() {}
00056     //: Construct from a face index list
00057     imesh_half_edge_set(const vcl_vector<vcl_vector<unsigned int> >& face_list);
00058 
00059     //: Build the half edges from an indexed face set
00060     void build_from_ifs(const vcl_vector<vcl_vector<unsigned int> >& face_list);
00061 
00062     //: Access by index
00063     const imesh_half_edge& operator [] (unsigned int i) const { return half_edges_[i]; }
00064     //: Access by index
00065     imesh_half_edge& operator [] (unsigned int i)  { return half_edges_[i]; }
00066 
00067     //: number of half edges
00068     unsigned int size() const { return half_edges_.size(); }
00069 
00070     //: clear the edges
00071     void clear()
00072     {
00073       half_edges_.clear();
00074       vert_to_he_.clear();
00075       face_to_he_.clear();
00076     }
00077 
00078     // forward declare iterators
00079     class f_iterator;
00080     class f_const_iterator;
00081     class v_iterator;
00082     class v_const_iterator;
00083 
00084     //=====================================================
00085     // Mesh Face Iterators - each half edge touches the same face
00086 
00087     //: An iterator of half edges adjacent to a face
00088     class f_iterator : public vcl_iterator<vcl_forward_iterator_tag,imesh_half_edge>
00089     {
00090       friend class f_const_iterator;
00091       friend class v_iterator;
00092       public:
00093         //: Constructor
00094         f_iterator(unsigned int hei, imesh_half_edge_set& edge_set)
00095           :half_edge_index_(hei), edge_set_(edge_set) {}
00096 
00097         //: Constructor from vertex iterator
00098         explicit f_iterator(const v_iterator& other)
00099           :half_edge_index_(other.half_edge_index_), edge_set_(other.edge_set_) {}
00100 
00101         //: Assignment
00102         f_iterator& operator = (const f_iterator& other)
00103         {
00104           if (this != &other){
00105             assert(&edge_set_ == &other.edge_set_);
00106             half_edge_index_ = other.half_edge_index_;
00107           }
00108           return *this;
00109         }
00110 
00111         imesh_half_edge & operator*() const { return edge_set_[half_edge_index_]; }
00112         imesh_half_edge * operator->() const { return &**this; }
00113         imesh_half_edge & pair() const { return edge_set_[half_edge_index_^1]; }
00114         f_iterator & operator++ () // pre-inc
00115         {
00116           half_edge_index_ = edge_set_[half_edge_index_].next_index();
00117           return *this;
00118         }
00119         f_iterator operator++(int) // post-inc
00120         {
00121           f_iterator old = *this;
00122           ++*this;
00123           return old;
00124         }
00125 
00126         bool operator == (const f_iterator& other) const
00127         {
00128           return this->half_edge_index_ == other.half_edge_index_ &&
00129                 &(this->edge_set_) == &(other.edge_set_);
00130         }
00131 
00132         bool operator != (const f_iterator& other) const
00133         {
00134           return !(*this == other);
00135         }
00136 
00137         bool operator == (const f_const_iterator& other) const
00138         {
00139           return this->half_edge_index_ == other.half_edge_index_ &&
00140                 &(this->edge_set_) == &(other.edge_set_);
00141         }
00142 
00143         bool operator != (const f_const_iterator& other) const
00144         {
00145           return !(*this == other);
00146         }
00147 
00148       private:
00149         unsigned int half_edge_index_;
00150         imesh_half_edge_set& edge_set_;
00151     };
00152 
00153     //: A const iterator of half edges adjacent to a face
00154     class f_const_iterator : public vcl_iterator<vcl_forward_iterator_tag,imesh_half_edge>
00155     {
00156         friend class f_iterator;
00157         friend class v_const_iterator;
00158       public:
00159         //: Constructor
00160         f_const_iterator(unsigned int hei, const imesh_half_edge_set& edge_set)
00161           :half_edge_index_(hei), edge_set_(edge_set) {}
00162 
00163         //: Constructor from non-const iterator
00164         f_const_iterator(const f_iterator& other)
00165           :half_edge_index_(other.half_edge_index_), edge_set_(other.edge_set_) {}
00166 
00167         //: Constructor from vertex iterator
00168         explicit f_const_iterator(const v_const_iterator& other)
00169           :half_edge_index_(other.half_edge_index_), edge_set_(other.edge_set_) {}
00170 
00171         //: Assignment
00172         f_const_iterator& operator = (const f_const_iterator& other)
00173         {
00174           if (this != &other){
00175             assert(&edge_set_ == &other.edge_set_);
00176             half_edge_index_ = other.half_edge_index_;
00177           }
00178           return *this;
00179         }
00180 
00181         const imesh_half_edge & operator*() const { return edge_set_[half_edge_index_]; }
00182         const imesh_half_edge * operator->() const { return &**this; }
00183         const imesh_half_edge & pair() const { return edge_set_[half_edge_index_^1]; }
00184         f_const_iterator & operator++ () // pre-inc
00185         {
00186           half_edge_index_ = edge_set_[half_edge_index_].next_index();
00187           return *this;
00188         }
00189         f_const_iterator operator++(int) // post-inc
00190         {
00191           f_const_iterator old = *this;
00192           ++*this;
00193           return old;
00194         }
00195 
00196         bool operator == (const f_const_iterator& other) const
00197         {
00198           return this->half_edge_index_ == other.half_edge_index_ &&
00199                 &(this->edge_set_) == &(other.edge_set_);
00200         }
00201 
00202         bool operator != (const f_const_iterator& other) const
00203         {
00204           return !(*this == other);
00205         }
00206 
00207       private:
00208         unsigned int half_edge_index_;
00209         const imesh_half_edge_set& edge_set_;
00210     };
00211 
00212 
00213     //=====================================================
00214     // Mesh Vertex Iterators - each half edge touches the same vertex
00215 
00216     //: An iterator of half edges adjacent to a vertex
00217     class v_iterator : public vcl_iterator<vcl_forward_iterator_tag,imesh_half_edge>
00218     {
00219         friend class v_const_iterator;
00220         friend class f_iterator;
00221       public:
00222         //: Constructor
00223         v_iterator(unsigned int hei, imesh_half_edge_set& edge_set)
00224           :half_edge_index_(hei), edge_set_(edge_set) {}
00225 
00226         //: Constructor from face iterator
00227         explicit v_iterator(const f_iterator& other)
00228           :half_edge_index_(other.half_edge_index_), edge_set_(other.edge_set_) {}
00229 
00230         //: Assignment
00231         v_iterator& operator = (const v_iterator& other)
00232         {
00233           if (this != &other){
00234             assert(&edge_set_ == &other.edge_set_);
00235             half_edge_index_ = other.half_edge_index_;
00236           }
00237           return *this;
00238         }
00239 
00240         imesh_half_edge & operator*() const { return edge_set_[half_edge_index_]; }
00241         imesh_half_edge * operator->() const { return &**this; }
00242         imesh_half_edge & pair() const { return edge_set_[half_edge_index_^1]; }
00243         v_iterator & operator++ () // pre-inc
00244         {
00245           half_edge_index_ = half_edge_index_ ^ 1; // pair index
00246           half_edge_index_ = edge_set_[half_edge_index_].next_index();
00247           return *this;
00248         }
00249         v_iterator operator++(int) // post-inc
00250         {
00251           v_iterator old = *this;
00252           ++*this;
00253           return old;
00254         }
00255 
00256         bool operator == (const v_iterator& other) const
00257         {
00258           return this->half_edge_index_ == other.half_edge_index_ &&
00259                 &(this->edge_set_) == &(other.edge_set_);
00260         }
00261 
00262         bool operator != (const v_iterator& other) const
00263         {
00264           return !(*this == other);
00265         }
00266 
00267         bool operator == (const v_const_iterator& other) const
00268         {
00269           return this->half_edge_index_ == other.half_edge_index_ &&
00270                 &(this->edge_set_) == &(other.edge_set_);
00271         }
00272 
00273         bool operator != (const v_const_iterator& other) const
00274         {
00275           return !(*this == other);
00276         }
00277 
00278       private:
00279         unsigned int half_edge_index_;
00280         imesh_half_edge_set& edge_set_;
00281     };
00282 
00283     //: A const iterator of half edges adjacent to a vertex
00284     class v_const_iterator : public vcl_iterator<vcl_forward_iterator_tag,imesh_half_edge>
00285     {
00286         friend class v_iterator;
00287         friend class f_const_iterator;
00288       public:
00289         //: Constructor
00290         v_const_iterator(unsigned int hei, const imesh_half_edge_set& edge_set)
00291           :half_edge_index_(hei), edge_set_(edge_set) {}
00292 
00293         //: Constructor from non-const iterator
00294         v_const_iterator(const v_iterator& other)
00295           :half_edge_index_(other.half_edge_index_), edge_set_(other.edge_set_) {}
00296 
00297         //: Constructor from face iterator
00298         explicit v_const_iterator(const f_const_iterator& other)
00299           :half_edge_index_(other.half_edge_index_), edge_set_(other.edge_set_) {}
00300 
00301         //: Assignment
00302         v_const_iterator& operator = (const v_const_iterator& other)
00303         {
00304           if (this != &other){
00305             assert(&edge_set_ == &other.edge_set_);
00306             half_edge_index_ = other.half_edge_index_;
00307           }
00308           return *this;
00309         }
00310 
00311         const imesh_half_edge & operator*() const { return edge_set_[half_edge_index_]; }
00312         const imesh_half_edge * operator->() const { return &**this; }
00313         const imesh_half_edge & pair() const { return edge_set_[half_edge_index_^1]; }
00314         v_const_iterator & operator++ () // pre-inc
00315         {
00316           half_edge_index_ = half_edge_index_ ^ 1; // pair index
00317           half_edge_index_ = edge_set_[half_edge_index_].next_index();
00318           return *this;
00319         }
00320         v_const_iterator operator++(int) // post-inc
00321         {
00322           v_const_iterator old = *this;
00323           ++*this;
00324           return old;
00325         }
00326 
00327         bool operator == (const v_const_iterator& other) const
00328         {
00329           return this->half_edge_index_ == other.half_edge_index_ &&
00330                 &(this->edge_set_) == &(other.edge_set_);
00331         }
00332 
00333         bool operator != (const v_const_iterator& other) const
00334         {
00335           return !(*this == other);
00336         }
00337 
00338       private:
00339         unsigned int half_edge_index_;
00340         const imesh_half_edge_set& edge_set_;
00341     };
00342 
00343     //: Access a face iterator for face \param f
00344     f_const_iterator face_begin(unsigned int f) const { return f_const_iterator(face_to_he_[f],*this); }
00345     f_iterator face_begin(unsigned int f) { return f_iterator(face_to_he_[f],*this); }
00346 
00347     //: Access a vertex iterator for vertex \param v
00348     v_const_iterator vertex_begin(unsigned int v) const { return v_const_iterator(vert_to_he_[v],*this); }
00349     v_iterator vertex_begin(unsigned int v) { return v_iterator(vert_to_he_[v],*this); }
00350 
00351     //: Count the number of vertices pointed to by these edges
00352     unsigned int num_verts() const;
00353 
00354     //: Count the number of faces pointed to by these edges
00355     unsigned int num_faces() const;
00356 
00357   private:
00358     vcl_vector<imesh_half_edge> half_edges_;
00359     vcl_vector<unsigned int> vert_to_he_;
00360     vcl_vector<unsigned int> face_to_he_;
00361 };
00362 
00363 
00364 #endif // imesh_half_edge_h_