Blender V4.3
node_geometry_attribute_search.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_index_range.hh"
6#include "BLI_listbase.h"
7#include "BLI_map.hh"
8#include "BLI_rect.h"
9#include "BLI_set.hh"
10#include "BLI_string.h"
11#include "BLI_string_ref.hh"
12
13#include "DNA_modifier_types.h"
14#include "DNA_node_types.h"
15#include "DNA_object_types.h"
16#include "DNA_space_types.h"
17
18#include "BKE_context.hh"
19#include "BKE_node_runtime.hh"
22#include "BKE_object.hh"
23
24#include "RNA_access.hh"
25#include "RNA_enum_types.hh"
26
27#include "ED_node.hh"
28#include "ED_screen.hh"
29#include "ED_undo.hh"
30
31#include "BLT_translation.hh"
32
33#include "UI_interface.hh"
34#include "UI_resources.hh"
35
37#include "NOD_socket.hh"
38
39#include "node_intern.hh"
40
42
44
49
50/* This class must not have a destructor, since it is used by buttons and freed with #MEM_freeN. */
51BLI_STATIC_ASSERT(std::is_trivially_destructible_v<AttributeSearchData>, "");
52
55{
56 using namespace nodes::geo_eval_log;
57
58 SpaceNode *snode = CTX_wm_space_node(&C);
59 if (!snode) {
61 return {};
62 }
64 if (node_tree == nullptr) {
66 return {};
67 }
68 const bNode *node = node_tree->node_by_id(data.node_id);
69 if (node == nullptr) {
71 return {};
72 }
73 const bke::bNodeTreeZones *tree_zones = node_tree->zones();
74 if (!tree_zones) {
75 return {};
76 }
78 GeoModifierLog::get_tree_log_by_zone_for_node_editor(*snode);
79
80 Set<StringRef> names;
81
82 /* For the attribute input node, collect attribute information from all nodes in the group. */
85 for (GeoTreeLog *tree_log : log_by_zone.values()) {
86 tree_log->ensure_socket_values();
87 tree_log->ensure_existing_attributes();
88 for (const GeometryAttributeInfo *attribute : tree_log->existing_attributes) {
89 if (!names.add(attribute->name)) {
90 continue;
91 }
93 continue;
94 }
95 attributes.append(attribute);
96 }
97 }
98 return attributes;
99 }
100 const bke::bNodeTreeZone *zone = tree_zones->get_zone_by_node(node->identifier);
101 GeoTreeLog *tree_log = log_by_zone.lookup_default(zone, nullptr);
102 if (!tree_log) {
103 return {};
104 }
105 tree_log->ensure_socket_values();
106 GeoNodeLog *node_log = tree_log->nodes.lookup_ptr(node->identifier);
107 if (node_log == nullptr) {
108 return {};
109 }
110
112 for (const bNodeSocket *input_socket : node->input_sockets()) {
113 if (input_socket->type != SOCK_GEOMETRY) {
114 continue;
115 }
116 const ValueLog *value_log = tree_log->find_socket_value_log(*input_socket);
117 if (value_log == nullptr) {
118 continue;
119 }
120 if (const GeometryInfoLog *geo_log = dynamic_cast<const GeometryInfoLog *>(value_log)) {
121 for (const GeometryAttributeInfo &attribute : geo_log->attributes) {
123 if (names.add(attribute.name)) {
124 attributes.append(&attribute);
125 }
126 }
127 }
128 }
129 }
130 return attributes;
131}
132
134 const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first)
135{
137 return;
138 }
139
140 AttributeSearchData *data = static_cast<AttributeSearchData *>(arg);
141
143
144 ui::attribute_search_add_items(str, true, infos, items, is_first);
145}
146
152{
153 switch (type) {
154 case CD_PROP_FLOAT:
155 case CD_PROP_INT32:
156 case CD_PROP_FLOAT3:
157 case CD_PROP_COLOR:
158 case CD_PROP_BOOL:
160 case CD_PROP_FLOAT4X4:
161 return type;
163 return CD_PROP_COLOR;
164 case CD_PROP_STRING:
165 /* Unsupported currently. */
166 return CD_PROP_FLOAT;
167 case CD_PROP_FLOAT2:
168 case CD_PROP_INT32_2D:
169 /* No 2D vector sockets currently. */
170 return CD_PROP_FLOAT3;
171 case CD_PROP_INT8:
172 return CD_PROP_INT32;
173 default:
174 return CD_PROP_FLOAT;
175 }
176}
177
178static void attribute_search_exec_fn(bContext *C, void *data_v, void *item_v)
179{
181 return;
182 }
184 if (item == nullptr) {
185 return;
186 }
187 SpaceNode *snode = CTX_wm_space_node(C);
188 if (!snode) {
190 return;
191 }
192 bNodeTree *node_tree = snode->edittree;
193 if (node_tree == nullptr) {
195 return;
196 }
197 AttributeSearchData *data = static_cast<AttributeSearchData *>(data_v);
198 bNode *node = node_tree->node_by_id(data->node_id);
199 if (node == nullptr) {
201 return;
202 }
203
204 /* For the attribute input node, also adjust the type and links connected to the output. */
205 if (node->type == GEO_NODE_INPUT_NAMED_ATTRIBUTE && item->data_type.has_value()) {
207 node->storage);
209 if (new_type != storage.data_type) {
210 storage.data_type = new_type;
211 /* Make the output socket with the new type on the attribute input node active. */
215 }
216 }
217
218 bNodeSocket *socket = bke::node_find_enabled_input_socket(*node, data->socket_identifier);
219 if (socket == nullptr) {
221 return;
222 }
223 BLI_assert(socket->type == SOCK_STRING);
224
225 bNodeSocketValueString *value = static_cast<bNodeSocketValueString *>(socket->default_value);
226 BLI_strncpy(value->value, item->name.c_str(), MAX_NAME);
227
228 ED_undo_push(C, "Assign Attribute Name");
229}
230
232 const bNode &node,
233 PointerRNA &socket_ptr,
234 uiLayout &layout,
235 const StringRefNull placeholder)
236{
237 uiBlock *block = uiLayoutGetBlock(&layout);
238 uiBut *but = uiDefIconTextButR(block,
240 0,
241 ICON_NONE,
242 "",
243 0,
244 0,
245 10 * UI_UNIT_X, /* Dummy value, replaced by layout system. */
246 UI_UNIT_Y,
247 &socket_ptr,
248 "default_value",
249 0,
250 0.0f,
251 0.0f,
252 "");
253 UI_but_placeholder_set(but, placeholder.c_str());
254
255 const bNodeSocket &socket = *static_cast<const bNodeSocket *>(socket_ptr.data);
256 AttributeSearchData *data = MEM_cnew<AttributeSearchData>(__func__);
257 data->node_id = node.identifier;
258 STRNCPY(data->socket_identifier, socket.identifier);
259
263 nullptr,
265 static_cast<void *>(data),
266 true,
267 nullptr,
269 nullptr);
270}
271
272} // namespace blender::ed::space_node
SpaceNode * CTX_wm_space_node(const bContext *C)
Main * CTX_data_main(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
#define GEO_NODE_INPUT_NAMED_ATTRIBUTE
Definition BKE_node.hh:1286
void BKE_ntree_update_tag_node_property(bNodeTree *ntree, bNode *node)
General operations, lookup, etc. for blender objects.
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_STATIC_ASSERT(a, msg)
Definition BLI_assert.h:87
#define BLI_assert(a)
Definition BLI_assert.h:50
#define STRNCPY(dst, src)
Definition BLI_string.h:593
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
@ CD_PROP_BYTE_COLOR
@ CD_PROP_FLOAT
@ CD_PROP_FLOAT3
@ CD_PROP_INT32_2D
@ CD_PROP_COLOR
@ CD_PROP_QUATERNION
@ CD_PROP_INT32
@ CD_PROP_FLOAT2
@ CD_PROP_STRING
@ CD_PROP_FLOAT4X4
#define MAX_NAME
Definition DNA_defs.h:50
@ SOCK_GEOMETRY
@ SOCK_STRING
Object is a sort of wrapper for general info.
void ED_node_tree_propagate_change(const bContext *C, Main *bmain, bNodeTree *ntree)
Definition node_edit.cc:492
bScreen * ED_screen_animation_playing(const wmWindowManager *wm)
void ED_undo_push(bContext *C, const char *str)
Definition ed_undo.cc:104
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
#define C
Definition RandGen.cpp:29
#define UI_UNIT_Y
void UI_but_placeholder_set(uiBut *but, const char *placeholder_text) ATTR_NONNULL(1)
void UI_but_func_search_set_results_are_suggestions(uiBut *but, bool value)
void UI_but_func_search_set(uiBut *but, uiButSearchCreateFn search_create_fn, uiButSearchUpdateFn search_update_fn, void *arg, bool free_arg, uiFreeArgFunc search_arg_free_fn, uiButHandleFunc search_exec_fn, void *active)
uiBlock * uiLayoutGetBlock(uiLayout *layout)
uiBut * uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, PointerRNA *ptr, const char *propname, int index, float min, float max, const char *tip)
void UI_but_func_search_set_sep_string(uiBut *but, const char *search_sep_string)
#define UI_UNIT_X
@ UI_BTYPE_SEARCH_MENU
Value lookup_default(const Key &key, const Value &default_value) const
Definition BLI_map.hh:531
ValueIterator values() const
Definition BLI_map.hh:846
bool add(const Key &key)
Definition BLI_set.hh:248
constexpr const char * c_str() const
void append(const T &value)
const bNodeTreeZone * get_zone_by_node(const int32_t node_id) const
#define str(s)
bNodeSocket * node_find_enabled_input_socket(bNode &node, StringRef name)
Definition node.cc:1863
bool allow_procedural_attribute_access(StringRef attribute_name)
static Vector< const GeometryAttributeInfo * > get_attribute_info_from_context(const bContext &C, AttributeSearchData &data)
static eCustomDataType data_type_in_attribute_input_node(const eCustomDataType type)
static void attribute_search_update_fn(const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first)
void node_geometry_add_attribute_search_button(const bContext &, const bNode &node, PointerRNA &socket_ptr, uiLayout &layout, const StringRefNull placeholder)
static void attribute_search_exec_fn(bContext *C, void *data_v, void *item_v)
void update_node_declaration_and_sockets(bNodeTree &ntree, bNode &node)
void attribute_search_add_items(StringRefNull str, bool can_create_attribute, Span< const nodes::geo_eval_log::GeometryAttributeInfo * > infos, uiSearchItems *items, bool is_first)
signed int int32_t
Definition stdint.h:77
#define UI_MENU_ARROW_SEP
void * data
Definition RNA_types.hh:42
struct bNodeTree * edittree
void * default_value
char identifier[64]
void * storage
int32_t identifier
int16_t type