-
Notifications
You must be signed in to change notification settings - Fork 18
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
Hackathon/edge mesh #378
Merged
Merged
Hackathon/edge mesh #378
Changes from 57 commits
Commits
Show all changes
59 commits
Select commit
Hold shift + click to select a range
ba90699
add dummy files
Zhouyuan-Chen 5095f98
fixed problem
Zhouyuan-Chen f792fb4
added throws for safety
Zhouyuan-Chen d412649
implemented some EdgeMesh functions
Zhouyuan-Chen 96325c6
add EdgeMeshOperationExecutor and DEBUG_EdgeMesh
Zhouyuan-Chen b749fac
add EdgeMesh_example and test code
Zhouyuan-Chen 01ba6f1
fix a bug for EdgeMesh::initialize, the loop's condition wrong.
Zhouyuan-Chen d9e3742
Merge remote-tracking branch 'origin/main' into hackathon/edge_mesh
zlyfunction 37392a7
get the desired frame for edgemesh operation executor
zlyfunction b551d2d
implement edgemesh split_edge
zlyfunction 913e166
fimish edgemesh split_edge with return tuple
zlyfunction 455c867
correct edgemsh split without aorientation assumptions
zlyfunction a75edd4
implement edge mesh connectivity
JcDai b6e2844
take care of the case of self loop
zlyfunction 588530a
a complete draft of edge mesh operations
zlyfunction 2f50e69
Merge branch 'hackathon/edge_mesh' of https://github.com/wildmeshing/…
JcDai b006e30
implemented edge mesh
JcDai 1a91445
add 1d topology unit test
JcDai 7f9f178
add implementation for operations in edgemesh clas
JcDai 0f1e5c4
fix typo
JcDai 4b549e2
add debug_edgemesh examples
JcDai d6f79e0
fix bug
JcDai 51e750d
rename tmoe to emoe
zlyfunction 9d210e5
add 1d tuple tests
JcDai 4c1fc6d
Merge branch 'hackathon/edge_mesh' of https://github.com/wildmeshing/…
JcDai 6cd9330
Merge remote-tracking branch 'origin/main' into hackathon/edge_mesh
JcDai 8443678
clean codes
JcDai 93078ed
fix collapse
zlyfunction 0191bc1
add test simplices_to_delete_for_split_1D
zlyfunction f9339ea
add test simplices_to_delete
zlyfunction e680734
add split and collapse test, need fix collapse
zlyfunction 36f5b4b
fix ccw, still need fix collapse
zlyfunction d5ae116
add more 1d topology test
JcDai 8cbc009
Merge branch 'hackathon/edge_mesh' of https://github.com/wildmeshing/…
JcDai 436714d
fix collapse, seems to be correct
zlyfunction 3af5411
Merge branch 'hackathon/edge_mesh' of https://github.com/wildmeshing/…
JcDai d3fd978
add is_simplex_deleted function in DEBUG_EdgeMesh
zlyfunction 8163b71
fix collapse edge ev update
zlyfunction 36ef0f2
fix bug for self loop otopo init
JcDai 4fff8d8
Merge branch 'main' into hackathon/edge_mesh
e43b219
collapse test add return_tuple check and delete simplex test
4f59656
fix bug in update ve in collapse edge
e20fd21
finish testing collapse edge
add571d
fix bug in split_edge ev update
22c615a
finish split test
zlyfunction 3844c20
refactor based on comments
JcDai 57f8aae
Merge remote-tracking branch 'origin/main' into hackathon/edge_mesh
JcDai cf18878
add throw
JcDai 56e6040
redo changes in TriMesh
JcDai d3cd444
rollback the redo for Trimesh
JcDai 29a6674
refactor based on comments
zlyfunction fd11974
reuse hash acc in tests
zlyfunction 88f62a7
fix DEBUG_EdgeMesh::operator==
zlyfunction 0409e9b
Merge branch 'main' into hackathon/edge_mesh
zlyfunction 281e5cc
Merge branch 'main' of https://github.com/wildmeshing/wildmeshing-too…
zlyfunction 6540991
modify to fit the changes happend in main branch
zlyfunction 3ee54bc
typo in comment
zlyfunction 25251ca
fix compile
zlyfunction e991d24
delete TODO in comments
zlyfunction File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,262 @@ | ||
#include "EdgeMesh.hpp" | ||
|
||
|
||
#include <wmtk/utils/edgemesh_topology_initialization.h> | ||
#include <wmtk/EdgeMeshOperationExecutor.hpp> | ||
#include <wmtk/SimplicialComplex.hpp> | ||
#include <wmtk/utils/Logger.hpp> | ||
namespace wmtk { | ||
EdgeMesh::EdgeMesh() | ||
: Mesh(1) | ||
, m_ve_handle(register_attribute<long>("m_ve", PrimitiveType::Vertex, 1)) | ||
, m_ev_handle(register_attribute<long>("m_ev", PrimitiveType::Edge, 2)) | ||
, m_ee_handle(register_attribute<long>("m_ee", PrimitiveType::Edge, 2)) | ||
{} | ||
EdgeMesh::EdgeMesh(const EdgeMesh& o) = default; | ||
EdgeMesh::EdgeMesh(EdgeMesh&& o) = default; | ||
EdgeMesh& EdgeMesh::operator=(const EdgeMesh& o) = default; | ||
EdgeMesh& EdgeMesh::operator=(EdgeMesh&& o) = default; | ||
|
||
Tuple EdgeMesh::split_edge(const Tuple& t, Accessor<long>& hash_accessor) | ||
{ | ||
EdgeMesh::EdgeMeshOperationExecutor executor(*this, t, hash_accessor); | ||
return executor.split_edge(); | ||
} | ||
|
||
Tuple EdgeMesh::collapse_edge(const Tuple& t, Accessor<long>& hash_accessor) | ||
{ | ||
EdgeMesh::EdgeMeshOperationExecutor executor(*this, t, hash_accessor); | ||
return executor.collapse_edge(); | ||
} | ||
|
||
long EdgeMesh::id(const Tuple& tuple, PrimitiveType type) const | ||
{ | ||
switch (type) { | ||
case PrimitiveType::Vertex: { | ||
ConstAccessor<long> ev_accessor = create_const_accessor<long>(m_ev_handle); | ||
auto ev = ev_accessor.vector_attribute(tuple); | ||
return ev(tuple.m_local_vid); | ||
} | ||
case PrimitiveType::Edge: { | ||
return tuple.m_global_cid; | ||
} | ||
case PrimitiveType::Face: | ||
case PrimitiveType::Tetrahedron: | ||
default: throw std::runtime_error("Tuple id: Invalid primitive type"); | ||
} | ||
} | ||
|
||
bool EdgeMesh::is_boundary(const Tuple& tuple) const | ||
{ | ||
return is_boundary_vertex(tuple); | ||
} | ||
|
||
bool EdgeMesh::is_boundary_vertex(const Tuple& tuple) const | ||
{ | ||
assert(is_valid_slow(tuple)); | ||
ConstAccessor<long> ee_accessor = create_const_accessor<long>(m_ee_handle); | ||
return ee_accessor.vector_attribute(tuple)(tuple.m_local_vid) < 0; | ||
} | ||
|
||
Tuple EdgeMesh::switch_tuple(const Tuple& tuple, PrimitiveType type) const | ||
{ | ||
assert(is_valid_slow(tuple)); | ||
bool ccw = is_ccw(tuple); | ||
|
||
switch (type) { | ||
case PrimitiveType::Vertex: | ||
return Tuple( | ||
1 - tuple.m_local_vid, | ||
tuple.m_local_eid, | ||
tuple.m_local_fid, | ||
tuple.m_global_cid, | ||
tuple.m_hash); | ||
case PrimitiveType::Edge: { | ||
const long gvid = id(tuple, PrimitiveType::Vertex); | ||
|
||
ConstAccessor<long> ee_accessor = create_const_accessor<long>(m_ee_handle); | ||
auto ee = ee_accessor.vector_attribute(tuple); | ||
|
||
long gcid_new = ee(tuple.m_local_vid); | ||
|
||
// TODO: This is for special case self-loop, just to make sure the local vid of the returned | ||
// tuple is the same as the input. (When doing double-switch this is needed) | ||
if (gcid_new == tuple.m_global_cid) { | ||
return tuple; | ||
} | ||
|
||
long lvid_new = -1; | ||
|
||
ConstAccessor<long> ev_accessor = create_const_accessor<long>(m_ev_handle); | ||
auto ev = ev_accessor.index_access().vector_attribute(gcid_new); | ||
|
||
for (long i = 0; i < 2; ++i) { | ||
if (ev(i) == gvid) { | ||
lvid_new = i; | ||
// break; | ||
} | ||
} | ||
assert(lvid_new != -1); | ||
|
||
ConstAccessor<long> hash_accessor = get_const_cell_hash_accessor(); | ||
|
||
const Tuple res( | ||
lvid_new, | ||
tuple.m_local_eid, | ||
tuple.m_local_fid, | ||
gcid_new, | ||
get_cell_hash(gcid_new, hash_accessor)); | ||
assert(is_valid(res, hash_accessor)); | ||
return res; | ||
} | ||
case PrimitiveType::Face: | ||
case PrimitiveType::Tetrahedron: | ||
default: throw std::runtime_error("Tuple switch: Invalid primitive type"); break; | ||
} | ||
} | ||
|
||
bool EdgeMesh::is_ccw(const Tuple& tuple) const | ||
{ | ||
assert(is_valid_slow(tuple)); | ||
return tuple.m_local_vid == 0; | ||
} | ||
|
||
void EdgeMesh::initialize( | ||
Eigen::Ref<const RowVectors2l> EV, | ||
Eigen::Ref<const RowVectors2l> EE, | ||
Eigen::Ref<const VectorXl> VE) | ||
{ | ||
// reserve memory for attributes | ||
|
||
std::vector<long> cap{static_cast<long>(VE.rows()), static_cast<long>(EE.rows())}; | ||
|
||
set_capacities(cap); | ||
|
||
// get accessors for topology | ||
Accessor<long> ev_accessor = create_accessor<long>(m_ev_handle); | ||
Accessor<long> ee_accessor = create_accessor<long>(m_ee_handle); | ||
Accessor<long> ve_accessor = create_accessor<long>(m_ve_handle); | ||
|
||
Accessor<char> v_flag_accessor = get_flag_accessor(PrimitiveType::Vertex); | ||
Accessor<char> e_flag_accessor = get_flag_accessor(PrimitiveType::Edge); | ||
|
||
// iterate over the matrices and fill attributes | ||
|
||
for (long i = 0; i < capacity(PrimitiveType::Edge); ++i) { | ||
ev_accessor.index_access().vector_attribute(i) = EV.row(i).transpose(); | ||
ee_accessor.index_access().vector_attribute(i) = EE.row(i).transpose(); | ||
|
||
e_flag_accessor.index_access().scalar_attribute(i) |= 0x1; | ||
} | ||
// m_ve | ||
for (long i = 0; i < capacity(PrimitiveType::Vertex); ++i) { | ||
ve_accessor.index_access().scalar_attribute(i) = VE(i); | ||
v_flag_accessor.index_access().scalar_attribute(i) |= 0x1; | ||
} | ||
} | ||
|
||
void EdgeMesh::initialize(Eigen::Ref<const RowVectors2l> E) | ||
{ | ||
auto [EE, VE] = edgemesh_topology_initialization(E); | ||
initialize(E, EE, VE); | ||
} | ||
|
||
long EdgeMesh::_debug_id(const Tuple& tuple, PrimitiveType type) const | ||
{ | ||
wmtk::logger().warn("This function must only be used for debugging!!"); | ||
return id(tuple, type); | ||
} | ||
|
||
Tuple EdgeMesh::tuple_from_id(const PrimitiveType type, const long gid) const | ||
{ | ||
switch (type) { | ||
case PrimitiveType::Vertex: { | ||
return vertex_tuple_from_id(gid); | ||
} | ||
case PrimitiveType::Edge: { | ||
return edge_tuple_from_id(gid); | ||
} | ||
case PrimitiveType::Face: { | ||
throw std::runtime_error("no tet tuple supported for edgemesh"); | ||
break; | ||
} | ||
case PrimitiveType::Tetrahedron: { | ||
throw std::runtime_error("no tet tuple supported for edgemesh"); | ||
break; | ||
} | ||
default: throw std::runtime_error("Invalid primitive type"); break; | ||
} | ||
} | ||
|
||
Tuple EdgeMesh::vertex_tuple_from_id(long id) const | ||
{ | ||
ConstAccessor<long> ve_accessor = create_const_accessor<long>(m_ve_handle); | ||
auto e = ve_accessor.index_access().scalar_attribute(id); | ||
ConstAccessor<long> ev_accessor = create_const_accessor<long>(m_ev_handle); | ||
auto ev = ev_accessor.index_access().vector_attribute(e); | ||
for (long i = 0; i < 2; ++i) { | ||
if (ev(i) == id) { | ||
Tuple v_tuple = Tuple(i, -1, -1, e, get_cell_hash_slow(e)); | ||
return v_tuple; | ||
} | ||
} | ||
throw std::runtime_error("vertex_tuple_from_id failed"); | ||
} | ||
|
||
Tuple EdgeMesh::edge_tuple_from_id(long id) const | ||
{ | ||
Tuple e_tuple = Tuple(0, -1, -1, id, get_cell_hash_slow(id)); | ||
|
||
assert(is_valid_slow(e_tuple)); | ||
return e_tuple; | ||
} | ||
|
||
bool EdgeMesh::is_valid(const Tuple& tuple, ConstAccessor<long>& hash_accessor) const | ||
{ | ||
if (tuple.is_null()) return false; | ||
|
||
if (tuple.m_local_vid < 0 || tuple.m_global_cid < 0) return false; | ||
|
||
return Mesh::is_hash_valid(tuple, hash_accessor); | ||
} | ||
|
||
bool EdgeMesh::is_connectivity_valid() const | ||
{ | ||
// get accessors for topology | ||
ConstAccessor<long> ev_accessor = create_const_accessor<long>(m_ev_handle); | ||
ConstAccessor<long> ee_accessor = create_const_accessor<long>(m_ee_handle); | ||
ConstAccessor<long> ve_accessor = create_const_accessor<long>(m_ve_handle); | ||
ConstAccessor<char> v_flag_accessor = get_flag_accessor(PrimitiveType::Vertex); | ||
ConstAccessor<char> e_flag_accessor = get_flag_accessor(PrimitiveType::Edge); | ||
|
||
// VE and EV | ||
for (long i = 0; i < capacity(PrimitiveType::Vertex); ++i) { | ||
if (v_flag_accessor.index_access().scalar_attribute(i) == 0) { | ||
wmtk::logger().debug("Vertex {} is deleted", i); | ||
continue; | ||
} | ||
int cnt = 0; | ||
for (long j = 0; j < 2; ++j) { | ||
if (ev_accessor.index_access().vector_attribute( | ||
ve_accessor.index_access().scalar_attribute(i))[j] == i) { | ||
cnt++; | ||
} | ||
} | ||
if (cnt == 0) { | ||
return false; | ||
} | ||
} | ||
|
||
// EV and EE | ||
for (long i = 0; i < capacity(PrimitiveType::Edge); ++i) { | ||
if (e_flag_accessor.index_access().scalar_attribute(i) == 0) { | ||
wmtk::logger().debug("Edge {} is deleted", i); | ||
continue; | ||
} | ||
// TODO: need to handle cornor case (self-loop) | ||
JcDai marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
return true; | ||
} | ||
|
||
} // namespace wmtk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#pragma once | ||
|
||
#include "Mesh.hpp" | ||
#include "Tuple.hpp" | ||
|
||
#include <Eigen/Core> | ||
|
||
namespace wmtk { | ||
|
||
class EdgeMesh : public Mesh | ||
{ | ||
public: | ||
EdgeMesh(); | ||
EdgeMesh(const EdgeMesh& o); | ||
EdgeMesh(EdgeMesh&& o); | ||
EdgeMesh& operator=(const EdgeMesh& o); | ||
EdgeMesh& operator=(EdgeMesh&& o); | ||
|
||
PrimitiveType top_simplex_type() const override { return PrimitiveType::Edge; } | ||
|
||
Tuple split_edge(const Tuple& t, Accessor<long>& hash_accessor); | ||
|
||
Tuple collapse_edge(const Tuple& t, Accessor<long>& hash_accessor); | ||
|
||
Tuple switch_tuple(const Tuple& tuple, PrimitiveType type) const override; | ||
|
||
bool is_ccw(const Tuple& tuple) const override; | ||
bool is_boundary(const Tuple& tuple) const override; | ||
bool is_boundary_vertex(const Tuple& tuple) const override; | ||
bool is_boundary_edge(const Tuple& tuple) const override | ||
{ | ||
throw("This function doesn't make sense for EdgeMesh"); | ||
} | ||
|
||
void initialize(Eigen::Ref<const RowVectors2l> E); | ||
|
||
void initialize( | ||
Eigen::Ref<const RowVectors2l> EV, | ||
Eigen::Ref<const RowVectors2l> EE, | ||
Eigen::Ref<const VectorXl> VE); | ||
|
||
long _debug_id(const Tuple& tuple, PrimitiveType type) const; | ||
long _debug_id(const Simplex& simplex) const | ||
{ | ||
return _debug_id(simplex.tuple(), simplex.primitive_type()); | ||
} | ||
|
||
|
||
bool is_valid(const Tuple& tuple, ConstAccessor<long>& hash_accessor) const override; | ||
|
||
bool is_connectivity_valid() const override; | ||
|
||
protected: | ||
long id(const Tuple& tuple, PrimitiveType type) const override; | ||
long id(const Simplex& simplex) const { return id(simplex.tuple(), simplex.primitive_type()); } | ||
|
||
long id_vertex(const Tuple& tuple) const { return id(tuple, PrimitiveType::Vertex); } | ||
long id_edge(const Tuple& tuple) const { return id(tuple, PrimitiveType::Edge); } | ||
|
||
/** | ||
* @brief internal function that returns the tuple of requested type, and has the global index | ||
* cid | ||
* | ||
* @param gid | ||
* @return Tuple | ||
*/ | ||
Tuple tuple_from_id(const PrimitiveType type, const long gid) const override; | ||
|
||
protected: | ||
attribute::MeshAttributeHandle<long> m_ve_handle; | ||
|
||
attribute::MeshAttributeHandle<long> m_ev_handle; | ||
attribute::MeshAttributeHandle<long> m_ee_handle; | ||
|
||
Tuple vertex_tuple_from_id(long id) const; | ||
Tuple edge_tuple_from_id(long id) const; | ||
|
||
// internal structure that encapsulations the actual execution of split and collapse | ||
class EdgeMeshOperationExecutor; | ||
}; | ||
|
||
} // namespace wmtk |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this TODO still a TODO?