/*************************************************************************** * Copyright (c) 2008 Werner Mayer * * * * 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 #include #include #include #include #include #include #include namespace Base { class SequencerLauncher; } // TODO: Replace OCC stuff with ublas & co namespace Reen { class ReenExport SplineBasisfunction { public: enum ValueT { Zero = 0, Full, Other }; /** * Konstruktor * @param iSize Length of Knots vector */ SplineBasisfunction(int iSize); /** * Konstruktor * @param vKnots Knotenvektor * @param iOrder Ordnung (Grad+1) des Basis-Polynoms */ SplineBasisfunction(TColStd_Array1OfReal& vKnots, int iOrder=1); /** * Konstruktor * @param vKnots Knotenvektor der Form (Wert) * @param vMults Knotenvektor der Form (Vielfachheit) * @param iSize Laenge des Knotenvektors * Die Arrays @a vKnots und @a vMults muessen die gleiche besitzen und die Summe der Werte in @a vMults * muss identisch mit @a iSize sein. * @param iOrder Ordnung (Grad+1) des Basis-Polynoms */ SplineBasisfunction(TColStd_Array1OfReal& vKnots, TColStd_Array1OfInteger& vMults, int iSize, int iOrder=1); virtual ~SplineBasisfunction(); /** * Gibt an, ob der Funktionswert Nik(t) an der Stelle fParam * 0, 1 oder ein Wert dazwischen ergibt. * Dies dient dazu, um die Berechnung zu u.U. zu beschleunigen. * * @param iIndex Index * @param fParam Parameterwert * @return ValueT */ virtual ValueT LocalSupport(int iIndex, double fParam)=0; /** * Berechnet den Funktionswert Nik(t) an der Stelle fParam * (aus: Piegl/Tiller 96 The NURBS-Book) * * @param iIndex Index * @param fParam Parameterwert * @return Funktionswert Nik(t) */ virtual double BasisFunction(int iIndex, double fParam)=0; /** * Berechnet die Funktionswerte der ersten iMaxDer Ableitungen an der * Stelle fParam (aus: Piegl/Tiller 96 The NURBS-Book) * * @param iIndex Index * @param iMaxDer max. Ableitung * @param fParam Parameterwert. * @return Derivat Liste der Funktionswerte * * Die Liste muss fuer iMaxDer+1 Elemente ausreichen. */ virtual void DerivativesOfBasisFunction(int iIndex, int iMaxDer, double fParam, TColStd_Array1OfReal& Derivat)=0; /** * Berechnet die k-te Ableitung an der Stelle fParam */ virtual double DerivativeOfBasisFunction(int iIndex, int k, double fParam)=0; /** * Setzt den Knotenvektor und die Ordnung fest. Die Groesse des Knotenvektors muss exakt so gross sein, * wie im Konstruktor festgelegt. */ virtual void SetKnots(TColStd_Array1OfReal& vKnots, int iOrder=1); /** * Setzt den Knotenvektor und die Ordnung fest. uebergeben wird der Knotenvektor der Form * (Wert, Vielfachheit). Intern wird dieser in einen Knotenvektor der Form (Wert,1) * umgerechnet. Die Groesse dieses neuen Vektors muss exakt so gross sein, wie im Konstruktor * festgelegt. */ virtual void SetKnots(TColStd_Array1OfReal& vKnots, TColStd_Array1OfInteger& vMults, int iOrder=1); protected: //Member // Knotenvektor TColStd_Array1OfReal _vKnotVector; // Ordnung (=Grad+1) int _iOrder; }; class ReenExport BSplineBasis : public SplineBasisfunction { public: /** * Konstruktor * @param iSize Laenge des Knotenvektors */ BSplineBasis(int iSize); /** * Konstruktor * @param vKnots Knotenvektor * @param iOrder Ordnung (Grad+1) des Basis-Polynoms */ BSplineBasis(TColStd_Array1OfReal& vKnots, int iOrder=1); /** * Konstruktor * @param vKnots Knotenvektor der Form (Wert) * @param vMults Knotenvektor der Form (Vielfachheit) * @param iSize Laenge des Knotenvektors * Die Arrays @a vKnots und @a vMults muessen die gleiche besitzen und die Summe der Werte in @a vMults * muss identisch mit @a iSize sein. * @param iOrder Ordnung (Grad+1) des Basis-Polynoms */ BSplineBasis(TColStd_Array1OfReal& vKnots, TColStd_Array1OfInteger& vMults, int iSize, int iOrder=1); /** * Bestimmt den Knotenindex zum Parameterwert (aus: Piegl/Tiller 96 The NURBS-Book) * @param fParam Parameterwert * @return Knotenindex */ virtual int FindSpan(double fParam); /** * Berechnet die Funktionswerte der an der Stelle fParam * nicht verschwindenden Basisfunktionen. Es muss darauf geachtet werden, dass * die Liste fuer d(=Grad des B-Splines) Elemente (0,...,d-1) ausreicht. * (aus: Piegl/Tiller 96 The NURBS-Book) * @param fParam Parameter * @param vFuncVals Liste der Funktionswerte * Index, Parameterwert */ virtual void AllBasisFunctions(double fParam, TColStd_Array1OfReal& vFuncVals); /** * Gibt an, ob der Funktionswert Nik(t) an der Stelle fParam * 0, 1 oder ein Wert dazwischen ergibt. * Dies dient dazu, um die Berechnung zu u.U. zu beschleunigen. * * @param iIndex Index * @param fParam Parameterwert * @return ValueT */ virtual ValueT LocalSupport(int iIndex, double fParam); /** * Berechnet den Funktionswert Nik(t) an der Stelle fParam * (aus: Piegl/Tiller 96 The NURBS-Book) * @param iIndex Index * @param fParam Parameterwert * @return Funktionswert Nik(t) */ virtual double BasisFunction(int iIndex, double fParam); /** * Berechnet die Funktionswerte der ersten iMaxDer Ableitungen an der Stelle fParam * (aus: Piegl/Tiller 96 The NURBS-Book) * @param iIndex Index * @param iMaxDer max. Ableitung * @param fParam Parameterwert. * @param Derivat * Die Liste muss fuer iMaxDer+1 Elemente ausreichen. * @return Liste der Funktionswerte */ virtual void DerivativesOfBasisFunction(int iIndex, int iMaxDer, double fParam, TColStd_Array1OfReal& Derivat); /** * Berechnet die k-te Ableitung an der Stelle fParam */ virtual double DerivativeOfBasisFunction(int iIndex, int k, double fParam); /** * Berechnet das Integral des Produkts zweier B-Splines bzw. deren Ableitungen. * Der Integrationsbereich erstreckt sich ueber den ganzen Definitionsbereich. * Berechnet wird das Integral mittels der Gauss'schen Quadraturformeln. */ virtual double GetIntegralOfProductOfBSplines(int i, int j, int r, int s); /** * Destruktor */ virtual~ BSplineBasis(); protected: /** * Berechnet die Nullstellen der Legendre-Polynome und die * zugehoerigen Gewichte */ virtual void GenerateRootsAndWeights(TColStd_Array1OfReal& vAbscissas, TColStd_Array1OfReal& vWeights); /** * Berechnet die Integrationsgrenzen (Indexe der Knoten) */ virtual void FindIntegrationArea(int iIdx1, int iIdx2, int& iBegin, int& iEnd); /** * Berechnet in Abhaengigkeit vom Grad die Anzahl der zu verwendenden Nullstellen/Gewichte * der Legendre-Polynome */ int CalcSize(int r, int s); }; class ReenExport ParameterCorrection { public: // Konstruktor ParameterCorrection(unsigned usUOrder=4, //Ordnung in u-Richtung (Ordnung=Grad+1) unsigned usVOrder=4, //Ordnung in v-Richtung unsigned usUCtrlpoints=6, //Anz. der Kontrollpunkte in u-Richtung unsigned usVCtrlpoints=6); //Anz. der Kontrollpunkte in v-Richtung virtual ~ParameterCorrection() { delete _pvcPoints; delete _pvcUVParam; } protected: /** * Berechnet die Eigenvektoren der Kovarianzmatrix */ virtual void CalcEigenvectors(); /** * Projiziert die Kontrollpunkte auf die Fit-Ebene */ void ProjectControlPointsOnPlane(); /** * Berechnet eine initiale Flaeche zu Beginn des Algorithmus. Dazu wird die Ausgleichsebene zu der * Punktwolke berechnet. * Die Punkte werden bzgl. der Basis bestehend aus den Eigenvektoren der Kovarianzmatrix berechnet und * auf die Ausgleichsebene projiziert. Von diesen Punkten wird die Boundingbox berechnet, dann werden * die u/v-Parameter fuer die Punkte berechnet. */ virtual bool DoInitialParameterCorrection(double fSizeFactor=0.0f); /** * Berechnet die u.v-Werte der Punkte */ virtual bool GetUVParameters(double fSizeFactor); /** * Fuehrt eine Parameterkorrektur durch. */ virtual void DoParameterCorrection(int iIter)=0; /** * Loest Gleichungssystem */ virtual bool SolveWithoutSmoothing()=0; /** * Loest ein regulaeres Gleichungssystem */ virtual bool SolveWithSmoothing(double fWeight)=0; public: /** * Berechnet eine B-Spline-Flaeche.aus den geg. Punkten */ virtual Handle_Geom_BSplineSurface CreateSurface(const TColgp_Array1OfPnt& points, int iIter, bool bParaCor, double fSizeFactor=0.0f); /** * Setzen der u/v-Richtungen * Dritter Parameter gibt an, ob die Richtungen tatsaechlich verwendet werden sollen. */ virtual void SetUV(const Base::Vector3d& clU, const Base::Vector3d& clV, bool bUseDir=true); /** * Gibt die u/v/w-Richtungen zurueck */ virtual void GetUVW(Base::Vector3d& clU, Base::Vector3d& clV, Base::Vector3d& clW) const; /** * */ virtual Base::Vector3d GetGravityPoint() const; /** * Verwende Glaettungsterme */ virtual void EnableSmoothing(bool bSmooth=true, double fSmoothInfl=1.0f); protected: bool _bGetUVDir; //! Stellt fest, ob u/v-Richtung vorgegeben wird bool _bSmoothing; //! Glaettung verwenden double _fSmoothInfluence; //! Einfluss der Glaettung unsigned _usUOrder; //! Ordnung in u-Richtung unsigned _usVOrder; //! Ordnung in v-Richtung unsigned _usUCtrlpoints; //! Anzahl der Kontrollpunkte in u-Richtung unsigned _usVCtrlpoints; //! Anzahl der Kontrollpunkte in v-Richtung Base::Vector3d _clU; //! u-Richtung Base::Vector3d _clV; //! v-Richtung Base::Vector3d _clW; //! w-Richtung (senkrecht zu u-und v-Richtung) TColgp_Array1OfPnt* _pvcPoints; //! Punktliste der Rohdaten TColgp_Array1OfPnt2d* _pvcUVParam; //! Parameterwerte zu den Punkten aus der Liste TColgp_Array2OfPnt _vCtrlPntsOfSurf; //! Array von Kontrollpunkten TColStd_Array1OfReal _vUKnots; //! Knotenvektor der B-Spline-Flaeche in u-Richtung TColStd_Array1OfReal _vVKnots; //! Knotenvektor der B-Spline-Flaeche in v-Richtung TColStd_Array1OfInteger _vUMults; //! Vielfachheit der Knoten im Knotenvektor TColStd_Array1OfInteger _vVMults; //! Vielfachheit der Knoten im Knotenvektor }; /////////////////////////////////////////////////////////////////////////////////////////////// /** * Diese Klasse berechnet auf einer beliebigen Punktwolke (auch scattered data) eine * B-Spline-Flaeche. Die Flaeche wird iterativ mit Hilfe einer Parameterkorrektur erzeugt. * Siehe dazu Hoschek/Lasser 2. Auflage (1992). * Erweitert wird die Approximation um Glaettungsterme, so dass glatte Flaechen erzeugt werden * koennen. */ class ReenExport BSplineParameterCorrection : public ParameterCorrection { public: // Konstruktor BSplineParameterCorrection(unsigned usUOrder=4, //Ordnung in u-Richtung (Ordnung=Grad+1) unsigned usVOrder=4, //Ordnung in v-Richtung unsigned usUCtrlpoints=6, //Anz. der Kontrollpunkte in u-Richtung unsigned usVCtrlpoints=6); //Anz. der Kontrollpunkte in v-Richtung virtual ~BSplineParameterCorrection(){}; protected: /** * Initialisierung */ virtual void Init(); /** * Fuehrt eine Parameterkorrektur durch. */ virtual void DoParameterCorrection(int iIter); /** * Loest ein ueberbestimmtes LGS mit Hilfe der Householder-Transformation */ virtual bool SolveWithoutSmoothing(); /** * Loest ein regulaeres Gleichungssystem durch LU-Zerlegung. Es fliessen je nach Gewichtung * Glaettungsterme mit ein */ virtual bool SolveWithSmoothing(double fWeight); public: /** * Setzen des Knotenvektors */ void SetUKnots(const std::vector& afKnots); /** * Setzen des Knotenvektors */ void SetVKnots(const std::vector& afKnots); /** * Gibt die erste Matrix der Glaettungsterme zurueck, falls berechnet */ virtual const math_Matrix& GetFirstSmoothMatrix() const; /** * Gibt die zweite Matrix der Glaettungsterme zurueck, falls berechnet */ virtual const math_Matrix& GetSecondSmoothMatrix() const; /** * Gibt die dritte Matrix der Glaettungsterme zurueck, falls berechnet */ virtual const math_Matrix& GetThirdSmoothMatrix() const; /** * Setzt die erste Matrix der Glaettungsterme */ virtual void SetFirstSmoothMatrix(const math_Matrix& rclMat); /** * Setzt die zweite Matrix der Glaettungsterme */ virtual void SetSecondSmoothMatrix(const math_Matrix& rclMat); /** * Setzt die dritte Matrix der Glaettungsterme */ virtual void SetThirdSmoothMatrix(const math_Matrix& rclMat); /** * Verwende Glaettungsterme */ virtual void EnableSmoothing(bool bSmooth=true, double fSmoothInfl=1.0f); /** * Verwende Glaettungsterme */ virtual void EnableSmoothing(bool bSmooth, double fSmoothInfl, double fFirst, double fSec, double fThird); protected: /** * Berechnet die Matrix zu den Glaettungstermen * (siehe Dissertation U.Dietz) */ virtual void CalcSmoothingTerms(bool bRecalc, double fFirst, double fSecond, double fThird); /** * Berechnet die Matrix zum ersten Glaettungsterm * (siehe Diss. U.Dietz) */ virtual void CalcFirstSmoothMatrix(Base::SequencerLauncher&); /** * Berechnet die Matrix zum zweiten Glaettunsterm * (siehe Diss. U.Dietz) */ virtual void CalcSecondSmoothMatrix(Base::SequencerLauncher&); /** * Berechnet die Matrix zum dritten Glaettungsterm */ virtual void CalcThirdSmoothMatrix(Base::SequencerLauncher&); protected: BSplineBasis _clUSpline; //! B-Spline-Basisfunktion in u-Richtung BSplineBasis _clVSpline; //! B-Spline-Basisfunktion in v-Richtung math_Matrix _clSmoothMatrix; //! Matrix der Glaettungsfunktionale math_Matrix _clFirstMatrix; //! Matrix der 1. Glaettungsfunktionale math_Matrix _clSecondMatrix; //! Matrix der 2. Glaettungsfunktionale math_Matrix _clThirdMatrix; //! Matrix der 3. Glaettungsfunktionale }; } // namespace Reen #endif // REEN_APPROXSURFACE_H