Wildmeshing Toolkit
edge_insertion.cpp
Go to the documentation of this file.
1 #include "edge_insertion.hpp"
2 
3 #include <wmtk/EdgeMesh.hpp>
4 #include <wmtk/Mesh.hpp>
5 #include <wmtk/TriMesh.hpp>
8 #include <wmtk/utils/Logger.hpp>
11 
14 
15 #include <fstream>
16 
17 namespace wmtk::components {
18 
19 using namespace internal;
20 
22 {
23  std::vector<Vector2r> v_final;
24  std::vector<std::array<int64_t, 3>> FV_new;
25  std::vector<std::array<int, 3>> local_e_on_input;
26 
27  wmtk::logger().info("start edge insertion ...");
28 
29  edge_insertion(bg_mesh, input_mesh, v_final, FV_new, local_e_on_input);
30 
31  wmtk::logger().info("finished edge insertion");
32 
33  wmtk::logger().info("creating multimesh ...");
34 
37 
38  V.resize(v_final.size(), 2);
39  FV.resize(FV_new.size(), 3);
40 
41  for (int64_t i = 0; i < v_final.size(); ++i) {
42  V.row(i) = v_final[i];
43  }
44 
45  for (int64_t i = 0; i < FV_new.size(); ++i) {
46  FV(i, 0) = FV_new[i][0];
47  FV(i, 1) = FV_new[i][1];
48  FV(i, 2) = FV_new[i][2];
49  }
50 
51  // remove unused vertices
52  std::vector<bool> v_is_used(V.rows(), false);
53  for (int64_t i = 0; i < FV.rows(); ++i) {
54  for (int64_t j = 0; j < 3; ++j) {
55  v_is_used[FV(i, j)] = true;
56  }
57  }
58 
59  std::map<int64_t, int64_t> v_map;
60  int64_t used_cnt = 0;
61  for (auto b : v_is_used) {
62  if (b) {
63  used_cnt++;
64  }
65  }
66 
67  MatrixX<Rational> V_valid;
68  MatrixX<int64_t> FV_valid;
69 
70  V_valid.resize(used_cnt, 2);
71  int64_t valid_row = 0;
72  for (int64_t i = 0; i < V.rows(); ++i) {
73  if (v_is_used[i]) {
74  V_valid.row(valid_row) = V.row(i);
75  v_map[i] = valid_row;
76  valid_row++;
77  }
78  }
79 
80  FV_valid.resize(FV.rows(), 3);
81  for (int64_t i = 0; i < FV.rows(); ++i) {
82  for (int64_t j = 0; j < 3; ++j) {
83  FV_valid(i, j) = v_map[FV(i, j)];
84  }
85  }
86 
87  std::shared_ptr<wmtk::TriMesh> m = std::make_shared<wmtk::TriMesh>();
88  m->initialize(FV_valid);
90 
91  // input child mesh
92  auto input_handle = m->register_attribute<int64_t>("input", PrimitiveType::Edge, 1);
93  auto input_accessor = m->create_accessor<int64_t>(input_handle);
94 
95  const auto& triangles = m->get_all(PrimitiveType::Triangle);
96 
97  for (int64_t i = 0; i < triangles.size(); ++i) {
98  const auto& e01 = triangles[i];
99  const auto& e02 = m->switch_tuple(e01, PrimitiveType::Edge);
100  const auto& e12 = m->switch_tuples(e01, {PrimitiveType::Vertex, PrimitiveType::Edge});
101 
102  input_accessor.scalar_attribute(e01) = local_e_on_input[i][2];
103  input_accessor.scalar_attribute(e02) = local_e_on_input[i][1];
104  input_accessor.scalar_attribute(e12) = local_e_on_input[i][0];
105  }
106 
107  std::shared_ptr<Mesh> inserted_input_mesh;
108 
109  internal::MultiMeshFromTag mmft(*m, input_handle, 1);
111 
112  inserted_input_mesh = m->get_child_meshes().back();
113 
114  mmft.remove_soup();
115 
116  // bbox child mesh
117  auto bbox_handle = m->register_attribute<int64_t>("bbox", PrimitiveType::Edge, 1);
118  auto bbox_accessor = m->create_accessor<int64_t>(bbox_handle);
119 
120  for (const auto& e : m->get_all(PrimitiveType::Edge)) {
121  if (m->is_boundary(PrimitiveType::Edge, e)) {
122  bbox_accessor.scalar_attribute(e) = 1;
123  }
124  }
125 
126  std::shared_ptr<Mesh> bbox_mesh;
127 
128  internal::MultiMeshFromTag mmft2(*m, bbox_handle, 1);
130 
131  bbox_mesh = m->get_child_meshes().back();
132 
133  mmft2.remove_soup();
134 
135  auto pt_attribute = m->get_attribute_handle<Rational>("vertices", PrimitiveType::Vertex);
136 
137  for (auto child : m->get_child_meshes()) {
138  auto child_position_handle = child->register_attribute<Rational>(
139  "vertices",
141  m->get_attribute_dimension(pt_attribute.as<Rational>()));
142 
143  auto propagate_to_child_position =
144  [](const Eigen::MatrixX<Rational>& P) -> Eigen::VectorX<Rational> { return P; };
145  auto update_child_positon =
146  std::make_shared<wmtk::operations::SingleAttributeTransferStrategy<Rational, Rational>>(
147  child_position_handle,
148  pt_attribute,
149  propagate_to_child_position);
150  update_child_positon->run_on_all();
151  }
152 
154  eim.inserted_edge_mesh = inserted_input_mesh;
155  eim.tri_mesh = m;
156  eim.bbox_mesh = bbox_mesh;
157 
158  return eim;
159 }
160 
161 } // namespace wmtk::components
This class generates a multi-mesh from a mesh where the substructure is represented by a tag.
void remove_soup()
Remove the substructure soup from the multimesh.
void compute_substructure_mesh()
Create a manifold mesh from the substructure.
void edge_insertion(TriMesh &_trimesh, EdgeMesh &edgemesh, std::vector< Vector2r > &v_final, std::vector< std::array< int64_t, 3 >> &FV_new, std::vector< std::array< int, 3 >> &local_e_on_input)
attribute::MeshAttributeHandle set_matrix_attribute(const Mat &data, const std::string &name, const PrimitiveType &type, Mesh &mesh)
Definition: mesh_utils.hpp:9
spdlog::logger & logger()
Retrieves the current logger.
Definition: Logger.cpp:58
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Definition: Types.hpp:14
std::shared_ptr< wmtk::Mesh > tri_mesh
std::shared_ptr< wmtk::Mesh > bbox_mesh
std::shared_ptr< wmtk::Mesh > inserted_edge_mesh