Finding Callback Function

Hi Blender Community,

I am trying to locate the function executed when I select a Node Tree in Geometry Node Editor as shown in the image below.

image

I have placed several breakpoints, which would be hit when I selected a Node Tree, and investigated the call stacks (I have appended one of the call stacks to the end), yet I could not find the callback function. I also enabled Python Tooltips but it does not show the tooltip when I hover over one of the Node Trees.

I would appreciate it if you could tell me how I can find that function.

Sincerely.

================

> blender.exe!updateDepsgraph(ModifierData * md, const ModifierUpdateDepsgraphContext * ctx) Line 156 C++
blender.exe!blender::deg::DepsgraphRelationBuilder::build_object_data_geometry(Object * object) Line 2054 C++
blender.exe!blender::deg::DepsgraphRelationBuilder::build_object_data(Object * object) Line 840 C++
blender.exe!blender::deg::DepsgraphRelationBuilder::build_object(Object * object) Line 739 C++
blender.exe!blender::deg::DepsgraphRelationBuilder::build_view_layer(Scene * scene, ViewLayer * view_layer, blender::deg::eDepsNode_LinkedState_Type linked_state) Line 98 C++
[Inline Frame] blender.exe!blender::deg::AbstractBuilderPipeline::build_step_relations() Line 85 C++
blender.exe!blender::deg::AbstractBuilderPipeline::build() Line 56 C++
[Inline Frame] blender.exe!DEG_graph_build_from_view_layer(Depsgraph *) Line 228 C++
blender.exe!DEG_graph_relations_update(Depsgraph * graph) Line 281 C++
blender.exe!scene_graph_update_tagged(Depsgraph * depsgraph, Main * bmain, bool only_if_tagged) Line 2622 C
[Inline Frame] blender.exe!wm_event_do_depsgraph(bContext *) Line 364 C
[Inline Frame] blender.exe!wm_event_do_refresh_wm_and_depsgraph(bContext *) Line 389 C
blender.exe!wm_event_do_notifiers(bContext * C) Line 589 C
blender.exe!WM_main(bContext * C) Line 641 C
blender.exe!main(int argc, const unsigned char * * UNUSED_argv_c) Line 527 C
[Inline Frame] blender.exe!invoke_main() Line 78 C++
blender.exe!__scrt_common_main_seh() Line 288 C++

rna_SpaceNodeEditor_node_tree_set might be the function?

Most of the buttons in the UI edit some RNA property, and so it’s a matter of finding the name of that property and where it is defined in the makesrna module.

Just to add to Brecht’s explanation:
This specific case is a data-block selector, internally called ID-template. It sets the RNA value via a callback, template_ID_set_property_exec_fn() in interface_templates.c.

Thank you @julianeisel and @brecht for your answers.

I am a newcomer and trying to get used to Blender architecture. Please forgive my questions.

I understand that when I press the button template_ID_set_property_exec_fn is called. As a parameter to that function, rna_SpaceNodeEditor_node_tree is given via PointerPropertyRNA *pprop variable. Eventually, rna_SpaceNodeEditor_node_tree_set is called inside template_ID_set_property_exec_fn. Is it correct?

Besides, I have debugged and CTRL+F’d really hard but could not find where this pprop variable is somehow assigned to rna_SpaceNodeEditor_node_tree. I could also not find where the parameters of the rna_SpaceNodeEditor_node_tree_set function are given. I suspected that it might be inside the interface_handler file but I could not pinpoint the location.

I realized that when the Geometry Nodes modifier is active rna_NodesModifier_node_group prop is called when the button is pressed. Otherwise, rna_SpaceNodeEditor_node_tree is called. I wonder at which part of the codebase this is decided.

By the way, I am working on this Good First Issue https://developer.blender.org/T84927. I, firstly, figured out how to add a new modifier. Now, I am trying to learn about callback functions.

Hi @Rgtemze I took a look at this issue and found that when I select an existing node tree without a geo modifier already present the template_ui->prop->identifier is node_tree (this prop is assigned to pprop in RNA_property_pointer_set function) whereas when a geo modifier is already present and I switch to a different node tree the template_ui->prop->identifier is node_group. rna_SpaceNodeEditor_node_tree_set is called indirectly from pprop->set in RNA_property_pointer_set when template_ui->prop->identifier is ‘node_tree’ and NodesModifier_node_group_set is called when template_ui->prop->identifier is ‘node_group’.

Hi @DAnkur, thank you for your time. I had realized too that template_ui->prop->identifier is controlled. Further, I recently found that at this line of code, it is defined as node_group. Still, I am not sure where it is defined as node_tree. However, I guess I might not need that information.

The way this works is a bit complicated and basically covers the core of how the RNA system works. Basically, there are RNA struct and RNA property definitions, and as part of that you can register callbacks like getters and setters. In this case this is done here.
When the property is changed via RNA (e.g. RNA_property_pointer_set()) the setter assigned to the property is called.
However, this info shouldn’t be needed to address the task. I will further address confusion points in the following replies, but it’s not clear to me how to address this best yet.

1 Like

The property identifier doesn’t change, what changes is the property displayed.
The code you link to is for the modifier UI, not for the node editor UI. The modifier indeed only shows the object.modifiers.active.node_group property:

The one in the geometry nodes editor header is defined here.
So:

  • When there is no active geometry nodes modifier in the active object, the node editor shows a selector for the general SpaceNodeEditor.node_tree property.
  • If there is one, it shows the node group property for the modifier: NodesModifier.node_group.

Worth noting that a node group is a node tree in fact.

Now the tasks suggests to create a modifier when selecting a tree in the first case. I’m not convinced that this is a good idea on the design side. I will raise that in the task.

1 Like