CARLA
Loading...
Searching...
No Matches
MeshReconstruction.h
Go to the documentation of this file.
1#pragma once
2#include "DataStructs.h"
3#include "Cube.h"
4#include "Triangulation.h"
5
6namespace MeshReconstruction
7{
8 /// Reconstructs a triangle mesh from a given signed distance function using <a href="https://en.wikipedia.org/wiki/Marching_cubes">Marching Cubes</a>.
9 /// @param sdf The <a href="http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm">Signed Distance Function</a>.
10 /// @param domain Domain of reconstruction.
11 /// @returns The reconstructed mesh.
12 Mesh MarchCube(
13 Fun3s const &sdf,
14 Rect3 const &domain);
15
16 /// Reconstructs a triangle mesh from a given signed distance function using <a href="https://en.wikipedia.org/wiki/Marching_cubes">Marching Cubes</a>.
17 /// @param sdf The <a href="http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm">Signed Distance Function</a>.
18 /// @param domain Domain of reconstruction.
19 /// @param cubeSize Size of marching cubes. Smaller cubes yields meshes of higher resolution.
20 /// @param isoLevel Level set of the SDF for which triangulation should be done. Changing this value moves the reconstructed surface.
21 /// @param sdfGrad Gradient of the SDF which yields the vertex normals of the reconstructed mesh. If none is provided a numerical approximation is used.
22 /// @returns The reconstructed mesh.
23 Mesh MarchCube(
24 Fun3s const &sdf,
25 Rect3 const &domain,
26 Vec3 const &cubeSize,
27 double isoLevel = 0,
28 Fun3v sdfGrad = nullptr);
29}
30
31// Adapted from here: http://paulbourke.net/geometry/polygonise/
32
33namespace MeshReconstruction
34{
35namespace
36{
37 Vec3 NumGrad(Fun3s const &f, Vec3 const &p)
38 {
39 auto const Eps = 1e-6;
40 Vec3 epsX{Eps, 0, 0}, epsY{0, Eps, 0}, epsZ{0, 0, Eps};
41 auto gx = (f(p + epsX) - f(p - epsX)) / 2;
42 auto gy = (f(p + epsY) - f(p - epsY)) / 2;
43 auto gz = (f(p + epsZ) - f(p - epsZ)) / 2;
44 return {gx, gy, gz};
45 }
46}
47
48Mesh MarchCube(Fun3s const &sdf, Rect3 const &domain)
49{
50 auto const NumCubes = 50;
51 auto cubeSize = domain.size * (1.0 / NumCubes);
52
53 return MarchCube(sdf, domain, cubeSize);
54}
55
57 Fun3s const &sdf,
58 Rect3 const &domain,
59 Vec3 const &cubeSize,
60 double isoLevel,
61 Fun3v sdfGrad)
62{
63 sdfGrad = sdfGrad == nullptr
64 ? [&sdf](Vec3 const &p)
65 { return NumGrad(sdf, p); }
66 : sdfGrad;
67
68 auto const NumX = static_cast<int>(ceil(domain.size.x / cubeSize.x));
69 auto const NumY = static_cast<int>(ceil(domain.size.y / cubeSize.y));
70 auto const NumZ = static_cast<int>(ceil(domain.size.z / cubeSize.z));
71
72 auto const HalfCubeDiag = cubeSize.Norm() / 2.0;
73 auto const HalfCubeSize = cubeSize * 0.5;
74
75 Mesh mesh;
76
77 for (auto ix = 0; ix < NumX; ++ix)
78 {
79 auto x = domain.min.x + ix * cubeSize.x;
80
81 for (auto iy = 0; iy < NumY; ++iy)
82 {
83 auto y = domain.min.y + iy * cubeSize.y;
84
85 for (auto iz = 0; iz < NumZ; ++iz)
86 {
87 auto z = domain.min.z + iz * cubeSize.z;
88 Vec3 min{x, y, z};
89
90 // Process only if cube lies within narrow band around surface.
91 auto cubeCenter = min + HalfCubeSize;
92 auto dist = abs(sdf(cubeCenter) - isoLevel);
93 if (dist > HalfCubeDiag)
94 continue;
95
96 Cube cube({min, cubeSize}, sdf);
97 auto intersect = cube.Intersect(isoLevel);
98 Triangulate(intersect, sdfGrad, mesh);
99 }
100 }
101 }
102
103 return mesh;
104}
105} // namespace MeshReconstruction
float y
float x
float z
double min(double v1, double v2)
Definition Simplify.h:285
IntersectInfo Intersect(double isoLevel=0) const
Definition Cube.h:156
std::function< Vec3(Vec3 const &)> Fun3v
Definition DataStructs.h:55
void Triangulate(IntersectInfo const &intersect, Fun3v const &grad, Mesh &mesh)
Given a grid cube and an isolevel the triangles (5 max) required to represent the isosurface in the c...
Mesh MarchCube(Fun3s const &sdf, Rect3 const &domain)
Reconstructs a triangle mesh from a given signed distance function using Marching Cubes.
std::function< double(Vec3 const &)> Fun3s
Definition DataStructs.h:54