intersection_blocking_collapse_edge_callbacks.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include <test_common.h>
  2. #include <igl/intersection_blocking_collapse_edge_callbacks.h>
  3. #include <igl/edge_flaps.h>
  4. #include <igl/decimate_callback_types.h>
  5. #include <igl/AABB.h>
  6. #include <igl/collapse_edge.h>
  7. #include <igl/min_heap.h>
  8. #include <tuple>
  9. TEST_CASE("intersection_blocking_collapse_edge_callbacks: simple", "[igl]")
  10. {
  11. // A mesh where collapsing edge e1 will create a self-intersection and
  12. // collapsed e2 will not
  13. Eigen::MatrixXd V(21,3);
  14. V<<
  15. 0,20,0,
  16. 0,30,0,
  17. 10,10,0,
  18. 10,20,-30,
  19. 10,30,0,
  20. 20,0,0,
  21. 20,10,30,
  22. 20,20,0,
  23. 30,0,0,
  24. 30,10,0,
  25. 10,17,-15,
  26. 7,23,15,
  27. 13,23,15,
  28. 10,30,30,
  29. 20,30,0,
  30. 0,10,3,
  31. 20,5,15,
  32. 25,0,0,
  33. 25,5,15,
  34. 25,10,15,
  35. 30,5,0;
  36. Eigen::MatrixXi F(22,3);
  37. F<<
  38. 5,17,16,
  39. 8,20,18,
  40. 8,18,17,
  41. 9,19,20,
  42. 6,16,18,
  43. 6,18,19,
  44. 18,16,17,
  45. 19,18,20,
  46. 2,5,16,
  47. 7,6,19,
  48. 2,16,6,
  49. 7,19,9,
  50. 2,3,0,
  51. 0,3,1,
  52. 3,4,1,
  53. 2,6,3,
  54. 6,7,3,
  55. 3,7,4,
  56. 10,11,12,
  57. 12,11,13,
  58. 4,7,14,
  59. 2,0,15;
  60. igl::AABB<Eigen::MatrixXd, 3> * tree = new igl::AABB<Eigen::MatrixXd, 3>();
  61. tree->init(V,F);
  62. igl::decimate_pre_collapse_callback pre_collapse;
  63. igl::decimate_post_collapse_callback post_collapse;
  64. igl::intersection_blocking_collapse_edge_callbacks(
  65. tree,
  66. pre_collapse,
  67. post_collapse);
  68. Eigen::VectorXi EMAP;
  69. Eigen::MatrixXi E,EF,EI;
  70. igl::edge_flaps(F,E,EMAP,EF,EI);
  71. igl::min_heap< std::tuple<double,int,int> > Q;
  72. Eigen::VectorXi EQ;
  73. Eigen::MatrixXd C = Eigen::MatrixXd::Zero(E.rows(),3);
  74. // Try to do the collapses.
  75. std::vector<int> edges_to_collapse;
  76. for(const auto edge : {Eigen::RowVector2i(3,6),Eigen::RowVector2i(6,18)})
  77. {
  78. int e = -1;
  79. const bool found =
  80. ( (E.array().col(0)==edge[0] && E.array().col(1)==edge[1])||
  81. (E.array().col(0)==edge[1] && E.array().col(1)==edge[0])).maxCoeff(&e);
  82. REQUIRE(found);
  83. edges_to_collapse.push_back(e);
  84. }
  85. std::vector<bool> should_collapse = {false,true};
  86. for(int i=0;i<edges_to_collapse.size();i++)
  87. {
  88. const auto e = edges_to_collapse[i];
  89. bool collapsed = true;
  90. int e1,e2,f1,f2;
  91. // pre_collapse only has access to C not p
  92. C.row(e) = 0.5*(V.row(E(e,0))+V.row(E(e,1)));
  93. if(pre_collapse(V,F,E,EMAP,EF,EI,Q,EQ,C,e))
  94. {
  95. collapsed = igl::collapse_edge(
  96. e,C.row(e).eval(),
  97. /*Nsv,Nsf,Ndv,Ndf,*/
  98. V,F,E,EMAP,EF,EI,e1,e2,f1,f2);
  99. }else
  100. {
  101. // Aborted by pre collapse callback
  102. collapsed = false;
  103. }
  104. REQUIRE(collapsed == should_collapse[i]);
  105. post_collapse(V,F,E,EMAP,EF,EI,Q,EQ,C,e,e1,e2,f1,f2,collapsed);
  106. }
  107. {
  108. auto * root = tree->root();
  109. const auto leaves = tree->gather_leaves();
  110. for(int f = 0;f<F.rows();f++)
  111. {
  112. if((F.row(f).array() == IGL_COLLAPSE_EDGE_NULL).all())
  113. {
  114. continue;
  115. }
  116. REQUIRE(f < leaves.size());
  117. auto * leaf = leaves[f];
  118. REQUIRE(root == leaf->root());
  119. // check containment all the way up to
  120. auto * node = leaf;
  121. while(node)
  122. {
  123. REQUIRE(node->m_box.contains(V.row(F(f,0)).transpose()));
  124. REQUIRE(node->m_box.contains(V.row(F(f,1)).transpose()));
  125. REQUIRE(node->m_box.contains(V.row(F(f,2)).transpose()));
  126. auto * parent = node->m_parent;
  127. if(parent)
  128. {
  129. REQUIRE(parent->m_box.contains(node->m_box));
  130. }
  131. node = parent;
  132. }
  133. }
  134. }
  135. tree = tree->root();
  136. delete tree;
  137. }