UniGridApprox.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2007                                                    *
00003  *   Joachim Zettler <Joachim.Zettler@gmx.de>                              *
00004  *   Human Rezai <Human@web.de>                                            *
00005  *                                                                         *
00006  *   This file is part of the FreeCAD CAx development system.              *
00007  *                                                                         *
00008  *   This library is free software; you can redistribute it and/or         *
00009  *   modify it under the terms of the GNU Library General Public           *
00010  *   License as published by the Free Software Foundation; either          *
00011  *   version 2 of the License, or (at your option) any later version.      *
00012  *                                                                         *
00013  *   This library  is distributed in the hope that it will be useful,      *
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00016  *   GNU Library General Public License for more details.                  *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU Library General Public     *
00019  *   License along with this library; see the file COPYING.LIB. If not,    *
00020  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00021  *   Suite 330, Boston, MA  02111-1307, USA                                *
00022  *                                                                         *
00023  ***************************************************************************/
00024 
00025 #include "PreCompiled.h"
00026 #include "UniGridApprox.h"
00027 
00028 #include "best_fit.h"
00029 
00030 #include <Mod/Mesh/App/Core/Grid.h>
00031 #include <Base/Builder3D.h>
00032 
00033 #include <TColgp_Array2OfPnt.hxx>
00034 #include <TColStd_Array1OfReal.hxx>
00035 #include <TColStd_Array1OfInteger.hxx>
00036 #include <GeomAPI_ProjectPointOnSurf.hxx>
00037 #include <BRepBuilderAPI_MakeFace.hxx>
00038 #include <Geom_BSplineSurface.hxx>
00039 #include <Handle_Geom_BSplineSurface.hxx>
00040 
00041 //
00043 #include <boost/numeric/bindings/traits/ublas_matrix.hpp>
00044 #include <boost/numeric/bindings/atlas/cblas.hpp>
00045 #include <boost/numeric/bindings/atlas/clapack.hpp>
00046 //
00047 using namespace boost::numeric::bindings;
00048 
00049 typedef ublas::matrix<double, ublas::column_major> cm_t;
00050 typedef ublas::symmetric_adaptor<cm_t, ublas::upper> adapt;
00051 
00052 UniGridApprox::UniGridApprox(const MeshCore::MeshKernel &mesh, double Tol)
00053         :m_Mesh(mesh),m_Tol(Tol),m_udeg(3),m_vdeg(3)
00054 {
00055 }
00056 
00057 UniGridApprox::~UniGridApprox()
00058 {
00059 }
00060 
00061 bool UniGridApprox::Perform(double TOL)
00062 {
00063 
00064     double maxErr;
00065     cout << "MeshOffset" << endl;
00066     MeshOffset();
00067 
00068     cout << "SurfMeshParam" << endl;
00069     SurfMeshParam();
00070 
00071     while (true)
00072     {
00073         cout << "CompKnots" << endl;
00074         CompKnots(uCP, vCP);
00075 
00076         cout << "MatComp" << endl;
00077         MatComp(uCP, vCP);
00078 
00079         BuildSurf();
00080 
00081         cout << "Compute Error";
00082         maxErr = CompMeshError();
00083 
00084         if (maxErr == -1)
00085             throw Base::Exception("CompError() couldn't project one point...");
00086 
00087         cout << " -> " << maxErr << endl;
00088 
00089         if (maxErr <= TOL) break;
00090         else
00091         {
00092             if (uCP >= vCP)
00093             {
00094                 uCP += 10;
00095                 vCP += vCP*10/uCP;
00096             }
00097             else
00098             {
00099                 vCP += 10;
00100                 uCP += uCP*10/vCP;
00101             }
00102         }
00103 
00104         if ( (uCP > (n_x + m_udeg + 1)) || (vCP > (n_y + m_vdeg + 1)) ) break;
00105 
00106         m_Grid.clear();
00107         m_Grid = m_GridCopy;
00108     }
00109 
00110     return true;
00111 }
00112 
00113 bool UniGridApprox::MeshOffset()
00114 {
00115 
00116     MeshCore::MeshPointIterator p_it(m_Mesh);
00117 
00118     //vorläufige Lösung bis CAD-Normalen verwendet werden können
00119     std::vector<Base::Vector3f> normals = best_fit::Comp_Normals(m_Mesh);
00120 
00121     double x_max=-(1e+10),y_max=-(1e+10),z_max=-(1e+10),x_min=1e+10,y_min=1e+10,st_x,st_y;
00122     int n = normals.size();
00123 
00124     // führe verschiebung durch
00125 
00126     //for(int i=0; i<n; ++i)
00127     //{
00128     // normals[i].Normalize();
00129     // normals[i].Scale(m_offset,m_offset,m_offset);
00130     // m_Mesh.MovePoint(i,normals[i]);
00131     //}
00132 
00133     // erzeuge nun ein uniformes Rechtecksgitter auf dem CAD-Netz
00134     m_Mesh.RecalcBoundBox();
00135 
00136     for (p_it.Begin(); p_it.More(); p_it.Next())
00137     {
00138         if (p_it->z>z_max) z_max = p_it->z;
00139         if (p_it->x>x_max) x_max = p_it->x;
00140         if (p_it->x<x_min) x_min = p_it->x;
00141         if (p_it->y>y_max) y_max = p_it->y;
00142         if (p_it->y<y_min) y_min = p_it->y;
00143     }
00144 
00145     // gittergrößen bestimmung über die bounding-box
00146     n_x = int((x_max - x_min)/(y_max - y_min)*sqrt((x_max - x_min)*(y_max - y_min)));
00147     n_y = int((y_max - y_min)/(x_max - x_min)*sqrt((x_max - x_min)*(y_max - y_min)));
00148 
00149     st_x = (x_max - x_min)/n_x;
00150     st_y = (y_max - y_min)/n_y;
00151 
00152     uCP = n_x/10;
00153     vCP = n_y/10;
00154 
00155     m_Grid.resize(n_x+1);
00156     for (int i=0; i<n_x+1; ++i)
00157         m_Grid[i].resize(n_y+1);
00158 
00159     unsigned long  facetIndex;
00160     MeshCore::MeshFacetGrid aFacetGrid(m_Mesh);
00161     MeshCore::MeshAlgorithm malg(m_Mesh);
00162     MeshCore::MeshAlgorithm malg2(m_Mesh);
00163     Base::Vector3f  projPoint, pnt, aNormal(0,0,1.0);
00164     Base::Builder3D log3d;
00165 
00166     pnt.z = float(z_max);
00167 
00168     //gp_Pnt p;
00169     //TColgp_Array2OfPnt Input(1,n_x+1,1,n_y+1);
00170 
00171     for (int i=0; i<n_x+1; ++i)
00172     {
00173         cout << double(i)/double(n_x) << endl;
00174         pnt.x = float(x_min + i*st_x);
00175         for (int j=0; j<n_y+1 - 10; ++j)
00176         {
00177             pnt.y = float(y_min + j*st_y);
00178             aNormal.z = 1.0;
00179             if (!malg.NearestFacetOnRay(pnt, aNormal, aFacetGrid, projPoint, facetIndex))
00180             {
00181                 aNormal.Scale(1,1,-1);// gridoptimiert
00182                 if (!malg.NearestFacetOnRay(pnt, aNormal, aFacetGrid, projPoint, facetIndex))
00183                 {
00184                     aNormal.Scale(1,1,-1);
00185                     if (!malg2.NearestFacetOnRay(pnt, aNormal, projPoint, facetIndex))
00186                     {
00187                         aNormal.Scale(1,1,-1);
00188                         if (!malg2.NearestFacetOnRay(pnt, aNormal, projPoint, facetIndex))
00189                         {
00190                             if (i != 0 && i !=n_x && j != 0 && j!= n_y)
00191                             {
00192                                 pnt.x += float(st_x / 10.0);
00193                                 aNormal.Scale(1,1,-1);
00194                                 if (malg.NearestFacetOnRay(pnt, aNormal, aFacetGrid, projPoint, facetIndex))
00195                                 {
00196                                     log3d.addSinglePoint(projPoint, 3, 1,0,0);
00197                                     m_Grid[i][j] = projPoint;
00198 
00199                                 }
00200                                 else
00201                                 {
00202                                     log3d.addSinglePoint(pnt, 3, 0,0,0);
00203                                     pnt.z = 1e+10;
00204                                     m_Grid[i][j] = pnt;
00205                                     pnt.z = (float) z_max;
00206                                 }
00207                             }
00208                             else
00209                             {
00210                                 log3d.addSinglePoint(pnt, 3, 0,0,0);
00211                                 m_Grid[i][j] = pnt;
00212                             }
00213                         }
00214                         else
00215                         {
00216                             log3d.addSinglePoint(projPoint, 3, 1,1,1);
00217                             m_Grid[i][j] = projPoint;
00218                         }
00219                     }
00220                     else
00221                     {
00222                         log3d.addSinglePoint(projPoint, 3, 1,1,1);
00223                         m_Grid[i][j] = projPoint;
00224                     }
00225                 }
00226                 else
00227                 {
00228                     log3d.addSinglePoint(projPoint, 3, 1,1,1);
00229                     m_Grid[i][j] = projPoint;
00230                 }
00231             }
00232             else
00233             {
00234                 log3d.addSinglePoint(projPoint, 3, 1,1,1);
00235                 m_Grid[i][j] = projPoint;
00236             }
00237         }
00238     }
00239 
00240     int c=0;
00241     for (int i=0; i<n_x+1; ++i)
00242     {
00243         for (int j=0; j<n_y+1; ++j)
00244         {
00245             c=0;
00246             if (m_Grid[i][j].z == 1e+10)
00247             {
00248 
00249                 m_Grid[i][j].x = 0;
00250                 m_Grid[i][j].y = 0;
00251                 m_Grid[i][j].z = 0;
00252 
00253                 if (m_Grid[i-1][j].z != 1e+10)
00254                 {
00255                     m_Grid[i][j] += (m_Grid[i-1][j]);
00256                     c++;
00257                 }
00258 
00259                 if (m_Grid[i][j-1].z != 1e+10)
00260                 {
00261                     m_Grid[i][j] += (m_Grid[i][j-1]);
00262                     c++;
00263                 }
00264 
00265                 if (m_Grid[i][j+1].z != 1e+10)
00266                 {
00267                     m_Grid[i][j] += (m_Grid[i][j+1]);
00268                     c++;
00269                 }
00270 
00271                 if (m_Grid[i+1][j].z != 1e+10)
00272                 {
00273                     m_Grid[i][j] += (m_Grid[i+1][j]);
00274                     c++;
00275                 }
00276 
00277                 m_Grid[i][j].Scale( float(1.0 / double(c)), float(1.0 / double(c)), float(1.0 / double(c)));;
00278                 log3d.addSinglePoint(m_Grid[i][j], 3, 0,0,0);
00279             }
00280         }
00281     }
00282 
00283     m_GridCopy = m_Grid;
00284 
00285     log3d.saveToFile("c:/projection.iv");
00286 
00287     return true;
00288 }
00289 
00290 bool UniGridApprox::SurfMeshParam()
00291 {
00292     // hier wird das in MeshOffset erzeugte gitter parametrisiert
00293     // parametrisierung: (x,y) -> (u,v)  ,  ( R x R ) -> ( [0,1] x [0,1] )
00294 
00295     int n = m_Grid.size()-1;      // anzahl der zu approximierenden punkte in x-richtung
00296     int m = m_Grid[0].size()-1;   // anzahl der zu approximierenden punkte in y-richtung
00297 
00298     std::vector<double> dist_x, dist_y;
00299     double sum,d;
00300     Base::Vector3f vlen;
00301 
00302     m_uParam.clear();
00303     m_vParam.clear();
00304     m_uParam.resize(n+1);
00305     m_vParam.resize(m+1);
00306     m_uParam[n] = 1.0;
00307     m_vParam[m] = 1.0;
00308 
00309     // berechne knotenvektor in u-richtung (entspricht x-richtung)
00310     for (int j=0; j<m+1; ++j)
00311     {
00312         sum = 0.0;
00313         dist_x.clear();
00314         for (int i=0; i<n; ++i)
00315         {
00316             vlen = (m_Grid[i+1][j] - m_Grid[i][j]);
00317             dist_x.push_back(vlen.Length());
00318             sum += dist_x[i];
00319         }
00320         d = 0.0;
00321         for (int i=0; i<n-1; ++i)
00322         {
00323             d += dist_x[i];
00324             m_uParam[i+1] = m_uParam[i+1] + d/sum;
00325         }
00326     }
00327 
00328     for (int i=0; i<n; ++i)
00329         m_uParam[i] /= m+1;
00330 
00331     // berechne knotenvektor in v-richtung (entspricht y-richtung)
00332     for (int i=0; i<n+1; ++i)
00333     {
00334         sum = 0.0;
00335         dist_y.clear();
00336         for (int j=0; j<m; ++j)
00337         {
00338             vlen = (m_Grid[i][j+1] - m_Grid[i][j]);
00339             dist_y.push_back(vlen.Length());
00340             sum += dist_y[j];
00341         }
00342         d = 0.0;
00343         for (int j=0; j<m-1; ++j)
00344         {
00345             d += dist_y[j];
00346             m_vParam[j+1] = m_vParam[j+1] + d/sum;
00347         }
00348     }
00349 
00350     for (int j=0; j<m; ++j)
00351         m_vParam[j] /= n+1;
00352 
00353     /*cout << "uParam:" << endl;
00354     for(int i=0; i<m_uParam.size(); ++i){
00355      cout << " " << m_uParam[i] << ", " << endl;
00356     }
00357 
00358     cout << "vParam:" << endl;
00359     for(int i=0; i<m_vParam.size(); ++i){
00360      cout << " " << m_vParam[i] << ", " << endl;
00361     }*/
00362 
00363     return true;
00364 }
00365 
00366 bool UniGridApprox::CompKnots(int u_CP, int v_CP)
00367 {
00368 
00369     // berechnung der knotenvektoren
00370     // siehe NURBS-BOOK Seite 412
00371 
00372     int r = n_x;
00373     int s = n_y;
00374 
00375     int n = u_CP-1;
00376     int m = v_CP-1;
00377 
00378     m_um = u_CP;
00379     m_vm = v_CP;
00380 
00381     int p = m_udeg;
00382     int q = m_vdeg;
00383 
00384     // U-Knot Vector Computation
00385     double d = ((double)r + 1.0)/((double)n - (double)p + 1.0);
00386 
00387     m_uknots.clear();
00388     m_uknots.resize(n + p + 2);
00389 
00390     for (int i=(p + 1) ; i<(n + p + 2); ++i)
00391         m_uknots[i] = 1.0;
00392 
00393     int ind;
00394     double alp;
00395 
00396     for (int i=1; i<(n - p + 1); ++i)
00397     {
00398 
00399         ind = int(i*d);          // abgerundete ganze zahl
00400         alp = i*d - ind;    // rest
00401         m_uknots[p+i] = ((1 - alp) * m_uParam[ind-1]) + (alp * m_uParam[ind]);
00402     }
00403 
00404     /*for(int i=0; i<m_uknots.size(); ++i){
00405      cout << " " << m_uknots[i] << ", " << endl;
00406     }*/
00407 
00408     // V-Knot Vector Computation
00409     d = ((double)s + 1.0)/((double)m - (double)q + 1.0);
00410 
00411     m_vknots.clear();
00412     m_vknots.resize(m + q + 2);
00413 
00414     for (int i = (q + 1) ;  i< (m + q + 2); ++i)
00415         m_vknots[i] = 1.0;
00416 
00417     for (int i=1; i<(m - q + 1); ++i)
00418     {
00419 
00420         ind = int(i*d);          // abgerundete ganze zahl
00421         alp = i*d - ind;    // rest
00422         m_vknots[q+i] = ((1 - alp) * m_vParam[ind-1]) + (alp * m_vParam[ind]);
00423     }
00424 
00425     /*for(int i=0; i<m_vknots.size(); ++i){
00426      cout << " " << m_vknots[i] << ", " << endl;
00427     }*/
00428 
00429     return true;
00430 }
00431 
00432 bool UniGridApprox::MatComp(int u_CP, int v_CP)
00433 {
00434     // hier wird schließlich approximiert
00435 
00436     int r = n_x;
00437     int s = n_y;
00438 
00439     int n = u_CP-1;
00440     int m = v_CP-1;
00441 
00442     int p = m_udeg;
00443     int q = m_vdeg;
00444 
00445     ublas::matrix<double> Nu_full(r - 1, n + 1);
00446     ublas::matrix<double> Nv_full(s - 1, m + 1);
00447     ublas::matrix<double> Nu_left(r - 1, n - 1);
00448     ublas::matrix<double> Nv_left(s - 1, m - 1);
00449     ublas::matrix<double> Nu     (n - 1, n - 1);
00450     ublas::matrix<double> Nv     (m - 1, m - 1);
00451 
00452     ublas::matrix<double> bx (1, n - 1);
00453     ublas::matrix<double> by (1, n - 1);
00454     ublas::matrix<double> bz (1, n - 1);
00455 
00456     // mit null vorinitialisieren
00457     for (int i=0; i<r-1; ++i)
00458         for (int j=0; j<n+1; ++j)
00459             Nu_full(i,j) = 0.0;
00460 
00461     for (int i=0; i<s-1; ++i)
00462         for (int j=0; j<m+1; ++j)
00463             Nv_full(i,j) = 0.0;
00464 
00465     std::vector<double> output(p+1);
00466 
00467     int ind;
00468     for (int i=1; i<r; ++i)
00469     {
00470         output.clear();
00471         output.resize(p+1);
00472         ind = Routines::FindSpan(n, p, m_uParam[i],m_uknots);
00473         Routines::Basisfun(ind,m_uParam[i],p,m_uknots,output);
00474 
00475         for (unsigned int j=0; j<output.size(); ++j)
00476         {
00477             Nu_full(i-1,ind-p+j) = output[j];
00478         }
00479     }
00480 
00481     for (int i=0; i<r-1; ++i)
00482     {
00483         for (int j=0; j<n-1; ++j)
00484         {
00485             Nu_left(i,j) = Nu_full(i,j+1);
00486         }
00487     }
00488 
00489     //WriteMatrix(Nu_full);
00490 
00491     for (int i=1; i<s; ++i)
00492     {
00493         output.clear();
00494         output.resize(q+1);
00495         ind = Routines::FindSpan(m, q, m_vParam[i],m_vknots);
00496         Routines::Basisfun(ind,m_vParam[i],q,m_vknots,output);
00497 
00498         for (unsigned int j=0; j<output.size(); ++j)
00499         {
00500             Nv_full(i-1,ind-q+j) = output[j];
00501         }
00502     }
00503 
00504     for (int i=0; i<s-1; ++i)
00505     {
00506         for (int j=0; j<m-1; ++j)
00507         {
00508             Nv_left(i,j) = Nv_full(i,j+1);
00509         }
00510     }
00511 
00512     //cout << "NV" << endl;
00513     //WriteMatrix(Nv_left);
00514 
00515     atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Nu_left,Nu_left, 0.0,Nu);  // Nu_left'*Nu_left = Nu
00516     atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Nv_left,Nv_left, 0.0,Nv);  // Nv_left'*Nv_left = Nv  !!! Achtung !!!
00517 
00518     std::vector<int> upiv(n - 1);   // pivotelement
00519     atlas::lu_factor(Nu,upiv);      // führt LU-Zerlegung durch
00520     std::vector<int> vpiv(m - 1);
00521     atlas::lu_factor(Nv,vpiv);
00522 
00523     ublas::matrix<double> uCP_x(n + 1, s + 1);
00524     ublas::matrix<double> uCP_y(n + 1, s + 1);
00525     ublas::matrix<double> uCP_z(n + 1, s + 1);
00526 
00527     CPx.resize(n + 1, m + 1);
00528     CPy.resize(n + 1, m + 1);
00529     CPz.resize(n + 1, m + 1);
00530 
00531     // mit null vorinitialisieren
00532     for (int i=0; i<n+1; ++i)
00533         for (int j=0; j<s+1; ++j)
00534         {
00535             uCP_x(i,j) = 0.0;
00536             uCP_y(i,j) = 0.0;
00537             uCP_z(i,j) = 0.0;
00538         }
00539 
00540     std::vector< ublas::matrix<double> > Ru_x(s+1);
00541     std::vector< ublas::matrix<double> > Ru_y(s+1);
00542     std::vector< ublas::matrix<double> > Ru_z(s+1);
00543 
00544     for (int j=0; j<s+1; ++j)
00545     {
00546 
00547         Ru_x[j].resize(r-1,1);
00548         Ru_y[j].resize(r-1,1);
00549         Ru_z[j].resize(r-1,1);
00550 
00551         uCP_x(0,j) = m_Grid[0][j].x;
00552         uCP_y(0,j) = m_Grid[0][j].y;
00553         uCP_z(0,j) = m_Grid[0][j].z;
00554 
00555         uCP_x(n,j) = m_Grid[r][j].x;
00556         uCP_y(n,j) = m_Grid[r][j].y;
00557         uCP_z(n,j) = m_Grid[r][j].z;
00558 
00559         for (int k=0; k<r-1; ++k)
00560         {
00561             Ru_x[j](k,0) = m_Grid[k+1][j].x - Nu_full(k,0)*m_Grid[0][j].x - Nu_full(k,n)*m_Grid[r][j].x;
00562             Ru_y[j](k,0) = m_Grid[k+1][j].y - Nu_full(k,0)*m_Grid[0][j].y - Nu_full(k,n)*m_Grid[r][j].y;
00563             Ru_z[j](k,0) = m_Grid[k+1][j].z - Nu_full(k,0)*m_Grid[0][j].z - Nu_full(k,n)*m_Grid[r][j].z;
00564         }
00565 
00566         atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Ru_x[j],Nu_left, 0.0, bx);
00567         atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Ru_y[j],Nu_left, 0.0, by);
00568         atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Ru_z[j],Nu_left, 0.0, bz);
00569 
00570         atlas::getrs(CblasTrans,Nu,upiv,bx);
00571         atlas::getrs(CblasTrans,Nu,upiv,by);
00572         atlas::getrs(CblasTrans,Nu,upiv,bz);
00573 
00574         for (int i=1; i<n; ++i)
00575         {
00576             uCP_x(i,j) = bx(0,i-1);
00577             uCP_y(i,j) = by(0,i-1);
00578             uCP_z(i,j) = bz(0,i-1);
00579         }
00580     }
00581 
00582     Base::Builder3D log3d;
00583     Base::Vector3f pnt,pnt1;
00584 
00585     for (int j=0; j<s; ++j)
00586     {
00587         for (int i=0; i<n; ++i)
00588         {
00589 
00590             pnt.x = (float) uCP_x(i,j);
00591             pnt.y = (float) uCP_y(i,j);
00592             pnt.z = (float) uCP_z(i,j);
00593 
00594             pnt1.x = (float) uCP_x(i+1,j);
00595             pnt1.y = (float) uCP_y(i+1,j);
00596             pnt1.z = (float) uCP_z(i+1,j);
00597 
00598             log3d.addSingleLine(pnt,pnt1, 1, 1,0,0);
00599         }
00600     }
00601 
00602 
00603     log3d.saveToFile("c:/ControlPoints_u.iv");
00604 
00605     //CPx = uCP_x;
00606     //CPy = uCP_y;
00607     //CPz = uCP_z;
00608 
00609     //return true;
00610 
00611     m_Grid.clear();
00612     m_Grid.resize(n+1);
00613     for (int i=0; i<n+1; ++i)
00614         m_Grid[i].resize(s+1);
00615 
00616     for (int i=0; i<n+1; ++i)
00617     {
00618         for (int j=0; j<s+1; ++j)
00619         {
00620 
00621             m_Grid[i][j].x = (float) uCP_x(i,j);
00622             m_Grid[i][j].y = (float) uCP_y(i,j);
00623             m_Grid[i][j].z = (float) uCP_z(i,j);
00624         }
00625     }
00626 
00627     //SurfMeshParam();
00628 
00629     // mit null vorinitialisieren
00630     for (int i=0; i<n + 1; ++i)
00631     {
00632         for (int j=0; j<m + 1; ++j)
00633         {
00634             CPx(i,j) = 0.0;
00635             CPy(i,j) = 0.0;
00636             CPz(i,j) = 0.0;
00637         }
00638     }
00639 
00640     std::vector< ublas::matrix<double> > Rv_x(n+1);
00641     std::vector< ublas::matrix<double> > Rv_y(n+1);
00642     std::vector< ublas::matrix<double> > Rv_z(n+1);
00643 
00644     Base::Builder3D log,logo;
00645 
00646     for (int j=0; j<n+1; ++j)
00647     {
00648 
00649         Rv_x[j].resize(s-1,1);
00650         Rv_y[j].resize(s-1,1);
00651         Rv_z[j].resize(s-1,1);
00652 
00653         CPx(j,0) = uCP_x(j,0);
00654         CPy(j,0) = uCP_y(j,0);
00655         CPz(j,0) = uCP_z(j,0);
00656 
00657         CPx(j,m) = uCP_x(j,s);
00658         CPy(j,m) = uCP_y(j,s);
00659         CPz(j,m) = uCP_z(j,s);
00660 
00661         for (int k=0; k<s-1; ++k)
00662         {
00663 
00664             Rv_x[j](k,0) = uCP_x(j,k+1) - Nv_full(k,0)*uCP_x(j,0) - Nv_full(k,m)*uCP_x(j,s);
00665             Rv_y[j](k,0) = uCP_y(j,k+1) - Nv_full(k,0)*uCP_y(j,0) - Nv_full(k,m)*uCP_y(j,s);
00666             Rv_z[j](k,0) = uCP_z(j,k+1) - Nv_full(k,0)*uCP_z(j,0) - Nv_full(k,m)*uCP_z(j,s);
00667 
00668             pnt.x = (float) uCP_x(j,k+1);
00669             pnt.y = (float) uCP_y(j,k+1);
00670             pnt.z = (float) uCP_z(j,k+1);
00671 
00672             pnt1.x = (float) uCP_x(j,k+2);
00673             pnt1.y = (float) uCP_y(j,k+2);
00674             pnt1.z = (float) uCP_z(j,k+2);
00675 
00676             log.addSingleLine(pnt,pnt1, 1, 0,0,0);
00677 
00678         }
00679 
00680         bx.clear();
00681         by.clear();
00682         bz.clear();
00683         bx.resize(1, m - 1);
00684         by.resize(1, m - 1);
00685         bz.resize(1, m - 1);
00686 
00687         atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Rv_x[j],Nv_left, 0.0, bx);
00688         atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Rv_y[j],Nv_left, 0.0, by);
00689         atlas::gemm(CblasTrans,CblasNoTrans, 1.0, Rv_z[j],Nv_left, 0.0, bz);
00690 
00691         atlas::getrs(CblasTrans,Nv,vpiv,bx);
00692         atlas::getrs(CblasTrans,Nv,vpiv,by);
00693         atlas::getrs(CblasTrans,Nv,vpiv,bz);
00694 
00695         for (int i=1; i<m; ++i)
00696         {
00697             CPx(j,i) = bx(0,i-1);
00698             CPy(j,i) = by(0,i-1);
00699             CPz(j,i) = bz(0,i-1);
00700 
00701             pnt.x = (float) CPx(j,i);
00702             pnt.y = (float) CPy(j,i);
00703             pnt.z = (float) CPz(j,i);
00704 
00705             logo.addSinglePoint(pnt,2,0,0,0);
00706         }
00707     }
00708 
00709     logo.saveToFile("c:/contrPnts.iv");
00710 
00711     ublas::matrix<double> Tmp = CPz;
00712 
00713     //glättung des kontrollpunktnetzes
00714     for (int i=1; i<n; ++i)
00715     {
00716         for (int j=1; j<m; ++j)
00717         {
00718             /*CPz(i,j) = ((Tmp(i-1,j-1) + Tmp(i-1,j) + Tmp(i-1,j+1)) +
00719                        (Tmp(i,j-1)   + Tmp(i,j)   + Tmp(i,j+1))   +
00720                      (Tmp(i+1,j-1) + Tmp(i+1,j) + Tmp(i+1,j+1)))/9;*/
00721 
00722             CPz(i,j) = (Tmp(i-1,j) + Tmp(i,j-1) + Tmp(i,j) + Tmp(i,j+1) +Tmp(i+1,j))/5;
00723         }
00724     }
00725 
00726     //for(int i=1; i<n; ++i){
00727     // for(int j=1; j<m; ++j){
00728     //  /*CPz(i,j) = ((Tmp(i-1,j-1) + Tmp(i-1,j) + Tmp(i-1,j+1)) +
00729 //             (Tmp(i,j-1)   + Tmp(i,j)   + Tmp(i,j+1))   +
00730     //           (Tmp(i+1,j-1) + Tmp(i+1,j) + Tmp(i+1,j+1)))/9;*/
00731 
00732     //  CPz(i,j) = (Tmp(i-1,j) + Tmp(i,j-1) + Tmp(i,j) + Tmp(i,j+1) +Tmp(i+1,j))/5;
00733     // }
00734     //}
00735 
00736     return true;
00737 }
00738 
00739 bool UniGridApprox::BuildSurf()
00740 {
00741 
00742     gp_Pnt pnt;
00743     TColgp_Array2OfPnt Poles(1,m_um,1,m_vm);
00744 
00745 
00746 
00747     for (int i=0; i<m_um; ++i)
00748     {
00749         for (int j=0; j<m_vm; ++j)
00750         {
00751             pnt.SetX(CPx(i,j));
00752             pnt.SetY(CPy(i,j));
00753             pnt.SetZ(CPz(i,j));
00754 
00755             Poles.SetValue(i+1,j+1,pnt);
00756         }
00757     }
00758 
00759     int c=1;
00760     for (unsigned int i=0; i<m_uknots.size()-1; ++i)
00761     {
00762         if (m_uknots[i+1] != m_uknots[i])
00763         {
00764             ++c;
00765         }
00766     }
00767 
00768 
00769     TColStd_Array1OfReal    UKnots(1,c);
00770     TColStd_Array1OfInteger UMults(1,c);
00771 
00772     c=1;
00773     for (unsigned int i=0; i<m_vknots.size()-1; ++i)
00774     {
00775         if (m_vknots[i+1] != m_vknots[i])
00776         {
00777             ++c;
00778         }
00779     }
00780 
00781 
00782     TColStd_Array1OfReal    VKnots(1,c);
00783     TColStd_Array1OfInteger VMults(1,c);
00784 
00785     int d=0;
00786     c=1;
00787     for (unsigned int i=0; i<m_uknots.size(); ++i)
00788     {
00789         if (m_uknots[i+1] != m_uknots[i])
00790         {
00791             UKnots.SetValue(d+1,m_uknots[i]);
00792             UMults.SetValue(d+1,c);
00793             ++d;
00794             c=1;
00795 
00796         }
00797         else
00798         {
00799             ++c;
00800         }
00801 
00802         if (i==(m_uknots.size()-2))
00803         {
00804             UKnots.SetValue(d+1,m_uknots[i+1]);
00805             UMults.SetValue(d+1,c);
00806             break;
00807         }
00808     }
00809 
00810     d=0;
00811     c=1;
00812     for (unsigned int i=0; i<m_vknots.size(); ++i)
00813     {
00814         if (m_vknots[i+1] != m_vknots[i])
00815         {
00816             VKnots.SetValue(d+1,m_vknots[i]);
00817             VMults.SetValue(d+1,c);
00818             ++d;
00819             c=1;
00820 
00821         }
00822         else
00823         {
00824             ++c;
00825         }
00826 
00827         if (i==(m_vknots.size()-2))
00828         {
00829             VKnots.SetValue(d+1,m_vknots[i+1]);
00830             VMults.SetValue(d+1,c);
00831             break;
00832         }
00833     }
00834 
00835     /*cout << "UKnots: " << endl;
00836     for(int i=0; i<UKnots.Upper(); ++i)
00837      cout << UKnots.Value(i+1) << ", ";
00838     cout << endl;
00839 
00840 
00841     cout << "UMults: " << endl;
00842     for(int i=0; i<UMults.Upper(); ++i)
00843      cout << UMults.Value(i+1) << ", ";
00844     cout << endl;
00845 
00846 
00847     cout << "VKnots: " << endl;
00848     for(int i=0; i<VKnots.Upper(); ++i)
00849      cout << VKnots.Value(i+1) << ", ";
00850     cout << endl;
00851 
00852 
00853     cout << "VMults: " << endl;
00854     for(int i=0; i<VMults.Upper(); ++i)
00855      cout << VMults.Value(i+1) << ", ";
00856     cout << endl;*/
00857 
00858 
00859     const Handle(Geom_BSplineSurface) surface = new Geom_BSplineSurface(
00860         Poles,        // const TColgp_Array2OfPnt &    Poles,
00861         UKnots,       // const TColStd_Array1OfReal &   UKnots,
00862         VKnots,       // const TColStd_Array1OfReal &   VKnots,
00863         UMults,       // const TColStd_Array1OfInteger &   UMults,
00864         VMults,       // const TColStd_Array1OfInteger &   VMults,
00865         3,            // const Standard_Integer   UDegree,
00866         3             // const Standard_Integer   VDegree,
00867         // const Standard_Boolean   UPeriodic = Standard_False,
00868         // const Standard_Boolean   VPeriodic = Standard_False*/
00869     );
00870 
00871     aAdaptorSurface.Load(surface);
00872 
00873     return true;
00874 }
00875 
00876 double UniGridApprox::CompGridError()
00877 {
00878     GeomAPI_ProjectPointOnSurf proj;
00879     MeshCore::MeshPointIterator pIt(m_Mesh);
00880     gp_Pnt pnt;
00881     double tmp = 0.0;
00882 
00883     mG_err.clear();
00884     mG_err.resize(m_Grid.size());
00885     for (unsigned int i=0; i<m_Grid.size(); ++i)
00886         mG_err[i].resize(m_Grid[i].size());
00887 
00888     for (unsigned int i=0; i<m_Grid.size(); ++i)
00889     {
00890         for (unsigned int j=0; j<m_Grid[i].size(); ++j)
00891         {
00892 
00893             pnt.SetCoord(m_Grid[i][j].x, m_Grid[i][j].y, m_Grid[i][j].z);
00894             proj.Init(pnt,aAdaptorSurface.BSpline(),0.1);
00895             if (proj.IsDone() == false)
00896                 return -1.0;
00897             mG_err[i][j] = proj.LowerDistance();
00898 
00899             if (mG_err[i][j] > tmp)
00900                 tmp = mG_err[i][j];
00901 
00902         }
00903     }
00904 
00905     return tmp;
00906 }
00907 
00908 bool UniGridApprox::WriteMatrix(ublas::matrix<double> M)
00909 {
00910 
00911     int row = M.size1();
00912     int col = M.size2();
00913 
00914     for (int i=0; i<row; ++i)
00915     {
00916         for (int j=0; j<col; ++j)
00917         {
00918             cout << M(i,j) << ", ";
00919         }
00920         cout << endl;
00921     }
00922 
00923     return true;
00924 }
00925 
00926 double UniGridApprox::CompMeshError()
00927 {
00928     Base::Builder3D log3d;
00929     MeshCore::MeshKernel mesh;
00930     BRepBuilderAPI_MakeFace Face(aAdaptorSurface.BSpline());
00931     GeomAPI_ProjectPointOnSurf proj;
00932     best_fit::Tesselate_Face(Face.Face(), mesh, float(0.1));
00933     cout << mesh.CountPoints() << endl;
00934     std::vector<Base::Vector3f> normals =  best_fit::Comp_Normals(mesh);
00935 
00936     double tmp = 0.0, sqrdis;
00937     double errSum = 0.0;
00938     int c=0;
00939 
00940     m_err.clear();
00941     m_err.resize(mesh.CountPoints(), 0.0);
00942 
00943     MeshCore::MeshFacetGrid aFacetGrid(m_Mesh);
00944     MeshCore::MeshAlgorithm malg(m_Mesh);
00945     MeshCore::MeshAlgorithm malg2(m_Mesh);
00946     MeshCore::MeshPointIterator p_it(mesh);
00947 
00948     Base::Vector3f projPoint, distVec, pnt;
00949     unsigned long  facetIndex;
00950 
00951 
00952     for (p_it.Begin(); p_it.More(); p_it.Next())
00953     {
00954         if (!malg.NearestFacetOnRay(*p_it, normals[p_it.Position()], aFacetGrid, projPoint, facetIndex))   // gridoptimiert
00955         {
00956             if (malg2.NearestFacetOnRay(*p_it, normals[p_it.Position()], projPoint, facetIndex))
00957             {
00958                 pnt.x = p_it->x;
00959                 pnt.y = p_it->y;
00960                 pnt.z = p_it->z;
00961                 log3d.addSingleLine(pnt,projPoint);
00962                 distVec  = projPoint - pnt;
00963                 sqrdis   = distVec*distVec;
00964             }
00965             else
00966             {
00967                 cout << "oops, ";
00968                 continue;
00969             }
00970         }
00971         else
00972         {
00973             pnt.x = p_it->x;
00974             pnt.y = p_it->y;
00975             pnt.z = p_it->z;
00976             log3d.addSingleLine(pnt,projPoint);
00977             distVec  = projPoint - pnt;
00978             sqrdis   = distVec*distVec;
00979         }
00980 
00981         errSum += sqrt(sqrdis);
00982         ++c;
00983 
00984         if (sqrt(sqrdis) > tmp)
00985         {
00986             m_err[p_it.Position()] = sqrt(sqrdis);
00987             tmp = m_err[p_it.Position()];
00988         }
00989     }
00990 
00991     log3d.saveToFile("c:/Error.iv");
00992 
00993     return errSum/c;
00994 }

Generated on Wed Nov 23 19:00:56 2011 for FreeCAD by  doxygen 1.6.1