Guest User

Untitled

a guest
Mar 5th, 2018
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.98 KB | None | 0 0
  1. template <typename DerivedTV,
  2.           typename DerivedTT,
  3.           typename Derivedisovalues,
  4.           typename DerivedoutV,
  5.           typename DerivedoutF>
  6. void igl::marching_tets_4(
  7.         const Eigen::PlainObjectBase<DerivedTV>& TV,
  8.         const Eigen::PlainObjectBase<DerivedTT>& TT,
  9.         const Eigen::PlainObjectBase<Derivedisovalues>& isovals,
  10.         double isovalue,
  11.         Eigen::PlainObjectBase<DerivedoutV>& outV,
  12.         Eigen::PlainObjectBase<DerivedoutF>& outF) {
  13.  
  14.     const int mt_cell_lookup[16][4] = {
  15.         { -1, -1, -1, -1 }, // 0000 0a
  16.         {  0,  2,  1, -1 }, // 0001 1a
  17.         {  0,  3,  4, -1 }, // 0010 1b
  18.         {  2,  1,  3,  4 }, // 0011 2b
  19.         {  5,  3,  1, -1 }, // 0100 1d
  20.         {  0,  2,  5,  3 }, // 0101 2a
  21.         {  0,  1,  5,  4 }, // 0110 2d
  22.         {  2,  5,  4, -1 }, // 0111 3a
  23.         {  4,  5,  2, -1 }, // 1000 1c
  24.         {  0,  4,  5,  1 }, // 1001 2c
  25.         {  0,  3,  5,  2 }, // 1010 2f
  26.         {  1,  3,  5, -1 }, // 1011 3d
  27.         {  4,  3,  1,  2 }, // 1100 2e
  28.         {  0,  4,  3, -1 }, // 1101 3c
  29.         {  0,  1,  2, -1 }, // 1110 3b
  30.         { -1, -1, -1, -1 }, // 1111 0b
  31.     };
  32.  
  33.     const int mt_edge_lookup[6][2] = {
  34.         {0, 1},
  35.         {0, 2},
  36.         {0, 3},
  37.         {1, 2},
  38.         {1, 3},
  39.         {2, 3},
  40.     };
  41.  
  42.     typedef std::pair<int, int> Edge;
  43.     std::vector<Eigen::RowVector3i> faces;
  44.     std::vector<std::pair<Edge, int>> all_edges;
  45.  
  46.     auto make_edge = [](int v1, int v2) {
  47.         return std::make_pair(std::min(v1, v2), std::max(v1, v2));
  48.     };
  49.  
  50.     assert(TT.rows() == 4);
  51.     assert(TV.rows() == 3);
  52.     assert(isovals.rows() == 1);
  53.  
  54.     static_assert(sizeof(std::int64_t) == 2*sizeof(std::int32_t), "need to fit 2 ints into a size_t");
  55.  
  56.     // For each tet
  57.     for (int i = 0; i < TT.rows(); i++) {
  58.         uint8_t key = 0;
  59.         for (int v = 0; v < 4; v++) {
  60.             int vid = TT(i, v);
  61.             uint8_t flag = isovals[vid] > isovalue;
  62.             key |= flag << v;
  63.         }
  64.  
  65.         // Insert the vertices if they don't exist
  66.         int v_ids[4] = {-1, -1, -1, -1}; // This will contain the index in TV of each vertex in the tet
  67.         for (int e = 0; e < 4 && mt_cell_lookup[key][e] != -1; ++e) {
  68.             int v1id = mt_edge_lookup[mt_cell_lookup[key][e]][0];
  69.             int v2id = mt_edge_lookup[mt_cell_lookup[key][e]][1];
  70.             int v1 = TT(i, v1id);
  71.             int v2 = TT(i, v2id);
  72.             v_ids[e] = all_edges.size();
  73.             all_edges.emplace_back(make_edge(v1, v2), v_ids[e]);
  74.         }
  75.         if (v_ids[0] != -1) {
  76.             bool is_quad = mt_cell_lookup[key][3] != -1;
  77.             if (is_quad) {
  78.                 Eigen::RowVector3i f1(v_ids[0], v_ids[1], v_ids[3]);
  79.                 Eigen::RowVector3i f2(v_ids[1], v_ids[2], v_ids[3]);
  80.                 faces.push_back(f1);
  81.                 faces.push_back(f2);
  82.             } else {
  83.                 Eigen::RowVector3i f(v_ids[0], v_ids[1], v_ids[2]);
  84.                 faces.push_back(f);
  85.             }
  86.         }
  87.     }
  88.  
  89.     // Dedup vertices
  90.     Eigen::VectorXi remap(all_edges.size());
  91.     std::sort(all_edges.begin(), all_edges.end());
  92.     Edge prev(-1, -1);
  93.     int num_vertices = -1;
  94.     for (auto &kv : all_edges) {
  95.         if (prev != kv.first) { ++num_vertices; }
  96.         remap(kv.second) = num_vertices;
  97.         prev = kv.first;
  98.     }
  99.     ++num_vertices;
  100.  
  101.     // Assign final mesh
  102.     outV.resize(num_vertices, 3);
  103.     outF.resize(faces.size(), 3);
  104.     for (auto &kv : all_edges) {
  105.         int v1 = kv.first.first;
  106.         int v2 = kv.first.second;
  107.         Eigen::RowVector3d p1 = TV.row(v1);
  108.         Eigen::RowVector3d p2 = TV.row(v2);
  109.         auto s0 = fabs(isovals[v1] - isovalue);
  110.         auto s1 = fabs(isovals[v2] - isovalue);
  111.         auto t  = s0 / (s0+s1);
  112.         outV.row(remap(kv.second)) = ((1.0f-t)*p1 + t*p2);
  113.     }
  114.     for (int i = 0; i < faces.size(); i++) {
  115.         outF.row(i) = faces[i].unaryExpr([&](int v) { return remap(v); });
  116.     }
  117. }
Advertisement
Add Comment
Please, Sign In to add comment