#include #include #include #include #include #include #include int main(int argc, char * argv[]) { using namespace Eigen; using namespace std; using namespace igl; MatrixXi F; MatrixXd V; // Read in inputs as double precision floating point meshes read_triangle_mesh( TUTORIAL_SHARED_PATH "/armadillo.obj",V,F); cout<<"Creating grid..."<VectorXd { VectorXd S; { VectorXi I; MatrixXd C,N; signed_distance(Q,V,F,SIGNED_DISTANCE_TYPE_FAST_WINDING_NUMBER,S,I,C,N); // Extremely flatten out near zero S = S.array().sign() * S.array().abs().exp(); } return S; }; VectorXd S = batch_implicit(GV); cout<<"Marching cubes..."< E2V; igl::marching_cubes(S,GV,res(0),res(1),res(2),0,SV,SF,E2V); // Initialize min and max for root finding bisection assert(E2V.size() == SV.rows()); Eigen::MatrixXd T(SV.rows(),2); Eigen::VectorXi I(SV.rows()); // Precompute slices for end points Eigen::MatrixXd GVi(SV.rows(),3); Eigen::MatrixXd GVj(SV.rows(),3); // This is only used for the assertion below const auto ij2key = [](std::int32_t i,std::int32_t j) { if(i>j){ std::swap(i,j); } std::int64_t ret = 0; ret |= i; ret |= static_cast(j) << 32; return ret; }; const auto key2ij = [](const std::int64_t & key, std::int32_t & i, std::int32_t & j) { i = key & 0xFFFFFFFF; j = key >> 32; }; for (const auto& e2v: E2V) { const std::int64_t key = e2v.first; const std::int32_t v = e2v.second; std::int32_t i,j; key2ij(key,i,j); const std::int64_t key0 = ij2key(i,j); assert(key0 != key); T.row(v) << 0,1; // (i,j) is ordered so that iS(j)) { std::swap(i,j); } GVi.row(v) = GV.row(i); GVj.row(v) = GV.row(j); } const auto root_find_iteration = [&SV,&I,&T,&GVi,&GVj,&batch_implicit]() { Eigen::VectorXd T_mid = (T.col(0)+T.col(1))/2; // Use this midpoint guess for the current visualization SV = GVi.array().colwise() * (1.0 - T_mid.array()) + GVj.array().colwise() * T_mid.array(); // Compute values at midpoints VectorXd S_mid = batch_implicit(SV); // Update bounds T.col(1) = (S_mid.array() > 0).select(T_mid, T.col(1)); T.col(0) = (S_mid.array() <= 0).select(T_mid, T.col(0)); }; cout<bool { switch(key) { default: return false; case ' ': root_find_iteration(); viewer.data().set_vertices(SV); viewer.data().compute_normals(); break; } return true; }; viewer.launch(); }