BinaryWindingNumberOperations.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 Qingnan Zhou <[email protected]>
  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. //
  9. #ifndef IGL_COPYLEFT_CGAL_BINARY_WINDING_NUMBER_OPERATIONS_H
  10. #define IGL_COPYLEFT_CGAL_BINARY_WINDING_NUMBER_OPERATIONS_H
  11. #include <stdexcept>
  12. #include "../../igl_inline.h"
  13. #include "../../MeshBooleanType.h"
  14. #include <Eigen/Core>
  15. // TODO: This is not written according to libigl style. These should be
  16. // function handles.
  17. //
  18. // Why is this templated on DerivedW
  19. //
  20. // These are all generalized to n-ary operations
  21. namespace igl
  22. {
  23. namespace copyleft
  24. {
  25. namespace cgal
  26. {
  27. /// Binary winding number operations
  28. template <igl::MeshBooleanType Op>
  29. class BinaryWindingNumberOperations {
  30. public:
  31. template<typename DerivedW>
  32. typename DerivedW::Scalar operator()(
  33. const Eigen::MatrixBase<DerivedW>& /*win_nums*/) const {
  34. throw (std::runtime_error("not implemented!"));
  35. }
  36. };
  37. /// A ∪ B ∪ ... ∪ Z
  38. template <>
  39. class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_UNION> {
  40. public:
  41. template<typename DerivedW>
  42. typename DerivedW::Scalar operator()(
  43. const Eigen::MatrixBase<DerivedW>& win_nums) const
  44. {
  45. for(int i = 0;i<win_nums.size();i++)
  46. {
  47. if(win_nums(i) > 0) return true;
  48. }
  49. return false;
  50. }
  51. };
  52. /// A ∩ B ∩ ... ∩ Z
  53. template <>
  54. class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_INTERSECT> {
  55. public:
  56. template<typename DerivedW>
  57. typename DerivedW::Scalar operator()(
  58. const Eigen::MatrixBase<DerivedW>& win_nums) const
  59. {
  60. for(int i = 0;i<win_nums.size();i++)
  61. {
  62. if(win_nums(i)<=0) return false;
  63. }
  64. return true;
  65. }
  66. };
  67. /// A \ B \ ... \ Z = A \ (B ∪ ... ∪ Z)
  68. template <>
  69. class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_MINUS> {
  70. public:
  71. template<typename DerivedW>
  72. typename DerivedW::Scalar operator()(
  73. const Eigen::MatrixBase<DerivedW>& win_nums) const
  74. {
  75. assert(win_nums.size()>1);
  76. // Union of objects 1 through n-1
  77. bool union_rest = false;
  78. for(int i = 1;i<win_nums.size();i++)
  79. {
  80. union_rest = union_rest || win_nums(i) > 0;
  81. if(union_rest) break;
  82. }
  83. // Must be in object 0 and not in union of objects 1 through n-1
  84. return win_nums(0) > 0 && !union_rest;
  85. }
  86. };
  87. /// A ∆ B ∆ ... ∆ Z (equivalent to set inside odd number of objects)
  88. template <>
  89. class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_XOR> {
  90. public:
  91. template<typename DerivedW>
  92. typename DerivedW::Scalar operator()(
  93. const Eigen::MatrixBase<DerivedW>& win_nums) const
  94. {
  95. // If inside an odd number of objects
  96. int count = 0;
  97. for(int i = 0;i<win_nums.size();i++)
  98. {
  99. if(win_nums(i) > 0) count++;
  100. }
  101. return count % 2 == 1;
  102. }
  103. };
  104. /// Resolve all intersections without removing non-coplanar faces
  105. template <>
  106. class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_RESOLVE> {
  107. public:
  108. template<typename DerivedW>
  109. typename DerivedW::Scalar operator()(
  110. const Eigen::MatrixBase<DerivedW>& /*win_nums*/) const {
  111. return true;
  112. }
  113. };
  114. typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_UNION> BinaryUnion;
  115. typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_INTERSECT> BinaryIntersect;
  116. typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_MINUS> BinaryMinus;
  117. typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_XOR> BinaryXor;
  118. typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_RESOLVE> BinaryResolve;
  119. /// Types of Keep policies
  120. enum KeeperType {
  121. /// Keep only inside
  122. KEEP_INSIDE,
  123. /// Keep everything
  124. KEEP_ALL
  125. };
  126. /// Filter winding numbers according to keep policy
  127. template<KeeperType T>
  128. class WindingNumberFilter {
  129. public:
  130. template<typename DerivedW>
  131. short operator()(
  132. const Eigen::MatrixBase<DerivedW>& /*win_nums*/) const {
  133. throw std::runtime_error("Not implemented");
  134. }
  135. };
  136. /// Keep inside policy
  137. template<>
  138. class WindingNumberFilter<KEEP_INSIDE> {
  139. public:
  140. template<typename T>
  141. short operator()(T out_w, T in_w) const {
  142. if (in_w > 0 && out_w <= 0) return 1;
  143. else if (in_w <= 0 && out_w > 0) return -1;
  144. else return 0;
  145. }
  146. };
  147. /// Keep all policy
  148. template<>
  149. class WindingNumberFilter<KEEP_ALL> {
  150. public:
  151. template<typename T>
  152. short operator()(T /*out_w*/, T /*in_w*/) const {
  153. return 1;
  154. }
  155. };
  156. using KeepInside = WindingNumberFilter<KEEP_INSIDE>;
  157. using KeepAll = WindingNumberFilter<KEEP_ALL>;
  158. }
  159. }
  160. }
  161. #endif