Wildmeshing Toolkit
ProjectOperation.cpp
Go to the documentation of this file.
1 #include "ProjectOperation.hpp"
2 
3 #include <wmtk/Mesh.hpp>
5 
6 #include <SimpleBVH/BVH.hpp>
7 
9 
11  std::shared_ptr<Operation> main_op,
12  const attribute::MeshAttributeHandle& project_to_mesh,
13  attribute::MeshAttributeHandle& child_mesh_coordinates)
14  : ProjectOperation(main_op, {std::make_pair(project_to_mesh, child_mesh_coordinates)})
15 {}
16 
17 
19  std::shared_ptr<Operation> main_op,
20  const std::vector<MeshConstrainPair>& mesh_constaint_pairs)
21  : AttributesUpdate(main_op->mesh())
22  , m_main_op(main_op)
23 {
24  for (auto& pair : mesh_constaint_pairs) {
25  int64_t count = 0;
26  int64_t index = 0;
27 
28  const std::vector<Tuple>& facest =
29  pair.first.mesh().get_all(pair.first.mesh().top_simplex_type());
30 
31  const int64_t dim = int64_t(pair.first.mesh().top_simplex_type()) + 1;
32 
33  Eigen::MatrixXd vertices(dim * facest.size(), pair.first.dimension());
34  Eigen::MatrixXi faces(facest.size(), dim);
35 
36  // hugly copy paste
37  if (pair.first.holds<double>()) {
38  const attribute::Accessor<double> accessor =
39  pair.first.mesh().create_const_accessor(pair.first.as<double>());
40 
41  for (const auto& f : facest) {
43  pair.first.mesh(),
44  simplex::Simplex(pair.first.mesh(), pair.first.mesh().top_simplex_type(), f),
46 
47  assert(tmp.size() == dim);
48  for (int64_t j = 0; j < tmp.size(); ++j) {
49  auto p = accessor.const_vector_attribute(tmp[j]);
50  faces(index, j) = count;
51  vertices.row(dim * index + j) = p;
52 
53  ++count;
54  }
55  ++index;
56  }
57  } else {
58  const attribute::Accessor<Rational> accessor =
59  pair.first.mesh().create_const_accessor(pair.first.as<Rational>());
60 
61 
62  for (const auto& f : facest) {
64  pair.first.mesh(),
65  simplex::Simplex(pair.first.mesh(), pair.first.mesh().top_simplex_type(), f),
67 
68  assert(tmp.size() == dim);
69  for (int64_t j = 0; j < tmp.size(); ++j) {
70  auto p = accessor.const_vector_attribute(tmp[j]).cast<double>();
71  faces(index, j) = count;
72  vertices.row(dim * index + j) = p;
73 
74  ++count;
75  }
76  ++index;
77  }
78  }
79 
80  auto bvh = std::make_shared<SimpleBVH::BVH>();
81  bvh->init(vertices, faces, 1e-10);
82 
83  m_bvh.emplace_back(pair.second, bvh);
84  }
85 }
86 
87 std::vector<simplex::Simplex> ProjectOperation::execute(const simplex::Simplex& simplex)
88 {
89  // mesh has to be the same as the main_op mesh
90  assert(&m_main_op->mesh() == &mesh());
91  const auto main_simplices = (*m_main_op)(simplex);
92  if (main_simplices.empty()) return {};
93  assert(main_simplices.size() == 1);
94  const auto main_tup = main_simplices.front().tuple();
95 
96 
97  for (auto& pair : m_bvh) {
98  const std::vector<Tuple> mapped_tuples_after =
99  mesh().map_tuples(pair.first.mesh(), primitive_type(), {main_tup});
100 
101  if (mapped_tuples_after.empty()) continue;
102 
103  if (pair.first.holds<double>()) {
105  pair.first.mesh().create_accessor(pair.first.as<double>());
106 
107  for (const auto& t : mapped_tuples_after) {
108  auto p = accessor.vector_attribute(t);
109  SimpleBVH::VectorMax3d nearest_point;
110  double sq_dist;
111  pair.second->nearest_facet(p, nearest_point, sq_dist);
112  p = nearest_point;
113  }
114  } else {
115  assert((pair.first.holds<Rational>()));
117  pair.first.mesh().create_accessor(pair.first.as<Rational>());
118 
119  for (const auto& t : mapped_tuples_after) {
120  auto p_map = accessor.vector_attribute(t);
121 
122  if (p_map.rows() == 3) {
123  const Eigen::Vector3d p = p_map.cast<double>();
124  SimpleBVH::VectorMax3d nearest_point;
125  double sq_dist;
126  pair.second->nearest_facet(p, nearest_point, sq_dist);
127  for (int64_t d = 0; d < pair.first.dimension(); ++d) {
128  p_map(d) = Rational(nearest_point[d], true);
129  }
130  } else if (p_map.rows() == 2) {
131  const Eigen::Vector2d p = p_map.cast<double>();
132  SimpleBVH::VectorMax3d nearest_point;
133  double sq_dist;
134  pair.second->nearest_facet(p, nearest_point, sq_dist);
135  for (int64_t d = 0; d < pair.first.dimension(); ++d) {
136  p_map(d) = Rational(nearest_point[d], true);
137  }
138  } else {
139  throw std::runtime_error("wrong vector dimension");
140  }
141  }
142  }
143  }
144 
145  return main_simplices;
146 }
147 
148 } // namespace wmtk::operations::composite
std::vector< Tuple > get_all(PrimitiveType type) const
Generate a vector of Tuples from global vertex/edge/triangle/tetrahedron index.
Definition: Mesh.cpp:18
std::vector< Tuple > map_tuples(const Mesh &other_mesh, const simplex::Simplex &my_simplex) const
maps a simplex from this mesh to any other mesh
A CachingAccessor that uses tuples for accessing attributes instead of indices.
Definition: Accessor.hpp:25
MapResult< D > vector_attribute(const ArgType &t)
ConstMapResult< D > const_vector_attribute(const ArgType &t) const
const Mesh & mesh() const
Definition: Operation.hpp:45
ProjectOperation(std::shared_ptr< Operation > main_op, const attribute::MeshAttributeHandle &project_to_mesh, attribute::MeshAttributeHandle &child_mesh_coordinates)
PrimitiveType primitive_type() const override
const std::shared_ptr< wmtk::operations::Operation > m_main_op
std::vector< simplex::Simplex > execute(const simplex::Simplex &simplex) override
returns an empty vector in case of failure
std::vector< Tuple > vertices(const Mesh &m, const Simplex &simplex)
std::vector< Tuple > faces_single_dimension_tuples(const Mesh &mesh, const Simplex &simplex, const PrimitiveType face_type)
SimplexCollection faces(const Mesh &mesh, const Simplex &simplex, const bool sort_and_clean)
Returns all faces of a simplex.
Definition: faces.cpp:10
Vector< double, 3 > Vector3d
Definition: Types.hpp:39