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 }