From 5f4bad2a9c6b631553bea4b4207e36e10a73778b Mon Sep 17 00:00:00 2001 From: Emilie Marchandise <emilie.marchandise@uclouvain.be> Date: Thu, 23 Jun 2011 10:28:41 +0000 Subject: [PATCH] UVStoXYZ --- Geo/GRbf.cpp | 165 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 107 insertions(+), 58 deletions(-) diff --git a/Geo/GRbf.cpp b/Geo/GRbf.cpp index 2f0feda2d1..f5febe14bf 100644 --- a/Geo/GRbf.cpp +++ b/Geo/GRbf.cpp @@ -234,7 +234,7 @@ fullMatrix<double> GRbf::generateRbfMat(int p, int n = nodes1.size1(); fullMatrix<double> rbfMat(m,n); - double eps =0.4/delta; //0.0677*(nbNodes^0.28)/min_dist; + double eps =0.5/delta; //0.0677*(nbNodes^0.28)/min_dist; if (_inUV) eps = epsilonUV; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { @@ -292,20 +292,38 @@ void GRbf::evalRbfDer(int p, } void GRbf::setup_level_set(const fullMatrix<double> &cntrs, - const fullMatrix<double> &normals, - fullMatrix<double> &level_set_nodes, - fullMatrix<double> &level_set_funvals){ + const fullMatrix<double> &normals, + fullMatrix<double> &level_set_nodes, + fullMatrix<double> &level_set_funvals){ int numNodes = cntrs.size1(); int nTot = 3*numNodes; + double normFactor; level_set_nodes.resize(nTot,3); level_set_funvals.resize(nTot,1); + fullMatrix<double> ONES(numNodes,1),sx(numNodes,1),sy(numNodes,1),sz(numNodes,1),norms(numNodes,3); + + //Computes the normal vectors to the surface at each node + for (int i=0;i<numNodes ; ++i){ + ONES(i,0)=1.0; + } + + evalRbfDer(1,cntrs,cntrs,ONES,sx); + evalRbfDer(2,cntrs,cntrs,ONES,sy); + evalRbfDer(3,cntrs,cntrs,ONES,sz); + for (int i=0;i<numNodes ; ++i){ + normFactor = sqrt(sx(i,0)*sx(i,0)+sy(i,0)*sy(i,0)+sz(i,0)*sz(i,0)); + sx(i,0) = sx(i,0)/normFactor; + sy(i,0) = sy(i,0)/normFactor; + sz(i,0) = sz(i,0)/normFactor; + norms(i,0) = sx(i,0);norms(i,1) = sy(i,0);norms(i,2) = sz(i,0); + } for (int i=0;i<numNodes ; ++i){ for (int j=0;j<3 ; ++j){ level_set_nodes(i,j) = cntrs(i,j); - level_set_nodes(i+numNodes,j) = cntrs(i,j)-delta*normals(i,j); - level_set_nodes(i+2*numNodes,j) = cntrs(i,j)+delta*normals(i,j); + level_set_nodes(i+numNodes,j) = cntrs(i,j)-delta*norms(i,j); + level_set_nodes(i+2*numNodes,j) = cntrs(i,j)+delta*norms(i,j); } level_set_funvals(i,0) = 0.0; level_set_funvals(i+numNodes,0) = -1; @@ -637,7 +655,6 @@ void GRbf::solveHarmonicMap(fullMatrix<double> Oper, F(iFix,1) = sin(theta); } - Oper.invertInPlace(); Oper.mult(F,UV); @@ -775,9 +792,9 @@ bool GRbf::UVStoXYZ(const double u_eval, const double v_eval, ANNidxArray index = new ANNidx[num_neighbours]; ANNdistArray dist = new ANNdist[num_neighbours]; UVkdtree->annkSearch(uvw, num_neighbours, index, dist); - - fullMatrix<double> ux(1,3), uy(1,3), uz(1,3), u_temp(1,3); - fullMatrix<double> nodes_eval(1,3); + int N_nbr = 5;//num_neighbours; + fullMatrix<double> ux(N_nbr,3), uy(N_nbr,3), uz(N_nbr,3), u_temp(N_nbr,3); + fullMatrix<double> nodes_eval(N_nbr,3),temp_nodes_eval(1,3),temp_u_temp(1,3); fullMatrix<double> u_vec(3*num_neighbours,3); fullMatrix<double> xyz_local(3*num_neighbours,3); @@ -811,75 +828,107 @@ bool GRbf::UVStoXYZ(const double u_eval, const double v_eval, } // u_vec_eval = [u_eval v_eval s_eval] - fullMatrix<double> u_vec_eval(1, 3); + fullMatrix<double> u_vec_eval(1, 3),nodes_vec_eval(1,3),u_test_vec_eval(1,3); u_vec_eval(0,0) = u_eval; u_vec_eval(0,1) = v_eval; u_vec_eval(0,2) = 0.0; //we will use a local interpolation to find the corresponding XYZ point to (u_eval,v_eval). _inUV = 1; - evalRbfDer(0, u_vec, u_vec_eval,xyz_local, nodes_eval); - u_temp(0,0) = u_eval; - u_temp(0,1) = v_eval; - u_temp(0,2) = 0.0; + evalRbfDer(0, u_vec, u_vec_eval,xyz_local, temp_nodes_eval); + nodes_eval(0,0) = temp_nodes_eval(0,0); + nodes_eval(0,1) = temp_nodes_eval(0,1); + nodes_eval(0,2) = temp_nodes_eval(0,2); _inUV= 0; + evalRbfDer(0,xyz_local,nodes_eval,u_vec,temp_u_temp); + u_temp(0,0) = temp_u_temp(0,0); + u_temp(0,1) = temp_u_temp(0,1); + u_temp(0,2) = temp_u_temp(0,2); - //we use the closest point - // nodes_eval(0,0) = extendedX(index[0],0); - // nodes_eval(0,1) = extendedX(index[0],1); - // nodes_eval(0,2) = extendedX(index[0],2); - // u_temp(0,0) = UV(index[0],0); - // u_temp(0,1) = UV(index[0],1); - // u_temp(0,2) = 0.0; + //we use the closest point + for (int i_nbr = 1; i_nbr < N_nbr; i_nbr++){ + nodes_eval(i_nbr,0) = extendedX(index[i_nbr-1],0); + nodes_eval(i_nbr,1) = extendedX(index[i_nbr-1],1); + nodes_eval(i_nbr,2) = extendedX(index[i_nbr-1],2); + u_temp(i_nbr,0) = UV(index[i_nbr-1],0); + u_temp(i_nbr,1) = UV(index[i_nbr-1],1); + u_temp(i_nbr,2) = 0.0; + } delete [] index; delete [] dist; - + int incr = 0; double norm = 0.0; - fullMatrix<double> Jac(3,3); - while(norm < 5 && incr < 10){ - + double norm_temp = 0.0; + double dist_test = 0.0; + fullMatrix<double> Jac(3,3),best_Jac(3,3); + fullMatrix<double> normDist(N_nbr,1); + fullMatrix<double> nodes_eval_temp(N_nbr,3); + double norm_treshhold = 8.0; + std::vector<fullMatrix<double> >JacV; + + while(norm < norm_treshhold && incr < 10){ // Find the entries of the m Jacobians evalRbfDer(1,xyz_local,nodes_eval,u_vec,ux); evalRbfDer(2,xyz_local,nodes_eval,u_vec,uy); evalRbfDer(3,xyz_local,nodes_eval,u_vec,uz); - - // Jacobian of the UVS coordinate system w.r.t. XYZ - for (int k = 0; k < 3;k++){ - Jac(k,0) = ux(0,k); - Jac(k,1) = uy(0,k); - Jac(k,2) = uz(0,k); - } - Jac.invertInPlace(); - - for (int j = 0; j< 3;j++) - nodes_eval(0,j) = nodes_eval(0,j) - + Jac(j,0)*( u_vec_eval(0,0) - u_temp(0,0)) - + Jac(j,1)*( u_vec_eval(0,1) - u_temp(0,1)) - + Jac(j,2)*( 0.0 - u_temp(0,2)); - + + for (int i_nbr = 0; i_nbr < N_nbr; i_nbr++){ + // Jacobian of the UVS coordinate system w.r.t. XYZ + for (int k = 0; k < 3;k++){ + Jac(k,0) = ux(i_nbr,k); + Jac(k,1) = uy(i_nbr,k); + Jac(k,2) = uz(i_nbr,k); + } + Jac.invertInPlace(); + JacV.push_back(Jac); + + for (int j = 0; j< 3;j++) + nodes_eval(i_nbr,j) = nodes_eval(i_nbr,j) + + Jac(j,0)*( u_vec_eval(0,0) - u_temp(i_nbr,0)) + + Jac(j,1)*( u_vec_eval(0,1) - u_temp(i_nbr,1)) + + Jac(j,2)*( 0.0 - u_temp(i_nbr,2)); + } // Find the corresponding u, v, s evalRbfDer(0,xyz_local,nodes_eval,u_vec,u_temp); - - double normDist = sqrt((u_temp(0,0)-u_eval)*(u_temp(0,0)-u_eval)+(u_temp(0,1)-v_eval)*(u_temp(0,1)-v_eval)+(u_temp(0,2)*u_temp(0,2))); - norm = fabs(log10(normDist)); + norm = 0; + for (int i_nbr = 0; i_nbr < N_nbr; i_nbr++){ + normDist(i_nbr,0) = sqrt((u_temp(i_nbr,0)-u_vec_eval(0,0))*(u_temp(i_nbr,0)-u_vec_eval(0,0))+(u_temp(i_nbr,1)-u_vec_eval(0,1))*(u_temp(i_nbr,1)-u_vec_eval(0,1))+(u_temp(i_nbr,2)*u_temp(i_nbr,2))); + norm_temp = -(log10(normDist(i_nbr,0))); + + if (norm_temp>norm_treshhold){ + norm = norm_temp; + nodes_vec_eval(0,0)=nodes_eval(i_nbr,0); + nodes_vec_eval(0,1)=nodes_eval(i_nbr,1); + nodes_vec_eval(0,2)=nodes_eval(i_nbr,2); + + u_test_vec_eval(0,0)=u_temp(i_nbr,0); + u_test_vec_eval(0,1)=u_temp(i_nbr,1); + u_test_vec_eval(0,2)=u_temp(i_nbr,2); + + best_Jac = JacV[i_nbr]; + dist_test = normDist(i_nbr,0); + i_nbr=N_nbr; //To get out of the for loof and thus also to get out of the while loop + } + } + incr++; +} - incr++; - } - if (norm < 5 ){ - printf("Newton not converged (norm=%g) for uv=(%g,%g) UVS=(%g,%g,%g) NB=%d \n", norm, u_eval, v_eval, u_temp(0,0), u_temp(0,1), u_temp(0,2), num_neighbours); - //converged = false; - return UVStoXYZ(u_eval, v_eval, XX, YY,ZZ, dXdu, dXdv, num_neighbours+5); - } +if (norm < norm_treshhold ){ + printf("Newton not converged (norm=%g, dist=%g) for uv=(%g,%g) UVS=(%g,%g,%g) NB=%d \n", norm, dist_test,u_eval, v_eval, u_test_vec_eval(0,0), u_test_vec_eval(0,1), u_test_vec_eval(0,2), num_neighbours); + //converged = false; + return UVStoXYZ(u_eval, v_eval, XX, YY,ZZ, dXdu, dXdv, num_neighbours+5); + } - XX = nodes_eval(0,0); - YY = nodes_eval(0,1); - ZZ = nodes_eval(0,2); - dXdu = SVector3(Jac(0,0), Jac(1,0), Jac(2,0)); - dXdv = SVector3(Jac(0,1), Jac(1,1), Jac(2,1)); - - return converged; +XX = nodes_vec_eval(0,0); +YY = nodes_vec_eval(0,1); +ZZ = nodes_vec_eval(0,2); +dXdu = SVector3(best_Jac(0,0), best_Jac(1,0), best_Jac(2,0)); +dXdv = SVector3(best_Jac(0,1), best_Jac(1,1), best_Jac(2,1)); +// printf("Converged (norm=%g, dist=%g) for uv=(%g,%g) UVS=(%g,%g,%g) NB=%d \n", norm, dist_test,u_eval, v_eval,u_test_vec_eval(0,0), u_test_vec_eval(0,1), u_test_vec_eval(0,2), num_neighbours); + printf("Converged (norm=%g, dist=%g) for uvs-UVS=(%g,%g,%g) NB=%d \n", norm, dist_test,u_eval-u_test_vec_eval(0,0), v_eval-u_test_vec_eval(0,1), u_test_vec_eval(0,2), num_neighbours); +return converged; #endif } -- GitLab