/*************************************************************************** * Copyright (c) 2007 * * Joachim Zettler * * Human Rezai * * Mohamad Najib Muhammad Noor * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ /*****************APPROX.CPP***************** * Contains implementations from Approx.h * * *********************************************/ /*********MAIN INCLUDES***********/ #include "PreCompiled.h" #include "Approx.h" #include #include #include #include #include #include #include #include #include /*************BOOST***************/ /********UBLAS********/ #include #include #include #include /*********BINDINGS********/ #include #include #include #include #include /*****ADDITIONAL FOR DEBUGGING*****/ //#include /*****NAMESPACE**/ using namespace boost::numeric::bindings; Approximate::Approximate(const MeshCore::MeshKernel &m,std::vector &_Cntrl, std::vector &_KnotU, std::vector &_KnotV, int &_OrderU, int &_OrderV, double tol) { MinX = 0, MinY = 0, MaxX = 0; MaxY = 0; tolerance = tol; int NumPnts = m.CountPoints(); //number of points to approximate Base::BoundBox3f bbox = m.GetBoundBox(); // get bounding box double x_len = bbox.LengthX(); double y_len = bbox.LengthY(); LocalMesh = m; //make a copy... //Initialize the NURB MainNurb.DegreeU = 3; MainNurb.DegreeV = 3; MainNurb.MaxU = std::max(MainNurb.DegreeU+1, (int)sqrt(double(NumPnts)*y_len/x_len)); MainNurb.MaxV = std::max(MainNurb.DegreeV+1, (int)sqrt(double(NumPnts)*x_len/y_len)); GenerateUniformKnot(MainNurb.MaxU,MainNurb.DegreeU,MainNurb.KnotU); GenerateUniformKnot(MainNurb.MaxV,MainNurb.DegreeV,MainNurb.KnotV); MainNurb.MaxKnotU = MainNurb.KnotU.size(); MainNurb.MaxKnotV = MainNurb.KnotV.size(); //GOTO Main program ApproxMain(); ofstream anOutputFile; anOutputFile.open("c:/approx_build_surface.txt"); anOutputFile << "start building surface" << endl; //Copying the Output //mesh = ParameterMesh; _Cntrl = MainNurb.CntrlArray; _KnotU = MainNurb.KnotU; _KnotV = MainNurb.KnotV; _OrderU = MainNurb.DegreeU + 1; _OrderV = MainNurb.DegreeV + 1; gp_Pnt pnt; TColgp_Array2OfPnt Poles(1,MainNurb.MaxU+1, 1,MainNurb.MaxV+1); for(int j=0; j< (MainNurb.MaxV+1); ++j) { for(int i=0; i < (MainNurb.MaxU+1); ++i) { pnt.SetX(_Cntrl[3*i + j*3*(MainNurb.MaxU+1)]); pnt.SetY(_Cntrl[3*i+1 + j*3*(MainNurb.MaxU+1)]); pnt.SetZ(_Cntrl[3*i+2 + j*3*(MainNurb.MaxU+1)]); Poles.SetValue(i+1,j+1,pnt); } } anOutputFile << "control points done" << endl; int c=1; for (unsigned int i=0; i<_KnotU.size()-1; ++i) { if (_KnotU[i+1] != _KnotU[i]) { ++c; } } TColStd_Array1OfReal UKnots(1,c); TColStd_Array1OfInteger UMults(1,c); c=1; for (unsigned int i=0; i<_KnotV.size()-1; ++i) { if (_KnotV[i+1] != _KnotV[i]) { ++c; } } TColStd_Array1OfReal VKnots(1,c); TColStd_Array1OfInteger VMults(1,c); int d=0; c=1; for (unsigned int i=0; i<_KnotU.size(); ++i) { if (_KnotU[i+1] != _KnotU[i]) { UKnots.SetValue(d+1,_KnotU[i]); UMults.SetValue(d+1,c); ++d; c=1; } else { ++c; } if (i==(_KnotU.size()-2)) { UKnots.SetValue(d+1,_KnotU[i+1]); UMults.SetValue(d+1,c); break; } } d=0; c=1; for (unsigned int i=0; i<_KnotV.size(); ++i) { if (_KnotV[i+1] != _KnotV[i]) { VKnots.SetValue(d+1,_KnotV[i]); VMults.SetValue(d+1,c); ++d; c=1; } else { ++c; } if (i==(_KnotV.size()-2)) { VKnots.SetValue(d+1,_KnotV[i+1]); VMults.SetValue(d+1,c); break; } } /*cout << "UKnots: " << endl; for(int i=0; i CornerIndex; std::vector Pointdistance; std::vector::iterator vec_it; std::vector ::iterator pnt_it; //Get BoundariesIndex and BoundariesPoints and extract it to v_neighbour algo.GetMeshBorders(BoundariesIndex); algo.GetMeshBorders(BoundariesPoints); std::list< std::vector >::iterator bInd = BoundariesIndex.begin(); std::list< std::vector >::iterator bPnt = BoundariesPoints.begin(); std::vector v_neighbour = *bInd; std::vector v_pnts = *bPnt; Base::BoundBox3f BoundBox = ParameterMesh.GetBoundBox(); //Resize the needed arrays NumOfOuterPoints = v_neighbour.size()-1; BoundariesX.resize(NumOfOuterPoints); BoundariesY.resize(NumOfOuterPoints); UnparamBoundariesX.resize(NumOfOuterPoints); UnparamBoundariesY.resize(NumOfOuterPoints); UnparamBoundariesZ.resize(NumOfOuterPoints); std::vector nei_tmp(NumOfOuterPoints); std::vector pnts_tmp(NumOfOuterPoints); //Look for corner points std::cout << "Looking for corners..." << std::endl; CornerIndex.push_back(FindCorner(BoundBox.MinX,BoundBox.MinY,v_neighbour,v_pnts)); //FindCorner(Parameter1, Parameter2, neighbour_list, mesh) CornerIndex.push_back(FindCorner(BoundBox.MaxX,BoundBox.MinY,v_neighbour,v_pnts)); CornerIndex.push_back(FindCorner(BoundBox.MaxX,BoundBox.MaxY,v_neighbour,v_pnts)); CornerIndex.push_back(FindCorner(BoundBox.MinX,BoundBox.MaxY,v_neighbour,v_pnts)); //Redo the list, start from (0,0), we are using the arrays in nei_tmp and pnts_tmp vec_it = find(v_neighbour.begin(),v_neighbour.end(),CornerIndex[0]); pnt_it = find(v_pnts.begin(), v_pnts.end(), LocalMesh.GetPoint(CornerIndex[0])); for (unsigned int i = 0; i < v_neighbour.size()-1; i++) { nei_tmp[i] = *vec_it; pnts_tmp[i] = *pnt_it; UnparamBoundariesX[i] = (*pnt_it).x; UnparamBoundariesY[i] = (*pnt_it).y; UnparamBoundariesZ[i] = (*pnt_it).z; ++vec_it; ++pnt_it; if (vec_it == v_neighbour.end()-1) { vec_it = v_neighbour.begin(); pnt_it = v_pnts.begin(); a = i; } } v_pnts.clear(); v_pnts = pnts_tmp; std::cout << "Parametirizing..." << std::endl; //Parameter the boundaries //Parameter the _ Boundaries //v_handle = CornerIndex[0]; double totaldistance = 0; unsigned int g = 0; unsigned int temp1 = g; unsigned int temp2 = g; do //Get distance first { distance = sqrt(((v_pnts[g+1][0] - v_pnts[g][0])*(v_pnts[g+1][0] - v_pnts[g][0])) + ((v_pnts[g+1][1] - v_pnts[g][1])*(v_pnts[g+1][1] - v_pnts[g][1]))); Pointdistance.push_back(distance); totaldistance += distance; g++; } while ((vec_it = find(CornerIndex.begin(), CornerIndex.end(), nei_tmp[g])) == CornerIndex.end()); //Secure current g-counter and reinitialize g-counter to initial value temp1 = g; g = temp2; //Parameter the first point, fill up the list we are using pnts_tmp[g][0] = 0.0f, pnts_tmp[g][1] = 0.0f; BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1]; g++; for (unsigned int i = 0; i < Pointdistance.size() - 1;i++) { //Parametirizing //0 < X < 1, Y = 0.0, Z = don't care lalalala pnts_tmp[g][0] = (Pointdistance[i]/totaldistance)+pnts_tmp[g-1][0], pnts_tmp[g][1] = 0.0f; BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1]; g++; } //Secure the counters and reinitialize the things we needed g = temp1; temp2 = g; Pointdistance.clear(); totaldistance = 0; //Parameter the -| boundary do //Get distance first { distance = sqrt(((v_pnts[g+1][0] - v_pnts[g][0])*(v_pnts[g+1][0] - v_pnts[g][0])) + ((v_pnts[g+1][1] - v_pnts[g][1])*(v_pnts[g+1][1] - v_pnts[g][1]))); Pointdistance.push_back(distance); totaldistance += distance; g++; } while ((vec_it = find(CornerIndex.begin(), CornerIndex.end(), nei_tmp[g])) == CornerIndex.end()); //Secure current g-counter and reinitialize g-counter to initial value temp1 = g; g = temp2; pnts_tmp[g][0] = 1.0f, pnts_tmp[g][1] = 0.0f; BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1]; g++; for (unsigned int i = 0; i < Pointdistance.size() - 1;i++) { //Parametirizing //X = 1, 0 < Y < 1, Z = don't care lalalala pnts_tmp[g][0] = 1.0f, pnts_tmp[g][1] = (Pointdistance[i]/totaldistance)+pnts_tmp[g-1][1]; BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1]; g++; } //Secure the counters and reinitialize´the things we needed g = temp1; temp2 = g; Pointdistance.clear(); totaldistance = 0; //Parameter the - boundary do //Get distance first { distance = sqrt(((v_pnts[g+1][0] - v_pnts[g][0])*(v_pnts[g+1][0] - v_pnts[g][0])) + ((v_pnts[g+1][1] - v_pnts[g][1])*(v_pnts[g+1][1] - v_pnts[g][1]))); Pointdistance.push_back(distance); totaldistance += distance; g++; } while ((vec_it = find(CornerIndex.begin(), CornerIndex.end(), nei_tmp[g])) == CornerIndex.end()); //Secure current g-counter and reinitialize g-counter to initial value temp1 = g; g = temp2; pnts_tmp[g][0] = 1.0f, pnts_tmp[g][1] = 1.0f; float prev = pnts_tmp[g][0]; BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1]; g++; for (unsigned int i = 0; i < Pointdistance.size() - 1;i++) { //Parametirizing //0 < X < 1,Y = 1, Z = don't care lalalala pnts_tmp[g][0] = (Pointdistance[i]/totaldistance)+prev, pnts_tmp[g][1] = 1.0f; prev = pnts_tmp[g][0]; pnts_tmp[g][0] = 2.0f - pnts_tmp[g][0]; BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1]; g++; } //Secure the counters and reinitialize´the things we needed g = temp1; temp2 = g; Pointdistance.clear(); totaldistance = 0; //Parameter the |- boundary do //Get distance first { distance = sqrt(((v_pnts[g+1][0] - v_pnts[g][0])*(v_pnts[g+1][0] - v_pnts[g][0])) + ((v_pnts[g+1][1] - v_pnts[g][1])*(v_pnts[g+1][1] - v_pnts[g][1]))); Pointdistance.push_back(distance); totaldistance += distance; g++; if (g+1 == v_pnts.size()) { distance = sqrt(((v_pnts[0][0] - v_pnts[g][0])*(v_pnts[0][0] - v_pnts[g][0])) + ((v_pnts[0][1] - v_pnts[g][1])*(v_pnts[0][1] - v_pnts[g][1]))); Pointdistance.push_back(distance); totaldistance += distance; break; } } while ((vec_it = find(CornerIndex.begin(), CornerIndex.end(), nei_tmp[g])) == CornerIndex.end()); //Secure current g-counter and reinitialize g-counter to initial value temp1 = g; g = temp2; pnts_tmp[g][0] = 0.0f, pnts_tmp[g][1] = 1.0f; prev = pnts_tmp[g][1]; BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1]; g++; for (unsigned int i = 0; i < Pointdistance.size() - 1;i++) { //Parametirizing //0 < X < 1, Y = 0, Z = don't care lalalala pnts_tmp[g][0] = 0.0, pnts_tmp[g][1] = (Pointdistance[i]/totaldistance)+prev; prev = pnts_tmp[g][1]; pnts_tmp[g][1] = 2.0f - pnts_tmp[g][1]; BoundariesX[g] = pnts_tmp[g][0], BoundariesY[g] = pnts_tmp[g][1]; g++; } //Secure the counters and reinitialize´the things we needed g = temp1; temp2 = g; Pointdistance.clear(); totaldistance = 0; ParameterX.resize(NumOfOuterPoints); ParameterY.resize(NumOfOuterPoints); int count = 0; NumOfInnerPoints = NumOfPoints - NumOfOuterPoints; mapper.resize(NumOfPoints); MeshCore::MeshPointIterator v_it(LocalMesh); a = 0; int b = 0; for (v_it.Begin(); !v_it.EndReached(); ++v_it) //For all points... { if ((vec_it = find(nei_tmp.begin(), nei_tmp.end(), v_it.Position())) != nei_tmp.end()) //...is it boundary? { //Yes ParameterX[count] = pnts_tmp[int(vec_it-nei_tmp.begin())][0]; ParameterY[count] = pnts_tmp[int(vec_it-nei_tmp.begin())][1]; mapper[v_it.Position()] = a+NumOfInnerPoints; a++, count++; } else { //No mapper[v_it.Position()] = b; b++; } } } /*! \brief Parameterizing the Inner Points This function will parameterize the inner points. Using the algorithim based on paper from Michael S. Floater, published in Computer Aided Design 14(1997) page 231 - 250, entitled Parametrization and smooth approximation of surface triangulation */ void Approximate::ParameterInnerPoints() { std::cout << "Computing the parameter for the inner points..." << std::endl; MeshCore::MeshPointIterator v_it(LocalMesh); MeshCore::MeshAlgorithm algo(LocalMesh); MeshCore::MeshRefPointToPoints vv_it(LocalMesh); MeshCore::MeshRefPointToFacets vf_it(LocalMesh); std::set PntNei; std::set FacetNei; ublas::compressed_matrix Lambda(NumOfInnerPoints, NumOfPoints); int count = 0; std::cout << "Prepping the Lambda" << std::endl; std::list< std::vector >::iterator bInd = BoundariesIndex.begin(); std::vector neiIndexes = *bInd; std::vector ::iterator vec_it; for (v_it.Begin(); !v_it.EndReached(); ++v_it) { if ((vec_it = find(neiIndexes.begin(), neiIndexes.end(), v_it.Position())) == neiIndexes.end()) { std::vector NeiPnts; std::vector nei; std::vector::iterator nei_it; PntNei = vv_it[v_it.Position()]; FacetNei = vf_it[v_it.Position()]; ReorderNeighbourList(PntNei,FacetNei,nei,v_it.Position()); std::vector Angle; std::vector Magnitude; Base::Vector3f CurrentPoint(*v_it); double TotAngle = 0; unsigned int NumOfNeighbour = PntNei.size(); unsigned int i = 0; //Angle and magnitude calculations for projection. //With respect to CurrentPoint while (i < NumOfNeighbour) { if (i+1 != NumOfNeighbour) { Base::Vector3f CurrentNeighbour(LocalMesh.GetPoint(nei[i])); Base::Vector3f NextNeighbour(LocalMesh.GetPoint(nei[i+1])); double ang = CalcAngle(CurrentNeighbour, CurrentPoint, NextNeighbour); double magn = sqrt((CurrentNeighbour - CurrentPoint) * (CurrentNeighbour - CurrentPoint)); Angle.push_back(ang); Magnitude.push_back(magn); TotAngle += ang; i++; } else { Base::Vector3f CurrentNeighbour(LocalMesh.GetPoint(nei[i])); Base::Vector3f NextNeighbour(LocalMesh.GetPoint(nei[0])); double ang = CalcAngle(CurrentNeighbour, CurrentPoint, NextNeighbour); double magn = sqrt((CurrentNeighbour - CurrentPoint) * (CurrentNeighbour - CurrentPoint)); Angle.push_back(ang); Magnitude.push_back(magn); TotAngle += ang; i++; } } //Projection //Current point is (0,0), First neighbour is on the X-Axis (y = 0), all other are projected //depending on angle and magnitude Base::Vector3f CurrentNeighbour(Magnitude[0],0.0,0.0); NeiPnts.push_back(CurrentNeighbour); double alpha = 0; unsigned int k = 0; for (unsigned int i = 1; i < NumOfNeighbour; i++) { alpha = alpha + ((2 * D_PI * Angle[i-1]) / TotAngle); double x_pnt = Magnitude[i] * cos(alpha), y_pnt = Magnitude[i] * sin(alpha); Base::Vector3f NewPoint(x_pnt,y_pnt,0.0); NeiPnts.push_back(NewPoint); ++k; } k = 0; //Preparing the needed matrix for iterating std::vector< std::vector > Mu(NumOfNeighbour, std::vector(NumOfNeighbour, 0.0)); //Mu Matrix std::vector< std::vector > MMatrix(2, std::vector(2,0.0)); //for the solver std::vector bMatrix(2,0.0); std::vector lMatrix(2,0.0); if (NumOfNeighbour > 3) //if NumOfNeighbour > 3... { for (k = 0; k < NumOfNeighbour;k++) //...for all neighbours... { for (unsigned int l = k+1; l < NumOfNeighbour+k; l++) //...another iterator iterate through other neighbour { MMatrix[0][0] = NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][0] - NeiPnts[(unsigned int)fmod((double)l-1,(double)NumOfNeighbour)][0]; MMatrix[1][0] = NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][1] - NeiPnts[(unsigned int)fmod((double)l-1,(double)NumOfNeighbour)][1]; MMatrix[0][1] = NeiPnts[k][0]; MMatrix[1][1] = NeiPnts[k][1]; bMatrix[0] = -NeiPnts[(unsigned int)fmod((double)l-1,(double)NumOfNeighbour)][0]; bMatrix[1] = -NeiPnts[(unsigned int)fmod((double)l-1,(double)NumOfNeighbour)][1]; if (det2(MMatrix) != 0) { CramerSolve(MMatrix, bMatrix, lMatrix); //Solve it if (lMatrix[0] <= 1.00001f && lMatrix[0] >= 0.0f && lMatrix[1] > 0.0f) //Condition for a solution { unsigned int r = (unsigned int)fmod((double)l-1,(double)NumOfNeighbour); MMatrix[0][0] = NeiPnts[k][0] - NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][0]; MMatrix[1][0] = NeiPnts[k][1] - NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][1]; MMatrix[0][1] = NeiPnts[(unsigned int)fmod((double)l-1,(double)NumOfNeighbour)][0] - NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][0]; MMatrix[1][1] = NeiPnts[(unsigned int)fmod((double)l-1,(double)NumOfNeighbour)][1] - NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][1]; bMatrix[0] = -NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][0]; bMatrix[1] = -NeiPnts[(unsigned int)fmod((double)l,(double)NumOfNeighbour)][1]; CramerSolve(MMatrix, bMatrix, lMatrix); //Solve it Mu[k][k] = fabs(lMatrix[0]); //Solution found, fill up the Mu Mu[r][k] = fabs(lMatrix[1]); if ((unsigned int)fmod((double)r,(double)NumOfNeighbour)+1 == NumOfNeighbour) Mu[0][k] = 1 -lMatrix[0] - lMatrix[1]; else Mu[(unsigned int)fmod((double)r,(double)NumOfNeighbour)+1][k] = 1 -lMatrix[0] - lMatrix[1]; break; } } } } //Fill in the lambda /*for(int j = 0; j < NumOfNeighbour; j++) //quick checker, if any bug comes out, one of { //possible bugspawn is here double sum = 0; for(int k = 0; k < NumOfNeighbour; k++) sum += Mu[k][j]; if(sum < 0.9999 || sum > 1.0001) { std::cout << "Mu is not correct.\nSum: " << sum << "\nCount: " << count << "\nNumOfNeighbour: " << NumOfNeighbour << std::endl; getchar(); } }*/ for (unsigned int j = 0; j < NumOfNeighbour; j++) { double sum = 0; for (unsigned int k = 0; k < NumOfNeighbour; k++) sum += Mu[j][k]; Lambda(count,mapper[nei[j]]) = sum/NumOfNeighbour; } count++; } else if (NumOfNeighbour == 3) //If NumOfNeighbour == 3... { Base::Vector3f Point1(NeiPnts[0]); Base::Vector3f Point2(NeiPnts[1]); Base::Vector3f Point3(NeiPnts[2]); Base::Vector3f Zeroes(0,0,0); double A = AreaTriangle(Point1,Point2,Point3); Lambda(count,mapper[nei[0]]) = AreaTriangle(Zeroes,Point2,Point3) / A; Lambda(count,mapper[nei[1]]) = AreaTriangle(Point1,Zeroes,Point3) / A; Lambda(count,mapper[nei[2]]) = AreaTriangle(Point1,Point2,Zeroes) / A; count++; } else //Can an inside point have less than 3 neighbours...? { throw Base::Exception("Something's wrong here. Less than 3 Neighbour"); } } } //Now, we split the lambda matrix //Using the compressed matrix class from boost std::cout << "Splitting the lambdas..." << std::endl; ublas::compressed_matrix, ublas::unbounded_array > UpperTerm(NumOfInnerPoints, NumOfInnerPoints); ublas::compressed_matrix OutLambda(NumOfInnerPoints, NumOfOuterPoints); //We need to extract this columnwise, and (i,j) is a row-major style of numbering... //Also, later we need to I - Upperterm, I := IdentityMatrix, this will also be done in this step for (int i = 0; i < NumOfInnerPoints; i++) { for (int j = 0; j < NumOfInnerPoints; j++) { if (Lambda(i,j) != 0) UpperTerm(i,j) = -Lambda(i,j); else if (i == j) UpperTerm(i,j) = 1.0 - Lambda(i,j); } } for (int j = NumOfInnerPoints, k = 0; j < NumOfPoints; j++, k++) { for (int i = 0; i < NumOfInnerPoints; i++) { if (Lambda(i,j) != 0) OutLambda(i,k) = Lambda(i,j); } } //Result Storage ublas::vector xResult(NumOfInnerPoints); ublas::vector MultResult(NumOfInnerPoints); ublas::vector yResult(NumOfInnerPoints); ofstream anOutputFile; anOutputFile.open("c:/approx_param_log.txt"); anOutputFile << 1 << endl; //Solving the X Term std::cout << "Solving the X Term..." << std::endl; //atlas::gemm and atlas::gemv can't work with sparse matrices it seems, therefore using axpy_prod ublas::axpy_prod(OutLambda, ParameterX, MultResult); anOutputFile << 2 << endl; bindings::umfpack::umf_solve (UpperTerm, xResult,MultResult ); //umfpack to solve sparse matrices equations anOutputFile << 3 << endl; //Solving the Y Term std::cout << "Solving the Y Term..." << std::endl; ublas::axpy_prod(OutLambda, ParameterY, MultResult); anOutputFile << 4 << endl; bindings::umfpack::umf_solve (UpperTerm, yResult, MultResult); anOutputFile << 5 << endl; std::cout << "Replacing the results.." << std::endl; //Another counter, temporary storage for old ParameterX and ParameterY, and resizing to include ALL points now unsigned int s = 0; unsigned int b = 0; ublas::vector tempox = ParameterX; ublas::vector tempoy = ParameterY; ParameterX.clear(), ParameterX.resize(NumOfPoints); ParameterY.clear(), ParameterY.resize(NumOfPoints); UnparamX.resize(NumOfPoints), UnparamY.resize(NumOfPoints),UnparamZ.resize(NumOfPoints); //Reextract the boundaries list anOutputFile << 6 << endl; std::vector boundarieslist = *bInd; anOutputFile << 7 << endl; /**************************/ MeshParam = LocalMesh; MeshCore::MeshPointArray pntArr= MeshParam.GetPoints(); MeshCore::MeshFacetArray fctArr= MeshParam.GetFacets(); /**************************/ for (v_it.Begin(); !v_it.EndReached(); ++v_it) { anOutputFile << 0 << endl; //Inner Points goes into the beginning of the list if ((vec_it = find(boundarieslist.begin(), boundarieslist.end(), v_it.Position())) == boundarieslist.end()) { ParameterX[s] = xResult[s]; ParameterY[s] = yResult[s]; pntArr[v_it.Position()].x = ParameterX[s]; pntArr[v_it.Position()].y = ParameterY[s]; pntArr[v_it.Position()].z = 0; UnparamX[s] = LocalMesh.GetPoint(v_it.Position())[0]; UnparamY[s] = LocalMesh.GetPoint(v_it.Position())[1]; UnparamZ[s] = LocalMesh.GetPoint(v_it.Position())[2]; s++; } //Boundaries goes into the end of the list else { ParameterX[NumOfInnerPoints+b] = tempox[b]; ParameterY[NumOfInnerPoints+b] = tempoy[b]; pntArr[v_it.Position()].x = ParameterX[NumOfInnerPoints+b]; pntArr[v_it.Position()].y = ParameterY[NumOfInnerPoints+b]; pntArr[v_it.Position()].z = 0; UnparamX[NumOfInnerPoints+b] = LocalMesh.GetPoint(v_it.Position())[0]; UnparamY[NumOfInnerPoints+b] = LocalMesh.GetPoint(v_it.Position())[1]; UnparamZ[NumOfInnerPoints+b] = LocalMesh.GetPoint(v_it.Position())[2]; b++; } } anOutputFile << 8 << endl; MeshParam.Assign(pntArr,fctArr); anOutputFile << 9 << endl; std::cout << "DONE" << std::endl; std::cout << "Information about the meshes:-" << std::endl; std::cout << "Number of Points: " << NumOfPoints << std::endl; std::cout << "Number of Inner Points: " << NumOfInnerPoints << std::endl; std::cout << "Number of Outer Points: " << NumOfOuterPoints << std::endl; //clear the mesh, we will continue working with the lists we have made ParameterMesh.Clear(); anOutputFile << 10 << endl; LocalMesh.Clear(); anOutputFile << 11 << endl; anOutputFile.close(); } /*! \brief Main Error Approximations routine This function will be ended once max_err < tolerance */ void Approximate::ErrorApprox() { ofstream anOutputFile; anOutputFile.open("c:/approx_param_log.txt"); anOutputFile << "Begin constructing NURB for first pass" << std::endl; double max_err = 0; bool ErrThere = true; //for breaking the while int h = 0; int cnt = 0; double av = 0, c2 = 0; double lam; anOutputFile << "Constructing" << std::endl; ublas::matrix C_Temp(NumOfPoints,3); anOutputFile << "C_Temp succesfully constructed" << std::endl; //Time saving... C_Temp matrix is constant for all time anOutputFile << "number of points: " << NumOfPoints << std::endl; std::vector err_w(NumOfPoints); anOutputFile << "checkpoint 1 " << std::endl; for (int i=1; i B_Matrix(NumOfPoints,(MainNurb.MaxU+1)*(MainNurb.MaxV+1)); anOutputFile << "********************************" << endl; anOutputFile << "B_Matrix succesfully constructed" << std::endl; anOutputFile << "Preparing B-Matrix..." << std::endl; std::vector N_u(MainNurb.MaxU+1, 0.0); std::vector N_v(MainNurb.MaxV+1, 0.0); std::vector TempU(MainNurb.DegreeU+1, 0.0); std::vector TempV(MainNurb.DegreeV+1, 0.0); std::vector swapDegreeU(MainNurb.DegreeU+1, 0.0); std::vector swapDegreeV(MainNurb.DegreeV+1, 0.0); std::vector swapV(MainNurb.MaxV+1, 0.0); std::vector swapU(MainNurb.MaxU+1, 0.0); for (int i = 0; i < NumOfPoints; i++) { std::vector N_u(MainNurb.MaxU+1, 0.0); std::vector N_v(MainNurb.MaxV+1, 0.0); std::vector TempU(MainNurb.DegreeU+1, 0.0); std::vector TempV(MainNurb.DegreeV+1, 0.0); int j1 = FindSpan(MainNurb.MaxU, MainNurb.DegreeU, ParameterX[i], MainNurb.KnotU); int j2 = FindSpan(MainNurb.MaxV, MainNurb.DegreeV, ParameterY[i], MainNurb.KnotV); Basisfun(j1,ParameterX[i], MainNurb.DegreeU, MainNurb.KnotU, TempU); Basisfun(j2,ParameterY[i], MainNurb.DegreeV, MainNurb.KnotV, TempV); for (int k = j1 - MainNurb.DegreeU, s = 0; k < j1+1; k++, s++) N_u[k] = TempU[s]; for (int k = j2 - MainNurb.DegreeV, s = 0; k < j2+1; k++, s++) N_v[k] = TempV[s]; for (int j = 0; j <= MainNurb.MaxV; j++) { for (int h = 0; h <= MainNurb.MaxU; h++) { //double result = N_u[h] * N_v[j]; B_Matrix(i,(j*(MainNurb.MaxU+1))+h) = sqrt(err_w[i]) * N_u[h] * N_v[j]; } } } for (unsigned int i = 0; i < UnparamX.size(); ++i) { C_Temp(i,0) = sqrt(err_w[i])*UnparamX[i]; C_Temp(i,1) = sqrt(err_w[i])*UnparamY[i]; C_Temp(i,2) = sqrt(err_w[i])*UnparamZ[i]; } ublas::matrix G_Matrix((MainNurb.MaxU+1)*(MainNurb.MaxV+1),(MainNurb.MaxU+1)*(MainNurb.MaxV+1)); ublas::matrix C_Tempo((MainNurb.MaxU+1)*(MainNurb.MaxV+1),3); atlas::gemm(CblasTrans, CblasNoTrans, 1.0, B_Matrix,C_Temp,0.0,C_Tempo); atlas::gemm(CblasTrans,CblasNoTrans,1.0,B_Matrix,B_Matrix,0.0,G_Matrix); //Multiplication with Boost bindings //to ATLAS's bindings to LAPACK B_Matrix.resize(1,1,false); B_Matrix.clear(); anOutputFile << "Preparing the A_Matrix" << std::endl; //ublas::matrix G_Matrix((MainNurb.MaxU+1)*(MainNurb.MaxV+1),(MainNurb.MaxU+1)*(MainNurb.MaxV+1)); ublas::compressed_matrix, ublas::unbounded_array > A_Matrix((MainNurb.MaxU+1)*(MainNurb.MaxV+1),(MainNurb.MaxU+1)*(MainNurb.MaxV+1)); anOutputFile << "Multiply..." << std::endl; anOutputFile << "Euclidean Norm" << std::endl; A_Matrix = G_Matrix; if(cnt == 0) lam = 10*ublas::norm_frobenius(G_Matrix); else lam /= 2; G_Matrix.resize(1,1, false); G_Matrix.clear(); ublas::compressed_matrix E_Matrix((MainNurb.MaxU+1)*(MainNurb.MaxV+1), (MainNurb.MaxU+1)*(MainNurb.MaxV+1)); anOutputFile << "E_Matrix succesfully constructed" << std::endl; anOutputFile << "Smoothing..." << std::endl; eFair2(E_Matrix); if(cnt == 0){ lam = lam / ublas::norm_frobenius(E_Matrix); } ++cnt; anOutputFile << "lam: " << lam << std::endl; A_Matrix = A_Matrix + (E_Matrix*lam); //Destroying the unneeded matrix E_Matrix.resize(1,1,false); E_Matrix.clear(); anOutputFile << "Preparing the C_Matrix" << std::endl; std::vector< std::vector > Solver; std::vector TempoSolv((MainNurb.MaxU+1)*(MainNurb.MaxV+1)); std::vector TempoB; anOutputFile << "Solving" << std::endl; for (unsigned int i = 0; i < 3; i++) //Since umfpack can only solve Ax = B, where x and B are vectors //instead of matrices... { //We will solve it column wise for (int j = 0; j < (MainNurb.MaxU+1)*(MainNurb.MaxV+1); j++) TempoB.push_back(C_Tempo(j,i)); //push back a column umfpack::umf_solve(A_Matrix,TempoSolv,TempoB); //solve Solver.push_back(TempoSolv); //push back the solution TempoB.clear(); } MainNurb.CntrlArray.clear(); anOutputFile << "Loading the Control Points" << std::endl; for (int i = 0; i < (MainNurb.MaxU+1)*(MainNurb.MaxV+1); i++) //now load the control points { MainNurb.CntrlArray.push_back(Solver[0][i]); //X MainNurb.CntrlArray.push_back(Solver[1][i]); //Y MainNurb.CntrlArray.push_back(Solver[2][i]); //Z } std::vector ContrArr = MainNurb.CntrlArray; anOutputFile << "Cntrl Count" << std::endl; anOutputFile << "U: " << MainNurb.MaxU + 1 << std::endl; anOutputFile << "V: " << MainNurb.MaxV + 1 << std::endl; //ComputeError(h, 0.1, 0.1, max_err,av, c2, err_w); //anOutputFile << "Maximum error is " << max_err < &E_Matrix) { ofstream anOutputFile; anOutputFile.open("c:/approx_param_log_efair.txt"); int precision = 100; std::vector U(precision+1, 0); std::vector V(precision+1, 0); for (int i = 1; i <= precision; i++) //Load U and V vectors uniformly, according to precision { U[i] = (1.0/(double)precision) + U[i-1]; V[i] = (1.0/(double)precision) + V[i-1]; } U[precision] = 1.0; V[precision] = 1.0; precision = precision + 1; int mu = MainNurb.MaxKnotU; int mv = MainNurb.MaxKnotV; int k = mu-MainNurb.MaxU-2; int l = mv-MainNurb.MaxV-2; //Preparing the needed matrices std::vector< std::vector > N_u0(precision, std::vector(mu-1-k,0.0)); std::vector< std::vector > N_u1(precision, std::vector(mu-1-k,0.0)); std::vector< std::vector > N_u2(precision, std::vector(mu-1-k,0.0)); std::vector< std::vector > N_v0(precision, std::vector(mu-1-l,0.0)); std::vector< std::vector > N_v1(precision, std::vector(mu-1-l,0.0)); std::vector< std::vector > N_v2(precision, std::vector(mu-1-l,0.0)); std::vector A_1(precision,0.0); std::vector B_1(precision,0.0); std::vector C_1(precision,0.0); std::vector A_2(precision,0.0); std::vector B_2(precision,0.0); std::vector C_2(precision,0.0); //Filling up the first six matrices for (int i = 0; i < precision; i++) { std::vector< std::vector > dersU(2+1, std::vector(k+1)); std::vector< std::vector > dersV(2+1, std::vector(k+1)); int s = FindSpan(MainNurb.MaxU, k, U[i], MainNurb.KnotU); DersBasisFuns(s, U[i], k, 2, MainNurb.KnotU, dersU); for (int a = s-k, b = 0; a < s+1; a++, b++) { N_u0[i][a] = dersU[0][b]; N_u1[i][a] = dersU[1][b]; N_u2[i][a] = dersU[2][b]; } s = FindSpan(MainNurb.MaxV, l, V[i], MainNurb.KnotV); DersBasisFuns(s, V[i], l, 2, MainNurb.KnotV, dersV); for (int a = s-l, b = 0; a < s+1; a++, b++) { N_v0[i][a] = dersV[0][b]; N_v1[i][a] = dersV[1][b]; N_v2[i][a] = dersV[2][b]; } } double A,B,C; //Needed Variables for the Trapezoid-Integration //Now lets fill up the E for (int a = 0; a < MainNurb.MaxV+1; a++) { //anOutputFile << "\r" << ceil(100.0*((double) a/(double) MainNurb.MaxV)) << "%" << " "; for (int b = 0; b < MainNurb.MaxU+1; b++) { for (int c = 0; c < MainNurb.MaxV+1; c++) { for (int d = 0; d < MainNurb.MaxU+1; d++) { for (int w = 0; w < precision; w++) //Fill up the last 6 Matrices from the first matrix { A_1[w] = (N_u2[w][b]*N_u2[w][d]); A_2[w] = (N_v0[w][a]*N_v0[w][c]); B_1[w] = (N_u1[w][b]*N_u1[w][d]); B_2[w] = (N_v1[w][a]*N_v1[w][c]); C_1[w] = (N_u0[w][b]*N_u0[w][d]); C_2[w] = (N_v2[w][a]*N_v2[w][c]); } //SehnenTrapezRegel A = TrapezoidIntergration(U, A_1); A *= TrapezoidIntergration(U, A_2); B = TrapezoidIntergration(U, B_1); B *= TrapezoidIntergration(U, B_2); C = TrapezoidIntergration(U, C_1); C *= TrapezoidIntergration(U, C_2); //result = A + 2*B + C; E_Matrix((a*(MainNurb.MaxU+1))+b,(c*(MainNurb.MaxV+1))+d) = A + 2*B + C; } } } } anOutputFile << std::endl; anOutputFile.close(); } /*! \brief This function will compute the current error */ void Approximate::ComputeError(int &h, double eps_1, double eps_2, double &max_error, double &av, double &c2, std::vector &err_w) { std::cout << "Computing Error..." << std::endl; av = 0; c2 = 0; max_error = 0; for (int i = 0; i < NumOfPoints; i++) //For all points { std::vector DerivNurb; std::vector DerivUNurb; std::vector DerivVNurb; std::vector > Jac; std::vector CurPoint; CurPoint.push_back(ParameterX[i]); CurPoint.push_back(ParameterY[i]); std::vector V(2,0.0); V[0] = CurPoint[0]; V[1] = CurPoint[1]; unsigned int j = 0; PointNrbDerivate(MainNurb, DerivNurb); PointNrbDerivate(DerivNurb[0], DerivUNurb); PointNrbDerivate(DerivNurb[1], DerivVNurb); int c = 0; std::vector error; std::vector EvalPoint; NrbDEval(MainNurb, DerivNurb, CurPoint, EvalPoint, Jac); EvalPoint[0] = EvalPoint[0] - UnparamX[i]; EvalPoint[1] = EvalPoint[1] - UnparamY[i]; EvalPoint[2] = EvalPoint[2] - UnparamZ[i]; ublas::matrix EvalMat(1, EvalPoint.size()); for (j = 0; j < 3; j++) EvalMat(0,j) = EvalPoint[j]; for (j = 0; j < 2; j++) { ublas::matrix Holder(1, 1); ublas::matrix JacPoint(Jac[j].size(), 1); for (unsigned int k = 0; k < Jac[j].size(); k++) JacPoint(k,0) = Jac[j][k]; atlas::gemm(CblasTrans, CblasTrans, 1.0, JacPoint,EvalMat,0.0,Holder); double lam = ublas::norm_frobenius(JacPoint) * ublas::norm_frobenius(EvalMat); if (lam == 0) throw "Division by Zero in ComputeError function"; lam = fabs(Holder(0,0) / lam); error.push_back(lam); } //recheck the... thingy here... while (((norm_frobenius(EvalMat) > eps_1) && ((error[0] > eps_2) || (error[1] > eps_2))) && c < 1000) //If somehow the eps is not reached... { c += 1; std::vector p_uu; std::vector p_uv; std::vector p_vu; std::vector p_vv; ublas::matrix P_UU(3, 1); ublas::matrix P_UV(3, 1); ublas::matrix P_VU(3, 1); ublas::matrix P_VV(3, 1); ublas::matrix JacPoint1(Jac[0].size(), 1); ublas::matrix JacPoint2(Jac[0].size(), 1); PointNrbEval(p_uu,CurPoint,DerivUNurb[0]); PointNrbEval(p_uv,CurPoint,DerivUNurb[1]); PointNrbEval(p_vu,CurPoint,DerivVNurb[0]); PointNrbEval(p_vv,CurPoint,DerivVNurb[1]); //Prepping the needed matrix for (unsigned int a = 0; a < Jac[0].size();a++) JacPoint1(a,0) = Jac[0][a]; for (unsigned int a = 0; a < Jac[1].size();a++) JacPoint2(a,0) = Jac[1][a]; for (unsigned int a = 0; a < 3; a++) { P_UU(a,0) = p_uu[a]; P_UV(a,0) = p_uv[a]; P_VU(a,0) = p_vu[a]; P_VV(a,0) = p_vv[a]; } std::vector< std::vector > J(2, std::vector(2,0.0)); std::vector K(2,0.0); //Newton iterate //J[0][0] ublas::matrix MultResult(1,1); atlas::gemm(CblasTrans, CblasNoTrans, 1.0, JacPoint1,JacPoint1,0.0,MultResult); J[0][0] += MultResult(0,0); atlas::gemm(CblasNoTrans, CblasNoTrans, 1.0, EvalMat,P_UU,0.0,MultResult); J[0][0] += MultResult(0,0); //J[0][1] atlas::gemm(CblasTrans, CblasNoTrans, 1.0, JacPoint1,JacPoint2,0.0,MultResult); J[0][1] += MultResult(0,0); atlas::gemm(CblasNoTrans, CblasNoTrans, 1.0, EvalMat,P_UV,0.0,MultResult); J[0][1] += MultResult(0,0); //J[1][0] atlas::gemm(CblasTrans, CblasNoTrans, 1.0, JacPoint1,JacPoint2,0.0,MultResult); J[1][0] += MultResult(0,0); atlas::gemm(CblasNoTrans, CblasNoTrans, 1.0, EvalMat,P_VU,0.0,MultResult); J[1][0] += MultResult(0,0); //J[1][1] atlas::gemm(CblasTrans, CblasNoTrans, 1.0, JacPoint2,JacPoint2,0.0,MultResult); J[1][1] += MultResult(0,0); atlas::gemm(CblasNoTrans, CblasNoTrans, 1.0, EvalMat,P_VV,0.0,MultResult); J[1][1] += MultResult(0,0); //K[0] atlas::gemm(CblasNoTrans, CblasNoTrans, 1.0, EvalMat,JacPoint1,0.0,MultResult); K[0] = (J[0][0]*V[0]) + (J[0][1]*V[1]) - MultResult(0,0); //K[1] atlas::gemm(CblasNoTrans, CblasNoTrans, 1.0, EvalMat,JacPoint2,0.0,MultResult); K[1] = (J[1][0]*V[0]) + (J[1][1]*V[1]) - MultResult(0,0); CramerSolve(J,K,V); if (V[0] < 0) V[0] = 0; else if (V[0] > 1) V[0] = 1; if (V[1] < 0) V[1] = 0; else if (V[1] > 1) V[1] = 1; if (c == 500) { V[0] = 0.5; V[1] = 0.5; } //Reevaluate error.clear(); CurPoint[0] = V[0]; CurPoint[1] = V[1]; EvalPoint.clear(); Jac.clear(); NrbDEval(MainNurb, DerivNurb, CurPoint, EvalPoint, Jac); EvalPoint[0] = EvalPoint[0] - UnparamX[i]; EvalPoint[1] = EvalPoint[1] - UnparamY[i]; EvalPoint[2] = EvalPoint[2] - UnparamZ[i]; for (j = 0; j < 3; j++) EvalMat(0,j) = EvalPoint[j]; for (j = 0; j < 2; j++) { ublas::matrix Holder(1, 1); ublas::matrix JacPoint(Jac[j].size(), 1); for (unsigned int k = 0; k < Jac[j].size(); k++) JacPoint(k,0) = Jac[j][k]; atlas::gemm(CblasTrans, CblasTrans, 1.0, JacPoint,EvalMat,0.0,Holder); double lam = ublas::norm_frobenius(JacPoint) * ublas::norm_frobenius(EvalMat); if (lam == 0) throw "Division by Zero in ComputeError function"; else lam = fabs(Holder(0,0) / lam); error.push_back(lam); } } ParameterX[i] = V[0]; ParameterY[i] = V[1]; av += norm_frobenius(EvalMat); //Average Error err_w[i] = norm_frobenius(EvalMat); if (norm_frobenius(EvalMat) > max_error && c < 1000) { max_error = norm_frobenius(EvalMat); h = i; //if(max_error > (3*tolerance)) // break; } if (norm_frobenius(EvalMat) > tolerance) c2++; //% of point's error still above tolerance } c2 /= NumOfPoints; av /= NumOfPoints; std::cout << " DONE" << std::endl; } /*! \brief Reparameterization after error computation */ double Approximate::Reparam() { MeshCore::MeshPointArray pntArr = MeshParam.GetPoints(); MeshCore::MeshFacetArray fctArr = MeshParam.GetFacets(); double error = 0.0; std::cout << "Reparameterization..."; for (int i = 0; i < NumOfPoints; i++) { std::vector DerivNurb; std::vector p; std::vector EvalPoint; std::vector< std::vector > T; std::vector< std::vector > A(2,std::vector(2,0.0)); std::vector bt(2,0.0); p.push_back(ParameterX[i]); p.push_back(ParameterY[i]); PointNrbDerivate(MainNurb, DerivNurb); NrbDEval(MainNurb, DerivNurb, p, EvalPoint, T); EvalPoint[0] = UnparamX[i] - EvalPoint[0]; EvalPoint[1] = UnparamY[i] - EvalPoint[1]; EvalPoint[2] = UnparamZ[i] - EvalPoint[2]; error += sqrt(EvalPoint[0]*EvalPoint[0] + EvalPoint[1]*EvalPoint[1] + EvalPoint[2]*EvalPoint[2]); for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { std::vector JacHolder1(3, 0.0); std::vector JacHolder2(3, 0.0); std::vector Result(1, 0.0); if (j == 0 && k == 0) { for (int l = 0; l < 3; l++) { JacHolder1[l] = T[0][l]; JacHolder2[l] = T[0][l]; } cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,1,1,3,1.0, &JacHolder1[0],3,&JacHolder2[0],1,0.0,&Result[0], 1); A[j][k] = Result[0]; } else if (j == 1 && k == 1) { for (int l = 0; l < 3; l++) { JacHolder1[l] = T[1][l]; JacHolder2[l] = T[1][l]; } cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,1,1,3,1.0, &JacHolder1[0],3,&JacHolder2[0],1,0.0,&Result[0], 1); A[j][k] = Result[0]; } else { for (int l = 0; l < 3; l++) { JacHolder1[l] = T[0][l]; JacHolder2[l] = T[1][l]; } cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,1,1,3,1.0, &JacHolder1[0],3,&JacHolder2[0],1,0.0,&Result[0], 1); A[j][k] = Result[0]; } } std::vector Resultant(1, 0.0); std::vector BJacHolder(3, 0.0); for (int l = 0; l < 3; l++) BJacHolder[l] = T[j][l]; cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,1,1,3,1.0, &EvalPoint[0],3,&BJacHolder[0],1,0.0,&Resultant[0], 1); bt[j] = Resultant[0]; } std::vector delt(2,0.0); CramerSolve(A,bt,delt); //Reparam if (ParameterX[i] + delt[0] <= 0) ParameterX[i] = 0; else if (ParameterX[i] + delt[0] >= 1) ParameterX[i] = 1; else ParameterX[i] += delt[0]; if (ParameterY[i] + delt[1] <= 0) ParameterY[i] = 0; else if (ParameterY[i] + delt[1] >= 1) ParameterY[i] = 1; else ParameterY[i] += delt[1]; } error /= NumOfPoints; MeshCore::MeshPointIterator v_it(MeshParam); std::list< std::vector >::iterator bInd = BoundariesIndex.begin(); std::vector boundarieslist = *bInd; std::vector ::iterator vec_it; int s=0; int b=0; for (v_it.Begin(); !v_it.EndReached(); ++v_it) { //Inner Points goes into the beginning of the list if ((vec_it = find(boundarieslist.begin(), boundarieslist.end(), v_it.Position())) == boundarieslist.end()) { pntArr[v_it.Position()].x = ParameterX[s]; pntArr[v_it.Position()].y = ParameterY[s]; s++; } //Boundaries goes into the end of the list else { pntArr[v_it.Position()].x = ParameterX[NumOfInnerPoints+b]; pntArr[v_it.Position()].y = ParameterY[NumOfInnerPoints+b]; b++; } } MeshParam.Assign(pntArr,fctArr); std::cout << "DONE" << std::endl; return error; } /*! \brief Extend the Nurb Once error is computed and the generated nurb is stil not satisfactory (i.e max_err > tolerance), this function will extend the given Nurb by extending the Knot vectors by 2 and, because the degree is held constant, the control points */ void Approximate::ExtendNurb(double c2, int h) { std::cout << "Extending Knot Vector" << std::endl; std::cout << "Two knot extension" << std::endl; MainNurb.MaxU += 2; MainNurb.MaxV += 2; MainNurb.MaxKnotU += 2; MainNurb.MaxKnotV += 2; //U-V Knot Extension ExtendKnot(ParameterX[h], MainNurb.DegreeU, MainNurb.MaxU, MainNurb.KnotU); ExtendKnot(ParameterY[h], MainNurb.DegreeV, MainNurb.MaxV, MainNurb.KnotV); } /*! \brief Reorder the neighbour list This function will reorder the list in one-direction. Clockwise or counter clockwise is depending on the facet list and will not be checked by this function. (i.e the third vertex i.e vertex in first facet that is not the CurIndex or the first neighbour in pnt[Ok, I am also lost with this..., just debug and step to see what I mean...]) */ void Approximate::ReorderNeighbourList(std::set &pnt, std::set &face, std::vector &nei, unsigned long CurInd) { MeshCore::MeshPointArray::_TConstIterator v_beg = LocalMesh.GetPoints().begin(); MeshCore::MeshFacetArray::_TConstIterator f_beg = LocalMesh.GetFacets().begin(); std::set::iterator pnt_it; std::set::iterator face_it; std::vector::iterator vec_it; std::vector::iterator ulong_it; unsigned long PrevIndex; pnt_it = pnt.begin(); face_it = face.begin(); nei.push_back(v_beg[*pnt_it]._ulProp); //push back first neighbour vec_it = nei.begin(); PrevIndex = nei[0]; //Initialize PrevIndex for (unsigned int i = 1; i < pnt.size(); i++) //Start { while (true) { std::vector facetpnt; facetpnt.push_back(f_beg[*face_it]._aulPoints[0]); //push back into a vector for easier iteration facetpnt.push_back(f_beg[*face_it]._aulPoints[1]); facetpnt.push_back(f_beg[*face_it]._aulPoints[2]); if ((ulong_it = find(facetpnt.begin(), facetpnt.end(), PrevIndex)) == facetpnt.end()) //if PrevIndex not found { //in current facet ++face_it; //next face please continue; } else { for (unsigned int k = 0 ; k < 3; k++) { //If current facetpnt[k] is not yet in nei_list AND it is not the CurIndex if (((vec_it = find(nei.begin(), nei.end(), facetpnt[k])) == nei.end()) && facetpnt[k] != CurInd) { face.erase(face_it); //erase this face nei.push_back(facetpnt[k]); //push back the index PrevIndex = facetpnt[k]; //this index is now PrevIndex face_it = face.begin(); //reassign the iterator break; //end this for-loop } } break; //end this while loop } } } }