main.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include <igl/opengl/glfw/Viewer.h>
  2. #include <igl/get_seconds.h>
  3. #include <igl/find.h>
  4. #include <igl/readDMAT.h>
  5. #include <igl/writeDMAT.h>
  6. #include <igl/triangulated_grid.h>
  7. #include <igl/cubic.h>
  8. #include <igl/cycodebase/box_cubic.h>
  9. #include <igl/cycodebase/point_spline_squared_distance.h>
  10. #include <igl/cycodebase/spline_eytzinger_aabb.h>
  11. #include <igl/predicates/spline_winding_number.h>
  12. int main(int argc, char * argv[])
  13. {
  14. IGL_TICTOC_LAMBDA;
  15. Eigen::MatrixXd P;
  16. Eigen::MatrixXi C;
  17. igl::readDMAT(argc>1?argv[1]: TUTORIAL_SHARED_PATH "/libigl-cursive-P.dmat",P);
  18. igl::readDMAT(argc>1?argv[2]: TUTORIAL_SHARED_PATH "/libigl-cursive-C.dmat",C);
  19. // Cheezy conversion of (P,C) to polyline using 50 samples per curve
  20. const int ns = 50;
  21. Eigen::MatrixXd V(ns*C.rows(),P.cols());
  22. Eigen::MatrixXi E((ns-1)*C.rows(),2);
  23. for(int c = 0;c<C.rows();c++)
  24. {
  25. for(int i = 0;i<ns;i++)
  26. {
  27. const double t = double(i)/(ns-1);
  28. // Evaluate cubic Bezier at parameter t
  29. Eigen::RowVectorXd Vct;
  30. igl::cubic(P(C.row(c),Eigen::all),t,Vct);
  31. V.row(c*ns + i) = Vct;
  32. if(i>0)
  33. {
  34. E.row(c*(ns-1) + (i-1))<< c*ns + (i-1), c*ns + i;
  35. }
  36. }
  37. }
  38. Eigen::MatrixXd GV;
  39. Eigen::MatrixXi GF;
  40. {
  41. Eigen::RowVector2d min_corner = P.colwise().minCoeff();
  42. Eigen::RowVector2d max_corner = P.colwise().maxCoeff();
  43. // samples on x-axis
  44. const int sx = 512;
  45. const int sy = sx * (max_corner(1)-min_corner(1)) / (max_corner(0)-min_corner(0));
  46. Eigen::RowVector2d diag = (max_corner - min_corner).eval();
  47. const double bbd = diag.norm();
  48. diag /= diag.norm();
  49. min_corner -= 0.1*bbd*diag;
  50. max_corner += 0.1*bbd*diag;
  51. igl::triangulated_grid(sx,sy,GV,GF);
  52. // Scale and translate grid to fit bounding box
  53. GV.col(0) = (GV.col(0).array() * (max_corner(0)-min_corner(0))) + min_corner(0);
  54. GV.col(1) = (GV.col(1).array() * (max_corner(1)-min_corner(1))) + min_corner(1);
  55. }
  56. Eigen::VectorXd sqrD,S;
  57. Eigen::VectorXi I;
  58. Eigen::MatrixXd K;
  59. Eigen::VectorXd W;
  60. Eigen::Matrix<double,Eigen::Dynamic,2,Eigen::RowMajor> B1,B2;
  61. Eigen::VectorXi leaf;
  62. tictoc();
  63. igl::cycodebase::spline_eytzinger_aabb(P, C, B1, B2,leaf);
  64. printf("AABB build time: %g secs\n",tictoc());
  65. igl::writeDMAT("P.dmat", Eigen::MatrixXd(P));
  66. igl::writeDMAT("C.dmat", Eigen::MatrixXi(C));
  67. igl::writeDMAT("B1.dmat",Eigen::MatrixXd(B1));
  68. igl::writeDMAT("B2.dmat",Eigen::MatrixXd(B2));
  69. {
  70. tictoc();
  71. igl::cycodebase::point_spline_squared_distance(
  72. GV, P, C, B1,B2,leaf, sqrD, I, S, K);
  73. printf("sqrD: %d points in %g secs\n",GV.rows(),tictoc());
  74. tictoc();
  75. igl::predicates::spline_winding_number(P,C,B1,B2,leaf,GV,W);
  76. printf("Wind: %d points in %g secs\n",GV.rows(),tictoc());
  77. }
  78. Eigen::VectorXd unsigned_D = sqrD.array().sqrt();
  79. Eigen::VectorXd signed_D = unsigned_D.array() * (0.5 - W.array().abs()) * 2.0;
  80. // Just leaves
  81. //Eigen::MatrixXd B1,B2;
  82. //igl::cycodebase::box_cubic(P,C,B1,B2);
  83. const auto nonempty = igl::find((leaf.array() != -2).eval());
  84. const int nb = nonempty.size();
  85. Eigen::MatrixXd BV(nb*4,2);
  86. BV<<
  87. B1(nonempty,0), B1(nonempty,1),
  88. B1(nonempty,0), B2(nonempty,1),
  89. B2(nonempty,0), B2(nonempty,1),
  90. B2(nonempty,0), B1(nonempty,1);
  91. Eigen::MatrixXi BE(nb*4,2);
  92. for(int c = 0;c<nb;c++)
  93. {
  94. BE.row(c*4 + 0)<< 0*nb + c, 1*nb + c;
  95. BE.row(c*4 + 1)<< 1*nb + c, 2*nb + c;
  96. BE.row(c*4 + 2)<< 2*nb + c, 3*nb + c;
  97. BE.row(c*4 + 3)<< 3*nb + c, 0*nb + c;
  98. }
  99. igl::opengl::glfw::Viewer vr;
  100. vr.data().set_mesh(GV,GF);
  101. vr.data().show_lines = false;
  102. const int g_index = vr.selected_data_index;
  103. vr.append_mesh();
  104. vr.data().set_mesh(V,E(Eigen::all,{0,1,1}).eval());
  105. vr.data().set_points(P,Eigen::RowVector3d(1,0.7,0.2));
  106. Eigen::MatrixXi CE(C.rows()*2,2);
  107. CE<< C(Eigen::all,{0,1}),
  108. C(Eigen::all,{2,3});
  109. vr.data().set_edges(P,CE,Eigen::RowVector3d(1,0.7,0.2));
  110. vr.data().point_size = 10;
  111. vr.append_mesh();
  112. vr.data().set_edges(BV,BE,Eigen::RowVector3d(0,0,0));
  113. enum Quantity
  114. {
  115. SIGNED_DISTANCE,
  116. UNSIGNED_DISTANCE,
  117. WINDING_NUMBER
  118. } quantity = SIGNED_DISTANCE;
  119. const auto update = [&]()
  120. {
  121. vr.core().lighting_factor = 0;
  122. const double dmax = unsigned_D.maxCoeff();
  123. const double dmin = -dmax;
  124. vr.data_list[g_index].show_texture = false;
  125. switch(quantity)
  126. {
  127. case SIGNED_DISTANCE:
  128. vr.data_list[g_index].set_data(signed_D,dmin,dmax,igl::COLOR_MAP_TYPE_ZOE,32);
  129. break;
  130. case UNSIGNED_DISTANCE:
  131. vr.data_list[g_index].set_data(unsigned_D,dmin,dmax,igl::COLOR_MAP_TYPE_ZOE,32);
  132. break;
  133. case WINDING_NUMBER:
  134. {
  135. vr.data_list[g_index].set_data(W,W.minCoeff(),W.maxCoeff(),igl::COLOR_MAP_TYPE_TURBO,std::round(W.maxCoeff()-W.minCoeff())+1);
  136. break;
  137. }
  138. }
  139. };
  140. update();
  141. vr.callback_key_pressed = [&](igl::opengl::glfw::Viewer &, unsigned int key, int mod)->bool
  142. {
  143. switch(key)
  144. {
  145. default:
  146. return false;
  147. case 'W':
  148. case 'w':
  149. quantity = WINDING_NUMBER;
  150. break;
  151. case 'U':
  152. case 'u':
  153. quantity = UNSIGNED_DISTANCE;
  154. break;
  155. case 'S':
  156. case 's':
  157. quantity = SIGNED_DISTANCE;
  158. break;
  159. }
  160. update();
  161. return true;
  162. };
  163. std::cout<<R"(
  164. S,s Signed distance
  165. W,w Winding number
  166. U,u Unsigned distance
  167. N,n Toggle naive / accelerated
  168. )"<<std::endl;
  169. vr.launch();
  170. return 0;
  171. }