MeshKit
1.0
|
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 }