Geometry Nodes: Add volume grid creation nodes

Add three nodes to the currently experimental volume grid nodes:
- **Mesh to Density Grid**
- **Mesh to SDF Grid**
- **Points to SDF Grid**

These nodes are just wrappers over basic OpenVDB utilities.
The difference from existing volume nodes is that they output
a grid directly instead of a geometry set.

See the design here: https://devtalk.blender.org/t/volumes-in-geometry-nodes-proposal/31917

Pull Request: https://projects.blender.org/blender/blender/pulls/118761
This commit is contained in:
Hans Goudey
2024-02-28 22:15:10 +01:00
committed by Hans Goudey
parent 6d3b68c9df
commit bea33a6be9
12 changed files with 352 additions and 88 deletions

View File

@@ -410,7 +410,11 @@ class NODE_MT_geometry_node_GEO_MESH_OPERATIONS(Menu):
node_add_menu.add_node_type(layout, "GeometryNodeFlipFaces")
node_add_menu.add_node_type(layout, "GeometryNodeMeshBoolean")
node_add_menu.add_node_type(layout, "GeometryNodeMeshToCurve")
if context.preferences.experimental.use_new_volume_nodes:
node_add_menu.add_node_type(layout, "GeometryNodeMeshToDensityGrid")
node_add_menu.add_node_type(layout, "GeometryNodeMeshToPoints")
if context.preferences.experimental.use_new_volume_nodes:
node_add_menu.add_node_type(layout, "GeometryNodeMeshToSDFGrid")
node_add_menu.add_node_type(layout, "GeometryNodeMeshToVolume")
node_add_menu.add_node_type(layout, "GeometryNodeScaleElements")
node_add_menu.add_node_type(layout, "GeometryNodeSplitEdges")
@@ -476,6 +480,8 @@ class NODE_MT_category_GEO_POINT(Menu):
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodePoints")
node_add_menu.add_node_type(layout, "GeometryNodePointsToCurves")
if context.preferences.experimental.use_new_volume_nodes:
node_add_menu.add_node_type(layout, "GeometryNodePointsToSDFGrid")
node_add_menu.add_node_type(layout, "GeometryNodePointsToVertices")
node_add_menu.add_node_type(layout, "GeometryNodePointsToVolume")
layout.separator()

View File

@@ -1330,6 +1330,9 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define GEO_NODE_SORT_ELEMENTS 2123
#define GEO_NODE_MENU_SWITCH 2124
#define GEO_NODE_SAMPLE_GRID 2125
#define GEO_NODE_MESH_TO_DENSITY_GRID 2126
#define GEO_NODE_MESH_TO_SDF_GRID 2127
#define GEO_NODE_POINTS_TO_SDF_GRID 2128
/** \} */

View File

@@ -56,15 +56,19 @@ bke::VolumeGridData *fog_volume_grid_add_from_mesh(Volume *volume,
float voxel_size,
float interior_band_width,
float density);
/**
* Add a new SDF VolumeGrid to the Volume by converting the supplied mesh.
*/
bke::VolumeGridData *sdf_volume_grid_add_from_mesh(Volume *volume,
StringRefNull name,
Span<float3> positions,
Span<int> corner_verts,
Span<int3> corner_tris,
float voxel_size,
float half_band_width);
bke::VolumeGrid<float> mesh_to_density_grid(const Span<float3> positions,
const Span<int> corner_verts,
const Span<int3> corner_tris,
const float voxel_size,
const float interior_band_width,
const float density);
bke::VolumeGrid<float> mesh_to_sdf_grid(Span<float3> positions,
Span<int> corner_verts,
Span<int3> corner_tris,
float voxel_size,
float half_band_width);
#endif
} // namespace blender::geometry

View File

@@ -2,12 +2,8 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_function_ref.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_string_ref.hh"
#include "DNA_modifier_types.h"
#include "BKE_volume_grid_fwd.hh"
#pragma once
@@ -31,13 +27,10 @@ bke::VolumeGridData *fog_volume_grid_add_from_points(Volume *volume,
Span<float> radii,
float voxel_size,
float density);
/**
* Add a new SDF VolumeGrid to the Volume by converting the supplied points.
*/
bke::VolumeGridData *sdf_volume_grid_add_from_points(Volume *volume,
StringRefNull name,
Span<float3> positions,
Span<float> radii,
float voxel_size);
bke::VolumeGrid<float> points_to_sdf_grid(Span<float3> positions,
Span<float> radii,
float voxel_size);
#endif
} // namespace blender::geometry

View File

@@ -6,6 +6,7 @@
#include "BLI_task.hh"
#include "BKE_volume.hh"
#include "BKE_volume_grid.hh"
#include "BKE_volume_openvdb.hh"
#include "GEO_mesh_to_volume.hh"
@@ -109,7 +110,7 @@ float volume_compute_voxel_size(const Depsgraph *depsgraph,
return voxel_size / volume_simplify;
}
static openvdb::FloatGrid::Ptr mesh_to_fog_volume_grid(
static openvdb::FloatGrid::Ptr mesh_to_density_grid_impl(
const Span<float3> positions,
const Span<int> corner_verts,
const Span<int3> corner_tris,
@@ -147,14 +148,34 @@ static openvdb::FloatGrid::Ptr mesh_to_fog_volume_grid(
return new_grid;
}
static openvdb::FloatGrid::Ptr mesh_to_sdf_volume_grid(const Span<float3> positions,
const Span<int> corner_verts,
const Span<int3> corner_tris,
const float voxel_size,
const float half_band_width)
bke::VolumeGrid<float> mesh_to_density_grid(const Span<float3> positions,
const Span<int> corner_verts,
const Span<int3> corner_tris,
const float voxel_size,
const float interior_band_width,
const float density)
{
openvdb::FloatGrid::Ptr grid = mesh_to_density_grid_impl(positions,
corner_verts,
corner_tris,
float4x4::identity(),
voxel_size,
interior_band_width,
density);
if (!grid) {
return {};
}
return bke::VolumeGrid<float>(std::move(grid));
}
bke::VolumeGrid<float> mesh_to_sdf_grid(const Span<float3> positions,
const Span<int> corner_verts,
const Span<int3> corner_tris,
const float voxel_size,
const float half_band_width)
{
if (voxel_size <= 0.0f || half_band_width <= 0.0f) {
return nullptr;
return {};
}
std::vector<openvdb::Vec3s> points(positions.size());
@@ -180,7 +201,7 @@ static openvdb::FloatGrid::Ptr mesh_to_sdf_volume_grid(const Span<float3> positi
openvdb::FloatGrid::Ptr new_grid = openvdb::tools::meshToLevelSet<openvdb::FloatGrid>(
*transform, points, triangles, half_band_width);
return new_grid;
return bke::VolumeGrid<float>(std::move(new_grid));
}
bke::VolumeGridData *fog_volume_grid_add_from_mesh(Volume *volume,
@@ -193,27 +214,15 @@ bke::VolumeGridData *fog_volume_grid_add_from_mesh(Volume *volume,
const float interior_band_width,
const float density)
{
openvdb::FloatGrid::Ptr mesh_grid = mesh_to_fog_volume_grid(positions,
corner_verts,
corner_tris,
mesh_to_volume_space_transform,
voxel_size,
interior_band_width,
density);
openvdb::FloatGrid::Ptr mesh_grid = mesh_to_density_grid_impl(positions,
corner_verts,
corner_tris,
mesh_to_volume_space_transform,
voxel_size,
interior_band_width,
density);
return mesh_grid ? BKE_volume_grid_add_vdb(*volume, name, std::move(mesh_grid)) : nullptr;
}
bke::VolumeGridData *sdf_volume_grid_add_from_mesh(Volume *volume,
const StringRefNull name,
const Span<float3> positions,
const Span<int> corner_verts,
const Span<int3> corner_tris,
const float voxel_size,
const float half_band_width)
{
openvdb::FloatGrid::Ptr mesh_grid = mesh_to_sdf_volume_grid(
positions, corner_verts, corner_tris, voxel_size, half_band_width);
return mesh_grid ? BKE_volume_grid_add_vdb(*volume, name, std::move(mesh_grid)) : nullptr;
}
} // namespace blender::geometry
#endif

View File

@@ -5,6 +5,7 @@
#include "BLI_math_matrix.hh"
#include "BKE_volume.hh"
#include "BKE_volume_grid.hh"
#include "BKE_volume_openvdb.hh"
#include "GEO_points_to_volume.hh"
@@ -17,31 +18,47 @@
namespace blender::geometry {
/* Implements the interface required by #openvdb::tools::ParticlesToLevelSet. */
struct OpenVDBParticleList {
class OpenVDBParticleList {
public:
using PosType = openvdb::Vec3R;
Span<float3> positions;
Span<float> radii;
private:
Span<float3> positions_;
Span<float> radii_;
float voxel_size_inv_;
public:
OpenVDBParticleList(const Span<float3> positions,
const Span<float> radii,
const float voxel_size)
: positions_(positions), radii_(radii), voxel_size_inv_(math::rcp(voxel_size))
{
BLI_assert(voxel_size > 0.0f);
}
size_t size() const
{
return size_t(positions.size());
return size_t(positions_.size());
}
void getPos(size_t n, openvdb::Vec3R &xyz) const
{
xyz = &positions[n].x;
float3 pos = positions_[n] * voxel_size_inv_;
/* Better align generated grid with source points. */
pos -= float3(0.5f);
xyz = &pos.x;
}
void getPosRad(size_t n, openvdb::Vec3R &xyz, openvdb::Real &radius) const
{
xyz = &positions[n].x;
radius = radii[n];
this->getPos(n, xyz);
radius = radii_[n] * voxel_size_inv_;
}
};
static openvdb::FloatGrid::Ptr points_to_sdf_grid(const Span<float3> positions,
const Span<float> radii)
static openvdb::FloatGrid::Ptr points_to_sdf_grid_impl(const Span<float3> positions,
const Span<float> radii,
const float voxel_size)
{
/* Create a new grid that will be filled. #ParticlesToLevelSet requires
* the background value to be positive */
@@ -52,13 +69,23 @@ static openvdb::FloatGrid::Ptr points_to_sdf_grid(const Span<float3> positions,
/* Don't ignore particles based on their radius. */
op.setRmin(0.0f);
op.setRmax(std::numeric_limits<float>::max());
OpenVDBParticleList particles{positions, radii};
OpenVDBParticleList particles{positions, radii, voxel_size};
op.rasterizeSpheres(particles);
op.finalize();
new_grid->transform().postScale(voxel_size);
new_grid->setGridClass(openvdb::GRID_LEVEL_SET);
return new_grid;
}
bke::VolumeGrid<float> points_to_sdf_grid(const Span<float3> positions,
const Span<float> radii,
const float voxel_size)
{
return bke::VolumeGrid<float>(points_to_sdf_grid_impl(positions, radii, voxel_size));
}
bke::VolumeGridData *fog_volume_grid_add_from_points(Volume *volume,
const StringRefNull name,
const Span<float3> positions,
@@ -66,8 +93,7 @@ bke::VolumeGridData *fog_volume_grid_add_from_points(Volume *volume,
const float voxel_size,
const float density)
{
openvdb::FloatGrid::Ptr new_grid = points_to_sdf_grid(positions, radii);
new_grid->transform().postScale(voxel_size);
openvdb::FloatGrid::Ptr new_grid = points_to_sdf_grid_impl(positions, radii, voxel_size);
new_grid->setGridClass(openvdb::GRID_FOG_VOLUME);
/* Convert the level set to a fog volume. This also sets the background value to zero. Inside the
@@ -83,17 +109,5 @@ bke::VolumeGridData *fog_volume_grid_add_from_points(Volume *volume,
return BKE_volume_grid_add_vdb(*volume, name, std::move(new_grid));
}
bke::VolumeGridData *sdf_volume_grid_add_from_points(Volume *volume,
const StringRefNull name,
const Span<float3> positions,
const Span<float> radii,
const float voxel_size)
{
openvdb::FloatGrid::Ptr new_grid = points_to_sdf_grid(positions, radii);
new_grid->transform().postScale(voxel_size);
new_grid->setGridClass(openvdb::GRID_LEVEL_SET);
return BKE_volume_grid_add_vdb(*volume, name, std::move(new_grid));
}
} // namespace blender::geometry
#endif

View File

@@ -395,7 +395,9 @@ DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_ICO_SPHERE, 0, "MESH_PRIMITIVE_ICO
DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_LINE, 0, "MESH_PRIMITIVE_LINE",MeshLine, "Mesh Line", "Generate vertices in a line and connect them with edges")
DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_UV_SPHERE, 0, "MESH_PRIMITIVE_UV_SPHERE", MeshUVSphere, "UV Sphere", "Generate a spherical mesh with quads, except for triangles at the top and bottom")
DefNode(GeometryNode, GEO_NODE_MESH_TO_CURVE, 0, "MESH_TO_CURVE", MeshToCurve, "Mesh to Curve", "Generate a curve from a mesh")
DefNode(GeometryNode, GEO_NODE_MESH_TO_DENSITY_GRID, 0, "MESH_TO_DENSITY_GRID", MeshToDensityGrid, "Mesh to Density Grid", "Create a filled volume grid from a mesh")
DefNode(GeometryNode, GEO_NODE_MESH_TO_POINTS, 0, "MESH_TO_POINTS", MeshToPoints, "Mesh to Points", "Generate a point cloud from a mesh's vertices")
DefNode(GeometryNode, GEO_NODE_MESH_TO_SDF_GRID, 0, "MESH_TO_SDF_GRID", MeshToSDFGrid, "Mesh to SDF Grid", "Create a signed distance volume grid from a mesh")
DefNode(GeometryNode, GEO_NODE_MESH_TO_VOLUME, 0, "MESH_TO_VOLUME", MeshToVolume, "Mesh to Volume", "Create a fog volume with the shape of the input mesh's surface")
DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_EDGE, 0, "CORNERS_OF_EDGE", CornersOfEdge, "Corners of Edge", "Retrieve face corners connected to edges")
DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_FACE, 0, "CORNERS_OF_FACE", CornersOfFace, "Corners of Face", "Retrieve corners that make up a face")
@@ -408,6 +410,7 @@ DefNode(GeometryNode, GEO_NODE_MESH_TOPOLOGY_VERTEX_OF_CORNER, 0, "VERTEX_OF_COR
DefNode(GeometryNode, GEO_NODE_OBJECT_INFO, 0, "OBJECT_INFO", ObjectInfo, "Object Info", "Retrieve information from an object")
DefNode(GeometryNode, GEO_NODE_OFFSET_POINT_IN_CURVE, 0, "OFFSET_POINT_IN_CURVE", OffsetPointInCurve, "Offset Point in Curve", "Offset a control point index within its curve")
DefNode(GeometryNode, GEO_NODE_POINTS_TO_CURVES, 0, "POINTS_TO_CURVES", PointsToCurves, "Points to Curves", "Split all points to curve by its group ID and reorder by weight")
DefNode(GeometryNode, GEO_NODE_POINTS_TO_SDF_GRID, 0, "POINTS_TO_SDF_GRID", PointsToSDFGrid, "Points to SDF Grid", "Create a signed distance volume grid from points")
DefNode(GeometryNode, GEO_NODE_POINTS_TO_VERTICES, 0, "POINTS_TO_VERTICES", PointsToVertices, "Points to Vertices", "Generate a mesh vertex for each point cloud point")
DefNode(GeometryNode, GEO_NODE_POINTS_TO_VOLUME, 0, "POINTS_TO_VOLUME", PointsToVolume, "Points to Volume", "Generate a fog volume sphere around every point")
DefNode(GeometryNode, GEO_NODE_POINTS, 0, "POINTS", Points, "Points", "Generate a point cloud with positions and radii defined by fields")

View File

@@ -133,7 +133,9 @@ set(SRC
nodes/node_geo_mesh_primitive_uv_sphere.cc
nodes/node_geo_mesh_subdivide.cc
nodes/node_geo_mesh_to_curve.cc
nodes/node_geo_mesh_to_density_grid.cc
nodes/node_geo_mesh_to_points.cc
nodes/node_geo_mesh_to_sdf_grid.cc
nodes/node_geo_mesh_to_volume.cc
nodes/node_geo_mesh_topology_corners_of_edge.cc
nodes/node_geo_mesh_topology_corners_of_face.cc
@@ -147,6 +149,7 @@ set(SRC
nodes/node_geo_offset_point_in_curve.cc
nodes/node_geo_points.cc
nodes/node_geo_points_to_curves.cc
nodes/node_geo_points_to_sdf_grid.cc
nodes/node_geo_points_to_vertices.cc
nodes/node_geo_points_to_volume.cc
nodes/node_geo_proximity.cc

View File

@@ -0,0 +1,68 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BKE_mesh.hh"
#include "BKE_volume_grid.hh"
#include "GEO_mesh_to_volume.hh"
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_mesh_to_density_grid_cc {
NODE_STORAGE_FUNCS(NodeGeometryMeshToVolume)
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Mesh").supported_type(GeometryComponent::Type::Mesh);
b.add_input<decl::Float>("Density").default_value(1.0f).min(0.01f).max(FLT_MAX);
b.add_input<decl::Float>("Voxel Size")
.default_value(0.3f)
.min(0.01f)
.max(FLT_MAX)
.subtype(PROP_DISTANCE);
b.add_input<decl::Float>("Gradient Width")
.default_value(0.2f)
.min(0.0001f)
.max(FLT_MAX)
.subtype(PROP_DISTANCE)
.description("Width of the gradient inside of the mesh");
b.add_output<decl::Float>("Density Grid");
}
static void node_geo_exec(GeoNodeExecParams params)
{
#ifdef WITH_OPENVDB
const GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
const Mesh *mesh = geometry_set.get_mesh();
if (!mesh || mesh->faces_num == 0) {
params.set_default_remaining_outputs();
return;
}
bke::VolumeGrid<float> grid = geometry::mesh_to_density_grid(
mesh->vert_positions(),
mesh->corner_verts(),
mesh->corner_tris(),
params.extract_input<float>("Voxel Size"),
params.extract_input<float>("Gradient Width"),
params.extract_input<float>("Density"));
params.set_output("Density Grid", std::move(grid));
#else
node_geo_exec_with_missing_openvdb(params);
#endif
}
static void node_register()
{
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_MESH_TO_DENSITY_GRID, "Mesh to Density Grid", NODE_CLASS_GEOMETRY);
ntype.declare = node_declare;
ntype.geometry_node_execute = node_geo_exec;
nodeRegisterType(&ntype);
}
NOD_REGISTER_NODE(node_register)
} // namespace blender::nodes::node_geo_mesh_to_density_grid_cc

View File

@@ -0,0 +1,62 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BKE_mesh.hh"
#include "BKE_volume_grid.hh"
#include "GEO_mesh_to_volume.hh"
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_mesh_to_sdf_grid_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Mesh").supported_type(GeometryComponent::Type::Mesh);
b.add_input<decl::Float>("Voxel Size")
.default_value(0.3f)
.min(0.01f)
.max(FLT_MAX)
.subtype(PROP_DISTANCE);
b.add_input<decl::Int>("Band Width")
.default_value(3)
.min(0)
.max(100)
.description("Width of the active voxel surface, in voxels");
b.add_output<decl::Float>("SDF Grid");
}
static void node_geo_exec(GeoNodeExecParams params)
{
#ifdef WITH_OPENVDB
const GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
const Mesh *mesh = geometry_set.get_mesh();
if (!mesh || mesh->faces_num == 0) {
params.set_default_remaining_outputs();
return;
}
bke::VolumeGrid<float> grid = geometry::mesh_to_sdf_grid(
mesh->vert_positions(),
mesh->corner_verts(),
mesh->corner_tris(),
params.extract_input<float>("Voxel Size"),
params.extract_input<int>("Band Width"));
params.set_output("SDF Grid", std::move(grid));
#else
node_geo_exec_with_missing_openvdb(params);
#endif
}
static void node_register()
{
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MESH_TO_SDF_GRID, "Mesh to SDF Grid", NODE_CLASS_GEOMETRY);
ntype.declare = node_declare;
ntype.geometry_node_execute = node_geo_exec;
nodeRegisterType(&ntype);
}
NOD_REGISTER_NODE(node_register)
} // namespace blender::nodes::node_geo_mesh_to_sdf_grid_cc

View File

@@ -0,0 +1,114 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BKE_volume.hh"
#include "BKE_volume_grid.hh"
#include "GEO_points_to_volume.hh"
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_points_to_sdf_grid_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Points");
b.add_input<decl::Float>("Radius")
.default_value(0.5f)
.min(0.0f)
.subtype(PROP_DISTANCE)
.field_on_all();
b.add_input<decl::Float>("Voxel Size").default_value(0.3f).min(0.01f).subtype(PROP_DISTANCE);
b.add_output<decl::Float>("SDF Grid");
}
#ifdef WITH_OPENVDB
static void gather_positions_from_component(const GeometryComponent &component,
Vector<float3> &r_positions)
{
if (component.is_empty()) {
return;
}
const VArray<float3> positions = *component.attributes()->lookup<float3>("position");
r_positions.resize(r_positions.size() + positions.size());
positions.materialize(r_positions.as_mutable_span().take_back(positions.size()));
}
static void gather_radii_from_component(const GeometryComponent &component,
const Field<float> radius_field,
Vector<float> &r_radii)
{
if (component.is_empty()) {
return;
}
const bke::GeometryFieldContext field_context{component, AttrDomain::Point};
const int domain_num = component.attribute_domain_size(AttrDomain::Point);
r_radii.resize(r_radii.size() + domain_num);
fn::FieldEvaluator evaluator{field_context, domain_num};
evaluator.add_with_destination(radius_field, r_radii.as_mutable_span().take_back(domain_num));
evaluator.evaluate();
}
/**
* Initializes the VolumeComponent of a GeometrySet with a new Volume from points.
* The grid class should be either openvdb::GRID_FOG_VOLUME or openvdb::GRID_LEVEL_SET.
*/
static bke::VolumeGrid<float> points_to_grid(const GeometrySet &geometry_set,
const Field<float> &radius_field,
const float voxel_size)
{
const double determinant = std::pow(double(voxel_size), 3.0);
if (!BKE_volume_grid_determinant_valid(determinant)) {
return {};
}
Vector<float3> positions;
Vector<float> radii;
for (const GeometryComponent::Type type : {GeometryComponent::Type::Mesh,
GeometryComponent::Type::PointCloud,
GeometryComponent::Type::Curve})
{
if (const GeometryComponent *component = geometry_set.get_component(type)) {
gather_positions_from_component(*component, positions);
gather_radii_from_component(*component, radius_field, radii);
}
}
if (positions.is_empty()) {
return {};
}
return geometry::points_to_sdf_grid(positions, radii, voxel_size);
}
#endif /* WITH_OPENVDB */
static void node_geo_exec(GeoNodeExecParams params)
{
#ifdef WITH_OPENVDB
bke::VolumeGrid<float> grid = points_to_grid(params.extract_input<GeometrySet>("Points"),
params.extract_input<Field<float>>("Radius"),
params.extract_input<float>("Voxel Size"));
params.set_output("SDF Grid", std::move(grid));
#else
node_geo_exec_with_missing_openvdb(params);
#endif
}
static void node_register()
{
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_POINTS_TO_SDF_GRID, "Points to SDF Grid", NODE_CLASS_GEOMETRY);
ntype.declare = node_declare;
ntype.geometry_node_execute = node_geo_exec;
nodeRegisterType(&ntype);
}
NOD_REGISTER_NODE(node_register)
} // namespace blender::nodes::node_geo_points_to_sdf_grid_cc

View File

@@ -69,19 +69,6 @@ static float compute_voxel_size_from_amount(const float voxel_amount,
return voxel_size;
}
static void convert_to_grid_index_space(const float voxel_size,
MutableSpan<float3> positions,
MutableSpan<float> radii)
{
const float voxel_size_inv = 1.0f / voxel_size;
for (const int i : positions.index_range()) {
positions[i] *= voxel_size_inv;
/* Better align generated grid with source points. */
positions[i] -= float3(0.5f);
radii[i] *= voxel_size_inv;
}
}
/**
* Initializes the VolumeComponent of a GeometrySet with a new Volume from points.
* The grid class should be either openvdb::GRID_FOG_VOLUME or openvdb::GRID_LEVEL_SET.
@@ -128,8 +115,6 @@ static void initialize_volume_component_from_points(GeoNodeExecParams &params,
Volume *volume = reinterpret_cast<Volume *>(BKE_id_new_nomain(ID_VO, nullptr));
convert_to_grid_index_space(voxel_size, positions, radii);
const float density = params.get_input<float>("Density");
blender::geometry::fog_volume_grid_add_from_points(
volume, "density", positions, radii, voxel_size, density);