1 // This is gel/vsol/vsol_spatial_object_2d.cxx
2 #include <iostream>
3 #include "vsol_spatial_object_2d.h"
4 //:
5 // \file
6 
7 #ifdef _MSC_VER
8 #  include "vcl_msvc_warnings.h"
9 #endif
10 #include <vsol/vsol_box_2d.h>
11 #include "vsl/vsl_binary_loader.h"
12 
13 const float vsol_spatial_object_2d::eps=1.0e-3f;
14 //int vsol_spatial_object_2d::tagcount_=0;
15 
16 const char * vsol_spatial_object_2d::SpatialTypes[] =
17 {
18   "NO_TYPE             ",
19   "TOPOLOGYOBJECT      ",
20   "POINT               ",
21   "CURVE               ",
22   "REGION              ",
23   "SPATIALGROUP        ",
24   "NUM_SPATIALOBJECT_TYPES"
25 };
26 
vsol_spatial_object_2d()27 vsol_spatial_object_2d::vsol_spatial_object_2d()
28   : bounding_box_(nullptr)
29 {
30   this->tag_ = 0;
31   this->id_ = 0;
32   set_tag_id(++tagcount_);
33 }
34 
vsol_spatial_object_2d(vsol_spatial_object_2d const & s)35 vsol_spatial_object_2d::vsol_spatial_object_2d(vsol_spatial_object_2d const& s)
36   : vsol_spatial_object(s), bounding_box_(nullptr)
37 {
38   this->tag_ = 0;
39   this->id_ = s.get_id();
40   set_tag_id(++tagcount_);
41 }
42 
get_name() const43 const char * vsol_spatial_object_2d::get_name() const
44 {
45   vsol_spatial_object_2d_type type =spatial_type();
46   if (type > 0 && type < vsol_spatial_object_2d::NUM_SPATIALOBJECT_TYPES)
47     return SpatialTypes[type];
48   else
49     return SpatialTypes[0];
50 }
51 
52 vsol_spatial_object_2d::~vsol_spatial_object_2d() = default;
53 
54 //: Return IO version number;
version() const55 short vsol_spatial_object_2d::version() const
56 {
57   return 1;
58 }
59 
compute_bounding_box() const60 void vsol_spatial_object_2d::compute_bounding_box() const
61 {
62   if (!bounding_box_) bounding_box_=new vsol_box_2d; bounding_box_->touch();
63 }
64 
empty_bounding_box() const65 void vsol_spatial_object_2d::empty_bounding_box() const
66 {
67   bounding_box_=new vsol_box_2d;
68 }
69 
set_bounding_box(double x,double y) const70 void vsol_spatial_object_2d::set_bounding_box(double x, double y) const
71 {
72   bounding_box_=new vsol_box_2d; bounding_box_->add_point(x,y);
73 }
74 
set_bounding_box(vsol_box_2d_sptr const & box) const75 void vsol_spatial_object_2d::set_bounding_box(vsol_box_2d_sptr const& box) const
76 {
77   bounding_box_=new vsol_box_2d(*box);
78 }
79 
add_to_bounding_box(double x,double y) const80 void vsol_spatial_object_2d::add_to_bounding_box(double x, double y) const
81 {
82   if (!bounding_box_) bounding_box_=new vsol_box_2d; bounding_box_->add_point(x,y);
83 }
84 
add_to_bounding_box(vsol_box_2d_sptr const & comp_box) const85 void vsol_spatial_object_2d::add_to_bounding_box(vsol_box_2d_sptr const& comp_box) const
86 {
87   if (!bounding_box_)
88     bounding_box_=new vsol_box_2d;
89   bounding_box_->grow_minmax_bounds(comp_box);
90 }
91 
92 //: Bounds Accessors:
93 // min_ and max_ are provided as methods on vsol_spatial_object_2d
94 // to be consistent with the previous interface
95 // Additional bounds accessors are available directly
96 // on vsol_box_2d.  - JLM
97 
check_update_bounding_box() const98 void vsol_spatial_object_2d::check_update_bounding_box() const
99 {
100   if (!bounding_box_)
101   {
102     bounding_box_ = new vsol_box_2d;
103     this->compute_bounding_box();
104     bounding_box_->touch();
105     return;
106   }
107   if (bounding_box_->older(this))
108   { // NOTE: first touch then compute, to avoid infinite loop!! - PVr
109     bounding_box_->touch();
110     this->compute_bounding_box();
111   }
112 }
113 
get_min_x() const114 double vsol_spatial_object_2d::get_min_x() const
115 {
116   check_update_bounding_box(); return bounding_box_->get_min_x();
117 }
118 
get_max_x() const119 double vsol_spatial_object_2d::get_max_x() const
120 {
121   check_update_bounding_box(); return bounding_box_->get_max_x();
122 }
123 
get_min_y() const124 double vsol_spatial_object_2d::get_min_y() const
125 {
126   check_update_bounding_box(); return bounding_box_->get_min_y();
127 }
128 
get_max_y() const129 double vsol_spatial_object_2d::get_max_y() const
130 {
131   check_update_bounding_box(); return bounding_box_->get_max_y();
132 }
133 
134 //: Binary save self to stream.
135 void
b_write(vsl_b_ostream & os) const136 vsol_spatial_object_2d::b_write(vsl_b_ostream &os) const
137 {
138   vsl_b_write(os, this->version());
139   vsl_b_write(os, this->tag_);
140   vsl_b_write(os, this->id_);
141 }
142 
143 //: Binary load self from stream.
144 void
b_read(vsl_b_istream & is)145 vsol_spatial_object_2d::b_read(vsl_b_istream &is)
146 {
147   if (!is) return;
148 
149   short ver;
150   vsl_b_read(is, ver);
151   switch (ver)
152   {
153    case 1:
154     vsl_b_read(is, this->tag_);
155     vsl_b_read(is, this->id_);
156     break;
157 
158    default:
159     std::cerr << "I/O ERROR: vsol_spatial_object_2d::b_read(vsl_b_istream&)\n"
160              << "           Unknown version number "<< ver << '\n';
161     is.is().clear(std::ios::badbit); // Set an unrecoverable IO error on stream
162     return;
163   }
164 }
165 
166 //==============================================
167 //: Allows derived class to be loaded by base-class pointer.
168 //  A loader object exists which is invoked by calls
169 //  of the form "vsl_b_read(os,base_ptr);".  This loads derived class
170 //  objects from the stream, places them on the heap and
171 //  returns a base class pointer.
172 //  In order to work the loader object requires
173 //  an instance of each derived class that might be
174 //  found.  This function gives the model class to
175 //  the appropriate loader.
vsl_add_to_binary_loader(vsol_spatial_object_2d const & b)176 void vsl_add_to_binary_loader(vsol_spatial_object_2d const& b)
177 {
178   vsl_binary_loader<vsol_spatial_object_2d>::instance().add(b);
179 }
180