29 const std::string& bg_position,
31 const std::string& in_position,
32 std::vector<attribute::MeshAttributeHandle>& pass_through,
46 Eigen::MatrixX<int64_t> F;
52 Eigen::MatrixX<int64_t> Fbg;
63 auto [tetmesh, tet_face_on_input_surface] =
69 auto rounding_pt_attribute =
72 std::shared_ptr<Mesh> m_ptr = tetmesh;
74 auto rounding = std::make_shared<wmtk::operations::Rounding>(*m_ptr, rounding_pt_attribute);
75 rounding->add_invariant(
82 "Executed rounding, {} ops (S/F) {}/{}. Time: collecting: {}, sorting: {}, "
84 stats.number_of_performed_operations(),
85 stats.number_of_successful_operations(),
86 stats.number_of_failed_operations(),
87 stats.collecting_time,
89 stats.executing_time);
94 if (track_submeshes) {
97 logger().trace(
"Registering input surface from tag surface");
100 auto surface_accessor = tetmesh->create_accessor<int64_t>(surface_handle);
105 assert(tets.size() == tet_face_on_input_surface.size());
107 logger().info(
"Assigning surface tags");
108 for (int64_t i = 0; i < tets.size(); ++i) {
109 const auto& t = tets[i];
110 std::array<Tuple, 4> fs = {
111 {tetmesh->switch_tuples(t, {
PV,
PE,
PF}),
112 tetmesh->switch_tuples(t, {PE, PF}),
114 tetmesh->switch_tuples(t, {
PF})}};
116 for (int64_t k = 0; k < 4; ++k) {
117 if (tet_face_on_input_surface[i][k]) {
118 surface_accessor.scalar_attribute(fs[k]) = 1;
120 surface_accessor.scalar_attribute(fs[k]) = 0;
125 pass_through.push_back(surface_handle);
130 if (make_child_free) {
131 logger().info(
"Making free child surface mesh");
135 surface_handle.as<int64_t>(),
140 logger().info(
"Making child surface mesh");
144 child_meshes.
surface_mesh = tetmesh->get_child_meshes().back();
151 logger().info(
"Going through open/nonmanifold stuff");
152 auto open_boundary_handle =
154 auto open_boundary_accessor = tetmesh->create_accessor<int64_t>(open_boundary_handle);
156 auto nonmanifold_edge_handle =
158 auto nonmanifold_edge_accessor = tetmesh->create_accessor<int64_t>(nonmanifold_edge_handle);
160 pass_through.push_back(open_boundary_handle);
161 pass_through.push_back(nonmanifold_edge_handle);
164 bool has_openboundary =
false;
165 bool has_nonmanifold_edge =
false;
167 logger().info(
"Looping edges for open/nonmanifold ones");
170 if (!child_meshes.
surface_mesh->is_boundary(surface_edge))
continue;
172 const auto& parent_e = child_meshes.
surface_mesh->map_to_parent(surface_edge);
173 const auto& child_e =
174 tetmesh->map_to_child_tuples(*child_meshes.
surface_mesh, parent_e);
176 assert(child_e.size() > 0);
178 if (child_e.size() == 1) {
181 open_boundary_accessor.scalar_attribute(parent_e.tuple()) = 1;
182 has_openboundary =
true;
185 nonmanifold_edge_accessor.scalar_attribute(parent_e.tuple()) = 1;
186 has_nonmanifold_edge =
true;
190 const bool process_nonmanifold_edges = !make_child_free && has_nonmanifold_edge;
194 if (has_openboundary) {
195 if (make_child_free) {
196 logger().error(
"Creating free open boundary child mesh");
200 open_boundary_handle.as<int64_t>(),
205 logger().error(
"Creating open boundary child mesh");
214 if (process_nonmanifold_edges) {
215 logger().info(
"Creating nonmanifold edge mesh");
225 auto bbox_accessor = tetmesh->create_accessor<int64_t>(bbox_handle);
227 pass_through.push_back(bbox_handle);
229 logger().info(
"Annotating bounding box boundary");
231 bbox_accessor.scalar_attribute(f) =
238 child_meshes.
bbox_mesh = tetmesh->get_child_meshes().back();
244 logger().info(
"Nonmanifold vertices");
245 auto nonmanifold_vertex_handle =
247 auto nonmanifold_vertex_accessor =
248 tetmesh->create_accessor<int64_t>(nonmanifold_vertex_handle);
250 pass_through.push_back(nonmanifold_vertex_handle);
253 int64_t on_open_boundary_cnt = 0;
254 int64_t on_nonmanifold_edge_cnt = 0;
256 if (has_openboundary) {
257 on_open_boundary_cnt = tetmesh
263 if (process_nonmanifold_edges) {
264 on_nonmanifold_edge_cnt = tetmesh
271 if (on_open_boundary_cnt + on_open_boundary_cnt > 1) {
273 nonmanifold_vertex_accessor.scalar_attribute(v) = 1;
276 on_open_boundary_cnt + on_nonmanifold_edge_cnt == 0 &&
277 tetmesh->map_to_child(
281 nonmanifold_vertex_accessor.scalar_attribute(v) = 1;
295 logger().info(
"Propagating position to child meshes");
300 for (
auto child : tetmesh->get_child_meshes()) {
301 auto child_position_handle = child->register_attribute<
Rational>(
304 tetmesh->get_attribute_dimension(pt_attribute.as<
Rational>()));
306 auto propagate_to_child_position =
307 [](
const Eigen::MatrixX<Rational>& P) -> Eigen::VectorX<Rational> {
return P; };
308 auto update_child_positon = std::make_shared<
310 child_position_handle,
312 propagate_to_child_position);
319 "TetMesh created: {} tets, {} faces, {} edges, {} vertices",
325 logger().info(
"Surface child TriMesh registered");
327 if (has_openboundary) {
328 logger().info(
"Open boundary child EdgeMesh registered");
330 if (process_nonmanifold_edges) {
331 logger().info(
"Nonmanifold edge child EdgeMesh registered");
334 logger().info(
"Bbox child TriMesh registered");
337 return std::make_tuple(tetmesh, child_meshes);