Wildmeshing Toolkit
trimesh_topology_initialization.cpp
Go to the documentation of this file.
2 #include <algorithm>
3 #include <vector>
5 #include <wmtk/utils/Logger.hpp>
6 
7 namespace wmtk {
8 
9 
10 std::tuple<RowVectors3l, RowVectors3l, VectorXl, VectorXl> trimesh_topology_initialization(
11  Eigen::Ref<const RowVectors3l> F)
12 {
13  RowVectors3l FE, FF;
14  VectorXl VF, EF;
15 
16  // Make sure there are 3 columns
17  assert(F.cols() == 3);
18 
19  char iv0 = 0;
20  char iv1 = 1;
21  char it = 2;
22  char ii = 3;
23 
24  std::vector<std::vector<int64_t>> TTT;
25 
26  int64_t vertex_count = F.maxCoeff() + 1;
27 
28  // Build a table for finding Faces and populate the corresponding
29  // topology relations
30  {
31  TTT.resize(F.rows() * 3);
32  for (int t = 0; t < F.rows(); ++t) {
33  for (int i = 0; i < 3; ++i) {
34  // v1 v2 v3 f ei
35  const auto& [f0, f1] = wmtk::autogen::tri_mesh::auto_2d_edges[i];
36  int64_t x = F(t, f0);
37  int64_t y = F(t, f1);
38  if (x > y) std::swap(x, y);
39 
40  std::vector<int64_t> r(4);
41  r[iv0] = x;
42  r[iv1] = y;
43  r[it] = t;
44  r[ii] = i;
45  TTT[t * 3 + i] = r;
46  }
47  }
48  std::sort(TTT.begin(), TTT.end());
49 
50  // VF
51  VF = VectorXl::Constant(vertex_count, 1, -1);
52  for (int i = 0; i < F.rows(); ++i) {
53  for (int j = 0; j < 3; ++j) {
54  VF[F(i, j)] = i;
55  }
56  }
57 
58  // Compute FE, FF, EF
59  FE.resize(F.rows(), 3);
60  FF.resize(F.rows(), 3);
61  std::vector<int64_t> EF_temp;
62 
63  // iterate over TTT to find faces
64  // for every entry check if the next is the same, and update the connectivity accordingly
65 
66  for (int i = 0; i < TTT.size(); ++i) {
67  if ((i == (TTT.size() - 1)) || (TTT[i][0] != TTT[i + 1][0]) ||
68  (TTT[i][1] != TTT[i + 1][1])) {
69  // If the next tuple is empty, then this is a boundary edge
70  EF_temp.push_back(TTT[i][it]);
71 
72  FF(TTT[i][it], TTT[i][ii]) = -1;
73  FE(TTT[i][it], TTT[i][ii]) = EF_temp.size() - 1;
74  } else {
75  // this is an internal edge, update both sides
76  EF_temp.push_back(TTT[i][it]);
77 
78  FF(TTT[i][it], TTT[i][ii]) = TTT[i + 1][it];
79  FE(TTT[i][it], TTT[i][ii]) = EF_temp.size() - 1;
80 
81  FF(TTT[i + 1][it], TTT[i + 1][ii]) = TTT[i][it];
82  FE(TTT[i + 1][it], TTT[i + 1][ii]) = EF_temp.size() - 1;
83 
84  ++i; // skip the other entry
85  }
86  }
87 
88  // copy EF
89  EF.resize(EF_temp.size());
90  for (int64_t i = 0; i < EF_temp.size(); ++i) EF(i) = EF_temp[i];
91  }
92 
93  return {FE, FF, VF, EF};
94 }
95 
96 } // namespace wmtk
const int64_t auto_2d_edges[3][2]
Definition: Accessor.hpp:6
RowVectors< int64_t, 3 > RowVectors3l
Definition: Types.hpp:47
VectorX< int64_t > VectorXl
Definition: Types.hpp:33
std::tuple< RowVectors3l, RowVectors3l, VectorXl, VectorXl > trimesh_topology_initialization(Eigen::Ref< const RowVectors3l > F)