www.pudn.com > AdRBF.rar > AdRbfGenerator.h
#ifndef ADRBFGENERATOR #define ADRBFGENERATOR #include "PointSet.h" #include "AxisKdTree.h" #include "BasisFunction.h" #include "EvaluationTreeD.h" #include "PBCG.h" #include#include #include "SVD.h" #include "jacobi.h" class ElementList{ public: int index; ElementList* next; double c; ~ElementList(){ if(next != NULL) delete next; } void add(int i, double w){ if(index == i) c += w; else{ if(next == NULL){ next = new ElementList; next->index = i; next->c = w; next->next = NULL; } else next->add(i, w); } } }; class GraphNode{ public: int index; GraphNode* next; GraphNode(){ index = -1; next = NULL; } ~GraphNode(){ if(next != NULL) delete next; } void add(int i){ if(index < 0){ index = i; } else if(index == i) return; else{ if(next == NULL){ next = new GraphNode; next->index = i; next->next = NULL; } else next->add(i); } } }; class AdRbfGenerator{ public: PointSet* ps; AxisKdTree* tree; int canN; float overlapT; float e0; int bfN; BasisFunction** bfs; float dia; AdRbfGenerator(PointSet* ps){ this->ps = ps; canN = 15; overlapT = 1.5f; float max[3], min[3]; ps->getBound(min, max, 1.0); float sx = max[0] - min[0]; float sy = max[1] - min[1]; float sz = max[2] - min[2]; dia = (float)sqrt(sx*sx + sy*sy + sz*sz); e0 = 0.0001f; } void generate(){ //quadric approx. generateBfsQB(); //linear approx. //generateBfsPB(); //RBF fitting globalFit(); //Oriented normals are unknown case. //createOrientation(); //printError(); } void globalFit(){ int i,j,k; int M = bfN; float max[3], min[3]; ps->getBound(min, max, 1.2f); EvaluationTreeD* func = new EvaluationTreeD(min, max); func->addBFS(bfs, M); func->out = 0; int N = ps->_pointN; float (*full_point)[3] = ps->_point; float *value = ps->_value; double L2_before=0, L2_after=0; double Lmax_before=0, Lmax_after=0; ElementList** element_list = new ElementList*[M]; double* b = new double[M+1]; for(i=0; i index = i; element_list[i]->c = 0; element_list[i]->next = NULL; b[i+1] = 0; } int listN, *list; double* weight; float total_value = 0; for(i=0; i valueAndGradient1(g, p[0], p[1], p[2])*value[i]; double g2 = g[0]*g[0]+g[1]*g[1]+g[2]*g[2]; if((float)g2 != 0){ total_value += value[i]; L2_before += v*v/g2; double e = fabs(v)/sqrt(g2); if(Lmax_before < e) Lmax_before = e; } func->collectIndexInSupport(list, weight, listN, p); for(j=0; j add(i1, w1*w1); for(k=j+1; k add(i2, w); element_list[i2]->add(i1, w); } b[i1+1] += v*w1; } if(i%1000 == 0){ printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%d points are processed.", i); //cout << i << "points are processed." << endl; } } cout << endl; int total = 0; for(i=0; i next) total++; cout << "Non-zero element in the matrix; " << total << endl; PBCG solver; double *sa = solver.sa = new double[total+2]; unsigned long *ija = solver.ija = new unsigned long[total+2]; double* sol = new double[bfN+1]; ija[1]=bfN+2; int kk=bfN+1; int* i_tmp = new int[M-1]; double* w_tmp = new double[M-1]; for(i=0; i next){ if(e->index != i){ i_tmp[m] = e->index; w_tmp[m] = e->c; m++; } else{ //diagonal element sa[i+1] = e->c; } } //sort delete element_list[i]; for(j=0; j i_tmp[k]){ int tmp = i_tmp[j]; i_tmp[j] = i_tmp[k]; i_tmp[k] = tmp; double tmp2 = w_tmp[j]; w_tmp[j] = w_tmp[k]; w_tmp[k] = tmp2; } } } for(j=0; j c0 += (float)sol[i+1]; } delete[] sol; for(i=0; i valueAndGradient1(g, p[0], p[1], p[2])*value[i]; double g2 = g[0]*g[0]+g[1]*g[1]+g[2]*g[2]; if((float)g2 != 0){ L2_after += v*v/g2; double e = fabs(v)/sqrt(g2); if(Lmax_after < e) Lmax_after = e; } } cout << "L2 before" << sqrt(L2_before/total_value)/dia << endl; cout << "L2 after " << sqrt(L2_after/total_value)/dia << endl; cout << "Lmax before" << Lmax_before/dia << endl; cout << "Lmax after " << Lmax_after/dia << endl; } void generateBfsQB(){ int N = ps->_pointN; float (*point)[3] = ps->_point; float (*normal)[3] = ps->_normal; float *conf = ps->_value; tree = new AxisKdTree(ps); float* overlap = new float[N]; int* active_table = new int[N]; int activeN = 0; int tableN = 0; int i,j; for(i=0; i 0.2){ overlap[i] = 0; active_table[activeN++] = i; } } cout << activeN << " points are candidates of centers" << endl; N = tableN = activeN; float w0 = (float)BasisFunction::weight(0, 1); bfN = 0; BFlist* bf_list = new BFlist(); bf_list->next = NULL; int* can = new int[canN]; long idum = 1; //For counter to stdout int pre_activeN = activeN; int percent = 0; float e0r = e0*dia; while(activeN > canN){ for(j=0; j = overlapT) j--; } //search minimun from multiple-choice int index = can[0]; for(j=1; j overlap[can[j]]) index = can[j]; } overlap[index] = overlapT; activeN--; float *center = point[index]; float scaleL = 50*e0r; float scaleS = e0r; BasisFunction* bf = new BasisFunction; float scale, error; error = localFitQ(center, scaleL, bf); //error = localFitQwithCV(center, scaleL, bf); while(error < e0r){ scaleS = scaleL; scaleL *= 2; error = localFitQ(center, scaleL, bf); //error = localFitQwithCV(center, scaleL, bf); } for(j=0; j<10; j++){ scale = 0.5f*(scaleS + scaleL); error = localFitQ(center, scale, bf); //error = localFitQwithCV(center, scale, bf); if(error > e0r) scaleL = scale; else{ scaleS = scale; } } if(error == 0){ scale = bf->support = scaleL; } //updtae overlap float R = scale; int *list, listN; tree->collectPointIndexInSphere(list, listN, center, scale); for(j=0; j d){ float w = (float)BasisFunction::weight(d, R)/w0; if(overlap[in] < overlapT){ overlap[in] += w; if(overlap[in] >= overlapT) activeN--; } else overlap[in] += w; } } //Add basis function to the list bf->level = 1; BFlist* l = new BFlist; l->next = bf_list; l->bf = bf; bf_list = l; bfN++; if(activeN < tableN/2){ //resize table int count = 0; for(j=0; j percent) printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b%d %%", ++percent); //cout << ++percent << " %" << endl; pre_activeN = activeN; } cout << endl; delete tree; delete[] overlap; delete[] active_table; bfs = new BasisFunction*[bfN]; int count = 0; for(BFlist* l=bf_list; l->next!=NULL; l=l->next){ bfs[count] = l->bf; bfs[count]->index = count; count++; } //delete bf_list; cout << bfN << " basis functions" << endl; } float localFitQ(float center[3], float scale, BasisFunction* bf){ float (*point)[3] = ps->_point; float (*normal)[3] = ps->_normal; bf->centerX = center[0]; bf->centerY = center[1]; bf->centerZ = center[2]; bf->support = scale; int *list, listN; tree->collectPointIndexInSphere(list, listN, center, scale); if(listN < 10) return 0; float n[3], t1[3], t2[3]; computeNormal(n, list, listN, bf); computeTangent(t1, t2, n); float **A = new float*[7]; float *b = new float[7]; int i; for(i=1; i<7; i++){ A[i] = new float[7]; A[i][1] = A[i][2] = A[i][3] = A[i][4] = A[i][5] = A[i][6] = b[i] = 0; } for(i=0; i wmax) wmax=(float)fabs(w[k]); /* if(wmax < 0.000000000001f){ bf_N--; return; }*/ float wmin=wmax*0.0000001f; for (k=1;k<7;k++){ if (fabs(w[k]) < wmin) w[k]=0.0; } SVD::svbksb(A, w, v, 6, 6, b, x); for(i=1; i<7; i++) delete[] A[i]; delete[] A; for(i=1; i<7; i++) delete[] v[i]; delete[] v; delete[] b; float cuu = x[1]; float cuv = x[2]; float cvv = x[3]; float cu = x[4]; float cv = x[5]; float c0 = x[6]; bf->cXX = -(cuu*t1[0]*t1[0] + cvv*t2[0]*t2[0] + cuv*t1[0]*t2[0]); bf->cYY = -(cuu*t1[1]*t1[1] + cvv*t2[1]*t2[1] + cuv*t1[1]*t2[1]); bf->cZZ = -(cuu*t1[2]*t1[2] + cvv*t2[2]*t2[2] + cuv*t1[2]*t2[2]); bf->cXY = -(2.0f*(cuu*t1[0]*t1[1] + cvv*t2[0]*t2[1]) + cuv*(t1[0]*t2[1] + t1[1]*t2[0])); bf->cYZ = -(2.0f*(cuu*t1[1]*t1[2] + cvv*t2[1]*t2[2]) + cuv*(t1[1]*t2[2] + t1[2]*t2[1])); bf->cZX = -(2.0f*(cuu*t1[2]*t1[0] + cvv*t2[2]*t2[0]) + cuv*(t1[2]*t2[0] + t1[0]*t2[2])); bf->cX = n[0] - cu*t1[0] - cv*t2[0]; bf->cY = n[1] - cu*t1[1] - cv*t2[1]; bf->cZ = n[2] - cu*t1[2] - cv*t2[2]; bf->c0 = -c0; //compute L2 error double error = 0; double totalW = 0; for(i=0; i _point; //float (*normal)[3] = ps->_normal; float *conf = ps->_value; bf->centerX = center[0]; bf->centerY = center[1]; bf->centerZ = center[2]; bf->support = scale; int *list, listN; tree->collectPointIndexInSphere(list, listN, center, scale); float sumC = 0; for(i=0; i w[3]) mini = 3; n[0] = v[1][mini]; n[1] = v[2][mini]; n[2] = v[3][mini]; //orientation checking /* float dotS = 0; for(i=0; i wmax) wmax=(float)fabs(w[k]); /* if(wmax < 0.000000000001f){ bf_N--; return; }*/ float wmin=wmax*0.0000001f; for (k=1;k<7;k++){ if (fabs(w[k]) < wmin) w[k]=0.0; } SVD::svbksb(A, w, v, 6, 6, b, x); for(i=1; i<7; i++) delete[] A[i]; delete[] A; for(i=1; i<7; i++) delete[] v[i]; delete[] v; delete[] b; float cuu = x[1]; float cuv = x[2]; float cvv = x[3]; float cu = x[4]; float cv = x[5]; float c0 = x[6]; bf->cXX = -(cuu*t1[0]*t1[0] + cvv*t2[0]*t2[0] + cuv*t1[0]*t2[0]); bf->cYY = -(cuu*t1[1]*t1[1] + cvv*t2[1]*t2[1] + cuv*t1[1]*t2[1]); bf->cZZ = -(cuu*t1[2]*t1[2] + cvv*t2[2]*t2[2] + cuv*t1[2]*t2[2]); bf->cXY = -(2.0f*(cuu*t1[0]*t1[1] + cvv*t2[0]*t2[1]) + cuv*(t1[0]*t2[1] + t1[1]*t2[0])); bf->cYZ = -(2.0f*(cuu*t1[1]*t1[2] + cvv*t2[1]*t2[2]) + cuv*(t1[1]*t2[2] + t1[2]*t2[1])); bf->cZX = -(2.0f*(cuu*t1[2]*t1[0] + cvv*t2[2]*t2[0]) + cuv*(t1[2]*t2[0] + t1[0]*t2[2])); bf->cX = n[0] - cu*t1[0] - cv*t2[0]; bf->cY = n[1] - cu*t1[1] - cv*t2[1]; bf->cZ = n[2] - cu*t1[2] - cv*t2[2]; bf->c0 = -c0; //compute L2 error double error = 0; double totalW = 0; for(i=0; i error) //error = e; } return sqrt(error/listN); //dia; //cout << scale << "::" << error << endl; //return error; } float localFitPwithCV(float center[3], float scale, BasisFunction* bf){ int i; float (*point)[3] = ps->_point; float (*normal)[3] = ps->_normal; bf->centerX = center[0]; bf->centerY = center[1]; bf->centerZ = center[2]; bf->support = scale; int *list, listN; tree->collectPointIndexInSphere(list, listN, center, scale); if(listN < 5) return 0; float n[3], t1[3], t2[3]; float **A = new float*[4]; float *b = new float[4]; for(i=1; i<4; i++){ A[i] = new float[4]; A[i][1] = A[i][2] = A[i][3] = b[i] = 0; } float w[4], x[4]; float **v = new float*[4]; for(i=1; i<4; i++) v[i] = new float[4]; //Computation of normal using CV method for(i=0; i w[3]) mini = 3; n[0] = v[1][mini]; n[1] = v[2][mini]; n[2] = v[3][mini]; //orientation checking /* float dotS = 0; for(i=0; i wmax) wmax=(float)fabs(w[k]); /* if(wmax < 0.000000000001f){ bf_N--; return; }*/ float wmin=wmax*0.0000001f; for (k=1;k<4;k++){ if (fabs(w[k]) < wmin) w[k]=0.0; } SVD::svbksb(A, w, v, 3, 3, b, x); for(i=1; i<4; i++) delete[] A[i]; delete[] A; for(i=1; i<4; i++) delete[] v[i]; delete[] v; delete[] b; float cuu = 0; float cuv = 0; float cvv = 0; float cu = x[1]; float cv = x[2]; float c0 = x[3]; bf->cXX = 0; bf->cYY = 0; bf->cZZ = 0; bf->cXY = 0; bf->cYZ = 0; bf->cZX = 0; bf->cX = n[0] - cu*t1[0] - cv*t2[0]; bf->cY = n[1] - cu*t1[1] - cv*t2[1]; bf->cZ = n[2] - cu*t1[2] - cv*t2[2]; bf->c0 = -c0; //compute L2 error double error = 0; double totalW = 0; for(i=0; i _pointN; float (*point)[3] = ps->_point; float (*normal)[3] = ps->_normal; tree = new AxisKdTree(ps); float* overlap = new float[N]; int* active_table = new int[N]; int activeN = N; int tableN = N; int i,j; for(i=0; i next = NULL; int* can = new int[canN]; long idum = 1; //For counter to stdout int pre_activeN = activeN; int percent = 0; while(activeN > canN){ for(j=0; j = overlapT) j--; } //search minimun from multiple-choice int index = can[0]; for(j=1; j overlap[can[j]]) //if(overlap[index]*value[index] > overlap[can[j]]*value[can[j]]) index = can[j]; } overlap[index] = overlapT; activeN--; float *center = point[index]; float scaleL = 50*e0*dia; float scaleS = e0*dia; BasisFunction* bf = new BasisFunction; float scale, error; error = localFitPwithCV(center, scaleL, bf); while(error < e0){ scaleS = scaleL; scaleL *= 2; error = localFitPwithCV(center, scaleL, bf); } for(j=0; j<10; j++){ scale = 0.5f*(scaleS + scaleL); error = localFitPwithCV(center, scale, bf); //cout << j << ", " << scale << ", " << error << endl; if(error > e0) scaleL = scale; else{ scaleS = scale; } } if(error == 0){ bf->support = scaleL; } //updtae overlap float R = scale; int *list, listN; tree->collectPointIndexInSphere(list, listN, center, scale); for(j=0; j d){ float w = (float)BasisFunction::weight(d, R)/w0; if(overlap[in] < overlapT){ overlap[in] += w; if(overlap[in] >= overlapT) activeN--; } else overlap[in] += w; } } //Add basis function to the list bf->level = 1; BFlist* l = new BFlist; l->next = bf_list; l->bf = bf; bf_list = l; bfN++; if(activeN < tableN/2){ //resize table int count = 0; for(j=0; j percent) printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b%d %%", ++percent); //cout << ++percent << " %" << endl; pre_activeN = activeN; } cout << endl; delete tree; delete[] overlap; delete[] active_table; bfs = new BasisFunction*[bfN]; int count = 0; for(BFlist* l=bf_list; l->next!=NULL; l=l->next){ bfs[count] = l->bf; bfs[count]->index = count; count++; } //delete bf_list; cout << bfN << " basis functions" << endl; } float localFitP(float center[3], float scale, BasisFunction* bf){ float (*point)[3] = ps->_point; float (*normal)[3] = ps->_normal; bf->centerX = center[0]; bf->centerY = center[1]; bf->centerZ = center[2]; bf->support = scale; int *list, listN; tree->collectPointIndexInSphere(list, listN, center, scale); if(listN < 6) return 0; float n[3], t1[3], t2[3]; computeNormal(n, list, listN, bf); computeTangent(t1, t2, n); float **A = new float*[4]; float *b = new float[4]; int i; for(i=1; i<4; i++){ A[i] = new float[4]; A[i][1] = A[i][2] = A[i][3] = b[i] = 0; } for(i=0; i wmax) wmax=(float)fabs(w[k]); /* if(wmax < 0.000000000001f){ bf_N--; return; }*/ float wmin=wmax*0.0000001f; for (k=1;k<4;k++){ if (fabs(w[k]) < wmin) w[k]=0.0; } SVD::svbksb(A, w, v, 3, 3, b, x); for(i=1; i<4; i++) delete[] A[i]; delete[] A; for(i=1; i<4; i++) delete[] v[i]; delete[] v; delete[] b; float cu = x[1]; float cv = x[2]; float c0 = x[3]; bf->cXX = 0; bf->cYY = 0; bf->cZZ = 0; bf->cXY = 0; bf->cYZ = 0; bf->cZX = 0; bf->cX = n[0] - cu*t1[0] - cv*t2[0]; bf->cY = n[1] - cu*t1[1] - cv*t2[1]; bf->cZ = n[2] - cu*t1[2] - cv*t2[2]; bf->c0 = -c0; //compute L2 error double error = 0; double totalW = 0; for(i=0; i getBound(min, max, 1.2f); EvaluationTreeD* func = new EvaluationTreeD(min, max); func->addBFS(bfs, M); func->out = 0; int N = ps->_pointN; float (*full_point)[3] = ps->_point; GraphNode** nodes = new GraphNode*[M]; for(i=0; i collectIndexInSupport(list, weight, listN, p); for(j=0; j add(i2); nodes[i2]->add(i1); } } } delete func; cout << "A conectivity graph is created." << endl; /* GraphNode** tree = new GraphNode*[M]; for(i=0; i centerZ < bfs[i]->centerZ){ bf = bfs[i]; update = i; } } float g[3]; bf->gradientP(g, bf->centerX, bf->centerY, bf->centerZ); if(g[2] > 0){ bf->cXX = -bf->cXX; bf->cYY = -bf->cYY; bf->cZZ = -bf->cZZ; bf->cXY = -bf->cXY; bf->cYZ = -bf->cYZ; bf->cZX = -bf->cZX; bf->cX = -bf->cX; bf->cY = -bf->cY; bf->cZ = -bf->cZ; bf->c0 = -bf->c0; } decide[update] = true; for(i=1; i next){ int j = c->index; if(decide[j]) continue; BasisFunction* bfj = bfs[j]; float w1 = bfj->support/(bfi->support + bfj->support); float w2 = bfi->support/(bfi->support + bfj->support); float x = w1*bfi->centerX + w2*bfj->centerX; float y = w1*bfi->centerY + w2*bfj->centerY; float z = w1*bfi->centerZ + w2*bfj->centerZ; float n1[3], n2[3]; bfi->gradientP(n1, x, y, z); bfj->gradientP(n2, x, y, z); normalize(n1); normalize(n2); float dot = n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2]; float d = (1.0f - fabs(dot)); /* float n1[3], n2[3], v[3]; bfi->gradientP(n1, bfi->centerX, bfi->centerY, bfi->centerZ); bfj->gradientP(n2, bfj->centerX, bfj->centerY, bfj->centerZ); v[0] = bfj->centerX - bfi->centerX; v[1] = bfj->centerY - bfi->centerY; v[2] = bfj->centerZ - bfi->centerZ; normalize(n1); normalize(n2); normalize(v); float d = (1.0f - fabs(n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2])); */ /* float c1[2], c2[2]; c1[0] = n1[1]*v[2] - n1[2]*v[1]; c1[1] = n1[2]*v[0] - n1[0]*v[2]; c1[2] = n1[0]*v[1] - n1[1]*v[0]; c2[0] = n2[1]*v[2] - n2[2]*v[1]; c2[1] = n2[2]*v[0] - n2[0]*v[2]; c2[2] = n2[0]*v[1] - n2[1]*v[0]; //normalize(c1); //normalize(c2); float d = (1.0f - 0.5f*(length(c1)+length(c2))); //float d = (1.0f - fabs(c1[0]*c2[0] + c1[1]*c2[1] + c1[2]*c2[2])); */ /* float dot = (c1[0]*c2[0] + c1[1]*c2[1] + c1[2]*c2[2]); float d = (n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2]) /(sqrt(n1[0]*n1[0]+n1[1]*n1[1]+n1[2]*n1[2]) * sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2])); if(d > 1.0f) d = 1.0f; else if(d < -1.0f) d = -1.0f; if(dot > 0){ d = acos(d); } else{ d = acos(-d); }*/ /* float n1[3], n2[3]; bfi->gradientP(n1, bfi->centerX, bfi->centerY, bfi->centerZ); bfj->gradientP(n2, bfi->centerX, bfi->centerY, bfi->centerZ); float dot1 = (float)(fabs(n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2]) /(sqrt(n1[0]*n1[0]+n1[1]*n1[1]+n1[2]*n1[2]) * sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]))); bfi->gradientP(n1, bfj->centerX, bfj->centerY, bfj->centerZ); bfj->gradientP(n2, bfj->centerX, bfj->centerY, bfj->centerZ); float dot2 = (float)(fabs(n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2]) /(sqrt(n1[0]*n1[0]+n1[1]*n1[1]+n1[2]*n1[2]) * sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]))); */ /* bfi->gradientP(n1, 0.5f*(bfi->centerX + bfj->centerX), 0.5f*(bfi->centerY + bfj->centerY), 0.5f*(bfi->centerZ + bfj->centerZ)); bfj->gradientP(n2, 0.5f*(bfi->centerX + bfj->centerX), 0.5f*(bfi->centerY + bfj->centerY), 0.5f*(bfi->centerZ + bfj->centerZ)); float dot3 = (float)(fabs(n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2]) /(sqrt(n1[0]*n1[0]+n1[1]*n1[1]+n1[2]*n1[2]) * sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]))); float d = (1.0f - 0.25f*(dot1 + 2.0f*dot3 + dot2));*/ //float d = (1.0f - 0.5f*(dot1+dot2)); /* float dot = bfi->normalX*bfj->normalX + bfi->normalY*bfj->normalY + bfi->normalZ*bfj->normalZ; float d = (1.0f - fabs(dot));*/ /* float vx = bfi->centerX - bfj->centerX; float vy = bfi->centerY - bfj->centerY; float vz = bfi->centerZ - bfj->centerZ; d = d*(float)sqrt(vx*vx + vy*vy + vz*vz);*/ if(cost[j] > d){ cost[j] = d; label[j] = update; if(index[j] < 0){ //insert into heap heap[++last_heap] = j; index[j] = last_heap; upheap(cost, last_heap, last_heap, heap, index); } else{ //update heap if(index[j] != 1 && cost[j] < cost[heap[index[j]/2]]) upheap(cost, last_heap, index[j], heap, index); else downheap(cost, last_heap, index[j], heap, index); } } } //remove top at heap int min = heap[1]; index[min] = -1; heap[1] = heap[last_heap--]; if(last_heap < 0){ cout << "Un-connected components may exist." << endl; break; } index[heap[1]] = 1; downheap(cost, last_heap, 1, heap, index); /* if(cost[min] > 0.1){ cout << cost[min] << ":" << i << endl; }*/ update = min; decide[update] = true; cost[update] = 0; int pair = label[update]; bfi = bfs[update]; BasisFunction* bfj = bfs[pair]; float w1 = bfj->support/(bfi->support + bfj->support); float w2 = bfi->support/(bfi->support + bfj->support); float x = w1*bfi->centerX + w2*bfj->centerX; float y = w1*bfi->centerY + w2*bfj->centerY; float z = w1*bfi->centerZ + w2*bfj->centerZ; float n1[3], n2[3]; bfi->gradientP(n1, x, y, z); bfj->gradientP(n2, x, y, z); float dot = n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2]; /* float n1[3], n2[3], v[3]; bfi->gradientP(n1, bfi->centerX, bfi->centerY, bfi->centerZ); bfj->gradientP(n2, bfj->centerX, bfj->centerY, bfj->centerZ); v[0] = bfj->centerX - bfi->centerX; v[1] = bfj->centerY - bfi->centerY; v[2] = bfj->centerZ - bfi->centerZ; float dot = n1[0]* n2[0] + n1[1]*n2[1] + n1[2]*n2[2]; float c1[2], c2[2]; c1[0] = n1[1]*v[2] - n1[2]*v[1]; c1[1] = n1[2]*v[0] - n1[0]*v[2]; c1[2] = n1[0]*v[1] - n1[1]*v[0]; c2[0] = n2[1]*v[2] - n2[2]*v[1]; c2[1] = n2[2]*v[0] - n2[0]*v[2]; c2[2] = n2[0]*v[1] - n2[1]*v[0]; float dot = (c1[0]*c2[0] + c1[1]*c2[1] + c1[2]*c2[2]);*/ /* bfi->gradientP(n1, bfi->centerX, bfi->centerY, bfi->centerZ); bfj->gradientP(n2, bfi->centerX, bfi->centerY, bfi->centerZ); float dot1 = (float)((n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2]) /(sqrt(n1[0]*n1[0]+n1[1]*n1[1]+n1[2]*n1[2]) * sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]))); bfi->gradientP(n1, bfj->centerX, bfj->centerY, bfj->centerZ); bfj->gradientP(n2, bfj->centerX, bfj->centerY, bfj->centerZ); float dot2 = (float)((n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2]) /(sqrt(n1[0]*n1[0]+n1[1]*n1[1]+n1[2]*n1[2]) * sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]))); */ /* bfi->gradientP(n1, 0.5f*(bfi->centerX + bfj->centerX), 0.5f*(bfi->centerY + bfj->centerY), 0.5f*(bfi->centerZ + bfj->centerZ)); bfj->gradientP(n2, 0.5f*(bfi->centerX + bfj->centerX), 0.5f*(bfi->centerY + bfj->centerY), 0.5f*(bfi->centerZ + bfj->centerZ)); float dot3 = (float)(fabs(n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2]) /(sqrt(n1[0]*n1[0]+n1[1]*n1[1]+n1[2]*n1[2]) * sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]))); float dot = dot1 + 2.0f*dot3 + dot2;*/ /* float dot = dot1 + dot2; if(fabs(dot) < 0.1f) cout << "Sharp feature or very high curvature region is found, maybe mistake: " << dot << endl; */ //float dot = bfi->normalX*bfj->normalX + bfi->normalY*bfj->normalY + bfi->normalZ*bfj->normalZ; if(dot < 0){ bfi->cXX = -bfi->cXX; bfi->cYY = -bfi->cYY; bfi->cZZ = -bfi->cZZ; bfi->cXY = -bfi->cXY; bfi->cYZ = -bfi->cYZ; bfi->cZX = -bfi->cZX; bfi->cX = -bfi->cX; bfi->cY = -bfi->cY; bfi->cZ = -bfi->cZ; bfi->c0 = -bfi->c0; } /* tree[update]->add(pair); tree[pair]->add(update);*/ } delete[] decide; delete[] cost; delete[] label; delete[] heap; delete[] index; for(i=0; i next) degree++; if(maxD < degree) maxD = degree; if(minD > degree) minD = degree; total += degree; } cout << (float)total/M << ":" << maxD << ":" << minD << endl;*/ } inline void normalize(float n[3]){ float len = (float)(sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2])); if(len != 0){ len = 1.0f/len; n[0] *= len; n[1] *= len; n[2] *= len; } } inline float length(float v[3]){ return (float)(sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2])); } inline void upheap(float *a, int N, int k, int *p, int *q){ int v; v = p[k]; while(k > 1 && a[p[k/2]] >= a[v]){ p[k] = p[k/2]; q[p[k/2]] = k; k = k/2; } p[k] = v; q[v] = k; } inline void downheap(float *a, int N, int k, int *p, int *q){ int j, v; v = p[k]; while(k <= N/2){ j = k+k; if(j < N && a[p[j]] > a[p[j+1]]) j++; if(a[v] <= a[p[j]]) break; p[k] = p[j]; q[p[j]] = k; k = j; } p[k] = v; q[v] = k; } inline bool computeNormal(float n[3], int* list, int listN, BasisFunction* bf){ n[0] = n[1] = n[2] = 0; float (*normal)[3] = ps->_normal; float (*point)[3] = ps->_point; for(int i=0; i weight(p[0], p[1], p[2]); //if(w < 0.99) // continue; n[0] += w*m[0]; n[1] += w*m[1]; n[2] += w*m[2]; } double len = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]); if((float)len == 0) return false; n[0] = (float)(n[0]/len); n[1] = (float)(n[1]/len); n[2] = (float)(n[2]/len); return true; } inline void computeTangent(float t1[3], float t2[3], float n[3]){ if(fabs(n[0]) < fabs(n[1])){ double l = sqrt(n[1]*n[1] + n[2]*n[2]); t1[0] = 0; t1[1] = -(float)(n[2]/l); t1[2] = (float)(n[1]/l); } else{ double l = sqrt(n[0]*n[0] + n[2]*n[2]); t1[0] = (float)(n[2]/l); t1[1] = 0; t1[2] = -(float)(n[0]/l); } t2[0] = n[1]*t1[2] - n[2]*t1[1]; t2[1] = n[2]*t1[0] - n[0]*t1[2]; t2[2] = n[0]*t1[1] - n[1]*t1[0]; } //From Numerical Recipes in C #define IA 16807 #define IM 2147483647 #define AM (1.0/IM) #define IQ 127773 #define IR 2836 #define MASK 123459876 double ran0(long *idum){ long k; double ans; *idum ^= MASK; k=(*idum)/IQ; *idum=IA*(*idum-k*IQ)-IR*k; if (*idum < 0) *idum += IM; ans=AM*(*idum); *idum ^= MASK; return ans; } #undef IA #undef IM #undef AM #undef IQ #undef IR #undef MASK /* (C) Copr. 1986-92 Numerical Recipes Software 9z!+!1(t+%. */ }; #endif