BinaryWindingNumberOperations.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 Qingnan Zhou <qnzhou@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. //
  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. template <igl::MeshBooleanType Op>
  28. class BinaryWindingNumberOperations {
  29. public:
  30. template<typename DerivedW>
  31. typename DerivedW::Scalar operator()(
  32. const Eigen::PlainObjectBase<DerivedW>& /*win_nums*/) const {
  33. throw (std::runtime_error("not implemented!"));
  34. }
  35. };
  36. // A ∪ B ∪ ... ∪ Z
  37. template <>
  38. class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_UNION> {
  39. public:
  40. template<typename DerivedW>
  41. typename DerivedW::Scalar operator()(
  42. const Eigen::PlainObjectBase<DerivedW>& win_nums) const
  43. {
  44. for(int i = 0;i<win_nums.size();i++)
  45. {
  46. if(win_nums(i) > 0) return true;
  47. }
  48. return false;
  49. }
  50. };
  51. // A ∩ B ∩ ... ∩ Z
  52. template <>
  53. class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_INTERSECT> {
  54. public:
  55. template<typename DerivedW>
  56. typename DerivedW::Scalar operator()(
  57. const Eigen::PlainObjectBase<DerivedW>& win_nums) const
  58. {
  59. for(int i = 0;i<win_nums.size();i++)
  60. {
  61. if(win_nums(i)<=0) return false;
  62. }
  63. return true;
  64. }
  65. };
  66. // A \ B \ ... \ Z = A \ (B ∪ ... ∪ Z)
  67. template <>
  68. class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_MINUS> {
  69. public:
  70. template<typename DerivedW>
  71. typename DerivedW::Scalar operator()(
  72. const Eigen::PlainObjectBase<DerivedW>& win_nums) const
  73. {
  74. assert(win_nums.size()>1);
  75. // Union of objects 1 through n-1
  76. bool union_rest = false;
  77. for(int i = 1;i<win_nums.size();i++)
  78. {
  79. union_rest = union_rest || win_nums(i) > 0;
  80. if(union_rest) break;
  81. }
  82. // Must be in object 0 and not in union of objects 1 through n-1
  83. return win_nums(0) > 0 && !union_rest;
  84. }
  85. };
  86. // A ∆ B ∆ ... ∆ Z (equivalent to set inside odd number of objects)
  87. template <>
  88. class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_XOR> {
  89. public:
  90. template<typename DerivedW>
  91. typename DerivedW::Scalar operator()(
  92. const Eigen::PlainObjectBase<DerivedW>& win_nums) const
  93. {
  94. // If inside an odd number of objects
  95. int count = 0;
  96. for(int i = 0;i<win_nums.size();i++)
  97. {
  98. if(win_nums(i) > 0) count++;
  99. }
  100. return count % 2 == 1;
  101. }
  102. };
  103. template <>
  104. class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_RESOLVE> {
  105. public:
  106. template<typename DerivedW>
  107. typename DerivedW::Scalar operator()(
  108. const Eigen::PlainObjectBase<DerivedW>& /*win_nums*/) const {
  109. return true;
  110. }
  111. };
  112. typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_UNION> BinaryUnion;
  113. typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_INTERSECT> BinaryIntersect;
  114. typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_MINUS> BinaryMinus;
  115. typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_XOR> BinaryXor;
  116. typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_RESOLVE> BinaryResolve;
  117. enum KeeperType {
  118. KEEP_INSIDE,
  119. KEEP_ALL
  120. };
  121. template<KeeperType T>
  122. class WindingNumberFilter {
  123. public:
  124. template<typename DerivedW>
  125. short operator()(
  126. const Eigen::PlainObjectBase<DerivedW>& /*win_nums*/) const {
  127. throw std::runtime_error("Not implemented");
  128. }
  129. };
  130. template<>
  131. class WindingNumberFilter<KEEP_INSIDE> {
  132. public:
  133. template<typename T>
  134. short operator()(T out_w, T in_w) const {
  135. if (in_w > 0 && out_w <= 0) return 1;
  136. else if (in_w <= 0 && out_w > 0) return -1;
  137. else return 0;
  138. }
  139. };
  140. template<>
  141. class WindingNumberFilter<KEEP_ALL> {
  142. public:
  143. template<typename T>
  144. short operator()(T /*out_w*/, T /*in_w*/) const {
  145. return 1;
  146. }
  147. };
  148. typedef WindingNumberFilter<KEEP_INSIDE> KeepInside;
  149. typedef WindingNumberFilter<KEEP_ALL> KeepAll;
  150. }
  151. }
  152. }
  153. #endif