Geogram  Version 1.9.1
A programming library of geometric algorithms
mesh_halfedges.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2000-2022 Inria
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * * Neither the name of the ALICE Project-Team nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * Contact: Bruno Levy
30  *
31  * https://www.inria.fr/fr/bruno-levy
32  *
33  * Inria,
34  * Domaine de Voluceau,
35  * 78150 Le Chesnay - Rocquencourt
36  * FRANCE
37  *
38  */
39 
40 #ifndef GEOGRAM_MESH_MESH_HALFEDGES
41 #define GEOGRAM_MESH_MESH_HALFEDGES
42 
43 #include <geogram/basic/common.h>
44 #include <geogram/mesh/mesh.h>
46 #include <iostream>
47 
53 namespace GEO {
54 
59  class GEOGRAM_API MeshHalfedges {
60  public:
65  struct Halfedge {
66 
67  static const index_t NO_FACET = index_t(-1);
68  static const index_t NO_CORNER = index_t(-1);
69 
74  facet(NO_FACET),
75  corner(NO_CORNER) {
76  }
77 
84  facet(f),
85  corner(c) {
86  }
87 
91  void clear() {
92  facet = NO_FACET;
93  corner = NO_CORNER;
94  }
95 
100  bool is_nil() const {
101  return (facet == NO_FACET) && (corner == NO_CORNER);
102  }
103 
110  bool operator== (const Halfedge& rhs) const {
111  return facet == rhs.facet && corner == rhs.corner;
112  }
113 
120  bool operator!= (const Halfedge& rhs) const {
121  return !(rhs == *this);
122  }
123 
124  index_t facet;
125  index_t corner;
126 
127  };
128 
133  MeshHalfedges(Mesh& mesh) : mesh_(mesh) {
134  }
135 
140  Mesh& mesh() {
141  return mesh_;
142  }
143 
148  const Mesh& mesh() const {
149  return mesh_;
150  }
151 
158  void set_use_facet_region(bool x) {
159  if(x) {
160  if(!facet_region_.is_bound()) {
161  facet_region_.bind(mesh_.facets.attributes(),"region");
162  }
163  } else {
164  if(facet_region_.is_bound()) {
165  facet_region_.unbind();
166  }
167  }
168  }
169 
175  void set_use_facet_region(const std::string& attribute_name) {
176  if(facet_region_.is_bound()) {
177  facet_region_.unbind();
178  }
179  facet_region_.bind(mesh_.facets.attributes(),attribute_name);
180  }
181 
189  void set_use_facet_region(const char* attribute_name) {
190  set_use_facet_region(std::string(attribute_name));
191  }
192 
193 
203  bool halfedge_is_valid(const Halfedge& H) const {
204  return
205  H.facet != Halfedge::NO_FACET &&
206  H.corner != Halfedge::NO_CORNER &&
207  H.facet < mesh_.facets.nb() &&
208  H.corner < mesh_.facet_corners.nb()
209  ;
210  }
211 
220  bool halfedge_is_border(const Halfedge& H) const {
221  geo_debug_assert(halfedge_is_valid(H));
222  if(facet_region_.is_bound()) {
223  index_t f = H.facet;
224  index_t adj_f =
225  mesh_.facet_corners.adjacent_facet(H.corner);
226  return
227  adj_f == NO_FACET ||
228  facet_region_[f] != facet_region_[adj_f]
229  ;
230  }
231  return mesh_.facet_corners.adjacent_facet(H.corner) == NO_FACET;
232  }
233 
239  geo_debug_assert(halfedge_is_valid(H));
240  H.corner = mesh_.facets.next_corner_around_facet(H.facet, H.corner);
241  }
242 
248  geo_debug_assert(halfedge_is_valid(H));
249  H.corner = mesh_.facets.prev_corner_around_facet(H.facet, H.corner);
250  }
251 
259 
267 
276 
285 
292  void move_to_opposite(Halfedge& H) const;
293 
294  private:
295  Mesh& mesh_;
296  Attribute<index_t> facet_region_;
297  };
298 
305  inline std::ostream& operator<< (
306  std::ostream& out, const MeshHalfedges::Halfedge& H
307  ) {
308  return out << '(' << H.facet << ',' << H.corner << ')';
309  }
310 
311  namespace Geom {
312 
319  inline const vec3& halfedge_vertex_from(
320  const Mesh& M, const MeshHalfedges::Halfedge& H
321  ) {
322  return mesh_vertex(M, M.facet_corners.vertex(H.corner));
323  }
324 
331  inline const vec3& halfedge_vertex_to(
332  const Mesh& M, const MeshHalfedges::Halfedge& H
333  ) {
334  index_t c = M.facets.next_corner_around_facet(H.facet, H.corner);
335  return mesh_vertex(M, M.facet_corners.vertex(c));
336  }
337 
347  const Mesh& M, const MeshHalfedges::Halfedge& H
348  ) {
349  return halfedge_vertex_to(M, H) - halfedge_vertex_from(M, H);
350  }
351 
358  inline double edge_length(
359  const Mesh& M, const MeshHalfedges::Halfedge& H
360  ) {
361  return length(halfedge_vector(M, H));
362  }
363  }
364 }
365 
366 #endif
#define geo_debug_assert(x)
Verifies that a condition is met.
Definition: assert.h:196
index_t vertex(index_t c) const
Gets the vertex that a corner is incident to.
Definition: mesh.h:876
index_t next_corner_around_facet(index_t f, index_t c) const
Gets the successor of a corner around a facet.
Definition: mesh.h:1146
Exposes a half-edge like API for traversing a Mesh.
bool halfedge_is_border(const Halfedge &H) const
Tests whether a Halfedge is on the boder.
void set_use_facet_region(const std::string &attribute_name)
Sets a facet attribute name that determines borders.
void set_use_facet_region(bool x)
Sets whether facet regions determine borders.
bool move_to_next_around_vertex(Halfedge &H) const
Replaces a Halfedge with the next one around the vertex.
void move_to_prev_around_border(Halfedge &H) const
Replaces a Halfedge with the previous one around the border.
Mesh & mesh()
Gets the mesh.
const Mesh & mesh() const
Gets the mesh.
bool move_to_prev_around_vertex(Halfedge &H) const
Replaces a Halfedge with the previous one around the vertex.
MeshHalfedges(Mesh &mesh)
Creates a new MeshHalfedges.
void move_to_next_around_border(Halfedge &H) const
Replaces a Halfedge with the next one around the border.
void move_to_next_around_facet(Halfedge &H) const
Replaces a Halfedge with the next one around the facet.
bool halfedge_is_valid(const Halfedge &H) const
Tests whether a Halfedge is valid.
void move_to_opposite(Halfedge &H) const
Replaces a Halfedge with the opposite one in the adjacent facet.
void set_use_facet_region(const char *attribute_name)
Sets a facet attribute name that determines borders.
void move_to_prev_around_facet(Halfedge &H) const
Replaces a Halfedge with the previous one around the facet.
Represents a mesh.
Definition: mesh.h:2701
Common include file, providing basic definitions. Should be included before anything else by all head...
The class that represents a mesh.
Functions for accessing the geometry in a mesh.
const vec3 & halfedge_vertex_to(const Mesh &M, const MeshHalfedges::Halfedge &H)
Gets the arrow extremity point of a Halfedge.
const vec3 & halfedge_vertex_from(const Mesh &M, const MeshHalfedges::Halfedge &H)
Gets the origin point of a Halfedge.
double edge_length(const Mesh &M, const MeshHalfedges::Halfedge &H)
Gets the length of a Halfedge.
vec3 halfedge_vector(const Mesh &M, const MeshHalfedges::Halfedge &H)
Gets a 3d vector that connects the origin with the arrow extremity of a Halfedge.
const vec3 & mesh_vertex(const Mesh &M, index_t v)
Gets a mesh vertex by its index.
Definition: mesh_geometry.h:64
bool operator!=(const aligned_allocator< T1, A1 > &, const aligned_allocator< T2, A2 > &)
Tests whether two aligned_allocators are different.
Definition: memory.h:617
bool operator==(const aligned_allocator< T1, A1 > &, const aligned_allocator< T2, A2 > &)
Tests whether two aligned_allocators are equal.
Definition: memory.h:606
Global Vorpaline namespace.
Definition: basic.h:55
geo_index_t index_t
The type for storing and manipulating indices.
Definition: numeric.h:329
Stores a reference to a mesh corner and facet, and provides a halfedge-like API.
void clear()
Clears this Halfedge.
Halfedge(index_t f, index_t c)
Constructs a new Halfedge from a facet and corner index.
Halfedge()
Constructs a new uninitialized Halfedge.
bool is_nil() const
Tests whether this Halfedge is initialized.