Common.hpp
00001 //
00002 // Common structures and exceptions for SAL3D.
00003 // Copyright 2008-2010 AQSENSE, S.L.
00004 //
00005 #if !defined (AQSENSE_SAL3DPP_COMMON_HPP)
00006 #define AQSENSE_SAL3DPP_COMMON_HPP
00007 
00008 #if defined (_MSC_VER) && (_MSC_VER >= 1020)
00009 #pragma once
00010 #endif
00011 
00012 #if ! defined(__GNUC__)
00013     /* msvc and borland */
00014     #include <float.h>
00015 #endif
00016 
00017 #include <cassert>
00018 #include <cmath>
00019 #include <stdexcept>
00020 #include <vector>
00021 #include <memory>
00022 #include <cstdio>
00023 #include <cstring>
00024 #include <cstdarg>
00025 #include <sal3d/zmap.h>
00026 #include <sal3d/metricconfig.h>
00027 
00029 namespace sal3d
00030 {
00033     typedef sal3d_zmap_factors ZMapFactors;
00034 
00037     inline bool isNaN(float f)
00038     {
00039 #if defined(__GNUC__)
00040         return std::isnan(f);
00041 #else /* msvc and borland */
00042         return _isnan(f) != 0;
00043 #endif
00044     }
00045 
00062     class Error : public std::exception
00063     {
00064         public:
00065         sal3d_error e;
00066 
00073         Error()
00074         {
00075             e.value = SAL3D_ERROR_UNKNOWN;
00076             e.text[0] = '\0';
00077         }
00078 
00080         Error(const struct sal3d_error &ep)
00081             :e(ep)
00082         {
00083         }
00084 
00087         Error(int val, const char *format, ...)
00088         {
00089             va_list ap;
00090 
00091             va_start(ap, format);
00092             e.value = val;
00093 #ifndef WIN32
00094             std::
00095 #endif
00096             vsnprintf(e.text, sizeof(e.text), format, ap);
00097             va_end(ap);
00098         }
00099 
00102         Error(int val)
00103         {
00104             e.value = val;
00105             e.text[0] = '\0';
00106         }
00107 
00108         virtual ~Error () throw() { };
00109 
00112         virtual const char * what () const throw()
00113         {
00114             return e.text;
00115         }
00116 
00123         int
00124         fill_error(struct sal3d_error *es) const
00125         {
00126             if (es)
00127             {
00128                 es->value = e.value;
00129                 unsigned int i;
00130                 /* sizeof()-1 to make the '\0' always fit */
00131                 for(i=0; i < (sizeof(es->text)-1) && e.text[i] != '\0'; ++i)
00132                     es->text[i] = e.text[i];
00133                 es->text[i] = '\0';
00134             }
00135             return e.value;
00136         }
00137 
00147         static int set_no_error(struct sal3d_error *e)
00148         {
00149             if (e)
00150             {
00151                 e->value = static_cast<enum SAL3D_ERROR>(0);
00152                 e->text[0] = '\0';
00153             }
00154             return SAL3D_ERROR_OK;
00155         }
00156 
00166         static int set_error_msg(struct sal3d_error *e, int val,
00167                 const char *format, ...)
00168         {
00169             va_list ap;
00170 
00171             va_start(ap, format);
00172             if (e)
00173             {
00174                 e->value = val;
00175 #ifndef WIN32
00176                 std::
00177 #endif
00178                 vsnprintf(e->text, sizeof(e->text), format, ap);
00179             }
00180             va_end(ap);
00181 
00182             return val;
00183         }
00184 
00198         static int set_unknown_error(struct sal3d_error *e)
00199         {
00200             if (e)
00201             {
00202                 const char text[] = "Unknown error";
00203                 e->value = SAL3D_ERROR_UNKNOWN;
00204                 std::memcpy(e->text, text, sizeof text);
00205             }
00206             return SAL3D_ERROR_UNKNOWN;
00207         }
00208     };
00209 
00214     template <typename T>
00215     class Array1D
00216     {
00217         public:
00219             typedef T &reference;
00221             typedef const T &const_reference;
00223             typedef T *iterator;
00225             typedef const T *const_iterator;
00226 
00234             Array1D (T *values, int length):
00235                 _length (length),
00236                 _values (values),
00237                 _end (values + length)
00238             {
00239                 assert ( values != 0 && "The values pointer is NULL." );
00240                 assert ( length > 0 && "Invalid row length." );
00241             }
00242 
00248             int
00249             length () const
00250             {
00251                 return _length;
00252             }
00253 
00264             const_reference
00265             operator[] (int x) const
00266             {
00267                 assert ( x < length () && "Invalid value index." );
00268                 return *(_values + x);
00269             }
00270 
00280             reference
00281             operator[] (int x)
00282             {
00283                 return const_cast<T &> (
00284                         static_cast<const Array1D &>(*this)[x]);
00285             }
00286 
00293             const_iterator
00294             begin() const
00295             {
00296                 return _values;
00297             }
00298 
00305             iterator
00306             begin()
00307             {
00308                 return const_cast<iterator>(
00309                         static_cast<const Array1D &>(*this).begin());
00310             }
00311 
00319             const_iterator
00320             end() const
00321             {
00322                 return _end;
00323             }
00324 
00332             iterator
00333             end()
00334             {
00335                 return const_cast<iterator>(
00336                         static_cast<const Array1D &>(*this).end());
00337             }
00338 
00339         private:
00341             int _length;
00343             T *_values;
00344             T *_end;
00345     };
00346 
00358     template <typename T>
00359     class Array2D
00360     {
00361         public:
00362 
00363             typedef Array1D<T> Row;
00364 
00374             Array2D (T* values, int width, int height, ptrdiff_t pitch):
00375                 _height (height),
00376                 _pitch (pitch),
00377                 _values (values),
00378                 _width (width)
00379             {
00380                 assert ( 0 != values && "The values pointer is NULL." );
00381                 assert ( width > 0 && "Invalid array's width." );
00382                 assert ( height > 0 && "Invalid array's height." );
00383             }
00384 
00390             int
00391             height () const
00392             {
00393                 return _height;
00394             }
00395 
00404             const Row
00405             operator[] (int y) const
00406             {
00407                 assert ( y < height () && "Invalid row index." );
00408                 return Row (_values + y * _pitch, width ());
00409             }
00410 
00419             Row
00420             operator[] (int y)
00421             {
00422                 return static_cast<const Array2D &>(*this)[y];
00423             }
00424 
00431             int
00432             width () const
00433             {
00434                 return _width;
00435             }
00436 
00437         private:
00439             int _height;
00441             ptrdiff_t _pitch;
00443             T *_values;
00445             int _width;
00446     };
00447 
00450     class Point2D
00451     {
00452         public:
00454             Point2D ():
00455                 _point2d ()
00456             {}
00457 
00461             explicit Point2D (const sal3d_point2d &point) :
00462                 _point2d (point)
00463             {}
00464 
00468             Point2D (const Point2D &point):
00469                 _point2d (point._point2d)
00470             {}
00471 
00476             Point2D (float x, float y) {
00477                 _point2d.p[0] = x;
00478                 _point2d.p[1] = y;
00479             }
00480 
00484             const sal3d_point2d &
00485             c_point_2d () const
00486             {
00487                 return _point2d;
00488             }
00489 
00490             sal3d_point2d &
00491             c_point_2d ()
00492             {
00493                 return _point2d;
00494             }
00495 
00499             const float& x() const {return _point2d.p[0];}
00500 
00504             float& x() {return _point2d.p[0];}
00505 
00509             const float& y() const {return _point2d.p[1];}
00510 
00514             float& y() {return _point2d.p[1];}
00515 
00519             float norm () const
00520             {
00521                 return std::sqrt (_point2d.p[0] * _point2d.p[0] +
00522                         _point2d.p[1] * _point2d.p[1]);
00523             }
00524 
00526             void normalize ()
00527             {
00528                 float n = norm();
00529                 _point2d.p[0] /= n;
00530                 _point2d.p[1] /= n;
00531             }
00532 
00540             Point2D vector (const Point2D& destination) const
00541             {
00542                 Point2D vector;
00543                 vector[0] = destination[0] - (*this)[0];
00544                 vector[1] = destination[1] - (*this)[1];
00545                 return vector;
00546             }
00547 
00554             Point2D &
00555             operator= (const Point2D& rhs)
00556             {
00557                 for (int i = 0; i < 2; ++i)
00558                     (*this)[i] = rhs[i];
00559 
00560                 return *this;
00561             }
00562 
00569             Point2D
00570             operator* (const float rhs) const
00571             {
00572                 Point2D result;
00573 
00574                 for (int i = 0; i < 2; ++i)
00575                     result[i] = (*this)[i] * rhs;
00576 
00577                 return result;
00578             }
00579 
00587             Point2D &
00588             operator*= (const float rhs)
00589             {
00590                 for (int i = 0; i < 2; ++i)
00591                     (*this)[i] *= rhs;
00592 
00593                 return *this;
00594             }
00595 
00602             const float &
00603             operator[] (int idx) const
00604             {
00605                 assert (idx < 2 && "Invalid index");
00606                 return _point2d.p[idx];
00607             }
00608 
00615             float &
00616             operator[] (int idx)
00617             {
00618                 return const_cast<float &> (
00619                         static_cast<const Point2D &>(*this)[idx]);
00620             }
00621 
00627             bool
00628             operator== (const Point2D& rhs)
00629             {
00630                 return x () == rhs.x () && y () == rhs.y ();
00631             }
00632 
00633         private:
00635             sal3d_point2d _point2d;
00636     };
00637 
00640     class Point3D
00641     {
00642         public:
00644             Point3D ():
00645                 _point3d ()
00646             {}
00647 
00651             explicit Point3D (const sal3d_point3d &point) :
00652                 _point3d (point)
00653             {}
00654 
00658             Point3D (const Point3D &point):
00659                 _point3d (point._point3d)
00660             {}
00661 
00667             Point3D (float x, float y, float z) {
00668                 _point3d.p[0] = x;
00669                 _point3d.p[1] = y;
00670                 _point3d.p[2] = z;
00671             }
00672 
00676             const sal3d_point3d &
00677             c_point_3d () const
00678             {
00679                 return _point3d;
00680             }
00681 
00686             sal3d_point3d &
00687             c_point_3d ()
00688             {
00689                 return _point3d;
00690             }
00691 
00695             const float& x() const {return _point3d.p[0];}
00696 
00700             float& x() {return _point3d.p[0];}
00701 
00705             const float& y() const {return _point3d.p[1];}
00706 
00710             float& y() {return _point3d.p[1];}
00711 
00715             const float& z() const {return _point3d.p[2];}
00716 
00720             float& z() {return _point3d.p[2];}
00721 
00725             float norm () const
00726             {
00727                 return std::sqrt (_point3d.p[0] * _point3d.p[0] +
00728                         _point3d.p[1] * _point3d.p[1] +
00729                         _point3d.p[2] * _point3d.p[2]);
00730             }
00731 
00733             void normalize ()
00734             {
00735                 float n = norm();
00736                 _point3d.p[0] /= n;
00737                 _point3d.p[1] /= n;
00738                 _point3d.p[2] /= n;
00739             }
00740 
00748             Point3D vector (const Point3D& destination) const
00749             {
00750                 Point3D vector;
00751                 vector[0] = destination[0] - (*this)[0];
00752                 vector[1] = destination[1] - (*this)[1];
00753                 vector[2] = destination[2] - (*this)[2];
00754                 return vector;
00755             }
00756 
00762             float dot (const Point3D& rhs) const
00763             {
00764                 float result (0);
00765                 for (int i = 0; i < 3; ++i)
00766                     result += (*this)[i] * rhs[i];
00767 
00768                 return result;
00769             }
00770 
00776             Point3D cross (const Point3D& rhs) const
00777             {
00778                 Point3D result;
00779 
00780                 result[0] = (*this)[1] * rhs[2] - ((*this)[2] * rhs[1]);
00781                 result[1] = (*this)[2] * rhs[0] - ((*this)[0] * rhs[2]);
00782                 result[2] = (*this)[0] * rhs[1] - ((*this)[1] * rhs[0]);
00783 
00784                 return result;
00785             }
00786 
00793             Point3D &
00794             operator= (const Point3D& rhs)
00795             {
00796                 for (int i = 0; i < 3; ++i)
00797                     (*this)[i] = rhs[i];
00798 
00799                 return *this;
00800             }
00801 
00808             Point3D
00809             operator* (const float rhs) const
00810             {
00811                 Point3D result;
00812 
00813                 for (int i = 0; i < 3; ++i)
00814                     result[i] = (*this)[i] * rhs;
00815 
00816                 return result;
00817             }
00818 
00826             Point3D &
00827             operator*= (const float rhs)
00828             {
00829                 for (int i = 0; i < 3; ++i)
00830                     (*this)[i] *= rhs;
00831 
00832                 return *this;
00833             }
00834 
00841             const float &
00842             operator[] (int idx) const
00843             {
00844                 assert (idx < 3 && "Invalid index");
00845                 return _point3d.p[idx];
00846             }
00847 
00854             float &
00855             operator[] (int idx)
00856             {
00857                 return const_cast<float &> (
00858                         static_cast<const Point3D &>(*this)[idx]);
00859             }
00860 
00866             bool
00867             operator== (const Point3D& rhs)
00868             {
00869                 return x () == rhs.x () && y () == rhs.y ()
00870                     && z () == rhs.z ();
00871             }
00872 
00873         private:
00875             sal3d_point3d _point3d;
00876     };
00877 
00880     class Polygon2D
00881     {
00882         public:
00886             explicit Polygon2D ()
00887             {
00888                 Error e;
00889                 sal3d_polygon2d_new (&_polygon2d, &e.e);
00890                 if (e.e.value < 0)
00891                     throw e;
00892             }
00893 
00902             explicit Polygon2D (const std::vector<sal3d::Point2D> &points)
00903             {
00904                 std::vector<sal3d_point2d> c_points (points.size ());
00905                 for (unsigned int i = 0; i < points.size (); ++i)
00906                     c_points[i] = points[i].c_point_2d ();
00907 
00908                 Error e;
00909                 sal3d_polygon2d_new_from_points (&c_points[0],
00910                         static_cast<int> (c_points.size ()), &_polygon2d, &e.e);
00911                 if (e.e.value < 0)
00912                     throw e;
00913             }
00914 
00919             explicit Polygon2D (const sal3d_polygon2d &polygon)
00920             {
00921                 Error e;
00922                 sal3d_polygon2d_check_validity (polygon, &e.e);
00923                 if (e.e.value < 0)
00924                     throw e;
00925 
00926                 sal3d_polygon2d_copy (polygon,
00927                         &_polygon2d, &e.e);
00928                 if (e.e.value < 0)
00929                     throw e;
00930             }
00931 
00937             Polygon2D (const Polygon2D &polygon)
00938             {
00939                 Error e;
00940                 sal3d_polygon2d_copy (polygon._polygon2d,
00941                         &_polygon2d, &e.e);
00942                 if (e.e.value < 0)
00943                     throw e;
00944             }
00945 
00952             ~Polygon2D ()
00953             {
00954                 sal3d_polygon2d_release (_polygon2d);
00955             }
00956 
00966             sal3d_polygon2d
00967             c_polygon_2d () const
00968             {
00969                 return _polygon2d;
00970             }
00971 
00978             int
00979             numPoints () const
00980             {
00981                 int num_points;
00982                 Error e;
00983                 sal3d_polygon2d_num_points (_polygon2d, &num_points, &e.e);
00984                 if (e.e.value < 0)
00985                     throw e;
00986 
00987                 return num_points;
00988             }
00989 
00996             void
00997             appendPoint (const sal3d::Point2D &point)
00998             {
00999                 Error e;
01000                 sal3d_polygon2d_append_point (_polygon2d,
01001                         point.c_point_2d (), &e.e);
01002                 if (e.e.value < 0)
01003                     throw e;
01004             }
01005 
01013             void
01014             insertPoint (const sal3d::Point2D &point, int pos)
01015             {
01016                 Error e;
01017                 sal3d_polygon2d_insert_point (_polygon2d,
01018                         point.c_point_2d (), pos, &e.e);
01019                 if (e.e.value < 0)
01020                     throw e;
01021             }
01022 
01028             sal3d::Point2D
01029             removePoint ()
01030             {
01031                 sal3d_point2d point;
01032 
01033                 Error e;
01034                 sal3d_polygon2d_remove_point_back (_polygon2d,
01035                         &point, &e.e);
01036                 if (e.e.value < 0)
01037                     throw e;
01038 
01039                 return sal3d::Point2D (point);
01040             }
01041 
01049             sal3d::Point2D
01050             removePoint (int pos)
01051             {
01052                 sal3d_point2d point;
01053 
01054                 Error e;
01055                 sal3d_polygon2d_remove_point_pos (_polygon2d, pos,
01056                         &point, &e.e);
01057                 if (e.e.value < 0)
01058                     throw e;
01059 
01060                 return sal3d::Point2D (point);
01061             }
01062 
01067             void
01068             removePoints ()
01069             {
01070                 Error e;
01071                 sal3d_polygon2d_remove_points (_polygon2d, &e.e);
01072                 if (e.e.value < 0)
01073                     throw e;
01074             }
01075 
01083             void
01084             setPoints (const std::vector<sal3d::Point2D> &points)
01085             {
01086                 std::vector<sal3d_point2d> c_points (points.size ());
01087                 for (unsigned int i = 0; i < points.size (); ++i)
01088                     c_points[i] = points[i].c_point_2d ();
01089 
01090                 Error e;
01091                 sal3d_polygon2d_set_points (_polygon2d,
01092                         &c_points[0], static_cast<int> (c_points.size ()), &e.e);
01093                 if (e.e.value < 0)
01094                     throw e;
01095             }
01096 
01102             std::vector<sal3d::Point2D>
01103             getPoints () const
01104             {
01105                 std::vector<sal3d_point2d> c_points (numPoints ());
01106                 Error e;
01107                 sal3d_polygon2d_get_points (_polygon2d,
01108                         &c_points[0], &e.e);
01109                 if (e.e.value < 0)
01110                     throw e;
01111 
01112                 std::vector<sal3d::Point2D> points (c_points.size ());
01113                 for (unsigned int i = 0; i < points.size (); ++i)
01114                     points[i] = sal3d::Point2D (c_points[i]);
01115 
01116                 return points;
01117             }
01118 
01126             sal3d::Point2D
01127             getPoint (int pos) const
01128             {
01129                 sal3d_point2d point;
01130                 Error e;
01131                 sal3d_polygon2d_get_point (_polygon2d, pos, &point, &e.e);
01132                 if (e.e.value < 0)
01133                     throw e;
01134 
01135                 return sal3d::Point2D (point);
01136             }
01137 
01147             bool
01148             isPointInside (const sal3d::Point2D &point) const
01149             {
01150                 int inside;
01151                 Error e;
01152                 sal3d_polygon2d_point_inside (point.c_point_2d (),
01153                         _polygon2d, &inside, &e.e);
01154                 if (e.e.value < 0)
01155                     throw e;
01156 
01157                 return inside ? true : false;
01158             }
01159 
01167             Polygon2D &
01168             operator= (const Polygon2D &polygon)
01169             {
01170                 sal3d_polygon2d tmp = _polygon2d;
01171                 Error e;
01172                 sal3d_polygon2d_copy (polygon._polygon2d, &_polygon2d, &e.e);
01173                 if (e.e.value < 0)
01174                     throw e;
01175 
01176                 sal3d_polygon2d_release (tmp);
01177 
01178                 return *this;
01179             }
01180 
01181         private:
01183             sal3d_polygon2d _polygon2d;
01184     };
01185 
01186     //Calibrations can come from outside sal3d, so we put the Model definition
01187     //here to make it independent of the lenscalib module
01188     namespace LensDistortion
01189     {
01192         typedef sal3d_lens_dist_model_type ModelType;
01193 
01213         class Model
01214         {
01215             public:
01217                 static const int TsaiNumCoeffs = 3;
01218  
01220                 static const int CubicNumCoeffs = 20;
01221                 
01223 
01224                 static const int NLPoly3NumCoeffs = 20;
01225 
01227                 static const int TsaiRegNumCoeffs = 6;
01230 
01231 
01232 
01233                 Model()
01234                 {
01235                     _model.type = NoDistortion;
01236                     _model.error_mean = 0;
01237                     _model.error_stddev = 0;
01238                     _model.error_max = 0;
01239                 }
01240 
01247                 Model(const sal3d_lens_distortion &model)
01248                     :_model(model)
01249                 {
01250                 }
01251 
01262                 Point2D
01263                 undistort(const Point2D &p) const
01264                 {
01265                     Error e;
01266                     Point2D up;
01267                     sal3d_lens_distortion_undistort(&_model,
01268                             &p.c_point_2d(), &up.c_point_2d(), &e.e);
01269                     if (e.e.value < 0)
01270                         throw e;
01271                     
01272                     return up;
01273                 }
01274 
01284                 ModelType
01285                 getType() const
01286                 {
01287                     return _model.type;
01288                 }
01289 
01299                 std::vector<float>
01300                 getCoeffs() const
01301                 {
01302                     int numCoeffs = 0;
01303                     switch (_model.type)
01304                     {
01305                         case NoDistortion:
01306                             numCoeffs = 0;
01307                             break;
01308                         case Tsai:
01309                             numCoeffs = TsaiNumCoeffs;
01310                             break;
01311                         case NLPoly3:
01312                             numCoeffs = NLPoly3NumCoeffs;
01313                             break;
01314                         case TsaiReg:
01315                             numCoeffs = TsaiRegNumCoeffs;
01316                             break;
01317                         case Cubic:
01318                             numCoeffs = CubicNumCoeffs;
01319                             break;
01320                         case MatrixLut:
01321                             numCoeffs = 0;
01322                             break;
01323                     }
01324                     std::vector<float> coeffs;
01325                     coeffs.assign(_model.coeffs, _model.coeffs + numCoeffs);
01326 
01327                     return coeffs;
01328                 }
01329 
01335                 const sal3d_lens_distortion &
01336                 c_lens_distortion() const
01337                 {
01338                     return _model;
01339                 }
01340 
01349                 static Model
01350                 createTsai(float x, float y, float k)
01351                 {
01352                     Model m;
01353 
01354                     m._model.type = Tsai;
01355                     m._model.coeffs[0] = x;
01356                     m._model.coeffs[1] = y;
01357                     m._model.coeffs[2] = k;
01358                     m._model.error_mean = 0;
01359                     m._model.error_stddev = 0;
01360                     m._model.error_max = 0;
01361 
01362                     return m;
01363                 }
01364 
01389                 float
01390                 getErrorMean() const
01391                 {
01392                     return _model.error_mean;
01393                 }
01394 
01400                 float
01401                 getErrorStdDev() const
01402                 {
01403                     return _model.error_stddev;
01404                 }
01405 
01411                 float
01412                 getErrorMax() const
01413                 {
01414                     return _model.error_max;
01415                 }
01416 
01417             private:
01419                 sal3d_lens_distortion _model;
01420         };
01421 
01422     }
01423 
01424     // The Metric::Config is placed here to ensure that users are able to
01425     // create COPs even if they don't have the Metric module.
01426     namespace Metric
01427     {
01428         /* In Common as it is used by Metric and Angular */
01435         typedef sal3d_pattern_sp_points PatternSPPoints;
01436 
01443         typedef sal3d_pattern_stp_points PatternSTPPoints;
01444 
01471         class Config
01472         {
01473             public:
01488                 Config (float factorU, float factorV, float factorG)
01489                 {
01490                     _metricConfig.p = 0;
01491                     Error e;
01492                     sal3d_metric_config_new_from_factors(
01493                             factorU, factorV, factorG, &_metricConfig,
01494                             &e.e);
01495                     if (e.e.value < 0)
01496                         throw e;
01497                 }
01498 
01513                 explicit Config (
01514                     const sal3d_metric_config &metricConfig):
01515                     _metricConfig (metricConfig)
01516                 {
01517                     Error e;
01518                     sal3d_metric_config_check_validity (metricConfig, &e.e);
01519                     if (e.e.value < 0)
01520                         throw e;
01521                 }
01522 
01530                 Config (const Config &mc)
01531                     : _metricConfig(mc._metricConfig)
01532                 {
01533                     Error e;
01534                     sal3d_metric_config_share(_metricConfig, &e.e);
01535                     if (e.e.value < 0)
01536                         throw e;
01537                 }
01538 
01548                 Config &
01549                 operator= (const Config &mc)
01550                 {
01551                     _metricConfig = mc._metricConfig;
01552                     Error e;
01553                     sal3d_metric_config_share(_metricConfig, &e.e);
01554                     if (e.e.value < 0)
01555                         throw e;
01556                     return *this;
01557                 }
01558 
01567                 explicit Config (const std::string &filename)
01568                 {
01569                     _metricConfig.p = 0;
01570                     Error e;
01571                     sal3d_metric_config_new_from_file (
01572                             filename.c_str (), &_metricConfig, &e.e);
01573                     if (e.e.value < 0)
01574                         throw e;
01575                 }
01576 
01588                 explicit Config(const std::vector<float> &conf)
01589                 {
01590                     _metricConfig.p = 0;
01591                     Error e;
01592                     sal3d_metric_config_new_from_deserialisation(&conf[0],
01593                             static_cast<int>(conf.size()), &_metricConfig, &e.e);
01594                     if (e.e.value < 0)
01595                         throw e;
01596                 }
01597 
01601                 ~Config ()
01602                 {
01603                     sal3d_metric_config_release (_metricConfig);
01604                 }
01605 
01623                 std::vector<float> accuracyMean() const
01624                 {
01625                     std::vector<float> vec(3);
01626                     Error e;
01627                     sal3d_metric_config_get_accuracy_mean(_metricConfig,
01628                             &vec[0], &vec[1], &vec[2], &e.e);
01629                     if (e.e.value < 0)
01630                         throw e;
01631                     return vec;
01632                 }
01633 
01652                 std::vector<float> accuracyStdDev() const
01653                 {
01654                     std::vector<float> vec(3);
01655                     Error e;
01656                     sal3d_metric_config_get_accuracy_stddev(_metricConfig,
01657                             &vec[0], &vec[1], &vec[2], &e.e);
01658                     if (e.e.value < 0)
01659                         throw e;
01660                     return vec;
01661                 }
01662 
01672                 const sal3d_metric_config &
01673                 c_metric_config () const
01674                 {
01675                     return _metricConfig;
01676                 }
01677 
01698                 std::vector<float> patternMisorientation() const
01699                 {
01700                     std::vector<float> vec(2);
01701                     Error e;
01702                     sal3d_metric_config_get_misorientation(_metricConfig,
01703                             &vec[0], &vec[1], &e.e);
01704                     if (e.e.value < 0)
01705                         throw e;
01706                     return vec;
01707                 }
01708 
01717                 void
01718                 saveToFile (const std::string &fileName) const
01719                 {
01720                     Error e;
01721                     sal3d_metric_config_save_to_file (_metricConfig,
01722                             fileName.c_str (), &e.e);
01723                     if (e.e.value < 0)
01724                         throw e;
01725                 }
01726 
01739                 std::vector<float>
01740                 serialise() const
01741                 {
01742                     std::vector<float> res(sal3d_metric_config_serialised_size(_metricConfig));
01743 
01744                     Error e;
01745                     sal3d_metric_config_serialise(_metricConfig,
01746                             &res[0], &e.e);
01747                     if (e.e.value < 0)
01748                         throw e;
01749 
01750                     return res;
01751                 }
01752 
01769                 Point3D
01770                 toPoint3D (float u, float v, float g) const
01771                 {
01772                     sal3d::Point3D point3d;
01773                     Error e;
01774                     sal3d_metric_config_point3d_from_range_map_point (u, v, g,
01775                             _metricConfig, &point3d.c_point_3d(), &e.e);
01776                     if (e.e.value < 0)
01777                         throw e;
01778                     return point3d;
01779                 }
01780 
01791                 LensDistortion::Model
01792                 getLensDistortionModel() const
01793                 {
01794                     sal3d_lens_distortion dm;
01795                     Error e;
01796                     sal3d_metric_config_get_lens_distortion(_metricConfig, &dm,
01797                             &e.e);
01798                     if (e.e.value < 0)
01799                         throw e;
01800 
01801                     return LensDistortion::Model(dm);
01802                 }
01803 
01804             private:
01806                 sal3d_metric_config _metricConfig;
01807         };
01808     }
01809 }
01810 
01811 #endif // !AQSENSE_SAL3DPP_COMMON_HPP