Blender V5.0
node_context_path.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9
10#include "BLI_listbase.h"
11#include "BLI_vector.hh"
12
13#include "DNA_node_types.h"
14
15#include "BKE_context.hh"
16#include "BKE_material.hh"
17#include "BKE_object.hh"
18
19#include "RNA_access.hh"
20#include "RNA_prototypes.hh"
21
22#include "ED_node_c.hh"
23#include "ED_screen.hh"
24
25#include "SEQ_modifier.hh"
26#include "SEQ_select.hh"
27#include "SEQ_sequencer.hh"
28
29#include "WM_api.hh"
30
31#include "UI_interface.hh"
32#include "UI_resources.hh"
33
34#include "node_intern.hh"
35
36struct Material;
37
39
41{
42 if (!object.data) {
43 return;
44 }
45 if (object.type == OB_MESH) {
46 ui::context_path_add_generic(path, RNA_Mesh, object.data);
47 }
48 else if (object.type == OB_CURVES) {
49 ui::context_path_add_generic(path, RNA_Curves, object.data);
50 }
51 else if (object.type == OB_LAMP) {
52 ui::context_path_add_generic(path, RNA_Light, object.data);
53 }
54 else if (ELEM(object.type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) {
55 ui::context_path_add_generic(path, RNA_Curve, object.data);
56 }
57}
58
59static std::function<void(bContext &)> tree_path_handle_func(int i)
60{
61 return [i](bContext &C) {
62 PointerRNA op_props;
63 wmOperatorType *ot = WM_operatortype_find("NODE_OT_tree_path_parent", false);
65 RNA_int_set(&op_props, "parent_tree_index", i);
67 &C, ot, blender::wm::OpCallContext::InvokeDefault, &op_props, nullptr);
69 };
70}
71
74 StructRNA &rna_type,
75 void *ptr)
76{
77 if (snode.nodetree != snode.edittree) {
78 ui::context_path_add_generic(path, rna_type, ptr, ICON_NONE, tree_path_handle_func(0));
79 }
80 else {
81 ui::context_path_add_generic(path, rna_type, ptr);
82 }
83}
84
87 const bool skip_base = false)
88{
89 int i = 0;
90 LISTBASE_FOREACH_INDEX (const bNodeTreePath *, path_item, &snode.treepath, i) {
91 if (skip_base && path_item == snode.treepath.first) {
92 continue;
93 }
94 if (path_item->nodetree == nullptr) {
95 continue;
96 }
97
98 int icon = ICON_NODETREE;
99 if (ID_IS_PACKED(&path_item->nodetree->id)) {
100 icon = ICON_PACKAGE;
101 }
102 else if (ID_IS_LINKED(&path_item->nodetree->id)) {
103 icon = ICON_LINKED;
104 }
105 else if (ID_IS_ASSET(&path_item->nodetree->id)) {
106 icon = ICON_ASSET_MANAGER;
107 }
108
109 if (path_item != snode.treepath.last) {
110 // We don't need to add handle function to last nodetree
112 path, RNA_NodeTree, path_item->nodetree, icon, tree_path_handle_func(i));
113 }
114 else {
115 ui::context_path_add_generic(path, RNA_NodeTree, path_item->nodetree, icon);
116 }
117 }
118}
119
121 SpaceNode &snode,
123{
124 if (snode.flag & SNODE_PIN) {
125 if (snode.shaderfrom == SNODE_SHADER_WORLD) {
126 Scene *scene = CTX_data_scene(&C);
127 ui::context_path_add_generic(path, RNA_Scene, scene);
128 if (scene != nullptr) {
129 context_path_add_top_level_shader_node_tree(snode, path, RNA_World, scene->world);
130 }
131 /* Skip the base node tree here, because the world contains a node tree already. */
133 }
134 else {
136 }
137 }
138 else {
139 Object *object = CTX_data_active_object(&C);
140 if (snode.shaderfrom == SNODE_SHADER_OBJECT && object != nullptr) {
141 ui::context_path_add_generic(path, RNA_Object, object);
142 if (!(object->matbits && object->matbits[object->actcol - 1])) {
143 context_path_add_object_data(path, *object);
144 }
145 Material *material = BKE_object_material_get(object, object->actcol);
146 context_path_add_top_level_shader_node_tree(snode, path, RNA_Material, material);
147 }
148 else if (snode.shaderfrom == SNODE_SHADER_WORLD) {
149 Scene *scene = CTX_data_scene(&C);
150 ui::context_path_add_generic(path, RNA_Scene, scene);
151 if (scene != nullptr) {
152 context_path_add_top_level_shader_node_tree(snode, path, RNA_World, scene->world);
153 }
154 }
155#ifdef WITH_FREESTYLE
156 else if (snode.shaderfrom == SNODE_SHADER_LINESTYLE) {
157 ViewLayer *viewlayer = CTX_data_view_layer(&C);
159 ui::context_path_add_generic(path, RNA_ViewLayer, viewlayer);
160 Material *mat = BKE_object_material_get(object, object->actcol);
161 ui::context_path_add_generic(path, RNA_Material, mat);
162 }
163#endif
165 }
166}
167
169 SpaceNode &snode,
171{
172 if (snode.flag & SNODE_PIN) {
174 }
175 else {
177 Scene *sequencer_scene = CTX_data_sequencer_scene(&C);
178 if (!sequencer_scene) {
180 return;
181 }
182 ui::context_path_add_generic(path, RNA_Scene, sequencer_scene, ICON_SCENE);
183 Editing *ed = seq::editing_get(sequencer_scene);
184 if (!ed) {
186 return;
187 }
188 Strip *strip = seq::select_active_get(sequencer_scene);
189 if (!strip) {
191 return;
192 }
193 ui::context_path_add_generic(path, RNA_Strip, strip, ICON_SEQ_STRIP_DUPLICATE);
195 if (!smd) {
197 return;
198 }
199 if (smd->type != eSeqModifierType_Compositor) {
201 return;
202 }
204 smd);
205 if (scmd->node_group == nullptr) {
207 return;
208 }
209 ui::context_path_add_generic(path, RNA_NodeTree, scmd->node_group);
211 }
212 else {
213 Scene *scene = CTX_data_scene(&C);
214 ui::context_path_add_generic(path, RNA_Scene, scene);
216 }
217 }
218}
219
221 SpaceNode &snode,
223{
224 if (snode.flag & SNODE_PIN || snode.node_tree_sub_type == SNODE_GEOMETRY_TOOL) {
226 }
227 else {
228 Object *object = CTX_data_active_object(&C);
229 if (!object) {
231 return;
232 }
233 ui::context_path_add_generic(path, RNA_Object, object);
235 if (!modifier) {
237 return;
238 }
239 ui::context_path_add_generic(path, RNA_Modifier, modifier, ICON_GEOMETRY_NODES);
241 }
242}
243
245{
246 SpaceNode *snode = CTX_wm_space_node(&C);
247 if (snode == nullptr) {
248 return {};
249 }
250
251 Vector<ui::ContextPathItem> context_path;
252
253 if (ED_node_is_geometry(snode)) {
254 get_context_path_node_geometry(C, *snode, context_path);
255 }
256 else if (ED_node_is_shader(snode)) {
257 get_context_path_node_shader(C, *snode, context_path);
258 }
259 else if (ED_node_is_compositor(snode)) {
260 get_context_path_node_compositor(C, *snode, context_path);
261 }
262
263 return context_path;
264}
265
266} // namespace blender::ed::space_node
SpaceNode * CTX_wm_space_node(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Scene * CTX_data_sequencer_scene(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
FreestyleLineStyle * BKE_linestyle_active_from_view_layer(struct ViewLayer *view_layer)
Definition linestyle.cc:714
General operations, lookup, etc. for materials.
Material * BKE_object_material_get(Object *ob, short act)
General operations, lookup, etc. for blender objects.
ModifierData * BKE_object_active_modifier(const Object *ob)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
#define ELEM(...)
#define ID_IS_PACKED(_id)
Definition DNA_ID.h:700
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:694
#define ID_IS_ASSET(_id)
Definition DNA_ID.h:737
@ OB_SURF
@ OB_FONT
@ OB_LAMP
@ OB_MESH
@ OB_CURVES_LEGACY
@ OB_CURVES
@ eSeqModifierType_Compositor
@ SNODE_PIN
@ SNODE_GEOMETRY_TOOL
@ SNODE_SHADER_WORLD
@ SNODE_SHADER_LINESTYLE
@ SNODE_SHADER_OBJECT
@ SNODE_COMPOSITOR_SEQUENCER
bool ED_node_is_geometry(const SpaceNode *snode)
Definition node_edit.cc:502
bool ED_node_is_compositor(const SpaceNode *snode)
Definition node_edit.cc:487
bool ED_node_is_shader(SpaceNode *snode)
Definition node_edit.cc:492
#define C
Definition RandGen.cpp:29
NodeLinkData data[NODELINK_GROUP_SIZE]
Definition drawnode.cc:1863
static std::function< void(bContext &)> tree_path_handle_func(int i)
static void get_context_path_node_shader(const bContext &C, SpaceNode &snode, Vector< ui::ContextPathItem > &path)
static void get_context_path_node_geometry(const bContext &C, SpaceNode &snode, Vector< ui::ContextPathItem > &path)
static void context_path_add_object_data(Vector< ui::ContextPathItem > &path, Object &object)
static void context_path_add_top_level_shader_node_tree(const SpaceNode &snode, Vector< ui::ContextPathItem > &path, StructRNA &rna_type, void *ptr)
static void get_context_path_node_compositor(const bContext &C, SpaceNode &snode, Vector< ui::ContextPathItem > &path)
Vector< ui::ContextPathItem > context_path_for_space_node(const bContext &C)
static void context_path_add_node_tree_and_node_groups(const SpaceNode &snode, Vector< ui::ContextPathItem > &path, const bool skip_base=false)
Editing * editing_get(const Scene *scene)
Definition sequencer.cc:286
Strip * select_active_get(const Scene *scene)
StripModifierData * modifier_get_active(const Strip *strip)
void context_path_add_generic(Vector< ContextPathItem > &path, StructRNA &rna_type, void *ptr, const BIFIconID icon_override=ICON_NONE, std::function< void(bContext &)> handle_func=nullptr)
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
void * last
void * first
struct World * world
char node_tree_sub_type
ListBase treepath
struct bNodeTree * edittree
struct bNodeTree * nodetree
i
Definition text_draw.cc:230
wmOperatorStatus WM_operator_name_call_ptr(bContext *C, wmOperatorType *ot, blender::wm::OpCallContext context, PointerRNA *properties, const wmEvent *event)
PointerRNA * ptr
Definition wm_files.cc:4238
wmOperatorType * ot
Definition wm_files.cc:4237
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
void WM_operator_properties_free(PointerRNA *ptr)