supereight
Loading...
Searching...
No Matches
marching_cube.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016-2019 Emanuele Vespa
3 * SPDX-FileCopyrightText: 2020-2021 Smart Robotics Lab, Imperial College London, Technical University of Munich
4 * SPDX-FileCopyrightText: 2020-2021 Nils Funk
5 * SPDX-FileCopyrightText: 2021 Sotiris Papatheodorou
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9#ifndef SE_MARCHING_CUBE_HPP
10#define SE_MARCHING_CUBE_HPP
11
13#include <se/common/timings.hpp>
18
19namespace se {
20namespace meshing {
21
23
24template<typename OctreeT>
25Eigen::Vector3f compute_intersection(const OctreeT& octree,
26 const Eigen::Vector3i& coord_0,
27 const Eigen::Vector3i& coord_1);
28
29template<typename OctreeT>
30Eigen::Vector3f
31interp_vertexes(const OctreeT& octree, const int x, const int y, const int z, const int edge);
32
33template<typename BlockT>
34void gather_data(const BlockT* block,
35 typename BlockT::DataType data[8],
36 const int x,
37 const int y,
38 const int z);
39
40template<typename OctreeT>
42 typename OctreeT::DataType data[8],
43 const int x,
44 const int y,
45 const int z);
46
47template<typename OctreeT>
49 const typename OctreeT::BlockType* block_ptr,
50 const int x,
51 const int y,
52 const int z);
53
54
55
57
58template<typename DataT>
59Eigen::Vector3f compute_dual_intersection(const DataT& data_0,
60 const DataT& data_1,
61 const Eigen::Vector3f& dual_point_0_M,
62 const Eigen::Vector3f& dual_point_1_M);
63
64template<typename DataT, typename ValueSelector>
65Eigen::Vector3f interp_dual_vertexes(const int edge,
66 const DataT data[8],
67 const std::array<Eigen::Vector3f, 8>& dual_corner_coords_f);
68
69/*
70 * Normalised offsets of the dual corners from the primal corner
71 */
72static const Eigen::Vector3f norm_dual_offset_f[8] = {{-1, -1, -1},
73 {+1, -1, -1},
74 {+1, -1, +1},
75 {-1, -1, +1},
76 {-1, +1, -1},
77 {+1, +1, -1},
78 {+1, +1, +1},
79 {-1, +1, +1}};
80
81template<typename BlockT, typename DataT>
82void gather_dual_data(const BlockT* block,
83 const int scale,
84 const Eigen::Vector3f& primal_corner_coord_f,
85 DataT data[8],
86 std::array<Eigen::Vector3f, 8>& dual_corner_coords_f,
87 std::array<Eigen::Vector3i, 8>& dual_corner_coords_i);
88
110inline void norm_dual_corner_idxs(const Eigen::Vector3i& primal_corner_coord_rel,
111 const int block_size,
114 BoundedVector<BoundedVector<int, 8>, 8>& neighbours);
115
116/*
117 * Normalised offsets of the primal corners from the primal corner
118 * The correct coordinates would be {-0.5, -0.5, -0.5}, {0.5, -0.5, -0.5}, ...
119 * However this would cause a lot of extra computations to cast the voxels back and forth and
120 * to make sure that the absolute coordinates {-0.5, y, z} won't be casted to {0, y, z} (and for y, z accordingly).
121 */
122static const Eigen::Vector3i logical_dual_offset[8] = {{-1, -1, -1},
123 {+0, -1, -1},
124 {+0, -1, +0},
125 {-1, -1, +0},
126 {-1, +0, -1},
127 {+0, +0, -1},
128 {+0, +0, +0},
129 {-1, +0, +0}};
130
131template<typename OctreeT, typename DataT>
133 const typename OctreeT::BlockType* block,
134 const int scale,
135 const Eigen::Vector3i& primal_corner_coord,
136 DataT data[8],
137 std::array<Eigen::Vector3f, 8>& dual_corner_coords_f,
138 std::array<Eigen::Vector3i, 8>& dual_corner_coords_i);
139
140template<typename OctreeT, typename DataT>
142 const typename OctreeT::BlockType* block_ptr,
143 const int scale,
144 const Eigen::Vector3i& primal_corner_coord,
146 DataT data[8],
147 std::array<Eigen::Vector3f, 8>& dual_corner_coords_f,
148 std::array<Eigen::Vector3i, 8>& dual_corner_coords_i);
149
150inline bool checkVertex(const Eigen::Vector3f& vertex_M, const float dim);
151
152} // namespace meshing
153
154
155
156namespace algorithms {
157
158template<typename OctreeT, typename = std::enable_if_t<OctreeT::res_ == se::Res::Single>>
159typename OctreeT::SurfaceMesh
161 const std::vector<const typename OctreeT::BlockType*>& block_ptrs);
162
163template<typename OctreeT, typename = std::enable_if_t<OctreeT::res_ == se::Res::Multi>>
164typename OctreeT::SurfaceMesh
166 const std::vector<const typename OctreeT::BlockType*>& block_ptrs,
167 const int min_desired_scale);
168
169template<typename OctreeT>
170std::vector<meshing::VertexIndexMesh<3>>
172 const std::vector<const typename OctreeT::BlockType*>& block_ptrs);
173
174template<typename OctreeT>
177 const std::vector<const typename OctreeT::BlockType*>& block_ptrs);
178
179template<typename OctreeT>
181
182
187template<typename OctreeT>
188typename OctreeT::SurfaceMesh marching_cube(const OctreeT& octree, const int min_desired_scale = 0);
189
190} // namespace algorithms
191} // namespace se
192
193#include "impl/marching_cube_impl.hpp"
194
195#endif // SE_MARCHING_CUBE_HPP
Definition image.hpp:19
Definition mesh.hpp:96
OctreeT::SurfaceMesh marching_cube_kernel(const OctreeT &octree, const std::vector< const typename OctreeT::BlockType * > &block_ptrs)
std::vector< meshing::VertexIndexMesh< 3 > > dual_marching_cube_kernel_new(const OctreeT &octree, const std::vector< const typename OctreeT::BlockType * > &block_ptrs)
OctreeT::SurfaceMesh marching_cube(const OctreeT &octree, const int min_desired_scale=0)
Return a triangle mesh of the surface in octree.
meshing::VertexIndexMesh< 3 > dual_marching_cube_new(const OctreeT &octree, const std::vector< const typename OctreeT::BlockType * > &block_ptrs)
OctreeT::SurfaceMesh dual_marching_cube_kernel(const OctreeT &octree, const std::vector< const typename OctreeT::BlockType * > &block_ptrs, const int min_desired_scale)
void gather_dual_data(const BlockT *block, const int scale, const Eigen::Vector3f &primal_corner_coord_f, DataT data[8], std::array< Eigen::Vector3f, 8 > &dual_corner_coords_f, std::array< Eigen::Vector3i, 8 > &dual_corner_coords_i)
static const Eigen::Vector3i logical_dual_offset[8]
Definition marching_cube.hpp:122
Eigen::Vector3f interp_vertexes(const OctreeT &octree, const int x, const int y, const int z, const int edge)
void gather_data(const BlockT *block, typename BlockT::DataType data[8], const int x, const int y, const int z)
Eigen::Vector3f compute_intersection(const OctreeT &octree, const Eigen::Vector3i &coord_0, const Eigen::Vector3i &coord_1)
Single-res marching cube implementation.
static const Eigen::Vector3f norm_dual_offset_f[8]
Definition marching_cube.hpp:72
uint8_t compute_index(const OctreeT &octree, const typename OctreeT::BlockType *block_ptr, const int x, const int y, const int z)
Eigen::Vector3f interp_dual_vertexes(const int edge, const DataT data[8], const std::array< Eigen::Vector3f, 8 > &dual_corner_coords_f)
void compute_dual_index(const OctreeT &octree, const typename OctreeT::BlockType *block_ptr, const int scale, const Eigen::Vector3i &primal_corner_coord, uint8_t &edge_pattern_idx, DataT data[8], std::array< Eigen::Vector3f, 8 > &dual_corner_coords_f, std::array< Eigen::Vector3i, 8 > &dual_corner_coords_i)
Eigen::Vector3f compute_dual_intersection(const DataT &data_0, const DataT &data_1, const Eigen::Vector3f &dual_point_0_M, const Eigen::Vector3f &dual_point_1_M)
Multires-res marching cube implementation.
bool checkVertex(const Eigen::Vector3f &vertex_M, const float dim)
void norm_dual_corner_idxs(const Eigen::Vector3i &primal_corner_coord_rel, const int block_size, BoundedVector< int, 8 > &lower_priority_neighbours, BoundedVector< int, 8 > &higher_priority_neighbours, BoundedVector< BoundedVector< int, 8 >, 8 > &neighbours)
The following strategy is derived from I.
Helper wrapper to allocate and de-allocate octants in the octree.
Definition bounded_vector.hpp:14
std::vector< T, detail::ArrayAllocator< T, N > > BoundedVector
A statically-allocated std::vector that can store at most N elements.
Definition bounded_vector.hpp:79