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);
void serialize(MeshWriter &writer, const Mesh *local_root=nullptr) const
SchedulerStats run_operation_on_all(operations::Operation &op)
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.
std::shared_ptr< Mesh > nonmanifold_edge_mesh
std::shared_ptr< Mesh > surface_mesh
std::shared_ptr< Mesh > open_boundary_mesh
std::shared_ptr< Mesh > bbox_mesh
static Simplex edge(const Mesh &m, const Tuple &t)
static Simplex vertex(const Mesh &m, const Tuple &t)
void get_TV_matrix(MatrixX< int64_t > &matrix)
void get_FV_matrix(MatrixX< int64_t > &matrix)
void get_double_matrix(const std::string &name, const PrimitiveType type, MatrixX< double > &matrix)
constexpr wmtk::PrimitiveType PT
constexpr wmtk::PrimitiveType PF
std::tuple< std::shared_ptr< wmtk::TetMesh >, ChildMeshes > triangle_insertion(const TetMesh &bg_mesh, const std::string &bg_position, const TriMesh &mesh_in, const std::string &in_position, std::vector< attribute::MeshAttributeHandle > &pass_through, bool round, bool track_submeshes, bool make_child_free)
std::shared_ptr< Mesh > extract_and_register_child_mesh_from_tag_handle(Mesh &m, const wmtk::attribute::TypedAttributeHandle< int64_t > &tag_handle, const int64_t tag_value, bool child_is_free)
extract a child mesh based on the tag handle and the tag value, and register it to the input (parent)...
std::tuple< std::shared_ptr< wmtk::TetMesh >, std::vector< std::array< bool, 4 > > > generate_raw_tetmesh_from_input_surface(const RowVectors3d &V, const RowVectors3l &F, const RowVectors3d &background_V, const RowVectors4l &background_TV)
input a triangle surface mesh, embed it into a background tet mesh, track the input surfaces on the t...
constexpr PrimitiveType PV
spdlog::logger & logger()
Retrieves the current logger.
constexpr PrimitiveType PE