Geometry Nodes: Add 'Fill Interior' option to Mesh to SDF Volume #107827

Closed
Erik Abrahamsson wants to merge 1 commits from erik85/blender:mesh-to-sdf-fill into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
3 changed files with 26 additions and 9 deletions

View File

@ -52,7 +52,11 @@ VolumeGrid *fog_volume_grid_add_from_mesh(Volume *volume,
/**
* Add a new SDF VolumeGrid to the Volume by converting the supplied mesh.
*/
VolumeGrid *sdf_volume_grid_add_from_mesh(
Volume *volume, StringRefNull name, const Mesh &mesh, float voxel_size, float half_band_width);
VolumeGrid *sdf_volume_grid_add_from_mesh(Volume *volume,
StringRefNull name,
const Mesh &mesh,
float voxel_size,
float half_band_width,
bool fill_interior);
#endif
} // namespace blender::geometry

View File

@ -141,7 +141,8 @@ static openvdb::FloatGrid::Ptr mesh_to_fog_volume_grid(
static openvdb::FloatGrid::Ptr mesh_to_sdf_volume_grid(const Mesh &mesh,
const float voxel_size,
const float half_band_width)
const float half_band_width,
const bool fill_interior)
{
if (voxel_size <= 0.0f || half_band_width <= 0.0f) {
return nullptr;
@ -153,6 +154,7 @@ static openvdb::FloatGrid::Ptr mesh_to_sdf_volume_grid(const Mesh &mesh,
std::vector<openvdb::Vec3s> points(positions.size());
std::vector<openvdb::Vec3I> triangles(looptris.size());
std::vector<openvdb::Vec4I> quads(0);
threading::parallel_for(positions.index_range(), 2048, [&](const IndexRange range) {
for (const int i : range) {
@ -169,11 +171,15 @@ static openvdb::FloatGrid::Ptr mesh_to_sdf_volume_grid(const Mesh &mesh,
corner_verts[loop_tri.tri[2]]);
}
});
openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform(
voxel_size);
openvdb::FloatGrid::Ptr new_grid = openvdb::tools::meshToLevelSet<openvdb::FloatGrid>(
*transform, points, triangles, half_band_width);
openvdb::FloatGrid::Ptr new_grid = openvdb::tools::meshToSignedDistanceField<openvdb::FloatGrid>(
*transform,
points,
triangles,
quads,
half_band_width,
fill_interior ? std::numeric_limits<float>::max() : half_band_width);
return new_grid;
}
@ -195,9 +201,11 @@ VolumeGrid *sdf_volume_grid_add_from_mesh(Volume *volume,
const StringRefNull name,
const Mesh &mesh,
const float voxel_size,
const float half_band_width)
const float half_band_width,
const bool fill_interior)
{
openvdb::FloatGrid::Ptr mesh_grid = mesh_to_sdf_volume_grid(mesh, voxel_size, half_band_width);
openvdb::FloatGrid::Ptr mesh_grid = mesh_to_sdf_volume_grid(
mesh, voxel_size, half_band_width, fill_interior);
return mesh_grid ? BKE_volume_grid_add_vdb(*volume, name, std::move(mesh_grid)) : nullptr;
}
} // namespace blender::geometry

View File

@ -39,6 +39,9 @@ static void node_declare(NodeDeclarationBuilder &b)
.default_value(3.0f)
.min(1.01f)
.max(10.0f);
b.add_input<decl::Bool>(N_("Fill Interior"))
.default_value(false)
.description(N_("Fill the entire interior of the mesh with distance values"));
Review

Maybe "with distance values" could be more clear as "with a gradient" or something

Maybe "with distance values" could be more clear as "with a gradient" or something
b.add_output<decl::Geometry>(CTX_N_(BLT_I18NCONTEXT_ID_ID, "Volume"))
.translation_context(BLT_I18NCONTEXT_ID_ID);
}
@ -91,6 +94,7 @@ static Volume *create_volume_from_mesh(const Mesh &mesh, GeoNodeExecParams &para
const NodeGeometryMeshToVolume &storage = node_storage(params.node());
const float half_band_width = params.get_input<float>("Half-Band Width");
const bool fill_interior = params.get_input<bool>("Fill Interior");
geometry::MeshToVolumeResolution resolution;
resolution.mode = (MeshToVolumeModifierResolutionMode)storage.resolution_mode;
@ -132,7 +136,8 @@ static Volume *create_volume_from_mesh(const Mesh &mesh, GeoNodeExecParams &para
Volume *volume = reinterpret_cast<Volume *>(BKE_id_new_nomain(ID_VO, nullptr));
/* Convert mesh to grid and add to volume. */
geometry::sdf_volume_grid_add_from_mesh(volume, "distance", mesh, voxel_size, half_band_width);
geometry::sdf_volume_grid_add_from_mesh(
volume, "distance", mesh, voxel_size, half_band_width, fill_interior);
return volume;
}