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