Wildmeshing Toolkit
SimplexInversionInvariant.cpp
Go to the documentation of this file.
2 #include <wmtk/EdgeMesh.hpp>
3 #include <wmtk/Mesh.hpp>
4 #include <wmtk/TetMesh.hpp>
5 #include <wmtk/TriMesh.hpp>
7 #include <wmtk/utils/Logger.hpp>
8 #include <wmtk/utils/orient.hpp>
10 
11 namespace wmtk {
12 
13 template <typename T>
15  const Mesh& m,
16  const TypedAttributeHandle<T>& coordinate)
17  : Invariant(m, true, false, true)
18  , m_coordinate_handle(coordinate)
19 {}
20 
21 template <typename T>
23  const std::vector<Tuple>&,
24  const std::vector<Tuple>& top_dimension_tuples_after) const
25 {
26  if (mesh().top_simplex_type() == PrimitiveType::Tetrahedron) {
27  const TetMesh& mymesh = static_cast<const TetMesh&>(mesh());
28  const auto accessor = mymesh.create_const_accessor(m_coordinate_handle);
29  assert(accessor.dimension() == 3);
30 
31  for (const auto& t : top_dimension_tuples_after) {
32  const auto tet_vertices = mymesh.orient_vertices(t);
33  assert(tet_vertices.size() == 4);
34  const Eigen::Vector3<T> p0 = accessor.const_vector_attribute(tet_vertices[0]);
35  const Eigen::Vector3<T> p1 = accessor.const_vector_attribute(tet_vertices[1]);
36  const Eigen::Vector3<T> p2 = accessor.const_vector_attribute(tet_vertices[2]);
37  const Eigen::Vector3<T> p3 = accessor.const_vector_attribute(tet_vertices[3]);
38 
39  if (utils::wmtk_orient3d(p0, p1, p2, p3) <= 0) {
40  wmtk::logger().debug(
41  "fail inversion check, volume = {}",
42  utils::wmtk_orient3d(p0, p1, p2, p3));
43  return false;
44  }
45 
46  // const Eigen::Vector3<T> p0 = accessor.const_vector_attribute(t);
47  // const Eigen::Vector3<T> p1 =
48  // accessor.const_vector_attribute(mymesh.switch_tuple(t, PrimitiveType::Vertex));
49  // const Eigen::Vector3<T> p2 = accessor.const_vector_attribute(
50  // mymesh.switch_tuples(t, {PrimitiveType::Edge, PrimitiveType::Vertex}));
51  // const Eigen::Vector3<T> p3 = accessor.const_vector_attribute(mymesh.switch_tuples(
52  // t,
53  // {PrimitiveType::Triangle, PrimitiveType::Edge, PrimitiveType::Vertex}));
54 
55  // if (mymesh.is_ccw(t)) {
56  // if (utils::wmtk_orient3d(p3, p0, p1, p2) <= 0) return false;
57  // } else {
58  // if (utils::wmtk_orient3d(p3, p0, p2, p1) <= 0) return false;
59  // }
60  }
61 
62  return true;
63 
64  } else if (mesh().top_simplex_type() == PrimitiveType::Triangle) {
65  const TriMesh& mymesh = static_cast<const TriMesh&>(mesh());
66  const auto accessor = mymesh.create_const_accessor(m_coordinate_handle);
67  assert(accessor.dimension() == 2);
68 
69  for (const Tuple& tuple : top_dimension_tuples_after) {
70  Tuple ccw_tuple = tuple;
71  if (!mymesh.is_ccw(tuple)) {
72  ccw_tuple = mymesh.switch_tuple(tuple, PrimitiveType::Vertex);
73  }
74  const Eigen::Vector2<T> p0 = accessor.const_vector_attribute(ccw_tuple);
75  const Eigen::Vector2<T> p1 = accessor.const_vector_attribute(
76  mymesh.switch_tuple(ccw_tuple, PrimitiveType::Vertex));
77  const Eigen::Vector2<T> p2 = accessor.const_vector_attribute(
78  mymesh.switch_tuples(ccw_tuple, {PrimitiveType::Edge, PrimitiveType::Vertex}));
79 
80  if (utils::wmtk_orient2d(p0, p1, p2) <= 0) return false;
81  }
82 
83  return true;
84  } else if (mesh().top_simplex_type() == PrimitiveType::Edge) {
85  const EdgeMesh& mymesh = static_cast<const EdgeMesh&>(mesh());
86  const auto accessor = mymesh.create_const_accessor(m_coordinate_handle);
87  assert(accessor.dimension() == 1);
88 
89  for (const Tuple& tuple : top_dimension_tuples_after) {
90  T p0 = accessor.const_scalar_attribute(tuple);
91  T p1 =
92  accessor.const_scalar_attribute(mymesh.switch_tuple(tuple, PrimitiveType::Vertex));
93 
94  if (utils::wmtk_orient1d(p0, 01) >= 0) return false;
95  }
96 
97  return true;
98  }
99 
100  return true;
101 }
102 
103 template class SimplexInversionInvariant<double>;
105 
106 } // namespace wmtk
Tuple switch_tuple(const Tuple &tuple, PrimitiveType type) const override
switch the orientation of the Tuple of the given dimension
Definition: EdgeMesh.cpp:38
const attribute::Accessor< T, Derived, Dim > create_const_accessor(const attribute::TypedAttributeHandle< T > &handle) const
constructs a const accessor that is aware of the derived mesh's type
Definition: MeshCRTP.hpp:74
Tuple switch_tuples(const Tuple &tuple, const ContainerType &op_sequence) const
Performs a sequence of switch_tuple operations in the order specified in op_sequence.
Definition: MeshCRTP.hpp:135
SimplexInversionInvariant(const Mesh &m, const TypedAttributeHandle< T > &coordinate)
bool after(const std::vector< Tuple > &, const std::vector< Tuple > &top_dimension_tuples_after) const override
we assume with local vid order (v0,v1,v2,v3) has positive volume (orient3d(v0,v1,v2,...
std::vector< Tuple > orient_vertices(const Tuple &t) const override
Definition: TetMesh.cpp:614
Tuple switch_tuple(const Tuple &tuple, PrimitiveType type) const final override
switch the orientation of the Tuple of the given dimension
Definition: TriMesh.cpp:99
bool is_ccw(const Tuple &tuple) const final override
TODO this needs dimension?
Definition: TriMesh.cpp:170
Handle that represents attributes for some mesh.
int wmtk_orient3d(const Eigen::Ref< const Eigen::Vector3< Rational >> &p0, const Eigen::Ref< const Eigen::Vector3< Rational >> &p1, const Eigen::Ref< const Eigen::Vector3< Rational >> &p2, const Eigen::Ref< const Eigen::Vector3< Rational >> &p3)
Definition: orient.cpp:75
int wmtk_orient1d(const Rational &p0, const Rational &p1)
Definition: orient.cpp:267
int wmtk_orient2d(double p0x, double p0y, double p1x, double p1y, double p2x, double p2y)
Definition: orient.cpp:178
Definition: Accessor.hpp:6
spdlog::logger & logger()
Retrieves the current logger.
Definition: Logger.cpp:58