Geometry Nodes: Add 'Fill Interior' option to Mesh to SDF Volume #107827
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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"));
|
||||||
|
|||||||
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 ¶
|
|||||||
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 ¶
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user
Maybe "with distance values" could be more clear as "with a gradient" or something