00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef MESH_APPROXIMATION_H
00025 #define MESH_APPROXIMATION_H
00026
00027 #include <Mod/Mesh/App/WildMagic4/Wm4Vector3.h>
00028 #include <Mod/Mesh/App/WildMagic4/Wm4QuadricSurface.h>
00029 #include <Mod/Mesh/App/WildMagic4/Wm4Eigen.h>
00030 #include <list>
00031 #include <set>
00032 #include <vector>
00033
00034 #include <Base/Vector3D.h>
00035 #include <Base/Matrix.h>
00036
00037 namespace MeshCore {
00038
00039
00043 class MeshExport Approximation
00044 {
00045 public:
00049 Approximation() : _bIsFitted(false) { }
00053 virtual ~Approximation(){ Clear(); }
00057 void AddPoint(const Base::Vector3f &rcVector);
00061 void AddPoints(const std::vector<Base::Vector3f> &rvPointVect);
00065 void AddPoints(const std::set<Base::Vector3f> &rsPointSet);
00069 void AddPoints(const std::list<Base::Vector3f> &rsPointList);
00073 const std::list<Base::Vector3f>& GetPoints() const { return _vPoints; }
00078 Base::Vector3f GetGravity() const;
00083 unsigned long CountPoints() const;
00087 void Clear();
00092 float GetLastResult() const;
00097 virtual float Fit() = 0;
00101 bool Done() const;
00102
00103 protected:
00107 static void Convert( const Wm4::Vector3<float>&, Base::Vector3f&);
00111 static void Convert( const Base::Vector3f&, Wm4::Vector3<float>&);
00115 void GetMgcVectorArray( std::vector< Wm4::Vector3<float> >& rcPts ) const;
00116
00117 protected:
00118 std::list< Base::Vector3f > _vPoints;
00119 bool _bIsFitted;
00120 float _fLastResult;
00121 };
00122
00123
00124
00128 class MeshExport PlaneFit : public Approximation
00129 {
00130 public:
00134 PlaneFit(){};
00138 virtual ~PlaneFit(){};
00139 Base::Vector3f GetBase() const;
00140 Base::Vector3f GetDirU() const;
00141 Base::Vector3f GetDirV() const;
00146 Base::Vector3f GetNormal() const;
00151 float Fit();
00156 float GetDistanceToPlane(const Base::Vector3f &rcPoint) const;
00161 float GetStdDeviation() const;
00166 float GetSignedStdDeviation() const;
00170 void ProjectToPlane();
00171
00172 protected:
00173 Base::Vector3f _vBase;
00174 Base::Vector3f _vDirU;
00175 Base::Vector3f _vDirV;
00176 Base::Vector3f _vDirW;
00177 };
00178
00179
00180
00190 class MeshExport QuadraticFit : public Approximation
00191 {
00192 public:
00196 QuadraticFit() : Approximation() {};
00200 virtual ~QuadraticFit(){};
00206 float GetCoeff(unsigned long ulIndex) const;
00212 const float& GetCoeffArray() const;
00217 float Fit();
00218
00219 void CalcZValues(float x, float y, float &dZ1, float &dZ2) const;
00232 bool GetCurvatureInfo(float x, float y, float z,
00233 float &rfCurv0, float &rfCurv1,
00234 Base::Vector3f &rkDir0, Base::Vector3f &rkDir1, float &dDistance);
00235
00236 bool GetCurvatureInfo(float x, float y, float z,
00237 float &rfCurv0, float &rfcurv1);
00247 void CalcEigenValues(float &dLambda1, float &dLambda2, float &dLambda3,
00248 Base::Vector3f &clEV1, Base::Vector3f &clEV2, Base::Vector3f &clEV3) const;
00249
00250 protected:
00251 float _fCoeff[ 10 ];
00252 };
00253
00254
00255
00266 class MeshExport SurfaceFit : public PlaneFit
00267 {
00268 public:
00272 SurfaceFit();
00276 virtual ~SurfaceFit(){};
00277
00278 bool GetCurvatureInfo(float x, float y, float z, float &rfCurv0, float &rfCurv1,
00279 Base::Vector3f &rkDir0, Base::Vector3f &rkDir1, float &dDistance);
00280 bool GetCurvatureInfo(float x, float y, float z, float &rfCurv0, float &rfcurv1);
00281 float Fit();
00282 float Value(float x, float y) const;
00283
00284 protected:
00285 float PolynomFit();
00286 float _fCoeff[ 10 ];
00287 };
00288
00289
00290
00296 class FunctionContainer
00297 {
00298 public:
00303 typedef float (*Function)(float,float,float);
00310 FunctionContainer(const float *pKoef)
00311 {
00312 Assign( pKoef );
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 pImplSurf = new Wm4::QuadricSurface<float>( dKoeff );
00332 }
00338 void Assign( const float *pKoef )
00339 {
00340 for (long ct=0; ct < 10; ct++)
00341 dKoeff[ ct ] = pKoef[ ct ];
00342 }
00347 virtual ~FunctionContainer(){ delete pImplSurf; }
00353 float& operator[](int idx){ return dKoeff[ idx ]; }
00367 bool CurvatureInfo(float x, float y, float z,
00368 float &rfCurv0, float &rfCurv1,
00369 Wm4::Vector3<float> &rkDir0, Wm4::Vector3<float> &rkDir1, float &dDistance)
00370 {
00371 return pImplSurf->ComputePrincipalCurvatureInfo( Wm4::Vector3<float>(x, y, z),rfCurv0, rfCurv1, rkDir0, rkDir1 );
00372 }
00373
00374 Base::Vector3f GetGradient( float x, float y, float z ) const
00375 {
00376 Wm4::Vector3<float> grad = pImplSurf->GetGradient( Wm4::Vector3<float>(x, y, z) );
00377 return Base::Vector3f( grad.X(), grad.Y(), grad.Z() );
00378 }
00379
00380 Base::Matrix4D GetHessian( float x, float y, float z ) const
00381 {
00382 Wm4::Matrix3<float> hess = pImplSurf->GetHessian( Wm4::Vector3<float>(x, y, z) );
00383 Base::Matrix4D cMat; cMat.setToUnity();
00384 cMat[0][0] = hess[0][0]; cMat[0][1] = hess[0][1]; cMat[0][2] = hess[0][2];
00385 cMat[1][0] = hess[1][0]; cMat[1][1] = hess[1][1]; cMat[1][2] = hess[1][2];
00386 cMat[2][0] = hess[2][0]; cMat[2][1] = hess[2][1]; cMat[2][2] = hess[2][2];
00387 return cMat;
00388 }
00389
00390 bool CurvatureInfo(float x, float y, float z,
00391 float &rfCurv0, float &rfCurv1)
00392 {
00393 float dQuot = Fz(x,y,z);
00394 float zx = - ( Fx(x,y,z) / dQuot );
00395 float zy = - ( Fy(x,y,z) / dQuot );
00396
00397 float zxx = - ( 2.0f * ( dKoeff[5] + dKoeff[6] * zx * zx + dKoeff[8] * zx ) ) / dQuot;
00398 float zyy = - ( 2.0f * ( dKoeff[5] + dKoeff[6] * zy * zy + dKoeff[9] * zy ) ) / dQuot;
00399 float zxy = - ( dKoeff[6] * zx * zy + dKoeff[7] + dKoeff[8] * zy + dKoeff[9] * zx ) / dQuot;
00400
00401 float dNen = 1 + zx*zx + zy*zy;
00402 float dNenSqrt = (float)sqrt( dNen );
00403 float K = ( zxx * zyy - zxy * zxy ) / ( dNen * dNen );
00404 float H = 0.5f * ( ( 1.0f+zx*zx - 2*zx*zy*zxy + (1.0f+zy*zy)*zxx ) / ( dNenSqrt * dNenSqrt * dNenSqrt ) ) ;
00405
00406 float dDiscr = (float)sqrt(fabs(H*H-K));
00407 rfCurv0 = H - dDiscr;
00408 rfCurv1 = H + dDiscr;
00409
00410 return true;
00411 }
00412
00413
00414 static float F ( float x, float y, float z )
00415 {
00416 return (dKoeff[0] + dKoeff[1]*x + dKoeff[2]*y + dKoeff[3]*z +
00417 dKoeff[4]*x*x + dKoeff[5]*y*y + dKoeff[6]*z*z +
00418 dKoeff[7]*x*y + dKoeff[8]*x*z + dKoeff[9]*y*z);
00419 }
00420
00421
00422 static float Fx ( float x, float y, float z )
00423 {
00424 return( dKoeff[1] + 2.0f*dKoeff[4]*x + dKoeff[7]*y + dKoeff[8]*z );
00425 }
00426 static float Fy ( float x, float y, float z )
00427 {
00428 return( dKoeff[2] + 2.0f*dKoeff[5]*y + dKoeff[7]*x + dKoeff[9]*z );
00429 }
00430 static float Fz ( float x, float y, float z )
00431 {
00432 return( dKoeff[3] + 2.0f*dKoeff[6]*z + dKoeff[8]*x + dKoeff[9]*y );
00433 }
00434
00435
00436 static float Fxx( float x, float y, float z )
00437 {
00438 return( 2.0f*dKoeff[4] );
00439 }
00440 static float Fxy( float x, float y, float z )
00441 {
00442 return( dKoeff[7] );
00443 }
00444 static float Fxz( float x, float y, float z )
00445 {
00446 return( dKoeff[8] );
00447 }
00448 static float Fyy( float x, float y, float z )
00449 {
00450 return( 2.0f*dKoeff[5] );
00451 }
00452 static float Fyz( float x, float y, float z )
00453 {
00454 return( dKoeff[9] );
00455 }
00456 static float Fzz( float x, float y, float z )
00457 {
00458 return( 2.0f*dKoeff[6] );
00459 }
00460
00461 protected:
00462 static float dKoeff[ 10 ];
00463 Wm4::ImplicitSurface<float> *pImplSurf;
00465 private:
00469 FunctionContainer(){};
00470 };
00471
00472 class MeshExport PolynomialFit : public Approximation
00473 {
00474 public:
00478 PolynomialFit();
00479
00483 virtual ~PolynomialFit();
00484 float Fit();
00485 float Value(float x, float y) const;
00486
00487 protected:
00488 float _fCoeff[9];
00489 };
00490
00491 }
00492
00493 #endif // MESH_APPROXIMATION_H