contrib/gel/vsol/vsol_spatial_object_2d.h
Go to the documentation of this file.
00001 // This is gel/vsol/vsol_spatial_object_2d.h
00002 #ifndef vsol_spatial_object_2d_h_
00003 #define vsol_spatial_object_2d_h_
00004 //-----------------------------------------------------------------------------
00005 //:
00006 // \file
00007 // \brief Base class of 2D spatial entities (topology geometry group)
00008 //
00009 //   vsol_spatial_object_2d is the base class of all 2d 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_2d 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/10 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/21 Ming-Ching Chang  Make clear distinction between 2D and 3D.
00035 //                                Remove the postfix _2d _3d from the cast_to functions.
00036 //   2004/09/27 Peter Vanroose added empty_bounding_box(), set_bounding_box(box)
00037 //                             and add_to_bounding_box(box)
00038 //   2004/11/15 H.Can Aras added inheritance from vsol_spatial_object, which introduces
00039 //                         inheritance from vul_timestamp, ref_count and vsol_flags_id
00040 //                         classes. members related to id, flags and tag are moved to
00041 //                         newly-created vsol_flags_id class.
00042 // \endverbatim
00043 //-----------------------------------------------------------------------------
00044 
00045 #include <vcl_string.h>
00046 #include <vcl_iostream.h>
00047 #include <vsol/vsol_spatial_object.h>
00048 #include <vsl/vsl_fwd.h>
00049 #include <vsol/vsol_spatial_object_2d_sptr.h>
00050 #include <vsol/vsol_box_2d_sptr.h>
00051 class vtol_topology_object;
00052 class vsol_spatial_object_2d;
00053 class vsol_point_2d;
00054 class vsol_curve_2d;
00055 class vsol_region_2d;
00056 class vsol_group_2d;
00057 
00058 class vsol_spatial_object_2d : public vsol_spatial_object
00059 {
00060  protected:
00061   // Data Members--------------------------------------------------------------
00062   
00063  private:
00064   mutable vsol_box_2d_sptr bounding_box_; // rectangular bounding area
00065 
00066  public:
00067   enum vsol_spatial_object_2d_type
00068   {
00069       SPATIAL_NO_TYPE=0,
00070       TOPOLOGYOBJECT,
00071       POINT,
00072       CURVE,
00073       REGION,
00074       SPATIALGROUP,
00075       VOLUME,
00076       NUM_SPATIALOBJECT_TYPES
00077   };
00078 
00079   static const char *SpatialTypes[];
00080   static const float eps;
00081 
00082   // Constructors/Destructors--------------------------------------------------
00083   virtual ~vsol_spatial_object_2d();
00084 
00085  protected:
00086   //: constructor initializes basic vsol_spatial_object_2d attributes.
00087   //   bounding_box is set to NULL.
00088   vsol_spatial_object_2d();
00089   vsol_spatial_object_2d(vsol_spatial_object_2d const& other);
00090   void not_applicable(vcl_string const& message) const
00091   {
00092       vcl_cerr <<message<<"() function call not applicable\tfor 2d spatial object "
00093                <<get_name()<<" !\n";
00094   }
00095 
00096  public:
00097   // Data Access---------------------------------------------------------------
00098 
00099   //: get the spatial type
00100   virtual vsol_spatial_object_2d_type spatial_type() const=0;
00101 
00102   const char *get_name() const; // derived from spatial_type()
00103 
00104   //: unprotect the object
00105   void un_protect() { this->unref(); }
00106 
00107   //---------------------------------------------------------------------------
00108   //: Clone `this': creation of a new object and initialization
00109   //  See Prototype pattern
00110   //---------------------------------------------------------------------------
00111   virtual vsol_spatial_object_2d* clone() const=0;
00112 
00113   // Binary I/O------------------------------------------------------------------
00114 
00115   //: Return a platform independent string identifying the class
00116   virtual vcl_string is_a() const=0;
00117 
00118   //: Return IO version number;
00119   short version() const;
00120 
00121   //: Binary save self to stream.
00122   virtual void b_write(vsl_b_ostream &os) const;
00123 
00124   //: Binary load self from stream.
00125   virtual void b_read(vsl_b_istream &is);
00126 
00127   virtual void print(vcl_ostream &strm=vcl_cout) const { describe(strm); }
00128   virtual void describe(vcl_ostream& =vcl_cout, int /*blanking*/=0) const { not_applicable("describe"); }
00129 
00130   friend inline vcl_ostream &operator<<(vcl_ostream &, vsol_spatial_object_2d const&);
00131   friend inline vcl_ostream &operator<<(vcl_ostream &, vsol_spatial_object_2d const*);
00132 
00133   //Operators
00134   virtual bool operator==(vsol_spatial_object_2d const& obj) const { return this==&obj; }
00135   bool operator!=(vsol_spatial_object_2d const& obj) { return !(*this==obj); }
00136 
00137   // Data Control--------------------------------------------------------------
00138 
00139   vsol_box_2d_sptr get_bounding_box() const { check_update_bounding_box(); return bounding_box_; }
00140 
00141   double get_min_x() const;
00142   double get_max_x() const;
00143   double get_min_y() const;
00144   double get_max_y() const;
00145 
00146  protected:
00147   //: make the bounding box empty; often first step in bounding box calculation
00148   void empty_bounding_box() const; // mutable const
00149   //: set the bounding box; to be used in bounding box calculation
00150   void set_bounding_box(vsol_box_2d_sptr const& box) const; // mutable const
00151   //: set the bounding box to a single point, discarding the old bounding box
00152   // This is a "const" method since the bounding box is a "mutable" data member:
00153   // calculating the bounding box does not change the object.
00154   void set_bounding_box(double x, double y) const;
00155   //: add a point to the bounding box and take the convex union
00156   // This is a "const" method since the bounding box is a "mutable" data member:
00157   // calculating the bounding box does not change the object.
00158   void add_to_bounding_box(double x, double y) const;
00159   //: set the existing bounding box to the convex union of it with the given box
00160   void add_to_bounding_box(vsol_box_2d_sptr const& box) const; // mutable const
00161   //: grow to the largest dim. of this and \a box, i.e., take the convex union
00162   void grow_minmax_bounds(vsol_box_2d_sptr const& b) const{ add_to_bounding_box(b); }
00163   //: compute bounding box, do nothing in this case except touching the box
00164   virtual void compute_bounding_box() const;
00165   //: Test consistency of bound
00166   void check_update_bounding_box() const;
00167 
00168  public:
00169   //---------------------------------------------------------------------------
00170   //: The same behavior than dynamic_cast<>.
00171   // Needed because VXL is not necessarily compiled with -frtti
00172   //---------------------------------------------------------------------------
00173   virtual vsol_spatial_object_2d* cast_to_spatial_object() { return this; }
00174   virtual vsol_spatial_object_2d const* cast_to_spatial_object() const{return this;}
00175 
00176   virtual vtol_topology_object* cast_to_topology_object() {return 0;}
00177   virtual vtol_topology_object const* cast_to_topology_object()const{return 0;}
00178 
00179   virtual vsol_spatial_object_2d* cast_to_vsol_spatial_object() { return 0; }
00180   virtual vsol_spatial_object_2d const* cast_to_vsol_spatial_object() const { return 0; }
00181   virtual vsol_point_2d* cast_to_point() { return 0; }
00182   virtual vsol_point_2d const* cast_to_point() const { return 0; }
00183   virtual vsol_curve_2d *cast_to_curve() { return 0; }
00184   virtual vsol_curve_2d const* cast_to_curve() const { return 0; }
00185   virtual vsol_region_2d* cast_to_region() { return 0; }
00186   virtual vsol_region_2d const* cast_to_region() const { return 0; }
00187   virtual vsol_group_2d *cast_to_group() { return 0; }
00188   virtual vsol_group_2d const* cast_to_group() const { return 0; }
00189 };
00190 
00191 // inline member functions
00192 
00193 inline vcl_ostream &operator<<(vcl_ostream &strm, vsol_spatial_object_2d const& so)
00194 {
00195   so.print(strm);
00196   return strm;
00197 }
00198 
00199 inline vcl_ostream &operator<<(vcl_ostream &strm, vsol_spatial_object_2d const* so)
00200 {
00201   if (so)
00202     so->print(strm);
00203   else
00204     strm << "NULL Spatial Object.\n";
00205   return strm;
00206 }
00207 
00208 //: Stream output operator for class pointer
00209 inline void vsl_print_summary(vcl_ostream& os, vsol_spatial_object_2d const* so)
00210 {
00211   os << so;
00212 }
00213 
00214 //: Allows derived class to be loaded by base-class pointer
00215 //  A loader object exists which is invoked by calls
00216 //  of the form "vsl_b_read(os,base_ptr)".  This loads derived class
00217 //  objects from the disk, places them on the heap and
00218 //  returns a base class pointer.
00219 //  In order to work the loader object requires
00220 //  an instance of each derived class that might be
00221 //  found.  This function gives the model class to
00222 //  the appropriate loader.
00223 void vsl_add_to_binary_loader(vsol_spatial_object_2d const& b);
00224 
00225 #endif // vsol_spatial_object_2d_h_