trim_with_solid.cpp 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 Alec Jacobson <[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. #include "trim_with_solid.h"
  9. #include "assign.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. MatrixX3E V;
  41. Eigen::MatrixXi _1;
  42. Eigen::VectorXi _2;
  43. // Intersect A and B meshes and stitch together new faces
  44. igl::copyleft::cgal::intersect_other(
  45. VA,FA,VB,FB,{false,false,true},_1,V,F,J,_2);
  46. // Partition result into manifold patches
  47. Eigen::VectorXi P;
  48. const size_t num_patches = igl::extract_manifold_patches(F,P);
  49. // only keep faces from A
  50. Eigen::Matrix<bool,Eigen::Dynamic,1> A = J.array()< FA.rows();
  51. igl::slice_mask(Eigen::MatrixXi(F),A,1,F);
  52. igl::slice_mask(Eigen::VectorXi(P),A,1,P);
  53. igl::slice_mask(Eigen::VectorXi(J),A,1,J);
  54. // Aggregate representative query points for each patch
  55. std::vector<bool> flag(num_patches);
  56. std::vector<std::vector<CGAL::Epeck::FT> > vQ;
  57. Eigen::VectorXi P2Q(num_patches);
  58. for(int f = 0;f<P.rows();f++)
  59. {
  60. const auto p = P(f);
  61. // if not yet processed this patch
  62. if(!flag[p])
  63. {
  64. P2Q(p) = vQ.size();
  65. std::vector<CGAL::Epeck::FT> q = {
  66. (V(F(f,0),0)+ V(F(f,1),0)+ V(F(f,2),0))/3.,
  67. (V(F(f,0),1)+ V(F(f,1),1)+ V(F(f,2),1))/3.,
  68. (V(F(f,0),2)+ V(F(f,1),2)+ V(F(f,2),2))/3.};
  69. vQ.emplace_back(q);
  70. flag[p] = true;
  71. }
  72. }
  73. MatrixX3E Q;
  74. igl::list_to_matrix(vQ,Q);
  75. VectorXE SP;
  76. point_solid_signed_squared_distance(Q,VB,FB,SP);
  77. Eigen::Matrix<bool,Eigen::Dynamic,1> DP = SP.array()>0;
  78. // distribute flag to all faces
  79. D.resize(F.rows());
  80. for(int f = 0;f<F.rows();f++)
  81. {
  82. D(f) = DP(P2Q(P(f)));
  83. }
  84. Eigen::VectorXi _;
  85. igl::remove_unreferenced(MatrixX3E(V),DerivedF(F),V,F,_);
  86. assign(V,Vd);
  87. }
  88. #ifdef IGL_STATIC_LIBRARY
  89. // Explicit template instantiation
  90. template void igl::copyleft::cgal::trim_with_solid<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  91. #endif