mesh_with_skeleton.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include "mesh_with_skeleton.h"
  2. #include <igl/sample_edges.h>
  3. #include <igl/cat.h>
  4. #include <igl/tetgen/tetrahedralize.h>
  5. #include <igl/writeOFF.h>
  6. #include <iostream>
  7. // Default settings pq2Y tell tetgen to mesh interior of triangle mesh and
  8. // to produce a graded tet mesh
  9. const static std::string DEFAULT_TETGEN_FLAGS = "pq2Y";
  10. bool igl::mesh_with_skeleton(
  11. const Eigen::MatrixXd & V,
  12. const Eigen::MatrixXi & F,
  13. const Eigen::MatrixXd & C,
  14. const Eigen::VectorXi & /*P*/,
  15. const Eigen::MatrixXi & BE,
  16. const Eigen::MatrixXi & CE,
  17. const int samples_per_bone,
  18. const std::string & tetgen_flags,
  19. Eigen::MatrixXd & VV,
  20. Eigen::MatrixXi & TT,
  21. Eigen::MatrixXi & FF)
  22. {
  23. using namespace Eigen;
  24. using namespace igl;
  25. using namespace std;
  26. const string eff_tetgen_flags =
  27. (tetgen_flags.length() == 0?DEFAULT_TETGEN_FLAGS:tetgen_flags);
  28. // Collect all edges that need samples:
  29. MatrixXi BECE = cat(1,BE,CE);
  30. MatrixXd S;
  31. // Sample each edge with 10 samples. (Choice of 10 doesn't seem to matter so
  32. // much, but could under some circumstances)
  33. sample_edges(C,BECE,samples_per_bone,S);
  34. // Vertices we'll constrain tet mesh to meet
  35. MatrixXd VS = cat(1,V,S);
  36. // Boundary faces
  37. MatrixXi BF;
  38. // Use tetgen to mesh the interior of surface, this assumes surface:
  39. // * has no holes
  40. // * has no non-manifold edges or vertices
  41. // * has consistent orientation
  42. // * has no self-intersections
  43. // * has no 0-volume pieces
  44. //writeOFF("mesh_with_skeleton.off",VS,F);
  45. cerr<<"tetgen begin()"<<endl;
  46. int status = tetrahedralize( VS,F,eff_tetgen_flags,VV,TT,FF);
  47. cerr<<"tetgen end()"<<endl;
  48. if(FF.rows() != F.rows())
  49. {
  50. // Issue a warning if the surface has changed
  51. cerr<<"mesh_with_skeleton: Warning: boundary faces != input faces"<<endl;
  52. }
  53. if(status != 0)
  54. {
  55. cerr<<
  56. "***************************************************************"<<endl<<
  57. "***************************************************************"<<endl<<
  58. "***************************************************************"<<endl<<
  59. "***************************************************************"<<endl<<
  60. "* mesh_with_skeleton: tetgen failed. Just meshing convex hull *"<<endl<<
  61. "***************************************************************"<<endl<<
  62. "***************************************************************"<<endl<<
  63. "***************************************************************"<<endl<<
  64. "***************************************************************"<<endl;
  65. // If meshing convex hull then use more regular mesh
  66. status = tetrahedralize(VS,F,"q1.414",VV,TT,FF);
  67. // I suppose this will fail if the skeleton is outside the mesh
  68. assert(FF.maxCoeff() < VV.rows());
  69. if(status != 0)
  70. {
  71. cerr<<"mesh_with_skeleton: tetgen failed again."<<endl;
  72. return false;
  73. }
  74. }
  75. return true;
  76. }
  77. bool igl::mesh_with_skeleton(
  78. const Eigen::MatrixXd & V,
  79. const Eigen::MatrixXi & F,
  80. const Eigen::MatrixXd & C,
  81. const Eigen::VectorXi & P,
  82. const Eigen::MatrixXi & BE,
  83. const Eigen::MatrixXi & CE,
  84. const int samples_per_bone,
  85. Eigen::MatrixXd & VV,
  86. Eigen::MatrixXi & TT,
  87. Eigen::MatrixXi & FF)
  88. {
  89. return igl::mesh_with_skeleton(
  90. V,F,C,P,BE,CE,samples_per_bone,DEFAULT_TETGEN_FLAGS,VV,TT,FF);
  91. }