Skip to content

Commit

Permalink
Merge pull request #439 from wildmeshing/dzint/401-edgeswap-does-not-…
Browse files Browse the repository at this point in the history
…use-invariants

Add edge swap invariants
  • Loading branch information
daniel-zint authored Oct 29, 2023
2 parents 5e4800c + bf8eddf commit 44d169d
Show file tree
Hide file tree
Showing 16 changed files with 449 additions and 203 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <wmtk/SimplicialComplex.hpp>
#include <wmtk/operations/tri_mesh/EdgeCollapseToMidpoint.hpp>
#include <wmtk/operations/tri_mesh/EdgeSplitAtMidpoint.hpp>
#include <wmtk/operations/tri_mesh/EdgeSwap.hpp>
#include <wmtk/operations/tri_mesh/EdgeSwapValence.hpp>
#include <wmtk/operations/tri_mesh/VertexTangentialLaplacianSmooth.hpp>

namespace wmtk::components::internal {
Expand Down Expand Up @@ -40,22 +40,23 @@ IsotropicRemeshing::IsotropicRemeshing(TriMesh& mesh, const double length, const
op_settings.max_squared_length = m_length_min * m_length_min;
op_settings.collapse_settings.collapse_boundary_edges = !m_lock_boundary;
op_settings.collapse_towards_boundary = true;

op_settings.initialize_invariants(m_mesh);

m_scheduler.add_operation_type<tri_mesh::EdgeCollapseToMidpoint>("collapse", op_settings);
}
// flip
{
OperationSettings<tri_mesh::EdgeSwap> op_settings;
op_settings.must_improve_valence = true;
OperationSettings<tri_mesh::EdgeSwapValence> op_settings;
op_settings.base_settings.initialize_invariants(m_mesh);

m_scheduler.add_operation_type<tri_mesh::EdgeSwap>("swap", op_settings);
m_scheduler.add_operation_type<tri_mesh::EdgeSwapValence>("swap", op_settings);
}
// smooth
{
OperationSettings<tri_mesh::VertexTangentialLaplacianSmooth> op_settings;
op_settings.smooth_settings.position = m_position_handle;
op_settings.smooth_settings.smooth_boundary = !m_lock_boundary;
op_settings.smooth_settings.base_settings.initialize_invariants(m_mesh);

op_settings.smooth_settings.initialize_invariants(m_mesh);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include <wmtk/operations/tri_mesh/EdgeCollapseToMidpoint.hpp>
#include <wmtk/operations/tri_mesh/EdgeSplitAtMidpoint.hpp>
#include <wmtk/operations/tri_mesh/EdgeSplitWithTag.hpp>
#include <wmtk/operations/tri_mesh/EdgeSwap.hpp>
#include <wmtk/operations/tri_mesh/FaceSplitWithTag.hpp>
#include <wmtk/operations/tri_mesh/VertexTangentialLaplacianSmooth.hpp>

Expand Down
4 changes: 2 additions & 2 deletions src/wmtk/invariants/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ set(SRC_FILES
ValidTupleInvariant.cpp
TriMeshLinkConditionInvariant.hpp
TriMeshLinkConditionInvariant.cpp

MultiMeshLinkConditionInvariant.hpp
MultiMeshLinkConditionInvariant.cpp

MaxEdgeLengthInvariant.hpp
MaxEdgeLengthInvariant.cpp
MinEdgeLengthInvariant.hpp
MinEdgeLengthInvariant.cpp
MinIncidentValenceInvariant.hpp
MinIncidentValenceInvariant.cpp
TriangleInversionInvariant.hpp
TriangleInversionInvariant.cpp
TodoInvariant.hpp
Expand Down
46 changes: 46 additions & 0 deletions src/wmtk/invariants/MinIncidentValenceInvariant.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "MinIncidentValenceInvariant.hpp"

#include <wmtk/Mesh.hpp>
#include <wmtk/simplex/link.hpp>

namespace wmtk::invariants {


MinIncidentValenceInvariant::MinIncidentValenceInvariant(const Mesh& m, long min_valence)
: MeshInvariant(m)
, m_min_valence(min_valence)
{}

bool MinIncidentValenceInvariant::before(const Tuple& t) const
{
return is_greater_min_valence(t);
}

bool MinIncidentValenceInvariant::after(PrimitiveType type, const std::vector<Tuple>& t) const
{
if (type == PrimitiveType::Edge) {
for (const Tuple& e : t) {
if (!is_greater_min_valence(e)) {
return false;
}
}
}

return true;
}

bool MinIncidentValenceInvariant::is_greater_min_valence(const Tuple& t) const
{
using namespace simplex;

const Simplex v0 = Simplex::vertex(t);
const Simplex v1 = Simplex::vertex(mesh().switch_vertex(t));
const long val0 =
static_cast<long>(link(mesh(), v0).simplex_vector(PrimitiveType::Vertex).size());
const long val1 =
static_cast<long>(link(mesh(), v1).simplex_vector(PrimitiveType::Vertex).size());

return val0 >= m_min_valence && val1 >= m_min_valence;
}

} // namespace wmtk::invariants
23 changes: 23 additions & 0 deletions src/wmtk/invariants/MinIncidentValenceInvariant.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include <wmtk/attribute/AttributeHandle.hpp>
#include "MeshInvariant.hpp"

namespace wmtk::invariants {
/**
* Invariant for minimum valence on both incident vertices of an edge.
*/
class MinIncidentValenceInvariant : public MeshInvariant
{
public:
MinIncidentValenceInvariant(const Mesh& m, long min_valence);
using MeshInvariant::MeshInvariant;
bool before(const Tuple& t) const override;
bool after(PrimitiveType type, const std::vector<Tuple>& t) const override;

private:
bool is_greater_min_valence(const Tuple& t) const;

long m_min_valence;
};
} // namespace wmtk::invariants
6 changes: 4 additions & 2 deletions src/wmtk/operations/tri_mesh/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ set(SRC_FILES
EdgeCollapse.cpp
EdgeCollapseToMidpoint.hpp
EdgeCollapseToMidpoint.cpp
EdgeSwap.hpp
EdgeSwap.cpp
EdgeSwapBase.hpp
EdgeSwapBase.cpp
EdgeSwapValence.hpp
EdgeSwapValence.cpp
VertexSmoothUsingDifferentiableEnergy.hpp
VertexSmoothUsingDifferentiableEnergy.cpp
EdgeSplitWithTag.hpp
Expand Down
142 changes: 0 additions & 142 deletions src/wmtk/operations/tri_mesh/EdgeSwap.cpp

This file was deleted.

100 changes: 100 additions & 0 deletions src/wmtk/operations/tri_mesh/EdgeSwapBase.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include "EdgeSwapBase.hpp"
#include <wmtk/SimplicialComplex.hpp>
#include <wmtk/TriMesh.hpp>
#include <wmtk/invariants/InteriorEdgeInvariant.hpp>

#include "EdgeCollapse.hpp"
#include "EdgeSplit.hpp"

namespace wmtk::operations {
void OperationSettings<tri_mesh::EdgeSwapBase>::initialize_invariants(const TriMesh& m)
{
// outdated + is valid tuple
invariants = basic_invariant_collection(m);
invariants.add(std::make_shared<InteriorEdgeInvariant>(m));

collapse_settings.initialize_invariants(m);
split_settings.initialize_invariants(m);
}


namespace tri_mesh {
EdgeSwapBase::EdgeSwapBase(Mesh& m, const Tuple& t, const OperationSettings<EdgeSwapBase>& settings)
: TriMeshOperation(m)
, TupleOperation(settings.invariants, t)
, m_settings{settings}
{}

std::string EdgeSwapBase::name() const
{
return "tri_mesh_edge_swap_base";
}

Tuple EdgeSwapBase::return_tuple() const
{
return m_output_tuple;
}

bool EdgeSwapBase::execute()
{
// input
// / \
// / \
// / f \
// X--->---
// \ /
// \ /
// \ /

Tuple split_ret;
{
tri_mesh::EdgeSplit split_op(mesh(), input_tuple(), m_settings.split_settings);
if (!split_op()) {
return false;
}
split_ret = split_op.return_tuple();
}
// after split
// /|\
// / | \
// / | f\
// ---X-->
// \ | /
// \ | /
// \|/

// switch also face to keep edge orientation
const Tuple coll_input_tuple = mesh().switch_face(mesh().switch_edge(split_ret));
// switch edge - switch face
// /|\
// / ^ \
// /f | \
// ---X---
// \ | /
// \ | /
// \|/
Tuple coll_ret;
{
tri_mesh::EdgeCollapse coll_op(mesh(), coll_input_tuple, m_settings.collapse_settings);
if (!coll_op()) {
return false;
}
coll_ret = coll_op.return_tuple();
}
// collapse output
// X
// /|\
// < | \
// / | \
// | f | |
// \ | /
// \ | /
// \|/
// adjust return tuple to be the swapped edge in the same orientation as the input
m_output_tuple = mesh().switch_vertex(mesh().switch_edge(coll_ret));

return true;
}

} // namespace tri_mesh
} // namespace wmtk::operations
Loading

0 comments on commit 44d169d

Please sign in to comment.