Blender V4.3
node_geo_sample_grid_index.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
6#include "BKE_volume_grid.hh"
8
9#include "NOD_rna_define.hh"
11
12#include "UI_interface.hh"
13#include "UI_resources.hh"
14
15#include "RNA_enum_types.hh"
16
17#include "node_geometry_util.hh"
18
20
22{
23 const bNode *node = b.node_or_null();
24 if (!node) {
25 return;
26 }
27 const eNodeSocketDatatype data_type = eNodeSocketDatatype(node->custom1);
28
29 b.add_input(data_type, "Grid").hide_value();
30 b.add_input<decl::Int>("X").supports_field();
31 b.add_input<decl::Int>("Y").supports_field();
32 b.add_input<decl::Int>("Z").supports_field();
33
34 b.add_output(data_type, "Value").dependent_field({1, 2, 3});
35}
36
37static std::optional<eNodeSocketDatatype> node_type_for_socket_type(const bNodeSocket &socket)
38{
39 switch (socket.type) {
40 case SOCK_FLOAT:
41 return SOCK_FLOAT;
42 case SOCK_BOOLEAN:
43 return SOCK_BOOLEAN;
44 case SOCK_INT:
45 return SOCK_INT;
46 case SOCK_VECTOR:
47 case SOCK_RGBA:
48 return SOCK_VECTOR;
49 default:
50 return std::nullopt;
51 }
52}
53
55{
56 if (!U.experimental.use_new_volume_nodes) {
57 return;
58 }
59 const std::optional<eNodeSocketDatatype> node_type = node_type_for_socket_type(
60 params.other_socket());
61 if (!node_type) {
62 return;
63 }
64 if (params.in_out() == SOCK_IN) {
65 params.add_item(IFACE_("Grid"), [node_type](LinkSearchOpParams &params) {
66 bNode &node = params.add_node("GeometryNodeSampleGridIndex");
67 node.custom1 = *node_type;
68 params.update_and_connect_available_socket(node, "Grid");
69 });
70 const eNodeSocketDatatype other_type = eNodeSocketDatatype(params.other_socket().type);
71 if (params.node_tree().typeinfo->validate_link(other_type, SOCK_INT)) {
72 params.add_item(IFACE_("X"), [](LinkSearchOpParams &params) {
73 bNode &node = params.add_node("GeometryNodeSampleGridIndex");
74 params.update_and_connect_available_socket(node, "X");
75 });
76 params.add_item(IFACE_("Y"), [](LinkSearchOpParams &params) {
77 bNode &node = params.add_node("GeometryNodeSampleGridIndex");
78 params.update_and_connect_available_socket(node, "Y");
79 });
80 params.add_item(IFACE_("Z"), [](LinkSearchOpParams &params) {
81 bNode &node = params.add_node("GeometryNodeSampleGridIndex");
82 params.update_and_connect_available_socket(node, "Z");
83 });
84 }
85 }
86 else {
87 params.add_item(IFACE_("Value"), [node_type](LinkSearchOpParams &params) {
88 bNode &node = params.add_node("GeometryNodeSampleGridIndex");
89 node.custom1 = *node_type;
90 params.update_and_connect_available_socket(node, "Value");
91 });
92 }
93}
94
95static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
96{
97 uiItemR(layout, ptr, "data_type", UI_ITEM_NONE, "", ICON_NONE);
98}
99
100static void node_init(bNodeTree * /*tree*/, bNode *node)
101{
102 node->custom1 = SOCK_FLOAT;
103}
104
105#ifdef WITH_OPENVDB
106
107template<typename T>
108void sample_grid(const bke::OpenvdbGridType<T> &grid,
109 const Span<int> x,
110 const Span<int> y,
111 const Span<int> z,
112 const IndexMask &mask,
113 MutableSpan<T> dst)
114{
115 using GridType = bke::OpenvdbGridType<T>;
116 using GridValueT = typename GridType::ValueType;
117 using AccessorT = typename GridType::ConstAccessor;
118 using TraitsT = typename bke::VolumeGridTraits<T>;
119 AccessorT accessor = grid.getConstAccessor();
120
121 mask.foreach_index([&](const int64_t i) {
122 GridValueT value = accessor.getValue(openvdb::Coord(x[i], y[i], z[i]));
123 dst[i] = TraitsT::to_blender(value);
124 });
125}
126
127template<typename Fn> void convert_to_static_type(const VolumeGridType type, const Fn &fn)
128{
129 switch (type) {
131 fn(bool());
132 break;
134 fn(float());
135 break;
136 case VOLUME_GRID_INT:
137 fn(int());
138 break;
139 case VOLUME_GRID_MASK:
140 fn(bool());
141 break;
143 fn(float3());
144 break;
145 default:
146 break;
147 }
148}
149
150class SampleGridIndexFunction : public mf::MultiFunction {
151 bke::GVolumeGrid grid_;
152 mf::Signature signature_;
153
154 public:
155 SampleGridIndexFunction(bke::GVolumeGrid grid) : grid_(std::move(grid))
156 {
157 BLI_assert(grid_);
158
159 const std::optional<eNodeSocketDatatype> data_type = bke::grid_type_to_socket_type(
160 grid_->grid_type());
161 const CPPType *cpp_type = bke::socket_type_to_geo_nodes_base_cpp_type(*data_type);
162 mf::SignatureBuilder builder{"Sample Grid Index", signature_};
163 builder.single_input<int>("X");
164 builder.single_input<int>("Y");
165 builder.single_input<int>("Z");
166 builder.single_output("Value", *cpp_type);
167 this->set_signature(&signature_);
168 }
169
170 void call(const IndexMask &mask, mf::Params params, mf::Context /*context*/) const final
171 {
172 const VArraySpan<int> x = params.readonly_single_input<int>(0, "X");
173 const VArraySpan<int> y = params.readonly_single_input<int>(1, "Y");
174 const VArraySpan<int> z = params.readonly_single_input<int>(2, "Z");
175 GMutableSpan dst = params.uninitialized_single_output(3, "Value");
176
177 bke::VolumeTreeAccessToken tree_token;
178 convert_to_static_type(grid_->grid_type(), [&](auto dummy) {
179 using T = decltype(dummy);
180 sample_grid<T>(grid_.typed<T>().grid(tree_token), x, y, z, mask, dst.typed<T>());
181 });
182 }
183};
184
185#endif /* WITH_OPENVDB */
186
188{
189#ifdef WITH_OPENVDB
190 const bNode &node = params.node();
191 const eNodeSocketDatatype data_type = eNodeSocketDatatype(node.custom1);
192
193 bke::GVolumeGrid grid = params.extract_input<bke::GVolumeGrid>("Grid");
194 if (!grid) {
195 params.set_default_remaining_outputs();
196 return;
197 }
198
199 auto fn = std::make_shared<SampleGridIndexFunction>(std::move(grid));
200 auto op = FieldOperation::Create(std::move(fn),
201 {params.extract_input<Field<int>>("X"),
202 params.extract_input<Field<int>>("Y"),
203 params.extract_input<Field<int>>("Z")});
204
206 const CPPType &output_type = *bke::socket_type_to_geo_nodes_base_cpp_type(data_type);
207 const GField output_field = conversions.try_convert(fn::GField(std::move(op)), output_type);
208 params.set_output("Value", std::move(output_field));
209
210#else
212#endif
213}
214
216 PointerRNA * /*ptr*/,
217 PropertyRNA * /*prop*/,
218 bool *r_free)
219{
220 *r_free = true;
221 return enum_items_filter(
224 });
225}
226
227static void node_rna(StructRNA *srna)
228{
230 "data_type",
231 "Data Type",
232 "Node socket data type",
237}
238
239static void node_register()
240{
241 static blender::bke::bNodeType ntype;
242
244 &ntype, GEO_NODE_SAMPLE_GRID_INDEX, "Sample Grid Index", NODE_CLASS_CONVERTER);
245 ntype.initfunc = node_init;
246 ntype.declare = node_declare;
252
253 node_rna(ntype.rna_ext.srna);
254}
256
257} // namespace blender::nodes::node_geo_sample_grid_index_cc
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:410
VolumeGridType
@ VOLUME_GRID_VECTOR_FLOAT
@ VOLUME_GRID_MASK
@ VOLUME_GRID_BOOLEAN
@ VOLUME_GRID_INT
@ VOLUME_GRID_FLOAT
#define BLI_assert(a)
Definition BLI_assert.h:50
#define ELEM(...)
#define IFACE_(msgid)
@ SOCK_IN
eNodeSocketDatatype
@ SOCK_INT
@ SOCK_VECTOR
@ SOCK_BOOLEAN
@ SOCK_FLOAT
@ SOCK_RGBA
#define NOD_REGISTER_NODE(REGISTER_FUNC)
#define NOD_inline_enum_accessors(member)
#define UI_ITEM_NONE
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
unsigned int U
Definition btGjkEpa3.h:78
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
static std::shared_ptr< FieldOperation > Create(std::shared_ptr< const mf::MultiFunction > function, Vector< GField > inputs={})
Definition FN_field.hh:244
local_group_size(16, 16) .push_constant(Type b
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
const DataTypeConversions & get_implicit_type_conversions()
const CPPType * socket_type_to_geo_nodes_base_cpp_type(eNodeSocketDatatype type)
Definition node.cc:4438
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
static void node_declare(NodeDeclarationBuilder &b)
static void node_geo_exec(GeoNodeExecParams params)
static void node_gather_link_search_ops(GatherLinkSearchOpParams &params)
static const EnumPropertyItem * data_type_filter_fn(bContext *, PointerRNA *, PropertyRNA *, bool *r_free)
static void node_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static std::optional< eNodeSocketDatatype > node_type_for_socket_type(const bNodeSocket &socket)
PropertyRNA * RNA_def_node_enum(StructRNA *srna, const char *identifier, const char *ui_name, const char *ui_description, const EnumPropertyItem *static_items, const EnumRNAAccessors accessors, std::optional< int > default_value, const EnumPropertyItemFunc item_func, const bool allow_animation)
void node_geo_exec_with_missing_openvdb(GeoNodeExecParams &params)
const EnumPropertyItem * enum_items_filter(const EnumPropertyItem *original_item_array, FunctionRef< bool(const EnumPropertyItem &item)> fn)
VecBase< float, 3 > float3
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
const EnumPropertyItem rna_enum_node_socket_data_type_items[]
__int64 int64_t
Definition stdint.h:89
StructRNA * srna
Definition RNA_types.hh:780
Defines a node type.
Definition BKE_node.hh:218
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:267
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:339
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:238
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition BKE_node.hh:363
NodeDeclareFunction declare
Definition BKE_node.hh:347
PointerRNA * ptr
Definition wm_files.cc:4126