Go to the documentation of this file.00001
00002 #ifndef imesh_half_edge_h_
00003 #define imesh_half_edge_h_
00004
00005
00006
00007
00008
00009
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
00025 unsigned int next_index() const { return next_; }
00026
00027 unsigned int pair_index() const { return edge_^1; }
00028
00029
00030 unsigned int edge_index() const { return edge_>>1; }
00031
00032 unsigned int half_edge_index() const { return edge_; }
00033
00034
00035 unsigned int vert_index() const { return vert_; }
00036
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
00051 class imesh_half_edge_set
00052 {
00053 public:
00054
00055 imesh_half_edge_set() {}
00056
00057 imesh_half_edge_set(const vcl_vector<vcl_vector<unsigned int> >& face_list);
00058
00059
00060 void build_from_ifs(const vcl_vector<vcl_vector<unsigned int> >& face_list);
00061
00062
00063 const imesh_half_edge& operator [] (unsigned int i) const { return half_edges_[i]; }
00064
00065 imesh_half_edge& operator [] (unsigned int i) { return half_edges_[i]; }
00066
00067
00068 unsigned int size() const { return half_edges_.size(); }
00069
00070
00071 void clear()
00072 {
00073 half_edges_.clear();
00074 vert_to_he_.clear();
00075 face_to_he_.clear();
00076 }
00077
00078
00079 class f_iterator;
00080 class f_const_iterator;
00081 class v_iterator;
00082 class v_const_iterator;
00083
00084
00085
00086
00087
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
00094 f_iterator(unsigned int hei, imesh_half_edge_set& edge_set)
00095 :half_edge_index_(hei), edge_set_(edge_set) {}
00096
00097
00098 explicit f_iterator(const v_iterator& other)
00099 :half_edge_index_(other.half_edge_index_), edge_set_(other.edge_set_) {}
00100
00101
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++ ()
00115 {
00116 half_edge_index_ = edge_set_[half_edge_index_].next_index();
00117 return *this;
00118 }
00119 f_iterator operator++(int)
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
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
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
00164 f_const_iterator(const f_iterator& other)
00165 :half_edge_index_(other.half_edge_index_), edge_set_(other.edge_set_) {}
00166
00167
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
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++ ()
00185 {
00186 half_edge_index_ = edge_set_[half_edge_index_].next_index();
00187 return *this;
00188 }
00189 f_const_iterator operator++(int)
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
00215
00216
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
00223 v_iterator(unsigned int hei, imesh_half_edge_set& edge_set)
00224 :half_edge_index_(hei), edge_set_(edge_set) {}
00225
00226
00227 explicit v_iterator(const f_iterator& other)
00228 :half_edge_index_(other.half_edge_index_), edge_set_(other.edge_set_) {}
00229
00230
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++ ()
00244 {
00245 half_edge_index_ = half_edge_index_ ^ 1;
00246 half_edge_index_ = edge_set_[half_edge_index_].next_index();
00247 return *this;
00248 }
00249 v_iterator operator++(int)
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
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
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
00294 v_const_iterator(const v_iterator& other)
00295 :half_edge_index_(other.half_edge_index_), edge_set_(other.edge_set_) {}
00296
00297
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
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++ ()
00315 {
00316 half_edge_index_ = half_edge_index_ ^ 1;
00317 half_edge_index_ = edge_set_[half_edge_index_].next_index();
00318 return *this;
00319 }
00320 v_const_iterator operator++(int)
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
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
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
00352 unsigned int num_verts() const;
00353
00354
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_