Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component extract_subset #426

Draft
wants to merge 72 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
3aa11fb
create dummy component extract subset&CMakeLists
ahighmoon Sep 28, 2023
3921e20
finish 2d extract subset by convert old vectices id to new
ahighmoon Oct 12, 2023
1be4189
correct extract_subset_2d interface w/o implementation
ahighmoon Oct 19, 2023
dcf2723
failed attempt to add fv/vf accessors
ahighmoon Oct 19, 2023
5504abb
change argument to MeshAttributeHandle, w/ one linking error in test …
ahighmoon Nov 5, 2023
476bb22
Merge branch 'main' into dzint/component_extract_subset
ahighmoon Nov 9, 2023
472a219
finish a version of ds adaption w/ linking error from external
ahighmoon Nov 9, 2023
06e9114
fix linking error and remove all unnecessary comments
ahighmoon Nov 10, 2023
3203b4c
change test case to 2d tet and change argument of extract_subset to r…
ahighmoon Nov 10, 2023
b6c5f36
fix internal bug and pass all tag tests on 2d tet
ahighmoon Nov 12, 2023
de1533e
add comments and another geometric config for test
ahighmoon Nov 12, 2023
db6d98c
init the topology algo, compiles and links fine
ahighmoon Nov 16, 2023
d299091
finish 1st version of topo algo, compiles, bdry function to be implem…
ahighmoon Nov 18, 2023
886909a
remove unnecessary bdry determine func, add manual test case of 3+4
ahighmoon Nov 18, 2023
b4b4d7f
fixing calcing cc using dfs recursion
ahighmoon Nov 19, 2023
da5b811
finish finding vertex copies and ready for reconstruct mesh
ahighmoon Nov 28, 2023
9faab15
finish mesh reconstruction
ahighmoon Nov 28, 2023
407b2b5
change helper functions to inline in the header, some performance mod…
ahighmoon Nov 28, 2023
183fabc
move utils functions back to cpp file
ahighmoon Nov 29, 2023
1fc1002
init the test validness & manifold functions
ahighmoon Nov 29, 2023
24c5142
test manifold conditions per vertex
ahighmoon Nov 29, 2023
c24e525
finish manifold test func on the return mesh
ahighmoon Nov 29, 2023
152cb95
refactor, extract get_connection into another func
ahighmoon Nov 29, 2023
7f7fa10
2d tet doesn't satisfy the manifold function, remove it from test cases
ahighmoon Nov 29, 2023
efc311e
remove print
ahighmoon Nov 29, 2023
b0fd76a
add random test based on delaunay2d, from previous manifold-extractio…
ahighmoon Nov 30, 2023
b39e35f
format
ahighmoon Nov 30, 2023
1a1a7b5
init the files for 3d topo algp dev
ahighmoon Dec 1, 2023
7a30eb7
refactor and remove some auto
ahighmoon Dec 1, 2023
822c722
fixing all autos
ahighmoon Dec 1, 2023
5d55b33
add some comments to internal algo
ahighmoon Dec 1, 2023
65ca4eb
move some util functions in topo_2d to utils so other files could use…
ahighmoon Dec 1, 2023
09ac3a4
change some code in extract_subset_2d to new defined util funcs
ahighmoon Dec 1, 2023
1471fed
generalize util functions to fit trimesh and tetmesh, linking error
ahighmoon Dec 1, 2023
7a946dd
add more templates, still linking error
ahighmoon Dec 1, 2023
3f2744e
change vertex_on_bdry function to existing implement, code runs fine …
ahighmoon Dec 6, 2023
2d8d2f6
move all util functions to utils so other files could use, runs fine
ahighmoon Dec 6, 2023
55f22c6
change some code in extract_subset_2d to new defined util funcs and f…
ahighmoon Dec 6, 2023
34d00a4
finish extract_subset_3d without error
ahighmoon Dec 6, 2023
2603077
Merge branch 'dzint/component_extract_subset' of https://github.com/w…
ahighmoon Dec 6, 2023
2da433c
fix all errors and redundency
ahighmoon Dec 6, 2023
a23f82f
fix minor bug, prev commit message is wrong
ahighmoon Dec 6, 2023
777cd32
save temp work in step 2 of topo_separate_3d
ahighmoon Dec 6, 2023
bcfd83e
copy & adapt the 2d case to 3d. question: to create dup edge on ident…
ahighmoon Dec 6, 2023
cb53ea9
finish topo_3d algo, extremely messy but should be correct
ahighmoon Dec 7, 2023
fdd4b5b
init the 3d_manifold test function
ahighmoon Dec 7, 2023
73cfe5e
refactor the function signature to handle 2d and 3d all at once
ahighmoon Dec 20, 2023
c08131c
[NOT proven correct] add first version of is_disk and is_sphere funct…
ahighmoon Dec 21, 2023
961cc25
remove redundant dimension argument, fix wrong use of m.capacity()
ahighmoon Feb 5, 2024
ad34515
move prev to attic & implement algo in new_topo_separate & create du…
ahighmoon Feb 7, 2024
1d757f1
save work, attempt to combine 2 functions into new_topo_sep
ahighmoon Feb 7, 2024
d3f23a4
add initial check for only processing tagged top simplices
ahighmoon Feb 7, 2024
5d89c64
finish new_topo_sep middle part, did experiments with top_dimension_c…
ahighmoon Feb 7, 2024
931b10c
finish reconstruction part
ahighmoon Feb 7, 2024
3afccbe
remove files unneed
ahighmoon Feb 7, 2024
2c56235
restore utils.cpp temporarily, seg fault
ahighmoon Feb 7, 2024
29327cd
restore the gen_submesh file since they are actually needed
ahighmoon Feb 8, 2024
ed177b2
[Save work] algo ok, but compile/linking error
ahighmoon Feb 11, 2024
be76d8b
finish the extract_submesh task without considering positions, everyt…
ahighmoon Feb 11, 2024
f8ecc61
Add coordinates preserving section
ahighmoon Feb 11, 2024
be2b55a
Move submesh functionality back to its own file; Note: because it is …
ahighmoon Feb 11, 2024
6cb1ed2
finish main algorithm, test on 3+4 test case and passes all 4 asserti…
ahighmoon Feb 11, 2024
92445ac
add coordinates preserving logic to topo_sep function
ahighmoon Feb 11, 2024
e656a30
remove unused accessor argument of topo_sep
ahighmoon Feb 11, 2024
4a8c362
minor changes
ahighmoon Feb 11, 2024
106aca6
[Save Temp work] in the middle of adjusting generate_submesh function…
ahighmoon Feb 11, 2024
bdcdfc1
finish generate_submesh, test passes on 3+4 2D case without coordinates
ahighmoon Feb 12, 2024
0b8e485
[Save Temp Work] restored some test cases in the test file, now 2_non…
ahighmoon Feb 12, 2024
6cfce0b
fix bug! in topo_sep func, should ALWAYS access and change the vertex…
ahighmoon Feb 12, 2024
3b5353c
restore the test case of 6_cycle_tets in 3D, passed it; remove unneed…
ahighmoon Feb 12, 2024
63e9562
change the way to determine planar graph : in calc euler char, add 1 …
ahighmoon Feb 12, 2024
5a7757b
add 3D random test case, now reports error for every mesh with more t…
ahighmoon Feb 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions components/wmtk_components/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ add_subdirectory(input)
add_subdirectory(isotropic_remeshing)
add_subdirectory(mesh_info)
add_subdirectory(output)
add_subdirectory(extract_subset)
add_subdirectory(regular_space)
19 changes: 19 additions & 0 deletions components/wmtk_components/extract_subset/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
set(SRC_FILES
#internal/extract_subset_2d.hpp
#internal/extract_subset_2d.cpp
#internal/topology_separate_2d.cpp
#internal/topology_separate_2d.hpp
#internal/extract_subset_3d.hpp
#internal/extract_subset_3d.cpp
#internal/topology_separate_3d.cpp
#internal/topology_separate_3d.hpp
internal/utils.hpp
internal/utils.cpp
internal/generate_submesh.cpp
internal/generate_submesh.hpp
internal/new_topology_separate.cpp
internal/new_topology_separate.hpp
extract_subset.hpp
extract_subset.cpp
)
target_sources(wildmeshing_components PRIVATE ${SRC_FILES})
44 changes: 44 additions & 0 deletions components/wmtk_components/extract_subset/extract_subset.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "extract_subset.hpp"
namespace wmtk {
namespace components {

Eigen::VectorX<long>& vector2tag(Eigen::VectorX<long>& ret, std::vector<int> vector)
{
ret.resize(vector.size());
for (int i = 0; i < vector.size(); ++i) ret.row(i) << vector[i];
return ret;
}

std::unique_ptr<wmtk::Mesh> extract_subset(wmtk::Mesh& m, const std::vector<int>& tag_vec, bool pos)
{
wmtk::PrimitiveType topType = m.top_simplex_type();
// tag vector must have the same size as the number of simplices in the mesh
assert(tag_vec.size() == m.get_all(topType).size());
if (pos) { // if user asks to preserve geometry, then geometry must be provided
try {
m.get_attribute_handle<double>("position", wmtk::PrimitiveType::Vertex);
} catch (const std::exception& e) {
throw std::runtime_error("input mesh doesn't have position attributes!");
}
}

Eigen::VectorX<long> tag;
wmtk::MeshAttributeHandle<long> tag_handle =
wmtk::mesh_utils::set_matrix_attribute(vector2tag(tag, tag_vec), "tag", topType, m);

std::unique_ptr<wmtk::Mesh> submesh; // Declare the submesh variable here
switch (m.top_cell_dimension()) {
case 2:
case 3:
submesh = internal::generate_submesh(
m,
tag_handle,
pos); // Assign the value inside the switch statement
// return submesh;
return internal::topology_separate(*(submesh.get()), pos);
default: throw std::runtime_error("Invalid mesh dimension in extracting subset!");
}
}

} // namespace components
} // namespace wmtk
17 changes: 17 additions & 0 deletions components/wmtk_components/extract_subset/extract_subset.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include "internal/generate_submesh.hpp"
#include "internal/new_topology_separate.hpp"
namespace wmtk {

namespace components {

/*
This function provides a unified interface for extracting a subset of a mesh, 2d or 3d, with or
without preserving geometry.
*/
std::unique_ptr<wmtk::Mesh>
extract_subset(wmtk::Mesh& m, const std::vector<int>& tag_vec, bool pos);
// wmtk::Mesh& extract_subset(wmtk::Mesh& m, const std::vector<int>& tag_vec, bool pos);
} // namespace components
} // namespace wmtk
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include "extract_subset_2d.hpp"
#include <iostream>
namespace wmtk::components::internal {

wmtk::TriMesh
extract_subset_2d(wmtk::TriMesh m, wmtk::MeshAttributeHandle<long> tag_handle, bool pos)
{
wmtk::Accessor<long> tag_acc = m.create_accessor(tag_handle);
std::vector<wmtk::Tuple> faces = m.get_all(wmtk::PrimitiveType::Face);
std::vector<wmtk::Tuple> vertices = m.get_all(wmtk::PrimitiveType::Vertex);
int nb_vertex = vertices.size();
int nb_tri = faces.size();

// a tag on each "real" vertex, true if tagged inside
std::map<long, bool> vertices_in_bool;
for (long t = 0; t < nb_vertex; ++t) vertices_in_bool.insert({t, false});

// both init to 0, increment by count later
long nb_vertex_in = 0, nb_tri_in = 0;

// store the temporary "id" of the tagged triangles
std::vector<long> tag_tri_index;
for (size_t i = 0; i < nb_tri; ++i) {
long tri_tag = tag_acc.const_scalar_attribute(faces.at(i));
switch (tri_tag) {
// inside: store the temp id of this tri
case 1:
tag_tri_index.push_back(i);
break;
// outside: do nothing
case 0: break;
// neither: runtime error
default: throw std::runtime_error("illegal tag!");
}
}
nb_tri_in = tag_tri_index.size();
assert(nb_tri_in <= nb_tri);
// std::cout << "# of tri inside = " << nb_tri_in << std::endl;

// for the tagged tri, mark their "real" vertices as inside (duplicates handled by boolean)
// current algo for bug fixing: O(N^2), go over all vertices and look for match,
// only assign tag to inside ones
// TODO: improve the algorithm to achieve O(N)
for (size_t i = 0; i < nb_tri_in; ++i) {
Simplex s = Simplex::face(faces[tag_tri_index[i]]);
std::vector<wmtk::Tuple> tuple_list =
wmtk::simplex::faces_single_dimension(m, s, PrimitiveType::Vertex);
for (wmtk::Tuple t : tuple_list) vertices_in_bool[find_vertex_index(m, t)] = true;
}

// std::cout << "# of vertex inside = " << vertices_in_bool.size() << std::endl;
// construct a map from old tuple to temp new "id" of a "real" vertex
std::map<long, long> old2new;
for (long i = 0; i < nb_vertex; ++i) {
if (vertices_in_bool[i]) {
// std::cout << "inside! nb_vertex_in = " << nb_vertex_in << std::endl;
// old vertex tuple t mapped to new vertex id j, where j increases by count
old2new.insert({i, nb_vertex_in});
nb_vertex_in++;
}
}
// std::cout << "# of pairs in map = " << old2new.size() << std::endl;
// for (auto [_, i] : old2new) std::cout << i << std::endl;

wmtk::TriMesh mesh;
wmtk::RowVectors3l tris;
tris.resize(nb_tri_in, 3);
// only put in the extracted ones
for (size_t i = 0; i < nb_tri_in; ++i) {
Simplex s = Simplex::face(faces[tag_tri_index[i]]);
std::vector<wmtk::Tuple> list =
wmtk::simplex::faces_single_dimension(m, s, PrimitiveType::Vertex);
std::vector<long> data(3, -1);
for (int index = 0; index < 3; ++index)
data[index] = old2new[find_vertex_index(m, list[index])];
tris.row(i) << data[0], data[1], data[2];
}
// for (size_t i = 0; i < nb_tri_in; ++i) {
// std::cout << tris.row(i)[0] << tris.row(i)[1] << tris.row(i)[2] << std::endl;
// }
mesh.initialize(tris); // init the topology

// if told to extract and preserve the coordinates
if (pos) {
Eigen::MatrixXd points_in;
points_in.resize(nb_vertex_in, 2);
wmtk::MeshAttributeHandle<double> pos_handle =
m.get_attribute_handle<double>("position", PrimitiveType::Vertex);
wmtk::ConstAccessor<double> pos_acc = m.create_const_accessor(pos_handle);
for (const Tuple& t : vertices) {
// ignore the outside vertices
long old_index = find_vertex_index(m, t);
if (vertices_in_bool[old_index]) {
points_in.row(old2new[old_index]) = pos_acc.const_vector_attribute(t);
}
wmtk::mesh_utils::set_matrix_attribute(
points_in,
"position",
wmtk::PrimitiveType::Vertex,
mesh);
}
}
return mesh;
}
} // namespace wmtk::components::internal
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include <wmtk/TriMesh.hpp>
#include <wmtk/simplex/faces_single_dimension.hpp>
#include <wmtk/utils/mesh_utils.hpp>
#include "utils.hpp"

namespace wmtk::components::internal {

wmtk::TriMesh
extract_subset_2d(wmtk::TriMesh m, wmtk::MeshAttributeHandle<long> taghandle, bool pos);
} // namespace wmtk::components::internal
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#include "extract_subset_3d.hpp"

namespace wmtk::components::internal {
wmtk::TetMesh
extract_subset_3d(wmtk::TetMesh m, wmtk::MeshAttributeHandle<long> taghandle, bool pos)
{
wmtk::Accessor<long> tag_acc = m.create_accessor(taghandle);
std::vector<wmtk::Tuple> tets = m.get_all(wmtk::PrimitiveType::Tetrahedron);
std::vector<wmtk::Tuple> vertices = m.get_all(wmtk::PrimitiveType::Vertex);
int nb_vertex = vertices.size();
int nb_tet = tets.size();

std::map<long, bool> vertices_in_bool;
for (long t = 0; t < nb_vertex; ++t) vertices_in_bool.insert({t, false});

long nb_vertex_in = 0, nb_tet_in = 0;

// store the temporary "id" of the tagged tets
std::vector<long> tag_tet_index;
for (size_t i = 0; i < nb_tet; ++i) {
long tri_tag = tag_acc.const_scalar_attribute(tets.at(i));
std::cout << tri_tag << " ";
switch (tri_tag) {
// inside: store the temp id of this tri
case 1:
nb_tet_in++;
tag_tet_index.push_back(i);
break;
// outside: do nothing
case 0: break;
// neither: runtime error
default: throw std::runtime_error("illegal tag!");
}
}
assert(nb_tet_in <= nb_tet);

// for the tagged tri, mark their "real" vertices as inside (duplicates handled by boolean)
// current algo for bug fixing: O(N^2), go over all vertices and look for match,
// only assign tag to inside ones
for (size_t i = 0; i < nb_tet_in; ++i) {
Simplex s = Simplex::tetrahedron(tets[tag_tet_index[i]]);
std::vector<wmtk::Tuple> tuple_list =
wmtk::simplex::faces_single_dimension(m, s, PrimitiveType::Vertex);
for (wmtk::Tuple t : tuple_list)
vertices_in_bool[find_vertex_index(m, t)] = true;
}

// construct a map from old tuple to temp new "id" of a "real" vertex
std::map<long, long> old2new;
for (long i = 0; i < nb_vertex; ++i) {
if (vertices_in_bool[i]) {
// std::cout << "inside! nb_vertex_in = " << nb_vertex_in << std::endl;
// old vertex tuple t mapped to new vertex id j, where j increases by count
old2new.insert({i, nb_vertex_in});
nb_vertex_in++;
}
}

wmtk::TetMesh mesh;
wmtk::RowVectors4l tris;
tris.resize(nb_tet_in, 4);
// only put in the extracted ones
for (size_t i = 0; i < nb_tet_in; ++i) {
Simplex s = Simplex::tetrahedron(tets[tag_tet_index[i]]);
std::vector<wmtk::Tuple> list =
wmtk::simplex::faces_single_dimension(m, s, PrimitiveType::Vertex);
std::vector<long> data(4, -1);
for (int index = 0; index < 4; ++index)
data[index] = old2new[find_vertex_index(m, list[index])];
tris.row(i) << data[0], data[1], data[2], data[3];
}
mesh.initialize(tris); // init the topology

// if told to extract and preserve the coordinates
if (pos) {
Eigen::MatrixXd points_in;
points_in.resize(nb_vertex_in, 3);
wmtk::MeshAttributeHandle<double> pos_handle =
m.get_attribute_handle<double>("position", PrimitiveType::Vertex);
wmtk::ConstAccessor<double> pos_acc = m.create_const_accessor(pos_handle);
for (const Tuple& t : vertices) {
// ignore the outside vertices
long old_index = find_vertex_index(m, t);
if (vertices_in_bool[old_index]) {
points_in.row(old2new[old_index]) = pos_acc.const_vector_attribute(t);
}
wmtk::mesh_utils::set_matrix_attribute(
points_in,
"position",
wmtk::PrimitiveType::Vertex,
mesh);
}
}
return mesh;
}

} // namespace wmtk::components::internal
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include <wmtk/TetMesh.hpp>
#include <wmtk/simplex/faces_single_dimension.hpp>
#include <wmtk/utils/mesh_utils.hpp>
#include "utils.hpp"

namespace wmtk::components::internal {

wmtk::TetMesh
extract_subset_3d(wmtk::TetMesh m, wmtk::MeshAttributeHandle<long> taghandle, bool pos);
} // namespace wmtk::components::internal
Loading