IGL_INLINE void igl::viewer::ViewerCore::get_scale_and_shift_to_fit_mesh( const Eigen::MatrixXd& V, float& zoom, Eigen::Vector3f& shift) { if (V.rows() == 0) return; Eigen::RowVector3d min_point; Eigen::RowVector3d max_point; Eigen::RowVector3d centroid; if (V.cols() == 3) { min_point = V.colwise().minCoeff(); max_point = V.colwise().maxCoeff(); } else if (V.cols() == 2) { min_point << V.colwise().minCoeff(),0; max_point << V.colwise().maxCoeff(),0; } else return; centroid = 0.5 * (min_point + max_point); shift = -centroid.cast<float>(); double x_scale = fabs(max_point[0] - min_point[0]); double y_scale = fabs(max_point[1] - min_point[1]); double z_scale = fabs(max_point[2] - min_point[2]); zoom = 2.0 / std::max(z_scale,std::max(x_scale,y_scale)); }
int main(int argc, char * argv[]) { using namespace Eigen; using namespace std; using namespace igl; VectorXd D; if(!read_triangle_mesh("../shared/beetle.off",V,F)) { cout<<"failed to load mesh"<<endl; } twod = V.col(2).minCoeff()==V.col(2).maxCoeff(); bbd = (V.colwise().maxCoeff()-V.colwise().minCoeff()).norm(); SparseMatrix<double> L,M; cotmatrix(V,F,L); L = (-L).eval(); massmatrix(V,F,MASSMATRIX_TYPE_DEFAULT,M); const size_t k = 5; if(!eigs(L,M,k+1,EIGS_TYPE_SM,U,D)) { cout<<"failed."<<endl; } U = ((U.array()-U.minCoeff())/(U.maxCoeff()-U.minCoeff())).eval(); igl::viewer::Viewer viewer; viewer.callback_key_down = [&](igl::viewer::Viewer & viewer,unsigned char key,int)->bool { switch(key) { default: return false; case ' ': { U = U.rightCols(k).eval(); // Rescale eigen vectors for visualization VectorXd Z = bbd*0.5*U.col(c); Eigen::MatrixXd C; igl::parula(U.col(c).eval(),false,C); c = (c+1)%U.cols(); if(twod) { V.col(2) = Z; } viewer.data.set_mesh(V,F); viewer.data.compute_normals(); viewer.data.set_colors(C); return true; } } }; viewer.callback_key_down(viewer,' ',0); viewer.core.show_lines = false; viewer.launch(); }
int main(int argc, char * argv[]) { using namespace Eigen; using namespace igl; using namespace std; // init mesh string filename = "/usr/local/igl/libigl/examples/shared/decimated-knight.obj" ; if(argc > 1) { filename = argv[1]; } if(!read_triangle_mesh(filename,V,F)) { return 1; } // Compute normals, centroid, colors, bounding box diagonal per_face_normals(V,F,N); normalize_row_lengths(N,N); mid = 0.5*(V.colwise().maxCoeff() + V.colwise().minCoeff()); bbd = (V.colwise().maxCoeff() - V.colwise().minCoeff()).maxCoeff(); // Init glut glutInit(&argc,argv); if( !TwInit(TW_OPENGL, NULL) ) { // A fatal error occured fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError()); return 1; } // Create a tweak bar rebar.TwNewBar("TweakBar"); rebar.TwAddVarRW("scene_rot", TW_TYPE_QUAT4F, &scene_rot, ""); rebar.load(REBAR_NAME); glutInitDisplayString( "rgba depth double samples>=8 "); glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH)/2.0,glutGet(GLUT_SCREEN_HEIGHT)); glutCreateWindow("sorted primitives transparency"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(key); glutMouseFunc(mouse); glutMotionFunc(mouse_drag); glutMainLoop(); return 0; }
IGL_INLINE void igl::viewer::ViewerCore::align_camera_center( const Eigen::MatrixXd& V) { if(V.rows() == 0) return; get_scale_and_shift_to_fit_mesh(V,model_zoom,model_translation); // Rather than crash on empty mesh... if(V.size() > 0) { object_scale = (V.colwise().maxCoeff() - V.colwise().minCoeff()).norm(); } }
Eigen::MatrixXd localWeighting( const Eigen::MatrixXd &W, bool isFull, bool isSymmetric) { int n = W.rows(); double Ls = (W.count()-n)/2; //count number of edges of the graph Eigen::MatrixXd C = Eigen::MatrixXd::Zero(n,n); double Ws = 0.5*W.sum(); Eigen::VectorXd D = W.colwise().sum(); if (isFull) { if (isSymmetric) { computeC_symmetric_full(const_cast<Eigen::MatrixXd &>(W),C,D,n); } else { // this is a trick to ensure vectorizatoin and no cache misses! some tranpositions have to be made though const_cast<Eigen::MatrixXd &>(W).transposeInPlace(); computeC_symmetric_full(const_cast<Eigen::MatrixXd &>(W),C,D,n); const_cast<Eigen::MatrixXd &>(W).transposeInPlace(); C.transposeInPlace(); // the original code use vertical access to rows, but is slower //compute_C_asymmetric_full(const_cast<Eigen::MatrixXd &>(W),C,D,n); } } else { if (isSymmetric) { computeC_symmetric_sparse(const_cast<Eigen::MatrixXd &>(W),C,D,n); } else { compute_C_asymmetric_sparse(const_cast<Eigen::MatrixXd &>(W),C,D,n); } } Eigen::MatrixXd G = ((Ls/Ws)*W).cwiseProduct(C); Eigen::VectorXd DG = G.colwise().sum(); for (int i=0; i<n; i++) { G.row(i)/=DG(i); } return G; }
int main(int argc, char * argv[]) { using namespace Eigen; using namespace igl; using namespace std; // init mesh string filename = "../shared/decimated-knight.obj"; if(argc < 2) { cerr<<"Usage:"<<endl<<" ./example input.obj"<<endl; cout<<endl<<"Opening default mesh..."<<endl; }else { // Read and prepare mesh filename = argv[1]; } if(!read_triangle_mesh(filename,V,F)) { return 1; } // Compute normals, centroid, colors, bounding box diagonal per_face_normals(V,F,N); normalize_row_lengths(N,N); mean = V.colwise().mean(); C.resize(F.rows(),3); init_C(); bbd = (V.colwise().maxCoeff() - V.colwise().minCoeff()).maxCoeff(); // Init embree ei.init(V.cast<float>(),F.cast<int>()); // Init glut glutInit(&argc,argv); glutInitDisplayString( "rgba depth double samples>=8 "); glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH)/2.0,glutGet(GLUT_SCREEN_HEIGHT)); glutCreateWindow("embree"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(key); glutMouseFunc(mouse); glutMotionFunc(mouse_drag); glutPassiveMotionFunc(mouse_move); glutMainLoop(); return 0; }
Eigen::MatrixXd caculateAlgebraicDistance(const Eigen::SparseMatrix<int,Eigen::RowMajor>& incidenceMatrix, const Eigen::SparseMatrix<double,Eigen::RowMajor>& updatedMatrix) { Eigen::MatrixXd inc = Eigen::MatrixXd(incidenceMatrix); Eigen::MatrixXd update = Eigen::MatrixXd(updatedMatrix); int edgeNumber = inc.cols(); int verticeNumber = inc.rows(); Eigen::MatrixXd algebraicDistanceForEdge(edgeNumber,1); Eigen::VectorXd sumOfcolsVector(edgeNumber); sumOfcolsVector = inc.colwise().sum(); for(int i = 0; i<edgeNumber;++i){ int verticeNumberForEdge = sumOfcolsVector[i]; Eigen::MatrixXd allEdgeMatrix(update.rows(),verticeNumberForEdge); int g=0; for(int j=0;j<verticeNumber;++j){ if(inc(j,i)){ ++g; for(int v = 0; v<update.rows();++v){ allEdgeMatrix(v,g-1) = update(v,j); } } } if(g!=0){ Eigen::MatrixXd maxValueOfEdge = getMaxDiffForeachEdge(allEdgeMatrix); maxValueOfEdge = maxValueOfEdge.transpose() * maxValueOfEdge; double edgeDistance = maxValueOfEdge.sum(); edgeDistance = sqrt(edgeDistance); algebraicDistanceForEdge(i,0) = edgeDistance; } } return algebraicDistanceForEdge; }
bool CGEOM::generate_scene_trans ( const SceneGeneratorOptions& sc_opts, Eigen::MatrixXd& mP3D, Eigen::MatrixXd& mMeasT, Eigen::MatrixXd& mMeasN, Eigen::Matrix3d& mR, Eigen::Vector3d& mt ) { if( !generate_scene( sc_opts, mP3D, mMeasT, mMeasN ) ) { return false; } // Create random transform mt = mP3D.rowwise().mean(); const double drotx = rand_range_d( -45., 45. )*3.14159/180.; const double droty = rand_range_d( -45., 45. )*3.14159/180.; const double drotz = rand_range_d( -45., 45. )*3.14159/180.; #if 1 mR = ( CEIGEN::skew_rot<Eigen::Matrix3d,double>( drotx, 0., 0. ) + CEIGEN::skew_rot<Eigen::Matrix3d,double>( 0., droty , 0.) + CEIGEN::skew_rot<Eigen::Matrix3d,double>( 0., 0., drotz ) ).exp(); #else mR = Eigen::Matrix3d::Identity(); #endif mP3D.colwise() -= mt; mP3D = mR.transpose() * mP3D; return true; }
IGL_INLINE void igl::viewer::ViewerCore::get_scale_and_shift_to_fit_mesh( const Eigen::MatrixXd& V, const Eigen::MatrixXi& F, float& zoom, Eigen::Vector3f& shift) { if (V.rows() == 0) return; //Eigen::SparseMatrix<double> M; //igl::massmatrix(V,F,igl::MASSMATRIX_TYPE_VORONOI,M); //const auto & MV = M*V; //Eigen::RowVector3d centroid = MV.colwise().sum()/M.diagonal().sum(); Eigen::MatrixXd BC; igl::barycenter(V,F,BC); Eigen::RowVector3d min_point = BC.colwise().minCoeff(); Eigen::RowVector3d max_point = BC.colwise().maxCoeff(); Eigen::RowVector3d centroid = 0.5*(min_point + max_point); shift = -centroid.cast<float>(); double x_scale = fabs(max_point[0] - min_point[0]); double y_scale = fabs(max_point[1] - min_point[1]); double z_scale = fabs(max_point[2] - min_point[2]); zoom = 2.0 / std::max(z_scale,std::max(x_scale,y_scale)); }
IGL_INLINE void igl::viewer::ViewerCore::get_scale_and_shift_to_fit_mesh( const Eigen::MatrixXd& V, const Eigen::MatrixXi& F, float& zoom, Eigen::Vector3f& shift) { if (V.rows() == 0) return; Eigen::MatrixXd BC; if (F.rows() <= 1) BC = V; else igl::barycenter(V,F,BC); Eigen::RowVector3d min_point = BC.colwise().minCoeff(); Eigen::RowVector3d max_point = BC.colwise().maxCoeff(); Eigen::RowVector3d centroid = 0.5*(min_point + max_point); shift = -centroid.cast<float>(); double x_scale = fabs(max_point[0] - min_point[0]); double y_scale = fabs(max_point[1] - min_point[1]); double z_scale = fabs(max_point[2] - min_point[2]); zoom = 2.0 / std::max(z_scale,std::max(x_scale,y_scale)); }
int main(int argc, char * argv[]) { using namespace Eigen; using namespace igl; using namespace std; // init mesh string filename = "/usr/local/igl/libigl/examples/shared/decimated-knight.obj" ; if(argc > 1) { filename = argv[1]; } if(!read_triangle_mesh(filename,V,F)) { return 1; } // Compute normals, centroid, colors, bounding box diagonal per_face_normals(V,F,N); normalize_row_lengths(N,N); mean = V.colwise().mean(); C.resize(F.rows(),3); init_C(); bbd = (V.colwise().maxCoeff() - V.colwise().minCoeff()).maxCoeff(); // Init viewports init_viewports(); // Init glut glutInit(&argc,argv); glutInitDisplayString( "rgba depth double samples>=8 "); glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH)/2.0,glutGet(GLUT_SCREEN_HEIGHT)); glutCreateWindow("multi-viewport"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(key); glutMouseFunc(mouse); glutMotionFunc(mouse_drag); glutPassiveMotionFunc(mouse_move); glutMainLoop(); return 0; }
int main(int argc, char *argv[]) { using namespace Eigen; using namespace std; igl::readOFF("../shared/decimated-knight.off",V,F); U=V; igl::readDMAT("../shared/decimated-knight-selection.dmat",S); // vertices in selection igl::colon<int>(0,V.rows()-1,b); b.conservativeResize(stable_partition( b.data(), b.data()+b.size(), [](int i)->bool{return S(i)>=0;})-b.data()); // Centroid mid = 0.5*(V.colwise().maxCoeff() + V.colwise().minCoeff()); // Precomputation arap_data.max_iter = 100; igl::arap_precomputation(V,F,V.cols(),b,arap_data); // Set color based on selection MatrixXd C(F.rows(),3); RowVector3d purple(80.0/255.0,64.0/255.0,255.0/255.0); RowVector3d gold(255.0/255.0,228.0/255.0,58.0/255.0); for(int f = 0;f<F.rows();f++) { if( S(F(f,0))>=0 && S(F(f,1))>=0 && S(F(f,2))>=0) { C.row(f) = purple; }else { C.row(f) = gold; } } // Plot the mesh with pseudocolors igl::viewer::Viewer viewer; viewer.data.set_mesh(U, F); viewer.data.set_colors(C); viewer.callback_pre_draw = &pre_draw; viewer.callback_key_down = &key_down; viewer.core.is_animating = false; viewer.core.animation_max_fps = 30.; cout<< "Press [space] to toggle animation"<<endl; viewer.launch(); }
std::pair<Eigen::MatrixXd::Index, double> dsearch(Eigen::Vector3d p, Eigen::MatrixXd positions) { Eigen::MatrixXd::Index index; // find nearest neighbour (positions.colwise() - p).colwise().squaredNorm().minCoeff(&index); double d = (positions.col(index) - p).norm(); return std::make_pair(index , d); }
void init_relative() { using namespace Eigen; using namespace igl; per_face_normals(V,F,N); Vmax = V.colwise().maxCoeff(); Vmin = V.colwise().minCoeff(); Vmid = 0.5*(Vmax + Vmin); bbd = (Vmax-Vmin).norm(); }
int FeatureTransformationEstimator::consensus3D(Eigen::MatrixXd P, Eigen::MatrixXd Q, Eigen::Isometry3d T, double thresh, Eigen::Array<bool, 1, Eigen::Dynamic> &consensusSet) { int consensus = 0; P = T * P.colwise().homogeneous(); Eigen::MatrixXd norms = (P - Q).colwise().norm(); consensusSet = norms.array() < thresh; consensus = consensusSet.count(); return consensus; }
void init_relative() { using namespace Eigen; using namespace igl; using namespace std; per_face_normals(V,F,N); const auto Vmax = V.colwise().maxCoeff(); const auto Vmin = V.colwise().minCoeff(); Vmid = 0.5*(Vmax + Vmin); centroid(V,F,Vcen); bbd = (Vmax-Vmin).norm(); camera.push_away(2); }
std::pair<std::vector<Eigen::MatrixXd::Index>, Eigen::VectorXd > dsearchn(Eigen::MatrixXd p1, Eigen::MatrixXd p2) { Eigen::MatrixXd::Index index; std::vector<Eigen::MatrixXd::Index> indexVector; Eigen::VectorXd D(p1.cols()); for (int i = 0; i < p1.cols(); i++) { // find nearest neighbour (p2.colwise() - p1.col(i)).colwise().squaredNorm().minCoeff(&index); D(i) = (p2.col(index) - p1.col(i)).norm(); indexVector.push_back(index); } return std::make_pair(indexVector , D); }
Eigen::MatrixXd joint2conditional(Eigen::MatrixXd edgePot)// assuming parent is the second dimension in edgepot { // second dimension of edgePot is the parent Eigen::MatrixXd Conditional(edgePot.rows(), edgePot.cols()); Eigen::VectorXd Parent_Marginal(edgePot.cols()); Parent_Marginal = edgePot.colwise().sum(); Parent_Marginal = normProbVector(Parent_Marginal); for (int col = 0; col < edgePot.cols(); col++) { if (Parent_Marginal(col)> TOLERANCE) Conditional.col(col) = edgePot.col(col) / (Parent_Marginal(col)); else Conditional.col(col) = Eigen::VectorXd::Zero(edgePot.rows()); } return Conditional; }
IGL_INLINE void igl::viewer::ViewerCore::get_scale_and_shift_to_fit_mesh( const Eigen::MatrixXd& V, float& zoom, Eigen::Vector3f& shift) { if (V.rows() == 0) return; auto min_point = V.colwise().minCoeff(); auto max_point = V.colwise().maxCoeff(); auto centroid = (0.5*(min_point + max_point)).eval(); shift.setConstant(0); shift.head(centroid.size()) = -centroid.cast<float>(); zoom = 2.0 / (max_point-min_point).array().abs().maxCoeff(); }
Eigen::MatrixXd get_symmetric_point( const Eigen::VectorXd& _normal, const Eigen::VectorXd& _center, const Eigen::MatrixXd& _points) { // Assume that '_normal' is normalized. Eigen::MatrixXd plane_to_points = _normal * _normal.transpose() * (_points.colwise() - _center); Eigen::MatrixXd symmetric_point = _points - (plane_to_points * 2); // Debug. //Eigen::MatrixXd mid_points = 0.5 * (symmetric_point + _points); //Eigen::VectorXd distances = (mid_points.colwise() - _center).transpose() * _normal; //std::cout << distances.sum() / distances.rows() << std::endl; return symmetric_point; }
void igl::fit_plane( const Eigen::MatrixXd & V, Eigen::RowVector3d & N, Eigen::RowVector3d & C) { assert(V.rows()>0); Eigen::Vector3d sum = V.colwise().sum(); Eigen::Vector3d center = sum.array()/(double(V.rows())); C = center; double sumXX=0.0f,sumXY=0.0f,sumXZ=0.0f; double sumYY=0.0f,sumYZ=0.0f; double sumZZ=0.0f; for(int i=0;i<V.rows();i++) { double diffX=V(i,0)-center(0); double diffY=V(i,1)-center(1); double diffZ=V(i,2)-center(2); sumXX+=diffX*diffX; sumXY+=diffX*diffY; sumXZ+=diffX*diffZ; sumYY+=diffY*diffY; sumYZ+=diffY*diffZ; sumZZ+=diffZ*diffZ; } Eigen::MatrixXd m(3,3); m << sumXX,sumXY,sumXZ, sumXY,sumYY,sumYZ, sumXZ,sumYZ,sumZZ; Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(m); N = es.eigenvectors().col(0); }
TEST(slice_into,density_reverse) { { Eigen::MatrixXd A = Eigen::MatrixXd::Random(10,9); Eigen::VectorXi I = Eigen::VectorXi::LinSpaced(A.rows(),A.rows()-1,0); Eigen::VectorXi J = Eigen::VectorXi::LinSpaced(A.cols(),0,A.cols()-1); Eigen::MatrixXd B(I.maxCoeff()+1,J.maxCoeff()+1); igl::slice_into(A,I,J,B); // reverse rows (i.e., reverse each column vector) Eigen::MatrixXd C = A.colwise().reverse().eval(); test_common::assert_eq(B,C); } { Eigen::MatrixXd A = Eigen::MatrixXd::Random(10,9); Eigen::VectorXi I = Eigen::VectorXi::LinSpaced(A.rows(),0,A.rows()-1); Eigen::VectorXi J = Eigen::VectorXi::LinSpaced(A.cols(),A.cols()-1,0); Eigen::MatrixXd B(I.maxCoeff()+1,J.maxCoeff()+1); igl::slice_into(A,I,J,B); // reverse cols (i.e., reverse each row vector) Eigen::MatrixXd C = A.rowwise().reverse().eval(); test_common::assert_eq(B,C); } }
Eigen::MatrixXd sqExp(const Eigen::MatrixXd &x1, const Eigen::MatrixXd &x2, const Eigen::VectorXd &lengthScale, bool noisy) { // assert(x1.rows() == x2.rows()) int n1 = x1.cols(), n2 = x2.cols(); // Compute the weighted square distances Eigen::VectorXd w = (lengthScale.array().square().cwiseInverse()).matrix(); Eigen::MatrixXd xx1 = w.replicate(1, n1).cwiseProduct(x1).cwiseProduct(x1).colwise().sum(); Eigen::MatrixXd xx2 = w.replicate(1, n2).cwiseProduct(x2).cwiseProduct(x2).colwise().sum(); Eigen::MatrixXd x1x2 = w.replicate(1, n1).cwiseProduct(x1).transpose() * x2; // Compute the covariance matrix Eigen::MatrixXd K = (-0.5 * Eigen::MatrixXd::Zero(n1, n2).cwiseMax( xx1.transpose().replicate(1, n2) + xx2.replicate(n1, 1) - 2 * x1x2)).array().exp(); if (noisy) { K += K.colwise().sum().asDiagonal(); } return K; }
void object::test<6>() { for (int i = 0;i<10;i++) { int dim = rand()%1000+2; int samplenum1 = rand()%1000+100; int samplenum2 = rand()%1000+100; Eigen::MatrixXd ha = Eigen::MatrixXd::Random(dim,samplenum1); Eigen::MatrixXd hb = Eigen::MatrixXd::Random(dim,samplenum2); Eigen::VectorXd haa = (ha.array()*ha.array()).colwise().sum(); Eigen::VectorXd hbb = (hb.array()*hb.array()).colwise().sum(); Eigen::MatrixXd hdist = -2*ha.transpose()*hb; hdist.colwise() += haa; hdist.rowwise() += hbb.transpose(); Matrix<double> ga(ha),gb(hb); Matrix<double> gdist = -2*ga.transpose()*gb; Vector<double> gaa = (ga.array()*ga.array()).colwise().sum(); Vector<double> gbb = (gb.array()*gb.array()).colwise().sum(); gdist.colwise() += gaa; gdist.rowwise() += gbb; ensure(check_diff(hdist,gdist)); } }
void parse_rhs( const int nrhs, const mxArray *prhs[], Eigen::MatrixXd & IV, Eigen::MatrixXi & IF, double & level, double & angle_bound, double & radius_bound, double & distance_bound, igl::SignedDistanceType & type) { using namespace std; using namespace igl; using namespace Eigen; mexErrMsgTxt(nrhs >= 2, "The number of input arguments must be >=2."); const int dim = mxGetN(prhs[0]); mexErrMsgTxt(dim == 3, "Mesh vertex list must be #V by 3 list of vertex positions"); parse_rhs_double(prhs,IV); parse_rhs_index(prhs+1,IF); // defaults level = 0.0; angle_bound = 28.0; double bbd = 1.0; // Radius and distance in terms of fraction of bbd if(IV.size() > 0) { bbd = (IV.colwise().maxCoeff()-IV.colwise().minCoeff()).norm(); } radius_bound = 0.02*bbd; distance_bound = 0.02*bbd; type = SIGNED_DISTANCE_TYPE_DEFAULT; { int i = 2; while(i<nrhs) { mexErrMsgTxt(mxIsChar(prhs[i]),"Parameter names should be strings"); // Cast to char const char * name = mxArrayToString(prhs[i]); const auto requires_arg = [](const int i, const int nrhs, const char * name) { mexErrMsgTxt((i+1)<nrhs, C_STR("Parameter '"<<name<<"' requires argument")); }; const auto validate_double = [](const int i, const mxArray * prhs[], const char * name) { mexErrMsgTxt(mxIsDouble(prhs[i]), C_STR("Parameter '"<<name<<"' requires Double argument")); }; const auto validate_scalar = [](const int i, const mxArray * prhs[], const char * name) { mexErrMsgTxt(mxGetN(prhs[i])==1 && mxGetM(prhs[i])==1, C_STR("Parameter '"<<name<<"' requires scalar argument")); }; const auto validate_char = [](const int i, const mxArray * prhs[], const char * name) { mexErrMsgTxt(mxIsChar(prhs[i]), C_STR("Parameter '"<<name<<"' requires char argument")); }; if(strcmp("Level",name) == 0) { requires_arg(i,nrhs,name); i++; validate_double(i,prhs,name); validate_scalar(i,prhs,name); level = (double)*mxGetPr(prhs[i]); }else if(strcmp("AngleBound",name) == 0) { requires_arg(i,nrhs,name); i++; validate_double(i,prhs,name); validate_scalar(i,prhs,name); angle_bound = (double)*mxGetPr(prhs[i]); }else if(strcmp("RadiusBound",name) == 0) { requires_arg(i,nrhs,name); i++; validate_double(i,prhs,name); validate_scalar(i,prhs,name); radius_bound = ((double)*mxGetPr(prhs[i])) * bbd; }else if(strcmp("DistanceBound",name) == 0) { requires_arg(i,nrhs,name); i++; validate_double(i,prhs,name); validate_scalar(i,prhs,name); distance_bound = ((double)*mxGetPr(prhs[i])) * bbd; }else if(strcmp("SignedDistanceType",name) == 0) { requires_arg(i,nrhs,name); i++; validate_char(i,prhs,name); const char * type_name = mxArrayToString(prhs[i]); if(strcmp("pseudonormal",type_name)==0) { type = igl::SIGNED_DISTANCE_TYPE_PSEUDONORMAL; }else if(strcmp("winding_number",type_name)==0) { type = igl::SIGNED_DISTANCE_TYPE_WINDING_NUMBER; }else if(strcmp("default",type_name)==0) { type = igl::SIGNED_DISTANCE_TYPE_DEFAULT; }else if(strcmp("unsigned",type_name)==0) { type = igl::SIGNED_DISTANCE_TYPE_UNSIGNED; }else { mexErrMsgTxt(false,C_STR("Unknown SignedDistanceType: "<<type_name)); } }else { mexErrMsgTxt(false,"Unknown parameter"); } i++; } } if(type != igl::SIGNED_DISTANCE_TYPE_UNSIGNED) { mexErrMsgTxt(dim == mxGetN(prhs[1]), "Mesh \"face\" simplex size must equal dimension"); } }
int main(int argc, char * argv[]) { using namespace Eigen; using namespace igl; using namespace std; // init mesh string filename = "../shared/beast.obj"; if(argc < 2) { cerr<<"Usage:"<<endl<<" ./example input.obj"<<endl; cout<<endl<<"Opening default mesh..."<<endl; }else { // Read and prepare mesh filename = argv[1]; } // dirname, basename, extension and filename string d,b,ext,f; pathinfo(filename,d,b,ext,f); // Convert extension to lower case transform(ext.begin(), ext.end(), ext.begin(), ::tolower); vector<vector<double > > vV,vN,vTC; vector<vector<int > > vF,vFTC,vFN; if(ext == "obj") { // Convert extension to lower case if(!igl::readOBJ(filename,vV,vTC,vN,vF,vFTC,vFN)) { return 1; } }else if(ext == "off") { // Convert extension to lower case if(!igl::readOFF(filename,vV,vF,vN)) { return 1; } }else if(ext == "wrl") { // Convert extension to lower case if(!igl::readWRL(filename,vV,vF)) { return 1; } //}else //{ // // Convert extension to lower case // MatrixXi T; // if(!igl::readMESH(filename,V,T,F)) // { // return 1; // } // //if(F.size() > T.size() || F.size() == 0) // { // boundary_faces(T,F); // } } if(vV.size() > 0) { if(!list_to_matrix(vV,V)) { return 1; } triangulate(vF,F); } // Compute normals, centroid, colors, bounding box diagonal per_vertex_normals(V,F,N); mid = 0.5*(V.colwise().maxCoeff() + V.colwise().minCoeff()); bbd = (V.colwise().maxCoeff() - V.colwise().minCoeff()).maxCoeff(); // Init embree ei.init(V.cast<float>(),F.cast<int>()); // Init glut glutInit(&argc,argv); if( !TwInit(TW_OPENGL, NULL) ) { // A fatal error occured fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError()); return 1; } // Create a tweak bar rebar.TwNewBar("TweakBar"); rebar.TwAddVarRW("scene_rot", TW_TYPE_QUAT4F, &scene_rot, ""); rebar.TwAddVarRW("lights_on", TW_TYPE_BOOLCPP, &lights_on, "key=l"); rebar.TwAddVarRW("color", TW_TYPE_COLOR4F, color.data(), "colormode=hls"); rebar.TwAddVarRW("ao_factor", TW_TYPE_DOUBLE, &ao_factor, "min=0 max=1 step=0.2 keyIncr=] keyDecr=[ "); rebar.TwAddVarRW("ao_normalize", TW_TYPE_BOOLCPP, &ao_normalize, "key=n"); rebar.TwAddVarRW("ao_on", TW_TYPE_BOOLCPP, &ao_on, "key=a"); rebar.TwAddVarRW("light_intensity", TW_TYPE_DOUBLE, &light_intensity, "min=0 max=0.4 step=0.1 keyIncr=} keyDecr={ "); rebar.load(REBAR_NAME); glutInitDisplayString( "rgba depth double samples>=8 "); glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH)/2.0,glutGet(GLUT_SCREEN_HEIGHT)); glutCreateWindow("ambient-occlusion"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(key); glutMouseFunc(mouse); glutMotionFunc(mouse_drag); glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT); glutMainLoop(); return 0; }
void BayesNet::createFullJoint(cspace b_Xprior[2]) { std::random_device rd; std::normal_distribution<double> dist(0, 1); cspace tmpConfig; for (int i = 0; i < numParticles; i ++) { // Root for (int j = 0; j < cdim; j++) { fullJointPrev[i][j] = b_Xprior[0][j] + b_Xprior[1][j] * (dist(rd)); tmpConfig[j] = fullJointPrev[i][j]; } // Front Plane cspace relativeConfig, baseConfig, transformedConfig, edgeConfig; cspace frontPlaneConfig, sidePlaneConfig, otherSidePlaneConfig; relativeConfig[0] = 1.22; relativeConfig[1] = -0.025; relativeConfig[2] = 0; relativeConfig[3] = 0; relativeConfig[4] = 0; relativeConfig[5] = Pi; baseConfig = tmpConfig; transFrameConfig(baseConfig, relativeConfig, frontPlaneConfig); //TEMP: if (frontPlaneConfig[5] < 0) frontPlaneConfig[5] += 2 * Pi; copyParticles(frontPlaneConfig, fullJointPrev[i], cdim); // Bottom Edge cspace prior1[2] = {{0,0,0,1.22,0,0},{0,0,0,0.0005,0.0005,0.0005}}; for (int j = 0; j < cdim; j++) { relativeConfig[j] = prior1[0][j] + prior1[1][j] * (dist(rd)); } baseConfig = tmpConfig; transPointConfig(baseConfig, relativeConfig, edgeConfig); copyParticles(edgeConfig, fullJointPrev[i], 2 * cdim); // Side Edge cspace prior2[2] = {{0,-0.025,0,0,-0.025,0.23},{0,0,0,0.0005,0.0005,0.0005}}; for (int j = 0; j < cdim; j++) { relativeConfig[j] = prior2[0][j] + prior2[1][j] * (dist(rd)); } baseConfig = tmpConfig; transPointConfig(baseConfig, relativeConfig, transformedConfig); copyParticles(transformedConfig, fullJointPrev[i], 3 * cdim); // Top edge double edgeTol = 0.001; double edgeOffSet = 0.23; Eigen::Vector3d pa, pb; pa << edgeConfig[0], edgeConfig[1], edgeConfig[2]; pb << edgeConfig[3], edgeConfig[4], edgeConfig[5]; Eigen::Vector3d pa_prime, pb_prime; inverseTransform(pa, frontPlaneConfig, pa_prime); inverseTransform(pb, frontPlaneConfig, pb_prime); double td = dist(rd) * edgeTol; // pa_prime(1) = 0; // pb_prime(1) = 0; Eigen::Vector3d normVec; normVec << (pb_prime(2) - pa_prime(2)), 0, (pa_prime(0) - pb_prime(0)); normVec.normalize(); normVec *= (edgeOffSet + td); pa_prime(0) += normVec(0); pb_prime(0) += normVec(0); pa_prime(2) += normVec(2); pb_prime(2) += normVec(2); Transform(pa_prime, frontPlaneConfig, pa); Transform(pb_prime, frontPlaneConfig, pb); fullJointPrev[i][24] = pa(0); fullJointPrev[i][25] = pa(1); fullJointPrev[i][26] = pa(2); fullJointPrev[i][27] = pb(0); fullJointPrev[i][28] = pb(1); fullJointPrev[i][29] = pb(2); // Side Plane relativeConfig[0] = 0; relativeConfig[1] = 0; relativeConfig[2] = 0; relativeConfig[3] = 0; relativeConfig[4] = 0; relativeConfig[5] = -Pi / 2.0; baseConfig = tmpConfig; transFrameConfig(baseConfig, relativeConfig, sidePlaneConfig); copyParticles(sidePlaneConfig, fullJointPrev[i], 5 * cdim); // Other Side Plane relativeConfig[0] = 1.24 + dist(rd) * 0.003; // relativeConfig[0] = 1.2192; relativeConfig[1] = 0; relativeConfig[2] = 0; relativeConfig[3] = 0; relativeConfig[4] = 0; relativeConfig[5] = Pi / 2.0; baseConfig = tmpConfig; transFrameConfig(baseConfig, relativeConfig, otherSidePlaneConfig); copyParticles(otherSidePlaneConfig, fullJointPrev[i], 6 * cdim); // Hole } fullJoint = fullJointPrev; Eigen::MatrixXd mat = Eigen::Map<Eigen::MatrixXd>((double *)fullJoint.data(), fulldim, numParticles); Eigen::MatrixXd mat_centered = mat.colwise() - mat.rowwise().mean(); cov_mat = (mat_centered * mat_centered.adjoint()) / double(max2(mat.cols() - 1, 1)); }
bool BayesNet::updateFullJoint(double cur_M[2][3], double Xstd_ob, double R, int nodeidx) { cout << "Start updating!" << endl; std::unordered_set<string> bins; std::random_device rd; std::normal_distribution<double> dist(0, 1); std::uniform_real_distribution<double> distribution(0, numParticles); int i = 0; int count = 0; int count2 = 0; int count3 = 0; bool iffar = false; FullJoint b_X = fullJointPrev; int idx = 0; jointCspace tempFullState; cspace tempState; double D; double cur_inv_M[2][3]; double unsigned_dist_check = R + 1 * Xstd_ob; double signed_dist_check = 1 * Xstd_ob; //Eigen::Vector3d gradient; Eigen::Vector3d touch_dir; int num_bins = 0; int count_bar = 0; double coeff = pow(4.0 / ((fulldim + 2.0) * numParticles), 2.0/(fulldim + 4.0)) /1.2155/1.2155; // cout << "Coeff: " << coeff << endl; Eigen::MatrixXd H_cov = coeff * cov_mat; // cout << "full_cov_mat: " << full_cov_mat << endl; // cout << "cov_mat: " << cov_mat << endl; // cout << "H_cov: " << H_cov << endl; Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eigenSolver(H_cov); Eigen::MatrixXd rot = eigenSolver.eigenvectors(); Eigen::VectorXd scl = eigenSolver.eigenvalues(); for (int j = 0; j < fulldim; j++) { scl(j, 0) = sqrt(max2(scl(j, 0),0)); } Eigen::VectorXd samples(fulldim, 1); Eigen::VectorXd rot_sample(fulldim, 1); if (nodeidx == 1 || nodeidx == 5 || nodeidx == 6) { // Plane cout << "Start updating Plane!" << endl; while (i < numParticles && i < maxNumParticles) { idx = int(floor(distribution(rd))); for (int j = 0; j < fulldim; j++) { samples(j, 0) = scl(j, 0) * dist(rd); } rot_sample = rot*samples; for (int j = 0; j < fulldim; j++) { /* TODO: use quaternions instead of euler angles */ tempFullState[j] = b_X[idx][j] + rot_sample(j, 0); } for (int j = 0; j < cdim; j++) { /* TODO: use quaternions instead of euler angles */ tempState[j] = tempFullState[j + nodeidx * cdim]; } inverseTransform(cur_M, tempState, cur_inv_M); touch_dir << cur_inv_M[1][0], cur_inv_M[1][1], cur_inv_M[1][2]; D = abs(cur_inv_M[0][1] - R); // cout << "D: " << D << endl; // if (xind >= (dist_transform->num_voxels[0] - 1) || yind >= (dist_transform->num_voxels[1] - 1) || zind >= (dist_transform->num_voxels[2] - 1)) // continue; count += 1; // if (sqrt(count) == floor(sqrt(count))) cout << "DDDD " << D << endl; if (D <= signed_dist_check) { // if (sqrt(count) == floor(sqrt(count))) cout << "D " << D << endl; count2 ++; for (int j = 0; j < fulldim; j++) { fullJoint[i][j] = tempFullState[j]; } if (checkEmptyBin(&bins, tempState) == 1) { num_bins++; // if (i >= N_MIN) { //int numBins = bins.size(); numParticles = min2(maxNumParticles, max2(((num_bins - 1) * 2), N_MIN)); // } } //double d = testResult(mesh, particles[i], cur_M, R); //if (d > 0.01) // cout << cur_inv_M[0][0] << " " << cur_inv_M[0][1] << " " << cur_inv_M[0][2] << " " << d << " " << D << //" " << gradient << " " << gradient.dot(touch_dir) << // " " << dist_adjacent[0] << " " << dist_adjacent[1] << " " << dist_adjacent[2] << " " << particles[i][2] << endl; i += 1; } } cout << "End updating Plane!" << endl; } else { // Edge // for (int i = 0; i < numParticles; i ++) { // // for (int j = 0; j < cdim; j ++) { // // cout << particles[i][j] << " ,"; // // } // cout << particles[i][0] << " ,"; // } // cout << endl; // for (int i = 0; i < numParticles; i ++) { // // for (int j = 0; j < 18; j ++) { // // cout << fullParticles[i][j] << " ,"; // // } // cout << fullParticles[i][0] << " ,"; // } // cout << endl; while (i < numParticles && i < maxNumParticles) { idx = int(floor(distribution(rd))); for (int j = 0; j < fulldim; j++) { samples(j, 0) = scl(j, 0) * dist(rd); } rot_sample = rot*samples; for (int j = 0; j < fulldim; j++) { /* TODO: use quaternions instead of euler angles */ tempFullState[j] = b_X[idx][j] + rot_sample(j, 0); } for (int j = 0; j < cdim; j++) { /* TODO: use quaternions instead of euler angles */ tempState[j] = tempFullState[j + nodeidx * cdim]; } Eigen::Vector3d x1, x2, x0, tmp1, tmp2; x1 << tempState[0], tempState[1], tempState[2]; x2 << tempState[3], tempState[4], tempState[5]; x0 << cur_M[0][0], cur_M[0][1], cur_M[0][2]; tmp1 = x1 - x0; tmp2 = x2 - x1; D = (tmp1.squaredNorm() * tmp2.squaredNorm() - pow(tmp1.dot(tmp2),2)) / tmp2.squaredNorm(); D = abs(sqrt(D)- R); // cout << "Cur distance: " << D << endl; // cout << "D: " << D << endl; // if (xind >= (dist_transform->num_voxels[0] - 1) || yind >= (dist_transform->num_voxels[1] - 1) || zind >= (dist_transform->num_voxels[2] - 1)) // continue; count += 1; // if (sqrt(count) == floor(sqrt(count))) cout << "DDDD " << D << endl; if (D <= signed_dist_check) { // if (sqrt(count) == floor(sqrt(count))) cout << "D " << D << endl; count2 ++; for (int j = 0; j < fulldim; j++) { fullJoint[i][j] = tempFullState[j]; } if (checkEmptyBin(&bins, tempState) == 1) { num_bins++; // if (i >= N_MIN) { //int numBins = bins.size(); numParticles = min2(maxNumParticles, max2(((num_bins - 1) * 2), N_MIN)); // } } //double d = testResult(mesh, particles[i], cur_M, R); //if (d > 0.01) // cout << cur_inv_M[0][0] << " " << cur_inv_M[0][1] << " " << cur_inv_M[0][2] << " " << d << " " << D << //" " << gradient << " " << gradient.dot(touch_dir) << // " " << dist_adjacent[0] << " " << dist_adjacent[1] << " " << dist_adjacent[2] << " " << particles[i][2] << endl; i += 1; } } cout << "End updating Edge!" << endl; } cout << "Number of total iterations: " << count << endl; cout << "Number of iterations after unsigned_dist_check: " << count2 << endl; cout << "Number of iterations before safepoint check: " << count3 << endl; cout << "Number of occupied bins: " << num_bins << endl; cout << "Number of particles: " << numParticles << endl; fullJointPrev = fullJoint; // double* tmpParticles = new double[numParticles * fulldim]; // for(int i = 0; i < numParticles; ++i) { // for (int j = 0; j < fulldim; j ++) { // tmpParticles[i * fulldim + j] = fullParticlesPrev[i][j]; // } // } Eigen::MatrixXd mat = Eigen::Map<Eigen::MatrixXd>((double *)fullJoint.data(), fulldim, numParticles); Eigen::MatrixXd mat_centered = mat.colwise() - mat.rowwise().mean(); cov_mat = (mat_centered * mat_centered.adjoint()) / double(max2(mat.cols() - 1, 1)); cout << "End updating!" << endl; return iffar; }
int main(int argc, char * argv[]) { using namespace Eigen; using namespace igl; using namespace std; // init mesh string filename = "../shared/truck.obj"; string filename_other = ""; switch(argc) { case 3: // Read and prepare mesh filename_other = argv[2]; has_other=true; // fall through case 2: // Read and prepare mesh filename = argv[1]; break; default: cerr<<"Usage:"<<endl<<" ./example input.obj [other.obj]"<<endl; cout<<endl<<"Opening default mesh..."<<endl; } const auto read = [] (const string & filename, MatrixXd & V, MatrixXi & F, MatrixXd & N) -> bool { // dirname, basename, extension and filename string d,b,ext,f; pathinfo(filename,d,b,ext,f); // Convert extension to lower case transform(ext.begin(), ext.end(), ext.begin(), ::tolower); vector<vector<double > > vV,vN,vTC; vector<vector<int > > vF,vFTC,vFN; if(ext == "obj") { // Convert extension to lower case if(!igl::readOBJ(filename,vV,vTC,vN,vF,vFTC,vFN)) { return false; } }else if(ext == "off") { // Convert extension to lower case if(!igl::readOFF(filename,vV,vF,vN)) { return false; } }else if(ext == "wrl") { // Convert extension to lower case if(!igl::readWRL(filename,vV,vF)) { return false; } //}else //{ // // Convert extension to lower case // MatrixXi T; // if(!igl::readMESH(filename,V,T,F)) // { // return false; // } // //if(F.size() > T.size() || F.size() == 0) // { // boundary_facets(T,F); // } } if(vV.size() > 0) { if(!list_to_matrix(vV,V)) { return false; } polygon_mesh_to_triangle_mesh(vF,F); } // Compute normals, centroid, colors, bounding box diagonal per_face_normals(V,F,N); return true; }; if(!read(filename,V,F,N)) { return 1; } if(has_other) { if(!read(argv[2],U,G,W)) { return 1; } cat(1,V,U,VU); color_intersections(V,F,U,G,C,D); }else { VU = V; color_selfintersections(V,F,C); } mid = 0.5*(VU.colwise().maxCoeff() + VU.colwise().minCoeff()); bbd = (VU.colwise().maxCoeff() - VU.colwise().minCoeff()).maxCoeff(); // Init glut glutInit(&argc,argv); if( !TwInit(TW_OPENGL, NULL) ) { // A fatal error occured fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError()); return 1; } // Create a tweak bar rebar.TwNewBar("TweakBar"); rebar.TwAddVarRW("camera_rotation", TW_TYPE_QUAT4D, s.camera.m_rotation_conj.coeffs().data(), "open readonly=true"); s.camera.push_away(3); s.camera.dolly_zoom(25-s.camera.m_angle); TwType RotationTypeTW = igl::anttweakbar::ReTwDefineEnumFromString("RotationType", "igl_trackball,two-a...-fixed-up"); rebar.TwAddVarCB( "rotation_type", RotationTypeTW, set_rotation_type,get_rotation_type,NULL,"keyIncr=] keyDecr=["); if(has_other) { rebar.TwAddVarRW("show_A",TW_TYPE_BOOLCPP,&show_A, "key=a",false); rebar.TwAddVarRW("show_B",TW_TYPE_BOOLCPP,&show_B, "key=b",false); } rebar.load(REBAR_NAME); glutInitDisplayString("rgba depth double samples>=8 "); glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH)/2.0,glutGet(GLUT_SCREEN_HEIGHT)); glutCreateWindow("mesh-intersections"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(key); glutMouseFunc(mouse); glutMotionFunc(mouse_drag); glutPassiveMotionFunc( [](int x, int y) { TwEventMouseMotionGLUT(x,y); glutPostRedisplay(); }); static std::function<void(int)> timer_bounce; auto timer = [] (int ms) { timer_bounce(ms); }; timer_bounce = [&] (int ms) { glutTimerFunc(ms, timer, ms); glutPostRedisplay(); }; glutTimerFunc(500, timer, 500); glutMainLoop(); return 0; }
int main(int argc, char *argv[]) { using namespace Eigen; using namespace std; igl::readOBJ("../shared/armadillo.obj",V,F); U=V; MatrixXd W; igl::readDMAT("../shared/armadillo-weights.dmat",W); igl::lbs_matrix_column(V,W,M); // Cluster according to weights VectorXi G; { VectorXi S; VectorXd D; igl::partition(W,50,G,S,D); } // vertices corresponding to handles (those with maximum weight) { VectorXd maxW; igl::mat_max(W,1,maxW,b); } // Precomputation for FAST cout<<"Initializing Fast Automatic Skinning Transformations..."<<endl; // number of weights const int m = W.cols(); Aeq.resize(m*3,m*3*(3+1)); vector<Triplet<double> > ijv; for(int i = 0;i<m;i++) { RowVector4d h**o; h**o << V.row(b(i)),1.; for(int d = 0;d<3;d++) { for(int c = 0;c<(3+1);c++) { ijv.push_back(Triplet<double>(3*i + d,i + c*m*3 + d*m, h**o(c))); } } } Aeq.setFromTriplets(ijv.begin(),ijv.end()); igl::arap_dof_precomputation(V,F,M,G,arap_dof_data); igl::arap_dof_recomputation(VectorXi(),Aeq,arap_dof_data); // Initialize MatrixXd Istack = MatrixXd::Identity(3,3+1).replicate(1,m); igl::columnize(Istack,m,2,L); // Precomputation for ARAP cout<<"Initializing ARAP..."<<endl; arap_data.max_iter = 1; igl::arap_precomputation(V,F,V.cols(),b,arap_data); // Grouped arap cout<<"Initializing ARAP with grouped edge-sets..."<<endl; arap_grouped_data.max_iter = 2; arap_grouped_data.G = G; igl::arap_precomputation(V,F,V.cols(),b,arap_grouped_data); // bounding box diagonal bbd = (V.colwise().maxCoeff()- V.colwise().minCoeff()).norm(); // Plot the mesh with pseudocolors igl::Viewer viewer; viewer.data.set_mesh(U, F); viewer.data.add_points(igl::slice(V,b,1),sea_green); viewer.core.show_lines = false; viewer.callback_pre_draw = &pre_draw; viewer.callback_key_down = &key_down; viewer.core.is_animating = false; viewer.core.animation_max_fps = 30.; cout<< "Press [space] to toggle animation."<<endl<< "Press '0' to reset pose."<<endl<< "Press '.' to switch to next deformation method."<<endl<< "Press ',' to switch to previous deformation method."<<endl; viewer.launch(); }