contrib/gel/vsol/vsol_spatial_object_3d.h
Go to the documentation of this file.
00001 // This is gel/vsol/vsol_spatial_object_3d.h
00002 #ifndef vsol_spatial_object_3d_h_
00003 #define vsol_spatial_object_3d_h_
00004 //-----------------------------------------------------------------------------
00005 //:
00006 // \file
00007 // \brief Base class of 3D spatial entities (topology geometry group)
00008 //
00009 //   vsol_spatial_object_3d is the base class of all 3d spatial entities.
00010 //   It provides ref counting, timestamps, a bounding box, ...
00011 //
00012 // \author
00013 //     Patricia A. Vrobel
00014 //
00015 // \verbatim
00016 //  Modifications
00017 //   1995/12/xx JLM
00018 //           Replaced the SpatialGroup pointer by an IUBox bounding volume.
00019 //           See the discussion in SpatialGroup.h for the rationale.
00020 //           The bounding volume is updated according to a timestamp
00021 //           mechanism similar to that used in 3D display. That is,
00022 //           if the vsol_spatial_object_3d is modified it is "touched" to
00023 //           set the timestamp.  Then, any request to bounding information
00024 //           automatically updates the bounding volume if necessary.
00025 //   1996/12/16 Peter VANROOSE  made destructor protected
00026 //   2000/05/03 Peter TU        ported to vxl
00027 //   2000/05/12 François BERTEL add cast_to_group() because VXL is not compiled
00028 //                              with -frtti :-(
00029 //   2002/12/12 Peter Vanroose added cast_to_region()
00030 //   2003/01/08 Peter Vanroose made bounding box "mutable" and changed interface
00031 //   2003/01/09 Peter Vanroose deprecated set_min_x() etc. and replaced with
00032 //                       more safe set_bounding_box() and add_to_bounding_box().
00033 //                     (The old setup only worked correctly when (0,0) in bbox.)
00034 //   2004/09/06 Peter Vanroose  Added safe cast methods to surface_3d
00035 //   2004/09/17 MingChing Chang  Add cast_to_region().
00036 //   2004/09/21 Ming-Ching Chang  Make clear distinction between 2D and 3D.
00037 //                                Add some missing parts to 3D classes.
00038 //   2004/09/27 Peter Vanroose added empty_bounding_box(), set_bounding_box(box)
00039 //                             and add_to_bounding_box(box)
00040 //   2004/11/15 H.Can Aras added inheritance from vsol_spatial_object, which introduces
00041 //                         inheritance from vul_timestamp, ref_count and vsol_flags_id
00042 //                         classes. members related to id, flags and tag are moved to
00043 //                         newly-created vsol_flags_id class.
00044 // \endverbatim
00045 //-----------------------------------------------------------------------------
00046 
00047 #include <vcl_string.h>
00048 #include <vcl_iostream.h>
00049 #include <vsol/vsol_spatial_object.h>
00050 #include <vsl/vsl_fwd.h>
00051 #include <vsol/vsol_spatial_object_3d_sptr.h>
00052 #include <vsol/vsol_box_3d_sptr.h>
00053 class vtol_topology_object;
00054 class vsol_spatial_object_3d;
00055 class vsol_point_3d;
00056 class vsol_curve_3d;
00057 class vsol_surface_3d;
00058 class vsol_region_3d;
00059 class vsol_volume_3d;
00060 class vsol_group_3d;
00061 
00062 #ifndef vsol_spatial_object_flags_
00063 #define vsol_spatial_object_flags_
00064 
00065 // system flags
00066 const unsigned int VSOL_UNIONBIT       = 0x80000000;
00067 const unsigned int VSOL_SYSTEM_FLAG1   = 0x01000000;
00068 // user flags
00069 const unsigned int VSOL_FLAG1          = 0x40000000;
00070 const unsigned int VSOL_FLAG2          = 0x20000000;
00071 const unsigned int VSOL_FLAG3          = 0x1000000;
00072 const unsigned int VSOL_FLAG4          = 0x08000000;
00073 const unsigned int VSOL_FLAG5          = 0x04000000;
00074 const unsigned int VSOL_FLAG6          = 0x02000000;
00075 
00076 // mask for last three bytes of tag field
00077 const unsigned int VSOL_DEXID_BITS     = 0x00FFFFFF;
00078 const unsigned int VSOL_FLAG_BITS      = 0xFF000000;
00079 
00080 #endif // vsol_spatial_object_flags_
00081 
00082 class vsol_spatial_object_3d : public vsol_spatial_object
00083 {
00084  protected:
00085   // Data Members--------------------------------------------------------------
00086 
00087  private:
00088   mutable vsol_box_3d_sptr bounding_box_; // 3d rectangular bounding area
00089 
00090  public:
00091   enum vsol_spatial_object_3d_type
00092   {
00093       SPATIAL_NO_TYPE=0,
00094       TOPOLOGYOBJECT,
00095       POINT,
00096       CURVE,
00097       REGION,
00098       SPATIALGROUP,
00099       VOLUME,
00100       NUM_SPATIALOBJECT_TYPES
00101   };
00102 
00103   static const char *SpatialTypes[];
00104   static const float eps;
00105 
00106   // Constructors/Destructors--------------------------------------------------
00107   virtual ~vsol_spatial_object_3d();
00108 
00109  protected:
00110   //: constructor initializes basic vsol_spatial_object_3d attributes.
00111   //   bounding_box is set to NULL.
00112   vsol_spatial_object_3d();
00113   vsol_spatial_object_3d(vsol_spatial_object_3d const& other);
00114   void not_applicable(vcl_string const& message) const
00115   {
00116       vcl_cerr <<message<<"() function call not applicable\tfor 3d spatial object "
00117                <<get_name()<<" !\n";
00118   }
00119 
00120  public:
00121   // Data Access---------------------------------------------------------------
00122 
00123   //: get the spatial type
00124   virtual vsol_spatial_object_3d_type spatial_type() const=0;
00125 
00126   const char *get_name() const; // derived from spatial_type()
00127 
00128   //: unprotect the object
00129   void un_protect() { this->unref(); }
00130 
00131   //---------------------------------------------------------------------------
00132   //: Clone `this': creation of a new object and initialization
00133   //  See Prototype pattern
00134   //---------------------------------------------------------------------------
00135   virtual vsol_spatial_object_3d* clone() const=0;
00136 
00137   // Binary I/O------------------------------------------------------------------
00138 
00139   //: Return a platform independent string identifying the class
00140   virtual vcl_string is_a() const=0;
00141 
00142   //: Return IO version number;
00143   short version() const;
00144 
00145   //: Binary save self to stream.
00146   virtual void b_write(vsl_b_ostream &os) const;
00147 
00148   //: Binary load self from stream.
00149   virtual void b_read(vsl_b_istream &is);
00150 
00151   virtual void print(vcl_ostream &strm=vcl_cout) const { describe(strm); }
00152   virtual void describe(vcl_ostream& =vcl_cout, int /*blanking*/=0) const { not_applicable("describe"); }
00153 
00154   friend inline vcl_ostream &operator<<(vcl_ostream &, vsol_spatial_object_3d const&);
00155   friend inline vcl_ostream &operator<<(vcl_ostream &, vsol_spatial_object_3d const*);
00156 
00157   //Operators
00158   virtual bool operator==(vsol_spatial_object_3d const& obj) const { return this==&obj; }
00159   bool operator!=(vsol_spatial_object_3d const& obj) { return !(*this==obj); }
00160 
00161   // Data Control--------------------------------------------------------------
00162 
00163   vsol_box_3d_sptr get_bounding_box() const { check_update_bounding_box(); return bounding_box_; }
00164 
00165   double get_min_x() const;
00166   double get_max_x() const;
00167   double get_min_y() const;
00168   double get_max_y() const;
00169   double get_min_z() const;
00170   double get_max_z() const;
00171 
00172  protected:
00173   //: make the bounding box empty; often first step in bounding box calculation
00174   void empty_bounding_box() const; // mutable const
00175   //: set the bounding box; to be used in bounding box calculation
00176   void set_bounding_box(vsol_box_3d_sptr const& box) const; // mutable const
00177   //: set the bounding box to a single point, discarding the old bounding box
00178   // This is a "const" method since the bounding box is a "mutable" data member:
00179   // calculating the bounding box does not change the object.
00180   void set_bounding_box(double x, double y, double z) const;
00181   //: add a point to the bounding box and take the convex union
00182   // This is a "const" method since the bounding box is a "mutable" data member:
00183   // calculating the bounding box does not change the object.
00184   void add_to_bounding_box(double x, double y, double z) const;
00185   //: set the existing bounding box to the convex union of it with the given box
00186   void add_to_bounding_box(vsol_box_3d_sptr const& box) const; // mutable const
00187   //: grow to the largest dim. of this and \a box, i.e., take the convex union
00188   void grow_minmax_bounds(vsol_box_3d_sptr const& b) const{ add_to_bounding_box(b); }
00189   //: compute bounding box, do nothing in this case except touching the box
00190   virtual void compute_bounding_box() const;
00191   //: Test consistency of bound
00192   void check_update_bounding_box() const;
00193 
00194  public:
00195   //---------------------------------------------------------------------------
00196   //: The same behavior than dynamic_cast<>.
00197   // Needed because VXL is not necessarily compiled with -frtti
00198   //---------------------------------------------------------------------------
00199   virtual vsol_spatial_object_3d* cast_to_spatial_object() { return this; }
00200   virtual vsol_spatial_object_3d const* cast_to_spatial_object() const{return this;}
00201 
00202   virtual vtol_topology_object* cast_to_topology_object() {return 0;}
00203   virtual vtol_topology_object const* cast_to_topology_object()const{return 0;}
00204 
00205   virtual vsol_spatial_object_3d* cast_to_vsol_spatial_object() { return 0; }
00206   virtual vsol_spatial_object_3d const* cast_to_vsol_spatial_object() const { return 0; }
00207   virtual vsol_point_3d* cast_to_point() { return 0; }
00208   virtual vsol_point_3d const* cast_to_point() const { return 0; }
00209   virtual vsol_curve_3d *cast_to_curve() { return 0; }
00210   virtual vsol_curve_3d const* cast_to_curve() const { return 0; }
00211   virtual vsol_surface_3d* cast_to_surface() { return 0; }
00212   virtual vsol_surface_3d const* cast_to_surface() const { return 0; }
00213   virtual vsol_volume_3d* cast_to_volume() { return 0; }
00214   virtual vsol_volume_3d const* cast_to_volume() const { return 0; }
00215   virtual vsol_region_3d* cast_to_region() { return 0; }
00216   virtual vsol_region_3d const* cast_to_region() const { return 0; }
00217   virtual vsol_group_3d *cast_to_group() { return 0; }
00218   virtual vsol_group_3d const* cast_to_group() const { return 0; }
00219 };
00220 
00221 // inline member functions
00222 
00223 inline vcl_ostream &operator<<(vcl_ostream &strm, vsol_spatial_object_3d const& so)
00224 {
00225   so.print(strm);
00226   return strm;
00227 }
00228 
00229 inline vcl_ostream &operator<<(vcl_ostream &strm, vsol_spatial_object_3d const* so)
00230 {
00231   if (so)
00232     so->print(strm);
00233   else
00234     strm << "NULL Spatial Object.\n";
00235   return strm;
00236 }
00237 
00238 //: Stream output operator for class pointer
00239 inline void vsl_print_summary(vcl_ostream& os, vsol_spatial_object_3d const* so)
00240 {
00241   os << so;
00242 }
00243 
00244 //: Allows derived class to be loaded by base-class pointer
00245 //  A loader object exists which is invoked by calls
00246 //  of the form "vsl_b_read(os,base_ptr)".  This loads derived class
00247 //  objects from the disk, places them on the heap and
00248 //  returns a base class pointer.
00249 //  In order to work the loader object requires
00250 //  an instance of each derived class that might be
00251 //  found.  This function gives the model class to
00252 //  the appropriate loader.
00253 void vsl_add_to_binary_loader(vsol_spatial_object_3d const& b);
00254 
00255 #endif // vsol_spatial_object_3d_h_