mesh_with_skeleton.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "mesh_with_skeleton.h"
  9. #include <igl/sample_edges.h>
  10. #include <igl/cat.h>
  11. #include <igl/tetgen/tetrahedralize.h>
  12. #include <igl/writeOFF.h>
  13. #include <igl/writeOBJ.h>
  14. #include <iostream>
  15. // Default settings pq2Y tell tetgen to mesh interior of triangle mesh and
  16. // to produce a graded tet mesh
  17. const static std::string DEFAULT_TETGEN_FLAGS = "pq2Y";
  18. IGL_INLINE bool igl::mesh_with_skeleton(
  19. const Eigen::MatrixXd & V,
  20. const Eigen::MatrixXi & F,
  21. const Eigen::MatrixXd & C,
  22. const Eigen::VectorXi & /*P*/,
  23. const Eigen::MatrixXi & BE,
  24. const Eigen::MatrixXi & CE,
  25. const int samples_per_bone,
  26. const std::string & tetgen_flags,
  27. Eigen::MatrixXd & VV,
  28. Eigen::MatrixXi & TT,
  29. Eigen::MatrixXi & FF)
  30. {
  31. using namespace Eigen;
  32. using namespace igl;
  33. using namespace std;
  34. const string eff_tetgen_flags =
  35. (tetgen_flags.length() == 0?DEFAULT_TETGEN_FLAGS:tetgen_flags);
  36. // Collect all edges that need samples:
  37. MatrixXi BECE = cat(1,BE,CE);
  38. MatrixXd S;
  39. // Sample each edge with 10 samples. (Choice of 10 doesn't seem to matter so
  40. // much, but could under some circumstances)
  41. sample_edges(C,BECE,samples_per_bone,S);
  42. // Vertices we'll constrain tet mesh to meet
  43. MatrixXd VS = cat(1,V,S);
  44. // Use tetgen to mesh the interior of surface, this assumes surface:
  45. // * has no holes
  46. // * has no non-manifold edges or vertices
  47. // * has consistent orientation
  48. // * has no self-intersections
  49. // * has no 0-volume pieces
  50. writeOBJ("mesh_with_skeleton.obj",VS,F);
  51. cerr<<"tetgen begin()"<<endl;
  52. int status = tetrahedralize( VS,F,eff_tetgen_flags,VV,TT,FF);
  53. cerr<<"tetgen end()"<<endl;
  54. if(FF.rows() != F.rows())
  55. {
  56. // Issue a warning if the surface has changed
  57. cerr<<"mesh_with_skeleton: Warning: boundary faces != input faces"<<endl;
  58. }
  59. if(status != 0)
  60. {
  61. cerr<<
  62. "***************************************************************"<<endl<<
  63. "***************************************************************"<<endl<<
  64. "***************************************************************"<<endl<<
  65. "***************************************************************"<<endl<<
  66. "* mesh_with_skeleton: tetgen failed. Just meshing convex hull *"<<endl<<
  67. "***************************************************************"<<endl<<
  68. "***************************************************************"<<endl<<
  69. "***************************************************************"<<endl<<
  70. "***************************************************************"<<endl;
  71. // If meshing convex hull then use more regular mesh
  72. status = tetrahedralize(VS,F,"q1.414",VV,TT,FF);
  73. // I suppose this will fail if the skeleton is outside the mesh
  74. assert(FF.maxCoeff() < VV.rows());
  75. if(status != 0)
  76. {
  77. cerr<<"mesh_with_skeleton: tetgen failed again."<<endl;
  78. return false;
  79. }
  80. }
  81. return true;
  82. }
  83. IGL_INLINE bool igl::mesh_with_skeleton(
  84. const Eigen::MatrixXd & V,
  85. const Eigen::MatrixXi & F,
  86. const Eigen::MatrixXd & C,
  87. const Eigen::VectorXi & P,
  88. const Eigen::MatrixXi & BE,
  89. const Eigen::MatrixXi & CE,
  90. const int samples_per_bone,
  91. Eigen::MatrixXd & VV,
  92. Eigen::MatrixXi & TT,
  93. Eigen::MatrixXi & FF)
  94. {
  95. return igl::mesh_with_skeleton(
  96. V,F,C,P,BE,CE,samples_per_bone,DEFAULT_TETGEN_FLAGS,VV,TT,FF);
  97. }
  98. #ifdef IGL_STATIC_LIBRARY
  99. // Explicit template instanciation
  100. #endif