CSGTree.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 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. #ifndef IGL_BOOLEAN_CSG_TREE_H
  9. #define IGL_BOOLEAN_CSG_TREE_H
  10. #include <igl/boolean/string_to_mesh_boolean_type.h>
  11. #include <igl/boolean/MeshBooleanType.h>
  12. #include <igl/boolean/mesh_boolean.h>
  13. #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
  14. #include <CGAL/number_utils.h>
  15. namespace igl
  16. {
  17. namespace boolean
  18. {
  19. // Class for defining and computing a constructive solid geometry result
  20. // out of a tree of boolean operations on "solid" triangle meshes.
  21. //
  22. //template <typename DerivedF>
  23. class CSGTree
  24. {
  25. private:
  26. typedef CGAL::Epeck::FT ExactScalar;
  27. typedef Eigen::Matrix<ExactScalar,Eigen::Dynamic,3> MatrixX3E;
  28. //typedef Eigen::PlainObjectBase<DerivedF> POBF;
  29. typedef Eigen::MatrixXi POBF;
  30. typedef POBF::Index FIndex;
  31. typedef Eigen::Matrix<FIndex,Eigen::Dynamic,1> VectorJ;
  32. // Resulting mesh
  33. MatrixX3E m_V;
  34. POBF m_F;
  35. VectorJ m_J;
  36. // Number of birth faces in A + those in B. I.e. sum of original "leaf"
  37. // faces involved in result.
  38. size_t m_number_of_birth_faces;
  39. public:
  40. CSGTree()
  41. {
  42. }
  43. //typedef Eigen::MatrixXd MatrixX3E;
  44. //typedef Eigen::MatrixXi POBF;
  45. // http://stackoverflow.com/a/3279550/148668
  46. CSGTree(const CSGTree & other)
  47. :
  48. // copy things
  49. m_V(other.m_V),
  50. // This is an issue if m_F is templated
  51. // https://forum.kde.org/viewtopic.php?f=74&t=128414
  52. m_F(other.m_F),
  53. m_J(other.m_J),
  54. m_number_of_birth_faces(other.m_number_of_birth_faces)
  55. {
  56. }
  57. // copy-swap idiom
  58. friend void swap(CSGTree& first, CSGTree& second)
  59. {
  60. using std::swap;
  61. // swap things
  62. swap(first.m_V,second.m_V);
  63. // This is an issue if m_F is templated, similar to
  64. // https://forum.kde.org/viewtopic.php?f=74&t=128414
  65. swap(first.m_F,second.m_F);
  66. swap(first.m_J,second.m_J);
  67. swap(first.m_number_of_birth_faces,second.m_number_of_birth_faces);
  68. }
  69. // Pass-by-value (aka copy)
  70. CSGTree& operator=(CSGTree other)
  71. {
  72. swap(*this,other);
  73. return *this;
  74. }
  75. CSGTree(CSGTree&& other):
  76. // initialize via default constructor
  77. CSGTree()
  78. {
  79. swap(*this,other);
  80. }
  81. // Construct and compute a boolean operation on existing CSGTree nodes.
  82. //
  83. // Inputs:
  84. // A Solid result of previous CSG operation (or identity, see below)
  85. // B Solid result of previous CSG operation (or identity, see below)
  86. // type type of mesh boolean to compute
  87. CSGTree(
  88. const CSGTree & A,
  89. const CSGTree & B,
  90. const MeshBooleanType & type)
  91. {
  92. // conduct boolean operation
  93. {
  94. Eigen::VectorXi I;
  95. mesh_boolean(A.V(),A.F(),B.V(),B.F(),type,m_V,m_F,m_J,I);
  96. }
  97. // reindex m_J
  98. std::for_each(m_J.data(),m_J.data()+m_J.size(),
  99. [&](typename VectorJ::Scalar & j)
  100. {
  101. if(j < A.F().rows())
  102. {
  103. j = A.J()(j);
  104. }else
  105. {
  106. assert(j<(A.F().rows()+B.F().rows()));
  107. j = A.number_of_birth_faces()+(B.J()(j-A.F().rows()));
  108. }
  109. });
  110. m_number_of_birth_faces =
  111. A.number_of_birth_faces() + B.number_of_birth_faces();
  112. }
  113. // Overload using string for type
  114. CSGTree(
  115. const CSGTree & A,
  116. const CSGTree & B,
  117. const std::string & s):
  118. CSGTree(A,B,string_to_mesh_boolean_type(s))
  119. {
  120. // do nothing (all done in constructor).
  121. }
  122. // "Leaf" node with identity operation on assumed "solid" mesh (V,F)
  123. //
  124. // Inputs:
  125. // V #V by 3 list of mesh vertices (in any precision, will be
  126. // converted to exact)
  127. // F #F by 3 list of mesh face indices into V
  128. template <typename DerivedV>
  129. CSGTree(const Eigen::PlainObjectBase<DerivedV> & V, const POBF & F)//:
  130. // Possible Eigen bug:
  131. // https://forum.kde.org/viewtopic.php?f=74&t=128414
  132. //m_V(V.template cast<ExactScalar>()),m_F(F)
  133. {
  134. m_V = V.template cast<ExactScalar>();
  135. m_F = F;
  136. // number of faces
  137. m_number_of_birth_faces = m_F.rows();
  138. // identity birth index
  139. m_J = VectorJ::LinSpaced(
  140. m_number_of_birth_faces,0,m_number_of_birth_faces-1);
  141. }
  142. // Returns reference to resulting mesh vertices m_V in exact scalar
  143. // representation
  144. const MatrixX3E & V() const
  145. {
  146. return m_V;
  147. }
  148. // Returns mesh vertices in the desired output type, casting when
  149. // appropriate to floating precision.
  150. template <typename DerivedV>
  151. Eigen::PlainObjectBase<DerivedV> cast_V() const
  152. {
  153. Eigen::PlainObjectBase<DerivedV> dV;
  154. dV.resize(m_V.rows(),m_V.cols());
  155. for(int i = 0;i<m_V.size();i++)
  156. {
  157. *(dV.data()+i) = CGAL::to_double((*(m_V.data()+i)));
  158. }
  159. return dV;
  160. }
  161. // Returns reference to resulting mesh faces m_F
  162. const POBF & F() const
  163. {
  164. return m_F;
  165. }
  166. // Returns reference to "birth parents" indices into [F1;F2;...;Fn]
  167. // where F1, ... , Fn are the face lists of the leaf ("original") input
  168. // meshes.
  169. const VectorJ & J() const
  170. {
  171. return m_J;
  172. }
  173. // The number of leaf faces = #F1 + #F2 + ... + #Fn
  174. const size_t & number_of_birth_faces() const
  175. {
  176. return m_number_of_birth_faces;
  177. }
  178. };
  179. }
  180. }
  181. #endif