Graphite  Version 3
An experimental 3D geometry processing program
mesh_geometry.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_GEOMETRY
41 #define GEOGRAM_MESH_MESH_GEOMETRY
42 
43 #include <geogram/basic/common.h>
44 #include <geogram/mesh/mesh.h>
45 #include <geogram/basic/geometry.h>
47 
53 namespace GEO {
54 
55  namespace Geom {
56 
64  inline const vec3& mesh_vertex(const Mesh& M, index_t v) {
65  geo_debug_assert(M.vertices.dimension() >= 3);
66  return *(const vec3*) (M.vertices.point_ptr(v));
67  }
68 
76  inline const vec3& mesh_vertex_ref(const Mesh& M, index_t v) {
77  geo_debug_assert(M.vertices.dimension() >= 3);
78  return *(vec3 const *) (M.vertices.point_ptr(v));
79  }
80 
88  inline vec3& mesh_vertex_ref(Mesh& M, index_t v) {
89  geo_debug_assert(M.vertices.dimension() >= 3);
90  return *(vec3*) (M.vertices.point_ptr(v));
91  }
92 
100  inline const vec3& mesh_corner_vertex(const Mesh& M, index_t c) {
101  return mesh_vertex(M, M.facet_corners.vertex(c));
102  }
103 
112  return mesh_vertex_ref(M, M.facet_corners.vertex(c));
113  }
114 
122  inline const vec3& mesh_vertex_normal(const Mesh& M, index_t v) {
123  geo_debug_assert(M.vertices.dimension() >= 6);
124  return *(const vec3*) (M.vertices.point_ptr(v) + 3);
125  }
126 
135  geo_debug_assert(M.vertices.dimension() >= 6);
136  return *(vec3*) (M.vertices.point_ptr(v) + 3);
137  }
138 
146  inline const vec3& mesh_vertex_normal_ref(const Mesh& M, index_t v) {
147  geo_debug_assert(M.vertices.dimension() >= 6);
148  return *(vec3 const *) (M.vertices.point_ptr(v) + 3);
149  }
150 
159  inline double mesh_facet_area(const Mesh& M, index_t f, index_t dim=0) {
160  geo_debug_assert(dim <= M.vertices.dimension());
161  if(dim == 0) {
162  dim = M.vertices.dimension();
163  }
164  double result = 0.0;
165  // Check for empty facet, should not happen.
166  if(M.facets.corners_end(f) == M.facets.corners_begin(f)) {
167  return result;
168  }
169  const double* p0 = M.vertices.point_ptr(
170  M.facet_corners.vertex(M.facets.corners_begin(f))
171  );
172  for(
173  index_t i = M.facets.corners_begin(f) + 1;
174  i + 1 < M.facets.corners_end(f); i++
175  ) {
176  result += GEO::Geom::triangle_area(
177  p0,
178  M.vertices.point_ptr(M.facet_corners.vertex(i)),
179  M.vertices.point_ptr(M.facet_corners.vertex(i + 1)),
180  coord_index_t(dim)
181  );
182  }
183  return result;
184  }
185 
194  vec3 GEOGRAM_API mesh_facet_normal(const Mesh& M, index_t f);
195 
202  inline vec3 mesh_facet_center(const Mesh& M, index_t f) {
203  vec3 result(0.0, 0.0, 0.0);
204  double count = 0.0;
205  for(index_t c = M.facets.corners_begin(f);
206  c < M.facets.corners_end(f); ++c) {
207  result += Geom::mesh_corner_vertex(M, c);
208  count += 1.0;
209  }
210  return (1.0 / count) * result;
211  }
212 
219  inline vec3 mesh_cell_center(const Mesh& M, index_t c) {
220  vec3 result(0.0, 0.0, 0.0);
221  for(index_t lv=0; lv<M.cells.nb_vertices(c); ++lv) {
222  index_t v = M.cells.vertex(c,lv);
223  result += vec3(M.vertices.point_ptr(v));
224  }
225  return (1.0 / double(M.cells.nb_vertices(c))) * result;
226  }
227 
228 
235  inline vec3 mesh_tet_center(const Mesh& M, index_t t) {
236  index_t iv1 = M.cells.vertex(t, 0);
237  index_t iv2 = M.cells.vertex(t, 1);
238  index_t iv3 = M.cells.vertex(t, 2);
239  index_t iv4 = M.cells.vertex(t, 3);
240  const vec3& v1 = Geom::mesh_vertex(M, iv1);
241  const vec3& v2 = Geom::mesh_vertex(M, iv2);
242  const vec3& v3 = Geom::mesh_vertex(M, iv3);
243  const vec3& v4 = Geom::mesh_vertex(M, iv4);
244  return 0.25 * (v1 + v2 + v3 + v4);
245  }
246 
256  inline vec3 mesh_corner_vector(const Mesh& M, index_t c1) {
257  geo_debug_assert(M.facets.are_simplices());
258  index_t c2 = M.facets.next_corner_around_facet(c1/3, c1);
259  index_t v1 = M.facet_corners.vertex(c1);
260  index_t v2 = M.facet_corners.vertex(c2);
261  return mesh_vertex(M,v2) - mesh_vertex(M,v1);
262  }
263 
273  double GEOGRAM_API mesh_normal_angle(const Mesh& M, index_t c);
274 
282  double GEOGRAM_API mesh_unsigned_normal_angle(
283  const Mesh& M, index_t f1, index_t f2
284  );
285 
294  double GEOGRAM_API mesh_area(const Mesh& M, index_t dim);
295 
301  inline double mesh_area(const Mesh& M) {
302  return mesh_area(M, M.vertices.dimension());
303  }
304 
310  double GEOGRAM_API mesh_enclosed_volume(const Mesh& M);
311  }
312 
318  void GEOGRAM_API compute_normals(Mesh& M);
319 
329  void GEOGRAM_API simple_Laplacian_smooth(
330  Mesh& M, index_t nb_iter, bool normals_only
331  );
332 
339  void GEOGRAM_API get_bbox(const Mesh& M, double* xyzmin, double* xyzmax);
340 
346  double GEOGRAM_API bbox_diagonal(const Mesh& M);
347 
355  void GEOGRAM_API set_anisotropy(Mesh& M, double s);
356 
361  void GEOGRAM_API unset_anisotropy(Mesh& M);
362 
373  void GEOGRAM_API compute_sizing_field(
374  Mesh& M, double gradation = 1.0, index_t nb_lfs_samples = 0
375  );
376 
385  void GEOGRAM_API normalize_embedding_area(Mesh& M);
386 
394  double GEOGRAM_API mesh_cell_volume(
395  const Mesh& M, index_t c
396  );
397 
403  double GEOGRAM_API mesh_cells_volume(const Mesh& M);
404 
405 
416  const Mesh& M, index_t c, index_t lf
417  );
418 
424  double GEOGRAM_API surface_average_edge_length(
425  const Mesh& M
426  );
427 }
428 
429 #endif
#define geo_debug_assert(x)
Verifies that a condition is met.
Definition: assert.h:196
index_t nb_vertices(index_t c) const
Gets the number of vertices of a cell.
Definition: mesh.h:1940
index_t vertex(index_t c, index_t lv) const
Gets a vertex of a cell by local vertex index.
Definition: mesh.h:1950
index_t vertex(index_t c) const
Gets the vertex that a corner is incident to.
Definition: mesh.h:876
index_t corners_end(index_t f) const
Gets the upper limit for iterating over the corners of a facet.
Definition: mesh.h:774
bool are_simplices() const
Tests whether all the facets are triangles.
Definition: mesh.h:809
index_t corners_begin(index_t f) const
Gets the first element for iterating over the corners of a facet.
Definition: mesh.h:763
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
const double * point_ptr(index_t v) const
Gets a point.
Definition: mesh.h:455
index_t dimension() const
Gets the dimension of the vertices.
Definition: mesh.h:427
Represents a mesh.
Definition: mesh.h:2693
Common include file, providing basic definitions. Should be included before anything else by all head...
Geometric functions in 2d and 3d.
Geometric functions in arbitrary dimension.
The class that represents a mesh.
const vec3 & mesh_vertex_normal(const Mesh &M, index_t v)
Gets a mesh vertex normal by vertex index.
vec3 mesh_corner_vector(const Mesh &M, index_t c1)
Gets a vector by a mesh corner.
vec3 & mesh_vertex_normal_ref(Mesh &M, index_t v)
Gets a mesh vertex normal by vertex index.
double mesh_unsigned_normal_angle(const Mesh &M, index_t f1, index_t f2)
Computes the angle between the normal vectors of two mesh facets sharing an edge.
double mesh_normal_angle(const Mesh &M, index_t c)
Computes the angle between the normal vectors of two mesh facets sharing an edge.
const vec3 & mesh_corner_vertex(const Mesh &M, index_t c)
Gets a mesh vertex by an incident corner index.
vec3 & mesh_corner_vertex_ref(Mesh &M, index_t c)
Gets a mesh vertex by an incident corner index.
double mesh_area(const Mesh &M, index_t dim)
Computes the total surface area of a mesh in arbitrary dimension.
vec3 mesh_cell_center(const Mesh &M, index_t c)
Gets the centroid of the vertices of a cell in a mesh.
double triangle_area(const vec3 &p1, const vec3 &p2, const vec3 &p3)
Computes the area of a 3d triangle.
Definition: geometry.h:348
vec3 mesh_facet_center(const Mesh &M, index_t f)
Gets the centroid of the vertices of a facet in a mesh.
vec3 mesh_tet_center(const Mesh &M, index_t t)
Gets the centroid of a tetrahedron in a mesh.
const vec3 & mesh_vertex_ref(const Mesh &M, index_t v)
Gets a mesh vertex by its index.
Definition: mesh_geometry.h:76
const vec3 & mesh_vertex(const Mesh &M, index_t v)
Gets a mesh vertex by its index.
Definition: mesh_geometry.h:64
double mesh_enclosed_volume(const Mesh &M)
Computes the volume enclosed by a surfacic mesh.
double mesh_facet_area(const Mesh &M, index_t f, index_t dim=0)
Computes the area of a facet.
vec3 mesh_facet_normal(const Mesh &M, index_t f)
Computes the normal to a mesh facet.
Global Vorpaline namespace.
void simple_Laplacian_smooth(Mesh &M, index_t nb_iter, bool normals_only)
Smoothes a mesh.
double surface_average_edge_length(const Mesh &M)
Computes the average edge length in a surface.
void get_bbox(const Mesh &M, double *xyzmin, double *xyzmax)
Gets the bounding box of a mesh.
void compute_sizing_field(Mesh &M, double gradation=1.0, index_t nb_lfs_samples=0)
Computes a sizing field using an estimate of lfs (local feature size).
double bbox_diagonal(const Mesh &M)
Computes the length of the bounding box diagonal of a mesh.
vecng< 3, Numeric::float64 > vec3
Represents points and vectors in 3d.
Definition: geometry.h:65
void compute_normals(Mesh &M)
Computes the normals to the vertices, and stores them as additional coordinates.
double mesh_cells_volume(const Mesh &M)
Computes the volume of the cells of a mesh.
double mesh_cell_volume(const Mesh &M, index_t c)
Computes the volume of a cell in a mesh.
void normalize_embedding_area(Mesh &M)
Computes vertices weights in such a way that triangle areas are normalized.
geo_index_t index_t
The type for storing and manipulating indices.
Definition: numeric.h:329
void set_anisotropy(Mesh &M, double s)
Normalizes and scales the stored vertex normals by a factor.
void unset_anisotropy(Mesh &M)
Normalizes the stored vertex normals.
geo_coord_index_t coord_index_t
The type for storing coordinate indices, and iterating on the coordinates of a point.
Definition: numeric.h:363
vec3 mesh_cell_facet_normal(const Mesh &M, index_t c, index_t lf)
Computes the normal of a cell facet.