#include "rbfcore.h" #include "mymesh/utility.h" #include "Solver.h" #include #include #include #include #include #include #include #include #include #include "mymesh/readers.h" #include "mymesh/UnionFind.h" //#include "mymesh/tinyply.h" typedef std::chrono::high_resolution_clock Clock; double randomdouble() {return static_cast (rand()) / static_cast (RAND_MAX);} double randomdouble(double be,double ed) {return be + randomdouble()*(ed-be); } void RBF_Core::NormalRecification(double maxlen, vector&nors){ double maxlen_r = -1; auto p_vn = nors.data(); int np = nors.size()/3; if(1){ for(int i=0;ilabelcolor(npt*4); vectorf2v; uchar red[] = {255,0,0, 255}; uchar green[] = {0,255,0, 255}; uchar blue[] = {0,0,255, 255}; // for(int i=0;inors; if(mode ==0)nors=initnormals; else if(mode == 1)nors=newnormals; else if(mode == 2)nors = initnormals_uninorm; NormalRecification(1.,nors); //for(int i=0;i&pts){ cout<<"Set_HermiteRBF"<&vn){ cout<<"Solve_HermiteRBF "<&pts, double &mindist, double &avedist){ int n = pts.size()/3; if(n==0)return; mindist = 1e30; avedist = 0; auto p_v = pts.data(); for(int i=0;i 0 ? user_ls : 0; } void RBF_Core::Set_Actual_Hermite_LSCoef(double hermite_ls){ ls_coef = Hermite_ls_weight_inject = hermite_ls > 0?hermite_ls:0; } void RBF_Core::Set_SparsePara(double spa){ sparse_para = spa; if(isuse_sparse){ SparsifyKH(finalH, sp_H); sp_K = sp_H; } } void RBF_Core::SparsifyKH(arma::mat &KH, arma::sp_mat &sp_KH){ if(isuse_sparse){ arma::mat spKH(KH); double cutele; int spmethod = 3; if(spmethod == 0){ cout<<"spmethod 0"<rowmax(npt),colmax(npt); for(int p1=0; p10){ arma::sp_mat eye; eye.eye(npt,npt); dI = inv(eye + User_Lamnbda*K00); saveK_finalH = K = K11 - (User_Lamnbda)*(K01.t()*dI*K01); }else saveK_finalH = K = K11; cout<<"solved: "<<(std::chrono::nanoseconds(Clock::now() - t1).count()/1e9)<0){ arma::sp_mat eye; eye.eye(npt,npt); if(ls_coef > 0){ arma:: mat tmpdI = inv(eye + (ls_coef+User_Lamnbda)*K00); K = K11 - (ls_coef+User_Lamnbda)*(K01.t()*tmpdI*K01); }else{ K = saveK_finalH; } } cout<<"solved: "<<(std::chrono::nanoseconds(Clock::now() - t1).count()/1e9)<&pts){ Set_HermiteRBF(pts); auto t1 = Clock::now(); cout<<"setting K"<weights(npt); for(int i=0;ieigenmatrix(npt); vectoreigenval(npt); for(int i=0;i(const Triple& l, const Triple& r){return l.val > r.val;} void BuildMST(vector&MST_edges, vector>&MST_v2v, vector&MST_edgesWeight, vector&eweights, int n_v){ MST_edges.clear(); MST_v2v.clear(); MST_edgesWeight.clear(); MST_v2v.resize(n_v); sort(eweights.begin(),eweights.end(),greater()); int n_neg = 0; vectorele(n_v); for(int i=0;i&isflip,vector>&edgelength, vector>&MST_v2v, int npt, int startpnt){ int nflip = 0; vectorisvisited(npt,false); isflip.clear(); isflip.resize(npt,false); queue>q; for(auto a:MST_v2v[startpnt])q.emplace(a,startpnt); isvisited[startpnt]=true; while(!q.empty()){ pair aa = q.front(); int curpnt = aa.first; q.pop(); if(isvisited[curpnt])continue; isvisited[curpnt] = true; if((edgelength[curpnt][aa.second]<0 && isflip[aa.second]) || (edgelength[curpnt][aa.second]>0 && !isflip[aa.second])){ isflip[curpnt] = true;++nflip; } for(auto a:MST_v2v[curpnt])q.emplace(a,curpnt); } //cout<<"nflip: "<&nors, bool isnormalized){ cout<<"NormalReOrientation"<nors_strength(npt); //arma::mat edgelength(npt,npt); vector>edgelength(npt,vector(npt)); vectorarma_normals(npt,arma::vec(3)); auto p_nor = nors.data(); for(int p1=0; p1eabslength; int n_neg = 0; for(int p1=0; p1 1e-4 )eabslength.emplace_back(fabs(edgelength[p1][p2]),p1,p2); } vector>MST_v2v; BuildMST(MST_edges, MST_v2v,MST_edgesWeight, eabslength, npt); vectorisflip(npt,false); int startpnt = max_element(nors_strength.begin(),nors_strength.end())-nors_strength.begin(); MST_Orientate(isflip,edgelength,MST_v2v,npt,startpnt); for(int p1=0; p1 &nors, bool isnormalized){ for(int i=0;ieabslength; Coherence_M.set_size(npt,npt); for(int p1=0; p1 1e-4 ) eabslength.emplace_back(fabs(ll),p1,p2); } sort(eabslength.begin(),eabslength.end(),greater()); Coherence_Graph_Weight.clear(); Coherence_Graph.clear(); for(auto &a:eabslength){ Coherence_Graph_Weight.push_back(a.val); Coherence_Graph.push_back(a.i); Coherence_Graph.push_back(a.j); } } double stdvar(vector&v){ int nv = v.size(); double ave = 0; for(auto a:v)ave+=a; ave/=nv; double re = 0; for(auto a:v)re+= pow(ave-a,2); return sqrt(re/nv); } void RBF_Core::LocalEigenInit_PredictNormal(){ cout<<"LocalEigenInit_PredictNormal"<eva(3); for(int i=0;i0){ // smalleig = i; // break; // } // if(smalleig!=0)if( fabs(eigval(smalleig-1)) < fabs(eigval(smalleig)) )smalleig-=1; //smalleig = 9; initnormals.resize(npt*3); arma::vec y(npt*4); for(int i=0;i&out_Vs, vector&normals, vector&labels); void RBF_Core::WriteSeletivePLY(string fname, vector&allnormals, vector&pickInd){ vectornpts; vectornnor; vectorlabels(pickInd.size(),0); for(auto ind:pickInd){ for(int j=0;j<3;++j)npts.push_back(pts[ind*3+j]); for(int j=0;j<3;++j)nnor.push_back(allnormals[ind*3+j]); } WritePointPLY(fname,npts,nnor,labels); } void RBF_Core::ClearSavedIterBatchInit(){ InitBatch_Vs.clear(); InitBatch_VNs.clear(); InitBatch_VUNs.clear(); InitBatch_VInds.clear(); InitBatch_Coherence_Graph.clear(); InitBatch_Coherence_Graph_Weight.clear(); } void RBF_Core::SaveIterBatchInit(vector&allnormals, vector&allnormals_uninorm, vector&pickInd){ int nnInd = InitBatch_Vs.size(); InitBatch_Vs.resize(nnInd+1); InitBatch_VNs.resize(nnInd+1); InitBatch_VUNs.resize(nnInd+1); InitBatch_Coherence_Graph.resize(nnInd+1); InitBatch_Coherence_Graph_Weight.resize(nnInd+1); InitBatch_VInds.emplace_back(pickInd); vector&npts = InitBatch_Vs[nnInd]; vector&nor = InitBatch_VNs[nnInd]; vector&nnor = InitBatch_VUNs[nnInd]; vector&gg = InitBatch_Coherence_Graph[nnInd]; vector&ggw = InitBatch_Coherence_Graph_Weight[nnInd]; vectorispick(npt,false); for(auto ind:pickInd){ for(int j=0;j<3;++j)npts.push_back(pts[ind*3+j]); for(int j=0;j<3;++j)nor.push_back(allnormals[ind*3+j]); for(int j=0;j<3;++j)nnor.push_back(allnormals_uninorm[ind*3+j]); ispick[ind]=true; } vectorsortInd(pickInd); sort(sortInd.begin(),sortInd.end()); vectorinvertInd(npt,-1); for(int p1=0; p1eeT; for(int p1=0; p1()); gg.clear();ggw.clear(); gg.reserve(eeT.size()*2);ggw.reserve(eeT.size()); for(auto &a:eeT){ ggw.push_back(a.val); gg.push_back(a.i); gg.push_back(a.j); } } int RBF_Core::Solve_Hermite_PredictNormal_UnitNorm_Iterative(){ vectorlabels(npt,0); double thres_coef = 0.5; arma::vec eigval, ny; arma::mat eigvec; int iter = 0; int maxiter = 20; vectoractiveInd(npt); vectorfixedInd; for(int i=0;inorm_normals(npt*3,0); ClearSavedIterBatchInit(); while(true){ ++iter; int n_Active = activeInd.size(); int n_Fixed = fixedInd.size(); bool prebreak = (iter>=maxiter) /*|| (n_Active < npt * 0.05)*/; arma::uvec row_ind(n_Active*3); for(int i=0;inewactive,addfixInd; //cout<<"thres: "<0){ int n_Addfix = fixedInd.size()-n_Fixed; arma::uvec addfix_row_ind(n_Addfix*3); addVec.set_size(n_Addfix*3); for(int i=0;i0){ cout<<"flip"<&isflip, vector>&en_mat, int n_v){ isflip.clear(); isflip.resize(n_v,false); if(n_v<2)return 1; cout<<"ExhaustedCombination"<labels(npt,0); double thres_coef = 0.9; arma::vec eigval, ny; arma::mat eigvec; int iter = 0; int maxiter = 100; vectoractiveInd(npt); vectorfixedInd; for(int i=0;inorm_normals(npt*3,0); vector>hyper_patch; ClearSavedIterBatchInit(); while(true){ ++iter; int n_Active = activeInd.size(); int n_Fixed = fixedInd.size(); bool prebreak = (iter>=maxiter) /*|| (n_Active < npt * 0.05)*/; arma::uvec row_ind(n_Active*3); for(int i=0;inewactive; vector&addfixInd = hyper_patch[hyper_patch.size()-1]; //cout<<"thres: "<MST_edges; vector>MST_v2v; vectoreweights; int n_hyper = hyper_patch.size(); vectorhyperb_vec(hyper_patch.size()); vectorhyperb_rowind(hyper_patch.size()); for(int i=0;i>interactiveEn_mat(n_hyper,vector(n_hyper)); for(int i=0;iisflip(n_hyper,false); if(1){ cout<<"BuildMST"<MST_edges.clear(); this->MST_edgesWeight.clear(); cout<<"Solve_Hermite_PredictNormal_UnitNorm_Iterative"<&x, vector&grad, void *fdata){ auto t1 = Clock::now(); RBF_Core *drbf = reinterpret_cast(fdata); int n = drbf->npt; arma::vec arma_x(n*3); //( sin(a)cos(b), sin(a)sin(b), cos(a) ) a =>[0, pi], b => [-pi, pi]; vectorsina_cosa_sinb_cosb(n * 4); for(int i=0;iisuse_sparse)a2 = drbf->sp_H * arma_x; else a2 = drbf->finalH * arma_x; if (!grad.empty()) { grad.resize(n*2); for(int i=0;iupper(npt*2); vectorlower(npt*2); for(int i=0;iupper(npt*2); vectorlower(npt*2); for(int i=0;i0)y.subvec(0,npt-1) = -User_Lamnbda*dI*K01*y.subvec(npt,npt*4-1); a = Minv*y; b = Ninv.t()*y; } } int RBF_Core::Solve_Hermite_PredictNormal_UnitNormal_InitializationTest(){ sol.solveval.resize(npt * 2); int global_eigenIndex = 1; int local_eigenIndex = 2; int gt_Index = 0; for(int kk=0;kk<2;++kk){ if(kk==global_eigenIndex){ Solve_Hermite_PredictNormal_UnitNorm(); NormalReOrientation_WithGT(initnormals,false); }else if(kk==local_eigenIndex){ LocalEigenInit_PredictNormal(); } double veccc[3]; for(int i=0;iupper(npt*2); vectorlower(npt*2); for(int i=0;iupper(npt*2); vectorlower(npt*2); for(int i=0;i "< "< "< "<fixedInd; arma::mat subactiveMat; vector>hyper_patch; ClearSavedIterBatchInit(); LocalEigenInit_PredictNormal(); vectornorm_normals(initnormals); vectornors_strength(npt); auto p_nor = initnormals.data(); for(int p1=0; p1headInd; vectorccInd; vectorheadpick(npt,false); for(int p1=0; p1maxstrength){ headInd.push_back(p1); headpick[p1] = true; } else ccInd.push_back(p1); } UnionFind uni_find_head; UnionFind uni_find_cc; uni_find_cc.SetElements(ccInd); uni_find_head.SetElements(headInd); double westrength = Coherence_Graph_Weight[0]*graph_cut_percentage; double n_reserve = 2 * npt * graph_cut_percentage; if(0){ for(int i=0;iwestrength){ int a = Coherence_Graph[i*2],b = Coherence_Graph[i*2+1]; if(!headpick[a] && !headpick[b]){ uni_find_cc.Union(a,b); } if(headpick[a] && headpick[b]){ uni_find_head.Union(a,b); } }else break; } }else{ for(int i=0;i>ccHyper,headHyper; uni_find_head.ExtractComponents(headHyper); uni_find_cc.ExtractComponents(ccHyper); cout<<"Hyper: "<MST_edges; vector>MST_v2v; vectorMST_edgesWeight; vectorind(npt,-10000); for(int i=0;i>edgelength(npt,vector(npt)); vectorarma_normals(n_Active,arma::vec(3)); auto p_nor = norm_normals.data(); for(int p1=0; p1eabslength; int n_neg = 0; for(int m=0; m 1e-4 )*/eabslength.emplace_back(fabs(edgelength[m][n]),m,n); } vectorisflip(n_Active); BuildMST(MST_edges, MST_v2v,MST_edgesWeight, eabslength, n_Active); MST_Orientate(isflip,edgelength,MST_v2v,n_Active,0); for(int i=0;isaveInit(initnormals),save_norm(norm_normals); for(auto &ccInd:ccHyper){ UnionFind uni_find; vectorele; for(auto &b:headHyper)for(auto a:b)ele.push_back(a); for(auto b:ccInd)ele.push_back(b); uni_find.SetElements(ele); for(auto &b:headHyper)for(int i=1;iccpick(npt,false); for(auto b:ccInd)ccpick[b]=true; for(int i=0;iactiveInd(ccInd); for(auto &b:headHyper)if(uni_find.Is_Connected(b[0],ccInd[0]))for(auto a:b)activeInd.push_back(a); int n_Active = activeInd.size(); arma::uvec row_ind(n_Active*3); for(int i=0;i*drawInd; if(visualmethod==0)drawInd = &activeInd;//activeInd ccInd else if(visualmethod==1)drawInd = &ccInd; for(int i=0;isize();++i){ auto p_nor = initnormals.data()+activeInd[i]*3; auto p_nor_n = norm_normals.data()+activeInd[i]*3; for(int j=0;j<3;++j)p_nor_n[j] = p_nor[j] = firstEigvec(i*3+j); MyUtility::normalize(p_nor_n); } cout<eweights; int n_hyper = hyper_patch.size(); vectorhyperb_vec(hyper_patch.size()); vectorhyperb_rowind(hyper_patch.size()); for(int i=0;i>interactiveEn_mat(n_hyper,vector(n_hyper)); for(int i=0;iisflip(n_hyper,false); if(1){ cout<<"BuildMST"<MST_edges; vector>MST_v2v; vectorMST_edgesWeight; BuildMST(MST_edges, MST_v2v,MST_edgesWeight, eweights, n_hyper); MST_Orientate(isflip,interactiveEn_mat,MST_v2v,n_hyper,0); }else{ ExhaustedCombination(isflip,interactiveEn_mat,n_hyper); } for(int i=0;iMST_edges.clear(); this->MST_edgesWeight.clear(); cout<<"Solve_Hermite_PredictNormal_UnitNorm_Cluster_MST"<lamnbda_list({0, 0.001, 0.01, 0.1, 1}); //vectorlamnbda_list({ 0.5,0.6,0.7,0.8,0.9,1,1.1,1.5,2,3}); //lamnbda_list.clear(); //for(double i=1.5;i<2.5;i+=0.1)lamnbda_list.push_back(i); //vectorlamnbda_list({0}); vectoriniten_list(lamnbda_list.size()); vectorfinalen_list(lamnbda_list.size()); vector>init_normallist; vector>opt_normallist; lamnbda_list_sa = lamnbda_list; for(int i=0;i "< "<