contrib/mul/msm/msm_curve.cxx
Go to the documentation of this file.
00001 #include "msm_curve.h"
00002 //:
00003 // \file
00004 // \brief List of points making a curve - for defining boundaries
00005 // \author Tim Cootes
00006 
00007 #include <vcl_iostream.h>
00008 #include <vcl_sstream.h>
00009 #include <vsl/vsl_indent.h>
00010 #include <vsl/vsl_binary_io.h>
00011 #include <vsl/vsl_vector_io.h>
00012 #include <mbl/mbl_parse_block.h>
00013 #include <mbl/mbl_read_props.h>
00014 #include <mbl/mbl_parse_int_list.h>
00015 #include <mbl/mbl_parse_keyword_list.h>
00016 #include <vul/vul_string.h>
00017 #include <vcl_iterator.h> // For vcl_back_inserter
00018 #include <vcl_cassert.h>
00019 
00020 // Default Constructor
00021 msm_curve::msm_curve()
00022 {
00023 }
00024 
00025 //: Define as range of indices [lo,hi]
00026 msm_curve::msm_curve(unsigned lo, unsigned hi,
00027                      bool open, vcl_string name)
00028 {
00029   set(lo,hi,open,name);
00030 }
00031 
00032 void msm_curve::set(const vcl_vector<unsigned>& index,
00033                     bool open, vcl_string name)
00034 {
00035   index_ = index;
00036   open_=open;
00037   name_=name;
00038 }
00039 
00040 //: Define as range of indices [lo,hi]
00041 void msm_curve::set(unsigned lo, unsigned hi,
00042                     bool open, vcl_string name)
00043 {
00044   assert(hi>lo);
00045   index_.resize(1+hi-lo);
00046   for (unsigned i=lo;i<=hi;++i) index_[i-lo]=i;
00047   open_=open;
00048   name_=name;
00049 }
00050 
00051 //: Return the largest index value
00052 unsigned msm_curve::max_index() const
00053 {
00054   if (index_.size()==0) return 0u;
00055   unsigned m=index_[0];
00056   for (unsigned i=1;i<index_.size();++i)
00057     if (index_[i]>m) m=index_[i];
00058   return m;
00059 }
00060 
00061 
00062 //: Adds offset to index of every point
00063 //  Useful when concatenating models
00064 void msm_curve::add_index_offset(int offset)
00065 {
00066   for (unsigned i=0;i<index_.size();++i)
00067     index_[i]=unsigned (index_[i]+offset);
00068 }
00069 
00070 //: Equality test
00071 bool msm_curve::operator==(const msm_curve& c) const
00072 {
00073   return (name_==c.name_) &&
00074          (open_==c.open_) &&
00075          (index_==c.index_);
00076 }
00077 
00078 
00079 //: Parse parameters in stream
00080 //  Expects
00081 // \verbatim
00082 // { name: Chin open: true indices: { 0 1 2 3 4 5 6 } }
00083 // \endverbatim
00084 void msm_curve::config_from_stream(vcl_istream& is)
00085 {
00086   // Cycle through stream and produce a map of properties
00087   vcl_string s = mbl_parse_block(is);
00088   vcl_istringstream ss(s);
00089   mbl_read_props_type props = mbl_read_props_ws(ss);
00090 
00091   name_= props.get_optional_property("name","");
00092   open_=vul_string_to_bool(props.get_optional_property("open","true"));
00093 
00094   index_.empty();
00095   vcl_istringstream ss1(props.get_required_property("indices"));
00096   mbl_parse_int_list(ss1, vcl_back_inserter(index_), unsigned());
00097 
00098   // Check for unused props
00099   mbl_read_props_look_for_unused_props(
00100       "msm_curve::config_from_stream", props, mbl_read_props_type());
00101 }
00102 
00103 //=======================================================================
00104 // Method: print
00105 //=======================================================================
00106 
00107 void msm_curve::print_summary(vcl_ostream& os) const
00108 {
00109   os<<" { name: "<<name_<<" open: ";
00110   if (open_) os<<"true"; else os<<"false";
00111   os<<" indices: { ";
00112   for (unsigned i=0;i<index_.size();++i) os<<index_[i]<<' ';
00113   os<<"} } ";
00114 }
00115 
00116 //=======================================================================
00117 // Method: save
00118 //=======================================================================
00119 void msm_curve::b_write(vsl_b_ostream& bfs) const
00120 {
00121   vsl_b_write(bfs,short(1)); // Version
00122   vsl_b_write(bfs,name_);
00123   vsl_b_write(bfs,open_);
00124   vsl_b_write(bfs,index_);
00125 }
00126 
00127 //=======================================================================
00128 // Method: load
00129 //=======================================================================
00130 void msm_curve::b_read(vsl_b_istream& bfs)
00131 {
00132   short version;
00133   vsl_b_read(bfs,version);
00134   switch (version)
00135   {
00136     case (1):
00137       vsl_b_read(bfs,name_);
00138       vsl_b_read(bfs,open_);
00139       vsl_b_read(bfs,index_);
00140       break;
00141     default:
00142       vcl_cerr << "msm_curve::b_read() :\n"
00143                << "Unexpected version number " << version << '\n';
00144       bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00145       return;
00146   }
00147 }
00148 
00149 
00150 //=======================================================================
00151 // Associated function: operator<<
00152 //=======================================================================
00153 
00154 void vsl_b_write(vsl_b_ostream& bfs, const msm_curve& b)
00155 {
00156   b.b_write(bfs);
00157 }
00158 
00159 //=======================================================================
00160 // Associated function: operator>>
00161 //=======================================================================
00162 
00163 void vsl_b_read(vsl_b_istream& bfs, msm_curve& b)
00164 {
00165   b.b_read(bfs);
00166 }
00167 
00168 //=======================================================================
00169 // Associated function: operator<<
00170 //=======================================================================
00171 
00172 vcl_ostream& operator<<(vcl_ostream& os,const msm_curve& b)
00173 {
00174   b.print_summary(os);
00175   return os;
00176 }
00177 
00178 //: Stream output operator for class reference
00179 void vsl_print_summary(vcl_ostream& os,const msm_curve& b)
00180 {
00181  os << b;
00182 }
00183 
00184 
00185 //: Default constructor
00186 msm_curves::msm_curves()
00187 {
00188 }
00189 
00190 
00191 //: Construct as a single curve
00192 msm_curves::msm_curves(unsigned lo, unsigned hi,
00193                        bool open, vcl_string name)
00194 {
00195   resize(1);
00196   operator[](0)=msm_curve(lo,hi,open,name);
00197 }
00198 
00199 //: Return index of first curve with given name, or -1
00200 int msm_curves::which_curve(const vcl_string& name) const
00201 {
00202   for (unsigned i=0;i<size();++i)
00203     if (operator[](i).name()==name) return i;
00204   return -1;
00205 }
00206 
00207 //: Return the largest index value in any curve
00208 unsigned msm_curves::max_index() const
00209 {
00210   if (size()==0) return 0;
00211   unsigned m = operator[](0).max_index();
00212   for (unsigned j=1;j<size();++j)
00213     if (operator[](j).max_index()>m) m=operator[](j).max_index();
00214   return m;
00215 }
00216 
00217 //: Parse parameters in stream
00218 //  Expects
00219 // \verbatim
00220 // {
00221 //   curve: { name: Chin open: true indices: { 0 1 2 3 4 5 6 } }
00222 //   curve: { name: Nose open: false indices: { 11 : 15 } }
00223 // }
00224 // \endverbatim
00225 void msm_curves::config_from_stream(vcl_istream& is)
00226 {
00227   vcl_vector<vcl_string> curve_params;
00228   mbl_parse_keyword_list(is,"curve:",curve_params);
00229   resize(curve_params.size());
00230   for (unsigned i=0;i<size();++i)
00231   {
00232     vcl_istringstream ss(curve_params[i]);
00233     operator[](i).config_from_stream(ss);
00234   }
00235 }
00236 
00237 //: Save to text file
00238 bool msm_curves::write_text_file(const vcl_string& path)
00239 {
00240   vcl_ofstream ofs(path.c_str());
00241   if (!ofs) return false;
00242   ofs<<(*this);
00243   return true;
00244 }
00245 
00246 //: Read from text file
00247 bool msm_curves::read_text_file(const vcl_string& path)
00248 {
00249   vcl_ifstream ifs(path.c_str());
00250   if (!ifs) return false;
00251   vcl_string label;
00252   ifs>>label;
00253   if (label!="curves:")
00254   {
00255     throw mbl_exception_parse_error("msm_curves::read_text_file: Expected 'curves', got: "+label);
00256     return false;
00257   }
00258   config_from_stream(ifs);
00259   return true;
00260 }
00261 
00262 //: Stream output operator
00263 vcl_ostream& operator<<(vcl_ostream& os,const msm_curves& c)
00264 {
00265   os<<"curves: {\n";
00266   for (unsigned i=0;i<c.size();++i)
00267   {
00268     os<<"  curve: "<<c[i]<<vcl_endl;
00269   }
00270   os<<'}'<<vcl_endl;
00271   return os;
00272 }
00273 
00274 //: Binary file stream output operator for class reference
00275 void vsl_b_write(vsl_b_ostream& bfs, const msm_curves& c)
00276 {
00277   vsl_b_write(bfs,short(1)); // Version number
00278   vsl_b_write(bfs,unsigned(c.size()));
00279   for (unsigned i=0;i<c.size();++i)
00280     vsl_b_write(bfs,c[i]);
00281 }
00282 
00283 //: Binary file stream input operator for class reference
00284 void vsl_b_read(vsl_b_istream& bfs, msm_curves& c)
00285 {
00286   short version;
00287   unsigned n;
00288   vsl_b_read(bfs,version);
00289   switch (version)
00290   {
00291     case (1):
00292       vsl_b_read(bfs,n);
00293       c.resize(n);
00294       for (unsigned i=0;i<c.size();++i)
00295         vsl_b_read(bfs,c[i]);
00296       break;
00297     default:
00298       vcl_cerr << "vsl_b_read(bfs,msm_curves) :\n"
00299                << "Unexpected version number " << version << '\n';
00300       bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00301       return;
00302   }
00303 }
00304 
00305