void init_patches() { using namespace Eigen; using namespace igl; using namespace std; { VectorXi VCC; components(F,VCC); cout<<"There are "<<VCC.maxCoeff()+1<<" connected components of vertices."<<endl; } bfs_orient(F,F,CC); VectorXi I; switch(orient_method) { case ORIENT_METHOD_AO: { cout<<"orient_outward_ao()"<<endl; igl::embree::reorient_facets_raycast(V,F,F,I); break; } case ORIENT_METHOD_OUTWARD: default: cout<<"orient_outward()"<<endl; orient_outward(V,F,CC,F,I); break; } double num_cc = (double)CC.maxCoeff()+1.0; cout<<"There are "<<num_cc<<" 'manifold/orientable' patches of faces."<<endl; }
TEST(slice_into, sparse_identity) { Eigen::SparseMatrix<double> A = Eigen::MatrixXd::Random(10,9).sparseView(); Eigen::VectorXi I = Eigen::VectorXi::LinSpaced(A.rows(),0,A.rows()-1); Eigen::VectorXi J = Eigen::VectorXi::LinSpaced(A.cols(),0,A.cols()-1); { Eigen::SparseMatrix<double> B(I.maxCoeff()+1,J.maxCoeff()+1); igl::slice_into(A,I,J,B); test_common::assert_eq(A,B); } { Eigen::SparseMatrix<double> B(I.maxCoeff()+1,A.cols()); igl::slice_into(A,I,1,B); test_common::assert_eq(A,B); } { Eigen::SparseMatrix<double> B(A.rows(),J.maxCoeff()+1); igl::slice_into(A,J,2,B); test_common::assert_eq(A,B); } }
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); } }
void randomly_color( const Eigen::VectorXi & CC, Eigen::MatrixXd & C) { using namespace Eigen; using namespace igl; using namespace std; VectorXi I; srand ( unsigned ( time(0) ) ); double num_cc = (double)CC.maxCoeff()+1.0; randperm(num_cc,I); C.resize(CC.rows(),3); for(int f = 0;f<CC.rows();f++) { jet( (double)I(CC(f))/num_cc, C(f,0), C(f,1), C(f,2)); } }
#include <test_common.h> #include <igl/unique_rows.h> #include <igl/matrix_to_list.h> TEST_CASE("unique: matrix", "[igl]") { Eigen::VectorXi A(12); A = (Eigen::VectorXd::Random(A.size(),1).array().abs()*9).cast<int>(); Eigen::VectorXi C,IA,IC; igl::unique_rows(A,C,IA,IC); std::vector<bool> inA(A.maxCoeff()+1,false); for(int i = 0;i<A.size();i++) { inA[A(i)] = true; REQUIRE (C(IC(i)) == A(i)); } std::vector<bool> inC(inA.size(),false); // Expect a column vector REQUIRE (C.cols() == 1); for(int i = 0;i<C.size();i++) { // Should be the first time finding this REQUIRE (!inC[C(i)]); // Mark as found inC[C(i)] = true; // Should be something also found in A REQUIRE (inA[C(i)]); REQUIRE (A(IA(i)) == C(i)); } for(int i = 0;i<inC.size();i++) {
void key(unsigned char key, int mouse_x, int mouse_y) { using namespace std; using namespace Eigen; using namespace igl; int mod = glutGetModifiers(); switch(key) { // ESC case char(27): rebar.save(REBAR_NAME); // ^C case char(3): exit(0); case 'I': case 'i': { push_undo(); s.N *= -1.0; F = F.rowwise().reverse().eval(); break; } case 'z': case 'Z': if(mod & GLUT_ACTIVE_COMMAND) { if(mod & GLUT_ACTIVE_SHIFT) { redo(); }else { undo(); } }else { push_undo(); Quaterniond q; snap_to_canonical_view_quat(s.camera.m_rotation_conj,1.0,q); switch(center_type) { default: case CENTER_TYPE_ORBIT: s.camera.orbit(q.conjugate()); break; case CENTER_TYPE_FPS: s.camera.turn_eye(q.conjugate()); break; } } break; case 'u': mouse_wheel(0, 1,mouse_x,mouse_y); break; case 'j': mouse_wheel(0,-1,mouse_x,mouse_y); break; case 'n': cc_selected = (cc_selected + 1) % (CC.maxCoeff() + 2); cout << "selected cc: " << cc_selected << endl; glutPostRedisplay(); break; default: if(!TwEventKeyboardGLUT(key,mouse_x,mouse_y)) { cout<<"Unknown key command: "<<key<<" "<<int(key)<<endl; } } }
bool BF3PointCircle::getRobustCircle(const cvb::CvContourChainCode& contour, const unsigned int maxVotes, const unsigned int maxAccu, const int maxInvalidVotesInSeries, BFCircle& circle) { cvb::CvChainCodes::const_iterator it = contour.chainCode.begin(); cvb::CvChainCodes::const_iterator it_beg = contour.chainCode.begin(); cvb::CvChainCodes::const_iterator it_end = contour.chainCode.end(); unsigned int x = contour.startingPoint.x; unsigned int y = contour.startingPoint.y; BFContour bfContour; while(it != it_end) { bfContour.add(BFCoordinate<int>(static_cast<int>(x),static_cast<int>(y))); x += cvb::cvChainCodeMoves[*it][0]; y += cvb::cvChainCodeMoves[*it][1]; it++; } const unsigned int nContourPoints = bfContour.getPixelCount(); BFRectangle rect = bfContour.getBounds(); int nRows = bfRound(rect.getHeight()); int nCols = bfRound(rect.getWidth()); int x0 = bfRound(rect.getX0()); int y0 = bfRound(rect.getY0()); BFCoordinate<int> topLeft(x0,y0); // generate 2d histogram for circle center estimation Eigen::MatrixXi H = Eigen::MatrixXi::Zero(nRows, nCols); unsigned int votes = 0; int invalidVotesInSeries = 0; while(votes < maxVotes) { unsigned int randIndex1 = (rand() % nContourPoints); unsigned int randIndex2 = (rand() % nContourPoints); while(randIndex2 == randIndex1) randIndex2 = (rand() % nContourPoints); unsigned int randIndex3 = (rand() % nContourPoints); while(randIndex3 == randIndex2 || randIndex3 == randIndex1) randIndex3 = (rand() % nContourPoints); BFCoordinate<int> c1 = bfContour.getCoordinate(randIndex1) - topLeft; BFCoordinate<int> c2 = bfContour.getCoordinate(randIndex2) - topLeft; BFCoordinate<int> c3 = bfContour.getCoordinate(randIndex3) - topLeft; BFCoordinate<double> center; bool validCenter = getCenter(c1,c2,c3,center); if(!validCenter) { votes--; invalidVotesInSeries++; if(invalidVotesInSeries > maxInvalidVotesInSeries) { return false; } continue; } invalidVotesInSeries = 0; double cxD = center.getX(); double cyD = center.getY(); int cx = bfRound(cxD); int cy = bfRound(cyD); if(cx < 0 || cy < 0 || cx >= nRows || cy >= nCols) { continue; } else { H(cx,cy) += 1; if(H(cx,cy) >= static_cast<int>(maxAccu)) { break; } } votes++; } int finalX = 0; int finalY = 0; H.maxCoeff(&finalX,&finalY); finalX += bfRound(x0); finalY += bfRound(y0); // generate 1d histogram for circle radius estimation Eigen::VectorXi K = Eigen::VectorXi::Zero(bfMax(nRows,nCols)); it = it_beg; x = contour.startingPoint.x; y = contour.startingPoint.y; while(it != it_end) { int r = bfRound(sqrt(pow(static_cast<double>(static_cast<int>(x)-finalX),2.0) + pow(static_cast<double>(static_cast<int>(y)-finalY),2.0))); if(r < K.rows()) { K(r) += 1; } x += cvb::cvChainCodeMoves[*it][0]; y += cvb::cvChainCodeMoves[*it][1]; it++; } int finalR = 0; K.maxCoeff(&finalR); circle.set(finalX,finalY,finalR); return true; }
bool BF3PointCircle::getRobustCircle(const BFContour& contour, const unsigned int maxVotes, const unsigned int maxAccu, const int maxInvalidVotesInSeries, BFCircle& circle) { unsigned int nContourPoints = contour.getPixelCount(); BFRectangle rect = contour.getBounds(); BFRectangle zeroRect; if(rect.equals(zeroRect)) { return false; } int nRows = bfRound(rect.getHeight()); int nCols = bfRound(rect.getWidth()); int x0 = bfRound(rect.getX0()); int y0 = bfRound(rect.getY0()); BFCoordinate<int> topLeft(x0,y0); int invalidVotesInSeries = 0; // generate 2d histogram for circle center estimation Eigen::MatrixXi H = Eigen::MatrixXi::Zero(nRows, nCols); unsigned int votes = 0; for(votes; votes <= maxVotes; ++votes) { // random index number in range [0,nContourPoints-1] unsigned int randIndex1 = (rand() % nContourPoints); unsigned int randIndex2 = (rand() % nContourPoints); while(randIndex2 == randIndex1) randIndex2 = (rand() % nContourPoints); unsigned int randIndex3 = (rand() % nContourPoints); while(randIndex3 == randIndex2 || randIndex3 == randIndex1) randIndex3 = (rand() % nContourPoints); BFCoordinate<int> c1 = contour.getCoordinate(randIndex1) - topLeft; BFCoordinate<int> c2 = contour.getCoordinate(randIndex2) - topLeft; BFCoordinate<int> c3 = contour.getCoordinate(randIndex3) - topLeft; BFCoordinate<double> center; bool validCenter = getCenter(c1,c2,c3,center); if(!validCenter) { votes--; invalidVotesInSeries++; if(invalidVotesInSeries > maxInvalidVotesInSeries) { return false; } continue; } invalidVotesInSeries = 0; double cxD = center.getX(); double cyD = center.getY(); int cx = bfRound(cxD); int cy = bfRound(cyD); if(cx < 0 || cy < 0 || cx >= nRows || cy >= nCols) { votes--; continue; } else { H(cx,cy) += 1; if(H(cx,cy) >= static_cast<int>(maxAccu)) { break; } } } int finalX = 0; int finalY = 0; H.maxCoeff(&finalX,&finalY); finalX += bfRound(x0); finalY += bfRound(y0); // generate 1d histogram for circle radius estimation Eigen::VectorXi K = Eigen::VectorXi::Zero(bfMax(nRows,nCols)); const std::vector<BFCoordinate<int> >& cont = contour.getContour(); std::vector<BFCoordinate<int> >::const_iterator iter = cont.begin(); int x; int y; while(iter != cont.end()) { x = bfRound((*iter).getX()); y = bfRound((*iter).getY()); int r = bfRound(sqrt(pow(static_cast<double>(x-finalX),2) + pow(static_cast<double>(y-finalY),2))); if(r < K.rows()) { K(r) += 1; } iter++; } int finalR = 0; K.maxCoeff(&finalR); // return result circle.set(finalX,finalY,finalR); return true; }
bool init_arap() { using namespace igl; using namespace Eigen; using namespace std; VectorXi b(num_in_selection(S)); assert(S.rows() == V.rows()); C.resize(S.rows(),3); MatrixXd bc = MatrixXd::Zero(b.size(),S.maxCoeff()+1); MatrixXi * Ele; if(T.rows()>0) { Ele = &T; }else { Ele = &F; } // get b from S { int bi = 0; for(int v = 0;v<S.rows(); v++) { if(S(v) >= 0) { b(bi) = v; bc(bi,S(v)) = 1; bi++; switch(S(v)) { case 0: C.row(v) = RowVector3d(0.039,0.31,1); break; case 1: C.row(v) = RowVector3d(1,0.41,0.70); break; default: C.row(v) = RowVector3d(0.4,0.8,0.3); break; } }else { C.row(v) = RowVector3d( GOLD_DIFFUSE[0], GOLD_DIFFUSE[1], GOLD_DIFFUSE[2]); } } } // Store current mesh U = V; VectorXi _S; VectorXd _D; MatrixXd W; if(!harmonic(V,*Ele,b,bc,1,W)) { return false; } //arap_data.with_dynamics = true; //arap_data.h = 0.5; //arap_data.max_iter = 100; //partition(W,100,arap_data.G,_S,_D); return arap_precomputation(V,*Ele,V.cols(),b,arap_data); }