collapse_edge.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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_COLLAPSE_EDGE_H
  9. #define IGL_COLLAPSE_EDGE_H
  10. #include "igl_inline.h"
  11. #include <Eigen/Core>
  12. #include <vector>
  13. #include <set>
  14. namespace igl
  15. {
  16. // Assumes (V,F) is a closed manifold mesh (except for previously collapsed
  17. // faces which should be set to:
  18. // [IGL_COLLAPSE_EDGE_NULL IGL_COLLAPSE_EDGE_NULL IGL_COLLAPSE_EDGE_NULL].
  19. // Collapses exactly two faces and exactly 3 edges from E (e and one side of
  20. // each face gets collapsed to the other). This is implemented in a way that
  21. // it can be repeatedly called until satisfaction and then the garbage in F
  22. // can be collected by removing NULL faces.
  23. //
  24. // Inputs:
  25. // e index into E of edge to try to collapse. E(e,:) = [s d] or [d s] so
  26. // that s<d, then d is collapsed to s.
  27. /// p dim list of vertex position where to place merged vertex
  28. // Inputs/Outputs:
  29. // V #V by dim list of vertex positions, lesser index of E(e,:) will be set
  30. // to midpoint of edge.
  31. // F #F by 3 list of face indices into V.
  32. // E #E by 2 list of edge indices into V.
  33. // EMAP #F*3 list of indices into E, mapping each directed edge to unique
  34. // unique edge in E
  35. // EF #E by 2 list of edge flaps, EF(e,0)=f means e=(i-->j) is the edge of
  36. // F(f,:) opposite the vth corner, where EI(e,0)=v. Similarly EF(e,1) "
  37. // e=(j->i)
  38. // EI #E by 2 list of edge flap corners (see above).
  39. // e1 index into E of edge collpased on left
  40. // e2 index into E of edge collpased on right
  41. // f1 index into F of face collpased on left
  42. // f2 index into F of face collpased on right
  43. // Returns true if edge was collapsed
  44. #define IGL_COLLAPSE_EDGE_NULL 0
  45. IGL_INLINE bool collapse_edge(
  46. const int e,
  47. const Eigen::RowVectorXd & p,
  48. Eigen::MatrixXd & V,
  49. Eigen::MatrixXi & F,
  50. Eigen::MatrixXi & E,
  51. Eigen::VectorXi & EMAP,
  52. Eigen::MatrixXi & EF,
  53. Eigen::MatrixXi & EI,
  54. int & e1,
  55. int & e2,
  56. int & f1,
  57. int & f2);
  58. IGL_INLINE bool collapse_edge(
  59. const int e,
  60. const Eigen::RowVectorXd & p,
  61. Eigen::MatrixXd & V,
  62. Eigen::MatrixXi & F,
  63. Eigen::MatrixXi & E,
  64. Eigen::VectorXi & EMAP,
  65. Eigen::MatrixXi & EF,
  66. Eigen::MatrixXi & EI);
  67. // Collapse least-cost edge from a priority queue and update queue
  68. //
  69. // Inputs/Outputs:
  70. // cost_and_placement function computing cost of collapsing an edge and 3d
  71. // position where it should be placed:
  72. // cost_and_placement(V,F,E,EMAP,EF,EI,cost,placement);
  73. // **If the edges is collapsed** then this function will be called on all
  74. // edges of all faces previously incident on the endpoints of the
  75. // collapsed edge.
  76. // Q queue containing pairs of costs and edge indices
  77. // Qit list of iterators so that Qit[e] --> iterator of edge e in Q
  78. // C #E by dim list of stored placements
  79. IGL_INLINE bool collapse_edge(
  80. const std::function<void(
  81. const int,
  82. const Eigen::MatrixXd &,
  83. const Eigen::MatrixXi &,
  84. const Eigen::MatrixXi &,
  85. const Eigen::VectorXi &,
  86. const Eigen::MatrixXi &,
  87. const Eigen::MatrixXi &,
  88. double &,
  89. Eigen::RowVectorXd &)> & cost_and_placement,
  90. Eigen::MatrixXd & V,
  91. Eigen::MatrixXi & F,
  92. Eigen::MatrixXi & E,
  93. Eigen::VectorXi & EMAP,
  94. Eigen::MatrixXi & EF,
  95. Eigen::MatrixXi & EI,
  96. std::set<std::pair<double,int> > & Q,
  97. std::vector<std::set<std::pair<double,int> >::iterator > & Qit,
  98. Eigen::MatrixXd & C);
  99. // Inputs:
  100. // pre_collapse callback called with index of edge whose collapse is about
  101. // to be attempted. This function should return whether to **proceed**
  102. // with the collapse: returning true means "yes, try to collapse",
  103. // returning false means "No, consider this edge 'uncollapsable', behave
  104. // as if collapse_edge(e) returned false.
  105. // post_collapse callback called with index of edge whose collapse was
  106. // just attempted and a flag revealing whether this was successful.
  107. IGL_INLINE bool collapse_edge(
  108. const std::function<void(
  109. const int,
  110. const Eigen::MatrixXd &,
  111. const Eigen::MatrixXi &,
  112. const Eigen::MatrixXi &,
  113. const Eigen::VectorXi &,
  114. const Eigen::MatrixXi &,
  115. const Eigen::MatrixXi &,
  116. double &,
  117. Eigen::RowVectorXd &)> & cost_and_placement,
  118. const std::function<bool(
  119. const Eigen::MatrixXd & ,/*V*/
  120. const Eigen::MatrixXi & ,/*F*/
  121. const Eigen::MatrixXi & ,/*E*/
  122. const Eigen::VectorXi & ,/*EMAP*/
  123. const Eigen::MatrixXi & ,/*EF*/
  124. const Eigen::MatrixXi & ,/*EI*/
  125. const std::set<std::pair<double,int> > & ,/*Q*/
  126. const std::vector<std::set<std::pair<double,int> >::iterator > &,/*Qit*/
  127. const Eigen::MatrixXd & ,/*C*/
  128. const int /*e*/
  129. )> & pre_collapse,
  130. const std::function<void(
  131. const Eigen::MatrixXd & , /*V*/
  132. const Eigen::MatrixXi & , /*F*/
  133. const Eigen::MatrixXi & , /*E*/
  134. const Eigen::VectorXi & ,/*EMAP*/
  135. const Eigen::MatrixXi & , /*EF*/
  136. const Eigen::MatrixXi & , /*EI*/
  137. const std::set<std::pair<double,int> > & , /*Q*/
  138. const std::vector<std::set<std::pair<double,int> >::iterator > &, /*Qit*/
  139. const Eigen::MatrixXd & , /*C*/
  140. const int , /*e*/
  141. const int , /*e1*/
  142. const int , /*e2*/
  143. const int , /*f1*/
  144. const int , /*f2*/
  145. const bool /*collapsed*/
  146. )> & post_collapse,
  147. Eigen::MatrixXd & V,
  148. Eigen::MatrixXi & F,
  149. Eigen::MatrixXi & E,
  150. Eigen::VectorXi & EMAP,
  151. Eigen::MatrixXi & EF,
  152. Eigen::MatrixXi & EI,
  153. std::set<std::pair<double,int> > & Q,
  154. std::vector<std::set<std::pair<double,int> >::iterator > & Qit,
  155. Eigen::MatrixXd & C);
  156. IGL_INLINE bool collapse_edge(
  157. const std::function<void(
  158. const int,
  159. const Eigen::MatrixXd &,
  160. const Eigen::MatrixXi &,
  161. const Eigen::MatrixXi &,
  162. const Eigen::VectorXi &,
  163. const Eigen::MatrixXi &,
  164. const Eigen::MatrixXi &,
  165. double &,
  166. Eigen::RowVectorXd &)> & cost_and_placement,
  167. const std::function<bool(
  168. const Eigen::MatrixXd & ,/*V*/
  169. const Eigen::MatrixXi & ,/*F*/
  170. const Eigen::MatrixXi & ,/*E*/
  171. const Eigen::VectorXi & ,/*EMAP*/
  172. const Eigen::MatrixXi & ,/*EF*/
  173. const Eigen::MatrixXi & ,/*EI*/
  174. const std::set<std::pair<double,int> > & ,/*Q*/
  175. const std::vector<std::set<std::pair<double,int> >::iterator > &,/*Qit*/
  176. const Eigen::MatrixXd & ,/*C*/
  177. const int /*e*/
  178. )> & pre_collapse,
  179. const std::function<void(
  180. const Eigen::MatrixXd & , /*V*/
  181. const Eigen::MatrixXi & , /*F*/
  182. const Eigen::MatrixXi & , /*E*/
  183. const Eigen::VectorXi & ,/*EMAP*/
  184. const Eigen::MatrixXi & , /*EF*/
  185. const Eigen::MatrixXi & , /*EI*/
  186. const std::set<std::pair<double,int> > & , /*Q*/
  187. const std::vector<std::set<std::pair<double,int> >::iterator > &, /*Qit*/
  188. const Eigen::MatrixXd & , /*C*/
  189. const int , /*e*/
  190. const int , /*e1*/
  191. const int , /*e2*/
  192. const int , /*f1*/
  193. const int , /*f2*/
  194. const bool /*collapsed*/
  195. )> & post_collapse,
  196. Eigen::MatrixXd & V,
  197. Eigen::MatrixXi & F,
  198. Eigen::MatrixXi & E,
  199. Eigen::VectorXi & EMAP,
  200. Eigen::MatrixXi & EF,
  201. Eigen::MatrixXi & EI,
  202. std::set<std::pair<double,int> > & Q,
  203. std::vector<std::set<std::pair<double,int> >::iterator > & Qit,
  204. Eigen::MatrixXd & C,
  205. int & e,
  206. int & e1,
  207. int & e2,
  208. int & f1,
  209. int & f2);
  210. }
  211. #ifndef IGL_STATIC_LIBRARY
  212. # include "collapse_edge.cpp"
  213. #endif
  214. #endif