contrib/gel/vtol/vtol_two_chain.cxx
Go to the documentation of this file.
00001 // This is gel/vtol/vtol_two_chain.cxx
00002 #include "vtol_two_chain.h"
00003 //:
00004 // \file
00005 // \verbatim
00006 //  Modifications
00007 //   05/13/98  RIH replaced append by insert_after to avoid n^2 behavior
00008 // \endverbatim
00009 
00010 #include <vcl_vector.h>
00011 #include <vcl_algorithm.h>
00012 
00013 #include <vtol/vtol_list_functions.h>
00014 #include <vtol/vtol_face.h>
00015 #include <vtol/vtol_edge.h>
00016 #include <vtol/vtol_vertex.h>
00017 #include <vtol/vtol_block.h>
00018 #include <vtol/vtol_macros.h>
00019 #include <vcl_cassert.h>
00020 
00021 //***************************************************************************
00022 // Initialization
00023 //***************************************************************************
00024 
00025 void vtol_two_chain::link_inferior(vtol_face_sptr inf)
00026 {
00027   vtol_topology_object::link_inferior(inf->cast_to_topology_object());
00028 }
00029 
00030 void vtol_two_chain::unlink_inferior(vtol_face_sptr inf)
00031 {
00032   vtol_topology_object::unlink_inferior(inf->cast_to_topology_object());
00033 }
00034 
00035 void vtol_two_chain::link_chain_inferior(vtol_two_chain_sptr chain_inferior)
00036 {
00037   vtol_chain::link_chain_inferior(chain_inferior->cast_to_chain());
00038 }
00039 
00040 void vtol_two_chain::unlink_chain_inferior(vtol_two_chain_sptr chain_inferior)
00041 {
00042   vtol_chain::unlink_chain_inferior(chain_inferior->cast_to_chain());
00043 }
00044 
00045 //---------------------------------------------------------------------------
00046 //: Constructor
00047 //---------------------------------------------------------------------------
00048 vtol_two_chain::vtol_two_chain(face_list const& faces,
00049                                bool new_is_cycle)
00050 {
00051   for (face_list::const_iterator i=faces.begin(); i!=faces.end();++i)
00052   {
00053     link_inferior(*i);
00054     // all face normals point outward.
00055     directions_.push_back((signed char)1);
00056   }
00057   is_cycle_=new_is_cycle;
00058 }
00059 
00060 //---------------------------------------------------------------------------
00061 //: Constructor
00062 //---------------------------------------------------------------------------
00063 vtol_two_chain::vtol_two_chain(face_list const& faces,
00064                                vcl_vector<signed char> const& dirs,
00065                                bool new_is_cycle)
00066 {
00067   vcl_vector<signed char>::const_iterator di;
00068   face_list::const_iterator fi;
00069 
00070   for (di=dirs.begin(),fi=faces.begin();
00071        fi!=faces.end()&&di!=dirs.end();
00072        ++fi,++di)
00073   {
00074     if ((*di)<0)
00075       (*fi)->reverse_normal();
00076     link_inferior(*fi);
00077     directions_.push_back(*di);
00078   }
00079   is_cycle_=new_is_cycle;
00080 }
00081 
00082 //---------------------------------------------------------------------------
00083 //: Pseudo copy constructor.  Deep copy.
00084 //---------------------------------------------------------------------------
00085 vtol_two_chain::vtol_two_chain(vtol_two_chain_sptr const& other)
00086 {
00087   // make a copy of the vertices
00088   vertex_list verts; other->vertices(verts);
00089   int vlen=verts.size();
00090   topology_list newverts(vlen);
00091 
00092   int i=0;
00093   for (vertex_list::iterator vi=verts.begin();vi!=verts.end();++vi,++i)
00094   {
00095     vtol_vertex_sptr v = *vi;
00096     newverts[i] = v->clone()->cast_to_topology_object();
00097     v->set_id(i);
00098   }
00099 
00100   // make a copy of the edges
00101   edge_list edges; other->edges(edges);
00102   int elen=edges.size();
00103   topology_list newedges(elen);
00104 
00105   int j=0;
00106   for (edge_list::iterator ei=edges.begin();ei!= edges.end();++ei,++j)
00107   {
00108     vtol_edge_sptr e = *ei;
00109     newedges[j] = newverts[e->v1()->get_id()]->cast_to_vertex()->new_edge(
00110                   newverts[e->v2()->get_id()]->cast_to_vertex())->cast_to_topology_object();
00111     e->set_id(j);
00112   }
00113 
00114   vcl_vector<signed char> &dirs=other->directions_;
00115   topology_list &infs=other->inferiors_;
00116 
00117   vcl_vector<signed char>::iterator ddi;
00118   topology_list::const_iterator tti;
00119   for (ddi=dirs.begin(),tti=infs.begin(); tti!=infs.end()&&ddi!=dirs.end(); ++ddi,++tti)
00120   {
00121     vtol_face_sptr f=(*tti)->cast_to_face();
00122     vtol_face_sptr new_f = f->copy_with_arrays(newverts,newedges);
00123 #ifdef DEBUG
00124     vcl_cout << "f\n";
00125     f->describe();
00126     vcl_cout << "new f\n";
00127     new_f->describe();
00128 #endif
00129     assert(*new_f == *f);
00130 
00131     link_inferior(new_f);
00132     directions_.push_back((*ddi));
00133   }
00134 
00135   set_cycle(other->is_cycle());
00136   const chain_list *hierarchy_infs=other->chain_inferiors();
00137 
00138   for (chain_list::const_iterator hhi=hierarchy_infs->begin();hhi!=hierarchy_infs->end();++hhi)
00139     link_chain_inferior((*hhi)->cast_to_two_chain()->copy_with_arrays(newverts,newedges));
00140 }
00141 
00142 vtol_two_chain *
00143 vtol_two_chain::copy_with_arrays(topology_list &newverts,
00144                                  topology_list &newedges) const
00145 {
00146   const vcl_vector<signed char> &dirs=directions_;
00147   const topology_list &infs=inferiors_;
00148 
00149   vtol_two_chain *result=new vtol_two_chain(infs.size());
00150 
00151   vcl_vector<signed char>::const_iterator di;
00152   topology_list::const_iterator ti;
00153   for (di=dirs.begin(),ti=infs.begin();
00154        ti!=infs.end()&&di!=dirs.end();
00155        ++ti,++di)
00156   {
00157     vtol_face *f=(*ti)->cast_to_face();
00158     result->link_inferior(f->copy_with_arrays(newverts,newedges));
00159     result->directions_.push_back((*di));
00160   }
00161 
00162   result->set_cycle(is_cycle());
00163   const chain_list *hierarchy_infs=chain_inferiors();
00164 
00165   for (chain_list::const_iterator hi=hierarchy_infs->begin();hi!=hierarchy_infs->end();++hi)
00166     result->link_chain_inferior((*hi)->cast_to_two_chain()->copy_with_arrays(newverts,newedges));
00167   return result;
00168 }
00169 
00170 //---------------------------------------------------------------------------
00171 // Destructor
00172 //---------------------------------------------------------------------------
00173 vtol_two_chain::~vtol_two_chain()
00174 {
00175   clear();
00176   unlink_all_chain_inferiors();
00177 }
00178 
00179 //---------------------------------------------------------------------------
00180 //: Clone `this': creation of a new object and initialization
00181 // See Prototype pattern
00182 //---------------------------------------------------------------------------
00183 vsol_spatial_object_2d* vtol_two_chain::clone() const
00184 {
00185   return new vtol_two_chain(vtol_two_chain_sptr(const_cast<vtol_two_chain*>(this)));
00186 }
00187 
00188 //---------------------------------------------------------------------------
00189 //: Shallow copy with no links
00190 //---------------------------------------------------------------------------
00191 vtol_topology_object *
00192 vtol_two_chain::shallow_copy_with_no_links() const
00193 {
00194   vtol_two_chain *result=new vtol_two_chain();
00195   result->is_cycle_=is_cycle_;
00196   vcl_vector<signed char>::const_iterator di;
00197 
00198   for (di=directions_.begin();di!=directions_.end();++di)
00199     result->directions_.push_back((*di));
00200   return result;
00201 }
00202 
00203 //***************************************************************************
00204 //   Editing Functions
00205 //***************************************************************************
00206 
00207 //: add the superiors from the parent
00208 
00209 void vtol_two_chain::add_superiors_from_parent(topology_list &sups)
00210 {
00211   for (topology_list::iterator si=sups.begin();si!=sups.end();++si)
00212     (*si)->link_inferior(this);
00213 
00214   chain_list::iterator hi;
00215   for (hi=chain_inferiors_.begin();hi!=chain_inferiors_.end();++hi)
00216     (*hi)->cast_to_two_chain()->add_superiors_from_parent(sups);
00217 }
00218 
00219 void vtol_two_chain::remove_superiors_of_parent(topology_list &sups)
00220 {
00221   for (topology_list::iterator si=sups.begin();si!=sups.end();++si)
00222     (*si)->unlink_inferior(this);
00223 
00224   chain_list::iterator hi;
00225   for (hi=chain_inferiors_.begin();hi!=chain_inferiors_.end();++hi)
00226     (*hi)->cast_to_two_chain()->remove_superiors_of_parent(sups);
00227 }
00228 
00229 void vtol_two_chain::remove_superiors()
00230 {
00231   superiors_.clear();
00232   chain_list::iterator hi;
00233   for (hi=chain_inferiors_.begin();hi!=chain_inferiors_.end();++hi)
00234     (*hi)->cast_to_two_chain()->remove_superiors();
00235 }
00236 
00237 void vtol_two_chain::update_superior_list_p_from_hierarchy_parent()
00238 {
00239   // Check to see if there is a parent node in the tree.
00240   const vtol_two_chain *hierarchy_parent=0;
00241   if (chain_superiors_.size()>0)
00242     hierarchy_parent = chain_superiors_.front()->cast_to_two_chain();
00243 
00244   // If vtol_two_chain is a child of another vtol_two_chain...the superiors
00245   // lists are updated.
00246 
00247   if (hierarchy_parent!=0)
00248   {
00249     const vcl_list<vtol_topology_object*> *parent_superiors = hierarchy_parent->superiors_list();
00250 
00251     // Clear all previous superiors.
00252     superiors_.clear();
00253     vcl_list<vtol_topology_object*>::const_iterator ti;
00254     for (ti=parent_superiors->begin();ti!= parent_superiors->end();++ti)
00255       if (vcl_find(superiors_.begin(),superiors_.end(),*ti)==superiors_.end())
00256         superiors_.push_back(*ti);
00257 
00258     // Recursively update all children.
00259     two_chain_list *chains=inferior_two_chains();
00260 
00261     for (two_chain_list::iterator ci=chains->begin();ci!=chains->end();++ci)
00262       (*ci)->update_superior_list_p_from_hierarchy_parent();
00263     delete chains;
00264   }
00265 }
00266 
00267 bool
00268 vtol_two_chain::break_into_connected_components( topology_list& /*components*/ )
00269 {
00270   vcl_cerr << "vtol_two_chain::break_into_connected_components() not yet implemented\n";
00271 #if 0 // TODO
00272   topology_list * tmp = get_inferiors();
00273   int numfaces = tmp->size();
00274   if ( numfaces == 0 ) return false;
00275   vcl_vector< vtol_face * > faces( numfaces );
00276   int i=0;
00277   for (topology_list::iterator ti= tmp->begin(); ti!=tmp->end();++ti, ++i )
00278     faces[ i ] = (*ti)->cast_to_face();
00279 
00280   // compnum[i] stores the component number of the ith face
00281   int * compnum = new int[ numfaces ];
00282   assert( compnum );
00283 
00284   // adjslists stores the adjacency lists representation of the face graph
00285   vcl_vector< int > * adjlists = new vcl_vector< int > [ numfaces ];
00286   assert( adjlists );
00287 
00288   // build the adjacency list representation
00289   for ( i = 0; i < numfaces; ++i )
00290   {
00291     compnum[ i ] = -1;  // -1 signals it is not part of any component yet
00292     for (int j = i+1; j < numfaces; ++j )
00293       if ( faces[ i ]->shares_edge_with( faces[ j ] ) )
00294       {
00295         adjlists[i].push_back( j );
00296         adjlists[j].push_back( i );
00297       }
00298   }
00299 
00300   // use depth first search to find connected components
00301   int numcomps = 0;
00302   for ( i = 0; i < numfaces; ++i )
00303   {
00304     if ( compnum[ i ] == -1 ) // unvisited
00305     {
00306       compnum[ i ] = numcomps;
00307       vcl_vector<int> to_be_explored;
00308       to_be_explored.push( i );
00309       while ( to_be_explored.size() )
00310       {
00311         int f = to_be_explored.pop();
00312         for ( adjlists[ f ].begin(); adjlists[ f ].end(); )
00313         {
00314           if ( compnum[ adjlists[ f ].value() ] == -1 )
00315           {
00316             compnum[ adjlists[ f ].value() ] = numcomps;
00317             to_be_explored.push( adjlists[ f ].value() );
00318           }
00319         }
00320       }
00321       ++numcomps;
00322     }
00323   }
00324 
00325   if ( numcomps > 1 )
00326     for ( i = 0; i < numcomps; ++i )
00327     {
00328       vcl_vector< vtol_face * > component_faces;
00329       // gather faces belonging to the ith component
00330       for ( j = 0; j < numfaces; ++j )
00331         if ( compnum[ j ] == i )
00332           component_faces.push_back( faces[ j ] );
00333       // create either a two chain or a face out of the component
00334       if ( component_faces.size() == 1 )
00335         components.push_back( component_faces.get( 0 ) );
00336       else
00337       {
00338         vtol_two_chain * newvtol_two_chain = new vtol_two_chain(component_faces, false);
00339         // need to check if it is a cycle??
00340         components.push_back( newvtol_two_chain );
00341       }
00342       component_faces.clear(); // necessary??
00343     }
00344 
00345   delete []compnum;
00346   delete []adjlists;
00347 
00348   if ( numcomps == 1 ) return false;
00349   else return true;
00350 #else // 0
00351   vcl_cerr << "vtol_two_chain::break_into_connected_components() not implemented yet\n";
00352   return false; // TODO
00353 #endif // 0
00354 }
00355 
00356 void vtol_two_chain::add_face(vtol_face_sptr const& new_face,
00357                               signed char dir)
00358 {
00359   directions_.push_back(dir);
00360   link_inferior(new_face);
00361 }
00362 
00363 #if 1 // deprecated
00364 void vtol_two_chain::add_face(vtol_face &new_face,
00365                               signed char dir)
00366 {
00367   vcl_cerr << "Warning: deprecated form of vtol_face::add_face()\n";
00368   directions_.push_back(dir);
00369   link_inferior(&new_face);
00370 }
00371 #endif
00372 
00373 void vtol_two_chain::remove_face(vtol_face_sptr const& doomed_face)
00374 {
00375   vtol_topology_object_sptr t=doomed_face->cast_to_topology_object();
00376   topology_list::const_iterator i=vcl_find(inferiors()->begin(),inferiors()->end(),t);
00377   topology_list::difference_type index=i-inferiors()->begin();
00378 
00379   if (index>=0 && i!= inferiors()->end())
00380   {
00381     vcl_vector<signed char>::iterator j = directions_.begin() + index;
00382     directions_.erase(j);
00383     touch();
00384     unlink_inferior(doomed_face);
00385   }
00386 }
00387 
00388 #if 1 // deprecated
00389 void vtol_two_chain::remove_face(vtol_face &doomed_face)
00390 {
00391   vcl_cerr << "Warning: deprecated form of vtol_face::remove_face()\n";
00392   vtol_topology_object_sptr t=&doomed_face;
00393   topology_list::const_iterator i=vcl_find(inferiors()->begin(),inferiors()->end(),t);
00394   topology_list::difference_type index=i-inferiors()->begin();
00395 
00396   if (index>=0 && i!= inferiors()->end())
00397   {
00398     vcl_vector<signed char>::iterator j = directions_.begin() + index;
00399     directions_.erase(j);
00400     touch();
00401     unlink_inferior(&doomed_face);
00402   }
00403 }
00404 #endif
00405 
00406 //***************************************************************************
00407 //    Accessor Functions
00408 //***************************************************************************
00409 
00410 vtol_face_sptr vtol_two_chain::face(int i)
00411 {
00412   return inferiors_[i]->cast_to_face();
00413 }
00414 
00415 //: outside boundary vertices
00416 
00417 vertex_list *vtol_two_chain::outside_boundary_vertices()
00418 {
00419   vertex_list *new_ref_list = new vertex_list;
00420   vcl_vector<vtol_vertex*>* ptr_list = this->outside_boundary_compute_vertices();
00421   // copy the lists
00422 
00423   for (vcl_vector<vtol_vertex*>::iterator ti = ptr_list->begin();
00424        ti != ptr_list->end(); ++ti)
00425     new_ref_list->push_back(*ti);
00426 
00427   delete ptr_list;
00428 
00429   return new_ref_list;
00430 }
00431 
00432 vcl_vector<vtol_vertex *> *
00433 vtol_two_chain::outside_boundary_compute_vertices()
00434 {
00435   SEL_INF(vtol_vertex,compute_vertices);
00436 }
00437 
00438 //: list of vertices
00439 
00440 vcl_vector<vtol_vertex *> *vtol_two_chain::compute_vertices()
00441 {
00442   vcl_vector<vtol_vertex *> *verts = outside_boundary_compute_vertices();
00443 
00444   // Set current position to the end
00445   // verts->set_position(verts->size()-1); - not sure what is supposed to happen here
00446 
00447   SUBCHAIN_INF(verts,two_chain,vtol_vertex,compute_vertices);
00448 }
00449 
00450 //: outside boundary zero chains
00451 
00452 zero_chain_list *vtol_two_chain::outside_boundary_zero_chains()
00453 {
00454   zero_chain_list *new_ref_list = new zero_chain_list;
00455   vcl_vector<vtol_zero_chain*>* ptr_list = this->outside_boundary_compute_zero_chains();
00456   // copy the lists
00457 
00458   for (vcl_vector<vtol_zero_chain*>::iterator ti = ptr_list->begin();
00459        ti != ptr_list->end(); ++ti)
00460     new_ref_list->push_back(*ti);
00461 
00462   delete ptr_list;
00463 
00464   return new_ref_list;
00465 }
00466 
00467 vcl_vector<vtol_zero_chain*> *vtol_two_chain::outside_boundary_compute_zero_chains()
00468 {
00469   SEL_INF(vtol_zero_chain,compute_zero_chains);
00470 }
00471 
00472 //: list of zero chains
00473 vcl_vector<vtol_zero_chain*> *vtol_two_chain::compute_zero_chains()
00474 {
00475   vcl_vector<vtol_zero_chain*> *zchs;
00476   zchs=outside_boundary_compute_zero_chains();
00477 
00478   SUBCHAIN_INF(zchs,two_chain,vtol_zero_chain,compute_zero_chains);
00479 }
00480 
00481 //: outside boundary edges
00482 edge_list *vtol_two_chain::outside_boundary_edges()
00483 {
00484   edge_list *new_ref_list = new edge_list;
00485   vcl_vector<vtol_edge*>* ptr_list = this->outside_boundary_compute_edges();
00486   // copy the lists
00487 
00488   for (vcl_vector<vtol_edge*>::iterator ti = ptr_list->begin();
00489        ti != ptr_list->end(); ++ti)
00490     new_ref_list->push_back(*ti);
00491 
00492   delete ptr_list;
00493 
00494   return new_ref_list;
00495 }
00496 
00497 //: outside boundary edges
00498 vcl_vector<vtol_edge*> *vtol_two_chain::outside_boundary_compute_edges()
00499 {
00500   SEL_INF(vtol_edge,compute_edges);
00501 }
00502 
00503 //: list of edges
00504 vcl_vector<vtol_edge*> *vtol_two_chain::compute_edges()
00505 {
00506   vcl_vector<vtol_edge*> *edgs;
00507   edgs=outside_boundary_compute_edges();
00508 
00509   SUBCHAIN_INF(edgs,two_chain,vtol_edge,compute_edges);
00510 }
00511 
00512 //: outside one chains
00513 one_chain_list *vtol_two_chain::outside_boundary_one_chains()
00514 {
00515   vcl_vector<vtol_one_chain*>* ptr_list= outside_boundary_compute_one_chains();
00516   one_chain_list *ref_list= new one_chain_list;
00517 
00518   vcl_vector<vtol_one_chain*>::iterator i;
00519   for (i=ptr_list->begin();i!=ptr_list->end();++i)
00520     ref_list->push_back(*i);
00521 
00522   delete ptr_list;
00523   return ref_list;
00524 }
00525 
00526 vcl_vector<vtol_one_chain*> *vtol_two_chain::outside_boundary_compute_one_chains()
00527 {
00528  SEL_INF(vtol_one_chain,compute_one_chains);
00529 }
00530 
00531 //: one chains
00532 vcl_vector<vtol_one_chain*> *vtol_two_chain::compute_one_chains()
00533 {
00534   vcl_vector<vtol_one_chain*> *onechs;
00535   onechs=outside_boundary_compute_one_chains();
00536   SUBCHAIN_INF(onechs,two_chain,vtol_one_chain,compute_one_chains);
00537 }
00538 
00539 //: outside faces
00540 face_list *vtol_two_chain::outside_boundary_faces()
00541 {
00542   vcl_vector<vtol_face*>* ptr_list= outside_boundary_compute_faces();
00543   face_list *ref_list= new face_list;
00544 
00545   vcl_vector<vtol_face*>::iterator i;
00546   for (i=ptr_list->begin();i!=ptr_list->end();++i)
00547     ref_list->push_back(*i);
00548 
00549   delete ptr_list;
00550   return ref_list;
00551 }
00552 
00553 // outside faces
00554 vcl_vector<vtol_face*> *vtol_two_chain::outside_boundary_compute_faces()
00555 {
00556  COPY_INF(face);
00557 }
00558 
00559 //: faces
00560 vcl_vector<vtol_face*> *vtol_two_chain::compute_faces()
00561 {
00562   vcl_vector<vtol_face*> *facs;
00563   facs=outside_boundary_compute_faces();
00564   SUBCHAIN_INF(facs,two_chain,vtol_face,compute_faces);
00565 }
00566 
00567 //: list of blocks
00568 vcl_vector<vtol_block*> *vtol_two_chain::compute_blocks()
00569 {
00570   if (is_sub_chain())
00571   {
00572     vcl_vector<vtol_block*>*result=new vcl_vector<vtol_block*>;
00573     vcl_list<vtol_chain*>::iterator tci;
00574     for (tci=chain_superiors_.begin();tci!=chain_superiors_.end();++tci)
00575     {
00576       vcl_vector<vtol_block*> *sublist=(*tci)->cast_to_two_chain()->compute_blocks();
00577       vcl_vector<vtol_block*>::iterator si;
00578       for (si=sublist->begin();si!=sublist->end();++si)
00579         result->push_back(*si);
00580       delete sublist;
00581     }
00582     return tagged_union(result);
00583   }
00584   else
00585   {
00586     SEL_SUP(vtol_block,compute_blocks);
00587   }
00588 }
00589 
00590 //: list of two chains
00591 
00592 vcl_vector<vtol_two_chain*> *vtol_two_chain::compute_two_chains()
00593 {
00594   vcl_vector<vtol_two_chain*> *result=outside_boundary_compute_two_chains();
00595 
00596   chain_list::iterator hi;
00597   for (hi=chain_inferiors_.begin();hi!=chain_inferiors_.end();++hi )
00598     result->push_back((*hi)->cast_to_two_chain());
00599   return result;
00600 }
00601 
00602 two_chain_list *vtol_two_chain::inferior_two_chains()
00603 {
00604   two_chain_list *result=new two_chain_list;
00605   chain_list::iterator hi;
00606   for (hi=chain_inferiors_.begin();hi!=chain_inferiors_.end();++hi)
00607     result->push_back((*hi)->cast_to_two_chain());
00608   return result;
00609 }
00610 
00611 
00612 two_chain_list *vtol_two_chain::superior_two_chains()
00613 {
00614   two_chain_list *result=new two_chain_list;
00615   vcl_list<vtol_chain*>::iterator hi;
00616   for (hi=chain_superiors_.begin();hi!=chain_superiors_.end();++hi)
00617     result->push_back((*hi)->cast_to_two_chain());
00618   return result;
00619 }
00620 
00621 two_chain_list *vtol_two_chain::outside_boundary_two_chains()
00622 {
00623   vcl_vector<vtol_two_chain*>* ptr_list= outside_boundary_compute_two_chains();
00624   two_chain_list *ref_list= new two_chain_list;
00625 
00626   vcl_vector<vtol_two_chain*>::iterator i;
00627   for (i=ptr_list->begin();i!=ptr_list->end();++i)
00628     ref_list->push_back(*i);
00629 
00630   delete ptr_list;
00631   return ref_list;
00632 }
00633 
00634 vcl_vector<vtol_two_chain*>  *vtol_two_chain::outside_boundary_compute_two_chains()
00635 {
00636   LIST_SELF(vtol_two_chain);
00637 }
00638 
00639 //***************************************************************************
00640 //     Operator Functions
00641 //***************************************************************************
00642 
00643 //: equality operator
00644 
00645 bool vtol_two_chain::operator==(vtol_two_chain const& other) const
00646 {
00647   if (this==&other)
00648     return true;
00649 
00650   if (numinf()!=other.numinf())
00651     return false;
00652 
00653   topology_list::const_iterator ti1,ti2;
00654   for (ti1=other.inferiors()->begin(),ti2=inferiors()->begin();
00655        ti2!=inferiors()->end(); ++ti1,++ti2)
00656   {
00657     vtol_face *f1=(*ti2)->cast_to_face();
00658     vtol_face *f2=(*ti1)->cast_to_face();
00659     if (!(*f1==*f2))
00660       return false;
00661   }
00662 
00663   // check out the directions
00664 
00665   const vcl_vector<signed char> *dir1=this->directions();
00666   const vcl_vector<signed char> *dir2=other.directions();
00667 
00668   vcl_vector<signed char>::const_iterator d1;
00669   vcl_vector<signed char>::const_iterator d2;
00670   for (d1=dir1->begin(), d2=dir2->begin(); d1 != dir1->end(); ++d1, ++d2)
00671     if (!(*d1 == *d2))
00672       return false;
00673 
00674   const chain_list &righth=chain_inferiors_;
00675   const chain_list &lefth=other.chain_inferiors_;
00676   if (righth.size()!=lefth.size())
00677     return false;
00678 
00679   chain_list::const_iterator hi1,hi2;
00680 
00681   for (hi1=righth.begin(),hi2=lefth.begin();
00682        hi1!=righth.end()&&hi2!=lefth.end();
00683        ++hi1,++hi2)
00684     if ( !(*(*hi1) == *(*hi2)))
00685       return false;
00686 
00687   return true;
00688 }
00689 
00690 //: spatial object equality
00691 
00692 bool vtol_two_chain::operator==(vsol_spatial_object_2d const& obj) const
00693 {
00694   return
00695    obj.cast_to_topology_object() &&
00696    obj.cast_to_topology_object()->cast_to_two_chain() &&
00697    *this == *obj.cast_to_topology_object()->cast_to_two_chain();
00698 }
00699 
00700 //***************************************************************************
00701 //    Utility Functions
00702 //***************************************************************************
00703 
00704 //: correct the chain directions
00705 void vtol_two_chain::correct_chain_directions()
00706 {
00707   vcl_cerr << "vtol_two_chain::correct_chain_directions() not yet implemented\n";
00708 }
00709 
00710 //***************************************************************************
00711 //    Print Functions
00712 //***************************************************************************
00713 
00714 void vtol_two_chain::print(vcl_ostream &strm) const
00715 {
00716   strm << "<vtol_two_chain with " << inferiors()->size() << " faces>\n";
00717 }
00718 
00719 void vtol_two_chain::describe_directions(vcl_ostream &strm,
00720                                          int blanking) const
00721 {
00722   for (int j=0; j<blanking; ++j) { strm << ' '; }
00723   strm << "<Dirs [" << directions_.size() << "]:";
00724 
00725   vcl_vector<signed char>::const_iterator di;
00726   for (di=directions_.begin();di!=directions_.end();++di)
00727   {
00728     strm << ' ' << (int)(*di);
00729   }
00730   strm << ">\n";
00731 }
00732 
00733 void vtol_two_chain::describe(vcl_ostream &strm,
00734                               int blanking) const
00735 {
00736   for (int j=0; j<blanking; ++j) strm << ' ';
00737   print(strm);
00738   describe_inferiors(strm,blanking);
00739   describe_directions(strm,blanking);
00740   describe_superiors(strm,blanking);
00741 }
00742 
00743 signed char vtol_two_chain::direction(vtol_face const& f) const
00744 {
00745   // return the direction of the face
00746 
00747   vcl_vector<signed char>::const_iterator dit;
00748   topology_list::const_iterator toit;
00749 
00750   dit=directions_.begin();
00751   for (toit=inferiors()->begin();toit!=inferiors()->end();++toit)
00752   {
00753     vtol_face *cf=(*toit)->cast_to_face();
00754     if (cf==&f)
00755       return *dit;
00756     ++dit;
00757   }
00758   return (signed char)1;
00759 }