triangulate.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@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 "triangulate.h"
  9. #ifdef ANSI_DECLARATORS
  10. # define IGL_PREVIOUSLY_DEFINED_ANSI_DECLARATORS ANSI_DECLARATORS
  11. # undef ANSI_DECLARATORS
  12. #endif
  13. #ifdef REAL
  14. # define IGL_PREVIOUSLY_DEFINED_REAL REAL
  15. # undef REAL
  16. #endif
  17. #ifdef VOID
  18. # define IGL_PREVIOUSLY_DEFINED_VOID VOID
  19. # undef VOID
  20. #endif
  21. #define ANSI_DECLARATORS
  22. #define REAL double
  23. #define VOID int
  24. extern "C"
  25. {
  26. #include <triangle.h>
  27. }
  28. #undef ANSI_DECLARATORS
  29. #ifdef IGL_PREVIOUSLY_DEFINED_ANSI_DECLARATORS
  30. # define ANSI_DECLARATORS IGL_PREVIOUSLY_DEFINED_ANSI_DECLARATORS
  31. #endif
  32. #undef REAL
  33. #ifdef IGL_PREVIOUSLY_DEFINED_REAL
  34. # define REAL IGL_PREVIOUSLY_DEFINED_REAL
  35. #endif
  36. #undef VOID
  37. #ifdef IGL_PREVIOUSLY_DEFINED_VOID
  38. # define VOID IGL_PREVIOUSLY_DEFINED_VOID
  39. #endif
  40. template <
  41. typename DerivedV,
  42. typename DerivedE,
  43. typename DerivedH,
  44. typename DerivedV2,
  45. typename DerivedF2>
  46. IGL_INLINE void igl::triangle::triangulate(
  47. const Eigen::MatrixBase<DerivedV> & V,
  48. const Eigen::MatrixBase<DerivedE> & E,
  49. const Eigen::MatrixBase<DerivedH> & H,
  50. const std::string flags,
  51. Eigen::PlainObjectBase<DerivedV2> & V2,
  52. Eigen::PlainObjectBase<DerivedF2> & F2)
  53. {
  54. Eigen::VectorXi VM,EM,VM2,EM2;
  55. return triangulate(V,E,H,VM,EM,flags,V2,F2,VM2,EM2);
  56. }
  57. template <
  58. typename DerivedV,
  59. typename DerivedE,
  60. typename DerivedH,
  61. typename DerivedVM,
  62. typename DerivedEM,
  63. typename DerivedV2,
  64. typename DerivedF2,
  65. typename DerivedVM2,
  66. typename DerivedEM2>
  67. IGL_INLINE void igl::triangle::triangulate(
  68. const Eigen::MatrixBase<DerivedV> & V,
  69. const Eigen::MatrixBase<DerivedE> & E,
  70. const Eigen::MatrixBase<DerivedH> & H,
  71. const Eigen::MatrixBase<DerivedVM> & VM,
  72. const Eigen::MatrixBase<DerivedEM> & EM,
  73. const std::string flags,
  74. Eigen::PlainObjectBase<DerivedV2> & V2,
  75. Eigen::PlainObjectBase<DerivedF2> & F2,
  76. Eigen::PlainObjectBase<DerivedVM2> & VM2,
  77. Eigen::PlainObjectBase<DerivedEM2> & EM2)
  78. {
  79. using namespace std;
  80. using namespace Eigen;
  81. assert( (VM.size() == 0 || V.rows() == VM.size()) &&
  82. "Vertex markers must be empty or same size as V");
  83. assert( (EM.size() == 0 || E.rows() == EM.size()) &&
  84. "Segment markers must be empty or same size as E");
  85. assert(V.cols() == 2);
  86. assert(E.size() == 0 || E.cols() == 2);
  87. assert(H.size() == 0 || H.cols() == 2);
  88. // Prepare the flags
  89. string full_flags = flags + "pz" + (EM.size() || VM.size() ? "" : "B");
  90. typedef Map< Matrix<double,Dynamic,Dynamic,RowMajor> > MapXdr;
  91. typedef Map< Matrix<int,Dynamic,Dynamic,RowMajor> > MapXir;
  92. // Prepare the input struct
  93. triangulateio in;
  94. in.numberofpoints = V.rows();
  95. in.pointlist = (double*)calloc(V.size(),sizeof(double));
  96. {
  97. MapXdr inpl(in.pointlist,V.rows(),V.cols());
  98. inpl = V.template cast<double>();
  99. }
  100. in.numberofpointattributes = 0;
  101. in.pointmarkerlist = (int*)calloc(V.size(),sizeof(int)) ;
  102. for(unsigned i=0;i<V.rows();++i) in.pointmarkerlist[i] = VM.size()?VM(i):1;
  103. in.trianglelist = NULL;
  104. in.numberoftriangles = 0;
  105. in.numberofcorners = 0;
  106. in.numberoftriangleattributes = 0;
  107. in.triangleattributelist = NULL;
  108. in.numberofsegments = E.size()?E.rows():0;
  109. in.segmentlist = (int*)calloc(E.size(),sizeof(int));
  110. {
  111. MapXir insl(in.segmentlist,E.rows(),E.cols());
  112. insl = E.template cast<int>();
  113. }
  114. in.segmentmarkerlist = (int*)calloc(E.rows(),sizeof(int));
  115. for (unsigned i=0;i<E.rows();++i) in.segmentmarkerlist[i] = EM.size()?EM(i):1;
  116. in.numberofholes = H.size()?H.rows():0;
  117. in.holelist = (double*)calloc(H.size(),sizeof(double));
  118. {
  119. MapXdr inhl(in.holelist,H.rows(),H.cols());
  120. inhl = H.template cast<double>();
  121. }
  122. in.numberofregions = 0;
  123. // Prepare the output struct
  124. triangulateio out;
  125. out.pointlist = NULL;
  126. out.trianglelist = NULL;
  127. out.segmentlist = NULL;
  128. out.segmentmarkerlist = NULL;
  129. out.pointmarkerlist = NULL;
  130. // Call triangle
  131. ::triangulate(const_cast<char*>(full_flags.c_str()), &in, &out, 0);
  132. // Return the mesh
  133. V2 = MapXdr(out.pointlist,out.numberofpoints,2).cast<typename DerivedV2::Scalar>();
  134. F2 = MapXir(out.trianglelist,out.numberoftriangles,3).cast<typename DerivedF2::Scalar>();
  135. if(VM.size())
  136. {
  137. VM2 = MapXir(out.pointmarkerlist,out.numberofpoints,1).cast<typename DerivedVM2::Scalar>();
  138. }
  139. if(EM.size())
  140. {
  141. EM2 = MapXir(out.segmentmarkerlist,out.numberofsegments,1).cast<typename DerivedEM2::Scalar>();
  142. }
  143. // Cleanup in
  144. free(in.pointlist);
  145. free(in.pointmarkerlist);
  146. free(in.segmentlist);
  147. free(in.segmentmarkerlist);
  148. free(in.holelist);
  149. // Cleanup out
  150. free(out.pointlist);
  151. free(out.trianglelist);
  152. free(out.segmentlist);
  153. free(out.segmentmarkerlist);
  154. free(out.pointmarkerlist);
  155. }
  156. #ifdef IGL_STATIC_LIBRARY
  157. // Explicit template instantiation
  158. // generated by autoexplicit.sh
  159. template void igl::triangle::triangulate<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  160. // generated by autoexplicit.sh
  161. template void igl::triangle::triangulate<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  162. #endif