8 #include "HalfEdgeTriangleMesh.h"
18 #include <Eigen/Dense>
24 #include <unordered_map>
36 vertex_indices_(vertex_indices),
37 triangle_index_(triangle_index) {}
53 int next_he_index = curr_he.
next_;
55 int next_next_he_index = next_he.
next_;
57 int next_next_twin_he_index = next_next_he.
twin_;
58 return next_next_twin_he_index;
70 std::vector<int> boundary_half_edge_indices;
71 int curr_he_index = init_he_index;
72 boundary_half_edge_indices.push_back(curr_he_index);
74 while (curr_he_index != init_he_index && curr_he_index != -1) {
75 boundary_half_edge_indices.push_back(curr_he_index);
78 return boundary_half_edge_indices;
83 std::vector<int> boundary_half_edges =
85 std::vector<int> boundary_vertices;
86 for (
const int &half_edge_idx : boundary_half_edges) {
87 boundary_vertices.push_back(
90 return boundary_vertices;
94 std::vector<std::vector<int>> boundaries;
95 std::unordered_set<int> visited;
97 for (
int vertex_ind = 0; vertex_ind < int(
vertices_.size()); ++vertex_ind) {
98 if (visited.find(vertex_ind) != visited.end()) {
105 if (
half_edges_[first_half_edge_ind].IsBoundary()) {
107 boundaries.push_back(boundary);
108 for (
int boundary_vertex : boundary) {
109 visited.insert(boundary_vertex);
112 visited.insert(vertex_ind);
118 int curr_half_edge_index)
const {
120 curr_half_edge_index == -1) {
122 "edge index {:d} out of range or half-edges not available.",
123 curr_half_edge_index);
126 if (!
half_edges_[curr_half_edge_index].IsBoundary()) {
128 "The currented half-edge index {:d} is on boundary.",
129 curr_half_edge_index);
138 if (!
half_edges_[next_half_edge_index].IsBoundary()) {
140 "[nextHalfEdgeOnBoundary] The next half-edge along the "
141 "boundary is not a boundary edge.");
144 return next_half_edge_index;
147 std::shared_ptr<HalfEdgeTriangleMesh>
150 assert(baseVertices);
151 auto mesh_cpy = std::make_shared<ccMesh>(baseVertices);
152 auto het_mesh = std::make_shared<HalfEdgeTriangleMesh>();
167 vertex_indices_to_half_edge_index;
169 for (
size_t triangle_index = 0; triangle_index < mesh_cpy->size();
171 const Eigen::Vector3i &triangle = mesh_cpy->getTriangle(triangle_index);
172 size_t num_half_edges = het_mesh->half_edges_.size();
174 size_t he_0_index = num_half_edges;
175 size_t he_1_index = num_half_edges + 1;
176 size_t he_2_index = num_half_edges + 2;
178 int(triangle_index),
int(he_1_index), -1);
180 int(triangle_index),
int(he_2_index), -1);
182 int(triangle_index),
int(he_0_index), -1);
185 vertex_indices_to_half_edge_index.end() ||
187 vertex_indices_to_half_edge_index.end() ||
189 vertex_indices_to_half_edge_index.end()) {
191 "ComputeHalfEdges failed. Duplicated half-edges.");
194 het_mesh->half_edges_.push_back(he_0);
195 het_mesh->half_edges_.push_back(he_1);
196 het_mesh->half_edges_.push_back(he_2);
204 for (
size_t this_he_index = 0; this_he_index < het_mesh->half_edges_.size();
206 HalfEdge &this_he = het_mesh->half_edges_[this_he_index];
209 if (this_he.
twin_ == -1 &&
210 vertex_indices_to_half_edge_index.find(twin_end_points) !=
211 vertex_indices_to_half_edge_index.end()) {
212 size_t twin_he_index =
213 vertex_indices_to_half_edge_index[twin_end_points];
214 HalfEdge &twin_he = het_mesh->half_edges_[twin_he_index];
215 this_he.
twin_ = int(twin_he_index);
216 twin_he.
twin_ = int(this_he_index);
222 std::vector<std::vector<int>> half_edges_from_vertex(
223 mesh_cpy->getVerticeSize());
224 for (
size_t half_edge_index = 0;
225 half_edge_index < het_mesh->half_edges_.size(); half_edge_index++) {
226 int src_vertex_index =
227 het_mesh->half_edges_[half_edge_index].vertex_indices_(0);
228 half_edges_from_vertex[src_vertex_index].push_back(
229 int(half_edge_index));
234 het_mesh->ordered_half_edge_from_vertex_.resize(mesh_cpy->getVerticeSize());
237 size_t num_boundaries = 0;
238 int init_half_edge_index = 0;
239 for (
const int &half_edge_index :
241 if (het_mesh->half_edges_[half_edge_index].IsBoundary()) {
243 init_half_edge_index = half_edge_index;
246 if (num_boundaries > 1) {
251 if (num_boundaries == 0) {
252 init_half_edge_index = half_edges_from_vertex[
vertex_index][0];
256 int curr_he_index = init_half_edge_index;
257 het_mesh->ordered_half_edge_from_vertex_[
vertex_index].push_back(
259 int next_next_twin_he_index =
260 het_mesh->nextHalfEdgeFromVertex(curr_he_index);
261 curr_he_index = next_next_twin_he_index;
262 while (curr_he_index != -1 && curr_he_index != init_half_edge_index) {
263 het_mesh->ordered_half_edge_from_vertex_[
vertex_index].push_back(
265 next_next_twin_he_index =
266 het_mesh->nextHalfEdgeFromVertex(curr_he_index);
267 curr_he_index = next_next_twin_he_index;
271 mesh_cpy->ComputeVertexNormals();
272 het_mesh->vertices_ = mesh_cpy->getEigenVertices();
273 het_mesh->vertex_normals_ = mesh_cpy->getVertexNormals();
274 het_mesh->vertex_colors_ = mesh_cpy->getVertexColors();
275 het_mesh->triangles_ = mesh_cpy->getTriangles();
276 het_mesh->triangle_normals_ = mesh_cpy->getTriangleNormals();
ccMesh & RemoveDegenerateTriangles()
Function that removes degenerate triangles, i.e., triangles that reference a single vertex multiple t...
ccMesh & RemoveDuplicatedTriangles()
Function that removes duplicated triangles, i.e., removes triangles that reference the same three ver...
ccMesh & RemoveUnreferencedVertices()
This function removes vertices from the triangle mesh that are not referenced in any triangle of the ...
ccMesh & RemoveDuplicatedVertices()
Function that removes duplicated verties, i.e., vertices that have identical coordinates.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
HalfEdge class contains vertex, triangle info about a half edge, as well as relations of next and twi...
int next_
Index of the next HalfEdge in the same triangle.
Eigen::Vector2i vertex_indices_
Index of the ordered vertices forming this half edge.
int twin_
Index of the twin HalfEdge.
HalfEdge()
Default Constructor.
HalfEdgeTriangleMesh inherits TriangleMesh class with the addition of HalfEdge data structure for eac...
HalfEdgeTriangleMesh(const char *name="HalfEdgeTriangleMesh")
Default Constructor.
std::vector< std::vector< int > > ordered_half_edge_from_vertex_
std::vector< int > boundaryHalfEdgesFromVertex(int vertex_index) const
bool hasHalfEdges() const
Returns true if half-edges have already been computed.
static std::shared_ptr< HalfEdgeTriangleMesh > CreateFromTriangleMesh(const ccMesh &mesh)
HalfEdgeTriangleMesh & operator+=(const HalfEdgeTriangleMesh &mesh)
std::vector< HalfEdge > half_edges_
List of HalfEdge in the mesh.
std::vector< int > boundaryVerticesFromVertex(int vertex_index) const
HalfEdgeTriangleMesh operator+(const HalfEdgeTriangleMesh &mesh) const
std::vector< std::vector< int > > getBoundaries() const
Returns a vector of boundaries. A boundary is a vector of vertices.
int nextHalfEdgeOnBoundary(int curr_half_edge_index) const
int nextHalfEdgeFromVertex(int init_half_edge_index) const
virtual HalfEdgeTriangleMesh & clear() override
virtual ecvMeshBase & clear()
ecvMeshBase & operator+=(const ecvMeshBase &mesh)
std::vector< Eigen::Vector3d > vertices_
Vertex coordinates.
Generic file read and write utility for python interface.
Eigen::Matrix< Index, 3, 1 > Vector3i
Eigen::Matrix< Index, 2, 1 > Vector2i