Wildmeshing Toolkit
Loading...
Searching...
No Matches
ProjectOperation.cpp
Go to the documentation of this file.
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) {
42 auto tmp = faces_single_dimension_tuples(
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) {
63 auto tmp = faces_single_dimension_tuples(
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
87std::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:28
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