MeshKit  1.0
GreenCoordinates3D.cpp
Go to the documentation of this file.
00001 #include "GreenCoordinates3D.hpp"
00002 #include <iostream>
00003 #include <math.h>
00004 #include <map>
00005 
00006 
00007 
00008 
00009 namespace MeshKit {
00010 
00011 GreenCoordinates3D::GreenCoordinates3D(MKCore* core, vector< vector<double> > iNodes)
00012 {
00013         mk_core = core;
00014         InteriorNodes.resize(iNodes.size());
00015         for (unsigned int i = 0; i < iNodes.size(); i++){
00016                 InteriorNodes[i].resize(3);
00017                 for (int j = 0; j < 3; j++)
00018                         InteriorNodes[i][j] = iNodes[i][j];
00019         }
00020         
00021 }
00022 
00023 //Setup the cages for surface mesh
00024 void GreenCoordinates3D::SetupCages(vector<vector<double> > cageNodes, vector< vector<int> > cageFaces, vector<vector<double> > normal)
00025 {
00026         int num_CageNodes = cageNodes.size(), num_CageFaces = cageFaces.size(); 
00027         CageNodes.resize(num_CageNodes);
00028         CageFaces.resize(num_CageFaces);
00029         
00030         for (int i = 0; i < num_CageNodes; i++){
00031                 int size_j = cageNodes[i].size();
00032                 CageNodes.resize(size_j);
00033                 for (int j = 0; j < size_j; j++)
00034                         CageNodes[i][j] = cageNodes[i][j];
00035         }
00036 
00037         for (int i = 0; i < num_CageFaces; i++){
00038                 int size_j = CageFaces[i].size();
00039                 CageFaces.resize(size_j);
00040                 for (int j = 0; j < size_j; j++)
00041                         CageFaces[i][j] = cageFaces[i][j];
00042         }
00043 
00044         Normals.resize(normal.size());
00045         for (unsigned int i = 0; i < normal.size(); i++){
00046                 unsigned int size_j = normal[i].size();
00047                 Normals[i].resize(size_j);
00048                 for (unsigned int j = 0; j < size_j; j++)               
00049                         Normals[i][j] = normal[i][j];
00050         }
00051 }
00052 
00053 //calculate the green coordinates
00054 void GreenCoordinates3D::Execute()
00055 {
00056         //Initialization
00057         double error = 1.0e-5;
00058         weight_t.resize(InteriorNodes.size());
00059         weight_v.resize(InteriorNodes.size());
00060         for (unsigned int i = 0; i < weight_t.size(); i++){
00061                 weight_t[i].resize(CageFaces.size());           
00062                 for (unsigned int j = 0; j < CageFaces.size(); j++)
00063                         weight_t[i][j] = 0.0;
00064         }
00065 
00066         for (unsigned int i = 0; i < weight_v.size(); i++){
00067                 weight_v[i].resize(CageNodes.size());
00068                 for (unsigned int j = 0; j < CageNodes.size(); j++)             
00069                         weight_v[i][j] = 0.0;
00070         }
00071 
00072         //Main Loop--Calculate the weight for cage nodes and cage face normal
00073         //From the appendix of the paper: Green Coordinates, Yaron Lipman, David Levin, Daniel Cohen-Or
00074         for (unsigned int i = 0; i < InteriorNodes.size(); i++){
00075                 for (unsigned int j = 0; j < CageFaces.size(); j++){
00076                         vector<vector<double> > node(3, vector<double>(3));
00077                         for (int k = 0; k < 3; k++){
00078                                 node[0][k] = CageNodes[CageFaces[j][0]][k] - InteriorNodes[i][k];
00079                                 node[1][k] = CageNodes[CageFaces[j][1]][k] - InteriorNodes[i][k];
00080                                 node[2][k] = CageNodes[CageFaces[j][2]][k] - InteriorNodes[i][k];
00081                         }
00082                         double mag = node[0][0]*Normals[j][0] + node[1][1]*Normals[j][1] + node[2][2]*Normals[j][2];
00083                         vector<double> p(3);
00084                         for (int k = 0; k < 3; k++)
00085                                 p[k] = mag*Normals[j][k];
00086 
00087                         vector<double> s(3),I(3),II(3);
00088                         vector<vector<double> > q(3, vector<double>(3)), N(3, vector<double>(3));
00089                         for (int k = 0; k < 3; k++){
00090                                 vector<double> ivector(3), jvector(3);
00091                                 for (int l = 0; l < 3; l++){
00092                                         ivector[l] = node[k][l] - p[l];
00093                                         jvector[l] = node[(k+1)%3][l]- p[l];
00094                                 }
00095                                 vector<double> crossproduct(3);
00096                                 crossproduct[0] = ivector[1]*jvector[2] - ivector[2]*jvector[1];
00097                                 crossproduct[1] = -1.0*(ivector[0]*jvector[2]-ivector[2]*jvector[0]);
00098                                 crossproduct[2] = ivector[0]*jvector[1] - ivector[1]*jvector[0];
00099                                 double dotproduct = crossproduct[0]*Normals[j][0]+crossproduct[1]*Normals[j][1]+crossproduct[2]*Normals[j][2];
00100                                 s[k] = dotproduct>0? 1.0:-1.0;
00101                                 vector<double> tmp(3);
00102                                 tmp[0] = 0.0; tmp[1] = 0.0; tmp[2] = 0.0;
00103                                 I[k] = GCTriInt(p, node[k], node[(k+1)%3], tmp);
00104                                 II[k] = GCTriInt(tmp, node[k], node[(k+1)%3], tmp);     
00105 
00106                                 q[k][0] = node[(k+1)%3][1]*node[k][2]-node[(k+1)%3][2]*node[k][1];
00107                                 q[k][1] = -1.0*(node[(k+1)%3][0]*node[k][2]-node[(k+1)%3][2]*node[k][0]);
00108                                 q[k][2] = node[(k+1)%3][0]*node[k][1]-node[(k+1)%3][1]*node[k][0];
00109 
00110                                 mag = sqrt(pow(q[k][0],2) + pow(q[k][1],2) + pow(q[k][2], 2));
00111                                 N[k][0] = q[k][0]/mag;
00112                                 N[k][1] = q[k][1]/mag;
00113                                 N[k][2] = q[k][2]/mag;                                          
00114                         }
00115 
00116                         double I_scalar = -1.0*fabs(s[0]*I[0]+s[1]*I[1]+s[2]*I[2]);
00117                         weight_t[i][j] = -1.0*I_scalar;
00118                         
00119                         vector<double> w(3);
00120                         w[0] = I_scalar*Normals[j][0] + N[0][0]*I_scalar*I[0] + N[1][0]*I_scalar*I[1] + N[2][0]*I_scalar*I[2];
00121                         w[1] = I_scalar*Normals[j][1] + N[0][1]*I_scalar*I[0] + N[1][1]*I_scalar*I[1] + N[2][1]*I_scalar*I[2];
00122                         w[2] = I_scalar*Normals[j][2] + N[0][2]*I_scalar*I[0] + N[1][2]*I_scalar*I[1] + N[2][2]*I_scalar*I[2];
00123 
00124                         double w_mag = sqrt(pow(w[0],2)+pow(w[1],2)+pow(w[2],2));
00125                         if (w_mag > error)//this guarantees the local deformation property
00126                                 for (int k = 0; k < 3; k++)
00127                                         weight_v[i][CageFaces[j][k]] += (N[(k+1)%3][0]*w[0]+N[(k+1)%3][1]*w[1]+N[(k+1)%3][2]*w[2])/(N[(k+1)%3][0]*node[k][0]+N[(k+1)%3][1]*node[k][1]+N[(k+1)%3][2]*node[k][2]);
00128                                 
00129                         
00130                 }
00131 
00132         }
00133 }
00134 
00135 
00136 
00137 double GreenCoordinates3D::GCTriInt(vector<double> p, vector<double> v1, vector<double> v2, vector<double> iNodes)
00138 {
00139         //calculate the angle
00140         double dotproduct_21p1 = (v2[0]-v1[0])*(p[0]-v1[0]) + (v2[1]-v1[1])*(p[1]-v1[1]) + (v2[2]-v1[2])*(p[2]-v1[2]);
00141         double dotproduct_1p2p = (v1[0]-p[0])*(v2[0]-p[0]) + (v1[1]-p[1])*(v2[1]-p[1]) + (v1[2]-p[2])*(v2[2]-p[2]);
00142         double mag_21 = sqrt((v2[0]-v1[0])*(v2[0]-v1[0])+(v2[1]-v1[1])*(v2[1]-v1[1])+(v2[2]-v1[2])*(v2[2]-v1[2]));
00143         double mag_p1 = sqrt((p[0]-v1[0])*(p[0]-v1[0])+(p[1]-v1[1])*(p[1]-v1[1])+(p[2]-v1[2])*(p[2]-v1[2]));
00144         double mag_p2 = sqrt((p[0]-v2[0])*(p[0]-v2[0])+(p[1]-v2[1])*(p[1]-v2[1])+(p[2]-v2[2])*(p[2]-v2[2]));
00145 
00146         double alpha = acos(dotproduct_21p1/(mag_21*mag_p1));
00147         double belta = acos(dotproduct_1p2p/(mag_p1*mag_p2));
00148 
00149         double lambda = pow(mag_p1,2)*pow(sin(alpha), 2);
00150         double c = pow(p[0]-iNodes[0],2) + pow(p[1]-iNodes[1],2) + pow(p[2]-iNodes[2],3);
00151 
00152         double pi = atan(1.0)*4.0;
00153         double S = sin(pi-alpha), C = cos(pi-alpha);
00154         double theta_pi_alpha = -1.0*(S >0? 1.0:-1.0)*0.5*(2.0*sqrt(C)*atan(sqrt(c)*C/sqrt(lambda+S*S*c)) + sqrt(lambda)*log(2*sqrt(lambda)*pow(S,2)*(1-2*c*C/(c*(1+C)+lambda+sqrt(pow(lambda,2)+lambda*c*pow(S,2))))/pow(1-C,2)));
00155         
00156         S = sin(pi-alpha-belta);
00157         C = cos(pi-alpha-belta);
00158         double theta_pi_alpha_belta = -1.0*(S >0? 1.0:-1.0)*0.5*(2.0*sqrt(C)*atan(sqrt(c)*C/sqrt(lambda+S*S*c)) + sqrt(lambda)*log(2*sqrt(lambda)*pow(S,2)*(1-2*c*C/(c*(1+C)+lambda+sqrt(pow(lambda,2)+lambda*c*pow(S,2))))/pow(1-C,2)));
00159 
00160         return -1.0*fabs(theta_pi_alpha-theta_pi_alpha_belta-sqrt(c)*belta)/(4*pi);     
00161 }
00162 
00163 
00164 //input new cage and calculate deformed interior points based on the existing weights for cage vertices and cage face normals
00165 void GreenCoordinates3D::GetDeformedVertices(vector< vector<double> > nodes, vector< vector<double> > norm, vector<vector<double> > &ReturnNodes)
00166 {
00167         ReturnNodes.resize(InteriorNodes.size());
00168         //loop over the interior nodes
00169         for (unsigned int i = 0; i < InteriorNodes.size(); i++){
00170                 ReturnNodes[i].resize(3);
00171                 for (int j = 0; j < 3; j++)
00172                         ReturnNodes[i][j] = 0.0;
00173                 //consider the effect of cage nodes             
00174                 for (unsigned int j = 0; j < nodes.size(); j++)
00175                         for (int k = 0; k < 3; k++)
00176                                 ReturnNodes[i][k] += weight_v[i][j]*nodes[j][k];
00177                 
00178                 //consider the effect of cage face normals
00179                 for (unsigned int j = 0; j < norm.size(); j++)
00180                         for (int k = 0; k < 3; k++)
00181                                 ReturnNodes[i][k] += weight_t[i][j]*norm[j][k];
00182         }
00183 }
00184 
00185 GreenCoordinates3D::~GreenCoordinates3D()
00186 {
00187         cout << "It is over now in calculating the green coordinates for " << endl;
00188 }
00189 
00190 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines