PhysicsBasedAnimationToolkit 0.0.10
Cross-platform C++20 library of algorithms and data structures commonly used in computer graphics research on physically-based simulation.
Loading...
Searching...
No Matches
Mesh.h
Go to the documentation of this file.
1
9
10#ifndef PBAT_GRAPH_MESH_H
11#define PBAT_GRAPH_MESH_H
12
13#include "pbat/Aliases.h"
16
17namespace pbat {
18namespace graph {
19
37template <
38 class TDerivedE,
39 class TDerivedW,
40 common::CIndex TIndex = typename TDerivedE::Scalar,
41 common::CArithmetic TScalar = typename TDerivedW::Scalar>
43 Eigen::DenseBase<TDerivedE> const& E,
44 Eigen::DenseBase<TDerivedW> const& w,
45 TIndex nNodes = TIndex(-1),
46 bool bVertexToElement = false,
47 bool bHasDuplicates = false) -> Eigen::SparseMatrix<TScalar, Eigen::ColMajor, TIndex>
48{
49 PBAT_PROFILE_NAMED_SCOPE("pbat.graph.MeshAdjacencyMatrix");
50 if (nNodes < 0)
51 nNodes = E.maxCoeff() + TIndex(1);
52
53 using AdjacencyMatrix = Eigen::SparseMatrix<TScalar, Eigen::ColMajor, TIndex>;
54 AdjacencyMatrix G(nNodes, E.cols());
55 using IndexVectorType = Eigen::Vector<TIndex, Eigen::Dynamic>;
56 if (not bHasDuplicates)
57 {
58 G.reserve(IndexVectorType::Constant(E.cols(), static_cast<TIndex>(E.rows())));
59 for (auto e = 0; e < E.cols(); ++e)
60 for (auto i = 0; i < E.rows(); ++i)
61 G.insert(E(i, e), e) = w(i, e);
62 }
63 else
64 {
65 using Triplet = Eigen::Triplet<TScalar, TIndex>;
66 std::vector<Triplet> triplets{};
67 triplets.reserve(static_cast<std::size_t>(E.rows() * E.cols()));
68 for (auto e = 0; e < E.cols(); ++e)
69 for (auto i = 0; i < E.rows(); ++i)
70 triplets.emplace_back(E(i, e), e, w(i, e));
71 G.setFromTriplets(triplets.begin(), triplets.end());
72 }
73 if (bVertexToElement)
74 G = G.transpose();
75 return G;
76}
77
90template <class TDerivedE, common::CIndex TIndex = typename TDerivedE::Scalar>
92 Eigen::DenseBase<TDerivedE> const& E,
93 TIndex nNodes = TIndex(-1),
94 bool bVertexToElement = false,
95 bool bHasDuplicates = false) -> Eigen::SparseMatrix<TIndex, Eigen::ColMajor, TIndex>
96{
97 using WeightMatrixType = Eigen::Matrix<TIndex, Eigen::Dynamic, Eigen::Dynamic>;
99 E,
100 WeightMatrixType::Ones(E.rows(), E.cols()),
101 nNodes,
102 bVertexToElement,
103 bHasDuplicates);
104}
105
116template <class TDerivedE, common::CIndex TIndex = typename TDerivedE::Scalar>
117auto MeshPrimalGraph(Eigen::DenseBase<TDerivedE> const& E, TIndex nNodes = TIndex(-1))
118 -> Eigen::SparseMatrix<TIndex, Eigen::ColMajor, TIndex>
119{
120 PBAT_PROFILE_NAMED_SCOPE("pbat.graph.MeshPrimalGraph");
121 auto const G = MeshAdjacencyMatrix(E, nNodes);
122 return G * G.transpose();
123}
124
128enum class EMeshDualGraphOptions : std::int32_t {
129 VertexAdjacent = 0b001,
130 EdgeAdjacent = 0b010,
131 FaceAdjacent = 0b100,
132 All = 0b111
133};
134
146template <class TDerivedE, common::CIndex TIndex = typename TDerivedE::Scalar>
148 Eigen::DenseBase<TDerivedE> const& E,
149 TIndex nNodes = TIndex(-1),
150 EMeshDualGraphOptions opts = EMeshDualGraphOptions::All)
151 -> Eigen::SparseMatrix<TIndex, Eigen::ColMajor, TIndex>
152{
153 PBAT_PROFILE_NAMED_SCOPE("pbat.graph.MeshDualGraph");
154 auto const G = MeshAdjacencyMatrix(E, nNodes);
155 using SparseMatrixType = Eigen::SparseMatrix<TIndex, Eigen::ColMajor, TIndex>;
156 SparseMatrixType GTG = G.transpose() * G;
157 if (opts == EMeshDualGraphOptions::All)
158 return GTG;
159 auto flags = static_cast<std::int32_t>(opts);
160 bool const bKeepFaceAdjacencies =
161 flags & static_cast<std::int32_t>(EMeshDualGraphOptions::FaceAdjacent);
162 bool const bKeepEdgeAdjacencies =
163 flags & static_cast<std::int32_t>(EMeshDualGraphOptions::EdgeAdjacent);
164 bool const bKeepVertexAdjacencies =
165 flags & static_cast<std::int32_t>(EMeshDualGraphOptions::VertexAdjacent);
166 auto const fKeepAdjacency =
167 [=]([[maybe_unused]] auto row, [[maybe_unused]] auto col, auto degree) {
168 bool const bKeep = (degree == 3 and bKeepFaceAdjacencies) or
169 (degree == 2 and bKeepEdgeAdjacencies) or
170 (degree == 1 and bKeepVertexAdjacencies);
171 return bKeep;
172 };
173 GTG.prune(fKeepAdjacency);
174 return GTG;
175}
176
177} // namespace graph
178} // namespace pbat
179
180#endif // PBAT_GRAPH_MESH_H
Concepts for common types.
Definition Adjacency.h:24
EMeshDualGraphOptions
Types of dual graph adjacencies.
Definition Mesh.h:128
auto MeshAdjacencyMatrix(Eigen::DenseBase< TDerivedE > const &E, Eigen::DenseBase< TDerivedW > const &w, TIndex nNodes=TIndex(-1), bool bVertexToElement=false, bool bHasDuplicates=false) -> Eigen::SparseMatrix< TScalar, Eigen::ColMajor, TIndex >
Construct adjacency matrix from mesh.
Definition Mesh.h:42
auto MeshPrimalGraph(Eigen::DenseBase< TDerivedE > const &E, TIndex nNodes=TIndex(-1)) -> Eigen::SparseMatrix< TIndex, Eigen::ColMajor, TIndex >
Construct primal graph of input mesh, i.e. the graph of adjacent vertices.
Definition Mesh.h:117
auto MeshDualGraph(Eigen::DenseBase< TDerivedE > const &E, TIndex nNodes=TIndex(-1), EMeshDualGraphOptions opts=EMeshDualGraphOptions::All) -> Eigen::SparseMatrix< TIndex, Eigen::ColMajor, TIndex >
Construct dual graph of input mesh, i.e. the graph of adjacent elements.
Definition Mesh.h:147
The main namespace of the library.
Definition Aliases.h:15
Profiling utilities for the Physics-Based Animation Toolkit (PBAT)