490 lines
18 KiB
C++
490 lines
18 KiB
C++
/***************************************************************************
|
|
* Copyright (c) 2008 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
|
* *
|
|
* This file is part of the FreeCAD CAx development system. *
|
|
* *
|
|
* This library is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU Library General Public *
|
|
* License as published by the Free Software Foundation; either *
|
|
* version 2 of the License, or (at your option) any later version. *
|
|
* *
|
|
* This library is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Library General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Library General Public *
|
|
* License along with this library; see the file COPYING.LIB. If not, *
|
|
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
|
* Suite 330, Boston, MA 02111-1307, USA *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
|
|
#ifndef REEN_APPROXSURFACE_H
|
|
#define REEN_APPROXSURFACE_H
|
|
|
|
#include <TColStd_Array1OfReal.hxx>
|
|
#include <TColStd_Array1OfInteger.hxx>
|
|
#include <TColgp_Array1OfPnt.hxx>
|
|
#include <TColgp_Array2OfPnt.hxx>
|
|
#include <TColgp_Array1OfPnt2d.hxx>
|
|
#include <Geom_BSplineSurface.hxx>
|
|
#include <math_Matrix.hxx>
|
|
|
|
#include <Base/Vector3D.h>
|
|
#include <Mod/ReverseEngineering/ReverseEngineeringGlobal.h>
|
|
|
|
namespace Base {
|
|
class SequencerLauncher;
|
|
}
|
|
|
|
// TODO: Replace OCC stuff with ublas & co
|
|
|
|
namespace Reen {
|
|
|
|
class ReenExport SplineBasisfunction
|
|
{
|
|
public:
|
|
enum ValueT {
|
|
Zero = 0,
|
|
Full,
|
|
Other
|
|
};
|
|
/**
|
|
* Constructor
|
|
* @param iSize Length of Knots vector
|
|
*/
|
|
SplineBasisfunction(int iSize);
|
|
|
|
/**
|
|
* Constructor
|
|
* @param vKnots Knot vector
|
|
* @param iOrder Order (degree + 1) of the basic polynomial
|
|
*/
|
|
SplineBasisfunction(TColStd_Array1OfReal& vKnots, int iOrder=1);
|
|
|
|
/**
|
|
* Constructor
|
|
* @param vKnots Knot vector of shape (value)
|
|
* @param vMults Knot vector of shape (multiplicity)
|
|
* @param iSize Length of the knot vector
|
|
* The arrays @a vKnots and @a vMults have to be of the same size
|
|
* and the sum of the values in @a vMults has to be identical to @a iSize.
|
|
* @param iOrder Order (degree + 1) of the basic polynomial
|
|
*/
|
|
SplineBasisfunction(TColStd_Array1OfReal& vKnots, TColStd_Array1OfInteger& vMults, int iSize, int iOrder=1);
|
|
|
|
virtual ~SplineBasisfunction();
|
|
|
|
/**
|
|
* Indicates whether the function value Nik(t) at the point fParam
|
|
* results in 0, 1 or a value in between.
|
|
* This serves to speed up the calculation under certain circumstances.
|
|
*
|
|
* @param iIndex Index
|
|
* @param fParam Parameter value
|
|
* @return ValueT
|
|
*/
|
|
virtual ValueT LocalSupport(int iIndex, double fParam)=0;
|
|
/**
|
|
* Calculates the function value Nik(t) at the point fParam
|
|
* (from: Piegl/Tiller 96 The NURBS-Book)
|
|
*
|
|
* @param iIndex Index
|
|
* @param fParam Parameter value
|
|
* @return Function value Nik(t)
|
|
*/
|
|
virtual double BasisFunction(int iIndex, double fParam)=0;
|
|
/**
|
|
* Calculates the function values of the first iMaxDer derivatives on the
|
|
* fParam position (from: Piegl/Tiller 96 The NURBS-Book)
|
|
*
|
|
* @param iIndex Index
|
|
* @param iMaxDer max. derivative
|
|
* @param fParam Parameter value.
|
|
* @return Derivative list of function values
|
|
*
|
|
* The list must be sufficiently long for iMaxDer+1 elements.
|
|
*/
|
|
virtual void DerivativesOfBasisFunction(int iIndex, int iMaxDer, double fParam,
|
|
TColStd_Array1OfReal& Derivat)=0;
|
|
|
|
/**
|
|
* Calculates the kth derivative at the point fParam
|
|
*/
|
|
virtual double DerivativeOfBasisFunction(int iIndex, int k, double fParam)=0;
|
|
|
|
/**
|
|
* Sets the knot vector and the order. The size of the knot vector has to be exactly as
|
|
* large as defined in the constructor.
|
|
*/
|
|
virtual void SetKnots(TColStd_Array1OfReal& vKnots, int iOrder=1);
|
|
|
|
/**
|
|
* Sets the knot vector and the order. The knot vector in the form of (Value, Multiplicity)
|
|
* is passed on. Internally, this is converted into a knot vector in the form of (value, 1).
|
|
* The size of this new vector has to be exactly as big as specified in the constructor.
|
|
*/
|
|
virtual void SetKnots(TColStd_Array1OfReal& vKnots, TColStd_Array1OfInteger& vMults, int iOrder=1);
|
|
|
|
protected: //Member
|
|
// Knot vector
|
|
TColStd_Array1OfReal _vKnotVector;
|
|
|
|
// Order (=Degree+1)
|
|
int _iOrder;
|
|
};
|
|
|
|
class ReenExport BSplineBasis : public SplineBasisfunction
|
|
{
|
|
public:
|
|
|
|
/**
|
|
* Constructor
|
|
* @param iSize Length of the knot vector
|
|
*/
|
|
BSplineBasis(int iSize);
|
|
|
|
/**
|
|
* Constructor
|
|
* @param vKnots Knot vector
|
|
* @param iOrder Order (degree + 1) of the basic polynomial
|
|
*/
|
|
BSplineBasis(TColStd_Array1OfReal& vKnots, int iOrder=1);
|
|
|
|
/**
|
|
* Constructor
|
|
* @param vKnots Knot vector of shape (value)
|
|
* @param vMults Knot vector of shape (multiplicity)
|
|
* @param iSize Length of the knot vector
|
|
* The arrays @a vKnots and @a vMults have to be of the same size and the
|
|
* sum of the values in @a vMults has to be identical to @a iSize.
|
|
* @param iOrder Order (degree + 1) of the basic polynomial
|
|
*/
|
|
BSplineBasis(TColStd_Array1OfReal& vKnots, TColStd_Array1OfInteger& vMults, int iSize, int iOrder=1);
|
|
|
|
/**
|
|
* Specifies the knot index for the parameter value (from: Piegl/Tiller 96 The NURBS-Book)
|
|
* @param fParam Parameter value
|
|
* @return Knot index
|
|
*/
|
|
virtual int FindSpan(double fParam);
|
|
|
|
/**
|
|
* Calculates the function values of the basic functions that do not vanish at fParam.
|
|
* It must be ensured that the list for d (= degree of the B-spline)
|
|
* elements (0, ..., d-1) is sufficient (from: Piegl/Tiller 96 The NURBS-Book)
|
|
* @param fParam Parameter
|
|
* @param vFuncVals List of function values
|
|
* Index, Parameter value
|
|
*/
|
|
virtual void AllBasisFunctions(double fParam, TColStd_Array1OfReal& vFuncVals);
|
|
|
|
/**
|
|
* Specifies whether the function value Nik(t) at the position fParam
|
|
* results in 0, 1 or a value in between.
|
|
* This serves to speed up the calculation under certain circumstances.
|
|
*
|
|
* @param iIndex Index
|
|
* @param fParam Parameter value
|
|
* @return ValueT
|
|
*/
|
|
virtual ValueT LocalSupport(int iIndex, double fParam);
|
|
|
|
/**
|
|
* Calculates the function value Nik(t) at the point fParam
|
|
* (from: Piegl/Tiller 96 The NURBS-Book)
|
|
* @param iIndex Index
|
|
* @param fParam Parameter value
|
|
* @return Function value Nik(t)
|
|
*/
|
|
virtual double BasisFunction(int iIndex, double fParam);
|
|
|
|
/**
|
|
* Calculates the function values of the first iMaxDer derivatives at the point fParam
|
|
* (from: Piegl/Tiller 96 The NURBS-Book)
|
|
* @param iIndex Index
|
|
* @param iMaxDer max. derivative
|
|
* @param fParam Parameter value
|
|
* @param Derivat
|
|
* The list must be sufficiently long for iMaxDer+1 elements.
|
|
* @return List of function values
|
|
*/
|
|
virtual void DerivativesOfBasisFunction(int iIndex, int iMaxDer, double fParam,
|
|
TColStd_Array1OfReal& Derivat);
|
|
|
|
/**
|
|
* Calculates the kth derivative at the point fParam
|
|
*/
|
|
virtual double DerivativeOfBasisFunction(int iIndex, int k, double fParam);
|
|
|
|
/**
|
|
* Calculates the integral of the product of two B-splines or their derivatives.
|
|
* The integration area extends over the entire domain of definition.
|
|
* The integral is calculated by means of the Gaussian quadrature formulas.
|
|
*/
|
|
virtual double GetIntegralOfProductOfBSplines(int i, int j, int r, int s);
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual~ BSplineBasis();
|
|
|
|
protected:
|
|
|
|
/**
|
|
* Calculates the roots of the Legendre-Polynomials and the corresponding weights
|
|
*/
|
|
virtual void GenerateRootsAndWeights(TColStd_Array1OfReal& vAbscissas, TColStd_Array1OfReal& vWeights);
|
|
|
|
/**
|
|
* Calculates the limits of integration (Indexes of the knots)
|
|
*/
|
|
virtual void FindIntegrationArea(int iIdx1, int iIdx2, int& iBegin, int& iEnd);
|
|
|
|
/**
|
|
* Calculates the number of roots/weights of the Legendre-Polynomials to be used as a function
|
|
* of the degree
|
|
*/
|
|
int CalcSize(int r, int s);
|
|
};
|
|
|
|
class ReenExport ParameterCorrection
|
|
{
|
|
|
|
public:
|
|
// Constructor
|
|
ParameterCorrection(unsigned usUOrder=4, //Order in u-direction (order = degree + 1)
|
|
unsigned usVOrder=4, //Order in v-direction
|
|
unsigned usUCtrlpoints=6, //Qty. of the control points in the u-direction
|
|
unsigned usVCtrlpoints=6); //Qty. of the control points in the v-direction
|
|
|
|
virtual ~ParameterCorrection()
|
|
{
|
|
delete _pvcPoints;
|
|
delete _pvcUVParam;
|
|
}
|
|
|
|
protected:
|
|
/**
|
|
* Calculates the eigenvectors of the covariance matrix
|
|
*/
|
|
virtual void CalcEigenvectors();
|
|
|
|
/**
|
|
* Projects the control points onto the fit plane
|
|
*/
|
|
void ProjectControlPointsOnPlane();
|
|
|
|
/**
|
|
* Calculates an initial area at the beginning of the algorithm.
|
|
* For this purpose, the best-fit plane for the point cloud is calculated.
|
|
* The points are calculated with respect to the base consisting of the
|
|
* eigenvectors of the covariance matrix and projected onto the best-fit plane.
|
|
* The bounding box is calculated from these points, then the u/v parameters for
|
|
* the points are calculated.
|
|
*/
|
|
virtual bool DoInitialParameterCorrection(double fSizeFactor=0.0f);
|
|
|
|
/**
|
|
* Calculates the (u, v) values of the points
|
|
*/
|
|
virtual bool GetUVParameters(double fSizeFactor);
|
|
|
|
/**
|
|
* Carries out a parameter correction.
|
|
*/
|
|
virtual void DoParameterCorrection(int iIter)=0;
|
|
|
|
/**
|
|
* Solves system of equations
|
|
*/
|
|
virtual bool SolveWithoutSmoothing()=0;
|
|
|
|
/**
|
|
* Solve a regular system of equations
|
|
*/
|
|
virtual bool SolveWithSmoothing(double fWeight)=0;
|
|
|
|
public:
|
|
/**
|
|
* Calculates a B-spline surface from the given points
|
|
*/
|
|
virtual Handle(Geom_BSplineSurface) CreateSurface(const TColgp_Array1OfPnt& points,
|
|
int iIter,
|
|
bool bParaCor,
|
|
double fSizeFactor=0.0f);
|
|
/**
|
|
* Setting the u/v directions
|
|
* The third parameter specifies whether the directions should actually be used.
|
|
*/
|
|
virtual void SetUV(const Base::Vector3d& clU, const Base::Vector3d& clV, bool bUseDir=true);
|
|
|
|
/**
|
|
* Returns the u/v/w directions
|
|
*/
|
|
virtual void GetUVW(Base::Vector3d& clU, Base::Vector3d& clV, Base::Vector3d& clW) const;
|
|
|
|
/**
|
|
* Get the center of gravity
|
|
*/
|
|
virtual Base::Vector3d GetGravityPoint() const;
|
|
|
|
/**
|
|
* Use smoothing-terms
|
|
*/
|
|
virtual void EnableSmoothing(bool bSmooth=true, double fSmoothInfl=1.0f);
|
|
|
|
protected:
|
|
bool _bGetUVDir; //! Determines whether u/v direction is given
|
|
bool _bSmoothing; //! Use smoothing
|
|
double _fSmoothInfluence; //! Influence of smoothing
|
|
unsigned _usUOrder; //! Order in u-direction
|
|
unsigned _usVOrder; //! Order in v-direction
|
|
unsigned _usUCtrlpoints; //! Number of control points in the u-direction
|
|
unsigned _usVCtrlpoints; //! Number of control points in the v-direction
|
|
Base::Vector3d _clU; //! u-direction
|
|
Base::Vector3d _clV; //! v-direction
|
|
Base::Vector3d _clW; //! w-direction (perpendicular to u & v directions)
|
|
TColgp_Array1OfPnt* _pvcPoints; //! Raw data point list
|
|
TColgp_Array1OfPnt2d* _pvcUVParam; //! Parameter value for the points in the list
|
|
TColgp_Array2OfPnt _vCtrlPntsOfSurf; //! Array of control points
|
|
TColStd_Array1OfReal _vUKnots; //! Knot vector of the B-spline surface in the u-direction
|
|
TColStd_Array1OfReal _vVKnots; //! Knot vector of the B-spline surface in the v-direction
|
|
TColStd_Array1OfInteger _vUMults; //! Multiplicity of the knots in the knot vector
|
|
TColStd_Array1OfInteger _vVMults; //! Multiplicity of the knots in the knot vector
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* This class calculates a B-spline area on any point cloud (AKA scattered data).
|
|
* The surface is generated iteratively with the help of a parameter correction.
|
|
* See Hoschek/Lasser 2nd ed. (1992).
|
|
* The approximation is expanded to include smoothing terms so that smooth surfaces
|
|
* can be generated.
|
|
*/
|
|
|
|
class ReenExport BSplineParameterCorrection : public ParameterCorrection
|
|
{
|
|
public:
|
|
// Constructor
|
|
BSplineParameterCorrection(unsigned usUOrder=4, //Order in u-direction (order = degree + 1)
|
|
unsigned usVOrder=4, //Order in the v-direction
|
|
unsigned usUCtrlpoints=6, //Qty. of the control points in u-direction
|
|
unsigned usVCtrlpoints=6); //Qty. of the control points in v-direction
|
|
|
|
virtual ~BSplineParameterCorrection(){}
|
|
|
|
protected:
|
|
/**
|
|
* Initialization
|
|
*/
|
|
virtual void Init();
|
|
|
|
/**
|
|
* Carries out a parameter correction.
|
|
*/
|
|
virtual void DoParameterCorrection(int iIter);
|
|
|
|
/**
|
|
* Solve an overdetermined LGS with the help of the Householder-Tansformation
|
|
*/
|
|
virtual bool SolveWithoutSmoothing();
|
|
|
|
/**
|
|
* Solve a regular system of equations by LU decomposition. Depending on the weighting,
|
|
* smoothing terms are included
|
|
*/
|
|
virtual bool SolveWithSmoothing(double fWeight);
|
|
|
|
public:
|
|
/**
|
|
* Setting the knot vector
|
|
*/
|
|
void SetUKnots(const std::vector<double>& afKnots);
|
|
|
|
/**
|
|
* Setting the knot vector
|
|
*/
|
|
void SetVKnots(const std::vector<double>& afKnots);
|
|
|
|
/**
|
|
* Returns the first matrix of smoothing terms, if calculated
|
|
*/
|
|
virtual const math_Matrix& GetFirstSmoothMatrix() const;
|
|
|
|
/**
|
|
* Returns the second matrix of smoothing terms, if calculated
|
|
*/
|
|
virtual const math_Matrix& GetSecondSmoothMatrix() const;
|
|
|
|
/**
|
|
* Returns the third matrix of smoothing terms, if calculated
|
|
*/
|
|
virtual const math_Matrix& GetThirdSmoothMatrix() const;
|
|
|
|
/**
|
|
* Sets the first matrix of the smoothing terms
|
|
*/
|
|
virtual void SetFirstSmoothMatrix(const math_Matrix& rclMat);
|
|
|
|
/**
|
|
* Sets the second matrix of smoothing terms
|
|
*/
|
|
virtual void SetSecondSmoothMatrix(const math_Matrix& rclMat);
|
|
|
|
/**
|
|
* Sets the third matrix of smoothing terms
|
|
*/
|
|
virtual void SetThirdSmoothMatrix(const math_Matrix& rclMat);
|
|
|
|
/**
|
|
* Use smoothing-terms
|
|
*/
|
|
virtual void EnableSmoothing(bool bSmooth=true, double fSmoothInfl=1.0f);
|
|
|
|
/**
|
|
* Use smoothing-terms
|
|
*/
|
|
virtual void EnableSmoothing(bool bSmooth, double fSmoothInfl,
|
|
double fFirst, double fSec, double fThird);
|
|
|
|
protected:
|
|
/**
|
|
* Calculates the matrix for the smoothing terms
|
|
* (see U.Dietz dissertation)
|
|
*/
|
|
virtual void CalcSmoothingTerms(bool bRecalc, double fFirst, double fSecond, double fThird);
|
|
|
|
/**
|
|
* Calculates the matrix for the first smoothing term
|
|
* (see U.Dietz dissertation)
|
|
*/
|
|
virtual void CalcFirstSmoothMatrix(Base::SequencerLauncher&);
|
|
|
|
/**
|
|
* Calculates the matrix for the second smoothing term
|
|
* (see U.Dietz dissertation)
|
|
*/
|
|
virtual void CalcSecondSmoothMatrix(Base::SequencerLauncher&);
|
|
|
|
/**
|
|
* Calculates the matrix for the third smoothing term
|
|
*/
|
|
virtual void CalcThirdSmoothMatrix(Base::SequencerLauncher&);
|
|
|
|
protected:
|
|
BSplineBasis _clUSpline; //! B-spline basic function in the u-direction
|
|
BSplineBasis _clVSpline; //! B-spline basic function in the v-direction
|
|
math_Matrix _clSmoothMatrix; //! Matrix of smoothing functionals
|
|
math_Matrix _clFirstMatrix; //! Matrix of the 1st smoothing functionals
|
|
math_Matrix _clSecondMatrix; //! Matrix of the 2nd smoothing functionals
|
|
math_Matrix _clThirdMatrix; //! Matrix of the 3rd smoothing functionals
|
|
};
|
|
|
|
} // namespace Reen
|
|
|
|
#endif // REEN_APPROXSURFACE_H
|