Blender V4.5
node_geo_points_to_sdf_grid.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BKE_volume.hh"
6#include "BKE_volume_grid.hh"
7
9
10#include "node_geometry_util.hh"
11
13
15{
16 b.add_input<decl::Geometry>("Points");
17 b.add_input<decl::Float>("Radius")
18 .default_value(0.5f)
19 .min(0.0f)
21 .field_on_all();
22 b.add_input<decl::Float>("Voxel Size").default_value(0.3f).min(0.01f).subtype(PROP_DISTANCE);
23 b.add_output<decl::Float>("SDF Grid").structure_type(StructureType::Grid);
24}
25
26#ifdef WITH_OPENVDB
27
28static void gather_positions_from_component(const GeometryComponent &component,
29 Vector<float3> &r_positions)
30{
31 if (component.is_empty()) {
32 return;
33 }
34 const VArray<float3> positions = *component.attributes()->lookup<float3>("position");
35 r_positions.resize(r_positions.size() + positions.size());
36 positions.materialize(r_positions.as_mutable_span().take_back(positions.size()));
37}
38
39static void gather_radii_from_component(const GeometryComponent &component,
40 const Field<float> radius_field,
41 Vector<float> &r_radii)
42{
43 if (component.is_empty()) {
44 return;
45 }
46
47 const bke::GeometryFieldContext field_context{component, AttrDomain::Point};
48 const int domain_num = component.attribute_domain_size(AttrDomain::Point);
49
50 r_radii.resize(r_radii.size() + domain_num);
51 fn::FieldEvaluator evaluator{field_context, domain_num};
52 evaluator.add_with_destination(radius_field, r_radii.as_mutable_span().take_back(domain_num));
53 evaluator.evaluate();
54}
55
60static bke::VolumeGrid<float> points_to_grid(const GeometrySet &geometry_set,
61 const Field<float> &radius_field,
62 const float voxel_size)
63{
64 if (!BKE_volume_voxel_size_valid(float3(voxel_size))) {
65 return {};
66 }
67
68 Vector<float3> positions;
69 Vector<float> radii;
70 for (const GeometryComponent::Type type : {GeometryComponent::Type::Mesh,
71 GeometryComponent::Type::PointCloud,
72 GeometryComponent::Type::Curve})
73 {
74 if (const GeometryComponent *component = geometry_set.get_component(type)) {
75 gather_positions_from_component(*component, positions);
76 gather_radii_from_component(*component, radius_field, radii);
77 }
78 }
79
80 if (positions.is_empty()) {
81 return {};
82 }
83
84 return geometry::points_to_sdf_grid(positions, radii, voxel_size);
85}
86
87#endif /* WITH_OPENVDB */
88
90{
91#ifdef WITH_OPENVDB
92 bke::VolumeGrid<float> grid = points_to_grid(params.extract_input<GeometrySet>("Points"),
93 params.extract_input<Field<float>>("Radius"),
94 params.extract_input<float>("Voxel Size"));
95 if (grid) {
96 params.set_output("SDF Grid", std::move(grid));
97 }
98
99 params.set_default_remaining_outputs();
100#else
102#endif
103}
104
105static void node_register()
106{
107 static blender::bke::bNodeType ntype;
108
109 geo_node_type_base(&ntype, "GeometryNodePointsToSDFGrid", GEO_NODE_POINTS_TO_SDF_GRID);
110 ntype.ui_name = "Points to SDF Grid";
111 ntype.ui_description = "Create a signed distance volume grid from points";
112 ntype.enum_name_legacy = "POINTS_TO_SDF_GRID";
114 ntype.declare = node_declare;
118}
120
121} // namespace blender::nodes::node_geo_points_to_sdf_grid_cc
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:447
#define GEO_NODE_POINTS_TO_SDF_GRID
Volume data-block.
bool BKE_volume_voxel_size_valid(const blender::float3 &voxel_size)
float[3] Vector
#define NOD_REGISTER_NODE(REGISTER_FUNC)
@ PROP_DISTANCE
Definition RNA_types.hh:244
int64_t size() const
bool is_empty() const
void resize(const int64_t new_size)
MutableSpan< T > as_mutable_span()
void materialize(MutableSpan< T > r_span) const
int64_t size() const
void resize(const int64_t new_size)
MutableSpan< T > as_mutable_span()
virtual std::optional< AttributeAccessor > attributes() const
virtual bool is_empty() const
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_register_type(bNodeType &ntype)
Definition node.cc:2748
static void node_declare(NodeDeclarationBuilder &b)
void search_link_ops_for_volume_grid_node(GatherLinkSearchOpParams &params)
void node_geo_exec_with_missing_openvdb(GeoNodeExecParams &params)
VecBase< float, 3 > float3
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
const GeometryComponent * get_component(GeometryComponent::Type component_type) const
Defines a node type.
Definition BKE_node.hh:226
std::string ui_description
Definition BKE_node.hh:232
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:347
const char * enum_name_legacy
Definition BKE_node.hh:235
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition BKE_node.hh:371
NodeDeclareFunction declare
Definition BKE_node.hh:355