1 // This is gel/vtol/vtol_topology_object.h
2 #ifndef topology_object_h_
3 #define topology_object_h_
4 //:
5 // \file
6 // \brief base class for topology objects
7 // \author Patricia A. Vrobel.
8 
9 #include <vector>
10 #include <list>
11 #include <iostream>
12 #include <iosfwd>
13 #include <vtol/vtol_topology_object_sptr.h>
14 #include <vsol/vsol_spatial_object_2d.h> // parent class
15 #ifdef _MSC_VER
16 #  include <vcl_msvc_warnings.h>
17 #endif
18 #include <vtol/vtol_vertex_sptr.h>
19 #include <vtol/vtol_zero_chain_sptr.h>
20 #include <vtol/vtol_edge_sptr.h>
21 #include <vtol/vtol_one_chain_sptr.h>
22 #include <vtol/vtol_face_sptr.h>
23 #include <vtol/vtol_two_chain_sptr.h>
24 #include <vtol/vtol_block_sptr.h>
25 #include <vtol/vtol_chain_sptr.h>
26 class vtol_topology_cache;
27 
28 // Useful typedefs
29 typedef std::vector<vtol_topology_object_sptr> topology_list;
30 typedef std::vector<vtol_vertex_sptr>          vertex_list;
31 typedef std::vector<vtol_zero_chain_sptr>      zero_chain_list;
32 typedef std::vector<vtol_edge_sptr>            edge_list;
33 typedef std::vector<vtol_one_chain_sptr>       one_chain_list;
34 typedef std::vector<vtol_face_sptr>            face_list;
35 typedef std::vector<vtol_two_chain_sptr>       two_chain_list;
36 typedef std::vector<vtol_block_sptr>           block_list;
37 typedef std::vector<vtol_chain_sptr>           chain_list;
38 
39 //*****************************************************************************
40 // ALL THE DERIVED AND NON-ABSTRACT CLASSES OF THIS CLASS MUST CALL
41 // unlink_all_inferiors() IN THEIR DESTRUCTOR
42 // unlink_all_inferiors() CANT BE CALLED DIRECTLY IN THIS CLASS, OTHERWISE
43 // BAD VERSIONS OF METHODS SHOULD BE CALLED (C++ IS STUPID !)
44 //*****************************************************************************
45 
46 //: Base class for topology objects
47 // The vtol_topology_object class is the interface base class for all
48 // topological entities. There are only access methods in this class.
49 // vtol_topology_object inherits from vtol_spatial_object, which is
50 // the base class for all topology and geometry.
51 //
52 // The topology class hierarchy:
53 // \verbatim
54 //                             vtol_topology_object
55 //                                   |
56 //             ---------------------------------------------------
57 //             |        |       |       |       |       |        |
58 //         vertex  zero_chain  edge  one_chain  face  two_chain  block
59 //             |                |               |
60 //        vertex_2d           edge_2d          face_2d
61 // \endverbatim
62 //
63 // (Actually, one_chain and two_chain share a common parent class vtol_chain,
64 //  but that's just a matter of convenience; conceptually, the scheme is this.)
65 //
66 // \verbatim
67 // Incidence of:
68 //       (vsol_point)      (vsol_curve)     (vsol_surface)    (vsol_volume)
69 // Directed
70 // Sequence of:       vertex           edge             face
71 //
72 // \endverbatim
73 //
74 // The vertex, edge and face entities account for incidence between
75 // points, curves and surfaces, respectively. For example, two vtol_edge(s)
76 // are incident at exactly one vtol_vertex.  That is, an edge does not
77 // intersect itself or another edge, except possibly at a vertex.
78 // The chain entities are directed sequences which define composite
79 // structures. Each element of the chain has a sign associated with
80 // with it denoting the "direction" of use in a boundary traversal.
81 // For example, a closed vtol_one_chain (a 1-cycle) forms the boundary of
82 // a surface region. Two adjacent surface regions (vtol_face(s)) use an
83 // edge in the opposite sense in their bounding 1-chains.
84 //
85 // The data member "inferiors_" stores a list of all topology objects of
86 // the type "below" the current one, which form the boundary of this one.
87 // All these objects should have the current object listed in their "superiors_"
88 // list.  It is the responsibility of the superior to break the link with its
89 // inferior, not vice versa, hence conceptually the "superiors_" entries are
90 // under control of the referred superior object.  Otherwise said, an object
91 // cannot live without its inferiors (and will disappear when its inferiors
92 // disappear), while an object can live without its superiors (and is just
93 // notified of their appearance and disappearance by the entries listed in
94 // its superiors_ list).
95 //
96 // As a consequence, the "inferior" does not obtain a new time stamp when its
97 // superiors change (hence its "superiors_" list is mutable).
98 // This also explains why the "superiors_" list consists of ordinary pointers,
99 // not smart pointers:  the refcount toggling is done from superior to
100 // inferior (which requires its inferiors to be kept alive), not from inferior
101 // to superior (which need not bother about its superiors' existence).
102 //
103 // \author
104 //    Patricia A. Vrobel.
105 // \verbatim
106 //  Modifications
107 //   ported to vxl by Luis E. Galup
108 //   JLM November 2002 - added a local bounding box method
109 //   dec.2002 -Peter Vanroose- added chain_list (typedef) and cast_to_chain()
110 //   dec.2002 -Peter Vanroose- link_inferior() now takes smart pointer argument
111 //   sep.2004 -Peter Vanroose- made methods returning the inf_sup cache "const"
112 // \endverbatim
113 
114 class vtol_topology_object : public vsol_spatial_object_2d
115 {
116   //***************************************************************************
117   // Data members
118   //***************************************************************************
119 
120   //---------------------------------------------------------------------------
121   // Description: cache system
122   //---------------------------------------------------------------------------
123   mutable vtol_topology_cache *inf_sup_cache_;
124 
125  protected:
126 
127   //---------------------------------------------------------------------------
128   // Description: array of superiors
129   //---------------------------------------------------------------------------
130   std::list<vtol_topology_object*> superiors_;
131 
132   //---------------------------------------------------------------------------
133   // Description: array of inferiors
134   //---------------------------------------------------------------------------
135   topology_list inferiors_;
136 
137   enum vtol_topology_object_type
138   { TOPOLOGY_NO_TYPE=0,
139     VERTEX,
140     ZEROCHAIN,
141     EDGE,
142     ONECHAIN,
143     FACE,
144     TRIFACE,
145     INTENSITYFACE,
146     INTENSITYFACE3D,
147     DDBINTENSITYFACE,
148     TWOCHAIN,
149     TRIMESHTWOCHAIN,
150     BLOCK,
151     NUM_TOPOLOGYOBJECT_TYPES
152   };
153  private: // has been superseded by is_a()
154   //: Return the topology type
155   // To be overridden by all subclasses
topology_type()156   virtual vtol_topology_object_type topology_type() const { return TOPOLOGY_NO_TYPE; }
157 
158  public:
159   //***************************************************************************
160   // Initialization
161   //***************************************************************************
162 
163   //---------------------------------------------------------------------------
164   //: Default constructor
165   //---------------------------------------------------------------------------
166   vtol_topology_object();
167 
168   //---------------------------------------------------------------------------
169   //: Constructor with given sizes for arrays of inferiors and superiors
170   //---------------------------------------------------------------------------
171   vtol_topology_object(int num_inferiors, int num_superiors);
172 
173  protected:
174   //---------------------------------------------------------------------------
175   //: Destructor
176   //---------------------------------------------------------------------------
177   ~vtol_topology_object() override;
178 
179  public:
180   //***************************************************************************
181   // Replaces dynamic_cast<T>
182   //***************************************************************************
cast_to_topology_object()183   vtol_topology_object *cast_to_topology_object() override { return this; }
cast_to_topology_object()184   const vtol_topology_object*cast_to_topology_object()const override{return this;}
185 
186   //---------------------------------------------------------------------------
187   //: Return `this' if `this' is a vertex, 0 otherwise
188   //---------------------------------------------------------------------------
cast_to_vertex()189   virtual const vtol_vertex *cast_to_vertex() const { return nullptr; }
190 
191   //---------------------------------------------------------------------------
192   //: Return `this' if `this' is a vertex, 0 otherwise
193   //---------------------------------------------------------------------------
cast_to_vertex()194   virtual vtol_vertex *cast_to_vertex() { return nullptr; }
195 
196   //---------------------------------------------------------------------------
197   //: Return `this' if `this' is a zero_chain, 0 otherwise
198   //---------------------------------------------------------------------------
cast_to_zero_chain()199   virtual const vtol_zero_chain *cast_to_zero_chain() const { return nullptr; }
200 
201   //---------------------------------------------------------------------------
202   //: Return `this' if `this' is a zero_chain, 0 otherwise
203   //---------------------------------------------------------------------------
cast_to_zero_chain()204   virtual vtol_zero_chain *cast_to_zero_chain() { return nullptr; }
205 
206   //---------------------------------------------------------------------------
207   //: Return `this' if `this' is an edge, 0 otherwise
208   //---------------------------------------------------------------------------
cast_to_edge()209   virtual const vtol_edge *cast_to_edge() const { return nullptr; }
210 
211   //---------------------------------------------------------------------------
212   //: Return `this' if `this' is an edge, 0 otherwise
213   //---------------------------------------------------------------------------
cast_to_edge()214   virtual vtol_edge *cast_to_edge() { return nullptr; }
215 
216   //---------------------------------------------------------------------------
217   //: Return `this' if `this' is a chain, 0 otherwise
218   //---------------------------------------------------------------------------
cast_to_chain()219   virtual const vtol_chain *cast_to_chain() const { return nullptr; }
220 
221   //---------------------------------------------------------------------------
222   //: Return `this' if `this' is a chain, 0 otherwise
223   //---------------------------------------------------------------------------
cast_to_chain()224   virtual vtol_chain *cast_to_chain() { return nullptr; }
225 
226   //---------------------------------------------------------------------------
227   //: Return `this' if `this' is a one_chain, 0 otherwise
228   //---------------------------------------------------------------------------
cast_to_one_chain()229   virtual const vtol_one_chain *cast_to_one_chain() const { return nullptr; }
230 
231   //---------------------------------------------------------------------------
232   //: Return `this' if `this' is a one_chain, 0 otherwise
233   //---------------------------------------------------------------------------
cast_to_one_chain()234   virtual vtol_one_chain *cast_to_one_chain() { return nullptr; }
235 
236   //---------------------------------------------------------------------------
237   //: Return `this' if `this' is a face, 0 otherwise
238   //---------------------------------------------------------------------------
cast_to_face()239   virtual const vtol_face *cast_to_face() const { return nullptr; }
240 
241   //---------------------------------------------------------------------------
242   //: Return `this' if `this' is a face, 0 otherwise
243   //---------------------------------------------------------------------------
cast_to_face()244   virtual vtol_face *cast_to_face() { return nullptr; }
245 
246   //---------------------------------------------------------------------------
247   //: Return `this' if `this' is a two_chain, 0 otherwise
248   //---------------------------------------------------------------------------
cast_to_two_chain()249   virtual const vtol_two_chain *cast_to_two_chain() const { return nullptr; }
250 
251   //---------------------------------------------------------------------------
252   //: Return `this' if `this' is a two_chain, 0 otherwise
253   //---------------------------------------------------------------------------
cast_to_two_chain()254   virtual vtol_two_chain *cast_to_two_chain() { return nullptr; }
255 
256   //---------------------------------------------------------------------------
257   //: Return `this' if `this' is a block, 0 otherwise
258   //---------------------------------------------------------------------------
cast_to_block()259   virtual const vtol_block *cast_to_block() const { return nullptr; }
260 
261   //---------------------------------------------------------------------------
262   //: Return `this' if `this' is a block, 0 otherwise
263   //---------------------------------------------------------------------------
cast_to_block()264   virtual vtol_block *cast_to_block() { return nullptr; }
265 
266   //***************************************************************************
267   // Status report
268   //***************************************************************************
269 
270   //---------------------------------------------------------------------------
271   //: Is `inferior' type valid for `this' ?
272   //---------------------------------------------------------------------------
273   virtual bool valid_inferior_type(vtol_topology_object const* inf) const = 0;
274 
275   //---------------------------------------------------------------------------
276   //: Is `superior' type valid for `this' ?
277   //---------------------------------------------------------------------------
valid_superior_type(vtol_topology_object const * sup)278   inline bool valid_superior_type(vtol_topology_object const* sup) const
279   { return sup->valid_inferior_type(this); }
280 
281   //---------------------------------------------------------------------------
282   //: Is `inferior' already an inferior of `this' ?
283   //---------------------------------------------------------------------------
284   bool is_inferior(const vtol_topology_object_sptr& inferior) const;
285 
286   //---------------------------------------------------------------------------
287   //: Is `superior' already a superior of `this' ?
288   //---------------------------------------------------------------------------
289   bool is_superior(vtol_topology_object* const& superior) const;
290 
291   //---------------------------------------------------------------------------
292   //: Number of inferiors
293   //---------------------------------------------------------------------------
numinf()294   int numinf() const { return inferiors()->size(); }
295 
296   //---------------------------------------------------------------------------
297   //: Number of superiors
298   //---------------------------------------------------------------------------
numsup()299   int numsup() const { return superiors_.size(); }
300 
301   //---------------------------------------------------------------------------
302   //: Return the superiors list (must be deallocated after use)
303   //---------------------------------------------------------------------------
304  private:
305   const topology_list *superiors() const;
306  public:
superiors_list()307   const std::list<vtol_topology_object*> *superiors_list() const {return &superiors_;}
308 
309   //---------------------------------------------------------------------------
310   //: Return the inferiors list
311   //---------------------------------------------------------------------------
inferiors()312         topology_list *inferiors() { return &inferiors_; }
inferiors()313   const topology_list *inferiors() const { return &inferiors_; }
314 
315   //---------------------------------------------------------------------------
316   //: Return the spatial type
317   //---------------------------------------------------------------------------
spatial_type()318   vsol_spatial_object_2d_type spatial_type()const override{return TOPOLOGYOBJECT;}
319 
320   //***************************************************************************
321   // Basic operations
322   //***************************************************************************
323 
324   //---------------------------------------------------------------------------
325   //: Link `this' with an inferior `inferior'
326   //  REQUIRE: valid_inferior_type(inferior) and !is_inferior(inferior)
327   //---------------------------------------------------------------------------
328   void link_inferior(const vtol_topology_object_sptr& inferior);
329 
330   //---------------------------------------------------------------------------
331   //: Unlink `this' from the inferior `inferior'
332   //  REQUIRE: valid_inferior_type(inferior) and is_inferior(inferior)
333   //---------------------------------------------------------------------------
334   void unlink_inferior(const vtol_topology_object_sptr& inferior);
335 
336   //---------------------------------------------------------------------------
337   //: Unlink `this' from all its inferiors
338   //---------------------------------------------------------------------------
339   void unlink_all_inferiors();
340 
341   //---------------------------------------------------------------------------
342   //: Unlink `this' of the network
343   //---------------------------------------------------------------------------
344   void unlink();
345 
346   //: Get list of vertices
347   void vertices(vertex_list &list) const;
348   //: Get list of zero chains
349   void zero_chains(zero_chain_list &list) const;
350   //: Get list of edges
351   void edges(edge_list &list) const;
352   //: Get list of one chains
353   void one_chains(one_chain_list &list) const;
354   //: Get list of faces
355   void faces(face_list &list) const;
356   //: Get list of two chains
357   void two_chains(two_chain_list &list) const;
358   //: Get list of blocks
359   void blocks(block_list &list) const;
360  private:
361   //---------------------------------------------------------------------------
362   //: Get list of vertices
363   // returned list must be deleted after use.
364   // \deprecated - use vertices(list) instead
365   //---------------------------------------------------------------------------
366   vertex_list *vertices() const;
367 
368   //---------------------------------------------------------------------------
369   //: Get list of zero chains
370   // returned list must be deleted after use.
371   // \deprecated - use zero_chains(list) instead
372   //---------------------------------------------------------------------------
373   zero_chain_list *zero_chains() const;
374 
375   //---------------------------------------------------------------------------
376   //: Get list of edges
377   // returned list must be deleted after use.
378   // \deprecated - use edges(list) instead
379   //---------------------------------------------------------------------------
380   edge_list *edges() const;
381 
382   //---------------------------------------------------------------------------
383   //: Get list of one chains
384   // returned list must be deleted after use.
385   // \deprecated - use one_chains(list) instead
386   //---------------------------------------------------------------------------
387   one_chain_list *one_chains() const;
388 
389   //---------------------------------------------------------------------------
390   //: Get list of faces
391   // returned list must be deleted after use.
392   // \deprecated - use faces(list) instead
393   //---------------------------------------------------------------------------
394   face_list *faces() const;
395 
396   //---------------------------------------------------------------------------
397   //: Get list of two chains
398   // returned list must be deleted after use.
399   // \deprecated - use two_chains(list) instead
400   //---------------------------------------------------------------------------
401   two_chain_list *two_chains() const;
402 
403   //---------------------------------------------------------------------------
404   //: Get list of blocks
405   // returned list must be deleted after use.
406   // \deprecated - use blocks(list) instead
407   //---------------------------------------------------------------------------
408   block_list *blocks() const;
409  public:
410   //---------------------------------------------------------------------------
411   //: print and describe the objects
412   //---------------------------------------------------------------------------
413   void print(std::ostream &strm=std::cout) const override;
414   void describe_inferiors(std::ostream &strm=std::cout, int blanking=0) const;
415   void describe_superiors(std::ostream &strm=std::cout, int blanking=0) const;
416   void describe(std::ostream &strm=std::cout, int blanking=0) const override;
417 
418   void compute_bounding_box() const override; //A local implementation
419 
420   //---------------------------------------------------------------------------
421   //: compute lists of vertices
422   // \warning should not be used by clients
423   //---------------------------------------------------------------------------
424   virtual std::vector<vtol_vertex*> *compute_vertices();
425 
426   //---------------------------------------------------------------------------
427   //: compute lists of zero chains
428   // \warning should not be used by clients
429   //---------------------------------------------------------------------------
430   virtual std::vector<vtol_zero_chain*> *compute_zero_chains();
431 
432   //---------------------------------------------------------------------------
433   //: compute lists of edges
434   // \warning should not be used by clients
435   //---------------------------------------------------------------------------
436   virtual std::vector<vtol_edge*> *compute_edges();
437 
438   //---------------------------------------------------------------------------
439   //: compute lists of one chains
440   // \warning should not be used by clients
441   //---------------------------------------------------------------------------
442   virtual std::vector<vtol_one_chain*> *compute_one_chains();
443 
444   //---------------------------------------------------------------------------
445   //: compute lists of faces
446   // \warning should not be used by clients
447   //---------------------------------------------------------------------------
448   virtual std::vector<vtol_face*> *compute_faces();
449 
450   //---------------------------------------------------------------------------
451   //: compute lists of two chains
452   // \warning should not be used by clients
453   //---------------------------------------------------------------------------
454   virtual std::vector<vtol_two_chain*> *compute_two_chains();
455 
456   //---------------------------------------------------------------------------
457   //: compute lists of blocks
458   // \warning should not be used by clients
459   //---------------------------------------------------------------------------
460   virtual std::vector<vtol_block*> *compute_blocks();
461 
462  private:
463   // declare a friend class
464   friend class vtol_topology_cache;
465 };
466 
467 #endif // topology_object_h_
468