From 281c785189fc1e52c6f1d1b202870bae576aa72f Mon Sep 17 00:00:00 2001 From: Erik Abrahamsson Date: Thu, 11 May 2023 00:31:49 +0200 Subject: [PATCH] Geometry Nodes: Add 'Fill Interior' option to Mesh to SDF Volume Adds an input socket 'Fill Interior to the Mesh to SDF Volume node. This will make the interior band fill the entire interior of the mesh. This is useful for example to be able to use the Threshold of 'Volume to Mesh' smoothly all the way down until the mesh disappears without needing to also increase the exterior band width. --- source/blender/geometry/GEO_mesh_to_volume.hh | 8 ++++++-- .../blender/geometry/intern/mesh_to_volume.cc | 20 +++++++++++++------ .../nodes/node_geo_mesh_to_sdf_volume.cc | 7 ++++++- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/source/blender/geometry/GEO_mesh_to_volume.hh b/source/blender/geometry/GEO_mesh_to_volume.hh index 98eff7a8999..866f80df006 100644 --- a/source/blender/geometry/GEO_mesh_to_volume.hh +++ b/source/blender/geometry/GEO_mesh_to_volume.hh @@ -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 diff --git a/source/blender/geometry/intern/mesh_to_volume.cc b/source/blender/geometry/intern/mesh_to_volume.cc index 2f41c9ba29c..8b029b9dce6 100644 --- a/source/blender/geometry/intern/mesh_to_volume.cc +++ b/source/blender/geometry/intern/mesh_to_volume.cc @@ -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 points(positions.size()); std::vector triangles(looptris.size()); + std::vector 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( - *transform, points, triangles, half_band_width); + openvdb::FloatGrid::Ptr new_grid = openvdb::tools::meshToSignedDistanceField( + *transform, + points, + triangles, + quads, + half_band_width, + fill_interior ? std::numeric_limits::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 diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_sdf_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_sdf_volume.cc index 05f096c1119..babc2612aaf 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_sdf_volume.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_sdf_volume.cc @@ -39,6 +39,9 @@ static void node_declare(NodeDeclarationBuilder &b) .default_value(3.0f) .min(1.01f) .max(10.0f); + b.add_input(N_("Fill Interior")) + .default_value(false) + .description(N_("Fill the entire interior of the mesh with distance values")); b.add_output(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 ¶ const NodeGeometryMeshToVolume &storage = node_storage(params.node()); const float half_band_width = params.get_input("Half-Band Width"); + const bool fill_interior = params.get_input("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 ¶ Volume *volume = reinterpret_cast(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; } -- 2.30.2