diff --git a/src/Mod/ReverseEngineering/App/ApproxSurface.cpp b/src/Mod/ReverseEngineering/App/ApproxSurface.cpp index 488a4972a..558c33890 100644 --- a/src/Mod/ReverseEngineering/App/ApproxSurface.cpp +++ b/src/Mod/ReverseEngineering/App/ApproxSurface.cpp @@ -37,45 +37,40 @@ using namespace Reen; // SplineBasisfunction SplineBasisfunction::SplineBasisfunction(int iSize) -: _vKnotVector(0,iSize-1) + : _vKnotVector(0,iSize-1) { } -SplineBasisfunction::SplineBasisfunction - (TColStd_Array1OfReal& vKnots, - TColStd_Array1OfInteger& vMults, - int iSize, - int iOrder) -: _vKnotVector(0,iSize-1) +SplineBasisfunction::SplineBasisfunction(TColStd_Array1OfReal& vKnots, + TColStd_Array1OfInteger& vMults, + int iSize, int iOrder) + : _vKnotVector(0,iSize-1) { - int sum = 0; - for (int h=vMults.Lower(); h<=vMults.Upper(); h++) - sum += vMults(h); + int sum = 0; + for (int h=vMults.Lower(); h<=vMults.Upper(); h++) + sum += vMults(h); - if (vKnots.Length() != vMults.Length() || iSize != sum) - { - // Werfe Exception - Standard_ConstructionError::Raise("BSplineBasis"); - } - - int k=0; - for (int i=vMults.Lower(); i<=vMults.Upper(); i++) - { - for (int j=0; j= _vKnotVector(mid+1)) - { - if (fParam < _vKnotVector(mid)) - high = mid; - else - low = mid; - mid = (low+high)/2; - } + while (fParam < _vKnotVector(mid) || fParam>= _vKnotVector(mid+1)) { + if (fParam < _vKnotVector(mid)) + high = mid; + else + low = mid; + mid = (low+high)/2; + } - return mid; + return mid; } void BSplineBasis::AllBasisFunctions(double fParam, TColStd_Array1OfReal& vFuncVals) { - if (vFuncVals.Length() != _iOrder) - Standard_RangeError::Raise("BSplineBasis"); + if (vFuncVals.Length() != _iOrder) + Standard_RangeError::Raise("BSplineBasis"); - int iIndex = FindSpan(fParam); + int iIndex = FindSpan(fParam); - TColStd_Array1OfReal zaehler_left(1,_iOrder-1); - TColStd_Array1OfReal zaehler_right(1,_iOrder-1); - vFuncVals(0) = 1.0f; + TColStd_Array1OfReal zaehler_left(1,_iOrder-1); + TColStd_Array1OfReal zaehler_right(1,_iOrder-1); + vFuncVals(0) = 1.0; - for (int j=1; j<_iOrder; j++) - { - zaehler_left(j) = fParam - _vKnotVector(iIndex+1-j); - zaehler_right(j) = _vKnotVector(iIndex+j) - fParam; - double saved = 0.0f; - for (int r=0; r= _vKnotVector(iIndex+p+1)) - { - return 0.0f; - } - - for (int j=0; j<=p; j++) - { - if (fParam >= _vKnotVector(iIndex+j) && fParam < _vKnotVector(iIndex+j+1)) - N(j) = 1.0f; - else - N(j) = 0.0f; - } - - for (int k=1; k<=p; k++) - { - if (N(0) == 0.0f) - saved = 0.0f; - else - saved = ((fParam - _vKnotVector(iIndex))*N(0)) / (_vKnotVector(iIndex+k) - _vKnotVector(iIndex)); - - for (int j=0; j= _vKnotVector(iIndex+p+1)) { + return 0.0; + } + + for (int j=0; j<=p; j++) { + if (fParam >= _vKnotVector(iIndex+j) && fParam < _vKnotVector(iIndex+j+1)) + N(j) = 1.0; + else + N(j) = 0.0; + } + + for (int k=1; k<=p; k++) { + if (N(0) == 0.0) + saved = 0.0; + else + saved = ((fParam - _vKnotVector(iIndex))*N(0)) / (_vKnotVector(iIndex+k) - _vKnotVector(iIndex)); + + for (int j=0; jGrad) sind Null - if (iMax >= _iOrder) - { - for (int i=_iOrder; i<=iMaxDer; i++) - Derivat(i) = 0.0f; - iMax = _iOrder - 1; - } - - TColStd_Array1OfReal ND(0, iMax); - int p = _iOrder-1; - math_Matrix N(0,p,0,p); - double saved; - - // falls Wert außerhalb Intervall, dann Funktionswert und alle Ableitungen gleich Null - if (fParam < _vKnotVector(iIndex) || fParam >= _vKnotVector(iIndex+p+1)) - { - for (int k=0; k<=iMax; k++) - Derivat(k) = 0.0f; - return; - } - - // Berechne die Basisfunktionen der Ordnung 1 - for (int j=0; j<_iOrder; j++) - { - if (fParam >= _vKnotVector(iIndex+j) && fParam < _vKnotVector(iIndex+j+1)) - N(j,0) = 1.0f; - else - N(j,0) = 0.0f; - } - - // Berechne Dreieckstabelle der Funktionswerte - for (int k=1; k<_iOrder; k++) - { - if (N(0,k-1) == 0.0f) - saved = 0.0f; - else - saved = ((fParam - _vKnotVector(iIndex))*N(0,k-1))/(_vKnotVector(iIndex+k)-_vKnotVector(iIndex)); - for (int j=0; jGrad) sind Null + if (iMax >= _iOrder) { + for (int i=_iOrder; i<=iMaxDer; i++) + Derivat(i) = 0.0; + iMax = _iOrder - 1; } - for (int jj=1; jj<=k; jj++) - { - if (ND(0) == 0.0f) - saved = 0.0f; - else - saved = ND(0)/(_vKnotVector(iIndex+p-k+jj) - _vKnotVector(iIndex)); + TColStd_Array1OfReal ND(0, iMax); + int p = _iOrder-1; + math_Matrix N(0,p,0,p); + double saved; - for (int j=0; j= _vKnotVector(iIndex+p+1)) { + for (int k=0; k<=iMax; k++) + Derivat(k) = 0.0; + return; + } + + // Berechne die Basisfunktionen der Ordnung 1 + for (int j=0; j<_iOrder; j++) { + if (fParam >= _vKnotVector(iIndex+j) && fParam < _vKnotVector(iIndex+j+1)) + N(j,0) = 1.0; + else + N(j,0) = 0.0; + } + + // Berechne Dreieckstabelle der Funktionswerte + for (int k=1; k<_iOrder; k++) { + if (N(0,k-1) == 0.0) + saved = 0.0; else - { - double tmp = ND(j+1)/(Tright-Tleft); - ND(j) = (p-k+jj)*(saved-tmp); - saved = tmp; + saved = ((fParam - _vKnotVector(iIndex))*N(0,k-1))/(_vKnotVector(iIndex+k)-_vKnotVector(iIndex)); + for (int j=0; jGrad) sind Null - if (iMax >= _iOrder) - { - return 0.0f; - } - - TColStd_Array1OfReal ND(0, iMax); - int p = _iOrder-1; - math_Matrix N(0,p,0,p); - double saved; - - // falls Wert außerhalb Intervall, dann Funktionswert und Ableitungen gleich Null - if (fParam < _vKnotVector(iIndex) || fParam >= _vKnotVector(iIndex+p+1)) - { - return 0.0f; - } - - // Berechne die Basisfunktionen der Ordnung 1 - for (int j=0; j<_iOrder; j++) - { - if (fParam >= _vKnotVector(iIndex+j) && fParam < _vKnotVector(iIndex+j+1)) - N(j,0) = 1.0f; - else - N(j,0) = 0.0f; - } - - // Berechne Dreieckstabelle der Funktionswerte - for (int k=1; k<_iOrder; k++) - { - if (N(0,k-1) == 0.0f) - saved = 0.0f; - else - saved = ((fParam - _vKnotVector(iIndex))*N(0,k-1))/(_vKnotVector(iIndex+k)-_vKnotVector(iIndex)); - for (int j=0; jGrad) sind Null + if (iMax >= _iOrder) { + return 0.0; } - } - // Berechne aus der Dreieckstabelle die Ableitungen - for (int j=0; j<=iMax; j++) - { - // Lade (p-iMax)-te Spalte - ND(j) = N(j,p-iMax); - } + TColStd_Array1OfReal ND(0, iMax); + int p = _iOrder-1; + math_Matrix N(0,p,0,p); + double saved; - for (int jj=1; jj<=iMax; jj++) - { - if (ND(0) == 0.0f) - saved = 0.0f; - else - saved = ND(0)/(_vKnotVector(iIndex+p-iMax+jj) - _vKnotVector(iIndex)); - - for (int j=0; j= _vKnotVector(iIndex+p+1)) { + return 0.0; } - } - return ND(0); //iMax-te Ableitung + // Berechne die Basisfunktionen der Ordnung 1 + for (int j=0; j<_iOrder; j++) { + if (fParam >= _vKnotVector(iIndex+j) && fParam < _vKnotVector(iIndex+j+1)) + N(j,0) = 1.0; + else + N(j,0) = 0.0; + } + + // Berechne Dreieckstabelle der Funktionswerte + for (int k=1; k<_iOrder; k++) { + if (N(0,k-1) == 0.0) + saved = 0.0; + else + saved = ((fParam - _vKnotVector(iIndex))*N(0,k-1))/(_vKnotVector(iIndex+k)-_vKnotVector(iIndex)); + + for (int j=0; j fMin) - { - for (int i=0; i<=iMax; i++) - { - double fParam = 0.5*(vRoots(i)+1)*(fMax-fMin)+fMin; - dIntegral += 0.5*(fMax-fMin)*vWeights(i) * - DerivativeOfBasisFunction(iIdx1, iOrd1, fParam) * - DerivativeOfBasisFunction(iIdx2, iOrd2, fParam); - } + if (fMax > fMin) { + for (int i=0; i<=iMax; i++) { + double fParam = 0.5*(vRoots(i)+1)*(fMax-fMin)+fMin; + dIntegral += 0.5*(fMax-fMin)*vWeights(i) * + DerivativeOfBasisFunction(iIdx1, iOrd1, fParam) * + DerivativeOfBasisFunction(iIdx2, iOrd2, fParam); + } + } } - } - return dIntegral; + return dIntegral; } void BSplineBasis::GenerateRootsAndWeights(TColStd_Array1OfReal& vRoots, TColStd_Array1OfReal& vWeights) { - int iSize = vRoots.Length(); + int iSize = vRoots.Length(); - //Nullstellen der Legendre-Polynome und die zugeh. Gewichte - if (iSize == 1) - { - vRoots(0) = 0.0f; vWeights(0) = 2.0f; - } - else if (iSize == 2) - { - vRoots(0) = 0.57735; vWeights(0) = 1.0; - vRoots(1) = -vRoots(0); vWeights(1) = vWeights(0); - } - else if (iSize == 4) - { - vRoots(0) = 0.33998; vWeights(0) = 0.65214; - vRoots(1) = 0.86113; vWeights(1) = 0.34785; - vRoots(2) = -vRoots(0); vWeights(2) = vWeights(0); - vRoots(3) = -vRoots(1); vWeights(3) = vWeights(1); - } - else if (iSize == 6) - { - vRoots(0) = 0.23861; vWeights(0) = 0.46791; - vRoots(1) = 0.66120; vWeights(1) = 0.36076; - vRoots(2) = 0.93246; vWeights(2) = 0.17132; - vRoots(3) = -vRoots(0); vWeights(3) = vWeights(0); - vRoots(4) = -vRoots(1); vWeights(4) = vWeights(1); - vRoots(5) = -vRoots(2); vWeights(5) = vWeights(2); - } - else if (iSize == 8) - { - vRoots(0) = 0.18343; vWeights(0) = 0.36268; - vRoots(1) = 0.52553; vWeights(1) = 0.31370; - vRoots(2) = 0.79666; vWeights(2) = 0.22238; - vRoots(3) = 0.96028; vWeights(3) = 0.10122; - vRoots(4) = -vRoots(0); vWeights(4) = vWeights(0); - vRoots(5) = -vRoots(1); vWeights(5) = vWeights(1); - vRoots(6) = -vRoots(2); vWeights(6) = vWeights(2); - vRoots(7) = -vRoots(3); vWeights(7) = vWeights(3); - } - else if (iSize == 10) - { - vRoots(0) = 0.14887; vWeights(0) = 0.29552; - vRoots(1) = 0.43339; vWeights(1) = 0.26926; - vRoots(2) = 0.67940; vWeights(2) = 0.21908; - vRoots(3) = 0.86506; vWeights(3) = 0.14945; - vRoots(4) = 0.97390; vWeights(4) = 0.06667; - vRoots(5) = -vRoots(0); vWeights(5) = vWeights(0); - vRoots(6) = -vRoots(1); vWeights(6) = vWeights(1); - vRoots(7) = -vRoots(2); vWeights(7) = vWeights(2); - vRoots(8) = -vRoots(3); vWeights(8) = vWeights(3); - vRoots(9) = -vRoots(4); vWeights(9) = vWeights(4); - } - else - { - vRoots(0) = 0.12523; vWeights(0) = 0.24914; - vRoots(1) = 0.36783; vWeights(1) = 0.23349; - vRoots(2) = 0.58731; vWeights(2) = 0.20316; - vRoots(3) = 0.76990; vWeights(3) = 0.16007; - vRoots(4) = 0.90411; vWeights(4) = 0.10693; - vRoots(5) = 0.98156; vWeights(5) = 0.04717; - vRoots(6) = -vRoots(0); vWeights(6) = vWeights(0); - vRoots(7) = -vRoots(1); vWeights(7) = vWeights(1); - vRoots(8) = -vRoots(2); vWeights(8) = vWeights(2); - vRoots(9) = -vRoots(3); vWeights(9) = vWeights(3); - vRoots(10)= -vRoots(4); vWeights(10)= vWeights(4); - vRoots(11)= -vRoots(5); vWeights(11)= vWeights(5); - } + //Nullstellen der Legendre-Polynome und die zugeh. Gewichte + if (iSize == 1) { + vRoots(0) = 0.0; vWeights(0) = 2.0; + } + else if (iSize == 2) { + vRoots(0) = 0.57735; vWeights(0) = 1.0; + vRoots(1) = -vRoots(0); vWeights(1) = vWeights(0); + } + else if (iSize == 4) { + vRoots(0) = 0.33998; vWeights(0) = 0.65214; + vRoots(1) = 0.86113; vWeights(1) = 0.34785; + vRoots(2) = -vRoots(0); vWeights(2) = vWeights(0); + vRoots(3) = -vRoots(1); vWeights(3) = vWeights(1); + } + else if (iSize == 6) { + vRoots(0) = 0.23861; vWeights(0) = 0.46791; + vRoots(1) = 0.66120; vWeights(1) = 0.36076; + vRoots(2) = 0.93246; vWeights(2) = 0.17132; + vRoots(3) = -vRoots(0); vWeights(3) = vWeights(0); + vRoots(4) = -vRoots(1); vWeights(4) = vWeights(1); + vRoots(5) = -vRoots(2); vWeights(5) = vWeights(2); + } + else if (iSize == 8) { + vRoots(0) = 0.18343; vWeights(0) = 0.36268; + vRoots(1) = 0.52553; vWeights(1) = 0.31370; + vRoots(2) = 0.79666; vWeights(2) = 0.22238; + vRoots(3) = 0.96028; vWeights(3) = 0.10122; + vRoots(4) = -vRoots(0); vWeights(4) = vWeights(0); + vRoots(5) = -vRoots(1); vWeights(5) = vWeights(1); + vRoots(6) = -vRoots(2); vWeights(6) = vWeights(2); + vRoots(7) = -vRoots(3); vWeights(7) = vWeights(3); + } + else if (iSize == 10) { + vRoots(0) = 0.14887; vWeights(0) = 0.29552; + vRoots(1) = 0.43339; vWeights(1) = 0.26926; + vRoots(2) = 0.67940; vWeights(2) = 0.21908; + vRoots(3) = 0.86506; vWeights(3) = 0.14945; + vRoots(4) = 0.97390; vWeights(4) = 0.06667; + vRoots(5) = -vRoots(0); vWeights(5) = vWeights(0); + vRoots(6) = -vRoots(1); vWeights(6) = vWeights(1); + vRoots(7) = -vRoots(2); vWeights(7) = vWeights(2); + vRoots(8) = -vRoots(3); vWeights(8) = vWeights(3); + vRoots(9) = -vRoots(4); vWeights(9) = vWeights(4); + } + else { + vRoots(0) = 0.12523; vWeights(0) = 0.24914; + vRoots(1) = 0.36783; vWeights(1) = 0.23349; + vRoots(2) = 0.58731; vWeights(2) = 0.20316; + vRoots(3) = 0.76990; vWeights(3) = 0.16007; + vRoots(4) = 0.90411; vWeights(4) = 0.10693; + vRoots(5) = 0.98156; vWeights(5) = 0.04717; + vRoots(6) = -vRoots(0); vWeights(6) = vWeights(0); + vRoots(7) = -vRoots(1); vWeights(7) = vWeights(1); + vRoots(8) = -vRoots(2); vWeights(8) = vWeights(2); + vRoots(9) = -vRoots(3); vWeights(9) = vWeights(3); + vRoots(10)= -vRoots(4); vWeights(10)= vWeights(4); + vRoots(11)= -vRoots(5); vWeights(11)= vWeights(5); + } } void BSplineBasis::FindIntegrationArea(int iIdx1, int iIdx2, int& iBegin, int& iEnd) { - // nach Index ordnen - if (iIdx2 < iIdx1) - { - int tmp=iIdx1; - iIdx1 = iIdx2; - iIdx2 = tmp; - } + // nach Index ordnen + if (iIdx2 < iIdx1) { + int tmp=iIdx1; + iIdx1 = iIdx2; + iIdx2 = tmp; + } - iBegin = iIdx2; - iEnd = iIdx1+_iOrder; - if (iEnd == _vKnotVector.Upper()) - iEnd -= 1; + iBegin = iIdx2; + iEnd = iIdx1+_iOrder; + if (iEnd == _vKnotVector.Upper()) + iEnd -= 1; } int BSplineBasis::CalcSize(int r, int s) { - int iMaxDegree = 2*(_iOrder-1)-r-s; + int iMaxDegree = 2*(_iOrder-1)-r-s; - if (iMaxDegree < 0) - return 0; - else if (iMaxDegree < 4) - return 1; - else if (iMaxDegree < 8) - return 3; - else if (iMaxDegree < 12) - return 5; - else if (iMaxDegree < 16) - return 7; - else if (iMaxDegree < 20) - return 9; - else - return 11; + if (iMaxDegree < 0) + return 0; + else if (iMaxDegree < 4) + return 1; + else if (iMaxDegree < 8) + return 3; + else if (iMaxDegree < 12) + return 5; + else if (iMaxDegree < 16) + return 7; + else if (iMaxDegree < 20) + return 9; + else + return 11; } /////////////////// ParameterCorrection ParameterCorrection::ParameterCorrection(unsigned short usUOrder, unsigned short usVOrder, unsigned short usUCtrlpoints, unsigned short usVCtrlpoints) - : _usUOrder(usUOrder), - _usVOrder(usVOrder), - _usUCtrlpoints(usUCtrlpoints), - _usVCtrlpoints(usVCtrlpoints), - _vCtrlPntsOfSurf(0,usUCtrlpoints-1,0,usVCtrlpoints-1), - _vUKnots(0,usUCtrlpoints-usUOrder+1), - _vVKnots(0,usVCtrlpoints-usVOrder+1), - _vUMults(0,usUCtrlpoints-usUOrder+1), - _vVMults(0,usVCtrlpoints-usVOrder+1) + : _usUOrder(usUOrder) + , _usVOrder(usVOrder) + , _usUCtrlpoints(usUCtrlpoints) + , _usVCtrlpoints(usVCtrlpoints) + , _vCtrlPntsOfSurf(0,usUCtrlpoints-1,0,usVCtrlpoints-1) + , _vUKnots(0,usUCtrlpoints-usUOrder+1) + , _vVKnots(0,usVCtrlpoints-usVOrder+1) + , _vUMults(0,usUCtrlpoints-usUOrder+1) + , _vVMults(0,usVCtrlpoints-usVOrder+1) { - _bGetUVDir = false; - _bSmoothing = false; - _fSmoothInfluence = 0.0f; + _bGetUVDir = false; + _bSmoothing = false; + _fSmoothInfluence = 0.0; } void ParameterCorrection::CalcEigenvectors() @@ -622,594 +565,534 @@ void ParameterCorrection::CalcEigenvectors() bool ParameterCorrection::DoInitialParameterCorrection(double fSizeFactor) { - // falls Richtungen nicht vorgegeben, selber berechnen - if (_bGetUVDir == false) - CalcEigenvectors(); - if (!GetUVParameters(fSizeFactor)) - return false; - if (_bSmoothing) - { - if (!SolveWithSmoothing(_fSmoothInfluence)) - return false; - } - else - { - if (!SolveWithoutSmoothing()) - return false; - } + // falls Richtungen nicht vorgegeben, selber berechnen + if (_bGetUVDir == false) + CalcEigenvectors(); + if (!GetUVParameters(fSizeFactor)) + return false; + if (_bSmoothing) { + if (!SolveWithSmoothing(_fSmoothInfluence)) + return false; + } + else { + if (!SolveWithoutSmoothing()) + return false; + } - return true; + return true; } bool ParameterCorrection::GetUVParameters(double fSizeFactor) { - // Eigenvektoren als neue Basis - Base::Vector3d e[3]; - e[0] = _clU; - e[1] = _clV; - e[2] = _clW; - - //kanonische Basis des R^3 - Base::Vector3d b[3]; - b[0]=Base::Vector3d(1.0,0.0,0.0); b[1]=Base::Vector3d(0.0,1.0,0.0);b[2]=Base::Vector3d(0.0,0.0,1.0); - // Erzeuge ein Rechtssystem aus den orthogonalen Eigenvektoren - if ((e[0]%e[1])*e[2] < 0) - { - Base::Vector3d tmp = e[0]; - e[0] = e[1]; - e[1] = tmp; - } + // Eigenvektoren als neue Basis + Base::Vector3d e[3]; + e[0] = _clU; + e[1] = _clV; + e[2] = _clW; - // Nun erzeuge die transpon. Rotationsmatrix - Wm4::Matrix3d clRotMatTrans; - for (int i=0; i<3; i++) - { - for (int j=0; j<3; j++) - { - clRotMatTrans[i][j] = b[j]*e[i]; + //kanonische Basis des R^3 + Base::Vector3d b[3]; + b[0]=Base::Vector3d(1.0,0.0,0.0); b[1]=Base::Vector3d(0.0,1.0,0.0);b[2]=Base::Vector3d(0.0,0.0,1.0); + // Erzeuge ein Rechtssystem aus den orthogonalen Eigenvektoren + if ((e[0]%e[1])*e[2] < 0) { + Base::Vector3d tmp = e[0]; + e[0] = e[1]; + e[1] = tmp; } - } - std::vector vcProjPts; - Base::BoundBox2D clBBox; - - // Berechne die Koordinaten der transf. Punkte und projiz. diese auf die x,y-Ebene des neuen - // Koordinatensystems - for (int ii=_pvcPoints->Lower(); ii<=_pvcPoints->Upper(); ii++) - { - Wm4::Vector3d clProjPnt = clRotMatTrans * ( Wm4::Vector3d( - (*_pvcPoints)(ii).X(), - (*_pvcPoints)(ii).Y(), - (*_pvcPoints)(ii).Z())); - vcProjPts.push_back(Base::Vector2D(clProjPnt.X(), clProjPnt.Y())); - clBBox.Add(Base::Vector2D(clProjPnt.X(), clProjPnt.Y())); - } - - if ((clBBox.fMaxX == clBBox.fMinX) || (clBBox.fMaxY == clBBox.fMinY)) - return false; - double tx = fSizeFactor*clBBox.fMinX-(fSizeFactor-1.0f)*clBBox.fMaxX; - double ty = fSizeFactor*clBBox.fMinY-(fSizeFactor-1.0f)*clBBox.fMaxY; - double fDeltaX = (2*fSizeFactor-1.0f)*(clBBox.fMaxX - clBBox.fMinX); - double fDeltaY = (2*fSizeFactor-1.0f)*(clBBox.fMaxY - clBBox.fMinY); - - // Berechne die u,v-Parameter mit u,v aus [0,1] - _pvcUVParam->Init(gp_Pnt2d(0.0f, 0.0f)); - int ii=0; - if (clBBox.fMaxX - clBBox.fMinX >= clBBox.fMaxY - clBBox.fMinY) { - for (std::vector::iterator It2=vcProjPts.begin(); It2!=vcProjPts.end(); ++It2) - { - (*_pvcUVParam)(ii) = gp_Pnt2d((It2->fX-tx)/fDeltaX, (It2->fY-ty)/fDeltaY); - ii++; + // Nun erzeuge die transpon. Rotationsmatrix + Wm4::Matrix3d clRotMatTrans; + for (int i=0; i<3; i++) { + for (int j=0; j<3; j++) { + clRotMatTrans[i][j] = b[j]*e[i]; + } } - } - else { - for (std::vector::iterator It2=vcProjPts.begin(); It2!=vcProjPts.end(); ++It2) - { - (*_pvcUVParam)(ii) = gp_Pnt2d((It2->fY-ty)/fDeltaY, (It2->fX-tx)/fDeltaX); - ii++; - } - } - return true; + std::vector vcProjPts; + Base::BoundBox2D clBBox; + + // Berechne die Koordinaten der transf. Punkte und projiz. diese auf die x,y-Ebene des neuen + // Koordinatensystems + for (int ii=_pvcPoints->Lower(); ii<=_pvcPoints->Upper(); ii++) { + Wm4::Vector3d clProjPnt = clRotMatTrans * ( Wm4::Vector3d( + (*_pvcPoints)(ii).X(), + (*_pvcPoints)(ii).Y(), + (*_pvcPoints)(ii).Z())); + vcProjPts.push_back(Base::Vector2D(clProjPnt.X(), clProjPnt.Y())); + clBBox.Add(Base::Vector2D(clProjPnt.X(), clProjPnt.Y())); + } + + if ((clBBox.fMaxX == clBBox.fMinX) || (clBBox.fMaxY == clBBox.fMinY)) + return false; + double tx = fSizeFactor*clBBox.fMinX-(fSizeFactor-1.0)*clBBox.fMaxX; + double ty = fSizeFactor*clBBox.fMinY-(fSizeFactor-1.0)*clBBox.fMaxY; + double fDeltaX = (2*fSizeFactor-1.0)*(clBBox.fMaxX - clBBox.fMinX); + double fDeltaY = (2*fSizeFactor-1.0)*(clBBox.fMaxY - clBBox.fMinY); + + // Berechne die u,v-Parameter mit u,v aus [0,1] + _pvcUVParam->Init(gp_Pnt2d(0.0, 0.0)); + int ii=0; + if (clBBox.fMaxX - clBBox.fMinX >= clBBox.fMaxY - clBBox.fMinY) { + for (std::vector::iterator It2=vcProjPts.begin(); It2!=vcProjPts.end(); ++It2) { + (*_pvcUVParam)(ii) = gp_Pnt2d((It2->fX-tx)/fDeltaX, (It2->fY-ty)/fDeltaY); + ii++; + } + } + else { + for (std::vector::iterator It2=vcProjPts.begin(); It2!=vcProjPts.end(); ++It2) { + (*_pvcUVParam)(ii) = gp_Pnt2d((It2->fY-ty)/fDeltaY, (It2->fX-tx)/fDeltaX); + ii++; + } + } + + return true; } void ParameterCorrection::SetUVW(const Base::Vector3d& clU, const Base::Vector3d& clV, const Base::Vector3d& clW, bool bUseDir) { - _clU = clU; - _clV = clV; - _clW = clW; - _bGetUVDir = bUseDir; + _clU = clU; + _clV = clV; + _clW = clW; + _bGetUVDir = bUseDir; } void ParameterCorrection::GetUVW(Base::Vector3d& clU, Base::Vector3d& clV, Base::Vector3d& clW) const { - clU = _clU; - clV = _clV; - clW = _clW; + clU = _clU; + clV = _clV; + clW = _clW; } Base::Vector3d ParameterCorrection::GetGravityPoint() const { - unsigned long ulSize = _pvcPoints->Length(); - double x=0.0, y=0.0, z=0.0; - for (int i=_pvcPoints->Lower(); i<=_pvcPoints->Upper(); i++) - { - x += (*_pvcPoints)(i).X(); - y += (*_pvcPoints)(i).Y(); - z += (*_pvcPoints)(i).Z(); - } + unsigned long ulSize = _pvcPoints->Length(); + double x=0.0, y=0.0, z=0.0; + for (int i=_pvcPoints->Lower(); i<=_pvcPoints->Upper(); i++) { + x += (*_pvcPoints)(i).X(); + y += (*_pvcPoints)(i).Y(); + z += (*_pvcPoints)(i).Z(); + } - return Base::Vector3d(x/ulSize, y/ulSize, z/ulSize); + return Base::Vector3d(x/ulSize, y/ulSize, z/ulSize); } Handle(Geom_BSplineSurface) ParameterCorrection::CreateSurface(const TColgp_Array1OfPnt& points, - unsigned short usIter, - bool bParaCor, - double fSizeFactor) + unsigned short usIter, + bool bParaCor, + double fSizeFactor) { - if (_pvcPoints != NULL) - { - delete _pvcPoints; - _pvcPoints = NULL; - delete _pvcUVParam; - _pvcUVParam = NULL; - } - _pvcPoints = new TColgp_Array1OfPnt(points.Lower(), points.Upper()); - *_pvcPoints = points; - _pvcUVParam = new TColgp_Array1OfPnt2d(points.Lower(), points.Upper()); + if (_pvcPoints != NULL) { + delete _pvcPoints; + _pvcPoints = NULL; + delete _pvcUVParam; + _pvcUVParam = NULL; + } + _pvcPoints = new TColgp_Array1OfPnt(points.Lower(), points.Upper()); + *_pvcPoints = points; + _pvcUVParam = new TColgp_Array1OfPnt2d(points.Lower(), points.Upper()); - if (_usUCtrlpoints*_usVCtrlpoints > _pvcPoints->Length()) - return NULL; //LGS unterbestimmt - if(!DoInitialParameterCorrection(fSizeFactor)) - return NULL; + if (_usUCtrlpoints*_usVCtrlpoints > _pvcPoints->Length()) + return NULL; //LGS unterbestimmt + if (!DoInitialParameterCorrection(fSizeFactor)) + return NULL; - if (bParaCor) - DoParameterCorrection(usIter); + if (bParaCor) + DoParameterCorrection(usIter); - return new Geom_BSplineSurface - (_vCtrlPntsOfSurf, - _vUKnots, - _vVKnots, - _vUMults, - _vVMults, - _usUOrder-1, - _usVOrder-1); + return new Geom_BSplineSurface(_vCtrlPntsOfSurf, _vUKnots, _vVKnots, + _vUMults, _vVMults, _usUOrder-1, _usVOrder-1); } void ParameterCorrection::EnableSmoothing(bool bSmooth, double fSmoothInfl) { - _bSmoothing = bSmooth; - _fSmoothInfluence = fSmoothInfl; + _bSmoothing = bSmooth; + _fSmoothInfluence = fSmoothInfl; } /////////////////// BSplineParameterCorrection -BSplineParameterCorrection::BSplineParameterCorrection(unsigned short usUOrder, unsigned short usVOrder, - unsigned short usUCtrlpoints, unsigned short usVCtrlpoints) - : ParameterCorrection - (usUOrder, usVOrder, usUCtrlpoints, usVCtrlpoints), - _clUSpline(usUCtrlpoints+usUOrder), - _clVSpline(usVCtrlpoints+usVOrder), - _clSmoothMatrix - (0,usUCtrlpoints*usVCtrlpoints-1, - 0,usUCtrlpoints*usVCtrlpoints-1), - _clFirstMatrix - (0,usUCtrlpoints*usVCtrlpoints-1, - 0,usUCtrlpoints*usVCtrlpoints-1), - _clSecondMatrix - (0,usUCtrlpoints*usVCtrlpoints-1, - 0,usUCtrlpoints*usVCtrlpoints-1), - _clThirdMatrix - (0,usUCtrlpoints*usVCtrlpoints-1, - 0,usUCtrlpoints*usVCtrlpoints-1) +BSplineParameterCorrection::BSplineParameterCorrection(unsigned short usUOrder, unsigned short usVOrder, + unsigned short usUCtrlpoints, unsigned short usVCtrlpoints) + : ParameterCorrection(usUOrder, usVOrder, usUCtrlpoints, usVCtrlpoints) + , _clUSpline(usUCtrlpoints+usUOrder) + , _clVSpline(usVCtrlpoints+usVOrder) + , _clSmoothMatrix(0,usUCtrlpoints*usVCtrlpoints-1, + 0,usUCtrlpoints*usVCtrlpoints-1) + , _clFirstMatrix (0,usUCtrlpoints*usVCtrlpoints-1, + 0,usUCtrlpoints*usVCtrlpoints-1) + , _clSecondMatrix(0,usUCtrlpoints*usVCtrlpoints-1, + 0,usUCtrlpoints*usVCtrlpoints-1) + , _clThirdMatrix (0,usUCtrlpoints*usVCtrlpoints-1, + 0,usUCtrlpoints*usVCtrlpoints-1) { - Init(); + Init(); } void BSplineParameterCorrection::Init() { - // Initialisierungen - _pvcUVParam = NULL; - _pvcPoints = NULL; - _clFirstMatrix.Init(0.0); - _clSecondMatrix.Init(0.0); - _clThirdMatrix.Init(0.0); - _clSmoothMatrix.Init(0.0); - - /* Berechne die Knotenvektoren */ - unsigned short usUMax = _usUCtrlpoints-_usUOrder+1; - unsigned short usVMax = _usVCtrlpoints-_usVOrder+1; + // Initialisierungen + _pvcUVParam = NULL; + _pvcPoints = NULL; + _clFirstMatrix.Init(0.0); + _clSecondMatrix.Init(0.0); + _clThirdMatrix.Init(0.0); + _clSmoothMatrix.Init(0.0); - // Knotenvektor für die CAS.CADE-Klasse - // u-Richtung - for (int i=0;i<=usUMax; i++) - { - _vUKnots(i) = static_cast(i) / static_cast(usUMax); - _vUMults(i) = 1; - } - _vUMults(0) = _usUOrder; - _vUMults(usUMax) = _usUOrder; - // v-Richtung - for (int i=0; i<=usVMax; i++) - { - _vVKnots(i) = static_cast(i) / static_cast(usVMax); - _vVMults(i) = 1; - } - _vVMults(0) = _usVOrder; - _vVMults(usVMax) = _usVOrder; + /* Berechne die Knotenvektoren */ + unsigned short usUMax = _usUCtrlpoints-_usUOrder+1; + unsigned short usVMax = _usVCtrlpoints-_usVOrder+1; - // Setzen der B-Spline-Basisfunktionen - _clUSpline.SetKnots(_vUKnots, _vUMults, _usUOrder); - _clVSpline.SetKnots(_vVKnots, _vVMults, _usVOrder); + // Knotenvektor für die CAS.CADE-Klasse + // u-Richtung + for (int i=0;i<=usUMax; i++) { + _vUKnots(i) = static_cast(i) / static_cast(usUMax); + _vUMults(i) = 1; + } + + _vUMults(0) = _usUOrder; + _vUMults(usUMax) = _usUOrder; + + // v-Richtung + for (int i=0; i<=usVMax; i++) { + _vVKnots(i) = static_cast(i) / static_cast(usVMax); + _vVMults(i) = 1; + } + + _vVMults(0) = _usVOrder; + _vVMults(usVMax) = _usVOrder; + + // Setzen der B-Spline-Basisfunktionen + _clUSpline.SetKnots(_vUKnots, _vUMults, _usUOrder); + _clVSpline.SetKnots(_vVKnots, _vVMults, _usVOrder); } void BSplineParameterCorrection::SetUKnots(const std::vector& afKnots) { - if (afKnots.size() != (unsigned long)(_usUCtrlpoints+_usUOrder)) - return; + if (afKnots.size() != (std::size_t)(_usUCtrlpoints+_usUOrder)) + return; - unsigned short usUMax = _usUCtrlpoints-_usUOrder+1; + unsigned short usUMax = _usUCtrlpoints-_usUOrder+1; - // Knotenvektor für die CAS.CADE-Klasse - // u-Richtung - for (int i=1;i& afKnots) { - if (afKnots.size() != (unsigned long)(_usVCtrlpoints+_usVOrder)) - return; + if (afKnots.size() != (unsigned long)(_usVCtrlpoints+_usVOrder)) + return; - unsigned short usVMax = _usVCtrlpoints-_usVOrder+1; + unsigned short usVMax = _usVCtrlpoints-_usVOrder+1; - // Knotenvektor für die CAS.CADE-Klasse - // v-Richtung - for (int i=1; iLength()); + Base::SequencerLauncher seq("Calc surface...", usIter*_pvcPoints->Length()); - do - { - fMaxScalar = 1.0f; - fMaxDiff = 0.0f; + do { + fMaxScalar = 1.0; + fMaxDiff = 0.0; - Geom_BSplineSurface* pclBSplineSurf = new Geom_BSplineSurface - (_vCtrlPntsOfSurf, - _vUKnots, - _vVKnots, - _vUMults, - _vVMults, - _usUOrder-1, - _usVOrder-1); + Geom_BSplineSurface* pclBSplineSurf = new Geom_BSplineSurface(_vCtrlPntsOfSurf, + _vUKnots, _vVKnots, _vUMults, _vVMults, _usUOrder-1, _usVOrder-1); - for (int ii=_pvcPoints->Lower();ii <=_pvcPoints->Upper();ii++) - { + for (int ii=_pvcPoints->Lower();ii <=_pvcPoints->Upper();ii++) { + double fDeltaU, fDeltaV, fU, fV; + gp_Vec P((*_pvcPoints)(ii).X(), (*_pvcPoints)(ii).Y(), (*_pvcPoints)(ii).Z()); + gp_Pnt PntX; + gp_Vec Xu, Xv, Xuv, Xuu, Xvv; + //Berechne die ersten beiden Ableitungen und Punkt an der Stelle (u,v) + pclBSplineSurf->D2((*_pvcUVParam)(ii).X(), (*_pvcUVParam)(ii).Y(), PntX, Xu, Xv, Xuu, Xvv, Xuv); + gp_Vec X(PntX.X(), PntX.Y(), PntX.Z()); + gp_Vec ErrorVec = X - P; - double fDeltaU, fDeltaV, fU, fV; - gp_Vec P((*_pvcPoints)(ii).X(), (*_pvcPoints)(ii).Y(), (*_pvcPoints)(ii).Z()); - gp_Pnt PntX; - gp_Vec Xu, Xv, Xuv, Xuu, Xvv; - //Berechne die ersten beiden Ableitungen und Punkt an der Stelle (u,v) - pclBSplineSurf->D2((*_pvcUVParam)(ii).X(), (*_pvcUVParam)(ii).Y(), PntX, Xu, Xv, Xuu, Xvv, Xuv); - gp_Vec X(PntX.X(), PntX.Y(), PntX.Z()); - gp_Vec ErrorVec = X - P; + // Berechne Xu x Xv die Normale in X(u,v) + gp_Dir clNormal = Xu ^ Xv; - // Berechne Xu x Xv die Normale in X(u,v) - gp_Dir clNormal = Xu ^ Xv; + //Prüfe, ob X = P + if (!(X.IsEqual(P,0.001,0.001))) { + ErrorVec.Normalize(); + if (fabs(clNormal*ErrorVec) < fMaxScalar) + fMaxScalar = fabs(clNormal*ErrorVec); + } - //Prüfe, ob X = P - if (!(X.IsEqual(P,0.001,0.001))) - { - ErrorVec.Normalize(); - if(fabs(clNormal*ErrorVec) < fMaxScalar) - fMaxScalar = fabs(clNormal*ErrorVec); - } + fDeltaU = ( (P-X) * Xu ) / ( (P-X)*Xuu - Xu*Xu ); + if (fabs(fDeltaU) < FLOAT_EPS) + fDeltaU = 0.0; + fDeltaV = ( (P-X) * Xv ) / ( (P-X)*Xvv - Xv*Xv ); + if (fabs(fDeltaV) < FLOAT_EPS) + fDeltaV = 0.0; - fDeltaU = ( (P-X) * Xu ) / ( (P-X)*Xuu - Xu*Xu ); - if (fabs(fDeltaU) < FLOAT_EPS) - fDeltaU = 0.0f; - fDeltaV = ( (P-X) * Xv ) / ( (P-X)*Xvv - Xv*Xv ); - if (fabs(fDeltaV) < FLOAT_EPS) - fDeltaV = 0.0f; + //Ersetze die alten u/v-Werte durch die neuen + fU = (*_pvcUVParam)(ii).X() - fDeltaU; + fV = (*_pvcUVParam)(ii).Y() - fDeltaV; + if (fU <= 1.0 && fU >= 0.0 && + fV <= 1.0 && fV >= 0.0) { + (*_pvcUVParam)(ii).SetX(fU); + (*_pvcUVParam)(ii).SetY(fV); + fMaxDiff = std::max(fabs(fDeltaU), fMaxDiff); + fMaxDiff = std::max(fabs(fDeltaV), fMaxDiff); + } - //Ersetze die alten u/v-Werte durch die neuen - fU = (*_pvcUVParam)(ii).X() - fDeltaU; - fV = (*_pvcUVParam)(ii).Y() - fDeltaV; - if (fU <= 1.0f && fU >= 0.0f && - fV <= 1.0f && fV >= 0.0f) - { - (*_pvcUVParam)(ii).SetX(fU); - (*_pvcUVParam)(ii).SetY(fV); - fMaxDiff = std::max(fabs(fDeltaU), fMaxDiff); - fMaxDiff = std::max(fabs(fDeltaV), fMaxDiff); - } + seq.next(); + } - seq.next(); + if (_bSmoothing) { + fWeight *= 0.5f; + SolveWithSmoothing(fWeight); + } + else { + SolveWithoutSmoothing(); + } + + i++; } - - if (_bSmoothing) - { - fWeight *= 0.5f; - SolveWithSmoothing(fWeight); - } - else - SolveWithoutSmoothing(); - - i++; - } - while(i FLOAT_EPS && fMaxScalar < 0.99); + while(i FLOAT_EPS && fMaxScalar < 0.99); } bool BSplineParameterCorrection::SolveWithoutSmoothing() { - unsigned long ulSize = _pvcPoints->Length(); - math_Matrix M (0, ulSize-1, 0,_usUCtrlpoints*_usVCtrlpoints-1); - math_Matrix Xx (0, _usUCtrlpoints*_usVCtrlpoints-1,0,0); - math_Matrix Xy (0, _usUCtrlpoints*_usVCtrlpoints-1,0,0); - math_Matrix Xz (0, _usUCtrlpoints*_usVCtrlpoints-1,0,0); - math_Vector bx (0, ulSize-1); - math_Vector by (0, ulSize-1); - math_Vector bz (0, ulSize-1); + unsigned long ulSize = _pvcPoints->Length(); + math_Matrix M (0, ulSize-1, 0,_usUCtrlpoints*_usVCtrlpoints-1); + math_Matrix Xx (0, _usUCtrlpoints*_usVCtrlpoints-1,0,0); + math_Matrix Xy (0, _usUCtrlpoints*_usVCtrlpoints-1,0,0); + math_Matrix Xz (0, _usUCtrlpoints*_usVCtrlpoints-1,0,0); + math_Vector bx (0, ulSize-1); + math_Vector by (0, ulSize-1); + math_Vector bz (0, ulSize-1); + + //Bestimmung der Koeffizientenmatrix des überbestimmten LGS + for (unsigned long i=0; iLower(); ii<=_pvcPoints->Upper(); ii++) { + bx(ii) = (*_pvcPoints)(ii).X(); by(ii) = (*_pvcPoints)(ii).Y(); bz(ii) = (*_pvcPoints)(ii).Z(); + } + + // Löse das überbest. LGS mit der Householder-Transformation + math_Householder hhX(M,bx); + math_Householder hhY(M,by); + math_Householder hhZ(M,bz); + + if (!(hhX.IsDone() && hhY.IsDone() && hhZ.IsDone())) + //LGS konnte nicht gelöst werden + return false; + Xx = hhX.AllValues(); + Xy = hhY.AllValues(); + Xz = hhZ.AllValues(); - //Bestimmung der Koeffizientenmatrix des überbestimmten LGS - for (unsigned long i=0; iLower(); ii<=_pvcPoints->Upper(); ii++) - { - bx(ii) = (*_pvcPoints)(ii).X(); by(ii) = (*_pvcPoints)(ii).Y(); bz(ii) = (*_pvcPoints)(ii).Z(); - } - - // Löse das überbest. LGS mit der Householder-Transformation - math_Householder hhX(M,bx); - math_Householder hhY(M,by); - math_Householder hhZ(M,bz); - - if (!(hhX.IsDone() && hhY.IsDone() && hhZ.IsDone())) - //LGS konnte nicht gelöst werden - return false; - Xx = hhX.AllValues(); - Xy = hhY.AllValues(); - Xz = hhZ.AllValues(); - - unsigned long ulIdx=0; - for (unsigned short j=0;j<_usUCtrlpoints;j++) - { - for (unsigned short k=0;k<_usVCtrlpoints;k++) - { - _vCtrlPntsOfSurf(j,k) = gp_Pnt(Xx(ulIdx,0),Xy(ulIdx,0),Xz(ulIdx,0)); - ulIdx++; - } - } - - return true; + return true; } bool BSplineParameterCorrection::SolveWithSmoothing(double fWeight) { - unsigned long ulSize = _pvcPoints->Length(); - unsigned long ulDim = _usUCtrlpoints*_usVCtrlpoints; - math_Matrix M (0, ulSize-1, 0,_usUCtrlpoints*_usVCtrlpoints-1); - math_Matrix MTM(0, _usUCtrlpoints*_usVCtrlpoints-1, + unsigned long ulSize = _pvcPoints->Length(); + unsigned long ulDim = _usUCtrlpoints*_usVCtrlpoints; + math_Matrix M (0, ulSize-1, 0,_usUCtrlpoints*_usVCtrlpoints-1); + math_Matrix MTM(0, _usUCtrlpoints*_usVCtrlpoints-1, 0, _usUCtrlpoints*_usVCtrlpoints-1); - math_Vector Xx (0, _usUCtrlpoints*_usVCtrlpoints-1); - math_Vector Xy (0, _usUCtrlpoints*_usVCtrlpoints-1); - math_Vector Xz (0, _usUCtrlpoints*_usVCtrlpoints-1); - math_Vector bx (0, ulSize-1); - math_Vector by (0, ulSize-1); - math_Vector bz (0, ulSize-1); - math_Vector Mbx(0, _usUCtrlpoints*_usVCtrlpoints-1); - math_Vector Mby(0, _usUCtrlpoints*_usVCtrlpoints-1); - math_Vector Mbz(0, _usUCtrlpoints*_usVCtrlpoints-1); + math_Vector Xx (0, _usUCtrlpoints*_usVCtrlpoints-1); + math_Vector Xy (0, _usUCtrlpoints*_usVCtrlpoints-1); + math_Vector Xz (0, _usUCtrlpoints*_usVCtrlpoints-1); + math_Vector bx (0, ulSize-1); + math_Vector by (0, ulSize-1); + math_Vector bz (0, ulSize-1); + math_Vector Mbx(0, _usUCtrlpoints*_usVCtrlpoints-1); + math_Vector Mby(0, _usUCtrlpoints*_usVCtrlpoints-1); + math_Vector Mbz(0, _usUCtrlpoints*_usVCtrlpoints-1); + + //Bestimmung der Koeffizientenmatrix des überbestimmten LGS + for (unsigned long i=0; iLower(); ii<=_pvcPoints->Upper(); ii++) { + bx(ii) = (*_pvcPoints)(ii).X(); by(ii) = (*_pvcPoints)(ii).Y(); bz(ii) = (*_pvcPoints)(ii).Z(); + } + for (unsigned long i=0; iLower(); ii<=_pvcPoints->Upper(); ii++) - { - bx(ii) = (*_pvcPoints)(ii).X(); by(ii) = (*_pvcPoints)(ii).Y(); bz(ii) = (*_pvcPoints)(ii).Z(); - } - for (unsigned long i=0; i& afKnots); - virtual ~BSplineParameterCorrection(){}; + /** + * Setzen des Knotenvektors + */ + void SetVKnots(const std::vector& afKnots); + + /** + * Gibt die erste Matrix der Glättungsterme zurück, falls berechnet + */ + virtual const math_Matrix& GetFirstSmoothMatrix() const; + + /** + * Gibt die zweite Matrix der Glättungsterme zurück, falls berechnet + */ + virtual const math_Matrix& GetSecondSmoothMatrix() const; + + /** + * Gibt die dritte Matrix der Glättungsterme zurück, falls berechnet + */ + virtual const math_Matrix& GetThirdSmoothMatrix() const; + + /** + * Setzt die erste Matrix der Glättungsterme + */ + virtual void SetFirstSmoothMatrix(const math_Matrix& rclMat); + + /** + * Setzt die zweite Matrix der Glättungsterme + */ + virtual void SetSecondSmoothMatrix(const math_Matrix& rclMat); + + /** + * Setzt die dritte Matrix der Glättungsterme + */ + virtual void SetThirdSmoothMatrix(const math_Matrix& rclMat); + + /** + * Verwende Glättungsterme + */ + virtual void EnableSmoothing(bool bSmooth=true, double fSmoothInfl=1.0f); + + /** + * Verwende Glättungsterme + */ + virtual void EnableSmoothing(bool bSmooth, double fSmoothInfl, + double fFirst, double fSec, double fThird); protected: - /** - * Initialisierung - */ - virtual void Init(); + /** + * Berechnet die Matrix zu den Glättungstermen + * (siehe Dissertation U.Dietz) + */ + virtual void CalcSmoothingTerms(bool bRecalc, double fFirst, double fSecond, double fThird); - /** - * Führt eine Parameterkorrektur durch. - */ - virtual void DoParameterCorrection(unsigned short usIter); + /** + * Berechnet die Matrix zum ersten Glättungsterm + * (siehe Diss. U.Dietz) + */ + virtual void CalcFirstSmoothMatrix(Base::SequencerLauncher&); - /** - * Löst ein überbestimmtes LGS mit Hilfe der Householder-Transformation - */ - virtual bool SolveWithoutSmoothing(); + /** + * Berechnet die Matrix zum zweiten Glättunsterm + * (siehe Diss. U.Dietz) + */ + virtual void CalcSecondSmoothMatrix(Base::SequencerLauncher&); - /** - * Löst ein reguläres Gleichungssystem durch LU-Zerlegung. Es fließen je nach Gewichtung - * Glättungsterme 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 Glättungsterme zurück, falls berechnet - */ - virtual const math_Matrix& GetFirstSmoothMatrix() const; - - /** - * Gibt die zweite Matrix der Glättungsterme zurück, falls berechnet - */ - virtual const math_Matrix& GetSecondSmoothMatrix() const; - - /** - * Gibt die dritte Matrix der Glättungsterme zurück, falls berechnet - */ - virtual const math_Matrix& GetThirdSmoothMatrix() const; - - /** - * Setzt die erste Matrix der Glättungsterme - */ - virtual void SetFirstSmoothMatrix(const math_Matrix& rclMat); - - /** - * Setzt die zweite Matrix der Glättungsterme - */ - virtual void SetSecondSmoothMatrix(const math_Matrix& rclMat); - - /** - * Setzt die dritte Matrix der Glättungsterme - */ - virtual void SetThirdSmoothMatrix(const math_Matrix& rclMat); - - /** - * Verwende Glättungsterme - */ - virtual void EnableSmoothing(bool bSmooth=true, double fSmoothInfl=1.0f); - - /** - * Verwende Glättungsterme - */ - virtual void EnableSmoothing(bool bSmooth, double fSmoothInfl, - double fFirst, double fSec, double fThird); + /** + * Berechnet die Matrix zum dritten Glättungsterm + */ + virtual void CalcThirdSmoothMatrix(Base::SequencerLauncher&); protected: - /** - * Berechnet die Matrix zu den Glättungstermen - * (siehe Dissertation U.Dietz) - */ - virtual void CalcSmoothingTerms(bool bRecalc, double fFirst, double fSecond, double fThird); - - /** - * Berechnet die Matrix zum ersten Glättungsterm - * (siehe Diss. U.Dietz) - */ - virtual void CalcFirstSmoothMatrix(Base::SequencerLauncher&); - - /** - * Berechnet die Matrix zum zweiten Glättunsterm - * (siehe Diss. U.Dietz) - */ - virtual void CalcSecondSmoothMatrix(Base::SequencerLauncher&); - - /** - * Berechnet die Matrix zum dritten Glättungsterm - */ - 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 Glättungsfunktionale - math_Matrix _clFirstMatrix; //! Matrix der 1. Glättungsfunktionale - math_Matrix _clSecondMatrix; //! Matrix der 2. Glättungsfunktionale - math_Matrix _clThirdMatrix; //! Matrix der 3. Glättungsfunktionale + BSplineBasis _clUSpline; //! B-Spline-Basisfunktion in u-Richtung + BSplineBasis _clVSpline; //! B-Spline-Basisfunktion in v-Richtung + math_Matrix _clSmoothMatrix; //! Matrix der Glättungsfunktionale + math_Matrix _clFirstMatrix; //! Matrix der 1. Glättungsfunktionale + math_Matrix _clSecondMatrix; //! Matrix der 2. Glättungsfunktionale + math_Matrix _clThirdMatrix; //! Matrix der 3. Glättungsfunktionale }; } // namespace Reen