1 // This is gel/vtol/vtol_topology_object.cxx
2 #include "vtol_topology_object.h"
3 //:
4 // \file
5 
6 #include <vtol/vtol_topology_cache.h>
7 #include <vtol/vtol_vertex.h>
8 #include <cassert>
9 #ifdef _MSC_VER
10 #  include "vcl_msvc_warnings.h"
11 #endif
12 
13 //***************************************************************************
14 // Initialization
15 //***************************************************************************
16 
17 //---------------------------------------------------------------------------
18 // Default constructor
19 //---------------------------------------------------------------------------
vtol_topology_object()20 vtol_topology_object::vtol_topology_object() : superiors_(0), inferiors_(0) {
21   inf_sup_cache_= new vtol_topology_cache(this);
22   touch();
23 }
24 
25 //---------------------------------------------------------------------------
26 //: Constructor with given sizes for arrays of inferiors and superiors
27 //---------------------------------------------------------------------------
vtol_topology_object(const int num_inferiors,const int num_superiors)28 vtol_topology_object::vtol_topology_object(const int num_inferiors,
29                                            const int num_superiors)
30   :superiors_(num_superiors),
31    inferiors_(num_inferiors)
32 {
33   inf_sup_cache_=new vtol_topology_cache(this);
34   touch();
35 }
36 
37 //---------------------------------------------------------------------------
38 // Destructor
39 //---------------------------------------------------------------------------
~vtol_topology_object()40 vtol_topology_object::~vtol_topology_object()
41 {
42   delete inf_sup_cache_;
43 }
44 
45 //***************************************************************************
46 // Status report
47 //***************************************************************************
48 
49 //---------------------------------------------------------------------------
50 //: Is `inferior' already an inferior of `this' ?
51 //---------------------------------------------------------------------------
52 bool
is_inferior(const vtol_topology_object_sptr & inferior) const53 vtol_topology_object::is_inferior(const vtol_topology_object_sptr& inferior) const
54 {
55   topology_list::const_iterator i;
56   for (i=inferiors_.begin(); i!=inferiors_.end(); ++i)
57     if ((*i) == inferior)
58       return true;
59 
60   return false;
61 }
62 
63 //---------------------------------------------------------------------------
64 //: Is `superior' already a superior of `this' ?
65 //---------------------------------------------------------------------------
66 bool
is_superior(vtol_topology_object * const & superior) const67 vtol_topology_object::is_superior(vtol_topology_object* const& superior) const
68 {
69   std::list<vtol_topology_object*>::const_iterator i;
70   for (i=superiors_.begin(); i!=superiors_.end(); ++i)
71     if (*i == superior)
72       return true;
73 
74   return false;
75 }
76 
77 #if 0
78 //---------------------------------------------------------------------------
79 //: Return the superiors list (must be deallocated after use)
80 //---------------------------------------------------------------------------
81 const topology_list * vtol_topology_object::superiors(void) const
82 {
83   std::cerr << "*** Warning: superiors() is deprecated\n";
84   topology_list *result=new topology_list;
85   result->reserve(superiors_.size());
86 
87   std::list<vtol_topology_object*>::const_iterator i;
88   for (i=superiors_.begin();i!=superiors_.end();++i)
89     result->push_back(*i);
90 
91   return result;
92 }
93 #endif
94 
95 //***************************************************************************
96 // Basic operations
97 //***************************************************************************
98 
99 //---------------------------------------------------------------------------
100 //: Link `this' with an inferior `inferior'
101 // Require: valid_inferior_type(inferior) and !is_inferior(inferior)
102 //---------------------------------------------------------------------------
link_inferior(const vtol_topology_object_sptr & inferior)103 void vtol_topology_object::link_inferior(const vtol_topology_object_sptr& inferior)
104 {
105   // require
106   assert(valid_inferior_type(inferior->cast_to_topology_object()));
107 
108   // Do nothing if already an inferior
109   if ( is_inferior(inferior) )  return;
110 
111   assert(!is_inferior(inferior));
112   assert(!inferior->is_superior(this));
113 
114   inferiors_.push_back(inferior);
115   inferior->superiors_.push_back(this);
116   inferior->touch();//The inferior's topology cache is now stale as well JLM
117   touch();
118 }
119 
120 //---------------------------------------------------------------------------
121 //: Unlink `this' with the inferior `inferior'
122 // Require: valid_inferior_type(inferior) and is_inferior(inferior)
123 //---------------------------------------------------------------------------
unlink_inferior(const vtol_topology_object_sptr & inferior)124 void vtol_topology_object::unlink_inferior(const vtol_topology_object_sptr& inferior)
125 {
126   // require
127   assert(valid_inferior_type(inferior->cast_to_topology_object()));
128   assert(is_inferior(inferior));
129   assert(inferior->is_superior(this));
130 
131   auto i=inferior->superiors_.begin();
132   while ( i!=inferior->superiors_.end() && *i!=this ) ++i;
133   // check presence in "superiors_" list of inferior:
134   assert(*i==this);
135 
136   inferior->superiors_.erase(i); // unlink this from superiors_ list of inferior
137   inferior->touch();
138   auto j=inferiors_.begin();
139   while ( j!=inferiors_.end() && (*j)!=inferior) ++j;
140   // check presence in "inferiors_" list:
141   assert((*j)==inferior);
142 
143   inferiors()->erase(j);
144   touch();
145 }
146 
147 //---------------------------------------------------------------------------
148 //: Unlink `this' from all its inferiors
149 //---------------------------------------------------------------------------
unlink_all_inferiors()150 void vtol_topology_object::unlink_all_inferiors() {
151   // remove superior-inferior link, running through inferiors list back-to-front
152   while (!inferiors_.empty())
153     unlink_inferior(inferiors_.back());
154 }
155 
156 //---------------------------------------------------------------------------
157 //: Unlink `this' of the network
158 //---------------------------------------------------------------------------
unlink()159 void vtol_topology_object::unlink() {
160   while (!superiors_.empty())
161     superiors_.front()->unlink_inferior(this);
162   unlink_all_inferiors();
163 }
164 
165 //: get list of vertices
166 
vertices() const167 vertex_list *vtol_topology_object::vertices() const {
168   auto* new_list=new vertex_list;
169   inf_sup_cache_->vertices(*new_list);
170   return new_list;
171 }
172 
173 //: get list of vertices
174 
vertices(vertex_list & verts) const175 void vtol_topology_object::vertices(vertex_list& verts) const
176 {
177   inf_sup_cache_->vertices(verts);
178 }
179 
180 //: get list of zero_chains
zero_chains() const181 zero_chain_list *vtol_topology_object::zero_chains() const {
182   auto* new_list=new zero_chain_list;
183   inf_sup_cache_->zero_chains(*new_list);
184   return new_list;
185 }
186 
187 //: get list of zero chains
zero_chains(zero_chain_list & zerochains) const188 void vtol_topology_object::zero_chains(zero_chain_list &zerochains) const
189 {
190   inf_sup_cache_->zero_chains(zerochains);
191 }
192 
193 //: get list of edges
194 
edges() const195 edge_list *vtol_topology_object::edges() const {
196   auto* new_list=new edge_list;
197   inf_sup_cache_->edges(*new_list);
198   return new_list;
199 }
200 
201 //: get list of edges
202 
edges(edge_list & edges) const203 void vtol_topology_object::edges(edge_list &edges) const
204 {
205   inf_sup_cache_->edges(edges);
206 }
207 
208 //: get list of one chains
209 
one_chains() const210 one_chain_list *vtol_topology_object::one_chains() const {
211   auto* new_list=new one_chain_list;
212   inf_sup_cache_->one_chains(*new_list);
213   return new_list;
214 }
215 
216 //: get list of one chains
217 
one_chains(one_chain_list & onechains) const218 void vtol_topology_object::one_chains(one_chain_list &onechains) const
219 {
220   inf_sup_cache_->one_chains(onechains);
221 }
222 
223 //: get list of faces
224 
faces() const225 face_list *vtol_topology_object::faces() const {
226   auto *new_list=new face_list;
227   inf_sup_cache_->faces(*new_list);
228   return new_list;
229 }
230 
231 //: get list of faces
232 
faces(face_list & face_list) const233 void vtol_topology_object::faces(face_list &face_list) const
234 {
235   inf_sup_cache_->faces(face_list);
236 }
237 
238 //: get list of two chains
239 
two_chains() const240 two_chain_list *vtol_topology_object::two_chains() const {
241   auto *new_list=new two_chain_list;
242   inf_sup_cache_->two_chains(*new_list);
243   return new_list;
244 }
245 
246 //: get list of two chains
247 
two_chains(two_chain_list & new_list) const248 void vtol_topology_object::two_chains(two_chain_list &new_list) const
249 {
250   inf_sup_cache_->two_chains(new_list);
251 }
252 
253 //: get list of blocks
254 
blocks() const255 block_list *vtol_topology_object::blocks() const {
256   auto *new_list=new block_list;
257   inf_sup_cache_->blocks(*new_list);
258   return new_list;
259 }
260 
261 //: get list of blocks
262 
blocks(block_list & new_list) const263 void vtol_topology_object::blocks(block_list &new_list) const
264 {
265   inf_sup_cache_->blocks(new_list);
266 }
267 
268 //: print the object
print(std::ostream & strm) const269 void vtol_topology_object::print(std::ostream &strm) const
270 {
271   strm<<"<vtol_topology_object "<<(void const *)this<<">\n"
272       <<"number of inferiors "<<numinf()<<std::endl
273       <<"number of superiors "<<numsup()<<std::endl;
274 }
275 
describe_inferiors(std::ostream & strm,int blanking) const276 void vtol_topology_object::describe_inferiors(std::ostream &strm,
277                                               int blanking) const
278 {
279   for (int n=0; n<blanking; ++n) strm << ' ';
280   if (inferiors()->empty())
281     strm<<"**INFERIORS:  Empty\n";
282   else
283     strm<<"**INFERIORS:\n";
284 
285   topology_list::const_iterator i;
286   for (i=inferiors()->begin();i!=inferiors()->end();++i)
287   {
288     for (int n=0; n<blanking+2; ++n) strm << ' ';
289     (*i)->print();
290   }
291 }
292 
describe_superiors(std::ostream & strm,int blanking) const293 void vtol_topology_object::describe_superiors(std::ostream &strm,
294                                               int blanking) const
295 {
296   for (int n=0; n<blanking; ++n) strm << ' ';
297   if (superiors_.empty()) {
298     strm<<"**SUPERIORS:  Empty\n";
299     return;
300   } else
301     strm<<"**SUPERIORS:\n";
302 
303   std::list<vtol_topology_object*>::const_iterator i;
304   for (i=superiors_.begin();i!= superiors_.end();++i)
305   {
306     for (int n=0; n<blanking+2; ++n) strm << ' ';
307     (*i)->print();
308   }
309 }
310 
describe(std::ostream & strm,int blanking) const311 void vtol_topology_object::describe(std::ostream &strm,
312                                     int blanking) const
313 {
314   describe_inferiors(strm,blanking);
315   describe_superiors(strm,blanking);
316 }
317 
318 
319 // temperary methods used for testing
320 
321 
322 //---------------------------------------------------------------------------
323 //: Compute lists of vertices
324 //---------------------------------------------------------------------------
compute_vertices()325 std::vector<vtol_vertex *> *vtol_topology_object::compute_vertices() {
326   std::cout << "Compute vertices\n";
327   return nullptr;
328 }
329 
330 //---------------------------------------------------------------------------
331 //: Compute lists of zero chains
332 //---------------------------------------------------------------------------
compute_zero_chains()333 std::vector<vtol_zero_chain *> *vtol_topology_object::compute_zero_chains() {
334   std::cout << "Compute zero_chains\n";
335   return nullptr;
336 }
337 
338 //---------------------------------------------------------------------------
339 //: compute lists of edges
340 //---------------------------------------------------------------------------
341 
compute_edges()342 std::vector<vtol_edge *> *vtol_topology_object::compute_edges() {
343   std::cout << "Compute edges\n";
344   return nullptr;
345 }
346 
347 //---------------------------------------------------------------------------
348 //: compute lists of one chains
349 //---------------------------------------------------------------------------
compute_one_chains()350 std::vector<vtol_one_chain *> *vtol_topology_object::compute_one_chains() {
351   std::cout << "Compute one chains\n";
352   return nullptr;
353 }
354 
355 //---------------------------------------------------------------------------
356 //: compute lists of faces
357 //---------------------------------------------------------------------------
compute_faces()358 std::vector<vtol_face *> *vtol_topology_object::compute_faces() {
359   std::cout << "Compute faces\n";
360   return nullptr;
361 }
362 
363 //---------------------------------------------------------------------------
364 //: compute lists of two chains
365 //---------------------------------------------------------------------------
compute_two_chains()366 std::vector<vtol_two_chain *> *vtol_topology_object::compute_two_chains() {
367   std::cout << "Compute two chains\n";
368   return nullptr;
369 }
370 
371 //---------------------------------------------------------------------------
372 //: compute lists of blocks
373 //---------------------------------------------------------------------------
compute_blocks()374 std::vector<vtol_block *> *vtol_topology_object::compute_blocks() {
375   std::cout << "Compute blocks\n";
376   return nullptr;
377 }
378 
379 //---------------------------------------------------------------------------
380 //: compute the bounding box from the set of vertices.
381 //  A generic method that applies to all topology_object(s)
382 //---------------------------------------------------------------------------
compute_bounding_box() const383 void vtol_topology_object::compute_bounding_box() const
384 {
385   this->empty_bounding_box();
386   vertex_list verts; this->vertices(verts);
387   for (auto & vert : verts)
388     this->add_to_bounding_box(vert->get_bounding_box());
389 }
390