486 lines
17 KiB
C++
486 lines
17 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 <Handle_Geom_BSplineSurface.hxx>
|
|
#include <math_Matrix.hxx>
|
|
|
|
#include <Base/Vector3D.h>
|
|
|
|
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();
|
|
|
|
/**
|
|
* 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 SetUVW(const Base::Vector3d& clU, const Base::Vector3d& clV, const Base::Vector3d& clW, 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 w-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<double>& afKnots);
|
|
|
|
/**
|
|
* Setzen des Knotenvektors
|
|
*/
|
|
void SetVKnots(const std::vector<double>& 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
|