00001 // This is gel/vtol/vtol_topology_object.h 00002 #ifndef topology_object_h_ 00003 #define topology_object_h_ 00004 //: 00005 // \file 00006 // \brief base class for topology objects 00007 // \author Patricia A. Vrobel. 00008 00009 #include <vtol/vtol_topology_object_sptr.h> 00010 #include <vsol/vsol_spatial_object_2d.h> // parent class 00011 #include <vcl_vector.h> 00012 #include <vcl_list.h> 00013 #include <vcl_iosfwd.h> 00014 #include <vtol/vtol_vertex_sptr.h> 00015 #include <vtol/vtol_zero_chain_sptr.h> 00016 #include <vtol/vtol_edge_sptr.h> 00017 #include <vtol/vtol_one_chain_sptr.h> 00018 #include <vtol/vtol_face_sptr.h> 00019 #include <vtol/vtol_two_chain_sptr.h> 00020 #include <vtol/vtol_block_sptr.h> 00021 #include <vtol/vtol_chain_sptr.h> 00022 class vtol_topology_cache; 00023 00024 // Useful typedefs 00025 typedef vcl_vector<vtol_topology_object_sptr> topology_list; 00026 typedef vcl_vector<vtol_vertex_sptr> vertex_list; 00027 typedef vcl_vector<vtol_zero_chain_sptr> zero_chain_list; 00028 typedef vcl_vector<vtol_edge_sptr> edge_list; 00029 typedef vcl_vector<vtol_one_chain_sptr> one_chain_list; 00030 typedef vcl_vector<vtol_face_sptr> face_list; 00031 typedef vcl_vector<vtol_two_chain_sptr> two_chain_list; 00032 typedef vcl_vector<vtol_block_sptr> block_list; 00033 typedef vcl_vector<vtol_chain_sptr> chain_list; 00034 00035 //***************************************************************************** 00036 // ALL THE DERIVED AND NON-ABSTRACT CLASSES OF THIS CLASS MUST CALL 00037 // unlink_all_inferiors() IN THEIR DESTRUCTOR 00038 // unlink_all_inferiors() CANT BE CALLED DIRECTLY IN THIS CLASS, OTHERWISE 00039 // BAD VERSIONS OF METHODS SHOULD BE CALLED (C++ IS STUPID !) 00040 //***************************************************************************** 00041 00042 //: Base class for topology objects 00043 // The vtol_topology_object class is the interface base class for all 00044 // topological entities. There are only access methods in this class. 00045 // vtol_topology_object inherits from vtol_spatial_object, which is 00046 // the base class for all topology and geometry. 00047 // 00048 // The topology class hierarchy: 00049 // \verbatim 00050 // vtol_topology_object 00051 // | 00052 // --------------------------------------------------- 00053 // | | | | | | | 00054 // vertex zero_chain edge one_chain face two_chain block 00055 // | | | 00056 // vertex_2d edge_2d face_2d 00057 // \endverbatim 00058 // 00059 // (Actually, one_chain and two_chain share a common parent class vtol_chain, 00060 // but that's just a matter of convenience; conceptually, the scheme is this.) 00061 // 00062 // \verbatim 00063 // Incidence of: 00064 // (vsol_point) (vsol_curve) (vsol_surface) (vsol_volume) 00065 // Directed 00066 // Sequence of: vertex edge face 00067 // 00068 // \endverbatim 00069 // 00070 // The vertex, edge and face entities account for incidence between 00071 // points, curves and surfaces, respectively. For example, two vtol_edge(s) 00072 // are incident at exactly one vtol_vertex. That is, an edge does not 00073 // intersect itself or another edge, except possibly at a vertex. 00074 // The chain entities are directed sequences which define composite 00075 // structures. Each element of the chain has a sign associated with 00076 // with it denoting the "direction" of use in a boundary traversal. 00077 // For example, a closed vtol_one_chain (a 1-cycle) forms the boundary of 00078 // a surface region. Two adjacent surface regions (vtol_face(s)) use an 00079 // edge in the opposite sense in their bounding 1-chains. 00080 // 00081 // The data member "inferiors_" stores a list of all topology objects of 00082 // the type "below" the current one, which form the boundary of this one. 00083 // All these objects should have the current object listed in their "superiors_" 00084 // list. It is the responsibility of the superior to break the link with its 00085 // inferior, not vice versa, hence conceptually the "superiors_" entries are 00086 // under control of the referred superior object. Otherwise said, an object 00087 // cannot live without its inferiors (and will disappear when its inferiors 00088 // disappear), while an object can live without its superiors (and is just 00089 // notified of their appearance and disappearance by the entries listed in 00090 // its superiors_ list). 00091 // 00092 // As a consequence, the "inferior" does not obtain a new time stamp when its 00093 // superiors change (hence its "superiors_" list is mutable). 00094 // This also explains why the "superiors_" list consists of ordinary pointers, 00095 // not smart pointers: the refcount toggling is done from superior to 00096 // inferior (which requires its inferiors to be kept alive), not from inferior 00097 // to superior (which need not bother about its superiors' existence). 00098 // 00099 // \author 00100 // Patricia A. Vrobel. 00101 // \verbatim 00102 // Modifications 00103 // ported to vxl by Luis E. Galup 00104 // JLM November 2002 - added a local bounding box method 00105 // dec.2002 -Peter Vanroose- added chain_list (typedef) and cast_to_chain() 00106 // dec.2002 -Peter Vanroose- link_inferior() now takes smart pointer argument 00107 // sep.2004 -Peter Vanroose- made methods returning the inf_sup cache "const" 00108 // \endverbatim 00109 00110 class vtol_topology_object : public vsol_spatial_object_2d 00111 { 00112 //*************************************************************************** 00113 // Data members 00114 //*************************************************************************** 00115 00116 //--------------------------------------------------------------------------- 00117 // Description: cache system 00118 //--------------------------------------------------------------------------- 00119 mutable vtol_topology_cache *inf_sup_cache_; 00120 00121 protected: 00122 00123 //--------------------------------------------------------------------------- 00124 // Description: array of superiors 00125 //--------------------------------------------------------------------------- 00126 vcl_list<vtol_topology_object*> superiors_; 00127 00128 //--------------------------------------------------------------------------- 00129 // Description: array of inferiors 00130 //--------------------------------------------------------------------------- 00131 topology_list inferiors_; 00132 00133 enum vtol_topology_object_type 00134 { TOPOLOGY_NO_TYPE=0, 00135 VERTEX, 00136 ZEROCHAIN, 00137 EDGE, 00138 ONECHAIN, 00139 FACE, 00140 TRIFACE, 00141 INTENSITYFACE, 00142 INTENSITYFACE3D, 00143 DDBINTENSITYFACE, 00144 TWOCHAIN, 00145 TRIMESHTWOCHAIN, 00146 BLOCK, 00147 NUM_TOPOLOGYOBJECT_TYPES 00148 }; 00149 private: // has been superseded by is_a() 00150 //: Return the topology type 00151 // To be overridden by all subclasses 00152 virtual vtol_topology_object_type topology_type() const { return TOPOLOGY_NO_TYPE; } 00153 00154 public: 00155 //*************************************************************************** 00156 // Initialization 00157 //*************************************************************************** 00158 00159 //--------------------------------------------------------------------------- 00160 //: Default constructor 00161 //--------------------------------------------------------------------------- 00162 vtol_topology_object(); 00163 00164 //--------------------------------------------------------------------------- 00165 //: Constructor with given sizes for arrays of inferiors and superiors 00166 //--------------------------------------------------------------------------- 00167 vtol_topology_object(int num_inferiors, int num_superiors); 00168 00169 protected: 00170 //--------------------------------------------------------------------------- 00171 //: Destructor 00172 //--------------------------------------------------------------------------- 00173 virtual ~vtol_topology_object(); 00174 00175 public: 00176 //*************************************************************************** 00177 // Replaces dynamic_cast<T> 00178 //*************************************************************************** 00179 virtual vtol_topology_object *cast_to_topology_object() { return this; } 00180 virtual const vtol_topology_object*cast_to_topology_object()const{return this;} 00181 00182 //--------------------------------------------------------------------------- 00183 //: Return `this' if `this' is a vertex, 0 otherwise 00184 //--------------------------------------------------------------------------- 00185 virtual const vtol_vertex *cast_to_vertex() const { return 0; } 00186 00187 //--------------------------------------------------------------------------- 00188 //: Return `this' if `this' is a vertex, 0 otherwise 00189 //--------------------------------------------------------------------------- 00190 virtual vtol_vertex *cast_to_vertex() { return 0; } 00191 00192 //--------------------------------------------------------------------------- 00193 //: Return `this' if `this' is a zero_chain, 0 otherwise 00194 //--------------------------------------------------------------------------- 00195 virtual const vtol_zero_chain *cast_to_zero_chain() const { return 0; } 00196 00197 //--------------------------------------------------------------------------- 00198 //: Return `this' if `this' is a zero_chain, 0 otherwise 00199 //--------------------------------------------------------------------------- 00200 virtual vtol_zero_chain *cast_to_zero_chain() { return 0; } 00201 00202 //--------------------------------------------------------------------------- 00203 //: Return `this' if `this' is an edge, 0 otherwise 00204 //--------------------------------------------------------------------------- 00205 virtual const vtol_edge *cast_to_edge() const { return 0; } 00206 00207 //--------------------------------------------------------------------------- 00208 //: Return `this' if `this' is an edge, 0 otherwise 00209 //--------------------------------------------------------------------------- 00210 virtual vtol_edge *cast_to_edge() { return 0; } 00211 00212 //--------------------------------------------------------------------------- 00213 //: Return `this' if `this' is a chain, 0 otherwise 00214 //--------------------------------------------------------------------------- 00215 virtual const vtol_chain *cast_to_chain() const { return 0; } 00216 00217 //--------------------------------------------------------------------------- 00218 //: Return `this' if `this' is a chain, 0 otherwise 00219 //--------------------------------------------------------------------------- 00220 virtual vtol_chain *cast_to_chain() { return 0; } 00221 00222 //--------------------------------------------------------------------------- 00223 //: Return `this' if `this' is a one_chain, 0 otherwise 00224 //--------------------------------------------------------------------------- 00225 virtual const vtol_one_chain *cast_to_one_chain() const { return 0; } 00226 00227 //--------------------------------------------------------------------------- 00228 //: Return `this' if `this' is a one_chain, 0 otherwise 00229 //--------------------------------------------------------------------------- 00230 virtual vtol_one_chain *cast_to_one_chain() { return 0; } 00231 00232 //--------------------------------------------------------------------------- 00233 //: Return `this' if `this' is a face, 0 otherwise 00234 //--------------------------------------------------------------------------- 00235 virtual const vtol_face *cast_to_face() const { return 0; } 00236 00237 //--------------------------------------------------------------------------- 00238 //: Return `this' if `this' is a face, 0 otherwise 00239 //--------------------------------------------------------------------------- 00240 virtual vtol_face *cast_to_face() { return 0; } 00241 00242 //--------------------------------------------------------------------------- 00243 //: Return `this' if `this' is a two_chain, 0 otherwise 00244 //--------------------------------------------------------------------------- 00245 virtual const vtol_two_chain *cast_to_two_chain() const { return 0; } 00246 00247 //--------------------------------------------------------------------------- 00248 //: Return `this' if `this' is a two_chain, 0 otherwise 00249 //--------------------------------------------------------------------------- 00250 virtual vtol_two_chain *cast_to_two_chain() { return 0; } 00251 00252 //--------------------------------------------------------------------------- 00253 //: Return `this' if `this' is a block, 0 otherwise 00254 //--------------------------------------------------------------------------- 00255 virtual const vtol_block *cast_to_block() const { return 0; } 00256 00257 //--------------------------------------------------------------------------- 00258 //: Return `this' if `this' is a block, 0 otherwise 00259 //--------------------------------------------------------------------------- 00260 virtual vtol_block *cast_to_block() { return 0; } 00261 00262 //*************************************************************************** 00263 // Status report 00264 //*************************************************************************** 00265 00266 //--------------------------------------------------------------------------- 00267 //: Is `inferior' type valid for `this' ? 00268 //--------------------------------------------------------------------------- 00269 virtual bool valid_inferior_type(vtol_topology_object const* inf) const = 0; 00270 00271 //--------------------------------------------------------------------------- 00272 //: Is `superior' type valid for `this' ? 00273 //--------------------------------------------------------------------------- 00274 inline bool valid_superior_type(vtol_topology_object const* sup) const 00275 { return sup->valid_inferior_type(this); } 00276 00277 //--------------------------------------------------------------------------- 00278 //: Is `inferior' already an inferior of `this' ? 00279 //--------------------------------------------------------------------------- 00280 bool is_inferior(vtol_topology_object_sptr inferior) const; 00281 00282 //--------------------------------------------------------------------------- 00283 //: Is `superior' already a superior of `this' ? 00284 //--------------------------------------------------------------------------- 00285 bool is_superior(vtol_topology_object* const& superior) const; 00286 00287 //--------------------------------------------------------------------------- 00288 //: Number of inferiors 00289 //--------------------------------------------------------------------------- 00290 int numinf() const { return inferiors()->size(); } 00291 00292 //--------------------------------------------------------------------------- 00293 //: Number of superiors 00294 //--------------------------------------------------------------------------- 00295 int numsup() const { return superiors_.size(); } 00296 00297 //--------------------------------------------------------------------------- 00298 //: Return the superiors list (must be deallocated after use) 00299 //--------------------------------------------------------------------------- 00300 private: 00301 const topology_list *superiors() const; 00302 public: 00303 const vcl_list<vtol_topology_object*> *superiors_list() const {return &superiors_;} 00304 00305 //--------------------------------------------------------------------------- 00306 //: Return the inferiors list 00307 //--------------------------------------------------------------------------- 00308 topology_list *inferiors() { return &inferiors_; } 00309 const topology_list *inferiors() const { return &inferiors_; } 00310 00311 //--------------------------------------------------------------------------- 00312 //: Return the spatial type 00313 //--------------------------------------------------------------------------- 00314 virtual vsol_spatial_object_2d_type spatial_type()const{return TOPOLOGYOBJECT;} 00315 00316 //*************************************************************************** 00317 // Basic operations 00318 //*************************************************************************** 00319 00320 //--------------------------------------------------------------------------- 00321 //: Link `this' with an inferior `inferior' 00322 // REQUIRE: valid_inferior_type(inferior) and !is_inferior(inferior) 00323 //--------------------------------------------------------------------------- 00324 void link_inferior(vtol_topology_object_sptr inferior); 00325 00326 //--------------------------------------------------------------------------- 00327 //: Unlink `this' from the inferior `inferior' 00328 // REQUIRE: valid_inferior_type(inferior) and is_inferior(inferior) 00329 //--------------------------------------------------------------------------- 00330 void unlink_inferior(vtol_topology_object_sptr inferior); 00331 00332 //--------------------------------------------------------------------------- 00333 //: Unlink `this' from all its inferiors 00334 //--------------------------------------------------------------------------- 00335 void unlink_all_inferiors(); 00336 00337 //--------------------------------------------------------------------------- 00338 //: Unlink `this' of the network 00339 //--------------------------------------------------------------------------- 00340 void unlink(); 00341 00342 //: Get list of vertices 00343 void vertices(vertex_list &list) const; 00344 //: Get list of zero chains 00345 void zero_chains(zero_chain_list &list) const; 00346 //: Get list of edges 00347 void edges(edge_list &list) const; 00348 //: Get list of one chains 00349 void one_chains(one_chain_list &list) const; 00350 //: Get list of faces 00351 void faces(face_list &list) const; 00352 //: Get list of two chains 00353 void two_chains(two_chain_list &list) const; 00354 //: Get list of blocks 00355 void blocks(block_list &list) const; 00356 private: 00357 //--------------------------------------------------------------------------- 00358 //: Get list of vertices 00359 // returned list must be deleted after use. 00360 // \deprecated - use vertices(list) instead 00361 //--------------------------------------------------------------------------- 00362 vertex_list *vertices() const; 00363 00364 //--------------------------------------------------------------------------- 00365 //: Get list of zero chains 00366 // returned list must be deleted after use. 00367 // \deprecated - use zero_chains(list) instead 00368 //--------------------------------------------------------------------------- 00369 zero_chain_list *zero_chains() const; 00370 00371 //--------------------------------------------------------------------------- 00372 //: Get list of edges 00373 // returned list must be deleted after use. 00374 // \deprecated - use edges(list) instead 00375 //--------------------------------------------------------------------------- 00376 edge_list *edges() const; 00377 00378 //--------------------------------------------------------------------------- 00379 //: Get list of one chains 00380 // returned list must be deleted after use. 00381 // \deprecated - use one_chains(list) instead 00382 //--------------------------------------------------------------------------- 00383 one_chain_list *one_chains() const; 00384 00385 //--------------------------------------------------------------------------- 00386 //: Get list of faces 00387 // returned list must be deleted after use. 00388 // \deprecated - use faces(list) instead 00389 //--------------------------------------------------------------------------- 00390 face_list *faces() const; 00391 00392 //--------------------------------------------------------------------------- 00393 //: Get list of two chains 00394 // returned list must be deleted after use. 00395 // \deprecated - use two_chains(list) instead 00396 //--------------------------------------------------------------------------- 00397 two_chain_list *two_chains() const; 00398 00399 //--------------------------------------------------------------------------- 00400 //: Get list of blocks 00401 // returned list must be deleted after use. 00402 // \deprecated - use blocks(list) instead 00403 //--------------------------------------------------------------------------- 00404 block_list *blocks() const; 00405 public: 00406 //--------------------------------------------------------------------------- 00407 //: print and describe the objects 00408 //--------------------------------------------------------------------------- 00409 virtual void print(vcl_ostream &strm=vcl_cout) const; 00410 void describe_inferiors(vcl_ostream &strm=vcl_cout, int blanking=0) const; 00411 void describe_superiors(vcl_ostream &strm=vcl_cout, int blanking=0) const; 00412 virtual void describe(vcl_ostream &strm=vcl_cout, int blanking=0) const; 00413 00414 virtual void compute_bounding_box() const; //A local implementation 00415 00416 //--------------------------------------------------------------------------- 00417 //: compute lists of vertices 00418 // \warning should not be used by clients 00419 //--------------------------------------------------------------------------- 00420 virtual vcl_vector<vtol_vertex*> *compute_vertices(); 00421 00422 //--------------------------------------------------------------------------- 00423 //: compute lists of zero chains 00424 // \warning should not be used by clients 00425 //--------------------------------------------------------------------------- 00426 virtual vcl_vector<vtol_zero_chain*> *compute_zero_chains(); 00427 00428 //--------------------------------------------------------------------------- 00429 //: compute lists of edges 00430 // \warning should not be used by clients 00431 //--------------------------------------------------------------------------- 00432 virtual vcl_vector<vtol_edge*> *compute_edges(); 00433 00434 //--------------------------------------------------------------------------- 00435 //: compute lists of one chains 00436 // \warning should not be used by clients 00437 //--------------------------------------------------------------------------- 00438 virtual vcl_vector<vtol_one_chain*> *compute_one_chains(); 00439 00440 //--------------------------------------------------------------------------- 00441 //: compute lists of faces 00442 // \warning should not be used by clients 00443 //--------------------------------------------------------------------------- 00444 virtual vcl_vector<vtol_face*> *compute_faces(); 00445 00446 //--------------------------------------------------------------------------- 00447 //: compute lists of two chains 00448 // \warning should not be used by clients 00449 //--------------------------------------------------------------------------- 00450 virtual vcl_vector<vtol_two_chain*> *compute_two_chains(); 00451 00452 //--------------------------------------------------------------------------- 00453 //: compute lists of blocks 00454 // \warning should not be used by clients 00455 //--------------------------------------------------------------------------- 00456 virtual vcl_vector<vtol_block*> *compute_blocks(); 00457 00458 private: 00459 // declare a friend class 00460 friend class vtol_topology_cache; 00461 }; 00462 00463 #endif // topology_object_h_