add MeshReconstruction dep and some test meshes
This commit is contained in:
parent
068dede832
commit
1659341370
@ -6,6 +6,10 @@ find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
add_subdirectory(external/OpenMesh)
|
||||
add_subdirectory(external/Eigen)
|
||||
|
||||
add_subdirectory(external/MeshReconstruction)
|
||||
target_include_directories(MeshReconstruction INTERFACE
|
||||
external/MeshReconstruction/lib)
|
||||
|
||||
add_executable(${PROJECT_NAME})
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
resources.qrc
|
||||
@ -28,11 +32,14 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||
src/quad_patch.cpp
|
||||
src/quad_patch.h
|
||||
src/quad_patch_tesselator.cpp
|
||||
src/quad_patch_tesselator.h)
|
||||
src/quad_patch_tesselator.h
|
||||
src/hole_filling.h
|
||||
src/hole_filling.cpp)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
Qt5::Core Qt5::Gui Qt5::Widgets
|
||||
OpenMeshCore
|
||||
eigen)
|
||||
eigen
|
||||
MeshReconstruction)
|
||||
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
AUTOMOC ON
|
||||
|
68474
data/face_scaled.obj
Normal file
68474
data/face_scaled.obj
Normal file
File diff suppressed because it is too large
Load Diff
103420
data/gargoyle_trou.obj
Normal file
103420
data/gargoyle_trou.obj
Normal file
File diff suppressed because it is too large
Load Diff
BIN
external/MeshReconstruction/.DS_Store
vendored
Normal file
BIN
external/MeshReconstruction/.DS_Store
vendored
Normal file
Binary file not shown.
3
external/MeshReconstruction/.gitignore
vendored
Normal file
3
external/MeshReconstruction/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
bin
|
||||
html/
|
||||
latex/
|
16
external/MeshReconstruction/CMakeLists.txt
vendored
Normal file
16
external/MeshReconstruction/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
cmake_minimum_required (VERSION 3.0)
|
||||
project (MeshReconstruction)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Parallel compilation.
|
||||
if(WIN32)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4250")
|
||||
endif()
|
||||
|
||||
set(CMAKE_DEBUG_POSTFIX "d")
|
||||
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(demo)
|
13
external/MeshReconstruction/Readme.md
vendored
Normal file
13
external/MeshReconstruction/Readme.md
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
# MeshReconstruction
|
||||
|
||||
This is a small library that can reconstruct a triangle mesh from a <a href="http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm">signed distance function</a> using the <a href="https://en.wikipedia.org/wiki/Marching_cubes">Marching Cubes algorithm</a> and export it to a file in the <a href="https://de.wikipedia.org/wiki/Wavefront_OBJ">obj format</a>.
|
||||
|
||||
The library is self-contained and has no dependencies. The library is fast due to precomputed lookup tables and a narrow-band approach which excludes a lot of marching cubes that are far away from the surface.
|
||||
|
||||
The library requires C++14 and has been tested under Visual Studio 2017 and Windows 10 but should port to other systems without major problems.
|
||||
|
||||
The library can be used under the terms of the MIT License.
|
||||
|
||||
<p align="center">
|
||||
<img src="overview.png" width="400" alt="Overview">
|
||||
</p>
|
3
external/MeshReconstruction/demo/CMakeLists.txt
vendored
Normal file
3
external/MeshReconstruction/demo/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
include_directories("." ${PROJECT_SOURCE_DIR}/lib)
|
||||
add_executable(Demo main.cpp)
|
||||
target_link_libraries (Demo MeshReconstruction)
|
22
external/MeshReconstruction/demo/main.cpp
vendored
Normal file
22
external/MeshReconstruction/demo/main.cpp
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
#include <MeshReconstruction.h>
|
||||
#include <IO.h>
|
||||
|
||||
using namespace MeshReconstruction;
|
||||
|
||||
int main()
|
||||
{
|
||||
auto sphereSdf = [](Vec3 const& pos)
|
||||
{
|
||||
auto const Radius = 1.0;
|
||||
return pos.Norm() - Radius;
|
||||
};
|
||||
|
||||
Rect3 domain;
|
||||
domain.min = { -1.1, -1.1, -1.1 };
|
||||
domain.size = {2.2, 2.2, 2.2};
|
||||
|
||||
Vec3 cubeSize{ 0.05, 0.05, 0.05 };
|
||||
|
||||
auto mesh = MarchCube(sphereSdf, domain, cubeSize);
|
||||
WriteObjFile(mesh, "sphere.obj");
|
||||
}
|
12
external/MeshReconstruction/lib/CMakeLists.txt
vendored
Normal file
12
external/MeshReconstruction/lib/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
add_library(MeshReconstruction MeshReconstruction.h MeshReconstruction.cpp Cube.h Cube.cpp DataStructs.h IO.h IO.cpp Triangulation.h Triangulation.cpp)
|
||||
|
||||
target_link_libraries(MeshReconstruction m)
|
||||
|
||||
install(TARGETS MeshReconstruction
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib)
|
||||
|
||||
install(DIRECTORY .
|
||||
DESTINATION .
|
||||
FILES_MATCHING PATTERN "*.h")
|
149
external/MeshReconstruction/lib/Cube.cpp
vendored
Normal file
149
external/MeshReconstruction/lib/Cube.cpp
vendored
Normal file
@ -0,0 +1,149 @@
|
||||
#include "Cube.h"
|
||||
#include <cmath>
|
||||
|
||||
using namespace MeshReconstruction;
|
||||
|
||||
namespace
|
||||
{
|
||||
// Cube has 8 vertices. Each vertex can have positive or negative sign.
|
||||
// 2^8 = 256 possible configurations mapped to intersected edges in each case.
|
||||
// The 12 edges are numbered as 1, 2, 4, ..., 2048 and are stored as a 12-bit bitstring for each configuration.
|
||||
const int signConfigToIntersectedEdges[256] = {
|
||||
0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
|
||||
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
|
||||
0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
|
||||
0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
|
||||
0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
|
||||
0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
|
||||
0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
|
||||
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
|
||||
0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
|
||||
0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
|
||||
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
|
||||
0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
|
||||
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
|
||||
0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
|
||||
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
|
||||
0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
|
||||
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
|
||||
0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
|
||||
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
|
||||
0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
|
||||
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
|
||||
0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
|
||||
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
|
||||
0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
|
||||
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
|
||||
0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
|
||||
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
|
||||
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
|
||||
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
|
||||
0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
|
||||
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
|
||||
0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 };
|
||||
|
||||
struct Edge
|
||||
{
|
||||
int edgeFlag : 12; // flag: 1, 2, 4, ... 2048
|
||||
int vert0; // 0-7
|
||||
int vert1; // 0-7
|
||||
};
|
||||
|
||||
const Edge edges[12] =
|
||||
{
|
||||
{ 1, 0, 1 }, // edge 0
|
||||
{ 2, 1, 2 }, // edge 1
|
||||
{ 4, 2, 3 }, // ...
|
||||
{ 8, 3, 0 },
|
||||
{ 16, 4, 5 },
|
||||
{ 32, 5, 6 },
|
||||
{ 64, 6, 7 },
|
||||
{ 128, 7, 4 },
|
||||
{ 256, 0, 4 },
|
||||
{ 512, 1, 5 },
|
||||
{ 1024, 2, 6 },
|
||||
{ 2048, 3, 7 } // edge 11
|
||||
};
|
||||
}
|
||||
|
||||
Vec3 Cube::LerpVertex(double isoLevel, int i1, int i2) const
|
||||
{
|
||||
auto const Eps = 1e-5;
|
||||
auto const v1 = sdf[i1];
|
||||
auto const v2 = sdf[i2];
|
||||
auto const& p1 = pos[i1];
|
||||
auto const& p2 = pos[i2];
|
||||
|
||||
if (abs(isoLevel - v1) < Eps) return p1;
|
||||
if (abs(isoLevel - v2) < Eps) return p2;
|
||||
if (abs(v1 - v2) < Eps) return p1;
|
||||
|
||||
auto mu = (isoLevel - v1) / (v2 - v1);
|
||||
return p1 + (p2 - p1)*mu;
|
||||
}
|
||||
|
||||
Cube::Cube(Rect3 const& space, Fun3s const& sdf)
|
||||
{
|
||||
auto mx = space.min.x;
|
||||
auto my = space.min.y;
|
||||
auto mz = space.min.z;
|
||||
|
||||
auto sx = space.size.x;
|
||||
auto sy = space.size.y;
|
||||
auto sz = space.size.z;
|
||||
|
||||
pos[0] = space.min;
|
||||
pos[1] = { mx + sx, my, mz };
|
||||
pos[2] = { mx + sx, my, mz + sz };
|
||||
pos[3] = { mx, my, mz + sz };
|
||||
pos[4] = { mx, my + sy, mz };
|
||||
pos[5] = { mx + sx, my + sy, mz };
|
||||
pos[6] = { mx + sx, my + sy, mz + sz };
|
||||
pos[7] = { mx, my + sy, mz + sz };
|
||||
|
||||
for (auto i = 0; i < 8; ++i)
|
||||
{
|
||||
auto sd = sdf(pos[i]);
|
||||
if (sd == 0) sd += 1e-6;
|
||||
this->sdf[i] = sd;
|
||||
}
|
||||
}
|
||||
|
||||
int Cube::SignConfig(double isoLevel) const
|
||||
{
|
||||
auto edgeIndex = 0;
|
||||
|
||||
for (auto i = 0; i < 8; ++i)
|
||||
{
|
||||
if (sdf[i] < isoLevel)
|
||||
{
|
||||
edgeIndex |= 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
return edgeIndex;
|
||||
}
|
||||
|
||||
IntersectInfo Cube::Intersect(double iso) const
|
||||
{
|
||||
// idea:
|
||||
// from signs at 8 corners of cube a sign configuration (256 possible ones) is computed
|
||||
// this configuration can be used to index into a table that tells which of the 12 edges are intersected
|
||||
// find vertices adjacent to edges and interpolate cut vertex and store it in IntersectionInfo object
|
||||
|
||||
IntersectInfo intersect;
|
||||
intersect.signConfig = SignConfig(iso);
|
||||
|
||||
for (auto e = 0; e<12; ++e)
|
||||
{
|
||||
if (signConfigToIntersectedEdges[intersect.signConfig] & edges[e].edgeFlag)
|
||||
{
|
||||
auto v0 = edges[e].vert0;
|
||||
auto v1 = edges[e].vert1;
|
||||
auto vert = LerpVertex(iso, v0, v1);
|
||||
intersect.edgeVertIndices[e] = vert;
|
||||
}
|
||||
}
|
||||
|
||||
return intersect;
|
||||
}
|
30
external/MeshReconstruction/lib/Cube.h
vendored
Normal file
30
external/MeshReconstruction/lib/Cube.h
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include "DataStructs.h"
|
||||
|
||||
namespace MeshReconstruction
|
||||
{
|
||||
struct IntersectInfo
|
||||
{
|
||||
// 0 - 255
|
||||
int signConfig;
|
||||
|
||||
// If it exists, vertex on edge i is stored at position i.
|
||||
// For edge numbering and location see numberings.png.
|
||||
std::array<Vec3, 12> edgeVertIndices;
|
||||
};
|
||||
|
||||
class Cube
|
||||
{
|
||||
Vec3 pos[8];
|
||||
double sdf[8];
|
||||
|
||||
Vec3 LerpVertex(double isoLevel, int i1, int i2) const;
|
||||
int SignConfig(double isoLevel) const;
|
||||
|
||||
public:
|
||||
Cube(Rect3 const& space, Fun3s const& sdf);
|
||||
|
||||
// Find the vertices where the surface intersects the cube.
|
||||
IntersectInfo Intersect(double isoLevel = 0) const;
|
||||
};
|
||||
}
|
57
external/MeshReconstruction/lib/DataStructs.h
vendored
Normal file
57
external/MeshReconstruction/lib/DataStructs.h
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <cmath>
|
||||
|
||||
namespace MeshReconstruction
|
||||
{
|
||||
struct Vec3
|
||||
{
|
||||
double x, y, z;
|
||||
|
||||
Vec3 operator+(Vec3 const& o) const
|
||||
{
|
||||
return { x + o.x, y + o.y, z + o.z };
|
||||
}
|
||||
|
||||
Vec3 operator-(Vec3 const& o) const
|
||||
{
|
||||
return { x - o.x, y - o.y, z - o.z };
|
||||
}
|
||||
|
||||
Vec3 operator*(double c) const
|
||||
{
|
||||
return { c*x, c*y, c*z };
|
||||
}
|
||||
|
||||
double Norm() const
|
||||
{
|
||||
return sqrt(x*x + y*y + z*z);
|
||||
}
|
||||
|
||||
Vec3 Normalized() const
|
||||
{
|
||||
auto n = Norm();
|
||||
return { x / n, y / n, z / n };
|
||||
}
|
||||
};
|
||||
|
||||
struct Rect3
|
||||
{
|
||||
Vec3 min;
|
||||
Vec3 size;
|
||||
};
|
||||
|
||||
using Triangle = std::array<int, 3>;
|
||||
|
||||
struct Mesh
|
||||
{
|
||||
std::vector<Vec3> vertices;
|
||||
std::vector<Triangle> triangles;
|
||||
std::vector<Vec3> vertexNormals;
|
||||
};
|
||||
|
||||
using Fun3s = std::function<double(Vec3 const&)>;
|
||||
using Fun3v = std::function<Vec3(Vec3 const&)>;
|
||||
}
|
53
external/MeshReconstruction/lib/IO.cpp
vendored
Normal file
53
external/MeshReconstruction/lib/IO.cpp
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
#include "IO.h"
|
||||
#include <stdexcept>
|
||||
using namespace std;
|
||||
|
||||
void MeshReconstruction::WriteObjFile(Mesh const& mesh, string const& fileName)
|
||||
{
|
||||
// FILE faster than streams.
|
||||
|
||||
FILE* file;
|
||||
//auto status = fopen_s(&file, fileName.c_str(), "w");
|
||||
//if (status != 0)
|
||||
//{
|
||||
// throw runtime_error("Could not write obj file.");
|
||||
//}
|
||||
file = fopen(fileName.c_str(), "w");
|
||||
if (file == NULL)
|
||||
{
|
||||
throw runtime_error("Could not write obj file.");
|
||||
}
|
||||
|
||||
// write stats
|
||||
fprintf(file, "# %d vertices, %d triangles\n\n",
|
||||
static_cast<int>(mesh.vertices.size()),
|
||||
static_cast<int>(mesh.triangles.size()));
|
||||
|
||||
// vertices
|
||||
for (auto vi = 0; vi < mesh.vertices.size(); ++vi)
|
||||
{
|
||||
auto const& v = mesh.vertices.at(vi);
|
||||
fprintf(file, "v %f %f %f\n", v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
// vertex normals
|
||||
fprintf(file, "\n");
|
||||
for (auto ni = 0; ni < mesh.vertices.size(); ++ni)
|
||||
{
|
||||
auto const& vn = mesh.vertexNormals.at(ni);
|
||||
fprintf(file, "vn %f %f %f\n", vn.x, vn.y, vn.z);
|
||||
}
|
||||
|
||||
// triangles (1-based)
|
||||
fprintf(file, "\n");
|
||||
for (auto ti = 0; ti < mesh.triangles.size(); ++ti)
|
||||
{
|
||||
auto const& t = mesh.triangles.at(ti);
|
||||
fprintf(file, "f %d//%d %d//%d %d//%d\n",
|
||||
t[0] + 1, t[0] + 1,
|
||||
t[1] + 1, t[1] + 1,
|
||||
t[2] + 1, t[2] + 1);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
9
external/MeshReconstruction/lib/IO.h
vendored
Normal file
9
external/MeshReconstruction/lib/IO.h
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "DataStructs.h"
|
||||
|
||||
namespace MeshReconstruction
|
||||
{
|
||||
/// Writes a mesh to a file in <a href="https://de.wikipedia.org/wiki/Wavefront_OBJ">obj format</a>.
|
||||
void WriteObjFile(Mesh const& mesh, std::string const& file);
|
||||
}
|
78
external/MeshReconstruction/lib/MeshReconstruction.cpp
vendored
Normal file
78
external/MeshReconstruction/lib/MeshReconstruction.cpp
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
#include "MeshReconstruction.h"
|
||||
#include "Cube.h"
|
||||
#include "Triangulation.h"
|
||||
|
||||
using namespace MeshReconstruction;
|
||||
using namespace std;
|
||||
|
||||
// Adapted from here: http://paulbourke.net/geometry/polygonise/
|
||||
|
||||
namespace
|
||||
{
|
||||
Vec3 NumGrad(Fun3s const& f, Vec3 const& p)
|
||||
{
|
||||
auto const Eps = 1e-6;
|
||||
Vec3 epsX{ Eps, 0, 0 }, epsY{ 0, Eps, 0 }, epsZ{ 0, 0, Eps };
|
||||
auto gx = (f(p + epsX) - f(p - epsX)) / 2;
|
||||
auto gy = (f(p + epsY) - f(p - epsY)) / 2;
|
||||
auto gz = (f(p + epsZ) - f(p - epsZ)) / 2;
|
||||
return { gx, gy, gz };
|
||||
}
|
||||
}
|
||||
|
||||
Mesh MeshReconstruction::MarchCube(Fun3s const& sdf, Rect3 const& domain)
|
||||
{
|
||||
auto const NumCubes = 50;
|
||||
auto cubeSize = domain.size * (1.0 / NumCubes);
|
||||
|
||||
return MarchCube(sdf, domain, cubeSize);
|
||||
}
|
||||
|
||||
Mesh MeshReconstruction::MarchCube(
|
||||
Fun3s const& sdf,
|
||||
Rect3 const& domain,
|
||||
Vec3 const& cubeSize,
|
||||
double isoLevel,
|
||||
Fun3v sdfGrad)
|
||||
{
|
||||
// Default value.
|
||||
sdfGrad = sdfGrad == nullptr
|
||||
? [&sdf](Vec3 const& p) { return NumGrad(sdf, p); }
|
||||
: sdfGrad;
|
||||
|
||||
auto const NumX = static_cast<int>(ceil(domain.size.x / cubeSize.x));
|
||||
auto const NumY = static_cast<int>(ceil(domain.size.y / cubeSize.y));
|
||||
auto const NumZ = static_cast<int>(ceil(domain.size.z / cubeSize.z));
|
||||
|
||||
auto const HalfCubeDiag = cubeSize.Norm() / 2.0;
|
||||
auto const HalfCubeSize = cubeSize * 0.5;
|
||||
|
||||
Mesh mesh;
|
||||
|
||||
for (auto ix = 0; ix < NumX; ++ix)
|
||||
{
|
||||
auto x = domain.min.x + ix * cubeSize.x;
|
||||
|
||||
for (auto iy = 0; iy < NumY; ++iy)
|
||||
{
|
||||
auto y = domain.min.y + iy * cubeSize.y;
|
||||
|
||||
for (auto iz = 0; iz < NumZ; ++iz)
|
||||
{
|
||||
auto z = domain.min.z + iz * cubeSize.z;
|
||||
Vec3 min{ x, y, z };
|
||||
|
||||
// Process only if cube lies within narrow band around surface.
|
||||
auto cubeCenter = min + HalfCubeSize;
|
||||
auto dist = abs(sdf(cubeCenter) - isoLevel);
|
||||
if (dist > HalfCubeDiag) continue;
|
||||
|
||||
Cube cube({ min, cubeSize }, sdf);
|
||||
auto intersect = cube.Intersect(isoLevel);
|
||||
Triangulate(intersect, sdfGrad, mesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
27
external/MeshReconstruction/lib/MeshReconstruction.h
vendored
Normal file
27
external/MeshReconstruction/lib/MeshReconstruction.h
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "DataStructs.h"
|
||||
|
||||
namespace MeshReconstruction
|
||||
{
|
||||
/// Reconstructs a triangle mesh from a given signed distance function using <a href="https://en.wikipedia.org/wiki/Marching_cubes">Marching Cubes</a>.
|
||||
/// @param sdf The <a href="http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm">Signed Distance Function</a>.
|
||||
/// @param domain Domain of reconstruction.
|
||||
/// @returns The reconstructed mesh.
|
||||
Mesh MarchCube(
|
||||
Fun3s const& sdf,
|
||||
Rect3 const& domain);
|
||||
|
||||
/// Reconstructs a triangle mesh from a given signed distance function using <a href="https://en.wikipedia.org/wiki/Marching_cubes">Marching Cubes</a>.
|
||||
/// @param sdf The <a href="http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm">Signed Distance Function</a>.
|
||||
/// @param domain Domain of reconstruction.
|
||||
/// @param cubeSize Size of marching cubes. Smaller cubes yields meshes of higher resolution.
|
||||
/// @param isoLevel Level set of the SDF for which triangulation should be done. Changing this value moves the reconstructed surface.
|
||||
/// @param sdfGrad Gradient of the SDF which yields the vertex normals of the reconstructed mesh. If none is provided a numerical approximation is used.
|
||||
/// @returns The reconstructed mesh.
|
||||
Mesh MarchCube(
|
||||
Fun3s const& sdf,
|
||||
Rect3 const& domain,
|
||||
Vec3 const& cubeSize,
|
||||
double isoLevel = 0,
|
||||
Fun3v sdfGrad = nullptr);
|
||||
}
|
301
external/MeshReconstruction/lib/Triangulation.cpp
vendored
Normal file
301
external/MeshReconstruction/lib/Triangulation.cpp
vendored
Normal file
@ -0,0 +1,301 @@
|
||||
#include "Triangulation.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
// Indices into vertex buffer (0 - 11).
|
||||
// Three successive entries make up one triangle.
|
||||
// -1 means unused.
|
||||
const int signConfigToTriangles[256][16] =
|
||||
{ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
|
||||
{ 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 },
|
||||
{ 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 },
|
||||
{ 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 },
|
||||
{ 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 },
|
||||
{ 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 },
|
||||
{ 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 },
|
||||
{ 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 },
|
||||
{ 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 },
|
||||
{ 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 },
|
||||
{ 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
|
||||
{ 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 },
|
||||
{ 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1 },
|
||||
{ 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1 },
|
||||
{ 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1 },
|
||||
{ 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 },
|
||||
{ 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 },
|
||||
{ 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 },
|
||||
{ 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 },
|
||||
{ 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 },
|
||||
{ 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 },
|
||||
{ 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 },
|
||||
{ 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 },
|
||||
{ 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 },
|
||||
{ 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 },
|
||||
{ 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 },
|
||||
{ 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1 },
|
||||
{ 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1 },
|
||||
{ 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1 },
|
||||
{ 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1 },
|
||||
{ 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 },
|
||||
{ 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 },
|
||||
{ 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1 },
|
||||
{ 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1 },
|
||||
{ 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1 },
|
||||
{ 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1 },
|
||||
{ 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 },
|
||||
{ 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 },
|
||||
{ 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 },
|
||||
{ 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1 },
|
||||
{ 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1 },
|
||||
{ 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1 },
|
||||
{ 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 },
|
||||
{ 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 },
|
||||
{ 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 },
|
||||
{ 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 },
|
||||
{ 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 },
|
||||
{ 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 },
|
||||
{ 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 },
|
||||
{ 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 },
|
||||
{ 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 },
|
||||
{ 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 },
|
||||
{ 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 },
|
||||
{ 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 },
|
||||
{ 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 },
|
||||
{ 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 },
|
||||
{ 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 },
|
||||
{ 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 },
|
||||
{ 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 },
|
||||
{ 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 },
|
||||
{ 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 },
|
||||
{ 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1 },
|
||||
{ 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1 },
|
||||
{ 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1 },
|
||||
{ 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 },
|
||||
{ 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 },
|
||||
{ 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 },
|
||||
{ 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 },
|
||||
{ 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1 },
|
||||
{ 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1 },
|
||||
{ 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1 },
|
||||
{ 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1 },
|
||||
{ 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 },
|
||||
{ 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 },
|
||||
{ 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 },
|
||||
{ 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 },
|
||||
{ 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1 },
|
||||
{ 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1 },
|
||||
{ 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1 },
|
||||
{ 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 },
|
||||
{ 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 },
|
||||
{ 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 },
|
||||
{ 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1 },
|
||||
{ 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1 },
|
||||
{ 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1 },
|
||||
{ 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1 },
|
||||
{ 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 },
|
||||
{ 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 },
|
||||
{ 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 },
|
||||
{ 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1 },
|
||||
{ 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1 },
|
||||
{ 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1 },
|
||||
{ 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1 },
|
||||
{ 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 },
|
||||
{ 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1 },
|
||||
{ 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1 },
|
||||
{ 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1 },
|
||||
{ 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1 },
|
||||
{ 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1 },
|
||||
{ 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 },
|
||||
{ 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 },
|
||||
{ 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 },
|
||||
{ 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1 },
|
||||
{ 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1 },
|
||||
{ 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1 },
|
||||
{ 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1 },
|
||||
{ 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 },
|
||||
{ 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 },
|
||||
{ 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
|
||||
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } };
|
||||
}
|
||||
|
||||
/// Given a grid cube and an isolevel the triangles (5 max)
|
||||
/// required to represent the isosurface in the cube are computed.
|
||||
void MeshReconstruction::Triangulate(
|
||||
IntersectInfo const& intersect,
|
||||
Fun3v const& grad,
|
||||
Mesh& mesh)
|
||||
{
|
||||
// Cube is entirely in/out of the surface. Generate no triangles.
|
||||
if (intersect.signConfig == 0 || intersect.signConfig == 255) return;
|
||||
|
||||
auto const& tri = signConfigToTriangles[intersect.signConfig];
|
||||
|
||||
for (auto i = 0; tri[i] != -1; i += 3)
|
||||
{
|
||||
auto const& v0 = intersect.edgeVertIndices[tri[i]];
|
||||
auto const& v1 = intersect.edgeVertIndices[tri[i + 1]];
|
||||
auto const& v2 = intersect.edgeVertIndices[tri[i + 2]];
|
||||
|
||||
mesh.vertices.push_back(v0);
|
||||
mesh.vertices.push_back(v1);
|
||||
mesh.vertices.push_back(v2);
|
||||
|
||||
auto normal0 = grad(v0).Normalized();
|
||||
auto normal1 = grad(v1).Normalized();
|
||||
auto normal2 = grad(v2).Normalized();
|
||||
|
||||
mesh.vertexNormals.push_back(normal0);
|
||||
mesh.vertexNormals.push_back(normal1);
|
||||
mesh.vertexNormals.push_back(normal2);
|
||||
|
||||
auto last = static_cast<int>(mesh.vertices.size() - 1);
|
||||
|
||||
mesh.triangles.push_back({ last - 2, last - 1, last });
|
||||
}
|
||||
}
|
11
external/MeshReconstruction/lib/Triangulation.h
vendored
Normal file
11
external/MeshReconstruction/lib/Triangulation.h
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "Cube.h"
|
||||
#include "DataStructs.h"
|
||||
|
||||
namespace MeshReconstruction
|
||||
{
|
||||
void Triangulate(
|
||||
IntersectInfo const& intersect,
|
||||
Fun3v const& grad,
|
||||
Mesh& mesh);
|
||||
}
|
BIN
external/MeshReconstruction/numberings.png
vendored
Normal file
BIN
external/MeshReconstruction/numberings.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
BIN
external/MeshReconstruction/overview.png
vendored
Normal file
BIN
external/MeshReconstruction/overview.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 107 KiB |
5
notes_réparation_bac.txt
Normal file
5
notes_réparation_bac.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Notes du TP de réparation de maillage par surface implicite de Mme Bac
|
||||
|
||||
Fonction implicite f(x) = Σ(1,n)[αi φ(||X-Xi||) + …]
|
||||
|
||||
φ(r) = r²ln(r) : fonction radiale, une par point, =0 au point
|
58
src/hole_filling.cpp
Normal file
58
src/hole_filling.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "hole_filling.h"
|
||||
#include "util.h"
|
||||
#include <MeshReconstruction.h>
|
||||
|
||||
|
||||
static std::vector<std::vector<HalfedgeHandle>> findHoles(MyMesh &mesh) {
|
||||
std::vector<std::vector<HalfedgeHandle>> holes;
|
||||
std::set<HalfedgeHandle> ignore;
|
||||
for (HalfedgeHandle it : mesh.halfedges()) {
|
||||
if (mesh.is_boundary(it)
|
||||
&& ignore.find(it) == ignore.end()) {
|
||||
holes.emplace_back();
|
||||
holes.back().push_back(it);
|
||||
ignore.insert(it);
|
||||
for (HalfedgeHandle it2 : HalfedgeLoopRange<MyMesh>(mesh, it)) {
|
||||
holes.back().push_back(it2);
|
||||
ignore.insert(it2);
|
||||
}
|
||||
}
|
||||
}
|
||||
return holes;
|
||||
}
|
||||
|
||||
|
||||
void fillHoleDumb(MyMesh &mesh, std::vector<HalfedgeHandle> &hole) {
|
||||
mesh.request_vertex_status();
|
||||
mesh.request_edge_status();
|
||||
mesh.request_face_status();
|
||||
|
||||
Point center(0, 0, 0);
|
||||
size_t length = 0;
|
||||
for (HalfedgeHandle it : hole) {
|
||||
VertexHandle vert = mesh.to_vertex_handle(it);
|
||||
center += mesh.point(vert);
|
||||
length++;
|
||||
}
|
||||
center /= length;
|
||||
VertexHandle center_handle = mesh.new_vertex_dirty(center);
|
||||
mesh.set_color(center_handle, mesh.default_color);
|
||||
|
||||
for (HalfedgeHandle it : hole) {
|
||||
mesh.add_face(mesh.from_vertex_handle(it),
|
||||
mesh.to_vertex_handle(it),
|
||||
center_handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fillHolesDumb(MyMesh &mesh) {
|
||||
mesh.holes = findHoles(mesh);
|
||||
for (auto hole : mesh.holes) {
|
||||
fillHoleDumb(mesh, hole);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fillHolesImplicit(MyMesh &mesh) {
|
||||
}
|
13
src/hole_filling.h
Normal file
13
src/hole_filling.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef HOLE_FILLING_H
|
||||
#define HOLE_FILLING_H
|
||||
|
||||
#include "my_mesh.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
void fillHoleDumb(MyMesh &mesh, std::vector<HalfedgeHandle> &hole);
|
||||
void fillHolesDumb(MyMesh &mesh);
|
||||
void fillHolesImplicit(MyMesh &mesh);
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user