IGL_INLINE void igl::remove_unreferenced( const Eigen::PlainObjectBase<DerivedV> &V, const Eigen::PlainObjectBase<DerivedF> &F, Eigen::PlainObjectBase<DerivedNV> &NV, Eigen::PlainObjectBase<DerivedNF> &NF, Eigen::PlainObjectBase<DerivedI> &I) { // Mark referenced vertices Eigen::MatrixXi mark = Eigen::MatrixXi::Zero(V.rows(),1); for(int i=0; i<F.rows(); ++i) { for(int j=0; j<F.cols(); ++j) { if (F(i,j) != -1) mark(F(i,j)) = 1; } } // Sum the occupied cells int newsize = mark.sum(); NV.resize(newsize,V.cols()); I.resize(V.rows(),1); // Do a pass on the marked vector and remove the unreferenced vertices int count = 0; for(int i=0;i<mark.rows();++i) { if (mark(i) == 1) { NV.row(count) = V.row(i); I(i) = count; count++; } else { I(i) = -1; } } NF.resize(F.rows(),F.cols()); // Apply I on F for (int i=0; i<F.rows(); ++i) { Eigen::RowVectorXi t(F.cols()); for (int j=0; j<F.cols(); ++j) t(j) = I(F(i,j)); NF.row(i) = t; } }
void drawCuts(igl::viewer::Viewer& viewer, const Eigen::MatrixXi &cuts) { int maxCutNum = cuts.sum(); Eigen::MatrixXd start(maxCutNum,3); Eigen::MatrixXd end(maxCutNum,3); int ind = 0; for (unsigned int i=0;i<F.rows();i++) for (int j=0;j<3;j++) if (cuts(i,j)) { start.row(ind) = V.row(F(i,j)); end.row(ind) = V.row(F(i,(j+1)%3)); ind++; } viewer.data.add_edges(start, end , Eigen::RowVector3d(1.,0,1.)); }
bool key_down(igl::viewer::Viewer& viewer, unsigned char key, int modifier) { if (key == 'E') { extend_arrows = !extend_arrows; } if (key <'1' || key >'8') return false; viewer.data.clear(); viewer.core.show_lines = false; viewer.core.show_texture = false; if (key == '1') { // Cross field viewer.data.set_mesh(V, F); viewer.data.add_edges(extend_arrows ? B - global_scale*X1 : B, B + global_scale*X1 ,Eigen::RowVector3d(1,0,0)); viewer.data.add_edges(extend_arrows ? B - global_scale*X2 : B, B + global_scale*X2 ,Eigen::RowVector3d(0,0,1)); } if (key == '2') { // Bisector field viewer.data.set_mesh(V, F); viewer.data.add_edges(extend_arrows ? B - global_scale*BIS1 : B, B + global_scale*BIS1 ,Eigen::RowVector3d(1,0,0)); viewer.data.add_edges(extend_arrows ? B - global_scale*BIS2 : B, B + global_scale*BIS2 ,Eigen::RowVector3d(0,0,1)); } if (key == '3') { // Bisector field combed viewer.data.set_mesh(V, F); viewer.data.add_edges(extend_arrows ? B - global_scale*BIS1_combed : B, B + global_scale*BIS1_combed ,Eigen::RowVector3d(1,0,0)); viewer.data.add_edges(extend_arrows ? B - global_scale*BIS2_combed : B, B + global_scale*BIS2_combed ,Eigen::RowVector3d(0,0,1)); } if (key == '4') { // Singularities and cuts viewer.data.set_mesh(V, F); // Plot cuts int l_count = Seams.sum(); Eigen::MatrixXd P1(l_count,3); Eigen::MatrixXd P2(l_count,3); for (unsigned i=0; i<Seams.rows(); ++i) { for (unsigned j=0; j<Seams.cols(); ++j) { if (Seams(i,j) != 0) { P1.row(l_count-1) = V.row(F(i,j)); P2.row(l_count-1) = V.row(F(i,(j+1)%3)); l_count--; } } } viewer.data.add_edges(P1, P2, Eigen::RowVector3d(1, 0, 0)); // Plot the singularities as colored dots (red for negative, blue for positive) for (unsigned i=0; i<singularityIndex.size(); ++i) { if (singularityIndex(i) < 2 && singularityIndex(i) > 0) viewer.data.add_points(V.row(i),Eigen::RowVector3d(1,0,0)); else if (singularityIndex(i) > 2) viewer.data.add_points(V.row(i),Eigen::RowVector3d(0,1,0)); } } if (key == '5') { // Singularities and cuts, original field // Singularities and cuts viewer.data.set_mesh(V, F); viewer.data.add_edges(extend_arrows ? B - global_scale*X1_combed : B, B + global_scale*X1_combed ,Eigen::RowVector3d(1,0,0)); viewer.data.add_edges(extend_arrows ? B - global_scale*X2_combed : B, B + global_scale*X2_combed ,Eigen::RowVector3d(0,0,1)); // Plot cuts int l_count = Seams.sum(); Eigen::MatrixXd P1(l_count,3); Eigen::MatrixXd P2(l_count,3); for (unsigned i=0; i<Seams.rows(); ++i) { for (unsigned j=0; j<Seams.cols(); ++j) { if (Seams(i,j) != 0) { P1.row(l_count-1) = V.row(F(i,j)); P2.row(l_count-1) = V.row(F(i,(j+1)%3)); l_count--; } } } viewer.data.add_edges(P1, P2, Eigen::RowVector3d(1, 0, 0)); // Plot the singularities as colored dots (red for negative, blue for positive) for (unsigned i=0; i<singularityIndex.size(); ++i) { if (singularityIndex(i) < 2 && singularityIndex(i) > 0) viewer.data.add_points(V.row(i),Eigen::RowVector3d(1,0,0)); else if (singularityIndex(i) > 2) viewer.data.add_points(V.row(i),Eigen::RowVector3d(0,1,0)); } } if (key == '6') { // Global parametrization UV viewer.data.set_mesh(UV, FUV); viewer.data.set_uv(UV); viewer.core.show_lines = true; } if (key == '7') { // Global parametrization in 3D viewer.data.set_mesh(V, F); viewer.data.set_uv(UV,FUV); viewer.core.show_texture = true; } if (key == '8') { // Global parametrization in 3D with seams viewer.data.set_mesh(V, F); viewer.data.set_uv(UV_seams,FUV_seams); viewer.core.show_texture = true; } viewer.data.set_colors(Eigen::RowVector3d(1,1,1)); // Replace the standard texture with an integer shift invariant texture Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic> texture_R, texture_G, texture_B; line_texture(texture_R, texture_G, texture_B); viewer.data.set_texture(texture_R, texture_B, texture_G); viewer.core.align_camera_center(viewer.data.V,viewer.data.F); return false; }