diff --git a/source/blender/blenkernel/BKE_compositor.hh b/source/blender/blenkernel/BKE_compositor.hh index 96b31c12b1b..46822e82b05 100644 --- a/source/blender/blenkernel/BKE_compositor.hh +++ b/source/blender/blenkernel/BKE_compositor.hh @@ -14,6 +14,7 @@ struct Scene; struct ViewLayer; +struct bContext; namespace blender::bke::compositor { @@ -22,4 +23,8 @@ namespace blender::bke::compositor { * which case, the compositor will return an invalid output and issue a warning. */ Set get_used_passes(const Scene &scene, const ViewLayer *view_layer); +/* Checks if the viewport compositor is currently being used. This is similar to + * DRWContext::is_viewport_compositor_enabled but checks all 3D views. */ +bool is_viewport_compositor_used(const bContext &context); + } // namespace blender::bke::compositor diff --git a/source/blender/blenkernel/BKE_node.hh b/source/blender/blenkernel/BKE_node.hh index 0cfab1917cd..31de9201242 100644 --- a/source/blender/blenkernel/BKE_node.hh +++ b/source/blender/blenkernel/BKE_node.hh @@ -348,11 +348,6 @@ struct bNodeType { * responsibility of the caller. */ NodeGetCompositorOperationFunction get_compositor_operation = nullptr; - /* A message to display in the node header for unsupported compositor nodes. The message - * is assumed to be static and thus require no memory handling. This field is to be removed when - * all nodes are supported. */ - const char *compositor_unsupported_message = nullptr; - /* Build a multi-function for this node. */ NodeMultiFunctionBuildFunction build_multi_function = nullptr; diff --git a/source/blender/blenkernel/intern/compositor.cc b/source/blender/blenkernel/intern/compositor.cc index 3450daaecda..c8df9049dad 100644 --- a/source/blender/blenkernel/intern/compositor.cc +++ b/source/blender/blenkernel/intern/compositor.cc @@ -7,19 +7,27 @@ #include #include "BLI_index_range.hh" +#include "BLI_listbase.h" #include "BLI_math_base.hh" #include "BLI_set.hh" #include "BLI_string_ref.hh" #include "BKE_compositor.hh" +#include "BKE_context.hh" #include "BKE_cryptomatte.hh" #include "BKE_node.hh" #include "BKE_node_legacy_types.hh" #include "BKE_node_runtime.hh" +#include "WM_api.hh" + #include "DNA_layer_types.h" #include "DNA_node_types.h" +#include "DNA_object_enums.h" #include "DNA_scene_types.h" +#include "DNA_space_types.h" +#include "DNA_view3d_types.h" +#include "DNA_windowmanager_types.h" namespace blender::bke::compositor { @@ -171,4 +179,35 @@ Set get_used_passes(const Scene &scene, const ViewLayer *view_layer return used_passes; } +bool is_viewport_compositor_used(const bContext &context) +{ + const Scene *scene = CTX_data_scene(&context); + if (!scene->compositing_node_group) { + return false; + } + + wmWindowManager *window_manager = CTX_wm_manager(&context); + LISTBASE_FOREACH (const wmWindow *, window, &window_manager->windows) { + const bScreen *screen = WM_window_get_active_screen(window); + LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) { + const SpaceLink &space = *static_cast(area->spacedata.first); + if (space.spacetype == SPACE_VIEW3D) { + const View3D &view_3d = reinterpret_cast(space); + + if (view_3d.shading.use_compositor == V3D_SHADING_USE_COMPOSITOR_DISABLED) { + continue; + } + + if (!(view_3d.shading.type >= OB_MATERIAL)) { + continue; + } + + return true; + } + } + } + + return false; +} + } // namespace blender::bke::compositor diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 56f5faa0699..38e16f1064a 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -140,10 +140,6 @@ struct TreeDrawContext { geo_log::ContextualGeoTreeLogs tree_logs; NestedTreePreviews *nested_group_infos = nullptr; - /** - * True if there is an active compositor using the node tree, false otherwise. - */ - bool used_by_compositor = false; Map *compositor_per_node_execution_time = nullptr; @@ -2051,13 +2047,6 @@ static void node_add_error_message_button(const TreeDrawContext &tree_draw_ctx, const rctf &rect, float &icon_offset) { - if (ntree.type == NTREE_COMPOSIT) { - if (tree_draw_ctx.used_by_compositor && node.typeinfo->compositor_unsupported_message) { - add_error_message_button( - block, rect, ICON_ERROR, icon_offset, node.typeinfo->compositor_unsupported_message); - } - return; - } if (ntree.type == NTREE_GEOMETRY) { geo_log::GeoTreeLog *geo_tree_log = [&]() -> geo_log::GeoTreeLog * { const bNodeTreeZones *zones = node.owner_tree().zones(); @@ -4588,39 +4577,6 @@ static void snode_setup_v2d(SpaceNode &snode, ARegion ®ion, const float2 &cen snode.runtime->aspect = BLI_rctf_size_x(&v2d.cur) / float(region.winx); } -/* Similar to DRW_is_viewport_compositor_enabled() in `draw_manager.cc` but checks all 3D views. */ -static bool compositor_is_in_use(const bContext &context) -{ - const Scene *scene = CTX_data_scene(&context); - - if (!scene->compositing_node_group) { - return false; - } - - wmWindowManager *wm = CTX_wm_manager(&context); - LISTBASE_FOREACH (const wmWindow *, win, &wm->windows) { - const bScreen *screen = WM_window_get_active_screen(win); - LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) { - const SpaceLink &space = *static_cast(area->spacedata.first); - if (space.spacetype == SPACE_VIEW3D) { - const View3D &view_3d = reinterpret_cast(space); - - if (view_3d.shading.use_compositor == V3D_SHADING_USE_COMPOSITOR_DISABLED) { - continue; - } - - if (!(view_3d.shading.type >= OB_MATERIAL)) { - continue; - } - - return true; - } - } - } - - return false; -} - static void draw_nodetree(const bContext &C, ARegion ®ion, bNodeTree &ntree, @@ -4658,7 +4614,6 @@ static void draw_nodetree(const bContext &C, } else if (ntree.type == NTREE_COMPOSIT) { const Scene *scene = CTX_data_scene(&C); - tree_draw_ctx.used_by_compositor = compositor_is_in_use(C); tree_draw_ctx.compositor_per_node_execution_time = &scene->runtime->compositor.per_node_execution_time; } diff --git a/source/blender/nodes/composite/nodes/node_composite_group_input.cc b/source/blender/nodes/composite/nodes/node_composite_group_input.cc index b4bdd7c166c..0d615eb2f68 100644 --- a/source/blender/nodes/composite/nodes/node_composite_group_input.cc +++ b/source/blender/nodes/composite/nodes/node_composite_group_input.cc @@ -44,7 +44,6 @@ class GroupInputOperation : public NodeOperation { if (!pass.is_allocated()) { /* Pass not rendered yet, or not supported by viewport. */ result.allocate_invalid(); - this->context().set_info_message("Viewport compositor setup not fully supported"); return; } diff --git a/source/blender/nodes/composite/nodes/node_composite_image.cc b/source/blender/nodes/composite/nodes/node_composite_image.cc index e7a42fbf225..d515c83b624 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.cc +++ b/source/blender/nodes/composite/nodes/node_composite_image.cc @@ -17,6 +17,7 @@ #include "BLI_string_utf8.h" #include "BLI_utildefines.h" +#include "BKE_compositor.hh" #include "BKE_context.hh" #include "BKE_global.hh" #include "BKE_image.hh" @@ -41,6 +42,8 @@ #include "GPU_shader.hh" +#include "NOD_node_extra_info.hh" + #include "COM_algorithm_extract_alpha.hh" #include "COM_node_operation.hh" #include "COM_utilities.hh" @@ -672,6 +675,43 @@ static void node_composit_buts_viewlayers(uiLayout *layout, bContext *C, Pointer RNA_string_set(&op_ptr, "scene", scene_name); } +/* Give a warning if passes are used with a render engine that does not support them. */ +static void node_extra_info(NodeExtraInfoParams ¶meters) +{ + const Scene *scene = CTX_data_scene(¶meters.C); + + /* EEVEE supports passes. */ + if (StringRef(scene->r.engine) == RE_engine_id_BLENDER_EEVEE) { + return; + } + + if (!bke::compositor::is_viewport_compositor_used(parameters.C)) { + return; + } + + bool is_any_pass_used = false; + for (const bNodeSocket *output : parameters.node.output_sockets()) { + /* Combined pass is always available. */ + if (StringRef(output->name) == "Image" || StringRef(output->name) == "Alpha") { + continue; + } + if (output->is_logically_linked()) { + is_any_pass_used = true; + break; + } + } + + if (!is_any_pass_used) { + return; + } + + NodeExtraInfoRow row; + row.text = RPT_("Passes Not Supported"); + row.tooltip = TIP_("Render passes in the Viewport compositor are only supported in EEVEE"); + row.icon = ICON_ERROR; + parameters.rows.append(std::move(row)); +} + using namespace blender::compositor; class RenderLayerOperation : public NodeOperation { @@ -724,7 +764,6 @@ class RenderLayerOperation : public NodeOperation { if (!pass.is_allocated()) { /* Pass not rendered yet, or not supported by viewport. */ result.allocate_invalid(); - this->context().set_info_message("Viewport compositor setup not fully supported"); return; } @@ -854,8 +893,6 @@ static void register_node_type_cmp_rlayers() ntype.initfunc_api = file_ns::node_composit_init_rlayers; ntype.poll = file_ns::node_composit_poll_rlayers; ntype.get_compositor_operation = file_ns::get_compositor_operation; - ntype.compositor_unsupported_message = N_( - "Render passes in the Viewport compositor are only supported in EEVEE"); ntype.flag |= NODE_PREVIEW; blender::bke::node_type_storage(ntype, std::nullopt, @@ -863,6 +900,7 @@ static void register_node_type_cmp_rlayers() file_ns::node_composit_copy_rlayers); ntype.updatefunc = file_ns::cmp_node_rlayers_update; ntype.initfunc = node_cmp_rlayers_outputs; + ntype.get_extra_info = file_ns::node_extra_info; blender::bke::node_type_size_preset(ntype, blender::bke::eNodeSizePreset::Large); blender::bke::node_register_type(ntype);