00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "PreCompiled.h"
00035 #include "Approx.h"
00036 #include <iostream>
00037 #include <algorithm>
00038 #include <Base/Exception.h>
00039
00040
00041 #include <TColgp_Array2OfPnt.hxx>
00042 #include <TColStd_Array1OfReal.hxx>
00043 #include <TColStd_Array1OfInteger.hxx>
00044 #include <GeomAPI_ProjectPointOnSurf.hxx>
00045 #include <Geom_BSplineSurface.hxx>
00046 #include <BRepBuilderAPI_MakeFace.hxx>
00047
00048
00049
00050
00051 #include <boost/numeric/ublas/matrix_sparse.hpp>
00052 #include <boost/numeric/ublas/blas.hpp>
00053 #include <boost/numeric/ublas/operation.hpp>
00054 #include <boost/numeric/ublas/io.hpp>
00055
00056
00057 #include <boost/numeric/bindings/traits/ublas_matrix.hpp>
00058 #include <boost/numeric/bindings/traits/ublas_sparse.hpp>
00059 #include <boost/numeric/bindings/umfpack/umfpack.hpp>
00060 #include <boost/numeric/bindings/atlas/cblas.hpp>
00061 #include <boost/numeric/bindings/atlas/clapack.hpp>
00062
00063
00064
00065
00066 using namespace boost::numeric::bindings;
00067
00068 Approximate::Approximate(const MeshCore::MeshKernel &m,std::vector<double> &_Cntrl, std::vector<double> &_KnotU, std::vector<double> &_KnotV,
00069 int &_OrderU, int &_OrderV, double tol)
00070 {
00071 MinX = 0, MinY = 0, MaxX = 0;
00072 MaxY = 0;
00073 tolerance = tol;
00074 int NumPnts = m.CountPoints();
00075 Base::BoundBox3f bbox = m.GetBoundBox();
00076 double x_len = bbox.LengthX();
00077 double y_len = bbox.LengthY();
00078
00079 LocalMesh = m;
00080
00081
00082
00083 MainNurb.DegreeU = 3;
00084 MainNurb.DegreeV = 3;
00085 MainNurb.MaxU = std::max<int>(MainNurb.DegreeU+1, (int)sqrt(double(NumPnts)*y_len/x_len));
00086 MainNurb.MaxV = std::max<int>(MainNurb.DegreeV+1, (int)sqrt(double(NumPnts)*x_len/y_len));
00087
00088 GenerateUniformKnot(MainNurb.MaxU,MainNurb.DegreeU,MainNurb.KnotU);
00089 GenerateUniformKnot(MainNurb.MaxV,MainNurb.DegreeV,MainNurb.KnotV);
00090 MainNurb.MaxKnotU = MainNurb.KnotU.size();
00091 MainNurb.MaxKnotV = MainNurb.KnotV.size();
00092
00093
00094 ApproxMain();
00095
00096 ofstream anOutputFile;
00097 anOutputFile.open("c:/approx_build_surface.txt");
00098
00099 anOutputFile << "start building surface" << endl;
00100
00101
00102
00103 _Cntrl = MainNurb.CntrlArray;
00104 _KnotU = MainNurb.KnotU;
00105 _KnotV = MainNurb.KnotV;
00106 _OrderU = MainNurb.DegreeU + 1;
00107 _OrderV = MainNurb.DegreeV + 1;
00108
00109 gp_Pnt pnt;
00110 TColgp_Array2OfPnt Poles(1,MainNurb.MaxU+1, 1,MainNurb.MaxV+1);
00111
00112 for(int j=0; j< (MainNurb.MaxV+1); ++j)
00113 {
00114 for(int i=0; i < (MainNurb.MaxU+1); ++i)
00115 {
00116 pnt.SetX(_Cntrl[3*i + j*3*(MainNurb.MaxU+1)]);
00117 pnt.SetY(_Cntrl[3*i+1 + j*3*(MainNurb.MaxU+1)]);
00118 pnt.SetZ(_Cntrl[3*i+2 + j*3*(MainNurb.MaxU+1)]);
00119
00120 Poles.SetValue(i+1,j+1,pnt);
00121 }
00122 }
00123
00124 anOutputFile << "control points done" << endl;
00125
00126 int c=1;
00127 for (unsigned int i=0; i<_KnotU.size()-1; ++i)
00128 {
00129 if (_KnotU[i+1] != _KnotU[i])
00130 {
00131 ++c;
00132 }
00133 }
00134
00135
00136 TColStd_Array1OfReal UKnots(1,c);
00137 TColStd_Array1OfInteger UMults(1,c);
00138
00139 c=1;
00140 for (unsigned int i=0; i<_KnotV.size()-1; ++i)
00141 {
00142 if (_KnotV[i+1] != _KnotV[i])
00143 {
00144 ++c;
00145 }
00146 }
00147
00148
00149 TColStd_Array1OfReal VKnots(1,c);
00150 TColStd_Array1OfInteger VMults(1,c);
00151
00152 int d=0;
00153 c=1;
00154 for (unsigned int i=0; i<_KnotU.size(); ++i)
00155 {
00156 if (_KnotU[i+1] != _KnotU[i])
00157 {
00158 UKnots.SetValue(d+1,_KnotU[i]);
00159 UMults.SetValue(d+1,c);
00160 ++d;
00161 c=1;
00162
00163 }
00164 else
00165 {
00166 ++c;
00167 }
00168
00169 if (i==(_KnotU.size()-2))
00170 {
00171 UKnots.SetValue(d+1,_KnotU[i+1]);
00172 UMults.SetValue(d+1,c);
00173 break;
00174 }
00175 }
00176
00177 d=0;
00178 c=1;
00179 for (unsigned int i=0; i<_KnotV.size(); ++i)
00180 {
00181 if (_KnotV[i+1] != _KnotV[i])
00182 {
00183 VKnots.SetValue(d+1,_KnotV[i]);
00184 VMults.SetValue(d+1,c);
00185 ++d;
00186 c=1;
00187
00188 }
00189 else
00190 {
00191 ++c;
00192 }
00193
00194 if (i==(_KnotV.size()-2))
00195 {
00196 VKnots.SetValue(d+1,_KnotV[i+1]);
00197 VMults.SetValue(d+1,c);
00198 break;
00199 }
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 const Handle(Geom_BSplineSurface) surface = new Geom_BSplineSurface(
00229 Poles,
00230 UKnots,
00231 VKnots,
00232 UMults,
00233 VMults,
00234 3,
00235 3
00236
00237
00238 );
00239
00240 aAdaptorSurface.Load(surface);
00241
00242
00243
00244 }
00245
00246 Approximate::~Approximate()
00247 {
00248 }
00251 void Approximate::ApproxMain()
00252 {
00253 std::cout << "BEGIN COMPUTE NURB" << std::endl;
00254 ParameterBoundary();
00255 ParameterInnerPoints();
00256
00257 ErrorApprox();
00258 std::cout << "END COMPUTE NURB" << std::endl;
00259 }
00260
00261
00269 void Approximate::ParameterBoundary()
00270 {
00271 std::cout << "Computing the parameter for the outer boundary..." << std::endl;
00272
00273 ParameterMesh = LocalMesh;
00274 MeshCore::MeshAlgorithm algo(ParameterMesh);
00275 MeshCore::MeshPointIterator p_it(ParameterMesh);
00276 NumOfPoints = LocalMesh.CountPoints();
00277 NumOfOuterPoints = 0;
00278 double distance = 0;
00279 unsigned int a;
00280 std::vector<unsigned long> CornerIndex;
00281 std::vector<double> Pointdistance;
00282 std::vector<unsigned long>::iterator vec_it;
00283 std::vector <Base::Vector3f>::iterator pnt_it;
00284
00285
00286 algo.GetMeshBorders(BoundariesIndex);
00287 algo.GetMeshBorders(BoundariesPoints);
00288 std::list< std::vector <unsigned long> >::iterator bInd = BoundariesIndex.begin();
00289 std::list< std::vector <Base::Vector3f> >::iterator bPnt = BoundariesPoints.begin();
00290 std::vector <unsigned long> v_neighbour = *bInd;
00291 std::vector <Base::Vector3f> v_pnts = *bPnt;
00292
00293 Base::BoundBox3f BoundBox = ParameterMesh.GetBoundBox();
00294
00295
00296 NumOfOuterPoints = v_neighbour.size()-1;
00297 BoundariesX.resize(NumOfOuterPoints);
00298 BoundariesY.resize(NumOfOuterPoints);
00299 UnparamBoundariesX.resize(NumOfOuterPoints);
00300 UnparamBoundariesY.resize(NumOfOuterPoints);
00301 UnparamBoundariesZ.resize(NumOfOuterPoints);
00302 std::vector <unsigned long> nei_tmp(NumOfOuterPoints);
00303 std::vector <Base::Vector3f> pnts_tmp(NumOfOuterPoints);
00304
00305
00306
00307 std::cout << "Looking for corners..." << std::endl;
00308 CornerIndex.push_back(FindCorner(BoundBox.MinX,BoundBox.MinY,v_neighbour,v_pnts));
00309 CornerIndex.push_back(FindCorner(BoundBox.MaxX,BoundBox.MinY,v_neighbour,v_pnts));
00310 CornerIndex.push_back(FindCorner(BoundBox.MaxX,BoundBox.MaxY,v_neighbour,v_pnts));
00311 CornerIndex.push_back(FindCorner(BoundBox.MinX,BoundBox.MaxY,v_neighbour,v_pnts));
00312
00313
00314 vec_it = find(v_neighbour.begin(),v_neighbour.end(),CornerIndex[0]);
00315 pnt_it = find(v_pnts.begin(), v_pnts.end(), LocalMesh.GetPoint(CornerIndex[0]));
00316 for (unsigned int i = 0; i < v_neighbour.size()-1; i++)
00317 {
00318 nei_tmp[i] = *vec_it;
00319 pnts_tmp[i] = *pnt_it;
00320 UnparamBoundariesX[i] = (*pnt_it).x;
00321 UnparamBoundariesY[i] = (*pnt_it).y;
00322 UnparamBoundariesZ[i] = (*pnt_it).z;
00323 ++vec_it;
00324 ++pnt_it;
00325 if (vec_it == v_neighbour.end()-1)
00326 {
00327 vec_it = v_neighbour.begin();
00328 pnt_it = v_pnts.begin();
00329 a = i;
00330 }
00331
00332
00333 }
00334 v_pnts.clear();
00335 v_pnts = pnts_tmp;
00336
00337 std::cout << "Parametirizing..." << std::endl;
00338
00339
00340
00341
00342 double totaldistance = 0;
00343 unsigned int g = 0;
00344 unsigned int temp1 = g;
00345 unsigned int temp2 = g;
00346 do
00347 {
00348 distance = sqrt(((v_pnts[g+1][0] - v_pnts[g][0])*(v_pnts[g+1][0] - v_pnts[g][0]))
00349 + ((v_pnts[g+1][1] - v_pnts[g][1])*(v_pnts[g+1][1] - v_pnts[g][1])));
00350 Pointdistance.push_back(distance);
00351 totaldistance += distance;
00352 g++;
00353 }
00354 while ((vec_it = find(CornerIndex.begin(), CornerIndex.end(), nei_tmp[g])) == CornerIndex.end());
00355
00356
00357 temp1 = g;
00358 g = temp2;
00359
00360
00361 pnts_tmp[g][0] = 0.0f, pnts_tmp[g][1] = 0.0f;
00362 BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1];
00363 g++;
00364 for (unsigned int i = 0; i < Pointdistance.size() - 1;i++)
00365 {
00366
00367
00368 pnts_tmp[g][0] = (Pointdistance[i]/totaldistance)+pnts_tmp[g-1][0], pnts_tmp[g][1] = 0.0f;
00369 BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1];
00370 g++;
00371 }
00372
00373
00374 g = temp1;
00375 temp2 = g;
00376 Pointdistance.clear();
00377 totaldistance = 0;
00378
00379
00380 do
00381 {
00382 distance = sqrt(((v_pnts[g+1][0] - v_pnts[g][0])*(v_pnts[g+1][0] - v_pnts[g][0]))
00383 + ((v_pnts[g+1][1] - v_pnts[g][1])*(v_pnts[g+1][1] - v_pnts[g][1])));
00384 Pointdistance.push_back(distance);
00385 totaldistance += distance;
00386 g++;
00387 }
00388 while ((vec_it = find(CornerIndex.begin(), CornerIndex.end(), nei_tmp[g])) == CornerIndex.end());
00389
00390
00391 temp1 = g;
00392 g = temp2;
00393 pnts_tmp[g][0] = 1.0f, pnts_tmp[g][1] = 0.0f;
00394 BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1];
00395 g++;
00396 for (unsigned int i = 0; i < Pointdistance.size() - 1;i++)
00397 {
00398
00399
00400 pnts_tmp[g][0] = 1.0f, pnts_tmp[g][1] = (Pointdistance[i]/totaldistance)+pnts_tmp[g-1][1];
00401 BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1];
00402 g++;
00403 }
00404
00405
00406 g = temp1;
00407 temp2 = g;
00408 Pointdistance.clear();
00409 totaldistance = 0;
00410
00411
00412 do
00413 {
00414 distance = sqrt(((v_pnts[g+1][0] - v_pnts[g][0])*(v_pnts[g+1][0] - v_pnts[g][0]))
00415 + ((v_pnts[g+1][1] - v_pnts[g][1])*(v_pnts[g+1][1] - v_pnts[g][1])));
00416 Pointdistance.push_back(distance);
00417 totaldistance += distance;
00418 g++;
00419 }
00420 while ((vec_it = find(CornerIndex.begin(), CornerIndex.end(), nei_tmp[g])) == CornerIndex.end());
00421
00422
00423 temp1 = g;
00424 g = temp2;
00425 pnts_tmp[g][0] = 1.0f, pnts_tmp[g][1] = 1.0f;
00426 float prev = pnts_tmp[g][0];
00427 BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1];
00428 g++;
00429 for (unsigned int i = 0; i < Pointdistance.size() - 1;i++)
00430 {
00431
00432
00433 pnts_tmp[g][0] = (Pointdistance[i]/totaldistance)+prev, pnts_tmp[g][1] = 1.0f;
00434 prev = pnts_tmp[g][0];
00435 pnts_tmp[g][0] = 2.0f - pnts_tmp[g][0];
00436 BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1];
00437 g++;
00438 }
00439
00440
00441 g = temp1;
00442 temp2 = g;
00443 Pointdistance.clear();
00444 totaldistance = 0;
00445
00446
00447 do
00448 {
00449 distance = sqrt(((v_pnts[g+1][0] - v_pnts[g][0])*(v_pnts[g+1][0] - v_pnts[g][0]))
00450 + ((v_pnts[g+1][1] - v_pnts[g][1])*(v_pnts[g+1][1] - v_pnts[g][1])));
00451 Pointdistance.push_back(distance);
00452 totaldistance += distance;
00453 g++;
00454 if (g+1 == v_pnts.size())
00455 {
00456 distance = sqrt(((v_pnts[0][0] - v_pnts[g][0])*(v_pnts[0][0] - v_pnts[g][0]))
00457 + ((v_pnts[0][1] - v_pnts[g][1])*(v_pnts[0][1] - v_pnts[g][1])));
00458 Pointdistance.push_back(distance);
00459 totaldistance += distance;
00460 break;
00461 }
00462 }
00463 while ((vec_it = find(CornerIndex.begin(), CornerIndex.end(), nei_tmp[g])) == CornerIndex.end());
00464
00465
00466 temp1 = g;
00467 g = temp2;
00468 pnts_tmp[g][0] = 0.0f, pnts_tmp[g][1] = 1.0f;
00469 prev = pnts_tmp[g][1];
00470 BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1];
00471 g++;
00472 for (unsigned int i = 0; i < Pointdistance.size() - 1;i++)
00473 {
00474
00475
00476 pnts_tmp[g][0] = 0.0, pnts_tmp[g][1] = (Pointdistance[i]/totaldistance)+prev;
00477 prev = pnts_tmp[g][1];
00478 pnts_tmp[g][1] = 2.0f - pnts_tmp[g][1];
00479 BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1];
00480 g++;
00481 }
00482
00483
00484 g = temp1;
00485 temp2 = g;
00486 Pointdistance.clear();
00487 totaldistance = 0;
00488
00489 ParameterX.resize(NumOfOuterPoints);
00490 ParameterY.resize(NumOfOuterPoints);
00491 int count = 0;
00492 NumOfInnerPoints = NumOfPoints - NumOfOuterPoints;
00493 mapper.resize(NumOfPoints);
00494 MeshCore::MeshPointIterator v_it(LocalMesh);
00495 a = 0;
00496 int b = 0;
00497 for (v_it.Begin(); !v_it.EndReached(); ++v_it)
00498 {
00499 if ((vec_it = find(nei_tmp.begin(), nei_tmp.end(), v_it.Position())) != nei_tmp.end())
00500 {
00501
00502 ParameterX[count] = pnts_tmp[int(vec_it-nei_tmp.begin())][0];
00503 ParameterY[count] = pnts_tmp[int(vec_it-nei_tmp.begin())][1];
00504 mapper[v_it.Position()] = a+NumOfInnerPoints;
00505 a++, count++;
00506 }
00507 else
00508 {
00509
00510 mapper[v_it.Position()] = b;
00511 b++;
00512 }
00513 }
00514 }
00521 void Approximate::ParameterInnerPoints()
00522 {
00523 std::cout << "Computing the parameter for the inner points..." << std::endl;
00524 MeshCore::MeshPointIterator v_it(LocalMesh);
00525 MeshCore::MeshAlgorithm algo(LocalMesh);
00526 MeshCore::MeshRefPointToPoints vv_it(LocalMesh);
00527 MeshCore::MeshRefPointToFacets vf_it(LocalMesh);
00528 std::set<unsigned long> PntNei;
00529 std::set<unsigned long> FacetNei;
00530 ublas::compressed_matrix<double> Lambda(NumOfInnerPoints, NumOfPoints);
00531 int count = 0;
00532
00533 std::cout << "Prepping the Lambda" << std::endl;
00534 std::list< std::vector <unsigned long> >::iterator bInd = BoundariesIndex.begin();
00535 std::vector <unsigned long> neiIndexes = *bInd;
00536 std::vector <unsigned long>::iterator vec_it;
00537 for (v_it.Begin(); !v_it.EndReached(); ++v_it)
00538 {
00539 if ((vec_it = find(neiIndexes.begin(), neiIndexes.end(), v_it.Position())) == neiIndexes.end())
00540 {
00541
00542 std::vector<Base::Vector3f> NeiPnts;
00543 std::vector<unsigned long> nei;
00544 std::vector<unsigned int>::iterator nei_it;
00545 PntNei = vv_it[v_it.Position()];
00546 FacetNei = vf_it[v_it.Position()];
00547 ReorderNeighbourList(PntNei,FacetNei,nei,v_it.Position());
00548 std::vector<double> Angle;
00549 std::vector<double> Magnitude;
00550 Base::Vector3f CurrentPoint(*v_it);
00551 double TotAngle = 0;
00552 unsigned int NumOfNeighbour = PntNei.size();
00553 unsigned int i = 0;
00554
00555
00556 while (i < NumOfNeighbour)
00557 {
00558 if (i+1 != NumOfNeighbour)
00559 {
00560 Base::Vector3f CurrentNeighbour(LocalMesh.GetPoint(nei[i]));
00561 Base::Vector3f NextNeighbour(LocalMesh.GetPoint(nei[i+1]));
00562 double ang = CalcAngle(CurrentNeighbour, CurrentPoint, NextNeighbour);
00563 double magn = sqrt((CurrentNeighbour - CurrentPoint) * (CurrentNeighbour - CurrentPoint));
00564 Angle.push_back(ang);
00565 Magnitude.push_back(magn);
00566 TotAngle += ang;
00567 i++;
00568 }
00569 else
00570 {
00571 Base::Vector3f CurrentNeighbour(LocalMesh.GetPoint(nei[i]));
00572 Base::Vector3f NextNeighbour(LocalMesh.GetPoint(nei[0]));
00573 double ang = CalcAngle(CurrentNeighbour, CurrentPoint, NextNeighbour);
00574 double magn = sqrt((CurrentNeighbour - CurrentPoint) * (CurrentNeighbour - CurrentPoint));
00575 Angle.push_back(ang);
00576 Magnitude.push_back(magn);
00577 TotAngle += ang;
00578 i++;
00579 }
00580
00581 }
00582
00583
00584
00585 Base::Vector3f CurrentNeighbour(Magnitude[0],0.0,0.0);
00586 NeiPnts.push_back(CurrentNeighbour);
00587 double alpha = 0;
00588 unsigned int k = 0;
00589 for (unsigned int i = 1; i < NumOfNeighbour; i++)
00590 {
00591 alpha = alpha + ((2 * D_PI * Angle[i-1]) / TotAngle);
00592 double x_pnt = Magnitude[i] * cos(alpha), y_pnt = Magnitude[i] * sin(alpha);
00593 Base::Vector3f NewPoint(x_pnt,y_pnt,0.0);
00594 NeiPnts.push_back(NewPoint);
00595 ++k;
00596
00597 }
00598 k = 0;
00599
00600 std::vector< std::vector<double> > Mu(NumOfNeighbour, std::vector<double>(NumOfNeighbour, 0.0));
00601 std::vector< std::vector<double> > MMatrix(2, std::vector<double>(2,0.0));
00602 std::vector<double> bMatrix(2,0.0);
00603 std::vector<double> lMatrix(2,0.0);
00604 if (NumOfNeighbour > 3)
00605 {
00606 for (k = 0; k < NumOfNeighbour;k++)
00607 {
00608 for (unsigned int l = k+1; l < NumOfNeighbour+k; l++)
00609 {
00610 MMatrix[0][0] = NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][0] -
00611 NeiPnts[(unsigned int)fmod((double)l-1,(double)NumOfNeighbour)][0];
00612 MMatrix[1][0] = NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][1] -
00613 NeiPnts[(unsigned int)fmod((double)l-1,(double)NumOfNeighbour)][1];
00614 MMatrix[0][1] = NeiPnts[k][0];
00615 MMatrix[1][1] = NeiPnts[k][1];
00616
00617 bMatrix[0] = -NeiPnts[(unsigned int)fmod((double)l-1,(double)NumOfNeighbour)][0];
00618 bMatrix[1] = -NeiPnts[(unsigned int)fmod((double)l-1,(double)NumOfNeighbour)][1];
00619
00620 if (det2(MMatrix) != 0)
00621 {
00622 CramerSolve(MMatrix, bMatrix, lMatrix);
00623 if (lMatrix[0] <= 1.00001f && lMatrix[0] >= 0.0f && lMatrix[1] > 0.0f)
00624 {
00625 unsigned int r = (unsigned int)fmod((double)l-1,(double)NumOfNeighbour);
00626 MMatrix[0][0] = NeiPnts[k][0] -
00627 NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][0];
00628 MMatrix[1][0] = NeiPnts[k][1] -
00629 NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][1];
00630 MMatrix[0][1] = NeiPnts[(unsigned int)fmod((double)l-1,(double)NumOfNeighbour)][0] -
00631 NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][0];
00632 MMatrix[1][1] = NeiPnts[(unsigned int)fmod((double)l-1,(double)NumOfNeighbour)][1] -
00633 NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][1];
00634
00635 bMatrix[0] = -NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][0];
00636 bMatrix[1] = -NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][1];
00637 CramerSolve(MMatrix, bMatrix, lMatrix);
00638
00639 Mu[k][k] = fabs(lMatrix[0]);
00640 Mu[r][k] = fabs(lMatrix[1]);
00641 if ((unsigned int)fmod((double)r,(double)NumOfNeighbour)+1 == NumOfNeighbour)
00642 Mu[0][k] = 1 -lMatrix[0] - lMatrix[1];
00643 else
00644 Mu[(unsigned int)fmod((double)r,(double)NumOfNeighbour)+1][k] = 1 -lMatrix[0] - lMatrix[1];
00645 break;
00646
00647 }
00648 }
00649 }
00650 }
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666 for (unsigned int j = 0; j < NumOfNeighbour; j++)
00667 {
00668 double sum = 0;
00669 for (unsigned int k = 0; k < NumOfNeighbour; k++)
00670 sum += Mu[j][k];
00671
00672 Lambda(count,mapper[nei[j]]) = sum/NumOfNeighbour;
00673 }
00674 count++;
00675 }
00676 else if (NumOfNeighbour == 3)
00677 {
00678 Base::Vector3f Point1(NeiPnts[0]);
00679 Base::Vector3f Point2(NeiPnts[1]);
00680 Base::Vector3f Point3(NeiPnts[2]);
00681 Base::Vector3f Zeroes(0,0,0);
00682 double A = AreaTriangle(Point1,Point2,Point3);
00683
00684 Lambda(count,mapper[nei[0]]) =
00685 AreaTriangle(Zeroes,Point2,Point3) / A;
00686
00687 Lambda(count,mapper[nei[1]]) =
00688 AreaTriangle(Point1,Zeroes,Point3) / A;
00689
00690 Lambda(count,mapper[nei[2]]) =
00691 AreaTriangle(Point1,Point2,Zeroes) / A;
00692
00693 count++;
00694 }
00695 else
00696 {
00697 throw Base::Exception("Something's wrong here. Less than 3 Neighbour");
00698 }
00699 }
00700 }
00701
00702
00703
00704 std::cout << "Splitting the lambdas..." << std::endl;
00705 ublas::compressed_matrix<double, ublas::column_major, 0, ublas::unbounded_array<int>, ublas::unbounded_array<double> >
00706 UpperTerm(NumOfInnerPoints, NumOfInnerPoints);
00707 ublas::compressed_matrix<double, ublas::column_major> OutLambda(NumOfInnerPoints, NumOfOuterPoints);
00708
00709
00710 for (int i = 0; i < NumOfInnerPoints; i++)
00711 {
00712 for (int j = 0; j < NumOfInnerPoints; j++)
00713 {
00714 if (Lambda(i,j) != 0)
00715 UpperTerm(i,j) = -Lambda(i,j);
00716 else if (i == j)
00717 UpperTerm(i,j) = 1.0 - Lambda(i,j);
00718 }
00719 }
00720
00721 for (int j = NumOfInnerPoints, k = 0; j < NumOfPoints; j++, k++)
00722 {
00723 for (int i = 0; i < NumOfInnerPoints; i++)
00724 {
00725 if (Lambda(i,j) != 0)
00726 OutLambda(i,k) = Lambda(i,j);
00727 }
00728 }
00729
00730
00731 ublas::vector<double> xResult(NumOfInnerPoints);
00732 ublas::vector<double> MultResult(NumOfInnerPoints);
00733 ublas::vector<double> yResult(NumOfInnerPoints);
00734
00735 ofstream anOutputFile;
00736 anOutputFile.open("c:/approx_param_log.txt");
00737 anOutputFile << 1 << endl;
00738
00739 std::cout << "Solving the X Term..." << std::endl;
00740
00741 ublas::axpy_prod(OutLambda, ParameterX, MultResult);
00742 anOutputFile << 2 << endl;
00743 bindings::umfpack::umf_solve (UpperTerm, xResult,MultResult );
00744 anOutputFile << 3 << endl;
00745
00746 std::cout << "Solving the Y Term..." << std::endl;
00747 ublas::axpy_prod(OutLambda, ParameterY, MultResult);
00748 anOutputFile << 4 << endl;
00749 bindings::umfpack::umf_solve (UpperTerm, yResult, MultResult);
00750 anOutputFile << 5 << endl;
00751 std::cout << "Replacing the results.." << std::endl;
00752
00753
00754
00755
00756 unsigned int s = 0;
00757 unsigned int b = 0;
00758
00759 ublas::vector<double> tempox = ParameterX;
00760 ublas::vector<double> tempoy = ParameterY;
00761 ParameterX.clear(), ParameterX.resize(NumOfPoints);
00762 ParameterY.clear(), ParameterY.resize(NumOfPoints);
00763 UnparamX.resize(NumOfPoints), UnparamY.resize(NumOfPoints),UnparamZ.resize(NumOfPoints);
00764
00765 anOutputFile << 6 << endl;
00766 std::vector <unsigned long> boundarieslist = *bInd;
00767
00768 anOutputFile << 7 << endl;
00769
00770
00771
00772
00773 MeshParam = LocalMesh;
00774 MeshCore::MeshPointArray pntArr= MeshParam.GetPoints();
00775 MeshCore::MeshFacetArray fctArr= MeshParam.GetFacets();
00776
00777
00778
00779 for (v_it.Begin(); !v_it.EndReached(); ++v_it)
00780 {
00781 anOutputFile << 0 << endl;
00782
00783 if ((vec_it = find(boundarieslist.begin(), boundarieslist.end(), v_it.Position())) == boundarieslist.end())
00784 {
00785 ParameterX[s] = xResult[s];
00786 ParameterY[s] = yResult[s];
00787
00788 pntArr[v_it.Position()].x = ParameterX[s];
00789 pntArr[v_it.Position()].y = ParameterY[s];
00790 pntArr[v_it.Position()].z = 0;
00791
00792 UnparamX[s] = LocalMesh.GetPoint(v_it.Position())[0];
00793 UnparamY[s] = LocalMesh.GetPoint(v_it.Position())[1];
00794 UnparamZ[s] = LocalMesh.GetPoint(v_it.Position())[2];
00795 s++;
00796 }
00797
00798 else
00799 {
00800 ParameterX[NumOfInnerPoints+b] = tempox[b];
00801 ParameterY[NumOfInnerPoints+b] = tempoy[b];
00802
00803 pntArr[v_it.Position()].x = ParameterX[NumOfInnerPoints+b];
00804 pntArr[v_it.Position()].y = ParameterY[NumOfInnerPoints+b];
00805 pntArr[v_it.Position()].z = 0;
00806
00807 UnparamX[NumOfInnerPoints+b] = LocalMesh.GetPoint(v_it.Position())[0];
00808 UnparamY[NumOfInnerPoints+b] = LocalMesh.GetPoint(v_it.Position())[1];
00809 UnparamZ[NumOfInnerPoints+b] = LocalMesh.GetPoint(v_it.Position())[2];
00810 b++;
00811 }
00812 }
00813
00814 anOutputFile << 8 << endl;
00815 MeshParam.Assign(pntArr,fctArr);
00816 anOutputFile << 9 << endl;
00817
00818 std::cout << "DONE" << std::endl;
00819 std::cout << "Information about the meshes:-" << std::endl;
00820 std::cout << "Number of Points: " << NumOfPoints << std::endl;
00821 std::cout << "Number of Inner Points: " << NumOfInnerPoints << std::endl;
00822 std::cout << "Number of Outer Points: " << NumOfOuterPoints << std::endl;
00823
00824 ParameterMesh.Clear();
00825 anOutputFile << 10 << endl;
00826 LocalMesh.Clear();
00827 anOutputFile << 11 << endl;
00828 anOutputFile.close();
00829
00830 }
00831
00832
00837 void Approximate::ErrorApprox()
00838 {
00839 ofstream anOutputFile;
00840 anOutputFile.open("c:/approx_param_log.txt");
00841
00842 anOutputFile << "Begin constructing NURB for first pass" << std::endl;
00843 double max_err = 0;
00844 bool ErrThere = true;
00845 int h = 0;
00846 int cnt = 0;
00847 double av = 0, c2 = 0;
00848 double lam;
00849
00850 anOutputFile << "Constructing" << std::endl;
00851 ublas::matrix<double> C_Temp(NumOfPoints,3);
00852 anOutputFile << "C_Temp succesfully constructed" << std::endl;
00853
00854
00855 anOutputFile << "number of points: " << NumOfPoints << std::endl;
00856 std::vector <double> err_w(NumOfPoints);
00857 anOutputFile << "checkpoint 1 " << std::endl;
00858 for (int i=1; i<NumOfPoints; i++)
00859 err_w[i] = 1;
00860
00861 anOutputFile << "checkpoint 2 " << std::endl;
00862 int g = 1;
00863
00864 while(ErrThere)
00865 {
00866 anOutputFile << "checkpoint 3 " << std::endl;
00867 anOutputFile << "checkpoint 3 " << std::endl;
00868 anOutputFile << "size(B_Matrix): " << NumOfPoints << " x " << (MainNurb.MaxU+1)*(MainNurb.MaxV+1) << std::endl;
00869 ublas::matrix<double> B_Matrix(NumOfPoints,(MainNurb.MaxU+1)*(MainNurb.MaxV+1));
00870 anOutputFile << "********************************" << endl;
00871 anOutputFile << "B_Matrix succesfully constructed" << std::endl;
00872 anOutputFile << "Preparing B-Matrix..." << std::endl;
00873
00874 std::vector<double> N_u(MainNurb.MaxU+1, 0.0);
00875 std::vector<double> N_v(MainNurb.MaxV+1, 0.0);
00876 std::vector<double> TempU(MainNurb.DegreeU+1, 0.0);
00877 std::vector<double> TempV(MainNurb.DegreeV+1, 0.0);
00878 std::vector<double> swapDegreeU(MainNurb.DegreeU+1, 0.0);
00879 std::vector<double> swapDegreeV(MainNurb.DegreeV+1, 0.0);
00880 std::vector<double> swapV(MainNurb.MaxV+1, 0.0);
00881 std::vector<double> swapU(MainNurb.MaxU+1, 0.0);
00882
00883 for (int i = 0; i < NumOfPoints; i++)
00884 {
00885 std::vector<double> N_u(MainNurb.MaxU+1, 0.0);
00886 std::vector<double> N_v(MainNurb.MaxV+1, 0.0);
00887 std::vector<double> TempU(MainNurb.DegreeU+1, 0.0);
00888 std::vector<double> TempV(MainNurb.DegreeV+1, 0.0);
00889
00890 int j1 = FindSpan(MainNurb.MaxU, MainNurb.DegreeU, ParameterX[i], MainNurb.KnotU);
00891 int j2 = FindSpan(MainNurb.MaxV, MainNurb.DegreeV, ParameterY[i], MainNurb.KnotV);
00892
00893
00894 Basisfun(j1,ParameterX[i], MainNurb.DegreeU, MainNurb.KnotU, TempU);
00895 Basisfun(j2,ParameterY[i], MainNurb.DegreeV, MainNurb.KnotV, TempV);
00896
00897 for (int k = j1 - MainNurb.DegreeU, s = 0; k < j1+1; k++, s++)
00898 N_u[k] = TempU[s];
00899 for (int k = j2 - MainNurb.DegreeV, s = 0; k < j2+1; k++, s++)
00900 N_v[k] = TempV[s];
00901
00902 for (int j = 0; j <= MainNurb.MaxV; j++)
00903 {
00904 for (int h = 0; h <= MainNurb.MaxU; h++)
00905 {
00906
00907 B_Matrix(i,(j*(MainNurb.MaxU+1))+h) = sqrt(err_w[i]) * N_u[h] * N_v[j];
00908 }
00909 }
00910 }
00911
00912 for (unsigned int i = 0; i < UnparamX.size(); ++i)
00913 {
00914 C_Temp(i,0) = sqrt(err_w[i])*UnparamX[i];
00915 C_Temp(i,1) = sqrt(err_w[i])*UnparamY[i];
00916 C_Temp(i,2) = sqrt(err_w[i])*UnparamZ[i];
00917 }
00918
00919 ublas::matrix<double> G_Matrix((MainNurb.MaxU+1)*(MainNurb.MaxV+1),(MainNurb.MaxU+1)*(MainNurb.MaxV+1));
00920 ublas::matrix<double> C_Tempo((MainNurb.MaxU+1)*(MainNurb.MaxV+1),3);
00921 atlas::gemm(CblasTrans, CblasNoTrans, 1.0, B_Matrix,C_Temp,0.0,C_Tempo);
00922 atlas::gemm(CblasTrans,CblasNoTrans,1.0,B_Matrix,B_Matrix,0.0,G_Matrix);
00923
00924 B_Matrix.resize(1,1,false);
00925 B_Matrix.clear();
00926
00927 anOutputFile << "Preparing the A_Matrix" << std::endl;
00928
00929 ublas::compressed_matrix<double, ublas::column_major, 0, ublas::unbounded_array<int>, ublas::unbounded_array<double> >
00930 A_Matrix((MainNurb.MaxU+1)*(MainNurb.MaxV+1),(MainNurb.MaxU+1)*(MainNurb.MaxV+1));
00931 anOutputFile << "Multiply..." << std::endl;
00932
00933 anOutputFile << "Euclidean Norm" << std::endl;
00934 A_Matrix = G_Matrix;
00935
00936 if(cnt == 0)
00937 lam = 10*ublas::norm_frobenius(G_Matrix);
00938 else
00939 lam /= 2;
00940
00941 G_Matrix.resize(1,1, false);
00942 G_Matrix.clear();
00943 ublas::compressed_matrix<double> E_Matrix((MainNurb.MaxU+1)*(MainNurb.MaxV+1), (MainNurb.MaxU+1)*(MainNurb.MaxV+1));
00944 anOutputFile << "E_Matrix succesfully constructed" << std::endl;
00945 anOutputFile << "Smoothing..." << std::endl;
00946 eFair2(E_Matrix);
00947
00948 if(cnt == 0){
00949 lam = lam / ublas::norm_frobenius(E_Matrix);
00950 }
00951
00952 ++cnt;
00953
00954 anOutputFile << "lam: " << lam << std::endl;
00955 A_Matrix = A_Matrix + (E_Matrix*lam);
00956
00957
00958 E_Matrix.resize(1,1,false);
00959 E_Matrix.clear();
00960 anOutputFile << "Preparing the C_Matrix" << std::endl;
00961 std::vector< std::vector<double> > Solver;
00962 std::vector<double> TempoSolv((MainNurb.MaxU+1)*(MainNurb.MaxV+1));
00963 std::vector<double> TempoB;
00964
00965 anOutputFile << "Solving" << std::endl;
00966 for (unsigned int i = 0; i < 3; i++)
00967
00968 {
00969
00970 for (int j = 0; j < (MainNurb.MaxU+1)*(MainNurb.MaxV+1); j++)
00971 TempoB.push_back(C_Tempo(j,i));
00972
00973 umfpack::umf_solve(A_Matrix,TempoSolv,TempoB);
00974 Solver.push_back(TempoSolv);
00975 TempoB.clear();
00976 }
00977 MainNurb.CntrlArray.clear();
00978 anOutputFile << "Loading the Control Points" << std::endl;
00979 for (int i = 0; i < (MainNurb.MaxU+1)*(MainNurb.MaxV+1); i++)
00980 {
00981 MainNurb.CntrlArray.push_back(Solver[0][i]);
00982 MainNurb.CntrlArray.push_back(Solver[1][i]);
00983 MainNurb.CntrlArray.push_back(Solver[2][i]);
00984 }
00985
00986 std::vector<double> ContrArr = MainNurb.CntrlArray;
00987
00988 anOutputFile << "Cntrl Count" << std::endl;
00989 anOutputFile << "U: " << MainNurb.MaxU + 1 << std::endl;
00990 anOutputFile << "V: " << MainNurb.MaxV + 1 << std::endl;
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000 anOutputFile << "Reparameterize ..." << std::endl;
01001 av = Reparam();
01002 anOutputFile << "End Reparameterize" << std::endl;
01003 anOutputFile << "Average error: " << av << std::endl;
01004
01005 if (av <= tolerance)
01006 ErrThere = false;
01007 }
01008
01009 anOutputFile.close();
01010 }
01011
01014 void Approximate::eFair2(ublas::compressed_matrix<double> &E_Matrix)
01015 {
01016 ofstream anOutputFile;
01017 anOutputFile.open("c:/approx_param_log_efair.txt");
01018
01019 int precision = 100;
01020 std::vector<double> U(precision+1, 0);
01021 std::vector<double> V(precision+1, 0);
01022 for (int i = 1; i <= precision; i++)
01023 {
01024 U[i] = (1.0/(double)precision) + U[i-1];
01025 V[i] = (1.0/(double)precision) + V[i-1];
01026 }
01027 U[precision] = 1.0;
01028 V[precision] = 1.0;
01029 precision = precision + 1;
01030
01031 int mu = MainNurb.MaxKnotU;
01032 int mv = MainNurb.MaxKnotV;
01033 int k = mu-MainNurb.MaxU-2;
01034 int l = mv-MainNurb.MaxV-2;
01035
01036 std::vector< std::vector<double> > N_u0(precision, std::vector<double>(mu-1-k,0.0));
01037 std::vector< std::vector<double> > N_u1(precision, std::vector<double>(mu-1-k,0.0));
01038 std::vector< std::vector<double> > N_u2(precision, std::vector<double>(mu-1-k,0.0));
01039 std::vector< std::vector<double> > N_v0(precision, std::vector<double>(mu-1-l,0.0));
01040 std::vector< std::vector<double> > N_v1(precision, std::vector<double>(mu-1-l,0.0));
01041 std::vector< std::vector<double> > N_v2(precision, std::vector<double>(mu-1-l,0.0));
01042
01043 std::vector<double> A_1(precision,0.0);
01044 std::vector<double> B_1(precision,0.0);
01045 std::vector<double> C_1(precision,0.0);
01046 std::vector<double> A_2(precision,0.0);
01047 std::vector<double> B_2(precision,0.0);
01048 std::vector<double> C_2(precision,0.0);
01049
01050
01051 for (int i = 0; i < precision; i++)
01052 {
01053 std::vector< std::vector<double> > dersU(2+1, std::vector<double>(k+1));
01054 std::vector< std::vector<double> > dersV(2+1, std::vector<double>(k+1));
01055 int s = FindSpan(MainNurb.MaxU, k, U[i], MainNurb.KnotU);
01056 DersBasisFuns(s, U[i], k, 2, MainNurb.KnotU, dersU);
01057 for (int a = s-k, b = 0; a < s+1; a++, b++)
01058 {
01059 N_u0[i][a] = dersU[0][b];
01060 N_u1[i][a] = dersU[1][b];
01061 N_u2[i][a] = dersU[2][b];
01062 }
01063
01064 s = FindSpan(MainNurb.MaxV, l, V[i], MainNurb.KnotV);
01065 DersBasisFuns(s, V[i], l, 2, MainNurb.KnotV, dersV);
01066 for (int a = s-l, b = 0; a < s+1; a++, b++)
01067 {
01068 N_v0[i][a] = dersV[0][b];
01069 N_v1[i][a] = dersV[1][b];
01070 N_v2[i][a] = dersV[2][b];
01071 }
01072
01073 }
01074
01075 double A,B,C;
01076
01077 for (int a = 0; a < MainNurb.MaxV+1; a++)
01078 {
01079
01080
01081 for (int b = 0; b < MainNurb.MaxU+1; b++)
01082 {
01083 for (int c = 0; c < MainNurb.MaxV+1; c++)
01084 {
01085
01086 for (int d = 0; d < MainNurb.MaxU+1; d++)
01087 {
01088 for (int w = 0; w < precision; w++)
01089 {
01090 A_1[w] = (N_u2[w][b]*N_u2[w][d]);
01091 A_2[w] = (N_v0[w][a]*N_v0[w][c]);
01092
01093 B_1[w] = (N_u1[w][b]*N_u1[w][d]);
01094 B_2[w] = (N_v1[w][a]*N_v1[w][c]);
01095
01096 C_1[w] = (N_u0[w][b]*N_u0[w][d]);
01097 C_2[w] = (N_v2[w][a]*N_v2[w][c]);
01098 }
01099
01100
01101
01102
01103 A = TrapezoidIntergration(U, A_1);
01104 A *= TrapezoidIntergration(U, A_2);
01105
01106 B = TrapezoidIntergration(U, B_1);
01107 B *= TrapezoidIntergration(U, B_2);
01108
01109 C = TrapezoidIntergration(U, C_1);
01110 C *= TrapezoidIntergration(U, C_2);
01111
01112
01113 E_Matrix((a*(MainNurb.MaxU+1))+b,(c*(MainNurb.MaxV+1))+d) = A + 2*B + C;
01114 }
01115 }
01116 }
01117 }
01118 anOutputFile << std::endl;
01119 anOutputFile.close();
01120 }
01121
01124 void Approximate::ComputeError(int &h, double eps_1, double eps_2, double &max_error,
01125 double &av, double &c2, std::vector <double> &err_w)
01126 {
01127 std::cout << "Computing Error..." << std::endl;
01128 av = 0;
01129 c2 = 0;
01130 max_error = 0;
01131 for (int i = 0; i < NumOfPoints; i++)
01132 {
01133
01134 std::vector<NURBS> DerivNurb;
01135 std::vector<NURBS> DerivUNurb;
01136 std::vector<NURBS> DerivVNurb;
01137 std::vector<std::vector<double> > Jac;
01138 std::vector<double> CurPoint;
01139 CurPoint.push_back(ParameterX[i]);
01140 CurPoint.push_back(ParameterY[i]);
01141 std::vector<double> V(2,0.0);
01142 V[0] = CurPoint[0];
01143 V[1] = CurPoint[1];
01144 unsigned int j = 0;
01145 PointNrbDerivate(MainNurb, DerivNurb);
01146 PointNrbDerivate(DerivNurb[0], DerivUNurb);
01147 PointNrbDerivate(DerivNurb[1], DerivVNurb);
01148 int c = 0;
01149 std::vector<double> error;
01150 std::vector<double> EvalPoint;
01151
01152 NrbDEval(MainNurb, DerivNurb, CurPoint, EvalPoint, Jac);
01153 EvalPoint[0] = EvalPoint[0] - UnparamX[i];
01154 EvalPoint[1] = EvalPoint[1] - UnparamY[i];
01155 EvalPoint[2] = EvalPoint[2] - UnparamZ[i];
01156 ublas::matrix<double> EvalMat(1, EvalPoint.size());
01157 for (j = 0; j < 3; j++)
01158 EvalMat(0,j) = EvalPoint[j];
01159 for (j = 0; j < 2; j++)
01160 {
01161 ublas::matrix<double> Holder(1, 1);
01162 ublas::matrix<double> JacPoint(Jac[j].size(), 1);
01163 for (unsigned int k = 0; k < Jac[j].size(); k++)
01164 JacPoint(k,0) = Jac[j][k];
01165
01166 atlas::gemm(CblasTrans, CblasTrans, 1.0, JacPoint,EvalMat,0.0,Holder);
01167 double lam = ublas::norm_frobenius(JacPoint) * ublas::norm_frobenius(EvalMat);
01168 if (lam == 0)
01169 throw "Division by Zero in ComputeError function";
01170 lam = fabs(Holder(0,0) / lam);
01171 error.push_back(lam);
01172 }
01173
01174 while (((norm_frobenius(EvalMat) > eps_1) && ((error[0] > eps_2) || (error[1] > eps_2))) && c < 1000)
01175 {
01176 c += 1;
01177 std::vector<double> p_uu;
01178 std::vector<double> p_uv;
01179 std::vector<double> p_vu;
01180 std::vector<double> p_vv;
01181 ublas::matrix<double> P_UU(3, 1);
01182 ublas::matrix<double> P_UV(3, 1);
01183 ublas::matrix<double> P_VU(3, 1);
01184 ublas::matrix<double> P_VV(3, 1);
01185 ublas::matrix<double> JacPoint1(Jac[0].size(), 1);
01186 ublas::matrix<double> JacPoint2(Jac[0].size(), 1);
01187 PointNrbEval(p_uu,CurPoint,DerivUNurb[0]);
01188 PointNrbEval(p_uv,CurPoint,DerivUNurb[1]);
01189 PointNrbEval(p_vu,CurPoint,DerivVNurb[0]);
01190 PointNrbEval(p_vv,CurPoint,DerivVNurb[1]);
01191
01192
01193
01194 for (unsigned int a = 0; a < Jac[0].size();a++)
01195 JacPoint1(a,0) = Jac[0][a];
01196 for (unsigned int a = 0; a < Jac[1].size();a++)
01197 JacPoint2(a,0) = Jac[1][a];
01198 for (unsigned int a = 0; a < 3; a++)
01199 {
01200 P_UU(a,0) = p_uu[a];
01201 P_UV(a,0) = p_uv[a];
01202 P_VU(a,0) = p_vu[a];
01203 P_VV(a,0) = p_vv[a];
01204 }
01205
01206 std::vector< std::vector<double> > J(2, std::vector<double>(2,0.0));
01207 std::vector<double> K(2,0.0);
01208
01209
01210 ublas::matrix<double> MultResult(1,1);
01211 atlas::gemm(CblasTrans, CblasNoTrans, 1.0, JacPoint1,JacPoint1,0.0,MultResult);
01212 J[0][0] += MultResult(0,0);
01213 atlas::gemm(CblasNoTrans, CblasNoTrans, 1.0, EvalMat,P_UU,0.0,MultResult);
01214 J[0][0] += MultResult(0,0);
01215
01216
01217 atlas::gemm(CblasTrans, CblasNoTrans, 1.0, JacPoint1,JacPoint2,0.0,MultResult);
01218 J[0][1] += MultResult(0,0);
01219 atlas::gemm(CblasNoTrans, CblasNoTrans, 1.0, EvalMat,P_UV,0.0,MultResult);
01220 J[0][1] += MultResult(0,0);
01221
01222
01223 atlas::gemm(CblasTrans, CblasNoTrans, 1.0, JacPoint1,JacPoint2,0.0,MultResult);
01224 J[1][0] += MultResult(0,0);
01225 atlas::gemm(CblasNoTrans, CblasNoTrans, 1.0, EvalMat,P_VU,0.0,MultResult);
01226 J[1][0] += MultResult(0,0);
01227
01228
01229 atlas::gemm(CblasTrans, CblasNoTrans, 1.0, JacPoint2,JacPoint2,0.0,MultResult);
01230 J[1][1] += MultResult(0,0);
01231 atlas::gemm(CblasNoTrans, CblasNoTrans, 1.0, EvalMat,P_VV,0.0,MultResult);
01232 J[1][1] += MultResult(0,0);
01233
01234
01235 atlas::gemm(CblasNoTrans, CblasNoTrans, 1.0, EvalMat,JacPoint1,0.0,MultResult);
01236 K[0] = (J[0][0]*V[0]) + (J[0][1]*V[1]) - MultResult(0,0);
01237
01238
01239 atlas::gemm(CblasNoTrans, CblasNoTrans, 1.0, EvalMat,JacPoint2,0.0,MultResult);
01240 K[1] = (J[1][0]*V[0]) + (J[1][1]*V[1]) - MultResult(0,0);
01241
01242 CramerSolve(J,K,V);
01243
01244 if (V[0] < 0)
01245 V[0] = 0;
01246 else if (V[0] > 1)
01247 V[0] = 1;
01248
01249 if (V[1] < 0)
01250 V[1] = 0;
01251 else if (V[1] > 1)
01252 V[1] = 1;
01253
01254 if (c == 500)
01255 {
01256 V[0] = 0.5;
01257 V[1] = 0.5;
01258 }
01259
01260 error.clear();
01261 CurPoint[0] = V[0];
01262 CurPoint[1] = V[1];
01263 EvalPoint.clear();
01264 Jac.clear();
01265 NrbDEval(MainNurb, DerivNurb, CurPoint, EvalPoint, Jac);
01266 EvalPoint[0] = EvalPoint[0] - UnparamX[i];
01267 EvalPoint[1] = EvalPoint[1] - UnparamY[i];
01268 EvalPoint[2] = EvalPoint[2] - UnparamZ[i];
01269 for (j = 0; j < 3; j++)
01270 EvalMat(0,j) = EvalPoint[j];
01271 for (j = 0; j < 2; j++)
01272 {
01273 ublas::matrix<double> Holder(1, 1);
01274 ublas::matrix<double> JacPoint(Jac[j].size(), 1);
01275 for (unsigned int k = 0; k < Jac[j].size(); k++)
01276 JacPoint(k,0) = Jac[j][k];
01277
01278 atlas::gemm(CblasTrans, CblasTrans, 1.0, JacPoint,EvalMat,0.0,Holder);
01279 double lam = ublas::norm_frobenius(JacPoint) * ublas::norm_frobenius(EvalMat);
01280 if (lam == 0)
01281 throw "Division by Zero in ComputeError function";
01282 else
01283 lam = fabs(Holder(0,0) / lam);
01284 error.push_back(lam);
01285 }
01286 }
01287 ParameterX[i] = V[0];
01288 ParameterY[i] = V[1];
01289 av += norm_frobenius(EvalMat);
01290
01291 err_w[i] = norm_frobenius(EvalMat);
01292
01293 if (norm_frobenius(EvalMat) > max_error && c < 1000)
01294 {
01295 max_error = norm_frobenius(EvalMat);
01296 h = i;
01297
01298
01299
01300 }
01301 if (norm_frobenius(EvalMat) > tolerance)
01302 c2++;
01303 }
01304 c2 /= NumOfPoints;
01305 av /= NumOfPoints;
01306
01307 std::cout << " DONE" << std::endl;
01308 }
01309
01312 double Approximate::Reparam()
01313 {
01314 MeshCore::MeshPointArray pntArr = MeshParam.GetPoints();
01315 MeshCore::MeshFacetArray fctArr = MeshParam.GetFacets();
01316
01317 double error = 0.0;
01318
01319 std::cout << "Reparameterization...";
01320 for (int i = 0; i < NumOfPoints; i++)
01321 {
01322 std::vector<NURBS> DerivNurb;
01323 std::vector<double> p;
01324 std::vector<double> EvalPoint;
01325 std::vector< std::vector<double> > T;
01326 std::vector< std::vector<double> > A(2,std::vector<double>(2,0.0));
01327 std::vector<double> bt(2,0.0);
01328
01329 p.push_back(ParameterX[i]);
01330 p.push_back(ParameterY[i]);
01331 PointNrbDerivate(MainNurb, DerivNurb);
01332 NrbDEval(MainNurb, DerivNurb, p, EvalPoint, T);
01333
01334 EvalPoint[0] = UnparamX[i] - EvalPoint[0];
01335 EvalPoint[1] = UnparamY[i] - EvalPoint[1];
01336 EvalPoint[2] = UnparamZ[i] - EvalPoint[2];
01337
01338 error += sqrt(EvalPoint[0]*EvalPoint[0] + EvalPoint[1]*EvalPoint[1] + EvalPoint[2]*EvalPoint[2]);
01339
01340 for (int j = 0; j < 2; j++)
01341 {
01342 for (int k = 0; k < 2; k++)
01343 {
01344 std::vector<double> JacHolder1(3, 0.0);
01345 std::vector<double> JacHolder2(3, 0.0);
01346 std::vector<double> Result(1, 0.0);
01347 if (j == 0 && k == 0)
01348 {
01349 for (int l = 0; l < 3; l++)
01350 {
01351 JacHolder1[l] = T[0][l];
01352 JacHolder2[l] = T[0][l];
01353 }
01354 cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,1,1,3,1.0,
01355 &JacHolder1[0],3,&JacHolder2[0],1,0.0,&Result[0], 1);
01356
01357 A[j][k] = Result[0];
01358 }
01359 else if (j == 1 && k == 1)
01360 {
01361 for (int l = 0; l < 3; l++)
01362 {
01363 JacHolder1[l] = T[1][l];
01364 JacHolder2[l] = T[1][l];
01365 }
01366 cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,1,1,3,1.0,
01367 &JacHolder1[0],3,&JacHolder2[0],1,0.0,&Result[0], 1);
01368
01369 A[j][k] = Result[0];
01370 }
01371 else
01372 {
01373 for (int l = 0; l < 3; l++)
01374 {
01375 JacHolder1[l] = T[0][l];
01376 JacHolder2[l] = T[1][l];
01377 }
01378 cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,1,1,3,1.0,
01379 &JacHolder1[0],3,&JacHolder2[0],1,0.0,&Result[0], 1);
01380
01381 A[j][k] = Result[0];
01382 }
01383 }
01384 std::vector<double> Resultant(1, 0.0);
01385 std::vector<double> BJacHolder(3, 0.0);
01386 for (int l = 0; l < 3; l++)
01387 BJacHolder[l] = T[j][l];
01388 cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,1,1,3,1.0,
01389 &EvalPoint[0],3,&BJacHolder[0],1,0.0,&Resultant[0], 1);
01390
01391 bt[j] = Resultant[0];
01392
01393 }
01394
01395 std::vector<double> delt(2,0.0);
01396 CramerSolve(A,bt,delt);
01397
01398
01399 if (ParameterX[i] + delt[0] <= 0)
01400 ParameterX[i] = 0;
01401 else if (ParameterX[i] + delt[0] >= 1)
01402 ParameterX[i] = 1;
01403 else ParameterX[i] += delt[0];
01404
01405 if (ParameterY[i] + delt[1] <= 0)
01406 ParameterY[i] = 0;
01407 else if (ParameterY[i] + delt[1] >= 1)
01408 ParameterY[i] = 1;
01409 else ParameterY[i] += delt[1];
01410
01411 }
01412
01413 error /= NumOfPoints;
01414
01415 MeshCore::MeshPointIterator v_it(MeshParam);
01416 std::list< std::vector <unsigned long> >::iterator bInd = BoundariesIndex.begin();
01417 std::vector <unsigned long> boundarieslist = *bInd;
01418 std::vector <unsigned long>::iterator vec_it;
01419 int s=0;
01420 int b=0;
01421 for (v_it.Begin(); !v_it.EndReached(); ++v_it)
01422 {
01423
01424 if ((vec_it = find(boundarieslist.begin(), boundarieslist.end(), v_it.Position())) == boundarieslist.end())
01425 {
01426
01427 pntArr[v_it.Position()].x = ParameterX[s];
01428 pntArr[v_it.Position()].y = ParameterY[s];
01429 s++;
01430 }
01431
01432 else
01433 {
01434
01435 pntArr[v_it.Position()].x = ParameterX[NumOfInnerPoints+b];
01436 pntArr[v_it.Position()].y = ParameterY[NumOfInnerPoints+b];
01437
01438 b++;
01439 }
01440 }
01441
01442
01443 MeshParam.Assign(pntArr,fctArr);
01444 std::cout << "DONE" << std::endl;
01445 return error;
01446 }
01447
01453 void Approximate::ExtendNurb(double c2, int h)
01454 {
01455 std::cout << "Extending Knot Vector" << std::endl;
01456 std::cout << "Two knot extension" << std::endl;
01457 MainNurb.MaxU += 2;
01458 MainNurb.MaxV += 2;
01459 MainNurb.MaxKnotU += 2;
01460 MainNurb.MaxKnotV += 2;
01461
01462 ExtendKnot(ParameterX[h], MainNurb.DegreeU, MainNurb.MaxU, MainNurb.KnotU);
01463 ExtendKnot(ParameterY[h], MainNurb.DegreeV, MainNurb.MaxV, MainNurb.KnotV);
01464
01465 }
01466
01473 void Approximate::ReorderNeighbourList(std::set<unsigned long> &pnt,
01474 std::set<unsigned long> &face, std::vector<unsigned long> &nei, unsigned long CurInd)
01475 {
01476 MeshCore::MeshPointArray::_TConstIterator v_beg = LocalMesh.GetPoints().begin();
01477 MeshCore::MeshFacetArray::_TConstIterator f_beg = LocalMesh.GetFacets().begin();
01478 std::set<unsigned long>::iterator pnt_it;
01479 std::set<unsigned long>::iterator face_it;
01480 std::vector<unsigned long>::iterator vec_it;
01481 std::vector<unsigned long>::iterator ulong_it;
01482 unsigned long PrevIndex;
01483 pnt_it = pnt.begin();
01484 face_it = face.begin();
01485 nei.push_back(v_beg[*pnt_it]._ulProp);
01486 vec_it = nei.begin();
01487 PrevIndex = nei[0];
01488 for (unsigned int i = 1; i < pnt.size(); i++)
01489 {
01490 while (true)
01491 {
01492 std::vector<unsigned long> facetpnt;
01493 facetpnt.push_back(f_beg[*face_it]._aulPoints[0]);
01494 facetpnt.push_back(f_beg[*face_it]._aulPoints[1]);
01495 facetpnt.push_back(f_beg[*face_it]._aulPoints[2]);
01496 if ((ulong_it = find(facetpnt.begin(), facetpnt.end(), PrevIndex)) == facetpnt.end())
01497 {
01498
01499 ++face_it;
01500 continue;
01501 }
01502 else
01503 {
01504 for (unsigned int k = 0 ; k < 3; k++)
01505 {
01506
01507 if (((vec_it = find(nei.begin(), nei.end(), facetpnt[k])) == nei.end()) && facetpnt[k] != CurInd)
01508 {
01509 face.erase(face_it);
01510 nei.push_back(facetpnt[k]);
01511 PrevIndex = facetpnt[k];
01512 face_it = face.begin();
01513 break;
01514 }
01515 }
01516 break;
01517 }
01518 }
01519 }
01520 }