cellcomplex_C.h

Go to the documentation of this file.
00001 
00008 #include "cellcomplex.h"
00009 #include "cell.h"
00010 
00011 //using std::make_pair;
00012 using namespace std;
00013 
00014 
00016 template<class Vertex,class Edge,class Face,class Tuple>
00017 CellComplex<Vertex,Edge,Face,Tuple>::CellComplex(PersistantStore& store) 
00018 : vertexs(store), edges(store), faces(store)
00019 , trash_(store), keep_trash_(false), pool_(store)
00020 , switch0(store), switch1(store), switch2(store), inverted_faces(store)
00021 {
00022 }
00023 
00030 template<class Vertex,class Edge,class Face,class Tuple>
00031 CellComplex<Vertex,Edge,Face,Tuple>::~CellComplex()
00032 {
00033   /* All the Persistant* data structures deallocate their interiors on their
00034    * own; the pool also deallocates all the cells. */
00035 }
00036 
00040 template<class Vertex,class Edge,class Face,class Tuple>
00041 PersistantStore& 
00042 CellComplex<Vertex,Edge,Face,Tuple>::get_store() const
00043 {
00044   return vertexs.get_store();
00045 }
00046 
00047 
00088 template<class Vertex,class Edge,class Face,class Tuple>
00089 Tuple CellComplex<Vertex,Edge,Face,Tuple>::Switch(int snum,const Tuple& ct)
00090     const
00091 {
00092     Tuple new_ct(ct);
00093     switch(snum){
00094         case 0:
00095           {
00096             typename Switch0_Hash_T::const_iterator it =
00097               switch0.find(make_pair(ct.v,ct.e));
00098         if (it == switch0.end())
00099           {
00100         cout << "[cellcomplex.C] Fell off the end of switch 0 hash"<<endl;
00101         cout << "Looking for ctv = "<<*ct.v<<endl;
00102         cout << "Looking for cte = "<<*ct.e<<endl;
00103         assert(it != switch0.end());
00104           }
00105             new_ct.v = (*it).second;
00106             break;
00107           }
00108         case 1:
00109           {
00110             typename Switch1_Hash_T::const_iterator it = switch1.find(ct);
00111             assert(it != switch1.end());
00112             new_ct.e = (*it).second;
00113             break;
00114           }
00115         case 2:
00116           {
00117             typename Switch2_Hash_T::const_iterator it =
00118               switch2.find(make_pair(ct.e,ct.f));
00119             assert(it != switch2.end());
00120             new_ct.f = (*it).second;
00121             break;
00122           }
00123         default:
00124             assert(0);
00125             break;
00126     }
00127     return new_ct;
00128 }
00129 
00138 template<class Vertex,class Edge,class Face,class Tuple>
00139 void CellComplex<Vertex,Edge,Face,Tuple>::add_vertex(Vertex *v)
00140 {
00141 #ifdef DEBUG
00142     if( !v ) FATAL_ERROR("CellComplex::add_vertex -- vertex is NULL");
00143     if( is_member(v) ) FATAL_ERROR("CellComplex::add_vertex --- vertex is already in Complex");
00144 #endif
00145 
00146     pool_.mark_allocated(v);
00147     vertexs.insert(v);
00148 }
00149 
00161 template<class Vertex,class Edge,class Face,class Tuple>
00162 void CellComplex<Vertex,Edge,Face,Tuple>::add_edge(Edge *e)
00163 {
00164   Vertex *v1 = e->get_vertex(0);
00165   Vertex *v2 = e->get_vertex(1);
00166 
00167   /* Run standard checks */
00168   assert(e);
00169   assert(is_member(v1));
00170   assert(is_member(v2));
00171   assert(!is_member(e));
00172 
00173   // update vertex's edge list
00174   v1->add_edge(e);
00175   if (v1 != v2) {
00176     v2->add_edge(e);
00177   }
00178 
00179     //update switch0's
00180     switch0[make_pair(v1,e)]=v2;
00181     switch0[make_pair(v2,e)]=v1;
00182 
00183     pool_.mark_allocated(e);
00184     edges.insert(e);
00185 }
00186 
00204 template<class Vertex,class Edge,class Face,class Tuple>
00205 void CellComplex<Vertex,Edge,Face,Tuple>::add_face(Face *f,Edge **es,int num_es,bool inverse_handed)
00206 {
00207     int i,j;
00208 #ifdef DEBUG
00209     /* Run standard error checks */
00210     if(!f) FATAL_ERROR("CellComplex::add_face --- face is NULL");
00211     if(is_member(f)) FATAL_ERROR("CellComplex::add_face --- face is already in Complex");
00212     for(i=0; i < num_es; i++){
00213         if( !es[i]) FATAL_ERROR("CellComplex::add_face --- given edge is NULL");
00214         if( !is_member(es[i]) ) FATAL_ERROR("CellComplex::add_face --- given edge is not in Complex");
00215     }
00216 #endif
00217 
00218     //update face's edge list, and edge's face list
00219     for(i=0;i<num_es;i++){
00220         f->add_edge(es[i]);
00221         es[i]->add_face(f);
00222     }
00223 
00224     // update switch 2's
00225     for(int i = 0; i < num_es; i++) {
00226       Edge *e = es[i];
00227       if (e->num_faces() == 1) {
00228         Face *ef = e->get_any_face();
00229         switch2[make_pair(e,ef)] = ef;
00230       } else {
00231         assert(e->num_faces() == 2);
00232     typename Edge::face_iterator it = e->begin_faces();
00233     Face *f1 = *it;
00234     Face *f2 = *(++it);
00235         switch2[make_pair(es[i],f1)] = f2;
00236         switch2[make_pair(es[i],f2)] = f1;
00237       }
00238     }
00239 
00240     //update switch 1's
00241     //invariant that only two of the es[i] share each vertex
00242     //through each iteration es[i] will share v0 with v0_edge and v1 with v1_edge
00243     Tuple tup(NULL,NULL,f);
00244     Vertex *v0,*v1;
00245     Edge *v0_edge, *v1_edge;
00246 
00247     //check for self loop
00248     if(num_es==1){
00249         tup.e = es[0];
00250         tup.v = es[0]->get_vertex(0);
00251         switch1[tup] = es[0];
00252         tup.v = es[0]->get_vertex(1);
00253         switch1[tup] = es[0];
00254     }
00255     // otherwise we have more than one edge
00256     else{
00257         /* foreach edge e,
00258          *  foreach vertex v of the edge,
00259          *  find the other edge e' that shares v
00260          *  set up the switch from (v,e) to e'
00261          * since we do this for every edge, the reverse switch will be
00262          * set up eventually.
00263          */
00264         for(i=0;i<num_es;i++){
00265             tup.e = es[i];
00266             v0 = es[i]->get_vertex(0);
00267             v1 = es[i]->get_vertex(1);
00268             v0_edge = NULL;
00269             v1_edge = NULL;
00270             for(j=0; j < num_es; j++){
00271                 if(i != j){
00272                     if(es[j]->get_vertex(0)==v0 || es[j]->get_vertex(1)==v0) v0_edge=es[j];
00273                     if(es[j]->get_vertex(0)==v1 || es[j]->get_vertex(1)==v1) v1_edge=es[j];
00274                 }
00275             }
00276             if(v0_edge==NULL || v1_edge==NULL) FATAL_ERROR("CellComplex::add_face --- edge set for face is not closed");
00277             tup.v=v0;
00278             switch1[tup]=v0_edge;
00279             tup.v=v1;
00280             switch1[tup]=v1_edge;
00281         }
00282     }
00283 
00284     if( inverse_handed ) inverted_faces.insert(f);
00285 
00286     pool_.mark_allocated(f);
00287     faces.insert(f);
00288 }
00289 
00298 template<class Vertex,class Edge,class Face,class Tuple>
00299 void CellComplex<Vertex,Edge,Face,Tuple>::delete_vertex(Vertex *v)
00300 {
00301     if( !v ) return;
00302     if( !is_member(v) ) FATAL_ERROR("CellComplex::delete_vertex --- vertex is not a member of Complex");
00303 
00304     // delete edges with v as a vertex (they will themselves delete the faces)
00305     while(v->num_edges() > 0) {
00306       Edge *e = v->get_any_edge();
00307       delete_edge(e); // this will remove e from v also, hence the strange loop
00308     }
00309     vertexs.erase(v);
00310 
00311     trash_cell(v);
00312 }
00313 
00321 template<class Vertex,class Edge,class Face,class Tuple>
00322 void CellComplex<Vertex,Edge,Face,Tuple>::delete_edge(Edge *e)
00323 {
00324     if(!e) return;
00325     if( !is_member(e) ) FATAL_ERROR("CellComplex::delete_edge --- edge is not a member of Complex");
00326 
00327     Vertex *v0,*v1;
00328     v0 = e->get_vertex(0);
00329     v1 = e->get_vertex(1);
00330 
00331     // delete faces that have e as an edge; this changes faces_, hence the
00332     // strange loop
00333     while(e->num_faces() > 0) {
00334       delete_face(e->get_any_face());
00335     }
00336 
00337     //remove e from the list of uppers of its vertexes
00338     v0->delete_edge(e);
00339     v1->delete_edge(e);
00340 
00341     // remove switch 0's; higher switches were owned by the faces, which have
00342     // already been deleted
00343     switch0.erase(make_pair(v0,e));
00344     switch0.erase(make_pair(v1,e));
00345 
00346     //remove edge from complex
00347     edges.erase(e);
00348 
00349     trash_cell(e);
00350 }
00351 
00359 template<class Vertex,class Edge,class Face,class Tuple>
00360 void CellComplex<Vertex,Edge,Face,Tuple>::delete_face(Face *f)
00361 {
00362     if(!f) return;
00363     if( !is_member(f) ) FATAL_ERROR("CellComplex::delete_face --- face is not a member of Complex");
00364 
00365     Vertex *v0,*v1;
00366     Tuple tup(0,0,f);
00367 
00368     for(typename Face::edge_iterator it = f->begin_edges();
00369         it != f->end_edges(); ++it) {
00370         Edge *e = *it;
00371 
00372         //remove f from its edge's face list
00373         e->delete_face(f);
00374 
00375         // remove switch2 out of this face;
00376         // make switch2 into this face be a self-loop (if there are any
00377         // edges left around the edge)
00378         switch2.erase(make_pair(e,f));
00379         switch(e->num_faces()) {
00380           case 0:
00381             break;
00382           case 1:
00383             switch2[make_pair(e,e->get_any_face())] = e->get_any_face();
00384             break;
00385           default:
00386             assert(e->num_faces() == 0 || e->num_faces() == 1);
00387             break;
00388         }
00389 
00390         // remove switch1 out of this edge (the reverse direction will be
00391         // removed by the corresponding edge in another iteration of this loop)
00392         v0 = e->get_vertex(0);
00393         v1 = e->get_vertex(1);
00394         tup.e = e;
00395         tup.v = v0;
00396         switch1.erase(tup);
00397         tup.v = v1;
00398         switch1.erase(tup);
00399 
00400         // switch0 doesn't deal with faces
00401     }
00402 
00403     //remove f from inverted_faces
00404     inverted_faces.erase(f);
00405 
00406     //remove f from complex
00407     faces.erase(f);
00408 
00409     trash_cell(f);
00410 }
00411 
00413 template<class Vertex,class Edge,class Face,class Tuple>
00414 void CellComplex<Vertex,Edge,Face,Tuple>::trash_cell(Cell *c)
00415 {
00416   if (keep_trash_ > 0) {
00417     bool found;
00418     found = trash_.insert(c).second;
00419     assert(found);
00420   } else {
00421     pool_.mark_deleted(c);
00422   }
00423 }
00424 
00429 template<class Vertex,class Edge,class Face,class Tuple>
00430 void CellComplex<Vertex,Edge,Face,Tuple>::keep_trash()
00431 {
00432   keep_trash_++;
00433 }
00434 
00441 template<class Vertex,class Edge,class Face,class Tuple>
00442 void CellComplex<Vertex,Edge,Face,Tuple>::empty_trash()
00443 {
00444   assert(keep_trash_ > 0);
00445   keep_trash_--;
00446   if (keep_trash_ == 0) {
00447     for(typename Trash_T::iterator it = trash_.begin();
00448         it != trash_.end(); ++it) {
00449       pool_.mark_deleted(*it);
00450     }
00451     trash_.clear();
00452   }
00453 }
00454 
00456 template<class Vertex,class Edge,class Face,class Tuple>
00457 bool CellComplex<Vertex,Edge,Face,Tuple>::is_member(Vertex *v) const
00458 {
00459     //return ids.find(v->id) != ids.end();
00460     return vertexs.find(v) != vertexs.end();
00461 }
00462 
00464 template<class Vertex,class Edge,class Face,class Tuple>
00465 bool CellComplex<Vertex,Edge,Face,Tuple>::is_member(Edge *e) const
00466 {
00467     //return ids.find(e->id) != ids.end();
00468     return edges.find(e) != edges.end();
00469 }
00470 
00472 template<class Vertex,class Edge,class Face,class Tuple>
00473 bool CellComplex<Vertex,Edge,Face,Tuple>::is_member(Face *f) const
00474 {
00475     //return ids.find(f->id) != ids.end();
00476     return faces.find(f) != faces.end();
00477 }
00478 
00480 template<class Vertex,class Edge,class Face,class Tuple>
00481 bool CellComplex<Vertex,Edge,Face,Tuple>::is_inverse_handed(Face *f) const
00482 {
00483     return ( inverted_faces.count(f) != 0 );
00484 }
00485 
00486 
00487 
00488 
00489 /***************************************************************************
00490   Size of switch hashes, for debugging.
00491  ***************************************************************************/
00492 template<class Vertex,class Edge,class Face,class Tuple>
00493 int CellComplex<Vertex,Edge,Face,Tuple>::switch_size(int d) const
00494 {
00495   switch(d) {
00496     case 0: return switch0.size();
00497     case 1: return switch1.size();
00498     case 2: return switch2.size();
00499     default: assert(0); return 0;
00500   }
00501 }
00502 
00511 template<class Vertex,class Edge,class Face,class Tuple>
00512 int CellComplex<Vertex,Edge,Face,Tuple>::lower(Edge *e, std::vector<Vertex*> &vs)
00513 {
00514     vs.push_back(e->get_vertex(0));
00515     vs.push_back(e->get_vertex(1));
00516     return 2;
00517 }
00518 
00527 template<class Vertex,class Edge,class Face,class Tuple>
00528 int CellComplex<Vertex,Edge,Face,Tuple>::lower(Edge *e, std::list<Vertex*> &vs)
00529 {
00530     vs.push_back(e->get_vertex(0));
00531     vs.push_back(e->get_vertex(1));
00532     return 2;
00533 }
00534 
00543 template<class Vertex,class Edge,class Face,class Tuple>
00544 int CellComplex<Vertex,Edge,Face,Tuple>::lower(Face *f, std::vector<Edge*> &es)
00545 {
00546     if(!f) return -1;
00547     for(typename Face::edge_iterator it = f->begin_edges();
00548         it != f->end_edges(); ++it) {
00549       es.push_back(*it);
00550     }
00551     return f->num_edges();
00552 }
00553 
00562 template<class Vertex,class Edge,class Face,class Tuple>
00563 int CellComplex<Vertex,Edge,Face,Tuple>::lower(Face *f, std::list<Edge*> &es)
00564 {
00565     if(!f) return -1;
00566     for(typename Face::edge_iterator it = f->begin_edges();
00567         it != f->end_edges(); ++it) {
00568       es.push_back(*it);
00569     }
00570     return f->num_edges();
00571 }
00572 
00581 template<class Vertex,class Edge,class Face,class Tuple>
00582 int CellComplex<Vertex,Edge,Face,Tuple>::upper(Vertex *v, std::vector<Edge*> &es)
00583 {
00584   if(!v) return -1;
00585   copy(v->begin_edges(), v->end_edges(), std::back_inserter(es));
00586   return v->num_edges();
00587 }
00588 
00597 template<class Vertex,class Edge,class Face,class Tuple>
00598 int CellComplex<Vertex,Edge,Face,Tuple>::upper(Vertex *v, std::list<Edge*> &es)
00599 {
00600   if(!v) return -1;
00601   copy(v->begin_edges(), v->end_edges(), std::back_inserter(es));
00602   return v->num_edges();
00603 }
00604 
00614 template<class Vertex,class Edge,class Face,class Tuple>
00615 int CellComplex<Vertex,Edge,Face,Tuple>::upper(Edge *e, std::vector<Face*> &fs)
00616 {
00617     int n=0;
00618     assert(e);
00619     for(typename Edge::face_iterator it = e->begin_faces();
00620         it != e->end_faces(); ++it) {
00621         Face *f= *it;
00622         if(f){
00623             fs.push_back(f);
00624             n++;
00625         }
00626     }
00627     return n;
00628 }
00629 
00639 template<class Vertex,class Edge,class Face,class Tuple>
00640 int CellComplex<Vertex,Edge,Face,Tuple>::upper(Edge *e, std::list<Face*> &fs)
00641 {
00642     int n=0;
00643     assert(e);
00644     for(typename Edge::face_iterator it = e->begin_faces();
00645         it != e->end_faces(); ++it) {
00646         Face *f= *it;
00647         if(f){
00648             fs.push_back(f);
00649             n++;
00650         }
00651     }
00652     return n;
00653 }
00654 
00664 template<class Vertex,class Edge,class Face,class Tuple>
00665 Vertex* CellComplex<Vertex,Edge,Face,Tuple>::get_opposite_vertex(Edge *e, Vertex *v)
00666 {
00667     Vertex *v0 = e->get_vertex(0);
00668     if( v == v0) v0 = e->get_vertex(1);
00669     return v0;
00670 }
00671 
00681 template<class Vertex,class Edge,class Face,class Tuple>
00682 Face* CellComplex<Vertex,Edge,Face,Tuple>::get_opposite_face(Edge *e, Face *f)
00683 {
00684 #ifdef DEBUG
00685     if( !f->has_edge(e) ) FATAL_ERROR( "CellComplex::get_opposite_face --- e is not an edge of f" );
00686 #endif
00687     typename Edge::face_iterator it = find_if(e->begin_faces(), e->end_faces(),
00688         std::bind2nd(std::not_equal_to<Face*>(),f));
00689     if (it == e->end_faces()) {
00690       return NULL;
00691     } else {
00692       return *it;
00693     }
00694 }
00695 
00706 template<class Vertex,class Edge,class Face,class Tuple>
00707 void CellComplex<Vertex,Edge,Face,Tuple>::enqueue_edges(Vertex *v, std::deque<Edge*> &edges)
00708 {
00709   copy(v->begin_edges(), v->end_edges(), std::back_inserter(edges));
00710 }
00711 
00721 template<class Vertex,class Edge,class Face,class Tuple>
00722 void CellComplex<Vertex,Edge,Face,Tuple>::enqueue_faces(Vertex *v, std::deque<Face*> &faces)
00723 {
00724     assert(v);
00725     std::list<Face*> temp;
00726     for(typename Vertex::edge_iterator it = v->begin_edges();
00727         it != v->end_edges(); ++it) {
00728         Edge *e = *it;
00729         for(typename Edge::face_iterator it = e->begin_faces();
00730             it != e->end_faces(); ++it) {
00731             Face *f = *it;
00732             if(f) temp.push_back(f);
00733         }
00734     }
00735     temp.unique();
00736     copy(temp.begin(), temp.end(), back_inserter(faces));
00737 }
00738 
00739 
00746 template<class Vertex,class Edge,class Face,class Tuple>
00747 Edge* CellComplex<Vertex,Edge,Face,Tuple>::find_common_edge(Vertex *v0, Vertex *v1)
00748 {
00749     for(typename Vertex::edge_iterator it = v0->begin_edges();
00750         it != v0->end_edges(); ++it) {
00751         Edge *e = *it;
00752         if((e->get_vertex(0) == v1) || (e->get_vertex(1) == v1)) return e;
00753     }
00754     return NULL;
00755 }
00756 
00763 template<class Vertex,class Edge,class Face,class Tuple>
00764 Edge* CellComplex<Vertex,Edge,Face,Tuple>::find_common_edge(Face *f0, Face *f1)
00765 {
00766     for(typename Face::edge_iterator it = f0->begin_edges();
00767         it != f0->end_edges(); ++it) {
00768         Edge *e = *it;
00769         if(e->has_face(f1)) return e;
00770     }
00771     return NULL;
00772 }
00773 
00782 template<class Vertex,class Edge,class Face,class Tuple>
00783 void CellComplex<Vertex,Edge,Face,Tuple>::find_adjacent_faces(Face *f, std::list<Face*> &faces)
00784 {
00785     for(typename Face::edge_iterator it = f->begin_edges();
00786         it != f->end_edges(); ++it) {
00787         Edge *e = *it;
00788         Face *temp = get_opposite_face(e, f);
00789         if (temp) faces.push_back(temp);
00790     }
00791 }
00792 
00793 
00802 template<class Vertex,class Edge,class Face,class Tuple>
00803 void CellComplex<Vertex,Edge,Face,Tuple>::find_adjacent_faces(Face *f, std::deque<Face*> &faces)
00804 {
00805     for(typename Face::edge_iterator it = f->begin_edges();
00806         it != f->end_edges(); ++it) {
00807         Edge *e = *it;
00808         Face *temp = get_opposite_face(e, f);
00809         if (temp) faces.push_back(temp);
00810     }
00811 }
00812 
00826 template<class Vertex,class Edge,class Face,class Tuple>
00827 void CellComplex<Vertex,Edge,Face,Tuple>::find_adjacent_edges(Edge *e, std::list<Edge*> &edges)
00828 {
00829   assert(e);
00830   for(typename Edge::face_iterator it = e->begin_faces();
00831       it != e->end_faces(); ++it) {
00832     Face *f = *it;
00833     for(typename Face::edge_iterator it = f->begin_edges();
00834         it != f->end_edges(); ++it) {
00835       Edge *temp = *it;
00836       if(temp != e) edges.push_back(temp);
00837     }
00838   }
00839 }
00840 
00854 template<class Vertex,class Edge,class Face,class Tuple>
00855 void CellComplex<Vertex,Edge,Face,Tuple>::find_adjacent_edges(Edge *e, std::deque<Edge*> &edges)
00856 {
00857   assert(e);
00858   for(typename Edge::face_iterator it = e->begin_faces();
00859       it != e->end_faces(); ++it) {
00860     Face *f = *it;
00861     for(typename Face::edge_iterator it = f->begin_edges();
00862         it != f->end_edges(); ++it) {
00863       Edge *temp = *it;
00864       if(temp != e) edges.push_back(temp);
00865     }
00866   }
00867 }
00868 
00873 template<class Vertex,class Edge,class Face,class Tuple>
00874 Tuple CellComplex<Vertex,Edge,Face,Tuple>::get_tuple() const
00875 {
00876     return get_tuple( *faces.begin() );
00877 }
00878 
00884 template<class Vertex,class Edge,class Face,class Tuple>
00885 Tuple CellComplex<Vertex,Edge,Face,Tuple>::get_tuple(Face *f) const
00886 {
00887 #ifdef DEBUG
00888     if( !f ) FATAL_ERROR("CellComplex::get_tuple(f) --- face is NULL!");
00889 #endif
00890 
00891     Edge *e = f->get_canon_edge();
00892     Vertex *v = e->get_canon_vertex();
00893 
00894     Tuple ct(v,e,f);
00895     if (!is_inverse_handed(f)) return ct;
00896     else return Switch(0,ct);
00897 }
00898 
00905 template<class Vertex,class Edge,class Face,class Tuple>
00906 Tuple CellComplex<Vertex,Edge,Face,Tuple>::get_tuple(Edge *e, Face *f)
00907     const
00908 {
00909 #ifdef DEBUG
00910     if( !f ) FATAL_ERROR("CellComplex::get_tuple(e,f) --- face is NULL!");
00911     if( !e ) FATAL_ERROR("CellComplex::get_tuple(e,f) --- edge is NULL!");
00912     if( !f->has_edge(e) ) FATAL_ERROR("CellComplex::get_tuple(e,f) --- edge is not an edge of face");
00913 #endif
00914 
00915     Tuple tup;
00916     tup = get_tuple(f);
00917     while(e != tup.e) tup = Switch(1, Switch(0, tup) );
00918     return tup;
00919 }
00920 
00927 template<class Vertex,class Edge,class Face,class Tuple>
00928 Tuple CellComplex<Vertex,Edge,Face,Tuple>::get_tuple(Vertex *v, Face *f)
00929     const
00930 {
00931 #ifdef DEBUG
00932     if( !v ) FATAL_ERROR("CellComplex::get_tuple(v,f) --- vertex is NULL!");
00933     if( !f ) FATAL_ERROR("CellComplex::get_tuple(v,f) --- face is NULL!");
00934     if( !f->has_vertex(v) ) FATAL_ERROR("CellComplex::get_tuple(v,f) --- vertex is not a sub-simplex of face");
00935 #endif
00936 
00937     Tuple tup;
00938     tup = get_tuple(f);
00939     while(v != tup.v) tup = Switch(1,Switch(0,tup));
00940     return tup;
00941 }
00942 
00943 
00956 template<class Vertex, class Edge, class Face, class Tuple>
00957 Tuple CellComplex<Vertex,Edge,Face,Tuple>::get_tuple(Vertex *v, Edge *e)
00958      const
00959 {
00960   Tuple tup;
00961   Face *f = e->get_any_face();
00962   tup = get_tuple(e,f); // this is oriented by might not contain v
00963   if (tup.v != v) tup = Switch(2, Switch(0, tup));
00964   //If this was one sided, then switch 2 is fixed, and there is no oriented tuple
00965   assert((tup.v == v) && "Edge Vertex pair is on the boundary: No oriented tuple exists");
00966 
00967   return tup;
00968 }
00969 
00975 template<class Vertex,class Edge,class Face,class Tuple>
00976 Tuple CellComplex<Vertex,Edge,Face,Tuple>::get_tuple(Vertex *v)
00977     const
00978 {
00979 #ifdef DEBUG
00980     if( !v ) FATAL_ERROR("CellComplex::get_tuple(v) --- vertex is NULL!");
00981 #endif
00982 
00983     Edge *e = v->get_any_edge();
00984 
00985 #ifdef DEBUG
00986     if( !e ) FATAL_ERROR("CellComplex::get_tuple(v) --- vertex has no edges");
00987 #endif
00988 
00989     Face *f = e->get_any_face();
00990 
00991 #ifdef DEBUG
00992     if( !f ) FATAL_ERROR("CellComplex::get_tuple(v) --- edge 0 has no face");
00993 #endif
00994 
00995     return get_tuple(v,f);
00996 }
00997 
01003 template<class Vertex,class Edge,class Face,class Tuple>
01004 Tuple CellComplex<Vertex,Edge,Face,Tuple>::get_tuple(Edge* e)
01005     const
01006 {
01007 #ifdef DEBUG
01008   if( !e ) FATAL_ERROR("CellComplex::get_tuple(e) --- edge is NULL!");
01009 #endif
01010   
01011   Face *f = e->get_any_face();
01012   
01013   return get_tuple(e,f);
01014 }
01015 
01018 template<class Vertex,class Edge,class Face,class Tuple>
01019 void CellComplex<Vertex,Edge,Face,Tuple>::print(std::ostream& os) const
01020 {
01021     //this will be improved later
01022     os  << "CellComplex:= { num_vertexs=" << get_num_vertices()
01023         << ", num_edges=" << get_num_edges()
01024         << ", num_faces=" << get_num_faces()
01025         << " }\n";
01026     typename Vertex_Hash_T::const_iterator i;
01027     typename Edge_Hash_T::const_iterator j;
01028     typename Face_Hash_T::const_iterator k;
01029 
01030     os << "---------------------Vertices------------------\n";
01031     for(i=vertexs.begin();i!=vertexs.end(); ++i) { os << (*i); }
01032     os << "----------------------Edges--------------------\n";
01033     for(j=edges.begin();j!=edges.end(); ++j) { os << (*j); }
01034     os << "----------------------Faces--------------------\n";
01035     for(k=faces.begin();k!=faces.end(); ++k) { os << (*k); }
01036 }
01037 
01039 template<class Vertex,class Edge,class Face,class Tuple>
01040 void CellComplex<Vertex,Edge,Face,Tuple>::print_statistics(std::ostream& os)
01041     const
01042 {
01043     os  <<"#######################CELL COMPLEX##############################\n"
01044         << "Vertices: " << get_num_vertices() << std::endl
01045         << "Edges:    " << get_num_edges()    << std::endl
01046         << "Faces:    " << get_num_faces()    << std::endl
01047         << "Inverted Faces: " << inverted_faces.size() << std::endl
01048         << "Switch0 size: " << switch0.size() << std::endl
01049         << "Switch1 size: " << switch1.size() << std::endl
01050         << "Switch2 size: " << switch2.size() << std::endl
01051         << "##############################################################\n\n";
01052 }
01053 
01054 
01055 /* From here down are wrappers for ruby */
01056 
01057 template<class Vertex,class Edge,class Face,class Tuple>
01058 typename CellComplex<Vertex,Edge,Face,Tuple>::Vertex_Hash_T::iterator
01059 CellComplex<Vertex,Edge,Face,Tuple>::get_vertexs_begin() const
01060 {
01061     return vertexs.begin();
01062 }
01063 
01064 template<class Vertex,class Edge,class Face,class Tuple>
01065 typename CellComplex<Vertex,Edge,Face,Tuple>::Vertex_Hash_T::iterator
01066 CellComplex<Vertex,Edge,Face,Tuple>::get_vertexs_end() const
01067 {
01068     return vertexs.end();
01069 }
01070 
01071 template<class Vertex,class Edge,class Face,class Tuple>
01072 typename CellComplex<Vertex,Edge,Face,Tuple>::Edge_Hash_T::iterator
01073 CellComplex<Vertex,Edge,Face,Tuple>::get_edges_begin() const
01074 {
01075     return edges.begin();
01076 }
01077 
01078 template<class Vertex,class Edge,class Face,class Tuple>
01079 typename CellComplex<Vertex,Edge,Face,Tuple>::Edge_Hash_T::iterator
01080 CellComplex<Vertex,Edge,Face,Tuple>::get_edges_end() const
01081 {
01082     return edges.end();
01083 }
01084 
01085 template<class Vertex,class Edge,class Face,class Tuple>
01086 typename CellComplex<Vertex,Edge,Face,Tuple>::Face_Hash_T::iterator
01087 CellComplex<Vertex,Edge,Face,Tuple>::get_faces_begin() const
01088 {
01089     return faces.begin();
01090 }
01091 
01092 template<class Vertex,class Edge,class Face,class Tuple>
01093 typename CellComplex<Vertex,Edge,Face,Tuple>::Face_Hash_T::iterator
01094 CellComplex<Vertex,Edge,Face,Tuple>::get_faces_end() const
01095 {
01096     return faces.end();
01097 }
01098 
01099 template<class Vertex,class Edge,class Face,class Tuple>
01100 Vertex *
01101 CellComplex<Vertex,Edge,Face,Tuple>::get_next_vertex(typename CellComplex<Vertex,Edge,Face,Tuple>::Vertex_Hash_T::iterator &it) const
01102 {
01103   if(it == get_vertices_end()) {
01104     return NULL;
01105   }
01106   Vertex *v = *it;
01107   ++it;
01108   return v;
01109 }
01110 
01111 template<class Vertex,class Edge,class Face,class Tuple>
01112 Edge *
01113 CellComplex<Vertex,Edge,Face,Tuple>::get_next_edge(typename CellComplex<Vertex,Edge,Face,Tuple>::Edge_Hash_T::iterator &it) const
01114 {
01115   if(it == get_edges_end()) {
01116     return NULL;
01117   }
01118   Edge *e = *it;
01119   ++it;
01120   return e;
01121 }
01122 
01123 template<class Vertex,class Edge,class Face,class Tuple>
01124 Face *
01125 CellComplex<Vertex,Edge,Face,Tuple>::get_next_face(typename CellComplex<Vertex,Edge,Face,Tuple>::Face_Hash_T::iterator &it) const
01126 {
01127   if(it == get_faces_end()) {
01128     return NULL;
01129   }
01130   Face *f = *it;
01131   ++it;
01132   return f;
01133 }

Generated on Mon May 24 09:53:30 2010 for TUMBLE by  doxygen 1.5.2