Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/util')
-rw-r--r--source/blender/editors/util/CMakeLists.txt2
-rw-r--r--source/blender/editors/util/ed_draw.c3
-rw-r--r--source/blender/editors/util/ed_transverts.c4
-rw-r--r--source/blender/editors/util/ed_util.c19
-rw-r--r--source/blender/editors/util/ed_util_imbuf.c10
-rw-r--r--source/blender/editors/util/ed_util_ops.cc10
-rw-r--r--source/blender/editors/util/ed_viewer_path.cc365
7 files changed, 389 insertions, 24 deletions
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index a9e6adc6e60..128cb897ac4 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -28,6 +28,7 @@ set(SRC
ed_util.c
ed_util_imbuf.c
ed_util_ops.cc
+ ed_viewer_path.cc
gizmo_utils.c
numinput.c
select_utils.c
@@ -89,6 +90,7 @@ set(SRC
../include/ED_uvedit.h
../include/ED_view3d.h
../include/ED_view3d_offscreen.h
+ ../include/ED_viewer_path.hh
../include/UI_abstract_view.hh
../include/UI_grid_view.hh
../include/UI_icons.h
diff --git a/source/blender/editors/util/ed_draw.c b/source/blender/editors/util/ed_draw.c
index 7ec3d3c1ef4..80bf732e173 100644
--- a/source/blender/editors/util/ed_draw.c
+++ b/source/blender/editors/util/ed_draw.c
@@ -484,6 +484,7 @@ float ED_slider_factor_get(struct tSlider *slider)
void ED_slider_factor_set(struct tSlider *slider, const float factor)
{
+ slider->raw_factor = factor;
slider->factor = factor;
if (!slider->overshoot) {
slider->factor = clamp_f(slider->factor, 0, 1);
@@ -768,7 +769,7 @@ void ED_region_image_metadata_draw(
GPU_matrix_translate_2f(x, y);
GPU_matrix_scale_2f(zoomx, zoomy);
- BLF_size(blf_mono_font, style->widgetlabel.points * 1.5f * U.pixelsize, U.dpi);
+ BLF_size(blf_mono_font, style->widgetlabel.points * U.dpi_fac);
/* *** upper box*** */
diff --git a/source/blender/editors/util/ed_transverts.c b/source/blender/editors/util/ed_transverts.c
index ef57f9e9b33..334516bfd6c 100644
--- a/source/blender/editors/util/ed_transverts.c
+++ b/source/blender/editors/util/ed_transverts.c
@@ -318,8 +318,8 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, const Object *obedit,
if (ebo->layer & arm->layer) {
const bool tipsel = (ebo->flag & BONE_TIPSEL) != 0;
const bool rootsel = (ebo->flag & BONE_ROOTSEL) != 0;
- const bool rootok = (!(ebo->parent && (ebo->flag & BONE_CONNECTED) &&
- (ebo->parent->flag & BONE_TIPSEL)));
+ const bool rootok = !(ebo->parent && (ebo->flag & BONE_CONNECTED) &&
+ (ebo->parent->flag & BONE_TIPSEL));
if ((tipsel && rootsel) || (rootsel)) {
/* Don't add the tip (unless mode & TM_ALL_JOINTS, for getting all joints),
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index e70851aedd6..92d65688bf1 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -54,22 +54,19 @@
#include "WM_api.h"
#include "WM_types.h"
-/* ********* general editor util funcs, not BKE stuff please! ********* */
+/* ********* general editor util functions, not BKE stuff please! ********* */
void ED_editors_init_for_undo(Main *bmain)
{
wmWindowManager *wm = bmain->wm.first;
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
+ Scene *scene = WM_window_get_active_scene(win);
ViewLayer *view_layer = WM_window_get_active_view_layer(win);
- Base *base = view_layer->basact;
- if (base != NULL) {
- Object *ob = base->object;
- if (ob->mode & OB_MODE_TEXTURE_PAINT) {
- Scene *scene = WM_window_get_active_scene(win);
-
- BKE_texpaint_slots_refresh_object(scene, ob);
- ED_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
- }
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ Object *ob = BKE_view_layer_active_object_get(view_layer);
+ if (ob && (ob->mode & OB_MODE_TEXTURE_PAINT)) {
+ BKE_texpaint_slots_refresh_object(scene, ob);
+ ED_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
}
}
}
@@ -377,7 +374,7 @@ void unpack_menu(bContext *C,
char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
BLI_split_file_part(abs_name, fi, sizeof(fi));
- BLI_path_join(local_name, sizeof(local_name), "//", folder, fi, NULL);
+ BLI_path_join(local_name, sizeof(local_name), "//", folder, fi);
if (!STREQ(abs_name, local_name)) {
switch (BKE_packedfile_compare_to_file(blendfile_path, local_name, pf)) {
case PF_CMP_NOFILE:
diff --git a/source/blender/editors/util/ed_util_imbuf.c b/source/blender/editors/util/ed_util_imbuf.c
index f222f93d2b6..b1c8fc42d08 100644
--- a/source/blender/editors/util/ed_util_imbuf.c
+++ b/source/blender/editors/util/ed_util_imbuf.c
@@ -52,13 +52,13 @@ typedef struct ImageSampleInfo {
int width, height;
int sample_size;
- unsigned char col[4];
+ uchar col[4];
float colf[4];
float linearcol[4];
int z;
float zf;
- unsigned char *colp;
+ uchar *colp;
const float *colfp;
int *zp;
float *zfp;
@@ -79,7 +79,7 @@ static void image_sample_pixel_color_ubyte(const ImBuf *ibuf,
uchar r_col[4],
float r_col_linear[4])
{
- const uchar *cp = (unsigned char *)(ibuf->rect + coord[1] * ibuf->x + coord[0]);
+ const uchar *cp = (uchar *)(ibuf->rect + coord[1] * ibuf->x + coord[0]);
copy_v4_v4_uchar(r_col, cp);
rgba_uchar_to_float(r_col_linear, r_col);
IMB_colormanagement_colorspace_to_scene_linear_v4(r_col_linear, false, ibuf->rect_colorspace);
@@ -311,7 +311,7 @@ static void sequencer_sample_apply(bContext *C, wmOperator *op, const wmEvent *e
if (fx >= 0.0f && fy >= 0.0f && fx < ibuf->x && fy < ibuf->y) {
const float *fp;
- unsigned char *cp;
+ uchar *cp;
int x = (int)fx, y = (int)fy;
info->x = x;
@@ -323,7 +323,7 @@ static void sequencer_sample_apply(bContext *C, wmOperator *op, const wmEvent *e
info->colfp = NULL;
if (ibuf->rect) {
- cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
+ cp = (uchar *)(ibuf->rect + y * ibuf->x + x);
info->col[0] = cp[0];
info->col[1] = cp[1];
diff --git a/source/blender/editors/util/ed_util_ops.cc b/source/blender/editors/util/ed_util_ops.cc
index af3589e50f0..18d47af7854 100644
--- a/source/blender/editors/util/ed_util_ops.cc
+++ b/source/blender/editors/util/ed_util_ops.cc
@@ -125,7 +125,7 @@ static bool lib_id_generate_preview_poll(bContext *C)
return true;
}
-static int lib_id_generate_preview_exec(bContext *C, wmOperator *UNUSED(op))
+static int lib_id_generate_preview_exec(bContext *C, wmOperator * /*op*/)
{
PointerRNA idptr = CTX_data_pointer_get(C, "id");
ID *id = (ID *)idptr.data;
@@ -170,7 +170,7 @@ static bool lib_id_generate_preview_from_object_poll(bContext *C)
return true;
}
-static int lib_id_generate_preview_from_object_exec(bContext *C, wmOperator *UNUSED(op))
+static int lib_id_generate_preview_from_object_exec(bContext *C, wmOperator * /*op*/)
{
PointerRNA idptr = CTX_data_pointer_get(C, "id");
ID *id = (ID *)idptr.data;
@@ -229,7 +229,7 @@ static int lib_id_fake_user_toggle_exec(bContext *C, wmOperator *op)
ID *id = (ID *)idptr.data;
if (!BKE_id_is_editable(CTX_data_main(C), id) ||
- (ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS))) {
+ ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS)) {
BKE_report(op->reports, RPT_ERROR, "Data-block type does not support fake user");
return OPERATOR_CANCELLED;
}
@@ -304,7 +304,7 @@ static bool lib_id_override_editable_toggle_poll(bContext *C)
return id && ID_IS_OVERRIDE_LIBRARY_REAL(id) && !ID_IS_LINKED(id);
}
-static int lib_id_override_editable_toggle_exec(bContext *C, wmOperator *UNUSED(op))
+static int lib_id_override_editable_toggle_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
const PointerRNA id_ptr = CTX_data_pointer_get_type(C, "id", &RNA_ID);
@@ -346,7 +346,7 @@ static void ED_OT_lib_id_override_editable_toggle(wmOperatorType *ot)
/** \name General editor utils.
* \{ */
-static int ed_flush_edits_exec(bContext *C, wmOperator *UNUSED(op))
+static int ed_flush_edits_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
ED_editors_flush_edits(bmain);
diff --git a/source/blender/editors/util/ed_viewer_path.cc b/source/blender/editors/util/ed_viewer_path.cc
new file mode 100644
index 00000000000..4da1559b726
--- /dev/null
+++ b/source/blender/editors/util/ed_viewer_path.cc
@@ -0,0 +1,365 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "ED_viewer_path.hh"
+#include "ED_screen.h"
+
+#include "BKE_context.h"
+#include "BKE_main.h"
+#include "BKE_node_runtime.hh"
+#include "BKE_workspace.h"
+
+#include "BLI_listbase.h"
+#include "BLI_vector.hh"
+
+#include "DNA_modifier_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "DEG_depsgraph.h"
+
+#include "WM_api.h"
+
+namespace blender::ed::viewer_path {
+
+static void viewer_path_for_geometry_node(const SpaceNode &snode,
+ const bNode &node,
+ ViewerPath &r_dst)
+{
+ BKE_viewer_path_init(&r_dst);
+
+ Object *ob = reinterpret_cast<Object *>(snode.id);
+ IDViewerPathElem *id_elem = BKE_viewer_path_elem_new_id();
+ id_elem->id = &ob->id;
+ BLI_addtail(&r_dst.path, id_elem);
+
+ NodesModifierData *modifier = nullptr;
+ LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
+ if (md->type != eModifierType_Nodes) {
+ continue;
+ }
+ NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
+ if (nmd->node_group != snode.nodetree) {
+ continue;
+ }
+ if (snode.flag & SNODE_PIN) {
+ /* If the node group is pinned, use the first matching modifier. This can be improved by
+ * storing the modifier name in the node editor when the context is pinned. */
+ modifier = nmd;
+ break;
+ }
+ if (md->flag & eModifierFlag_Active) {
+ modifier = nmd;
+ }
+ }
+
+ ModifierViewerPathElem *modifier_elem = BKE_viewer_path_elem_new_modifier();
+ modifier_elem->modifier_name = BLI_strdup(modifier->modifier.name);
+ BLI_addtail(&r_dst.path, modifier_elem);
+
+ Vector<const bNodeTreePath *, 16> tree_path = snode.treepath;
+ for (const bNodeTreePath *tree_path_elem : tree_path.as_span().drop_front(1)) {
+ NodeViewerPathElem *node_elem = BKE_viewer_path_elem_new_node();
+ node_elem->node_name = BLI_strdup(tree_path_elem->node_name);
+ BLI_addtail(&r_dst.path, node_elem);
+ }
+
+ NodeViewerPathElem *viewer_node_elem = BKE_viewer_path_elem_new_node();
+ viewer_node_elem->node_name = BLI_strdup(node.name);
+ BLI_addtail(&r_dst.path, viewer_node_elem);
+}
+
+void activate_geometry_node(Main &bmain, SpaceNode &snode, bNode &node)
+{
+ wmWindowManager *wm = (wmWindowManager *)bmain.wm.first;
+ if (wm == nullptr) {
+ return;
+ }
+ LISTBASE_FOREACH (bNode *, iter_node, &snode.edittree->nodes) {
+ if (iter_node->type == GEO_NODE_VIEWER) {
+ SET_FLAG_FROM_TEST(iter_node->flag, iter_node == &node, NODE_DO_OUTPUT);
+ }
+ }
+ ViewerPath new_viewer_path{};
+ BLI_SCOPED_DEFER([&]() { BKE_viewer_path_clear(&new_viewer_path); });
+ viewer_path_for_geometry_node(snode, node, new_viewer_path);
+
+ bool found_view3d_with_enabled_viewer = false;
+ View3D *any_view3d_without_viewer = nullptr;
+ LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
+ WorkSpace *workspace = BKE_workspace_active_get(window->workspace_hook);
+ bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ SpaceLink *sl = static_cast<SpaceLink *>(area->spacedata.first);
+ if (sl->spacetype == SPACE_SPREADSHEET) {
+ SpaceSpreadsheet &sspreadsheet = *reinterpret_cast<SpaceSpreadsheet *>(sl);
+ if (!(sspreadsheet.flag & SPREADSHEET_FLAG_PINNED)) {
+ sspreadsheet.object_eval_state = SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE;
+ }
+ }
+ else if (sl->spacetype == SPACE_VIEW3D) {
+ View3D &v3d = *reinterpret_cast<View3D *>(sl);
+ if (v3d.flag2 & V3D_SHOW_VIEWER) {
+ found_view3d_with_enabled_viewer = true;
+ }
+ else {
+ any_view3d_without_viewer = &v3d;
+ }
+ }
+ }
+
+ /* Enable viewer in one viewport if it is disable in all of them. */
+ if (!found_view3d_with_enabled_viewer && any_view3d_without_viewer != nullptr) {
+ any_view3d_without_viewer->flag2 |= V3D_SHOW_VIEWER;
+ }
+
+ BKE_viewer_path_clear(&workspace->viewer_path);
+ BKE_viewer_path_copy(&workspace->viewer_path, &new_viewer_path);
+
+ /* Make sure the viewed data becomes available. */
+ DEG_id_tag_update(snode.id, ID_RECALC_GEOMETRY);
+ WM_main_add_notifier(NC_VIEWER_PATH, nullptr);
+ }
+}
+
+Object *parse_object_only(const ViewerPath &viewer_path)
+{
+ if (BLI_listbase_count(&viewer_path.path) != 1) {
+ return nullptr;
+ }
+ const ViewerPathElem *elem = static_cast<ViewerPathElem *>(viewer_path.path.first);
+ if (elem->type != VIEWER_PATH_ELEM_TYPE_ID) {
+ return nullptr;
+ }
+ ID *id = reinterpret_cast<const IDViewerPathElem *>(elem)->id;
+ if (id == nullptr) {
+ return nullptr;
+ }
+ if (GS(id->name) != ID_OB) {
+ return nullptr;
+ }
+ return reinterpret_cast<Object *>(id);
+}
+
+std::optional<ViewerPathForGeometryNodesViewer> parse_geometry_nodes_viewer(
+ const ViewerPath &viewer_path)
+{
+ const Vector<const ViewerPathElem *, 16> elems_vec = viewer_path.path;
+ if (elems_vec.size() < 3) {
+ /* Need at least the object, modifier and viewer node name. */
+ return std::nullopt;
+ }
+ Span<const ViewerPathElem *> remaining_elems = elems_vec;
+ const ViewerPathElem &id_elem = *remaining_elems[0];
+ if (id_elem.type != VIEWER_PATH_ELEM_TYPE_ID) {
+ return std::nullopt;
+ }
+ ID *root_id = reinterpret_cast<const IDViewerPathElem &>(id_elem).id;
+ if (root_id == nullptr) {
+ return std::nullopt;
+ }
+ if (GS(root_id->name) != ID_OB) {
+ return std::nullopt;
+ }
+ Object *root_ob = reinterpret_cast<Object *>(root_id);
+ remaining_elems = remaining_elems.drop_front(1);
+ const ViewerPathElem &modifier_elem = *remaining_elems[0];
+ if (modifier_elem.type != VIEWER_PATH_ELEM_TYPE_MODIFIER) {
+ return std::nullopt;
+ }
+ const char *modifier_name =
+ reinterpret_cast<const ModifierViewerPathElem &>(modifier_elem).modifier_name;
+ if (modifier_name == nullptr) {
+ return std::nullopt;
+ }
+ remaining_elems = remaining_elems.drop_front(1);
+ Vector<StringRefNull> node_names;
+ for (const ViewerPathElem *elem : remaining_elems) {
+ if (elem->type != VIEWER_PATH_ELEM_TYPE_NODE) {
+ return std::nullopt;
+ }
+ const char *node_name = reinterpret_cast<const NodeViewerPathElem *>(elem)->node_name;
+ if (node_name == nullptr) {
+ return std::nullopt;
+ }
+ node_names.append(node_name);
+ }
+ const StringRefNull viewer_node_name = node_names.pop_last();
+ return ViewerPathForGeometryNodesViewer{root_ob, modifier_name, node_names, viewer_node_name};
+}
+
+bool exists_geometry_nodes_viewer(const ViewerPathForGeometryNodesViewer &parsed_viewer_path)
+{
+ const NodesModifierData *modifier = nullptr;
+ LISTBASE_FOREACH (const ModifierData *, md, &parsed_viewer_path.object->modifiers) {
+ if (md->type != eModifierType_Nodes) {
+ continue;
+ }
+ if (md->name != parsed_viewer_path.modifier_name) {
+ continue;
+ }
+ modifier = reinterpret_cast<const NodesModifierData *>(md);
+ break;
+ }
+ if (modifier == nullptr) {
+ return false;
+ }
+ if (modifier->node_group == nullptr) {
+ return false;
+ }
+ const bNodeTree *ngroup = modifier->node_group;
+ ngroup->ensure_topology_cache();
+ for (const StringRefNull group_node_name : parsed_viewer_path.group_node_names) {
+ const bNode *group_node = nullptr;
+ for (const bNode *node : ngroup->group_nodes()) {
+ if (node->name != group_node_name) {
+ continue;
+ }
+ group_node = node;
+ break;
+ }
+ if (group_node == nullptr) {
+ return false;
+ }
+ if (group_node->id == nullptr) {
+ return false;
+ }
+ ngroup = reinterpret_cast<const bNodeTree *>(group_node->id);
+ }
+ const bNode *viewer_node = nullptr;
+ for (const bNode *node : ngroup->nodes_by_type("GeometryNodeViewer")) {
+ if (node->name != parsed_viewer_path.viewer_node_name) {
+ continue;
+ }
+ viewer_node = node;
+ break;
+ }
+ if (viewer_node == nullptr) {
+ return false;
+ }
+ return true;
+}
+
+bool is_active_geometry_nodes_viewer(const bContext &C,
+ const ViewerPathForGeometryNodesViewer &parsed_viewer_path)
+{
+ const NodesModifierData *modifier = nullptr;
+ LISTBASE_FOREACH (const ModifierData *, md, &parsed_viewer_path.object->modifiers) {
+ if (md->name != parsed_viewer_path.modifier_name) {
+ continue;
+ }
+ if (md->type != eModifierType_Nodes) {
+ return false;
+ }
+ if ((md->mode & eModifierMode_Realtime) == 0) {
+ return false;
+ }
+ modifier = reinterpret_cast<const NodesModifierData *>(md);
+ break;
+ }
+ if (modifier == nullptr) {
+ return false;
+ }
+ if (modifier->node_group == nullptr) {
+ return false;
+ }
+ const bool modifier_is_active = modifier->modifier.flag & eModifierFlag_Active;
+
+ const Main *bmain = CTX_data_main(&C);
+ const wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
+ if (wm == nullptr) {
+ return false;
+ }
+ LISTBASE_FOREACH (const wmWindow *, window, &wm->windows) {
+ const bScreen *active_screen = BKE_workspace_active_screen_get(window->workspace_hook);
+ Vector<const bScreen *> screens = {active_screen};
+ if (ELEM(active_screen->state, SCREENMAXIMIZED, SCREENFULL)) {
+ const ScrArea *area = static_cast<ScrArea *>(active_screen->areabase.first);
+ screens.append(area->full);
+ }
+ for (const bScreen *screen : screens) {
+ LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) {
+ const SpaceLink *sl = static_cast<SpaceLink *>(area->spacedata.first);
+ if (sl == nullptr) {
+ continue;
+ }
+ if (sl->spacetype != SPACE_NODE) {
+ continue;
+ }
+ const SpaceNode &snode = *reinterpret_cast<const SpaceNode *>(sl);
+ if (!modifier_is_active) {
+ if (!(snode.flag & SNODE_PIN)) {
+ /* Node tree has to be pinned when the modifier is not active. */
+ continue;
+ }
+ }
+ if (snode.id != &parsed_viewer_path.object->id) {
+ continue;
+ }
+ if (snode.nodetree != modifier->node_group) {
+ continue;
+ }
+ Vector<const bNodeTreePath *, 16> tree_path = snode.treepath;
+ if (tree_path.size() != parsed_viewer_path.group_node_names.size() + 1) {
+ continue;
+ }
+ bool valid_path = true;
+ for (const int i : parsed_viewer_path.group_node_names.index_range()) {
+ if (parsed_viewer_path.group_node_names[i] != tree_path[i + 1]->node_name) {
+ valid_path = false;
+ break;
+ }
+ }
+ if (!valid_path) {
+ continue;
+ }
+ const bNodeTree *ngroup = snode.edittree;
+ ngroup->ensure_topology_cache();
+ const bNode *viewer_node = nullptr;
+ for (const bNode *node : ngroup->nodes_by_type("GeometryNodeViewer")) {
+ if (node->name != parsed_viewer_path.viewer_node_name) {
+ continue;
+ }
+ viewer_node = node;
+ }
+ if (viewer_node == nullptr) {
+ continue;
+ }
+ if (!(viewer_node->flag & NODE_DO_OUTPUT)) {
+ continue;
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bNode *find_geometry_nodes_viewer(const ViewerPath &viewer_path, SpaceNode &snode)
+{
+ const std::optional<ViewerPathForGeometryNodesViewer> parsed_viewer_path =
+ parse_geometry_nodes_viewer(viewer_path);
+ if (!parsed_viewer_path.has_value()) {
+ return nullptr;
+ }
+
+ snode.edittree->ensure_topology_cache();
+ bNode *possible_viewer = nullptr;
+ for (bNode *node : snode.edittree->nodes_by_type("GeometryNodeViewer")) {
+ if (node->name == parsed_viewer_path->viewer_node_name) {
+ possible_viewer = node;
+ break;
+ }
+ }
+ if (possible_viewer == nullptr) {
+ return nullptr;
+ }
+ ViewerPath tmp_viewer_path;
+ BLI_SCOPED_DEFER([&]() { BKE_viewer_path_clear(&tmp_viewer_path); });
+ viewer_path_for_geometry_node(snode, *possible_viewer, tmp_viewer_path);
+
+ if (BKE_viewer_path_equal(&viewer_path, &tmp_viewer_path)) {
+ return possible_viewer;
+ }
+ return nullptr;
+}
+
+} // namespace blender::ed::viewer_path