trim_with_solid.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 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. #include "trim_with_solid.h"
  9. #include "assign_scalar.h"
  10. #include "intersect_other.h"
  11. #include "point_solid_signed_squared_distance.h"
  12. #include "../../extract_manifold_patches.h"
  13. #include "../../list_to_matrix.h"
  14. #include "../../remove_unreferenced.h"
  15. #include "../../slice_mask.h"
  16. #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
  17. #include <vector>
  18. template <
  19. typename DerivedVA,
  20. typename DerivedFA,
  21. typename DerivedVB,
  22. typename DerivedFB,
  23. typename DerivedV,
  24. typename DerivedF,
  25. typename DerivedD,
  26. typename DerivedJ>
  27. IGL_INLINE void igl::copyleft::cgal::trim_with_solid(
  28. const Eigen::PlainObjectBase<DerivedVA> & VA,
  29. const Eigen::PlainObjectBase<DerivedFA> & FA,
  30. const Eigen::PlainObjectBase<DerivedVB> & VB,
  31. const Eigen::PlainObjectBase<DerivedFB> & FB,
  32. Eigen::PlainObjectBase<DerivedV> & Vd,
  33. Eigen::PlainObjectBase<DerivedF> & F,
  34. Eigen::PlainObjectBase<DerivedD> & D,
  35. Eigen::PlainObjectBase<DerivedJ> & J)
  36. {
  37. // resolve intersections using exact representation
  38. typedef Eigen::Matrix<CGAL::Epeck::FT,Eigen::Dynamic,3> MatrixX3E;
  39. typedef Eigen::Matrix<CGAL::Epeck::FT,Eigen::Dynamic,1> VectorXE;
  40. typedef Eigen::Matrix<CGAL::Epeck::FT,1,3> RowVector3E;
  41. MatrixX3E V;
  42. Eigen::MatrixXi _1;
  43. Eigen::VectorXi _2;
  44. // Intersect A and B meshes and stitch together new faces
  45. igl::copyleft::cgal::intersect_other(
  46. VA,FA,VB,FB,{false,false,true},_1,V,F,J,_2);
  47. // Partition result into manifold patches
  48. Eigen::VectorXi P;
  49. const size_t num_patches = igl::extract_manifold_patches(F,P);
  50. // only keep faces from A
  51. Eigen::Matrix<bool,Eigen::Dynamic,1> A = J.array()< FA.rows();
  52. igl::slice_mask(Eigen::MatrixXi(F),A,1,F);
  53. igl::slice_mask(Eigen::VectorXi(P),A,1,P);
  54. igl::slice_mask(Eigen::VectorXi(J),A,1,J);
  55. // Agregate representative query points for each patch
  56. std::vector<bool> flag(num_patches);
  57. std::vector<std::vector<CGAL::Epeck::FT> > vQ;
  58. Eigen::VectorXi P2Q(num_patches);
  59. for(int f = 0;f<P.rows();f++)
  60. {
  61. const auto p = P(f);
  62. // if not yet processed this patch
  63. if(!flag[p])
  64. {
  65. P2Q(p) = vQ.size();
  66. std::vector<CGAL::Epeck::FT> q = {
  67. (V(F(f,0),0)+ V(F(f,1),0)+ V(F(f,2),0))/3.,
  68. (V(F(f,0),1)+ V(F(f,1),1)+ V(F(f,2),1))/3.,
  69. (V(F(f,0),2)+ V(F(f,1),2)+ V(F(f,2),2))/3.};
  70. vQ.emplace_back(q);
  71. flag[p] = true;
  72. }
  73. }
  74. MatrixX3E Q;
  75. igl::list_to_matrix(vQ,Q);
  76. VectorXE SP;
  77. point_solid_signed_squared_distance(Q,VB,FB,SP);
  78. Eigen::Matrix<bool,Eigen::Dynamic,1> DP = SP.array()>0;
  79. // distribute flag to all faces
  80. D.resize(F.rows());
  81. for(int f = 0;f<F.rows();f++)
  82. {
  83. D(f) = DP(P2Q(P(f)));
  84. }
  85. Eigen::VectorXi _;
  86. igl::remove_unreferenced(MatrixX3E(V),DerivedF(F),V,F,_);
  87. const auto & assign = [](
  88. const MatrixX3E & V,
  89. Eigen::PlainObjectBase<DerivedV> & Vd)
  90. {
  91. Vd.resize(V.rows(),3);
  92. for(int v = 0;v<V.rows();v++)
  93. {
  94. for(int d = 0;d<3;d++)
  95. {
  96. igl::copyleft::cgal::assign_scalar(V(v,d),Vd(v,d));
  97. }
  98. }
  99. };
  100. assign(V,Vd);
  101. }