ApproxSurface.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2008 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 #include <math_Gauss.hxx>
00026 #include <math_Householder.hxx>
00027 #include <Geom_BSplineSurface.hxx>
00028 
00029 #include <Mod/Mesh/App/Core/Approximation.h>
00030 #include <Base/Sequencer.h>
00031 #include <Base/Tools2D.h>
00032 
00033 #include "ApproxSurface.h"
00034 
00035 using namespace Reen;
00036 
00037 // SplineBasisfunction
00038 
00039 SplineBasisfunction::SplineBasisfunction(int iSize)
00040 : _vKnotVector(0,iSize-1)
00041 {
00042 }
00043 
00044 SplineBasisfunction::SplineBasisfunction
00045                         (TColStd_Array1OfReal& vKnots, 
00046                          TColStd_Array1OfInteger& vMults, 
00047                          int iSize,
00048                          int iOrder)
00049 : _vKnotVector(0,iSize-1)
00050 {
00051   int sum = 0;
00052   for (int h=vMults.Lower(); h<=vMults.Upper(); h++)
00053     sum += vMults(h);
00054 
00055   if (vKnots.Length() != vMults.Length() || iSize != sum)
00056   {
00057     // Werfe Exception
00058     Standard_ConstructionError::Raise("BSplineBasis");
00059   }
00060 
00061   int k=0;
00062   for (int i=vMults.Lower(); i<=vMults.Upper(); i++)
00063   {
00064     for (int j=0; j<vMults(i); j++)
00065     {
00066       _vKnotVector(k) = vKnots(i);
00067       k++;
00068     }
00069   }
00070 
00071   _iOrder = iOrder;
00072 }
00073 
00074 SplineBasisfunction::SplineBasisfunction(TColStd_Array1OfReal& vKnots, int iOrder)
00075 : _vKnotVector(0,vKnots.Length()-1)
00076 {
00077   _vKnotVector = vKnots;
00078   _iOrder = iOrder;
00079 }
00080 
00081 SplineBasisfunction::~SplineBasisfunction()
00082 {
00083 }
00084 
00085 void SplineBasisfunction::SetKnots(TColStd_Array1OfReal& vKnots, int iOrder)
00086 {
00087   if (_vKnotVector.Length() != vKnots.Length())
00088         Standard_RangeError::Raise("BSplineBasis");
00089 
00090   _vKnotVector = vKnots;
00091   _iOrder = iOrder;
00092 }
00093 
00094 void SplineBasisfunction::SetKnots(TColStd_Array1OfReal& vKnots, TColStd_Array1OfInteger& vMults, 
00095                               int iOrder)
00096 {
00097   int sum = 0;
00098   for (int h=vMults.Lower(); h<=vMults.Upper(); h++)
00099     sum += vMults(h);
00100 
00101   if (vKnots.Length() != vMults.Length() || _vKnotVector.Length() != sum)
00102   {
00103     // Werfe Exception
00104     Standard_RangeError::Raise("BSplineBasis");
00105   }
00106   int k=0;
00107   for (int i=vMults.Lower(); i<=vMults.Upper(); i++)
00108   {
00109     for (int j=0; j<vMults(i); j++)
00110     {
00111       _vKnotVector(k) = vKnots(i);
00112       k++;
00113     }
00114   }
00115 
00116   _iOrder = iOrder;
00117 }
00118 
00120 
00121 BSplineBasis::BSplineBasis(int iSize)
00122 : SplineBasisfunction(iSize)
00123 {
00124 }
00125 
00126 BSplineBasis::BSplineBasis(TColStd_Array1OfReal& vKnots, TColStd_Array1OfInteger& vMults, int iSize, 
00127                              int iOrder)
00128 : SplineBasisfunction(vKnots, vMults, iSize, iOrder)
00129 {
00130 }
00131 
00132 BSplineBasis::BSplineBasis(TColStd_Array1OfReal& vKnots, int iOrder)
00133 : SplineBasisfunction(vKnots, iOrder)
00134 {
00135 }
00136 
00137 BSplineBasis::~BSplineBasis()
00138 {
00139 }
00140 
00141 int BSplineBasis::FindSpan(double fParam)
00142 {
00143   int n = _vKnotVector.Length()-_iOrder-1;
00144   if (fParam == _vKnotVector(n+1))
00145     return n;
00146 
00147   int low = _iOrder-1;
00148   int high = n+1;
00149   int mid = (low+high)/2; //Binärsuche
00150 
00151   while (fParam < _vKnotVector(mid) || fParam>= _vKnotVector(mid+1))
00152   {
00153     if (fParam < _vKnotVector(mid))
00154       high = mid;
00155     else
00156       low = mid;
00157     mid = (low+high)/2;
00158   }
00159 
00160   return mid;
00161 }
00162 
00163 void BSplineBasis::AllBasisFunctions(double fParam, TColStd_Array1OfReal& vFuncVals)
00164 {
00165   if (vFuncVals.Length() != _iOrder)
00166     Standard_RangeError::Raise("BSplineBasis");
00167 
00168   int iIndex = FindSpan(fParam);
00169 
00170   TColStd_Array1OfReal zaehler_left(1,_iOrder-1);
00171   TColStd_Array1OfReal zaehler_right(1,_iOrder-1);
00172   vFuncVals(0) = 1.0f;
00173 
00174   for (int j=1; j<_iOrder; j++)
00175   {
00176     zaehler_left(j)  = fParam - _vKnotVector(iIndex+1-j);
00177     zaehler_right(j) = _vKnotVector(iIndex+j) - fParam;
00178     double saved = 0.0f;
00179     for (int r=0; r<j; r++)
00180     {
00181       double tmp = vFuncVals(r)/(zaehler_right(r+1) + zaehler_left(j-r));
00182       vFuncVals(r) = saved + zaehler_right(r+1)*tmp;
00183       saved = zaehler_left(j-r)*tmp;
00184     }
00185     
00186     vFuncVals(j) = saved;
00187   }
00188 }
00189 
00190 double BSplineBasis::BasisFunction(int iIndex, double fParam)
00191 {
00192   int m = _vKnotVector.Length()-1;
00193   int p = _iOrder-1;
00194   double saved;
00195   TColStd_Array1OfReal N(0,p);
00196 
00197   if ((iIndex == 0 && fParam == _vKnotVector(0)) || 
00198       (iIndex == m-p-1 && fParam == _vKnotVector(m)))
00199   {
00200     return 1.0f;
00201   }
00202 
00203   if (fParam < _vKnotVector(iIndex) || fParam >= _vKnotVector(iIndex+p+1))
00204   {
00205     return 0.0f;
00206   }
00207 
00208   for (int j=0; j<=p; j++)
00209   {
00210     if (fParam >= _vKnotVector(iIndex+j) && fParam < _vKnotVector(iIndex+j+1))
00211       N(j) = 1.0f;
00212     else
00213       N(j) = 0.0f;
00214   }
00215 
00216   for (int k=1; k<=p; k++)
00217   {
00218     if (N(0) == 0.0f)
00219       saved = 0.0f;
00220     else
00221       saved = ((fParam - _vKnotVector(iIndex))*N(0)) / (_vKnotVector(iIndex+k) - _vKnotVector(iIndex));
00222     
00223     for (int j=0; j<p-k+1; j++)
00224     {
00225       double Tleft = _vKnotVector(iIndex+j+1);
00226       double Tright = _vKnotVector(iIndex+j+k+1);
00227      
00228       if (N(j+1) == 0.0)
00229       {
00230         N(j) = saved;
00231         saved = 0.0;
00232       }
00233       else 
00234       {
00235         double tmp = N(j+1)/(Tright-Tleft);
00236         N(j) = saved + (Tright - fParam)*tmp;
00237         saved = (fParam-Tleft)*tmp;
00238       }
00239     }
00240   }
00241 
00242   return N(0);
00243 }
00244 
00245 void BSplineBasis::DerivativesOfBasisFunction(int iIndex, int iMaxDer, double fParam,
00246                                                TColStd_Array1OfReal& Derivat)
00247 {
00248   int iMax = iMaxDer;
00249   if (Derivat.Length() != iMax+1)
00250     Standard_RangeError::Raise("BSplineBasis");
00251   //k-te Ableitungen (k>Grad) sind Null 
00252   if (iMax >= _iOrder)
00253   {
00254    for (int i=_iOrder; i<=iMaxDer; i++)
00255      Derivat(i) = 0.0f;
00256      iMax = _iOrder - 1;
00257   }
00258 
00259   TColStd_Array1OfReal ND(0, iMax);
00260   int p = _iOrder-1;
00261   math_Matrix N(0,p,0,p);
00262   double saved;
00263 
00264   // falls Wert außerhalb Intervall, dann Funktionswert und alle Ableitungen gleich Null
00265   if (fParam < _vKnotVector(iIndex) || fParam >= _vKnotVector(iIndex+p+1))
00266   {
00267     for (int k=0; k<=iMax; k++)
00268       Derivat(k) = 0.0f;
00269     return;
00270   }
00271 
00272   // Berechne die Basisfunktionen der Ordnung 1
00273   for (int j=0; j<_iOrder; j++)
00274   {
00275     if (fParam >= _vKnotVector(iIndex+j) && fParam < _vKnotVector(iIndex+j+1))
00276       N(j,0) = 1.0f;
00277     else 
00278       N(j,0) = 0.0f;
00279   }
00280 
00281   // Berechne Dreieckstabelle der Funktionswerte
00282   for (int k=1; k<_iOrder; k++)
00283   {
00284     if (N(0,k-1) == 0.0f)
00285       saved = 0.0f;
00286     else 
00287       saved = ((fParam - _vKnotVector(iIndex))*N(0,k-1))/(_vKnotVector(iIndex+k)-_vKnotVector(iIndex));
00288     for (int j=0; j<p-k+1; j++)
00289     {
00290       double Tleft = _vKnotVector(iIndex+j+1);
00291       double Tright = _vKnotVector(iIndex+j+k+1);
00292 
00293       if (N(j+1,k-1) == 0.0)
00294       {
00295         N(j,k) = saved;
00296         saved = 0.0f;
00297       }
00298       else
00299       {
00300         double tmp = N(j+1,k-1)/(Tright-Tleft);
00301         N(j,k) = saved + (Tright-fParam)*tmp;
00302         saved = (fParam-Tleft)*tmp;
00303       }
00304     }
00305   }
00306 
00307   // Funktionswert
00308   Derivat(0) = N(0,p);
00309   // Berechne aus der Dreieckstabelle die Ableitungen
00310   for (int k=1; k<=iMax; k++)
00311   {
00312     for (int j=0; j<=k; j++)
00313     {
00314       // Lade (p-k)-te Spalte
00315       ND(j) = N(j,p-k);
00316     }
00317 
00318     for (int jj=1; jj<=k; jj++)
00319     {
00320       if (ND(0) == 0.0f)
00321         saved = 0.0f;
00322       else
00323         saved = ND(0)/(_vKnotVector(iIndex+p-k+jj) - _vKnotVector(iIndex));
00324 
00325       for (int j=0; j<k-jj+1; j++)
00326       {
00327         double Tleft = _vKnotVector(iIndex+j+1);
00328         double Tright = _vKnotVector(iIndex+j+p-k+jj+1);
00329         if (ND(j+1) == 0.0f)
00330         {
00331           ND(j) = (p-k+jj)*saved;
00332           saved = 0.0f;
00333         }
00334         else
00335         {
00336           double tmp = ND(j+1)/(Tright-Tleft);
00337           ND(j) = (p-k+jj)*(saved-tmp);
00338           saved = tmp;
00339         }
00340       }
00341     }
00342 
00343     Derivat(k) = ND(0); //k-te Ableitung
00344   }
00345 
00346   return;
00347 }
00348 
00349 double BSplineBasis::DerivativeOfBasisFunction(int iIndex, int iMaxDer, double fParam)
00350 {
00351   int iMax = iMaxDer;
00352 
00353   // Funktionswert (0-te Ableitung)
00354   if (iMax == 0)
00355     return BasisFunction(iIndex, fParam);
00356 
00357   //k-te Ableitungen (k>Grad) sind Null 
00358   if (iMax >= _iOrder)
00359   {
00360     return 0.0f;
00361   }
00362 
00363   TColStd_Array1OfReal ND(0, iMax);
00364   int p = _iOrder-1;
00365   math_Matrix N(0,p,0,p);
00366   double saved;
00367 
00368   // falls Wert außerhalb Intervall, dann Funktionswert und Ableitungen gleich Null
00369   if (fParam < _vKnotVector(iIndex) || fParam >= _vKnotVector(iIndex+p+1))
00370   {
00371     return 0.0f;
00372   }
00373 
00374   // Berechne die Basisfunktionen der Ordnung 1
00375   for (int j=0; j<_iOrder; j++)
00376   {
00377     if (fParam >= _vKnotVector(iIndex+j) && fParam < _vKnotVector(iIndex+j+1))
00378       N(j,0) = 1.0f;
00379     else 
00380       N(j,0) = 0.0f;
00381   }
00382 
00383   // Berechne Dreieckstabelle der Funktionswerte
00384   for (int k=1; k<_iOrder; k++)
00385   {
00386     if (N(0,k-1) == 0.0f)
00387       saved = 0.0f;
00388     else 
00389       saved = ((fParam - _vKnotVector(iIndex))*N(0,k-1))/(_vKnotVector(iIndex+k)-_vKnotVector(iIndex));
00390     for (int j=0; j<p-k+1; j++)
00391     {
00392       double Tleft = _vKnotVector(iIndex+j+1);
00393       double Tright = _vKnotVector(iIndex+j+k+1);
00394 
00395       if (N(j+1,k-1) == 0.0)
00396       {
00397         N(j,k) = saved;
00398         saved = 0.0f;
00399       }
00400       else
00401       {
00402         double tmp = N(j+1,k-1)/(Tright-Tleft);
00403         N(j,k) = saved + (Tright-fParam)*tmp;
00404         saved = (fParam-Tleft)*tmp;
00405       }
00406     }
00407   }
00408 
00409   // Berechne aus der Dreieckstabelle die Ableitungen
00410   for (int j=0; j<=iMax; j++)
00411   {
00412     // Lade (p-iMax)-te Spalte
00413     ND(j) = N(j,p-iMax);
00414   }
00415 
00416   for (int jj=1; jj<=iMax; jj++)
00417   {
00418     if (ND(0) == 0.0f)
00419       saved = 0.0f;
00420     else
00421       saved = ND(0)/(_vKnotVector(iIndex+p-iMax+jj) - _vKnotVector(iIndex));
00422 
00423     for (int j=0; j<iMax-jj+1; j++)
00424     {
00425       double Tleft = _vKnotVector(iIndex+j+1);
00426       double Tright = _vKnotVector(iIndex+j+p-iMax+jj+1);
00427       if (ND(j+1) == 0.0f)
00428       {
00429         ND(j) = (p-iMax+jj)*saved;
00430         saved = 0.0f;
00431       }
00432       else
00433       {
00434         double tmp = ND(j+1)/(Tright-Tleft);
00435         ND(j) = (p-iMax+jj)*(saved-tmp);
00436         saved = tmp;
00437       }
00438     }
00439   }
00440 
00441   return ND(0); //iMax-te Ableitung
00442 }
00443 
00444 double BSplineBasis::GetIntegralOfProductOfBSplines(int iIdx1, int iIdx2, int iOrd1, int iOrd2)
00445 {
00446   int iMax = CalcSize(iOrd1, iOrd2);
00447   double dIntegral=0.0f;
00448   double fMin, fMax;
00449 
00450   TColStd_Array1OfReal vRoots(0,iMax), vWeights(0,iMax);
00451   GenerateRootsAndWeights(vRoots, vWeights);
00452 
00453   /*Berechne das Integral*/
00454   // Integrationsbereich
00455   int iBegin=0; int iEnd=0;
00456   FindIntegrationArea(iIdx1, iIdx2, iBegin, iEnd);
00457 
00458   for (int j=iBegin; j<iEnd; j++)
00459   {
00460     fMax = _vKnotVector(j+1);
00461     fMin = _vKnotVector(j);
00462 
00463     if (fMax > fMin)
00464     {
00465       for (int i=0; i<=iMax; i++)
00466       {
00467         double fParam = 0.5*(vRoots(i)+1)*(fMax-fMin)+fMin;
00468         dIntegral += 0.5*(fMax-fMin)*vWeights(i) * 
00469           DerivativeOfBasisFunction(iIdx1, iOrd1, fParam) * 
00470           DerivativeOfBasisFunction(iIdx2, iOrd2, fParam);
00471       }
00472     }
00473   }
00474 
00475   return dIntegral;
00476 }
00477 
00478 void BSplineBasis::GenerateRootsAndWeights(TColStd_Array1OfReal& vRoots, TColStd_Array1OfReal& vWeights)
00479 {
00480   int iSize = vRoots.Length();
00481 
00482   //Nullstellen der Legendre-Polynome und die zugeh. Gewichte
00483   if (iSize == 1)
00484   {
00485     vRoots(0) = 0.0f; vWeights(0) = 2.0f;
00486   }
00487   else if (iSize == 2)
00488   {
00489     vRoots(0) = 0.57735f;   vWeights(0) = 1.0f;
00490     vRoots(1) = -vRoots(0); vWeights(1) = vWeights(0);
00491   }
00492   else if (iSize == 4)
00493   {
00494     vRoots(0) = 0.33998f;   vWeights(0) = 0.65214f;
00495     vRoots(1) = 0.86113f;   vWeights(1) = 0.34785f;
00496     vRoots(2) = -vRoots(0); vWeights(2) = vWeights(0);
00497     vRoots(3) = -vRoots(1); vWeights(3) = vWeights(1);
00498   }
00499   else if (iSize == 6)
00500   {
00501     vRoots(0) = 0.23861f;   vWeights(0) = 0.46791f;
00502     vRoots(1) = 0.66120f;   vWeights(1) = 0.36076f;
00503     vRoots(2) = 0.93246f;   vWeights(2) = 0.17132f;
00504     vRoots(3) = -vRoots(0); vWeights(3) = vWeights(0);
00505     vRoots(4) = -vRoots(1); vWeights(4) = vWeights(1);
00506     vRoots(5) = -vRoots(2); vWeights(5) = vWeights(2);
00507   }
00508   else if (iSize == 8)
00509   {
00510     vRoots(0) = 0.18343f;   vWeights(0) = 0.36268f;
00511     vRoots(1) = 0.52553f;   vWeights(1) = 0.31370f;
00512     vRoots(2) = 0.79666f;   vWeights(2) = 0.22238f;
00513     vRoots(3) = 0.96028f;   vWeights(3) = 0.10122f;
00514     vRoots(4) = -vRoots(0); vWeights(4) = vWeights(0);
00515     vRoots(5) = -vRoots(1); vWeights(5) = vWeights(1);
00516     vRoots(6) = -vRoots(2); vWeights(6) = vWeights(2);
00517     vRoots(7) = -vRoots(3); vWeights(7) = vWeights(3);
00518   } 
00519   else if (iSize == 10)
00520   {
00521     vRoots(0) = 0.14887f;   vWeights(0) = 0.29552f;
00522     vRoots(1) = 0.43339f;   vWeights(1) = 0.26926f;
00523     vRoots(2) = 0.67940f;   vWeights(2) = 0.21908f;
00524     vRoots(3) = 0.86506f;   vWeights(3) = 0.14945f;
00525     vRoots(4) = 0.97390f;   vWeights(4) = 0.06667f;
00526     vRoots(5) = -vRoots(0); vWeights(5) = vWeights(0);
00527     vRoots(6) = -vRoots(1); vWeights(6) = vWeights(1);
00528     vRoots(7) = -vRoots(2); vWeights(7) = vWeights(2);
00529     vRoots(8) = -vRoots(3); vWeights(8) = vWeights(3);
00530     vRoots(9) = -vRoots(4); vWeights(9) = vWeights(4);
00531   }
00532   else
00533   {
00534     vRoots(0) = 0.12523f;   vWeights(0) = 0.24914f;
00535     vRoots(1) = 0.36783f;   vWeights(1) = 0.23349f;
00536     vRoots(2) = 0.58731f;   vWeights(2) = 0.20316f;
00537     vRoots(3) = 0.76990f;   vWeights(3) = 0.16007f;
00538     vRoots(4) = 0.90411f;   vWeights(4) = 0.10693f;
00539     vRoots(5) = 0.98156f;   vWeights(5) = 0.04717f;
00540     vRoots(6) = -vRoots(0); vWeights(6) = vWeights(0);
00541     vRoots(7) = -vRoots(1); vWeights(7) = vWeights(1);
00542     vRoots(8) = -vRoots(2); vWeights(8) = vWeights(2);
00543     vRoots(9) = -vRoots(3); vWeights(9) = vWeights(3);
00544     vRoots(10)= -vRoots(4); vWeights(10)= vWeights(4);
00545     vRoots(11)= -vRoots(5); vWeights(11)= vWeights(5);
00546   }
00547 }
00548 
00549 void BSplineBasis::FindIntegrationArea(int iIdx1, int iIdx2, int& iBegin, int& iEnd)
00550 {
00551   // nach Index ordnen
00552   if (iIdx2 < iIdx1)
00553   {
00554     int tmp=iIdx1;
00555     iIdx1 = iIdx2;
00556     iIdx2 = tmp;
00557   }
00558 
00559   iBegin = iIdx2;
00560   iEnd   = iIdx1+_iOrder;
00561   if (iEnd == _vKnotVector.Upper())
00562     iEnd -= 1;
00563 }
00564 
00565 int BSplineBasis::CalcSize(int r, int s)
00566 {
00567   int iMaxDegree = 2*(_iOrder-1)-r-s;
00568 
00569   if (iMaxDegree < 0)
00570     return 0;
00571   else if (iMaxDegree < 4)
00572     return 1;
00573   else if (iMaxDegree < 8)
00574     return 3;
00575   else if (iMaxDegree < 12)
00576     return 5;
00577   else if (iMaxDegree < 16)
00578     return 7;
00579   else if (iMaxDegree < 20)
00580     return 9;
00581   else
00582     return 11;
00583 }
00584 
00586 
00587 ParameterCorrection::ParameterCorrection(unsigned short usUOrder, unsigned short usVOrder, 
00588                              unsigned short usUCtrlpoints, unsigned short usVCtrlpoints)
00589     : _usUOrder(usUOrder),
00590       _usVOrder(usVOrder),
00591       _usUCtrlpoints(usUCtrlpoints),
00592       _usVCtrlpoints(usVCtrlpoints),
00593       _vCtrlPntsOfSurf(0,usUCtrlpoints-1,0,usVCtrlpoints-1),
00594       _vUKnots(0,usUCtrlpoints-usUOrder+1),
00595       _vVKnots(0,usVCtrlpoints-usVOrder+1),
00596       _vUMults(0,usUCtrlpoints-usUOrder+1),
00597       _vVMults(0,usVCtrlpoints-usVOrder+1)
00598 {
00599   _bGetUVDir = false;
00600   _bSmoothing = false;
00601   _fSmoothInfluence = 0.0f;
00602 }
00603 
00604 void ParameterCorrection::CalcEigenvectors()
00605 {
00606     MeshCore::PlaneFit planeFit;
00607     //for (it = aclPoints.begin(); it!=aclPoints.end(); ++it)
00608     //    planeFit.AddPoint(*it);
00609     for (int i=_pvcPoints->Lower(); i<=_pvcPoints->Upper(); i++) {
00610         planeFit.AddPoint(Base::Vector3f(
00611             (float)(*_pvcPoints)(i).X(),
00612             (float)(*_pvcPoints)(i).Y(),
00613             (float)(*_pvcPoints)(i).Z()));
00614     }
00615 
00616 
00617     planeFit.Fit();
00618     _clU = planeFit.GetDirU();
00619     _clV = planeFit.GetDirV();
00620     _clW = planeFit.GetNormal();
00621 }
00622 
00623 bool ParameterCorrection::DoInitialParameterCorrection(float fSizeFactor)
00624 {
00625   // falls Richtungen nicht vorgegeben, selber berechnen
00626   if (_bGetUVDir == false)
00627     CalcEigenvectors();
00628   if (!GetUVParameters(fSizeFactor))
00629     return false;
00630   if (_bSmoothing)
00631   {
00632     if (!SolveWithSmoothing(_fSmoothInfluence))
00633       return false;
00634   }
00635   else
00636   {
00637     if (!SolveWithoutSmoothing())
00638       return false;
00639   }
00640 
00641   return true;
00642 }
00643 
00644 bool ParameterCorrection::GetUVParameters(float fSizeFactor)
00645 {
00646   // Eigenvektoren als neue Basis
00647   Base::Vector3f e[3];
00648   e[0] = _clU;
00649   e[1] = _clV;
00650   e[2] = _clW;
00651   
00652   //kanonische Basis des R^3
00653   Base::Vector3f b[3];
00654   b[0]=Base::Vector3f(1.0f,0.0f,0.0f); b[1]=Base::Vector3f(0.0f,1.0f,0.0f);b[2]=Base::Vector3f(0.0f,0.0f,1.0f);
00655   // Erzeuge ein Rechtssystem aus den orthogonalen Eigenvektoren
00656   if ((e[0]%e[1])*e[2] < 0)
00657   {
00658     Base::Vector3f tmp = e[0];
00659     e[0] = e[1];
00660     e[1] = tmp;
00661   }
00662 
00663   // Nun erzeuge die transpon. Rotationsmatrix
00664   Wm4::Matrix3f clRotMatTrans;
00665   for (int i=0; i<3; i++)
00666   {
00667     for (int j=0; j<3; j++)
00668     {
00669       clRotMatTrans[i][j] = b[j]*e[i];
00670     }
00671   }
00672 
00673   std::vector<Base::Vector2D> vcProjPts;
00674   Base::BoundBox2D clBBox;
00675 
00676   // Berechne die Koordinaten der transf. Punkte und projiz. diese auf die x,y-Ebene des neuen
00677   // Koordinatensystems
00678   for (int ii=_pvcPoints->Lower(); ii<=_pvcPoints->Upper(); ii++)
00679   {
00680       Wm4::Vector3f clProjPnt = clRotMatTrans * ( Wm4::Vector3f(
00681           (float)(*_pvcPoints)(ii).X(),
00682           (float)(*_pvcPoints)(ii).Y(),
00683           (float)(*_pvcPoints)(ii).Z()));
00684       vcProjPts.push_back(Base::Vector2D(clProjPnt.X(), clProjPnt.Y()));
00685     clBBox &= (Base::Vector2D(clProjPnt.X(), clProjPnt.Y()));
00686   }
00687 
00688   if ((clBBox.fMaxX == clBBox.fMinX) || (clBBox.fMaxY == clBBox.fMinY))
00689     return false;
00690   float tx = fSizeFactor*clBBox.fMinX-(fSizeFactor-1.0f)*clBBox.fMaxX;
00691   float ty = fSizeFactor*clBBox.fMinY-(fSizeFactor-1.0f)*clBBox.fMaxY;
00692   float fDeltaX = (2*fSizeFactor-1.0f)*(clBBox.fMaxX - clBBox.fMinX);
00693   float fDeltaY = (2*fSizeFactor-1.0f)*(clBBox.fMaxY - clBBox.fMinY);
00694 
00695   // Berechne die u,v-Parameter mit u,v aus [0,1]
00696   _pvcUVParam->Init(gp_Pnt2d(0.0f, 0.0f));
00697   int ii=0;
00698   if (clBBox.fMaxX - clBBox.fMinX >= clBBox.fMaxY - clBBox.fMinY)
00699       for (std::vector<Base::Vector2D>::iterator It2=vcProjPts.begin(); It2!=vcProjPts.end(); It2++)
00700     {
00701       (*_pvcUVParam)(ii) = gp_Pnt2d((It2->fX-tx)/fDeltaX, (It2->fY-ty)/fDeltaY);
00702       ii++;
00703     }
00704   else
00705       for (std::vector<Base::Vector2D>::iterator It2=vcProjPts.begin(); It2!=vcProjPts.end(); It2++)
00706     {
00707       (*_pvcUVParam)(ii) = gp_Pnt2d((It2->fY-ty)/fDeltaY, (It2->fX-tx)/fDeltaX);
00708       ii++;
00709     }
00710 
00711   return true;
00712 }
00713 
00714 void ParameterCorrection::SetUVW(const Base::Vector3f& clU, const Base::Vector3f& clV, const Base::Vector3f& clW, bool bUseDir)
00715 {
00716   _clU = clU;
00717   _clV = clV;
00718   _clW = clW;
00719   _bGetUVDir = bUseDir;
00720 }
00721 
00722 void ParameterCorrection::GetUVW(Base::Vector3f& clU, Base::Vector3f& clV, Base::Vector3f& clW) const
00723 {
00724   clU = _clU;
00725   clV = _clV;
00726   clW = _clW;
00727 }
00728 
00729 Base::Vector3f ParameterCorrection::GetGravityPoint() const
00730 {
00731   unsigned long ulSize = _pvcPoints->Length();
00732   float x=0.0f, y=0.0f, z=0.0f;
00733   for (int i=_pvcPoints->Lower(); i<=_pvcPoints->Upper(); i++)
00734   {
00735     x += (float)(*_pvcPoints)(i).X();
00736     y += (float)(*_pvcPoints)(i).Y();
00737     z += (float)(*_pvcPoints)(i).Z();
00738   }
00739 
00740   return Base::Vector3f(float(x/ulSize), float(y/ulSize), float(z/ulSize));
00741 }
00742 
00743 Handle(Geom_BSplineSurface) ParameterCorrection::CreateSurface(const TColgp_Array1OfPnt& points, 
00744                                                                 unsigned short usIter,
00745                                                                 bool  bParaCor,
00746                                                                 float fSizeFactor)
00747 {
00748   if (_pvcPoints != NULL)
00749   {
00750     delete _pvcPoints;
00751     _pvcPoints = NULL;
00752     delete _pvcUVParam;
00753     _pvcUVParam = NULL;
00754   }
00755   _pvcPoints = new TColgp_Array1OfPnt(points.Lower(), points.Upper());
00756   *_pvcPoints = points;
00757   _pvcUVParam = new TColgp_Array1OfPnt2d(points.Lower(), points.Upper());
00758 
00759   if (_usUCtrlpoints*_usVCtrlpoints > _pvcPoints->Length())
00760     return NULL; //LGS unterbestimmt
00761   if(!DoInitialParameterCorrection(fSizeFactor))
00762     return NULL;
00763 
00764   if (bParaCor)
00765     DoParameterCorrection(usIter);
00766 
00767   return new Geom_BSplineSurface
00768                       (_vCtrlPntsOfSurf,
00769                        _vUKnots, 
00770                        _vVKnots,
00771                        _vUMults,
00772                        _vVMults,
00773                        _usUOrder-1,
00774                        _usVOrder-1);
00775 }
00776 
00777 void ParameterCorrection::EnableSmoothing(bool bSmooth, float fSmoothInfl)
00778 {
00779   _bSmoothing = bSmooth;
00780   _fSmoothInfluence = fSmoothInfl;
00781 }
00782 
00784 
00785 
00786 BSplineParameterCorrection::BSplineParameterCorrection(unsigned short usUOrder, unsigned short usVOrder, 
00787                              unsigned short usUCtrlpoints, unsigned short usVCtrlpoints)
00788     : ParameterCorrection
00789         (usUOrder, usVOrder, usUCtrlpoints, usVCtrlpoints),
00790       _clUSpline(usUCtrlpoints+usUOrder),
00791       _clVSpline(usVCtrlpoints+usVOrder),
00792       _clSmoothMatrix
00793           (0,usUCtrlpoints*usVCtrlpoints-1,
00794            0,usUCtrlpoints*usVCtrlpoints-1),
00795       _clFirstMatrix
00796           (0,usUCtrlpoints*usVCtrlpoints-1,
00797            0,usUCtrlpoints*usVCtrlpoints-1),
00798       _clSecondMatrix
00799           (0,usUCtrlpoints*usVCtrlpoints-1,
00800            0,usUCtrlpoints*usVCtrlpoints-1),
00801       _clThirdMatrix
00802           (0,usUCtrlpoints*usVCtrlpoints-1,
00803            0,usUCtrlpoints*usVCtrlpoints-1)
00804 {
00805   Init();
00806 }
00807 
00808 void BSplineParameterCorrection::Init()
00809 {
00810   // Initialisierungen
00811   _pvcUVParam       = NULL;
00812   _pvcPoints        = NULL;
00813   _clFirstMatrix.Init(0.0f);
00814   _clSecondMatrix.Init(0.0f);
00815   _clThirdMatrix.Init(0.0f);
00816   _clSmoothMatrix.Init(0.0f);
00817   
00818   /* Berechne die Knotenvektoren */
00819   unsigned short usUMax = _usUCtrlpoints-_usUOrder+1;
00820   unsigned short usVMax = _usVCtrlpoints-_usVOrder+1;
00821 
00822   // Knotenvektor für die CAS.CADE-Klasse
00823   // u-Richtung
00824   for (int i=0;i<=usUMax; i++)
00825   {
00826     _vUKnots(i) = ((float)i) / ((float)usUMax);
00827     _vUMults(i) = 1;
00828   }
00829   _vUMults(0) = _usUOrder;
00830   _vUMults(usUMax) = _usUOrder;
00831   // v-Richtung
00832   for (int i=0; i<=usVMax; i++)
00833   {
00834     _vVKnots(i) = ((float)i) / ((float)usVMax);
00835     _vVMults(i) = 1;
00836   }
00837   _vVMults(0) = _usVOrder;
00838   _vVMults(usVMax) = _usVOrder;
00839 
00840   // Setzen der B-Spline-Basisfunktionen
00841   _clUSpline.SetKnots(_vUKnots, _vUMults, _usUOrder);
00842   _clVSpline.SetKnots(_vVKnots, _vVMults, _usVOrder);
00843 }
00844 
00845 void BSplineParameterCorrection::SetUKnots(const std::vector<float>& afKnots)
00846 {
00847   if (afKnots.size() != (unsigned long)(_usUCtrlpoints+_usUOrder))
00848     return;
00849 
00850   unsigned short usUMax = _usUCtrlpoints-_usUOrder+1;
00851 
00852   // Knotenvektor für die CAS.CADE-Klasse
00853   // u-Richtung
00854   for (int i=1;i<usUMax; i++)
00855   {
00856     _vUKnots(i) = afKnots[_usUOrder+i-1];
00857     _vUMults(i) = 1;
00858   }
00859 
00860   // Setzen der B-Spline-Basisfunktionen
00861   _clUSpline.SetKnots(_vUKnots, _vUMults, _usUOrder);
00862 }
00863 
00864 void BSplineParameterCorrection::SetVKnots(const std::vector<float>& afKnots)
00865 {
00866   if (afKnots.size() != (unsigned long)(_usVCtrlpoints+_usVOrder))
00867     return;
00868 
00869   unsigned short usVMax = _usVCtrlpoints-_usVOrder+1;
00870 
00871   // Knotenvektor für die CAS.CADE-Klasse
00872   // v-Richtung
00873   for (int i=1; i<usVMax; i++)
00874   {
00875     _vVKnots(i) = afKnots[_usVOrder+i-1];
00876     _vVMults(i) = 1;
00877   }
00878 
00879   // Setzen der B-Spline-Basisfunktionen
00880   _clVSpline.SetKnots(_vVKnots, _vVMults, _usVOrder);
00881 }
00882 
00883 void BSplineParameterCorrection::DoParameterCorrection(unsigned short usIter)
00884 {
00885   int i=0;
00886   float fMaxDiff=0.0f, fMaxScalar=1.0f;
00887   float fWeight = _fSmoothInfluence;
00888 
00889   Base::SequencerLauncher seq("Calc surface...", usIter*_pvcPoints->Length());
00890 
00891   do
00892   {
00893     fMaxScalar = 1.0f;
00894     fMaxDiff   = 0.0f;
00895 
00896     Geom_BSplineSurface* pclBSplineSurf = new Geom_BSplineSurface
00897                         (_vCtrlPntsOfSurf,
00898                          _vUKnots, 
00899                          _vVKnots,
00900                          _vUMults,
00901                          _vVMults,
00902                          _usUOrder-1,
00903                          _usVOrder-1);
00904 
00905     for (int ii=_pvcPoints->Lower();ii <=_pvcPoints->Upper();ii++)
00906     {  
00907 
00908       double fDeltaU, fDeltaV, fU, fV;
00909       gp_Vec P((*_pvcPoints)(ii).X(), (*_pvcPoints)(ii).Y(), (*_pvcPoints)(ii).Z());
00910       gp_Pnt PntX;
00911       gp_Vec Xu, Xv, Xuv, Xuu, Xvv;
00912       //Berechne die ersten beiden Ableitungen und Punkt an der Stelle (u,v)
00913       pclBSplineSurf->D2((*_pvcUVParam)(ii).X(), (*_pvcUVParam)(ii).Y(), PntX, Xu, Xv, Xuu, Xvv, Xuv);
00914       gp_Vec X(PntX.X(), PntX.Y(), PntX.Z());
00915       gp_Vec ErrorVec = X - P;
00916 
00917       // Berechne Xu x Xv die Normale in X(u,v)
00918       gp_Dir clNormal = Xu ^ Xv;
00919 
00920       //Prüfe, ob X = P
00921       if (!(X.IsEqual(P,0.001,0.001)))
00922       {
00923         ErrorVec.Normalize();
00924         if(fabs(clNormal*ErrorVec) < fMaxScalar)
00925           fMaxScalar = (float)fabs(clNormal*ErrorVec);
00926       }
00927 
00928       fDeltaU =  ( (P-X) * Xu ) / ( (P-X)*Xuu - Xu*Xu );
00929       if (fabs(fDeltaU) < FLOAT_EPS)
00930         fDeltaU = 0.0f;
00931       fDeltaV =  ( (P-X) * Xv ) / ( (P-X)*Xvv - Xv*Xv );
00932       if (fabs(fDeltaV) < FLOAT_EPS)
00933         fDeltaV = 0.0f;
00934 
00935       //Ersetze die alten u/v-Werte durch die neuen
00936       fU = (*_pvcUVParam)(ii).X() - fDeltaU;
00937       fV = (*_pvcUVParam)(ii).Y() - fDeltaV;
00938       if (fU <= 1.0f && fU >= 0.0f &&
00939           fV <= 1.0f && fV >= 0.0f)
00940       {
00941         (*_pvcUVParam)(ii).SetX(fU);
00942         (*_pvcUVParam)(ii).SetY(fV);
00943         fMaxDiff = std::max<float>(float(fabs(fDeltaU)), fMaxDiff);
00944         fMaxDiff = std::max<float>(float(fabs(fDeltaV)), fMaxDiff);
00945       }
00946 
00947       seq.next();
00948     }
00949 
00950     if (_bSmoothing)
00951     {
00952       fWeight *= 0.5f;
00953       SolveWithSmoothing(fWeight);
00954     }
00955     else
00956       SolveWithoutSmoothing();
00957 
00958     i++;
00959   }
00960   while(i<usIter && fMaxDiff > FLOAT_EPS && fMaxScalar < 0.99);
00961 }
00962 
00963 bool BSplineParameterCorrection::SolveWithoutSmoothing()
00964 {
00965   unsigned long ulSize = _pvcPoints->Length();
00966   math_Matrix M  (0, ulSize-1, 0,_usUCtrlpoints*_usVCtrlpoints-1);
00967   math_Matrix Xx (0, _usUCtrlpoints*_usVCtrlpoints-1,0,0);
00968   math_Matrix Xy (0, _usUCtrlpoints*_usVCtrlpoints-1,0,0);
00969   math_Matrix Xz (0, _usUCtrlpoints*_usVCtrlpoints-1,0,0);
00970   math_Vector bx (0, ulSize-1);
00971   math_Vector by (0, ulSize-1);
00972   math_Vector bz (0, ulSize-1);
00973 
00974   //Bestimmung der Koeffizientenmatrix des überbestimmten LGS
00975   for (unsigned long i=0; i<ulSize; i++)
00976   {
00977     float fU = (float)(*_pvcUVParam)(i).X();
00978     float fV = (float)(*_pvcUVParam)(i).Y();
00979     unsigned long ulIdx=0;
00980 
00981     for (unsigned short j=0; j<_usUCtrlpoints; j++)
00982     {
00983       for (unsigned short k=0; k<_usVCtrlpoints; k++)
00984       {
00985         M(i,ulIdx) = _clUSpline.BasisFunction(j,fU)*_clVSpline.BasisFunction(k,fV);
00986         ulIdx++;
00987       }
00988     }
00989   }
00990 
00991   //Bestimmen der rechten Seite
00992   for (int ii=_pvcPoints->Lower(); ii<=_pvcPoints->Upper(); ii++)
00993   {
00994     bx(ii) = (*_pvcPoints)(ii).X(); by(ii) = (*_pvcPoints)(ii).Y(); bz(ii) = (*_pvcPoints)(ii).Z();
00995   }
00996 
00997   // Löse das überbest. LGS mit der Householder-Transformation
00998   math_Householder hhX(M,bx);
00999   math_Householder hhY(M,by);
01000   math_Householder hhZ(M,bz);
01001 
01002   if (!(hhX.IsDone() && hhY.IsDone() && hhZ.IsDone()))
01003     //LGS konnte nicht gelöst werden
01004     return false;
01005   Xx = hhX.AllValues();
01006   Xy = hhY.AllValues();
01007   Xz = hhZ.AllValues();
01008 
01009   unsigned long ulIdx=0;
01010   for (unsigned short j=0;j<_usUCtrlpoints;j++)
01011   {
01012     for (unsigned short k=0;k<_usVCtrlpoints;k++)
01013     {
01014       _vCtrlPntsOfSurf(j,k) = gp_Pnt(Xx(ulIdx,0),Xy(ulIdx,0),Xz(ulIdx,0));
01015       ulIdx++;
01016     }
01017   }
01018 
01019   return true;
01020 }
01021 
01022 bool BSplineParameterCorrection::SolveWithSmoothing(float fWeight)
01023 {
01024   unsigned long ulSize = _pvcPoints->Length();
01025   unsigned long ulDim  = _usUCtrlpoints*_usVCtrlpoints;
01026   math_Matrix M  (0, ulSize-1, 0,_usUCtrlpoints*_usVCtrlpoints-1);
01027   math_Matrix MTM(0, _usUCtrlpoints*_usVCtrlpoints-1, 
01028                   0, _usUCtrlpoints*_usVCtrlpoints-1);
01029   math_Vector Xx (0, _usUCtrlpoints*_usVCtrlpoints-1);
01030   math_Vector Xy (0, _usUCtrlpoints*_usVCtrlpoints-1);
01031   math_Vector Xz (0, _usUCtrlpoints*_usVCtrlpoints-1);
01032   math_Vector bx (0, ulSize-1);
01033   math_Vector by (0, ulSize-1);
01034   math_Vector bz (0, ulSize-1);
01035   math_Vector Mbx(0, _usUCtrlpoints*_usVCtrlpoints-1);
01036   math_Vector Mby(0, _usUCtrlpoints*_usVCtrlpoints-1);
01037   math_Vector Mbz(0, _usUCtrlpoints*_usVCtrlpoints-1);
01038 
01039   //Bestimmung der Koeffizientenmatrix des überbestimmten LGS
01040   for (unsigned long i=0; i<ulSize; i++)
01041   {
01042     float fU = (float)(*_pvcUVParam)(i).X();
01043     float fV = (float)(*_pvcUVParam)(i).Y();
01044     unsigned long ulIdx=0;
01045 
01046     for (unsigned short j=0; j<_usUCtrlpoints; j++)
01047     {
01048       for (unsigned short k=0; k<_usVCtrlpoints; k++)
01049       {
01050         M(i,ulIdx) = _clUSpline.BasisFunction(j,fU)*_clVSpline.BasisFunction(k,fV);
01051         ulIdx++;
01052       }
01053     }
01054   }
01055   //Das Produkt aus ihrer Transformierten und ihr selbst ergibt die quadratische Systemmatrix
01056   for (unsigned long m=0; m<ulDim; m++)
01057   {
01058     for (unsigned long n=m; n<ulDim; n++)
01059     {
01060       MTM(m,n)=MTM(n,m)=M.Col(m)*M.Col(n);
01061     }
01062   }
01063 
01064   //Bestimmen der rechten Seite
01065   for (int ii=_pvcPoints->Lower(); ii<=_pvcPoints->Upper(); ii++)
01066   {
01067     bx(ii) = (*_pvcPoints)(ii).X(); by(ii) = (*_pvcPoints)(ii).Y(); bz(ii) = (*_pvcPoints)(ii).Z();
01068   }
01069   for (unsigned long i=0; i<ulDim; i++)
01070   {
01071     Mbx(i) = M.Col(i) * bx;
01072     Mby(i) = M.Col(i) * by;
01073     Mbz(i) = M.Col(i) * bz;
01074   }
01075 
01076   // Löse das LGS mit der LU-Zerlegung
01077   math_Gauss mgGaussX(MTM+fWeight*_clSmoothMatrix);
01078   math_Gauss mgGaussY(MTM+fWeight*_clSmoothMatrix);
01079   math_Gauss mgGaussZ(MTM+fWeight*_clSmoothMatrix);
01080 
01081   mgGaussX.Solve(Mbx,Xx);
01082   if (!mgGaussX.IsDone())
01083     return false;
01084 
01085   mgGaussY.Solve(Mby,Xy);
01086   if (!mgGaussY.IsDone())
01087     return false;
01088 
01089   mgGaussZ.Solve(Mbz,Xz);
01090   if (!mgGaussZ.IsDone())
01091     return false;
01092 
01093   unsigned long ulIdx=0;
01094   for (unsigned short j=0;j<_usUCtrlpoints;j++)
01095   {
01096     for (unsigned short k=0;k<_usVCtrlpoints;k++)
01097     {
01098       _vCtrlPntsOfSurf(j,k) = gp_Pnt(Xx(ulIdx),Xy(ulIdx),Xz(ulIdx));
01099       ulIdx++;
01100     }
01101   }
01102 
01103   return true;
01104 }
01105 
01106 void BSplineParameterCorrection::CalcSmoothingTerms(bool bRecalc, float fFirst, float fSecond, float fThird)
01107 {
01108   if (bRecalc)
01109   {
01110     Base::SequencerLauncher seq("Initializing...", 3 * _usUCtrlpoints * _usUCtrlpoints * _usVCtrlpoints * _usVCtrlpoints);
01111     CalcFirstSmoothMatrix(seq);
01112     CalcSecondSmoothMatrix(seq);
01113     CalcThirdSmoothMatrix(seq);
01114   }
01115 
01116   _clSmoothMatrix = fFirst  * _clFirstMatrix  + 
01117                     fSecond * _clSecondMatrix +
01118                     fThird  * _clThirdMatrix  ;
01119 }
01120 
01121 void BSplineParameterCorrection::CalcFirstSmoothMatrix(Base::SequencerLauncher& seq)
01122 {
01123   unsigned long m=0;
01124   for (unsigned long k=0; k<_usUCtrlpoints; k++)
01125   {
01126     for (unsigned long l=0; l<_usVCtrlpoints; l++)
01127     {
01128       unsigned long n=0;
01129 
01130       for (unsigned short i=0; i<_usUCtrlpoints; i++)
01131       {
01132         for (unsigned short j=0; j<_usVCtrlpoints; j++)
01133         {
01134           _clFirstMatrix(m,n) =   _clUSpline.GetIntegralOfProductOfBSplines(i,k,1,1) *
01135                                   _clVSpline.GetIntegralOfProductOfBSplines(j,l,0,0) +
01136                                   _clUSpline.GetIntegralOfProductOfBSplines(i,k,0,0) *
01137                                   _clVSpline.GetIntegralOfProductOfBSplines(j,l,1,1);
01138           seq.next();
01139           n++;
01140         }
01141       }
01142       m++;
01143     }
01144   }
01145 }
01146 
01147 void BSplineParameterCorrection::CalcSecondSmoothMatrix(Base::SequencerLauncher& seq)
01148 {
01149   unsigned long m=0;
01150   for (unsigned long k=0; k<_usUCtrlpoints; k++)
01151   {
01152     for (unsigned long l=0; l<_usVCtrlpoints; l++)
01153     {
01154       unsigned long n=0;
01155 
01156       for (unsigned short i=0; i<_usUCtrlpoints; i++)
01157       {
01158         for (unsigned short j=0; j<_usVCtrlpoints; j++)
01159         {
01160           _clSecondMatrix(m,n) =  _clUSpline.GetIntegralOfProductOfBSplines(i,k,2,2) *
01161                                   _clVSpline.GetIntegralOfProductOfBSplines(j,l,0,0) +
01162                                 2*_clUSpline.GetIntegralOfProductOfBSplines(i,k,1,1) *
01163                                   _clVSpline.GetIntegralOfProductOfBSplines(j,l,1,1) +
01164                                   _clUSpline.GetIntegralOfProductOfBSplines(i,k,0,0) *
01165                                   _clVSpline.GetIntegralOfProductOfBSplines(j,l,2,2);
01166           seq.next();
01167           n++;
01168         }
01169       }
01170       m++;
01171     }
01172   }
01173 }
01174 
01175 void BSplineParameterCorrection::CalcThirdSmoothMatrix(Base::SequencerLauncher& seq)
01176 {
01177   unsigned long m=0;
01178   for (unsigned long k=0; k<_usUCtrlpoints; k++)
01179   {
01180     for (unsigned long l=0; l<_usVCtrlpoints; l++)
01181     {
01182       unsigned long n=0;
01183 
01184       for (unsigned short i=0; i<_usUCtrlpoints; i++)
01185       {
01186         for (unsigned short j=0; j<_usVCtrlpoints; j++)
01187         {
01188           _clThirdMatrix(m,n) = _clUSpline.GetIntegralOfProductOfBSplines(i,k,3,3) *
01189                                 _clVSpline.GetIntegralOfProductOfBSplines(j,l,0,0) +
01190                                 _clUSpline.GetIntegralOfProductOfBSplines(i,k,3,1) *
01191                                 _clVSpline.GetIntegralOfProductOfBSplines(j,l,0,2) +
01192                                 _clUSpline.GetIntegralOfProductOfBSplines(i,k,1,3) *
01193                                 _clVSpline.GetIntegralOfProductOfBSplines(j,l,2,0) +
01194                                 _clUSpline.GetIntegralOfProductOfBSplines(i,k,1,1) *
01195                                 _clVSpline.GetIntegralOfProductOfBSplines(j,l,2,2) +
01196                                 _clUSpline.GetIntegralOfProductOfBSplines(i,k,2,2) *
01197                                 _clVSpline.GetIntegralOfProductOfBSplines(j,l,1,1) +
01198                                 _clUSpline.GetIntegralOfProductOfBSplines(i,k,0,2) *
01199                                 _clVSpline.GetIntegralOfProductOfBSplines(j,l,3,1) +
01200                                 _clUSpline.GetIntegralOfProductOfBSplines(i,k,2,0) *
01201                                 _clVSpline.GetIntegralOfProductOfBSplines(j,l,1,3) +
01202                                 _clUSpline.GetIntegralOfProductOfBSplines(i,k,0,0) *
01203                                 _clVSpline.GetIntegralOfProductOfBSplines(j,l,3,3) ;
01204           seq.next();
01205           n++;
01206         }
01207       }
01208       m++;
01209     }
01210   }
01211 }
01212 
01213 void BSplineParameterCorrection::EnableSmoothing(bool bSmooth, float fSmoothInfl)
01214 {
01215     EnableSmoothing(bSmooth, fSmoothInfl, 1.0f, 0.0f, 0.0f);
01216 }
01217 
01218 void BSplineParameterCorrection::EnableSmoothing(bool bSmooth, float fSmoothInfl, 
01219                                                  float fFirst, float fSec, float fThird)
01220 {
01221     if (_bSmoothing && bSmooth)
01222         CalcSmoothingTerms(false, fFirst, fSec, fThird);
01223     else if (bSmooth)
01224         CalcSmoothingTerms(true, fFirst, fSec, fThird);
01225 
01226     ParameterCorrection::EnableSmoothing(bSmooth, fSmoothInfl);
01227 }
01228 
01229 const math_Matrix& BSplineParameterCorrection::GetFirstSmoothMatrix() const
01230 {
01231     return _clFirstMatrix;
01232 }
01233 
01234 const math_Matrix& BSplineParameterCorrection::GetSecondSmoothMatrix() const
01235 {
01236     return _clSecondMatrix;
01237 }
01238 
01239 const math_Matrix& BSplineParameterCorrection::GetThirdSmoothMatrix() const
01240 {
01241     return _clThirdMatrix;
01242 }
01243 
01244 void BSplineParameterCorrection::SetFirstSmoothMatrix(const math_Matrix& rclMat)
01245 {
01246     _clFirstMatrix = rclMat;
01247 }
01248 
01249 void BSplineParameterCorrection::SetSecondSmoothMatrix(const math_Matrix& rclMat)
01250 {
01251     _clSecondMatrix = rclMat;
01252 }
01253 
01254 void BSplineParameterCorrection::SetThirdSmoothMatrix(const math_Matrix& rclMat)
01255 {
01256     _clThirdMatrix = rclMat;
01257 }

Generated on Wed Nov 23 18:59:57 2011 for FreeCAD by  doxygen 1.6.1