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