contrib/brl/bbas/imesh/imesh_half_edge.cxx
Go to the documentation of this file.
00001 // This is brl/bbas/imesh/imesh_half_edge.cxx
00002 #include "imesh_half_edge.h"
00003 //:
00004 // \file
00005 
00006 #include <vcl_map.h>
00007 #include <vcl_utility.h>
00008 #include <vcl_cassert.h>
00009 
00010 
00011 //: Construct from a face index list
00012 imesh_half_edge_set::imesh_half_edge_set(const vcl_vector<vcl_vector<unsigned int> >& face_list)
00013 {
00014   build_from_ifs(face_list);
00015 }
00016 
00017 
00018 //: Build the half edges from an indexed face set
00019 void
00020 imesh_half_edge_set::build_from_ifs(const vcl_vector<vcl_vector<unsigned int> >& face_list)
00021 {
00022   half_edges_.clear();
00023   typedef vcl_pair<unsigned int, unsigned int> vert_pair;
00024   vcl_map<vert_pair, unsigned int> edge_map;
00025 
00026   face_to_he_.resize(face_list.size(), imesh_invalid_idx);
00027 
00028   unsigned int max_v = 0;
00029 
00030   const unsigned int num_faces = face_list.size();
00031   for (unsigned int f=0; f<num_faces; ++f) {
00032     const vcl_vector<unsigned int>& verts = face_list[f];
00033     const unsigned int num_verts = verts.size();
00034     unsigned int first_e = imesh_invalid_idx; // first edge index
00035     unsigned int prev_e = imesh_invalid_idx; // previous edge index
00036     for (unsigned int i=0; i<num_verts; ++i) {
00037       const unsigned int& v = verts[i];
00038       if (v > max_v) max_v = v;
00039       unsigned int ni = (i+1)%num_verts;
00040       const unsigned int& nv = verts[ni];
00041 
00042       vert_pair vp(v,nv);
00043       if (v > nv) vp = vert_pair(nv,v);
00044       vcl_map<vert_pair, unsigned int>::iterator m = edge_map.find(vp);
00045       unsigned int curr_e;
00046       if (m == edge_map.end()) {
00047         curr_e = half_edges_.size();
00048         edge_map.insert(vcl_pair<vert_pair,unsigned int>(vp,curr_e));
00049         half_edges_.push_back(imesh_half_edge(curr_e,imesh_invalid_idx,v,f));
00050         half_edges_.push_back(imesh_half_edge(curr_e+1,imesh_invalid_idx,nv,imesh_invalid_idx));
00051       }
00052       else {
00053         curr_e = m->second+1;
00054         assert(half_edges_[curr_e].next_index() == imesh_invalid_idx);
00055         assert(half_edges_[curr_e].vert_index() == v);
00056         half_edges_[curr_e].face_ = f;
00057       }
00058       if (first_e == imesh_invalid_idx)
00059         first_e = curr_e;
00060       if (prev_e != imesh_invalid_idx)
00061         half_edges_[prev_e].next_ = curr_e;
00062       prev_e = curr_e;
00063     }
00064     if (prev_e != imesh_invalid_idx)
00065       half_edges_[prev_e].next_ = first_e;
00066     face_to_he_[f] = first_e;
00067   }
00068 
00069   vert_to_he_.resize(max_v+1, imesh_invalid_idx);
00070 
00071   // create half edges for boundaries
00072   for (unsigned int i=0; i<half_edges_.size(); ++i) {
00073     imesh_half_edge& he = half_edges_[i];
00074     if (i < vert_to_he_[he.vert_index()])
00075       vert_to_he_[he.vert_index()] = i;
00076     if (he.next_index() != imesh_invalid_idx)
00077       continue;
00078     unsigned int next_b = half_edges_[i].pair_index();
00079     while(half_edges_[next_b].face_index() != imesh_invalid_idx)
00080     {
00081       f_iterator fi(next_b,*this);
00082       while (fi->next_index() != next_b)
00083         ++fi;
00084       next_b = fi->pair_index();
00085     }
00086     he.next_ = next_b;
00087   }
00088 }
00089 
00090 
00091 //: Count the number of vertices pointed to by these edges
00092 unsigned int
00093 imesh_half_edge_set::num_verts() const
00094 {
00095   unsigned int count = 0;
00096   for (unsigned int i=0; i<vert_to_he_.size(); ++i)
00097     if (vert_to_he_[i] != imesh_invalid_idx)
00098       ++count;
00099   return count;
00100 }
00101 
00102 
00103 //: Count the number of faces pointed to by these edges
00104 unsigned int
00105 imesh_half_edge_set::num_faces() const
00106 {
00107   unsigned int count = 0;
00108   for (unsigned int i=0; i<face_to_he_.size(); ++i)
00109     if (face_to_he_[i] != imesh_invalid_idx)
00110       ++count;
00111   return count;
00112 }