#include #include #include #include #include #include #include #include #include double sdCapsule( const Eigen::RowVector2d & p, const Eigen::RowVector2d & a, const Eigen::RowVector2d & b, const double & r ) { using Scalar = double; Eigen::RowVector2d pa = p - a, ba = b - a; Scalar h = std::max(Scalar(0), std::min(Scalar(1), pa.dot(ba)/ba.dot(ba))); return (pa - ba*h).norm() - r; } int main(int argc, char * argv[]) { IGL_TICTOC_LAMBDA; Eigen::MatrixXd V; Eigen::MatrixXi E; igl::readDMAT(argc>1?argv[1]: TUTORIAL_SHARED_PATH "/libigl-cursive-V.dmat",V); igl::readDMAT(argc>1?argv[2]: TUTORIAL_SHARED_PATH "/libigl-cursive-E.dmat",E); Eigen::MatrixXi F(E.rows(),3); F< EB1,EB2; igl::box_simplices(V,E,EB1,EB2); Eigen::Matrix B1,B2; Eigen::VectorXi leaf; igl::eytzinger_aabb(EB1,EB2,B1,B2,leaf); printf("AABB build: %f s\n",tictoc()); Eigen::VectorXi I,C; igl::eytzinger_aabb_winding_number_tree(E,leaf,I,C); printf("Winding number tree build: %f s\n",tictoc()); igl::opengl::glfw::Viewer viewer; viewer.data().set_mesh(GV,GF); enum Quantity { SIGNED_DISTANCE, UNSIGNED_DISTANCE, WINDING_NUMBER } quantity = SIGNED_DISTANCE; bool naive = false; const auto update = [&]() { tictoc(); Eigen::VectorXd D(GV.rows()); for(int i=0;i::infinity(); wi = 0; for(int e = 0;e primitive_p = [&](const int e)-> double { double d = sdCapsule( p, V.row(E(e,0)), V.row(E(e,1)), 0.0); return d; }; if(quantity == UNSIGNED_DISTANCE || quantity == SIGNED_DISTANCE) { igl::eytzinger_aabb_sdf(p,primitive_p,B1,B2,leaf,di); } if(quantity == WINDING_NUMBER || quantity == SIGNED_DISTANCE) { igl::eytzinger_aabb_winding_number(p,V,E,B1,B2,leaf,I,C,wi); } } switch(quantity) { case SIGNED_DISTANCE: D(i) = di * (std::abs(wi) > 0.5?-1:1); break; case UNSIGNED_DISTANCE: D(i) = di; break; case WINDING_NUMBER: D(i) = wi; break; } } printf("Compute %s %s: %f s\n", naive?"naive":"aabb", quantity==SIGNED_DISTANCE?"signed distance": quantity==UNSIGNED_DISTANCE?"unsigned distance":"winding number", tictoc()); viewer.data().set_data(D); }; update(); viewer.data().show_lines = false; viewer.data().line_width = 2; viewer.core().lighting_factor = 0; viewer.data().set_edges(V,E,Eigen::RowVector3d(0,0,0)); // key viewer.callback_key_pressed = [&](igl::opengl::glfw::Viewer &, unsigned int key, int mod)->bool { switch(key) { default: return false; case 'N': case 'n': naive = !naive; break; case 'W': case 'w': quantity = WINDING_NUMBER; break; case 'U': case 'u': quantity = UNSIGNED_DISTANCE; break; case 'S': case 's': quantity = SIGNED_DISTANCE; break; } update(); return true; }; std::cout<