16# include <openvdb/openvdb.h>
17# include <openvdb/tools/GridTransformer.h>
18# include <openvdb/tools/LevelSetUtil.h>
19# include <openvdb/tools/VolumeToMesh.h>
24class OpenVDBMeshAdapter {
26 Span<float3> positions_;
27 Span<int> corner_verts_;
28 Span<int3> corner_tris_;
32 OpenVDBMeshAdapter(
const Span<float3> positions,
33 const Span<int> corner_verts,
34 const Span<int3> corner_tris,
35 const float4x4 &transform);
36 size_t polygonCount()
const;
37 size_t pointCount()
const;
38 size_t vertexCount(
size_t )
const;
39 void getIndexSpacePoint(
size_t polygon_index,
size_t vertex_index, openvdb::Vec3d &
pos)
const;
42OpenVDBMeshAdapter::OpenVDBMeshAdapter(
const Span<float3> positions,
43 const Span<int> corner_verts,
44 const Span<int3> corner_tris,
46 : positions_(positions),
47 corner_verts_(corner_verts),
48 corner_tris_(corner_tris),
53size_t OpenVDBMeshAdapter::polygonCount()
const
55 return size_t(corner_tris_.size());
58size_t OpenVDBMeshAdapter::pointCount()
const
60 return size_t(positions_.size());
63size_t OpenVDBMeshAdapter::vertexCount(
size_t )
const
69void OpenVDBMeshAdapter::getIndexSpacePoint(
size_t polygon_index,
71 openvdb::Vec3d &
pos)
const
73 const int3 &tri = corner_tris_[polygon_index];
75 transform_, positions_[corner_verts_[tri[vertex_index]]]);
76 pos = &transformed_co.
x;
79float volume_compute_voxel_size(
const Depsgraph *
depsgraph,
80 const FunctionRef<Bounds<float3>()> bounds_fn,
81 const MeshToVolumeResolution res,
82 const float exterior_band_width,
83 const float4x4 &transform)
86 if (volume_simplify == 0.0f) {
91 return res.settings.voxel_size / volume_simplify;
93 if (res.settings.voxel_amount <= 0) {
97 const Bounds<float3>
bounds = bounds_fn();
106 const float voxel_size =
107 (diagonal / std::max(1.0f,
float(res.settings.voxel_amount) - 2.0f * exterior_band_width));
110 return voxel_size / volume_simplify;
113static openvdb::FloatGrid::Ptr mesh_to_density_grid_impl(
114 const Span<float3> positions,
115 const Span<int> corner_verts,
116 const Span<int3> corner_tris,
117 const float4x4 &mesh_to_volume_space_transform,
118 const float voxel_size,
119 const float interior_band_width,
122 if (voxel_size < 1e-5f) {
127 mesh_to_index_space_transform *= mesh_to_volume_space_transform;
129 mesh_to_index_space_transform.location() -= 0.5f;
131 OpenVDBMeshAdapter mesh_adapter{
132 positions, corner_verts, corner_tris, mesh_to_index_space_transform};
133 const float interior = std::max(1.0f, interior_band_width / voxel_size);
135 openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform(
137 openvdb::FloatGrid::Ptr new_grid = openvdb::tools::meshToVolume<openvdb::FloatGrid>(
138 mesh_adapter, *transform, 1.0f, interior);
140 openvdb::tools::sdfToFogVolume(*new_grid);
142 if (density != 1.0f) {
143 openvdb::tools::foreach (new_grid->beginValueOn(),
144 [&](
const openvdb::FloatGrid::ValueOnIter &iter) {
145 iter.modifyValue([&](float &value) { value *= density; });
151bke::VolumeGrid<float> mesh_to_density_grid(
const Span<float3> positions,
152 const Span<int> corner_verts,
153 const Span<int3> corner_tris,
154 const float voxel_size,
155 const float interior_band_width,
158 openvdb::FloatGrid::Ptr grid = mesh_to_density_grid_impl(positions,
161 float4x4::identity(),
168 return bke::VolumeGrid<float>(std::move(grid));
171bke::VolumeGrid<float> mesh_to_sdf_grid(
const Span<float3> positions,
172 const Span<int> corner_verts,
173 const Span<int3> corner_tris,
174 const float voxel_size,
175 const float half_band_width)
177 if (voxel_size <= 0.0f || half_band_width <= 0.0f) {
181 std::vector<openvdb::Vec3s> points(positions.size());
182 std::vector<openvdb::Vec3I> triangles(corner_tris.size());
184 threading::parallel_for(positions.index_range(), 2048, [&](
const IndexRange range) {
185 for (const int i : range) {
186 const float3 &co = positions[i];
187 points[i] = openvdb::Vec3s(co.x, co.y, co.z) - 0.5f * voxel_size;
191 threading::parallel_for(corner_tris.index_range(), 2048, [&](
const IndexRange range) {
192 for (const int i : range) {
193 const int3 &tri = corner_tris[i];
194 triangles[i] = openvdb::Vec3I(
195 corner_verts[tri[0]], corner_verts[tri[1]], corner_verts[tri[2]]);
199 openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform(
201 openvdb::FloatGrid::Ptr new_grid = openvdb::tools::meshToLevelSet<openvdb::FloatGrid>(
202 *transform, points, triangles, half_band_width);
204 return bke::VolumeGrid<float>(std::move(new_grid));
207bke::VolumeGridData *fog_volume_grid_add_from_mesh(
Volume *volume,
208 const StringRefNull name,
209 const Span<float3> positions,
210 const Span<int> corner_verts,
211 const Span<int3> corner_tris,
212 const float4x4 &mesh_to_volume_space_transform,
213 const float voxel_size,
214 const float interior_band_width,
217 openvdb::FloatGrid::Ptr mesh_grid = mesh_to_density_grid_impl(positions,
220 mesh_to_volume_space_transform,
224 return mesh_grid ? BKE_volume_grid_add_vdb(*volume, name, std::move(mesh_grid)) : nullptr;
float BKE_volume_simplify_factor(const Depsgraph *depsgraph)
@ MESH_TO_VOLUME_RESOLUTION_MODE_VOXEL_SIZE
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
const Depsgraph * depsgraph
T distance(const T &a, const T &b)
MatT from_scale(const VecBase< typename MatT::base_type, ScaleDim > &scale)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
MatBase< float, 4, 4 > float4x4