31 # include <openvdb/tools/GridTransformer.h>
32 # include <openvdb/tools/VolumeToMesh.h>
41 struct VolumeToMeshOp {
42 const openvdb::GridBase &base_grid;
43 const VolumeToMeshResolution resolution;
44 const float threshold;
45 const float adaptivity;
46 std::vector<openvdb::Vec3s>
verts;
47 std::vector<openvdb::Vec3I> tris;
48 std::vector<openvdb::Vec4I> quads;
52 if constexpr (std::is_scalar_v<typename GridType::ValueType>) {
53 this->generate_mesh_data<GridType>();
59 template<
typename Gr
idType>
void generate_mesh_data()
61 const GridType &grid =
static_cast<const GridType &
>(base_grid);
64 this->grid_to_mesh(grid);
68 const float resolution_factor = this->compute_resolution_factor(base_grid);
69 typename GridType::Ptr temp_grid = this->create_grid_with_changed_resolution(
70 grid, resolution_factor);
71 this->grid_to_mesh(*temp_grid);
74 template<
typename Gr
idType>
75 typename GridType::Ptr create_grid_with_changed_resolution(
const GridType &old_grid,
76 const float resolution_factor)
82 openvdb::tools::GridTransformer transformer{xform};
84 typename GridType::Ptr new_grid = GridType::create();
85 transformer.transformGrid<openvdb::tools::BoxSampler>(old_grid, *new_grid);
86 new_grid->transform() = old_grid.transform();
87 new_grid->transform().preScale(1.0f / resolution_factor);
91 float compute_resolution_factor(
const openvdb::GridBase &grid)
const
93 const openvdb::Vec3s voxel_size{grid.voxelSize()};
94 const float current_voxel_size =
std::max({voxel_size[0], voxel_size[1], voxel_size[2]});
95 const float desired_voxel_size = this->compute_desired_voxel_size(grid);
96 return current_voxel_size / desired_voxel_size;
99 float compute_desired_voxel_size(
const openvdb::GridBase &grid)
const
102 return this->resolution.settings.voxel_size;
104 const openvdb::CoordBBox coord_bbox = base_grid.evalActiveVoxelBoundingBox();
105 const openvdb::BBoxd bbox = grid.transform().indexToWorld(coord_bbox);
106 const float max_extent = bbox.extents()[bbox.maxExtent()];
107 const float voxel_size = max_extent / this->resolution.settings.voxel_amount;
111 template<
typename Gr
idType>
void grid_to_mesh(
const GridType &grid)
113 openvdb::tools::volumeToMesh(
114 grid, this->verts, this->tris, this->quads, this->threshold, this->adaptivity);
117 openvdb::Vec3s offset = grid.voxelSize() / 2.0f;
118 for (openvdb::Vec3s &position : this->verts) {
124 static Mesh *new_mesh_from_openvdb_data(Span<openvdb::Vec3s>
verts,
125 Span<openvdb::Vec3I> tris,
126 Span<openvdb::Vec4I> quads)
128 const int tot_loops = 3 * tris.
size() + 4 * quads.size();
129 const int tot_polys = tris.size() + quads.size();
134 for (
const int i :
verts.index_range()) {
140 for (
const int i : tris.index_range()) {
143 for (
int j = 0; j < 3; j++) {
150 const int poly_offset = tris.size();
151 const int loop_offset = tris.size() * 3;
152 for (
const int i : quads.index_range()) {
155 for (
int j = 0; j < 4; j++) {
157 mesh->
mloop[loop_offset + 4 * i + j].
v = quads[i][3 - j];
166 Mesh *volume_to_mesh(
const openvdb::GridBase &grid,
167 const VolumeToMeshResolution &resolution,
168 const float threshold,
169 const float adaptivity)
171 const VolumeGridType grid_type = BKE_volume_grid_type_openvdb(grid);
173 VolumeToMeshOp to_mesh_op{grid, resolution, threshold, adaptivity};
174 if (!BKE_volume_grid_type_operation(grid_type, to_mesh_op)) {
178 return new_mesh_from_openvdb_data(to_mesh_op.verts, to_mesh_op.tris, to_mesh_op.quads);
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
void BKE_mesh_calc_normals(struct Mesh *me)
void BKE_mesh_calc_edges(struct Mesh *mesh, bool keep_existing_edges, const bool select_new_edges)
MINLINE void copy_v3_v3(float r[3], const float a[3])
@ VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE
@ VOLUME_TO_MESH_RESOLUTION_MODE_GRID
VecMat::Vec3< double > Vec3d