1 /* 2 Copyright (C) 2014 Nicolas Mellado <nmellado0@gmail.com> 3 Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr> 4 5 This Source Code Form is subject to the terms of the Mozilla Public 6 License, v. 2.0. If a copy of the MPL was not distributed with this 7 file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 */ 9 10 11 #ifndef _GRENAILLE_COVARIANCE_PLANE_FIT_ 12 #define _GRENAILLE_COVARIANCE_PLANE_FIT_ 13 14 #include <Eigen/Eigenvalues> 15 #include "enums.h" 16 17 namespace Grenaille 18 { 19 20 /*! 21 \brief Plane fitting procedure using only points position 22 23 \note This procedure requires two passes to fit a plane 24 25 This class can also computes the surface variation measure introduced in 26 \cite Pauly:2002:PSSimplification. The solver used to analyse the covariance 27 matrix is stored for further use. 28 29 \inherit Concept::FittingProcedureConcept 30 31 \warning This class is currently untested and should not be used ! 32 33 \see CompactPlane 34 */ 35 template < class DataPoint, class _WFunctor, typename T > 36 class CovariancePlaneFit : public T 37 { 38 private: 39 typedef T Base; 40 41 protected: 42 enum 43 { 44 Check = Base::PROVIDES_PLANE 45 }; 46 47 public: 48 49 /*! \brief Scalar type inherited from DataPoint*/ 50 typedef typename Base::Scalar Scalar; 51 /*! \brief Vector type inherited from DataPoint*/ 52 typedef typename Base::VectorType VectorType; 53 /*! \brief Vector type inherited from DataPoint*/ 54 typedef typename Base::MatrixType MatrixType; 55 /*! \brief Weight Function*/ 56 typedef _WFunctor WFunctor; 57 /*! \brief Solver used to analyse the covariance matrix*/ 58 typedef Eigen::SelfAdjointEigenSolver<MatrixType> Solver; 59 60 protected: 61 62 // computation data 63 Scalar m_sumW; /*!< \brief Sum of queries weight.*/ 64 VectorType m_cog, /*!< \brief Gravity center of the neighborhood */ 65 m_evalPos; /*!< \brief Center of the evaluation basis */ 66 MatrixType m_cov; /*!< \brief Covariance matrix */ 67 68 Solver m_solver; /*!<\brief Solver used to analyse the covariance matrix */ 69 70 WFunctor m_w; /*!< \brief Weight function (must inherits BaseWeightFunc) */ 71 72 public: 73 74 /*! \brief Default constructor */ CovariancePlaneFit()75 MULTIARCH inline CovariancePlaneFit() : Base() {} 76 77 /**************************************************************************/ 78 /* Initialization */ 79 /**************************************************************************/ 80 /*! \copydoc Concept::FittingProcedureConcept::setWeightFunc() */ setWeightFunc(const WFunctor & _w)81 MULTIARCH inline void setWeightFunc (const WFunctor& _w) { m_w = _w; } 82 83 /*! \copydoc Concept::FittingProcedureConcept::init() */ 84 MULTIARCH inline void init (const VectorType& _evalPos); 85 86 /**************************************************************************/ 87 /* Processing */ 88 /**************************************************************************/ 89 /*! \copydoc Concept::FittingProcedureConcept::addNeighbor() */ 90 MULTIARCH inline bool addNeighbor(const DataPoint &_nei); 91 92 /*! \copydoc Concept::FittingProcedureConcept::finalize() */ 93 MULTIARCH inline FIT_RESULT finalize(); 94 95 /**************************************************************************/ 96 /* Results */ 97 /**************************************************************************/ 98 99 using Base::potential; 100 101 /*! \brief Value of the scalar field at the evaluation point */ potential()102 MULTIARCH inline Scalar potential() const { return Base::potential(m_evalPos); } 103 104 /*! \brief Value of the normal of the primitive at the evaluation point */ normal()105 MULTIARCH inline VectorType normal() const { return Base::m_p.template head<DataPoint::Dim>(); } 106 107 /*! \brief Reading access to the Solver used to analyse the covariance 108 matrix */ solver()109 MULTIARCH inline const Solver& solver() const { return m_solver; } 110 111 /*! \brief Implements \cite Pauly:2002:PSSimplification surface variation. 112 113 It computes the ratio \f$ d \frac{\lambda_0}{\sum_i \lambda_i} \f$ with \c d the dimension of the ambient space. 114 115 \return 0 for invalid fits 116 */ 117 MULTIARCH inline Scalar surfaceVariation() const; 118 }; //class CovariancePlaneFit 119 120 namespace internal { 121 122 using ::Grenaille::internal::FitSpaceDer; 123 using ::Grenaille::internal::FitScaleDer; 124 125 /*! 126 \brief Internal generic class computing the derivatives of covariance plane fits 127 \inherit Concept::FittingExtensionConcept 128 129 The differentiation can be done automatically in scale and/or space, by 130 combining the enum values FitScaleDer and FitSpaceDer in the template 131 parameter Type. 132 133 The differenciated values are stored in static arrays. The size of the 134 arrays is computed with respect to the derivation type (scale and/or space) 135 and the number of the dimension of the ambiant space. 136 By convention, the scale derivatives are stored at index 0 when Type 137 contains at least FitScaleDer. The size of these arrays can be known using 138 derDimension(), and the differentiation type by isScaleDer() and 139 isSpaceDer(). 140 */ 141 template < class DataPoint, class _WFunctor, typename T, int Type> 142 class CovariancePlaneDer : public T 143 { 144 private: 145 typedef T Base; /*!< \brief Generic base type */ 146 147 148 protected: 149 enum 150 { 151 Check = Base::PROVIDES_PLANE, /*!< \brief Needs plane */ 152 PROVIDES_COVARIANCE_PLANE_DERIVATIVE, /*!< \brief Provides derivatives for hyper-planes */ 153 PROVIDES_NORMAL_DERIVATIVE 154 }; 155 156 static const int NbDerivatives = ((Type & FitScaleDer) ? 1 : 0 ) + ((Type & FitSpaceDer) ? DataPoint::Dim : 0); 157 static const int DerStorageOrder = (Type & FitSpaceDer) ? Eigen::RowMajor : Eigen::ColMajor; 158 159 public: 160 typedef typename Base::Scalar Scalar; /*!< \brief Inherited scalar type*/ 161 typedef typename Base::VectorType VectorType; /*!< \brief Inherited vector type*/ 162 typedef typename Base::MatrixType MatrixType; /*!< \brief Inherited matrix type*/ 163 typedef typename Base::WFunctor WFunctor; /*!< \brief Weight Function*/ 164 165 /*! \brief Static array of scalars with a size adapted to the differentiation type */ 166 typedef Eigen::Matrix<Scalar, DataPoint::Dim, NbDerivatives, DerStorageOrder> VectorArray; 167 168 /*! \brief Static array of scalars with a size adapted to the differentiation type */ 169 typedef Eigen::Matrix<Scalar, 1, NbDerivatives> ScalarArray; 170 private: 171 // computation data 172 ScalarArray m_dSumW; /*!< \brief Sum of weight derivatives */ 173 MatrixType m_dCov[NbDerivatives]; 174 175 VectorArray m_dCog; /*!< \brief Derivatives of the centroid */ 176 VectorArray m_dNormal; /*!< \brief Derivatives of the hyper-plane normal */ 177 ScalarArray m_dDist; /*!< \brief Derivatives of the MLS scalar field */ 178 179 public: 180 181 /************************************************************************/ 182 /* Initialization */ 183 /************************************************************************/ 184 /*! \see Concept::FittingProcedureConcept::init() */ 185 MULTIARCH void init(const VectorType &evalPos); 186 187 /************************************************************************/ 188 /* Processing */ 189 /************************************************************************/ 190 /*! \see Concept::FittingProcedureConcept::addNeighbor() */ 191 MULTIARCH bool addNeighbor(const DataPoint &nei); 192 /*! \see Concept::FittingProcedureConcept::finalize() */ 193 MULTIARCH FIT_RESULT finalize(); 194 195 196 /**************************************************************************/ 197 /* Use results */ 198 /**************************************************************************/ 199 200 /*! \brief Returns the derivatives of the scalar field at the evaluation point */ dPotential()201 MULTIARCH inline ScalarArray dPotential() const { return m_dDist; } 202 203 /*! \brief Returns the derivatives of the primitive normal */ dNormal()204 MULTIARCH inline VectorArray dNormal() const { return m_dNormal; } 205 206 /*! \brief State specified at compilation time to differenciate the fit in scale */ isScaleDer()207 MULTIARCH inline bool isScaleDer() const {return bool(Type & FitScaleDer);} 208 /*! \brief State specified at compilation time to differenciate the fit in space */ isSpaceDer()209 MULTIARCH inline bool isSpaceDer() const {return bool(Type & FitSpaceDer);} 210 /*! \brief Number of dimensions used for the differentiation */ derDimension()211 MULTIARCH inline unsigned int derDimension() const { return NbDerivatives;} 212 213 }; //class CovariancePlaneDer 214 215 }// namespace internal 216 217 /*! 218 \brief Differentiation in scale of the CovariancePlaneFit 219 \inherit Concept::FittingExtensionConcept 220 221 Requierement: 222 \verbatim PROVIDES_COVARIANCE_PLANE \endverbatim 223 Provide: 224 \verbatim PROVIDES_COVARIANCE_PLANE_SCALE_DERIVATIVE \endverbatim 225 */ 226 template < class DataPoint, class _WFunctor, typename T> 227 class CovariancePlaneScaleDer:public internal::CovariancePlaneDer<DataPoint, _WFunctor, T, internal::FitScaleDer> 228 { 229 protected: 230 /*! \brief Inherited class */ 231 typedef internal::CovariancePlaneDer<DataPoint, _WFunctor, T, internal::FitScaleDer> Base; 232 enum { PROVIDES_COVARIANCE_PLANE_SCALE_DERIVATIVE, PROVIDES_NORMAL_SCALE_DERIVATIVE }; 233 }; 234 235 236 /*! 237 \brief Spatial differentiation of the CovariancePlaneFit 238 \inherit Concept::FittingExtensionConcept 239 240 Requierement: 241 \verbatim PROVIDES_COVARIANCE_PLANE \endverbatim 242 Provide: 243 \verbatim PROVIDES_COVARIANCE_PLANE_SPACE_DERIVATIVE \endverbatim 244 */ 245 template < class DataPoint, class _WFunctor, typename T> 246 class CovariancePlaneSpaceDer:public internal::CovariancePlaneDer<DataPoint, _WFunctor, T, internal::FitSpaceDer> 247 { 248 protected: 249 /*! \brief Inherited class */ 250 typedef internal::CovariancePlaneDer<DataPoint, _WFunctor, T, internal::FitSpaceDer> Base; 251 enum { PROVIDES_COVARIANCE_PLANE_SPACE_DERIVATIVE, PROVIDES_NORMAL_SPACE_DERIVATIVE }; 252 }; 253 254 255 /*! 256 \brief Differentiation both in scale and space of the CovariancePlaneFit 257 \inherit Concept::FittingExtensionConcept 258 259 Requierement: 260 \verbatim PROVIDES_COVARIANCE_PLANE \endverbatim 261 Provide: 262 \verbatim PROVIDES_COVARIANCE_PLANE_SCALE_DERIVATIVE 263 PROVIDES_COVARIANCE_PLANE_SPACE_DERIVATIVE 264 \endverbatim 265 */ 266 template < class DataPoint, class _WFunctor, typename T> 267 class CovariancePlaneScaleSpaceDer:public internal::CovariancePlaneDer<DataPoint, _WFunctor, T, internal::FitSpaceDer | internal::FitScaleDer> 268 { 269 protected: 270 /*! \brief Inherited class */ 271 typedef internal::CovariancePlaneDer<DataPoint, _WFunctor, T, internal::FitSpaceDer | internal::FitScaleDer> Base; 272 enum 273 { 274 PROVIDES_COVARIANCE_PLANE_SCALE_DERIVATIVE, 275 PROVIDES_COVARIANCE_PLANE_SPACE_DERIVATIVE, 276 PROVIDES_NORMAL_SCALE_DERIVATIVE, 277 PROVIDES_NORMAL_SPACE_DERIVATIVE 278 }; 279 }; 280 281 #include "covariancePlaneFit.hpp" 282 283 } //namespace Grenaille 284 285 #endif 286