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

Removed split/collapse from Mesh and customized Tri/Tet split/collapse #429

Merged
merged 2 commits into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 0 additions & 17 deletions src/wmtk/Mesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,23 +76,6 @@ class Mesh : public std::enable_shared_from_this<Mesh>
void clean();


// Split and collapse are the two atomic operations we want to support for each type of mesh.
// These functions are intended to be called within an single Operation and
// not on their own and the semantics between each derived Mesh class and
// its SplitEdge and CollapseEdge operations should be treated as internal
// implementation deatils.
//
// As such, the split_edge and collapse_edge functions JUST implement the
// updates to topological updates and any precondition / postcondition checks
// should be implemented by the user.
//
// These functions take in a single tuple, referring to the edge being
// operated on, and return a single tuple that refers to the new topology.
// This returned tuple has specific meaning for each derived Mesh class

virtual Tuple split_edge(const Tuple& t, Accessor<long>& hash_accessor) = 0;
virtual Tuple collapse_edge(const Tuple& t, Accessor<long>& hash_accessor) = 0;

template <typename T>
MeshAttributeHandle<T> register_attribute(
const std::string& name,
Expand Down
2 changes: 0 additions & 2 deletions src/wmtk/PointMesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ class PointMesh : public Mesh

bool is_valid(const Tuple& tuple, ConstAccessor<long>& hash_accessor) const override;

Tuple split_edge(const Tuple&, Accessor<long>&) override { return {}; }
Tuple collapse_edge(const Tuple&, Accessor<long>&) override { return {}; }
bool is_connectivity_valid() const override { return true; }

protected:
Expand Down
16 changes: 10 additions & 6 deletions src/wmtk/TetMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,22 +226,26 @@ Tuple TetMesh::tuple_from_id(const PrimitiveType type, const long gid) const
}
}

Tuple TetMesh::split_edge(const Tuple& t, Accessor<long>& hash_accessor)
auto TetMesh::split_edge(const Tuple& t, Accessor<long>& hash_accessor)
-> operations::tet_mesh::EdgeOperationData
{
// prototype
// Executor exec;
// exec.populate_ears()
// exec.populate_faces();
// exec.run_split();

TetMesh::TetMeshOperationExecutor executor(*this, t, hash_accessor);
return executor.split_edge();
TetMeshOperationExecutor executor(*this, t, hash_accessor);
executor.split_edge();
return executor;
}

Tuple TetMesh::collapse_edge(const Tuple& t, Accessor<long>& hash_accessor)
auto TetMesh::collapse_edge(const Tuple& t, Accessor<long>& hash_accessor)
-> operations::tet_mesh::EdgeOperationData
{
TetMesh::TetMeshOperationExecutor executor(*this, t, hash_accessor);
return executor.collapse_edge();
TetMeshOperationExecutor executor(*this, t, hash_accessor);
executor.collapse_edge();
return executor;
}

long TetMesh::id(const Tuple& tuple, PrimitiveType type) const
Expand Down
13 changes: 8 additions & 5 deletions src/wmtk/TetMesh.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <wmtk/operations/tet_mesh/EdgeOperationData.hpp>
#include "Mesh.hpp"

namespace wmtk {
Expand All @@ -12,8 +13,12 @@ class TetMesh : public Mesh
TetMesh& operator=(const TetMesh& o);
TetMesh& operator=(TetMesh&& o);

Tuple split_edge(const Tuple& t, Accessor<long>& hash_accessor) override;
Tuple collapse_edge(const Tuple& t, Accessor<long>& hash_accessor) override;
operations::tet_mesh::EdgeOperationData split_edge(
const Tuple& t,
Accessor<long>& hash_accessor);
operations::tet_mesh::EdgeOperationData collapse_edge(
const Tuple& t,
Accessor<long>& hash_accessor);
PrimitiveType top_simplex_type() const override { return PrimitiveType::Tetrahedron; }
Tuple switch_tuple(const Tuple& tuple, PrimitiveType type) const override;
bool is_ccw(const Tuple& tuple) const override;
Expand Down Expand Up @@ -62,6 +67,7 @@ class TetMesh : public Mesh

// private:
protected:
class TetMeshOperationExecutor;
MeshAttributeHandle<long> m_vt_handle;
MeshAttributeHandle<long> m_et_handle;
MeshAttributeHandle<long> m_ft_handle;
Expand All @@ -75,9 +81,6 @@ class TetMesh : public Mesh
Tuple edge_tuple_from_id(long id) const;
Tuple face_tuple_from_id(long id) const;
Tuple tet_tuple_from_id(long id) const;

// internal structure that encapsulations the actual execution of split and collapse
class TetMeshOperationExecutor;
};

} // namespace wmtk
14 changes: 5 additions & 9 deletions src/wmtk/TetMeshOperationExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ TetMesh::TetMeshOperationExecutor::TetMeshOperationExecutor(
, ft_accessor(m.create_accessor<long>(m.m_ft_handle))
, hash_accessor(hash_acc)
, m_mesh(m)
, m_operating_tuple(operating_tuple)
{
m_operating_tuple = operating_tuple;
// store ids of edge and incident vertices
m_operating_edge_id = m_mesh.id_edge(m_operating_tuple);
m_spine_vids[0] = m_mesh.id_vertex(m_operating_tuple);
Expand Down Expand Up @@ -241,7 +241,7 @@ void TetMesh::TetMeshOperationExecutor::update_ear_connectivity(
ft_accessor.index_access().scalar_attribute(common_fid) = ear_tid;
}

Tuple TetMesh::TetMeshOperationExecutor::split_edge()
void TetMesh::TetMeshOperationExecutor::split_edge()
{
simplex_ids_to_delete = get_split_simplices_to_delete(m_operating_tuple, m_mesh);

Expand Down Expand Up @@ -653,13 +653,11 @@ Tuple TetMesh::TetMeshOperationExecutor::split_edge()
assert(return_local_eid > -1);
assert(return_local_fid > -1);
const long return_tet_hash = hash_accessor.index_access().scalar_attribute(return_tid);
Tuple ret =
m_output_tuple =
Tuple(return_local_vid, return_local_eid, return_local_fid, return_tid, return_tet_hash);

return ret;
}

Tuple TetMesh::TetMeshOperationExecutor::collapse_edge()
void TetMesh::TetMeshOperationExecutor::collapse_edge()
{
simplex_ids_to_delete = get_collapse_simplices_to_delete(m_operating_tuple, m_mesh);

Expand Down Expand Up @@ -895,10 +893,8 @@ Tuple TetMesh::TetMeshOperationExecutor::collapse_edge()
const long return_tet_hash = hash_accessor.index_access().scalar_attribute(return_tid);


Tuple ret =
m_output_tuple =
Tuple(return_local_vid, return_local_eid, return_local_fid, return_tid, return_tet_hash);

return ret;
}

std::vector<long> TetMesh::TetMeshOperationExecutor::request_simplex_indices(
Expand Down
125 changes: 4 additions & 121 deletions src/wmtk/TetMeshOperationExecutor.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#pragma once
#include <wmtk/operations/tet_mesh/EdgeOperationData.hpp>
#include <wmtk/utils/Logger.hpp>
#include "SimplicialComplex.hpp"
#include "TetMesh.hpp"
#include "Tuple.hpp"
namespace wmtk {
class TetMesh::TetMeshOperationExecutor
class TetMesh::TetMeshOperationExecutor : public operations::tet_mesh::EdgeOperationData
{
public:
TetMeshOperationExecutor(TetMesh& m, const Tuple& operating_tuple, Accessor<long>& hash_acc);
Expand All @@ -21,107 +22,6 @@ class TetMesh::TetMeshOperationExecutor
Accessor<long> ft_accessor;
Accessor<long>& hash_accessor;

//
// E --------------- C --------------- F
// \-_ / | \ _-/
// \ EarTet / | \ EarTet /
// \ tid1 / | \ tid2 /
// \ -_/fid1|fid2\_- /
// \ / --_ | _-- \ /
// \ / __- D -__ \ /
// \ /_-- --_\ /
// A ================= B
// operating edge
//

/**
* An EarTet is a neighbor of a tet to be deleted in the split/collapse operation
*
*/
struct EarTet
{
long tid = -1; // global tid of the ear, -1 if it doesn't exist
long fid = -1; // global fid of the ear, -1 if it doesn't exist
};

/**
* Data on the incident tets of the operating edge
*/
struct IncidentTetData
{
long tid = -1;
std::array<EarTet, 2> ears;
};

/**
* @brief structs for split (to be merge with collapse)
*
*/

struct FaceSplitData
{
long fid_old = -1;
long fid_new_1 = -1;
long fid_new_2 = -1;
long eid_spine_old = -1;
long eid_spine_1 = -1;
long eid_spine_2 = -1;
long eid_split = -1;
};

/*
v3
/\\
ear1 / \ \ ear2
/ \ \
/ \ \
/ \ \
/ \ \
/ \ _\ v4
/______________\_ -
v1 e12 v2
*/

struct TetSplitData
{
long tid_old = -1;
long tid_new_1 = -1;
long tid_new_2 = -1;
long fid_split = -1;
long v1;
long v2;
long v3;
long v4;
long e12;
long e13;
long e14;
long e23;
long e24;
long e34;

EarTet ear_tet_1; // switch edge switch face
EarTet ear_tet_2; // switch vertex switch edge switch face
std::array<FaceSplitData, 2> new_face_data;
};

struct TetCollapseData
{
long tid_old = -1;
long v1;
long v2;
long v3;
long v4;
long e12;
long e13;
long e14;
long e23;
long e24;
long e34;

EarTet ear_tet_1; // switch edge switch face
EarTet ear_tet_2; // switch vertex switch edge switch face
};


/**
* @brief gather all simplices that are deleted in a split
Expand Down Expand Up @@ -155,10 +55,6 @@ class TetMesh::TetMeshOperationExecutor
const long old_tid,
const long common_fid);

const std::array<long, 2>& incident_vids() const { return m_spine_vids; }

const long operating_edge_id() const { return m_operating_edge_id; }


/*

Expand All @@ -184,7 +80,7 @@ class TetMesh::TetMeshOperationExecutor
* tet. In the illustration it will return Tuple(v1, v1-v_new, v1-v_new-v4, v1-v_new-v4-v3)
*
*/
Tuple split_edge();
void split_edge();

/**
* @brief split edge v1-v2
Expand All @@ -204,27 +100,14 @@ class TetMesh::TetMeshOperationExecutor
* link condition user level? *should return a invalid tuple if no ears?*).
*
*/
Tuple collapse_edge();
void collapse_edge();

std::vector<long> request_simplex_indices(const PrimitiveType type, long count);

std::array<std::vector<long>, 4> simplex_ids_to_delete;
std::vector<long> cell_ids_to_update_hash;

TetMesh& m_mesh;
Tuple m_operating_tuple;


private:
// common simplices
std::array<long, 2> m_spine_vids; // two endpoints of the edge
long m_operating_edge_id;
long m_operating_face_id;
long m_operating_tet_id;

// simplices required per-tet
std::vector<IncidentTetData> m_incident_tet_datas;

IncidentTetData get_incident_tet_data(Tuple t);


Expand Down
17 changes: 11 additions & 6 deletions src/wmtk/TriMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,22 @@ TriMesh::TriMesh(TriMesh&& o) = default;
TriMesh& TriMesh::operator=(const TriMesh& o) = default;
TriMesh& TriMesh::operator=(TriMesh&& o) = default;

Tuple TriMesh::split_edge(const Tuple& t, Accessor<long>& hash_accessor)
auto TriMesh::split_edge(const Tuple& t, Accessor<long>& hash_accessor) ->

operations::tri_mesh::EdgeOperationData
{
// TODO record the deleted simplices topology attributes
TriMesh::TriMeshOperationExecutor executor(*this, t, hash_accessor);
return executor.split_edge();
TriMeshOperationExecutor executor(*this, t, hash_accessor);
executor.split_edge();
return executor;
}

Tuple TriMesh::collapse_edge(const Tuple& t, Accessor<long>& hash_accessor)
auto TriMesh::collapse_edge(const Tuple& t, Accessor<long>& hash_accessor)
-> operations::tri_mesh::EdgeOperationData
{
TriMesh::TriMeshOperationExecutor executor(*this, t, hash_accessor);
return executor.collapse_edge();
TriMeshOperationExecutor executor(*this, t, hash_accessor);
executor.collapse_edge();
return executor;
}

long TriMesh::id(const Tuple& tuple, PrimitiveType type) const
Expand Down
7 changes: 4 additions & 3 deletions src/wmtk/TriMesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "Mesh.hpp"
#include "Tuple.hpp"
#include <wmtk/operations/tri_mesh/EdgeOperationData.hpp>

#include <Eigen/Core>

Expand All @@ -23,7 +24,7 @@ class TriMesh : public Mesh
* The returned tuple contains the new vertex. The face lies in the region where the input tuple
* face was, and the edge is oriented in the same direction as in the input.
*/
Tuple split_edge(const Tuple& t, Accessor<long>& hash_accessor) override;
operations::tri_mesh::EdgeOperationData split_edge(const Tuple& t, Accessor<long>& hash_accessor);
/**
* @brief collapse edge t
*
Expand All @@ -32,7 +33,7 @@ class TriMesh : public Mesh
* collapsed. The face is chosen such that the orientation of the tuple is the same as in the
* input. If this is not possible due to a boundary, the opposite face is chosen.
*/
Tuple collapse_edge(const Tuple& t, Accessor<long>& hash_accessor) override;
operations::tri_mesh::EdgeOperationData collapse_edge(const Tuple& t, Accessor<long>& hash_accessor);

Tuple switch_tuple(const Tuple& tuple, PrimitiveType type) const override;

Expand Down Expand Up @@ -97,7 +98,7 @@ class TriMesh : public Mesh
Tuple edge_tuple_from_id(long id) const;
Tuple face_tuple_from_id(long id) const;

// internal structure that encapsulations the actual execution of split and collapse

class TriMeshOperationExecutor;
static Tuple with_different_cid(const Tuple& t, long cid);
};
Expand Down
Loading
Loading