8#ifdef FEAT_HAVE_MESHHEXER
10#include <kernel/geometry/adaptive_mesh.hpp>
11#include <kernel/geometry/conformal_mesh.hpp>
12#include <kernel/geometry/meshhexer.hpp>
13#include <kernel/geometry/subdivision_levels.hpp>
14#include <kernel/shape.hpp>
17#include <meshhexer/meshhexer.hpp>
18#include <meshhexer/types.hpp>
22 MeshHexerSurfaceMesh::~MeshHexerSurfaceMesh()
24 delete static_cast<MeshHexer::SurfaceMesh*
>(_surface_mesh);
29 return static_cast<MeshHexer::SurfaceMesh*
>(_surface_mesh)->
is_closed();
54 std::vector<MeshHexer::Gap>
gaps =
static_cast<MeshHexer::SurfaceMesh*
>(_surface_mesh)->
gaps();
57 std::vector<Gap> result;
58 result.reserve(
gaps.size());
59 for(
const auto gap :
gaps)
61 result.emplace_back(gap.diameter, gap.confidence);
69 MeshHexer::Gap gap =
static_cast<MeshHexer::SurfaceMesh*
>(_surface_mesh)->
min_gap();
70 return {gap.diameter, gap.confidence};
73 template<
typename DataType_>
83 using AdaptiveMeshType = AdaptiveMesh<SchneidersTemplates, Shape::Hexahedron, 3, DataType_>;
85 auto data = prepare_fbm_mesh<DataType_>(x_min, y_min, z_min, x_max, y_max, z_max, levels);
87 AdaptiveMeshType amesh(data.first);
88 amesh.adapt(data.second, AdaptiveMeshType::ImportBehaviour::All);
90 return amesh.to_conformal_mesh(
Layer{amesh.num_layers() - 1});
93 template<
typename DataType_>
96 const MeshHexer::BoundingBox bb =
static_cast<MeshHexer::SurfaceMesh*
>(_surface_mesh)->bounding_box();
97 return fbm_mesh<DataType_>(
107 template<
typename DataType_>
115 std::uint64_t levels)
117 using MeshType = ConformalMesh<Shape::Hexahedron, 3, DataType_>;
118 using VertexType =
typename MeshType::VertexType;
120 MeshHexer::BoundingBox bb{
121 {double(x_min), double(y_min), double(z_min)},
122 {double(x_max), double(y_max), double(z_max)}};
123 MeshHexer::FBMMeshSettings settings{bb, levels};
125 MeshHexer::VolumeMesh vmesh =
static_cast<MeshHexer::SurfaceMesh*
>(_surface_mesh)->
fbm_mesh(settings);
127 SubdivisionLevels sdls(vmesh.num_vertices());
128 for(
Index i(0); i < vmesh.num_vertices(); i++)
130 sdls[i] = vmesh.subdivision_level(i);
133 std::array<Index, 4> size{vmesh.num_vertices(), vmesh.num_edges(), vmesh.num_faces(), vmesh.num_cells()};
134 ConformalMesh<Shape::Hexahedron, 3, DataType_> mesh(size.data());
138 auto& vertices = mesh.get_vertex_set();
139 for(
Index i(0); i < vmesh.num_vertices(); i++)
141 MeshHexer::Point p = vmesh.vertex(i);
142 vertices[i] = VertexType{p.x, p.y, p.z};
148 auto& v_at_e = mesh.template get_index_set<1, 0>();
149 for(
Index i(0); i < vmesh.num_edges(); i++)
151 v_at_e(i, 0) = vmesh.edge(i, 0);
152 v_at_e(i, 1) = vmesh.edge(i, 1);
158 auto& v_at_f = mesh.template get_index_set<2, 0>();
159 for(
Index i(0); i < vmesh.num_faces(); i++)
161 for(
int j(0); j < 4; j++)
163 v_at_f(i, j) = vmesh.face(i, std::size_t(j));
170 auto& v_at_c = mesh.template get_index_set<3, 0>();
171 for(
Index i(0); i < vmesh.num_cells(); i++)
173 for(
int j(0); j < 8; j++)
175 v_at_c(i, j) = vmesh.cell(i, std::size_t(j));
180 mesh.deduct_topology_from_top();
182 return std::make_pair(std::move(mesh), std::move(sdls));
185 template<
typename DataType_>
186 std::pair<ConformalMesh<Shape::Hexahedron, 3, DataType_>, SubdivisionLevels>
189 const MeshHexer::BoundingBox bb =
static_cast<MeshHexer::SurfaceMesh*
>(_surface_mesh)->bounding_box();
190 return prepare_fbm_mesh<DataType_>(
202 static_cast<MeshHexer::SurfaceMesh*
>(_surface_mesh)->
write_to_file(filename);
205 MeshHexerSurfaceMesh
load_from_file(
const String& filename,
bool triangulate)
207 auto result = MeshHexer::load_from_file(filename, triangulate);
211 std::cerr << result.err_ref() <<
"\n";
212 XABORTM(
"Reading MeshHexerSurfaceMesh failed!");
215 auto* mesh =
new MeshHexer::SurfaceMesh();
216 *mesh = std::move(result).take_ok();
218 return MeshHexerSurfaceMesh(mesh);
221 template ConformalMesh<Shape::Hexahedron, 3, double>
223 template ConformalMesh<Shape::Hexahedron, 3, float>
226 template std::pair<ConformalMesh<Shape::Hexahedron, 3, double>, SubdivisionLevels>
228 template std::pair<ConformalMesh<Shape::Hexahedron, 3, float>, SubdivisionLevels>
234 template std::pair<ConformalMesh<Shape::Hexahedron, 3, double>, SubdivisionLevels>
236 template std::pair<ConformalMesh<Shape::Hexahedron, 3, float>, SubdivisionLevels>
#define XABORTM(msg)
Abortion macro definition with custom message.
bool is_wound_consistently() const
Check if the winding order of the faces of the surface mesh is consistent.
bool is_outward_oriented() const
Check if the surface normals of all faces of the surface mesh point towards the unbounded side.
Gap min_gap()
Compute the smallest Gap of the surface mesh.
bool is_closed() const
Check if the surface mesh describes a closed surface.
ConformalMesh< Shape::Hexahedron, 3, DataType_ > fbm_mesh(DataType_ x_min, DataType_ y_min, DataType_ z_min, DataType_ x_max, DataType_ y_max, DataType_ z_max, std::uint64_t levels)
Create a non-fitted volume mesh for this surface mesh.
void write_to_file(const std::string &filename)
Write the surface mesh to disk.
std::pair< ConformalMesh< Shape::Hexahedron, 3, DataType_ >, SubdivisionLevels > prepare_fbm_mesh(DataType_ x_min, DataType_ y_min, DataType_ z_min, DataType_ x_max, DataType_ y_max, DataType_ z_max, std::uint64_t levels)
Create a non-fitted volume mesh for this surface mesh.
double minimal_aspect_ratio() const
Compute the smallest aspect ratio of any face of the surface mesh.
std::vector< Gap > gaps()
Compute Gap candidates of the surface mesh.
double maximal_aspect_ratio() const
Compute the largest aspect ratio of any face of the surface mesh.
Intern::Layer Layer
Re-export of layer type.
MeshHexerSurfaceMesh load_from_file(const String &filename, bool triangulate=false)
Load a surface mesh from a file.
std::uint64_t Index
Index data type.