PolyFEM
Loading...
Searching...
No Matches
OperationCache.cpp
Go to the documentation of this file.
1#include "OperationCache.hpp"
2
3namespace polyfem::mesh
4{
5 namespace
6 {
7 void insert_edges_of_face(
10 WildTriRemesher::EdgeMap<TriOperationCache::EdgeAttributes> &edge_map)
11 {
12 for (auto i = 0; i < 3; i++)
13 {
14 WildTriRemesher::Tuple e = m.tuple_from_edge(t.fid(m), i);
15 const size_t v0 = e.vid(m);
16 const size_t v1 = e.switch_vertex(m).vid(m);
17 edge_map[{{v0, v1}}] = m.boundary_attrs[e.eid(m)];
18 }
19 }
20
21 void insert_edges_of_tet(
24 WildTriRemesher::EdgeMap<TetOperationCache::EdgeAttributes> &edge_map)
25 {
26 for (auto i = 0; i < 6; i++)
27 {
28 WildTetRemesher::Tuple e = m.tuple_from_edge(t.tid(m), i);
29 const size_t v0 = e.vid(m);
30 const size_t v1 = e.switch_vertex(m).vid(m);
31 edge_map[{{v0, v1}}] = m.edge_attr(e.eid(m));
32 }
33 }
34
35 void insert_faces_of_tet(
38 WildTetRemesher::FaceMap<TetOperationCache::FaceAttributes> &face_map)
39 {
40 for (auto i = 0; i < 4; i++)
41 {
42 WildTetRemesher::Tuple f = m.tuple_from_face(t.tid(m), i);
43 std::array<WildTetRemesher::Tuple, 3> vs = m.get_face_vertices(f);
44 face_map[{{vs[0].vid(m), vs[1].vid(m), vs[2].vid(m)}}] = m.boundary_attrs[f.fid(m)];
45 }
46 }
47 } // namespace
48
49 std::shared_ptr<TriOperationCache> TriOperationCache::split_edge(WildTriRemesher &m, const Tuple &t)
50 {
51 std::shared_ptr<TriOperationCache> cache = std::make_shared<TriOperationCache>();
52
53 cache->m_v0.first = t.vid(m);
54 cache->m_v1.first = t.switch_vertex(m).vid(m);
55
56 cache->m_v0.second = m.vertex_attrs[cache->m_v0.first];
57 cache->m_v1.second = m.vertex_attrs[cache->m_v1.first];
58
59 insert_edges_of_face(m, t, cache->m_edges);
60 cache->m_faces.push_back(m.element_attrs[t.fid(m)]);
61
62 if (t.switch_face(m))
63 {
64 const Tuple t1 = t.switch_face(m).value();
65 insert_edges_of_face(m, t1, cache->m_edges);
66 cache->m_faces.push_back(m.element_attrs[t1.fid(m)]);
67 }
68
69 cache->m_is_boundary_op = m.is_boundary_edge(t);
70
71 return cache;
72 }
73
74 std::shared_ptr<TriOperationCache> TriOperationCache::collapse_edge(WildTriRemesher &m, const Tuple &t)
75 {
76 std::shared_ptr<TriOperationCache> cache = std::make_shared<TriOperationCache>();
77
78 cache->m_v0.first = t.vid(m);
79 cache->m_v1.first = t.switch_vertex(m).vid(m);
80
81 cache->m_v0.second = m.vertex_attrs[cache->m_v0.first];
82 cache->m_v1.second = m.vertex_attrs[cache->m_v1.first];
83
84 // Cache all edges of the faces in the one-ring of the edge
85 std::vector<Tuple> edge_one_ring_faces = m.get_one_ring_tris_for_vertex(t);
86 const std::vector<Tuple> tmp = m.get_one_ring_tris_for_vertex(t.switch_vertex(m));
87 edge_one_ring_faces.reserve(edge_one_ring_faces.size() + tmp.size());
88 edge_one_ring_faces.insert(edge_one_ring_faces.end(), tmp.begin(), tmp.end());
89
90 for (const auto &face : edge_one_ring_faces)
91 {
92 insert_edges_of_face(m, face, cache->m_edges);
93 }
94
95 // Cache the faces adjacent to the edge
96 cache->m_faces.push_back(m.element_attrs[t.fid(m)]);
97 if (t.switch_face(m))
98 cache->m_faces.push_back(m.element_attrs[t.switch_face(m)->fid(m)]);
99
100 cache->m_is_boundary_op = m.is_boundary_edge(t);
101
102 return cache;
103 }
104
105 std::shared_ptr<TriOperationCache> TriOperationCache::swap_edge(WildTriRemesher &m, const Tuple &t)
106 {
107 std::shared_ptr<TriOperationCache> cache = std::make_shared<TriOperationCache>();
108
109 cache->m_v0.first = t.vid(m);
110 cache->m_v1.first = t.switch_vertex(m).vid(m);
111
112 cache->m_v0.second = m.vertex_attrs[cache->m_v0.first];
113 cache->m_v1.second = m.vertex_attrs[cache->m_v1.first];
114
115 insert_edges_of_face(m, t, cache->m_edges);
116 cache->m_faces.push_back(m.element_attrs[t.fid(m)]);
117
118 assert(t.switch_face(m));
119 const Tuple t1 = t.switch_face(m).value();
120 insert_edges_of_face(m, t1, cache->m_edges);
121 cache->m_faces.push_back(m.element_attrs[t1.fid(m)]);
122
123 cache->m_is_boundary_op = m.is_boundary_edge(t);
124
125 return cache;
126 }
127
128 std::shared_ptr<TetOperationCache> TetOperationCache::split_edge(WildTetRemesher &m, const Tuple &e)
129 {
130 std::shared_ptr<TetOperationCache> cache = std::make_shared<TetOperationCache>();
131
132 cache->m_v0.first = e.vid(m);
133 cache->m_v1.first = e.switch_vertex(m).vid(m);
134
135 cache->m_v0.second = m.vertex_attrs[cache->m_v0.first];
136 cache->m_v1.second = m.vertex_attrs[cache->m_v1.first];
137
138 const std::vector<Tuple> tets = m.get_incident_tets_for_edge(e);
139 assert(tets.size() >= 1);
140 cache->m_tets.reserve(tets.size());
141 for (const Tuple &t : tets)
142 {
143 insert_edges_of_tet(m, t, cache->m_edges);
144 insert_faces_of_tet(m, t, cache->m_faces);
145 cache->m_tets[m.oriented_tet_vids(t)] = m.element_attrs[t.tid(m)];
146 }
147
148 cache->m_is_boundary_op = m.is_boundary_edge(e);
149
150 return cache;
151 }
152
153 std::shared_ptr<TetOperationCache> TetOperationCache::collapse_edge(WildTetRemesher &m, const Tuple &e)
154 {
155 std::shared_ptr<TetOperationCache> cache = std::make_shared<TetOperationCache>();
156
157 cache->m_v0.first = e.vid(m);
158 cache->m_v1.first = e.switch_vertex(m).vid(m);
159
160 cache->m_v0.second = m.vertex_attrs[cache->m_v0.first];
161 cache->m_v1.second = m.vertex_attrs[cache->m_v1.first];
162
163 const std::vector<Tuple> tets = m.get_one_ring_tets_for_edge(e);
164 assert(tets.size() >= 1);
165 cache->m_tets.reserve(tets.size());
166 for (const Tuple &t : tets)
167 {
168 insert_edges_of_tet(m, t, cache->m_edges);
169 insert_faces_of_tet(m, t, cache->m_faces);
170 cache->m_tets[m.oriented_tet_vids(t)] = m.element_attrs[t.tid(m)];
171 }
172
173 cache->m_is_boundary_op = m.is_boundary_edge(e);
174
175 return cache;
176 }
177} // namespace polyfem::mesh
std::unique_ptr< MatrixCache > cache
Definition Assembler.cpp:21
static std::shared_ptr< TetOperationCache > split_edge(WildTetRemesher &m, const Tuple &t)
static std::shared_ptr< TetOperationCache > collapse_edge(WildTetRemesher &m, const Tuple &t)
const Remesher::TetMap< TetAttributes > & tets() const
static std::shared_ptr< TriOperationCache > collapse_edge(WildTriRemesher &m, const Tuple &t)
static std::shared_ptr< TriOperationCache > split_edge(WildTriRemesher &m, const Tuple &t)
Construct a local mesh as an n-ring around a vertex.
static std::shared_ptr< TriOperationCache > swap_edge(WildTriRemesher &m, const Tuple &t)
wmtk::AttributeCollection< ElementAttributes > element_attrs
wmtk::AttributeCollection< VertexAttributes > vertex_attrs
bool is_boundary_edge(const Tuple &e) const
Is the given edge tuple on the boundary of the mesh?
WildRemesher< wmtk::TetMesh > WildTetRemesher
WildRemesher< wmtk::TriMesh > WildTriRemesher