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. * Add a new SDF VolumeGrid to the Volume by converting the supplied mesh.
*/ */
VolumeGrid *sdf_volume_grid_add_from_mesh( VolumeGrid *sdf_volume_grid_add_from_mesh(Volume *volume,
Volume *volume, StringRefNull name, const Mesh &mesh, float voxel_size, float half_band_width); StringRefNull name,
const Mesh &mesh,
float voxel_size,
float half_band_width,
bool fill_interior);
#endif #endif
} // namespace blender::geometry } // 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, static openvdb::FloatGrid::Ptr mesh_to_sdf_volume_grid(const Mesh &mesh,
const float voxel_size, 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) { if (voxel_size <= 0.0f || half_band_width <= 0.0f) {
return nullptr; 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::Vec3s> points(positions.size());
std::vector<openvdb::Vec3I> triangles(looptris.size()); std::vector<openvdb::Vec3I> triangles(looptris.size());
std::vector<openvdb::Vec4I> quads(0);
threading::parallel_for(positions.index_range(), 2048, [&](const IndexRange range) { threading::parallel_for(positions.index_range(), 2048, [&](const IndexRange range) {
for (const int i : 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]]); corner_verts[loop_tri.tri[2]]);
} }
}); });
openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform( openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform(
voxel_size); voxel_size);
openvdb::FloatGrid::Ptr new_grid = openvdb::tools::meshToLevelSet<openvdb::FloatGrid>( openvdb::FloatGrid::Ptr new_grid = openvdb::tools::meshToSignedDistanceField<openvdb::FloatGrid>(
*transform, points, triangles, half_band_width); *transform,
points,
triangles,
quads,
half_band_width,
fill_interior ? std::numeric_limits<float>::max() : half_band_width);
return new_grid; return new_grid;
} }
@ -195,9 +201,11 @@ VolumeGrid *sdf_volume_grid_add_from_mesh(Volume *volume,
const StringRefNull name, const StringRefNull name,
const Mesh &mesh, const Mesh &mesh,
const float voxel_size, 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; return mesh_grid ? BKE_volume_grid_add_vdb(*volume, name, std::move(mesh_grid)) : nullptr;
} }
} // namespace blender::geometry } // namespace blender::geometry

View File

@ -39,6 +39,9 @@ static void node_declare(NodeDeclarationBuilder &b)
.default_value(3.0f) .default_value(3.0f)
.min(1.01f) .min(1.01f)
.max(10.0f); .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")) b.add_output<decl::Geometry>(CTX_N_(BLT_I18NCONTEXT_ID_ID, "Volume"))
.translation_context(BLT_I18NCONTEXT_ID_ID); .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 NodeGeometryMeshToVolume &storage = node_storage(params.node());
const float half_band_width = params.get_input<float>("Half-Band Width"); 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; geometry::MeshToVolumeResolution resolution;
resolution.mode = (MeshToVolumeModifierResolutionMode)storage.resolution_mode; 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)); Volume *volume = reinterpret_cast<Volume *>(BKE_id_new_nomain(ID_VO, nullptr));
/* Convert mesh to grid and add to volume. */ /* 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; return volume;
} }