00001 // This is gel/vtol/vtol_topology_object.cxx 00002 #include "vtol_topology_object.h" 00003 //: 00004 // \file 00005 00006 #include <vtol/vtol_topology_cache.h> 00007 #include <vtol/vtol_vertex.h> 00008 #include <vcl_cassert.h> 00009 00010 //*************************************************************************** 00011 // Initialization 00012 //*************************************************************************** 00013 00014 //--------------------------------------------------------------------------- 00015 // Default constructor 00016 //--------------------------------------------------------------------------- 00017 vtol_topology_object::vtol_topology_object(void) 00018 :superiors_(0), 00019 inferiors_(0) 00020 { 00021 inf_sup_cache_= new vtol_topology_cache(this); 00022 touch(); 00023 } 00024 00025 //--------------------------------------------------------------------------- 00026 //: Constructor with given sizes for arrays of inferiors and superiors 00027 //--------------------------------------------------------------------------- 00028 vtol_topology_object::vtol_topology_object(const int num_inferiors, 00029 const int num_superiors) 00030 :superiors_(num_superiors), 00031 inferiors_(num_inferiors) 00032 { 00033 inf_sup_cache_=new vtol_topology_cache(this); 00034 touch(); 00035 } 00036 00037 //--------------------------------------------------------------------------- 00038 // Destructor 00039 //--------------------------------------------------------------------------- 00040 vtol_topology_object::~vtol_topology_object() 00041 { 00042 delete inf_sup_cache_; 00043 } 00044 00045 //*************************************************************************** 00046 // Status report 00047 //*************************************************************************** 00048 00049 //--------------------------------------------------------------------------- 00050 //: Is `inferior' already an inferior of `this' ? 00051 //--------------------------------------------------------------------------- 00052 bool 00053 vtol_topology_object::is_inferior(vtol_topology_object_sptr inferior) const 00054 { 00055 topology_list::const_iterator i; 00056 for (i=inferiors_.begin(); i!=inferiors_.end(); ++i) 00057 if ((*i) == inferior) 00058 return true; 00059 00060 return false; 00061 } 00062 00063 //--------------------------------------------------------------------------- 00064 //: Is `superior' already a superior of `this' ? 00065 //--------------------------------------------------------------------------- 00066 bool 00067 vtol_topology_object::is_superior(vtol_topology_object* const& superior) const 00068 { 00069 vcl_list<vtol_topology_object*>::const_iterator i; 00070 for (i=superiors_.begin(); i!=superiors_.end(); ++i) 00071 if (*i == superior) 00072 return true; 00073 00074 return false; 00075 } 00076 00077 #if 0 00078 //--------------------------------------------------------------------------- 00079 //: Return the superiors list (must be deallocated after use) 00080 //--------------------------------------------------------------------------- 00081 const topology_list * vtol_topology_object::superiors(void) const 00082 { 00083 vcl_cerr << "*** Warning: superiors() is deprecated\n"; 00084 topology_list *result=new topology_list; 00085 result->reserve(superiors_.size()); 00086 00087 vcl_list<vtol_topology_object*>::const_iterator i; 00088 for (i=superiors_.begin();i!=superiors_.end();++i) 00089 result->push_back(*i); 00090 00091 return result; 00092 } 00093 #endif 00094 00095 //*************************************************************************** 00096 // Basic operations 00097 //*************************************************************************** 00098 00099 //--------------------------------------------------------------------------- 00100 //: Link `this' with an inferior `inferior' 00101 // Require: valid_inferior_type(inferior) and !is_inferior(inferior) 00102 //--------------------------------------------------------------------------- 00103 void vtol_topology_object::link_inferior(vtol_topology_object_sptr inferior) 00104 { 00105 // require 00106 assert(valid_inferior_type(inferior->cast_to_topology_object())); 00107 00108 // Do nothing if already an inferior 00109 if ( is_inferior(inferior) ) return; 00110 00111 assert(!is_inferior(inferior)); 00112 assert(!inferior->is_superior(this)); 00113 00114 inferiors_.push_back(inferior); 00115 inferior->superiors_.push_back(this); 00116 inferior->touch();//The inferior's topology cache is now stale as well JLM 00117 touch(); 00118 } 00119 00120 //--------------------------------------------------------------------------- 00121 //: Unlink `this' with the inferior `inferior' 00122 // Require: valid_inferior_type(inferior) and is_inferior(inferior) 00123 //--------------------------------------------------------------------------- 00124 void vtol_topology_object::unlink_inferior(vtol_topology_object_sptr inferior) 00125 { 00126 // require 00127 assert(valid_inferior_type(inferior->cast_to_topology_object())); 00128 assert(is_inferior(inferior)); 00129 assert(inferior->is_superior(this)); 00130 00131 vcl_list<vtol_topology_object*>::iterator i=inferior->superiors_.begin(); 00132 while ( i!=inferior->superiors_.end() && *i!=this ) ++i; 00133 // check presence in "superiors_" list of inferior: 00134 assert(*i==this); 00135 00136 inferior->superiors_.erase(i); // unlink this from superiors_ list of inferior 00137 00138 topology_list::iterator j=inferiors_.begin(); 00139 while ( j!=inferiors_.end() && (*j)!=inferior) ++j; 00140 // check presence in "inferiors_" list: 00141 assert((*j)==inferior); 00142 00143 inferiors()->erase(j); 00144 touch(); 00145 } 00146 00147 //--------------------------------------------------------------------------- 00148 //: Unlink `this' from all its inferiors 00149 //--------------------------------------------------------------------------- 00150 void vtol_topology_object::unlink_all_inferiors(void) 00151 { 00152 // remove superior-inferior link, running through inferiors list back-to-front 00153 while (inferiors_.size()>0) 00154 unlink_inferior(inferiors_.back()); 00155 } 00156 00157 //--------------------------------------------------------------------------- 00158 //: Unlink `this' of the network 00159 //--------------------------------------------------------------------------- 00160 void vtol_topology_object::unlink(void) 00161 { 00162 while (superiors_.size()>0) 00163 superiors_.front()->unlink_inferior(this); 00164 unlink_all_inferiors(); 00165 } 00166 00167 //: get list of vertices 00168 00169 vertex_list* vtol_topology_object::vertices(void) const 00170 { 00171 vertex_list* new_list=new vertex_list; 00172 inf_sup_cache_->vertices(*new_list); 00173 return new_list; 00174 } 00175 00176 //: get list of vertices 00177 00178 void vtol_topology_object::vertices(vertex_list& verts) const 00179 { 00180 inf_sup_cache_->vertices(verts); 00181 } 00182 00183 //: get list of zero_chains 00184 zero_chain_list* vtol_topology_object::zero_chains(void) const 00185 { 00186 zero_chain_list* new_list=new zero_chain_list; 00187 inf_sup_cache_->zero_chains(*new_list); 00188 return new_list; 00189 } 00190 00191 //: get list of zero chains 00192 void vtol_topology_object::zero_chains(zero_chain_list &zerochains) const 00193 { 00194 inf_sup_cache_->zero_chains(zerochains); 00195 } 00196 00197 //: get list of edges 00198 00199 edge_list* vtol_topology_object::edges(void) const 00200 { 00201 edge_list* new_list=new edge_list; 00202 inf_sup_cache_->edges(*new_list); 00203 return new_list; 00204 } 00205 00206 //: get list of edges 00207 00208 void vtol_topology_object::edges(edge_list &edges) const 00209 { 00210 inf_sup_cache_->edges(edges); 00211 } 00212 00213 //: get list of one chains 00214 00215 one_chain_list* vtol_topology_object::one_chains(void) const 00216 { 00217 one_chain_list* new_list=new one_chain_list; 00218 inf_sup_cache_->one_chains(*new_list); 00219 return new_list; 00220 } 00221 00222 //: get list of one chains 00223 00224 void vtol_topology_object::one_chains(one_chain_list &onechains) const 00225 { 00226 inf_sup_cache_->one_chains(onechains); 00227 } 00228 00229 //: get list of faces 00230 00231 face_list *vtol_topology_object::faces(void) const 00232 { 00233 face_list *new_list=new face_list; 00234 inf_sup_cache_->faces(*new_list); 00235 return new_list; 00236 } 00237 00238 //: get list of faces 00239 00240 void vtol_topology_object::faces(face_list &face_list) const 00241 { 00242 inf_sup_cache_->faces(face_list); 00243 } 00244 00245 //: get list of two chains 00246 00247 two_chain_list *vtol_topology_object::two_chains(void) const 00248 { 00249 two_chain_list *new_list=new two_chain_list; 00250 inf_sup_cache_->two_chains(*new_list); 00251 return new_list; 00252 } 00253 00254 //: get list of two chains 00255 00256 void vtol_topology_object::two_chains(two_chain_list &new_list) const 00257 { 00258 inf_sup_cache_->two_chains(new_list); 00259 } 00260 00261 //: get list of blocks 00262 00263 block_list *vtol_topology_object::blocks(void) const 00264 { 00265 block_list *new_list=new block_list; 00266 inf_sup_cache_->blocks(*new_list); 00267 return new_list; 00268 } 00269 00270 //: get list of blocks 00271 00272 void vtol_topology_object::blocks(block_list &new_list) const 00273 { 00274 inf_sup_cache_->blocks(new_list); 00275 } 00276 00277 //: print the object 00278 void vtol_topology_object::print(vcl_ostream &strm) const 00279 { 00280 strm<<"<vtol_topology_object "<<(void const *)this<<">\n" 00281 <<"number of inferiors "<<numinf()<<vcl_endl 00282 <<"number of superiors "<<numsup()<<vcl_endl; 00283 } 00284 00285 void vtol_topology_object::describe_inferiors(vcl_ostream &strm, 00286 int blanking) const 00287 { 00288 for (int n=0; n<blanking; ++n) strm << ' '; 00289 if (inferiors()->size()==0) 00290 strm<<"**INFERIORS: Empty\n"; 00291 else 00292 strm<<"**INFERIORS:\n"; 00293 00294 topology_list::const_iterator i; 00295 for (i=inferiors()->begin();i!=inferiors()->end();++i) 00296 { 00297 for (int n=0; n<blanking+2; ++n) strm << ' '; 00298 (*i)->print(); 00299 } 00300 } 00301 00302 void vtol_topology_object::describe_superiors(vcl_ostream &strm, 00303 int blanking) const 00304 { 00305 for (int n=0; n<blanking; ++n) strm << ' '; 00306 if (superiors_.size()==0) 00307 { 00308 strm<<"**SUPERIORS: Empty\n"; 00309 return; 00310 } 00311 else 00312 strm<<"**SUPERIORS:\n"; 00313 00314 vcl_list<vtol_topology_object*>::const_iterator i; 00315 for (i=superiors_.begin();i!= superiors_.end();++i) 00316 { 00317 for (int n=0; n<blanking+2; ++n) strm << ' '; 00318 (*i)->print(); 00319 } 00320 } 00321 00322 void vtol_topology_object::describe(vcl_ostream &strm, 00323 int blanking) const 00324 { 00325 describe_inferiors(strm,blanking); 00326 describe_superiors(strm,blanking); 00327 } 00328 00329 00330 // temperary methods used for testing 00331 00332 00333 //--------------------------------------------------------------------------- 00334 //: Compute lists of vertices 00335 //--------------------------------------------------------------------------- 00336 vcl_vector<vtol_vertex *> *vtol_topology_object::compute_vertices(void) 00337 { 00338 vcl_cout << "Compute vertices\n"; 00339 return 0; 00340 } 00341 00342 00343 //--------------------------------------------------------------------------- 00344 //: Compute lists of zero chains 00345 //--------------------------------------------------------------------------- 00346 vcl_vector<vtol_zero_chain *> * 00347 vtol_topology_object::compute_zero_chains(void) 00348 { 00349 vcl_cout << "Compute zero_chains\n"; 00350 return 0; 00351 } 00352 00353 //--------------------------------------------------------------------------- 00354 //: compute lists of edges 00355 //--------------------------------------------------------------------------- 00356 00357 vcl_vector<vtol_edge *> *vtol_topology_object::compute_edges(void) 00358 { 00359 vcl_cout << "Compute edges\n"; 00360 return 0; 00361 } 00362 00363 //--------------------------------------------------------------------------- 00364 //: compute lists of one chains 00365 //--------------------------------------------------------------------------- 00366 vcl_vector<vtol_one_chain *> * 00367 vtol_topology_object::compute_one_chains(void) 00368 { 00369 vcl_cout << "Compute one chains\n"; 00370 return 0; 00371 } 00372 00373 //--------------------------------------------------------------------------- 00374 //: compute lists of faces 00375 //--------------------------------------------------------------------------- 00376 vcl_vector<vtol_face *> *vtol_topology_object::compute_faces(void) 00377 { 00378 vcl_cout << "Compute faces\n"; 00379 return 0; 00380 } 00381 00382 //--------------------------------------------------------------------------- 00383 //: compute lists of two chains 00384 //--------------------------------------------------------------------------- 00385 vcl_vector<vtol_two_chain *> * 00386 vtol_topology_object::compute_two_chains(void) 00387 { 00388 vcl_cout << "Compute two chains\n"; 00389 return 0; 00390 } 00391 00392 //--------------------------------------------------------------------------- 00393 //: compute lists of blocks 00394 //--------------------------------------------------------------------------- 00395 vcl_vector<vtol_block *> *vtol_topology_object::compute_blocks(void) 00396 { 00397 vcl_cout << "Compute blocks\n"; 00398 return 0; 00399 } 00400 00401 //--------------------------------------------------------------------------- 00402 //: compute the bounding box from the set of vertices. 00403 // A generic method that applies to all topology_object(s) 00404 //--------------------------------------------------------------------------- 00405 void vtol_topology_object::compute_bounding_box() const 00406 { 00407 this->empty_bounding_box(); 00408 vertex_list verts; this->vertices(verts); 00409 for (vertex_list::iterator vit = verts.begin(); vit != verts.end(); ++vit) 00410 this->add_to_bounding_box((*vit)->get_bounding_box()); 00411 }