9 # include <openvdb/openvdb.h>
10 # include <openvdb/tools/GridTransformer.h>
11 # include <openvdb/tools/VolumeToMesh.h>
16 class OpenVDBMeshAdapter {
18 Span<MVert> vertices_;
20 Span<MLoopTri> looptris_;
25 size_t polygonCount()
const;
26 size_t pointCount()
const;
27 size_t vertexCount(
size_t UNUSED(polygon_index))
const;
28 void getIndexSpacePoint(
size_t polygon_index,
size_t vertex_index,
openvdb::Vec3d &
pos)
const;
37 looptris_ =
Span(looptris, looptris_len);
40 size_t OpenVDBMeshAdapter::polygonCount()
const
42 return static_cast<size_t>(looptris_.size());
45 size_t OpenVDBMeshAdapter::pointCount()
const
47 return static_cast<size_t>(vertices_.size());
50 size_t OpenVDBMeshAdapter::vertexCount(
size_t UNUSED(polygon_index))
const
56 void OpenVDBMeshAdapter::getIndexSpacePoint(
size_t polygon_index,
60 const MLoopTri &looptri = looptris_[polygon_index];
61 const MVert &vertex = vertices_[loops_[looptri.
tri[vertex_index]].v];
63 pos = &transformed_co.
x;
67 FunctionRef<
void(
float3 &r_min,
float3 &r_max)> bounds_fn,
68 const MeshToVolumeResolution res,
69 const float exterior_band_width,
73 if (volume_simplify == 0.0f) {
78 return res.settings.voxel_size / volume_simplify;
80 if (res.settings.voxel_amount <= 0) {
86 bounds_fn(bb_min, bb_max);
91 const float approximate_volume_side_length = diagonal + exterior_band_width * 2.0f;
92 const float voxel_size = approximate_volume_side_length / res.settings.voxel_amount /
98 const float4x4 &mesh_to_volume_space_transform,
99 const float voxel_size,
100 const bool fill_volume,
101 const float exterior_band_width,
102 const float interior_band_width,
105 if (voxel_size == 0.0f) {
109 float4x4 mesh_to_index_space_transform;
110 scale_m4_fl(mesh_to_index_space_transform.values, 1.0f / voxel_size);
111 mul_m4_m4_post(mesh_to_index_space_transform.values, mesh_to_volume_space_transform.values);
113 add_v3_fl(mesh_to_index_space_transform.values[3], -0.5f);
115 OpenVDBMeshAdapter mesh_adapter{*
mesh, mesh_to_index_space_transform};
118 const float exterior =
MAX2(0.001f, exterior_band_width / voxel_size);
119 const float interior =
MAX2(0.001f, interior_band_width / voxel_size);
124 new_grid = openvdb::tools::meshToVolume<openvdb::FloatGrid>(
125 mesh_adapter, {}, exterior, FLT_MAX);
128 new_grid = openvdb::tools::meshToVolume<openvdb::FloatGrid>(
129 mesh_adapter, {}, exterior, interior);
134 new_grid->beginValueOn(),
135 [
density](
const openvdb::FloatGrid::ValueOnIter &iter) { iter.setValue(density); });
141 const StringRefNull name,
143 const float4x4 &mesh_to_volume_space_transform,
144 const float voxel_size,
145 const bool fill_volume,
146 const float exterior_band_width,
147 const float interior_band_width,
152 BKE_volume_grid_openvdb_for_write(volume, c_grid,
false));
156 mesh_to_volume_space_transform,
164 grid->merge(*mesh_grid);
166 grid->setGridClass(openvdb::GRID_FOG_VOLUME);
168 grid->transform().postScale(voxel_size);
const struct MLoopTri * BKE_mesh_runtime_looptri_ensure(const struct Mesh *mesh)
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh)
struct VolumeGrid * BKE_volume_grid_add(struct Volume *volume, const char *name, VolumeGridType type)
float BKE_volume_simplify_factor(const struct Depsgraph *depsgraph)
void scale_m4_fl(float R[4][4], float scale)
void mul_m4_m4_post(float R[4][4], const float B[4][4])
MINLINE void add_v3_fl(float r[3], float f)
struct Depsgraph Depsgraph
@ MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
const Depsgraph * depsgraph
VecMat::Vec3< double > Vec3d
T distance(const T &a, const T &b)
static const pxr::TfToken density("density", pxr::TfToken::Immortal)