Nodes: implement operator node.activate_viewer()
The goal is to have a clear separation between active nodes and active viewers in a node tree. Both the compositor and geometry nodes viewers are supported. This will also allow us to implement shortcuts for viewers for geometry nodes.
A viewer node can be activated using
```
viewer_node = bpy.context.scene.node_tree.nodes["Viewer"]
with bpy.context.temp_override(node=viewer_node):
bpy.ops.node.activate_viewer()
```
Pull Request: https://projects.blender.org/blender/blender/pulls/134456
This commit is contained in:
@@ -1804,6 +1804,62 @@ void NODE_OT_preview_toggle(wmOperatorType *ot)
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int node_activate_viewer_exec(bContext *C, wmOperator * /*op*/)
|
||||
{
|
||||
SpaceNode *snode = CTX_wm_space_node(C);
|
||||
PointerRNA ptr = CTX_data_pointer_get(C, "node");
|
||||
Main *bmain = CTX_data_main(C);
|
||||
bNodeTree *ntree = nullptr;
|
||||
bNode *node = nullptr;
|
||||
|
||||
if (ptr.data) {
|
||||
node = static_cast<bNode *>(ptr.data);
|
||||
ntree = reinterpret_cast<bNodeTree *>(ptr.owner_id);
|
||||
}
|
||||
else if (snode && snode->edittree) {
|
||||
ntree = snode->edittree;
|
||||
node = bke::node_get_active(*ntree);
|
||||
}
|
||||
|
||||
if (!node) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (node->is_type("CompositorNodeViewer")) {
|
||||
for (bNode *other_node : ntree->all_nodes()) {
|
||||
if (other_node->type_legacy == node->type_legacy) {
|
||||
other_node->flag &= ~NODE_DO_OUTPUT;
|
||||
}
|
||||
node->flag |= NODE_DO_OUTPUT;
|
||||
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, &ntree->id);
|
||||
WM_main_add_notifier(NC_SCENE | ND_NODES, &ntree->id);
|
||||
}
|
||||
}
|
||||
else if (node->is_type("GeometryNodeViewer")) {
|
||||
/* Geometry nodes viewers don't rely on NODE_DO_OUTPUT flag alone. */
|
||||
viewer_path::activate_geometry_node(*bmain, *snode, *node);
|
||||
}
|
||||
else {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
BKE_main_ensure_invariants(*bmain, snode->edittree->id);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void NODE_OT_activate_viewer(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Activate Viewer Node";
|
||||
ot->description = "Activate selected viewer node in compositor and geometry nodes";
|
||||
ot->idname = "NODE_OT_activate_viewer";
|
||||
|
||||
ot->exec = node_activate_viewer_exec;
|
||||
ot->poll = ED_operator_node_active;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int node_deactivate_viewer_exec(bContext *C, wmOperator * /*op*/)
|
||||
{
|
||||
SpaceNode &snode = *CTX_wm_space_node(C);
|
||||
|
||||
@@ -374,6 +374,7 @@ void NODE_OT_preview_toggle(wmOperatorType *ot);
|
||||
void NODE_OT_options_toggle(wmOperatorType *ot);
|
||||
void NODE_OT_node_copy_color(wmOperatorType *ot);
|
||||
void NODE_OT_deactivate_viewer(wmOperatorType *ot);
|
||||
void NODE_OT_activate_viewer(wmOperatorType *ot);
|
||||
|
||||
void NODE_OT_read_viewlayers(wmOperatorType *ot);
|
||||
void NODE_OT_render_changed(wmOperatorType *ot);
|
||||
|
||||
@@ -44,6 +44,7 @@ void node_operatortypes()
|
||||
WM_operatortype_append(NODE_OT_hide_socket_toggle);
|
||||
WM_operatortype_append(NODE_OT_node_copy_color);
|
||||
WM_operatortype_append(NODE_OT_deactivate_viewer);
|
||||
WM_operatortype_append(NODE_OT_activate_viewer);
|
||||
|
||||
WM_operatortype_append(NODE_OT_duplicate);
|
||||
WM_operatortype_append(NODE_OT_delete);
|
||||
|
||||
Reference in New Issue
Block a user