MCPcopy Create free account
hub / github.com/PyMesh/PyMesh / remove_line_faces

Method remove_line_faces

tools/MeshUtils/DegeneratedTriangleRemoval.cpp:78–172  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

76}
77
78size_t DegeneratedTriangleRemoval::remove_line_faces() {
79 init_edge_map();
80 // loop through faces, check if a face is a colinear.
81 // If so, flip the longest edge.
82
83 auto comp = [&](const Duplet& e1, const Duplet& e2) -> bool{
84 // Return true if e1 is longer than e2.
85 auto v1 = m_vertices.row(e1.get_ori_data()[0]);
86 auto v2 = m_vertices.row(e1.get_ori_data()[1]);
87 auto v3 = m_vertices.row(e2.get_ori_data()[0]);
88 auto v4 = m_vertices.row(e2.get_ori_data()[1]);
89 return (v1-v2).squaredNorm() > (v3-v4).squaredNorm();
90 };
91
92 const size_t num_faces = m_faces.rows();
93 std::set<Duplet, decltype(comp)> edges_to_remove(comp);
94 std::vector<size_t> longest_edges(num_faces, INVALID);
95 for (size_t fi=0; fi<num_faces; fi++) {
96 if (!is_degenerated(fi)) continue;
97 const auto& face = m_faces.row(fi);
98 const auto fi_opp_v = find_longest_edge(fi);
99 const auto vi_0 = face[(fi_opp_v+1)%3];
100 const auto vi_1 = face[(fi_opp_v+2)%3];
101 edges_to_remove.insert(Duplet{vi_0, vi_1});
102 longest_edges[fi] = fi_opp_v;
103 }
104
105 std::vector<VectorI> new_faces;
106 std::vector<VectorI::Scalar> new_ori_face_indices;
107 std::vector<bool> is_valid(num_faces, true);
108 size_t count = 0;
109
110 for (auto& edge : edges_to_remove) {
111 auto& neighboring_faces = m_edge_map[edge];
112 bool all_valid = true;
113 for (auto fj : neighboring_faces) { all_valid &= is_valid[fj]; }
114 if (!all_valid) continue;
115
116 const size_t vi_0 = edge.get_ori_data()[0];
117 const size_t vi_1 = edge.get_ori_data()[1];
118 size_t vi_opp = INVALID;
119 size_t fi = INVALID;
120 for (auto fj : neighboring_faces) {
121 if (longest_edges[fj] == INVALID) continue;
122 const auto neighbor_face = m_faces.row(fj);
123 const size_t vj_opp = neighbor_face[longest_edges[fj]];
124 if (vj_opp != vi_0 && vj_opp != vi_1) {
125 fi = fj;
126 vi_opp = vj_opp;
127 break;
128 }
129 }
130 assert(vi_opp != INVALID);
131 assert(fi != INVALID);
132
133 for (auto fj : neighboring_faces) {
134 is_valid[fj] = false;
135 if (fj == fi) continue;

Callers

nothing calls this directly

Calls 3

insertMethod · 0.45
emptyMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected