contrib/brl/bbas/bgrl/bgrl_vertex.cxx
Go to the documentation of this file.
00001 // This is brl/bbas/bgrl/bgrl_vertex.cxx
00002 #include "bgrl_vertex.h"
00003 //:
00004 // \file
00005 
00006 #include "bgrl_edge.h"
00007 #include <vsl/vsl_binary_io.h>
00008 #include <vsl/vsl_binary_loader.h>
00009 #include <vsl/vsl_set_io.h>
00010 #include <vbl/io/vbl_io_smart_ptr.h>
00011 
00012 //: Constructor
00013 bgrl_vertex::bgrl_vertex()
00014   : out_edges_(), in_edges_()
00015 {
00016 }
00017 
00018 
00019 //: Copy Constructor
00020 bgrl_vertex::bgrl_vertex(const bgrl_vertex& vertex)
00021   : vbl_ref_count()
00022 {
00023   for ( vcl_set<bgrl_edge_sptr>::const_iterator itr = vertex.out_edges_.begin();
00024         itr != vertex.out_edges_.end();  ++itr ){
00025     bgrl_edge_sptr edge_copy((*itr)->clone());
00026     edge_copy->from_ = this;
00027     out_edges_.insert(edge_copy);
00028   }
00029 }
00030 
00031 
00032 //: Strip all of the edges from this vertex
00033 void
00034 bgrl_vertex::strip()
00035 {
00036   // Iterate over all outgoing edges and remove back links
00037   for ( edge_iterator out_itr = out_edges_.begin();
00038         out_itr != out_edges_.end(); ++out_itr)
00039   {
00040     if ((*out_itr)->to_) {
00041       (*out_itr)->to_->in_edges_.erase(*out_itr);
00042       (*out_itr)->to_ = NULL;
00043     }
00044     (*out_itr)->from_ = NULL;
00045   }
00046 
00047   // Clear outgoing edges
00048   out_edges_.clear();
00049 
00050   // Iterate over all incoming edges and remove back links
00051   for ( edge_iterator in_itr = in_edges_.begin();
00052         in_itr != in_edges_.end(); ++in_itr)
00053   {
00054     if ((*in_itr)->from_){
00055       (*in_itr)->from_->out_edges_.erase(*in_itr);
00056       (*in_itr)->from_ = NULL;
00057     }
00058     (*in_itr)->to_ = NULL;
00059   }
00060 
00061   // Clear incoming edges
00062   in_edges_.clear();
00063 }
00064 
00065 
00066 //: Remove any edges to or from NULL vertices
00067 bool
00068 bgrl_vertex::purge()
00069 {
00070   bool retval = false;
00071 
00072   for ( edge_iterator itr = out_edges_.begin();
00073         itr != out_edges_.end(); )
00074   {
00075     edge_iterator next_itr = itr;
00076     ++next_itr;
00077     if (!(*itr)->to_) {
00078       out_edges_.erase(itr);
00079       retval = true;
00080     }
00081     itr = next_itr;
00082   }
00083 
00084   for ( edge_iterator itr = in_edges_.begin();
00085         itr != in_edges_.end(); )
00086   {
00087     edge_iterator next_itr = itr;
00088     ++next_itr;
00089     if (!(*itr)->from_) {
00090       in_edges_.erase(itr);
00091       retval = true;
00092     }
00093     itr = next_itr;
00094   }
00095 
00096   return retval;
00097 }
00098 
00099 
00100 //: Add an edge to \p vertex
00101 bgrl_edge_sptr
00102 bgrl_vertex::add_edge_to( const bgrl_vertex_sptr& vertex,
00103                           const bgrl_edge_sptr& model_edge )
00104 {
00105   if (!vertex || vertex.ptr() == this)
00106     return bgrl_edge_sptr(NULL);
00107 
00108   // verify that this edge is not already present
00109   for ( edge_iterator itr = out_edges_.begin();
00110         itr != out_edges_.end(); ++itr )
00111     if ((*itr)->to_ == vertex)
00112       return bgrl_edge_sptr(NULL);
00113 
00114   // add the edge
00115   bgrl_edge_sptr new_edge;
00116   if (model_edge)
00117     new_edge = model_edge->clone();
00118   else
00119     new_edge = new bgrl_edge;
00120 
00121   new_edge->from_ = this;
00122   new_edge->to_ = vertex.ptr();
00123   this->out_edges_.insert(new_edge);
00124   vertex->in_edges_.insert(new_edge);
00125 
00126   // initialize the edge
00127   new_edge->init();
00128 
00129   return new_edge;
00130 }
00131 
00132 
00133 //: Remove \p vertex from the neighborhood
00134 bool
00135 bgrl_vertex::remove_edge_to( const bgrl_vertex_sptr& vertex )
00136 {
00137   if (!vertex || vertex.ptr() == this)
00138     return false;
00139 
00140   for ( edge_iterator itr = out_edges_.begin();
00141         itr != out_edges_.end(); ++itr )
00142   {
00143     if ((*itr)->to_ == vertex) {
00144       if ( vertex->in_edges_.erase(*itr) > 0 ) {
00145         (*itr)->to_ = NULL;
00146         (*itr)->from_ = NULL;
00147         out_edges_.erase(itr);
00148         return true;
00149       }
00150     }
00151   }
00152 
00153   return false;
00154 }
00155 
00156 
00157 //: Returns an iterator to the beginning of the list of outgoing edges
00158 bgrl_vertex::edge_iterator
00159 bgrl_vertex::begin()
00160 {
00161   return out_edges_.begin();
00162 }
00163 
00164 
00165 //: Returns an iterator to the end of the list of outgoing edges
00166 bgrl_vertex::edge_iterator
00167 bgrl_vertex::end()
00168 {
00169   return out_edges_.end();
00170 }
00171 
00172 
00173 //: Return a platform independent string identifying the class
00174 vcl_string
00175 bgrl_vertex::is_a() const
00176 {
00177   return "bgrl_vertex";
00178 }
00179 
00180 
00181 //: Create a copy of the object on the heap.
00182 // The caller is responsible for deletion
00183 bgrl_vertex*
00184 bgrl_vertex::clone() const
00185 {
00186   return new bgrl_vertex(*this);
00187 }
00188 
00189 
00190 //: Binary save self to stream.
00191 void
00192 bgrl_vertex::b_write( vsl_b_ostream& os ) const
00193 {
00194   vsl_b_write(os, version());
00195 
00196   // write the outgoing edges
00197   vsl_b_write(os, out_edges_);
00198   // write the incoming edges
00199   vsl_b_write(os, in_edges_);
00200 }
00201 
00202 
00203 //: Binary load self from stream.
00204 void
00205 bgrl_vertex::b_read( vsl_b_istream& is )
00206 {
00207   if (!is) return;
00208 
00209   short ver;
00210   vsl_b_read(is, ver);
00211   switch (ver)
00212   {
00213    case 1:
00214     // read the outgoing edges
00215     out_edges_.clear();
00216     vsl_b_read(is, out_edges_);
00217     for ( edge_iterator itr = out_edges_.begin();
00218           itr != out_edges_.end(); ++itr )
00219       (*itr)->from_ = this;
00220 
00221     // read the incoming edges
00222     in_edges_.clear();
00223     vsl_b_read(is, in_edges_);
00224     for ( edge_iterator itr = in_edges_.begin();
00225           itr != in_edges_.end(); ++itr )
00226       (*itr)->to_ = this;
00227 
00228     break;
00229 
00230   default:
00231     vcl_cerr << "I/O ERROR: bgrl_vertex::b_read(vsl_b_istream&)\n"
00232              << "           Unknown version number "<< ver << '\n';
00233     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00234     return;
00235   }
00236 }
00237 
00238 
00239 //: Return IO version number;
00240 short
00241 bgrl_vertex::version() const
00242 {
00243   return 1;
00244 }
00245 
00246 
00247 //: Print an ascii summary to the stream
00248 void
00249 bgrl_vertex::print_summary( vcl_ostream& os ) const
00250 {
00251   os << this->degree() << " degree";
00252 }
00253 
00254 
00255 //-----------------------------------------------------------------------------------------
00256 // External functions
00257 //-----------------------------------------------------------------------------------------
00258 
00259 
00260 //: Allows derived class to be loaded by base-class pointer.
00261 //  A loader object exists which is invoked by calls
00262 //  of the form "vsl_b_read(os,base_ptr);".  This loads derived class
00263 //  objects from the stream, places them on the heap and
00264 //  returns a base class pointer.
00265 //  In order to work the loader object requires
00266 //  an instance of each derived class that might be
00267 //  found.  This function gives the model class to
00268 //  the appropriate loader.
00269 void vsl_add_to_binary_loader(const bgrl_vertex& v)
00270 {
00271   vsl_binary_loader<bgrl_vertex>::instance().add(v);
00272 }
00273 
00274 
00275 //: Print an ASCII summary to the stream
00276 void
00277 vsl_print_summary(vcl_ostream &os, const bgrl_vertex* v)
00278 {
00279   os << "bgrl_vertex{ ";
00280   v->print_summary(os);
00281   os << " }";
00282 }