void GlobalFun::computeEigenWithTheta(CMesh* _samples, double radius) { vector<vector<int> > neighborMap; typedef vector<CVertex>::iterator VertexIterator; VertexIterator begin = _samples->vert.begin(); VertexIterator end = _samples->vert.end(); neighborMap.assign(end - begin, vector<int>()); int curr_index = 0; for (VertexIterator iter=begin; iter!=end; iter++, curr_index++) { if(iter->neighbors.size() <= 3) { iter->eigen_confidence = 0.5; continue; } for(int j = 0; j < iter->neighbors.size(); j++) { neighborMap[curr_index].push_back(iter->neighbors[j]); } } double radius2 = radius*radius; double iradius16 = -1/radius2; int currIndex = 0; for (VertexIterator iter=begin; iter!=end; iter++, currIndex++) { if(iter->neighbors.size() <= 3) { iter->eigen_confidence = 0.5; continue; } Matrix33d covariance_matrix; Point3f diff; covariance_matrix.SetZero(); int neighborIndex = -1; int neighbor_size = iter->neighbors.size(); for (unsigned int n=0; n<neighbor_size; n++) { neighborIndex = neighborMap[currIndex][n]; if(neighborIndex < 0) break; VertexIterator neighborIter = begin + neighborIndex; diff = iter->P() - neighborIter->P(); Point3f vm = iter->N(); Point3f tm = neighborIter->N(); double dist2 = diff.SquaredNorm(); double theta = exp(dist2*iradius16); for (int i=0; i<3; i++) for (int j=0; j<3; j++) covariance_matrix[i][j] += diff[i]*diff[j] * theta; } Point3f eigenvalues; Matrix33d eigenvectors; int required_rotations; vcg::Jacobi< Matrix33d, Point3f >(covariance_matrix, eigenvalues, eigenvectors, required_rotations); vcg::SortEigenvaluesAndEigenvectors< Matrix33d, Point3f >(eigenvalues, eigenvectors); double sum_eigen_value = (eigenvalues[0] + eigenvalues[1] + eigenvalues[2]); iter->eigen_confidence = eigenvalues[0] / sum_eigen_value; for (int d=0; d<3; d++) iter->eigen_vector0[d] = eigenvectors[d][0]; for (int d=0; d<3; d++) iter->eigen_vector1[d] = eigenvectors[d][1]; for (int d=0; d<3; d++) iter->N()[d] = eigenvectors[d][2]; iter->eigen_vector0.Normalize(); iter->eigen_vector1.Normalize(); iter->N().Normalize(); } }
void GlobalFun::computeEigenIgnoreBranchedPoints(CMesh* _samples) { vector<vector<int> > neighborMap; typedef vector<CVertex>::iterator VertexIterator; VertexIterator begin = _samples->vert.begin(); VertexIterator end = _samples->vert.end(); neighborMap.assign(end - begin, vector<int>()); int curr_index = 0; for (VertexIterator iter=begin; iter!=end; ++iter, curr_index++) { if(iter->neighbors.size() <= 3) { iter->eigen_confidence = 0.5; continue; } //neighborMap[curr_index].push_back(curr_index); for(int j = 0; j < iter->neighbors.size(); j++) { CVertex& t = _samples->vert[iter->neighbors[j]]; if (t.is_skel_branch || t.is_skel_ignore) { continue; } neighborMap[curr_index].push_back(iter->neighbors[j]); } } int currIndex = 0; for (VertexIterator iter=begin; iter!=end; iter++, currIndex++) { int neighbor_size = neighborMap[currIndex].size(); if (neighbor_size < 3) { iter->eigen_confidence = 0.95; iter->eigen_vector0 = Point3f(0, 0, 0); continue; } Matrix33d covariance_matrix; Point3f diff; covariance_matrix.SetZero(); int neighborIndex = -1; for (unsigned int n=0; n<neighbor_size; n++) { neighborIndex = neighborMap[currIndex][n]; if(neighborIndex < 0) break; VertexIterator neighborIter = begin + neighborIndex; diff = iter->P() - neighborIter->P(); for (int i=0; i<3; i++) for (int j=0; j<3; j++) covariance_matrix[i][j] += diff[i]*diff[j]; } Point3f eigenvalues; Matrix33d eigenvectors; int required_rotations; vcg::Jacobi< Matrix33d, Point3f >(covariance_matrix, eigenvalues, eigenvectors, required_rotations); vcg::SortEigenvaluesAndEigenvectors< Matrix33d, Point3f >(eigenvalues, eigenvectors); double sum_eigen_value = (eigenvalues[0] + eigenvalues[1] + eigenvalues[2]); iter->eigen_confidence = eigenvalues[0] / sum_eigen_value; for (int d=0; d<3; d++) iter->eigen_vector0[d] = eigenvectors[d][0]; for (int d=0; d<3; d++) iter->eigen_vector1[d] = eigenvectors[d][1]; for (int d=0; d<3; d++) iter->N()[d] = eigenvectors[d][2]; iter->eigen_vector0.Normalize(); iter->eigen_vector1.Normalize(); iter->N().Normalize(); } }