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/space_node')
-rw-r--r--source/blender/editors/space_node/CMakeLists.txt5
-rw-r--r--source/blender/editors/space_node/drawnode.cc568
-rw-r--r--source/blender/editors/space_node/link_drag_search.cc3
-rw-r--r--source/blender/editors/space_node/node_add.cc316
-rw-r--r--source/blender/editors/space_node/node_draw.cc185
-rw-r--r--source/blender/editors/space_node/node_edit.cc103
-rw-r--r--source/blender/editors/space_node/node_gizmo.cc45
-rw-r--r--source/blender/editors/space_node/node_group.cc42
-rw-r--r--source/blender/editors/space_node/node_intern.hh44
-rw-r--r--source/blender/editors/space_node/node_ops.cc2
-rw-r--r--source/blender/editors/space_node/node_relationships.cc454
-rw-r--r--source/blender/editors/space_node/node_select.cc90
-rw-r--r--source/blender/editors/space_node/node_templates.cc67
-rw-r--r--source/blender/editors/space_node/node_view.cc20
-rw-r--r--source/blender/editors/space_node/space_node.cc14
15 files changed, 968 insertions, 990 deletions
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index badcccca87b..8a1d47eaa8d 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -17,7 +17,6 @@ set(INC
../../nodes
../../render
../../windowmanager
- ../../../../intern/glew-mx
../../../../intern/guardedalloc
# RNA_prototypes.h
${CMAKE_BINARY_DIR}/source/blender/makesrna
@@ -50,8 +49,8 @@ set(LIB
bf_editor_screen
)
-if(WITH_COMPOSITOR)
- add_definitions(-DWITH_COMPOSITOR)
+if(WITH_COMPOSITOR_CPU)
+ add_definitions(-DWITH_COMPOSITOR_CPU)
endif()
if(WITH_OPENIMAGEDENOISE)
diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc
index 25ab06850f5..a4db5edf0f6 100644
--- a/source/blender/editors/space_node/drawnode.cc
+++ b/source/blender/editors/space_node/drawnode.cc
@@ -6,6 +6,7 @@
* \brief lower level node drawing for nodes (boarders, headers etc), also node layout.
*/
+#include "BLI_color.hh"
#include "BLI_system.h"
#include "BLI_threads.h"
@@ -477,7 +478,7 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_RGB:
ntype->draw_buttons = node_buts_rgb;
break;
- case SH_NODE_MIX_RGB:
+ case SH_NODE_MIX_RGB_LEGACY:
ntype->draw_buttons = node_buts_mix_rgb;
break;
case SH_NODE_VALTORGB:
@@ -1584,102 +1585,75 @@ void draw_nodespace_back_pix(const bContext &C,
GPU_matrix_pop();
}
-bool node_link_bezier_handles(const View2D *v2d,
- const SpaceNode *snode,
- const bNodeLink &link,
- float vec[4][2])
+static float2 socket_link_connection_location(const bNodeSocket &socket, const bNodeLink &link)
{
- float cursor[2] = {0.0f, 0.0f};
-
- /* this function can be called with snode null (via cut_links_intersect) */
- /* XXX map snode->runtime->cursor back to view space */
- if (snode) {
- cursor[0] = snode->runtime->cursor[0] * UI_DPI_FAC;
- cursor[1] = snode->runtime->cursor[1] * UI_DPI_FAC;
- }
-
- /* in v0 and v3 we put begin/end points */
- if (link.fromsock) {
- vec[0][0] = link.fromsock->locx;
- vec[0][1] = link.fromsock->locy;
- if (link.fromsock->flag & SOCK_MULTI_INPUT) {
- const float2 position = node_link_calculate_multi_input_position(
- {link.fromsock->locx, link.fromsock->locy},
- link.fromsock->total_inputs - 1,
- link.fromsock->total_inputs);
- copy_v2_v2(vec[0], position);
- }
+ const float2 socket_location(socket.locx, socket.locy);
+ if (socket.flag & SOCK_MULTI_INPUT && socket.in_out == SOCK_IN) {
+ return node_link_calculate_multi_input_position(
+ socket_location, link.multi_input_socket_index, socket.total_inputs);
}
- else {
- if (snode == nullptr) {
- return false;
- }
- copy_v2_v2(vec[0], cursor);
- }
- if (link.tosock) {
- vec[3][0] = link.tosock->locx;
- vec[3][1] = link.tosock->locy;
- if (!(link.tonode->flag & NODE_HIDDEN) && link.tosock->flag & SOCK_MULTI_INPUT) {
- const float2 position = node_link_calculate_multi_input_position(
- {link.tosock->locx, link.tosock->locy},
- link.multi_input_socket_index,
- link.tosock->total_inputs);
- copy_v2_v2(vec[3], position);
- }
- }
- else {
- if (snode == nullptr) {
- return false;
- }
- copy_v2_v2(vec[3], cursor);
- }
-
- /* may be called outside of drawing (so pass spacetype) */
- int curving = UI_GetThemeValueType(TH_NODE_CURVING, SPACE_NODE);
+ return socket_location;
+}
+static void calculate_inner_link_bezier_points(std::array<float2, 4> &points)
+{
+ const int curving = UI_GetThemeValueType(TH_NODE_CURVING, SPACE_NODE);
if (curving == 0) {
/* Straight line: align all points. */
- mid_v2_v2v2(vec[1], vec[0], vec[3]);
- mid_v2_v2v2(vec[2], vec[1], vec[3]);
- return true;
+ points[1] = math::interpolate(points[0], points[3], 1.0f / 3.0f);
+ points[2] = math::interpolate(points[0], points[3], 2.0f / 3.0f);
}
+ else {
+ const float dist = curving * 0.1f * math::distance(points[0].x, points[3].x);
- const float dist = curving * 0.10f * fabsf(vec[0][0] - vec[3][0]);
+ points[1].x = points[0].x + dist;
+ points[1].y = points[0].y;
- vec[1][0] = vec[0][0] + dist;
- vec[1][1] = vec[0][1];
+ points[2].x = points[3].x - dist;
+ points[2].y = points[3].y;
+ }
+}
- vec[2][0] = vec[3][0] - dist;
- vec[2][1] = vec[3][1];
+static std::array<float2, 4> node_link_bezier_points(const bNodeLink &link)
+{
+ std::array<float2, 4> points;
+ points[0] = socket_link_connection_location(*link.fromsock, link);
+ points[3] = socket_link_connection_location(*link.tosock, link);
+ calculate_inner_link_bezier_points(points);
+ return points;
+}
- if (v2d && min_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax) {
- return false; /* clipped */
+static bool node_link_draw_is_visible(const View2D &v2d, const std::array<float2, 4> &points)
+{
+ if (min_ffff(points[0].x, points[1].x, points[2].x, points[3].x) > v2d.cur.xmax) {
+ return false;
}
- if (v2d && max_ffff(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin) {
- return false; /* clipped */
+ if (max_ffff(points[0].x, points[1].x, points[2].x, points[3].x) < v2d.cur.xmin) {
+ return false;
}
-
return true;
}
-bool node_link_bezier_points(const View2D *v2d,
- const SpaceNode *snode,
- const bNodeLink &link,
- float coord_array[][2],
- const int resol)
+void node_link_bezier_points_evaluated(const bNodeLink &link,
+ std::array<float2, NODE_LINK_RESOL + 1> &coords)
{
- float vec[4][2];
-
- if (node_link_bezier_handles(v2d, snode, link, vec)) {
- /* always do all three, to prevent data hanging around */
- BKE_curve_forward_diff_bezier(
- vec[0][0], vec[1][0], vec[2][0], vec[3][0], coord_array[0] + 0, resol, sizeof(float[2]));
- BKE_curve_forward_diff_bezier(
- vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0] + 1, resol, sizeof(float[2]));
+ const std::array<float2, 4> points = node_link_bezier_points(link);
- return true;
- }
- return false;
+ /* The extra +1 in size is required by these functions and would be removed ideally. */
+ BKE_curve_forward_diff_bezier(points[0].x,
+ points[1].x,
+ points[2].x,
+ points[3].x,
+ &coords[0].x,
+ NODE_LINK_RESOL,
+ sizeof(float2));
+ BKE_curve_forward_diff_bezier(points[0].y,
+ points[1].y,
+ points[2].y,
+ points[3].y,
+ &coords[0].y,
+ NODE_LINK_RESOL,
+ sizeof(float2));
}
#define NODELINK_GROUP_SIZE 256
@@ -1938,189 +1912,252 @@ void nodelink_batch_end(SpaceNode &snode)
g_batch_link.enabled = false;
}
+struct NodeLinkDrawConfig {
+ int th_col1;
+ int th_col2;
+ int th_col3;
+
+ ColorTheme4f start_color;
+ ColorTheme4f end_color;
+ ColorTheme4f outline_color;
+
+ bool drawarrow;
+ bool drawmuted;
+ bool highlighted;
+
+ float dim_factor;
+ float thickness;
+ float dash_factor;
+ float dash_alpha;
+};
+
static void nodelink_batch_add_link(const SpaceNode &snode,
- const float2 &p0,
- const float2 &p1,
- const float2 &p2,
- const float2 &p3,
- int th_col1,
- int th_col2,
- int th_col3,
- const float start_color[4],
- const float end_color[4],
- bool drawarrow,
- bool drawmuted,
- float dim_factor,
- float thickness,
- float dash_factor,
- float dash_alpha)
+ const std::array<float2, 4> &points,
+ const NodeLinkDrawConfig &draw_config)
{
/* Only allow these colors. If more is needed, you need to modify the shader accordingly. */
- BLI_assert(ELEM(th_col1, TH_WIRE_INNER, TH_WIRE, TH_ACTIVE, TH_EDGE_SELECT, TH_REDALERT));
- BLI_assert(ELEM(th_col2, TH_WIRE_INNER, TH_WIRE, TH_ACTIVE, TH_EDGE_SELECT, TH_REDALERT));
- BLI_assert(ELEM(th_col3, TH_WIRE, TH_REDALERT, -1));
+ BLI_assert(
+ ELEM(draw_config.th_col1, TH_WIRE_INNER, TH_WIRE, TH_ACTIVE, TH_EDGE_SELECT, TH_REDALERT));
+ BLI_assert(
+ ELEM(draw_config.th_col2, TH_WIRE_INNER, TH_WIRE, TH_ACTIVE, TH_EDGE_SELECT, TH_REDALERT));
+ BLI_assert(ELEM(draw_config.th_col3, TH_WIRE, TH_REDALERT, -1));
g_batch_link.count++;
- copy_v2_v2((float *)GPU_vertbuf_raw_step(&g_batch_link.p0_step), p0);
- copy_v2_v2((float *)GPU_vertbuf_raw_step(&g_batch_link.p1_step), p1);
- copy_v2_v2((float *)GPU_vertbuf_raw_step(&g_batch_link.p2_step), p2);
- copy_v2_v2((float *)GPU_vertbuf_raw_step(&g_batch_link.p3_step), p3);
+ copy_v2_v2((float *)GPU_vertbuf_raw_step(&g_batch_link.p0_step), points[0]);
+ copy_v2_v2((float *)GPU_vertbuf_raw_step(&g_batch_link.p1_step), points[1]);
+ copy_v2_v2((float *)GPU_vertbuf_raw_step(&g_batch_link.p2_step), points[2]);
+ copy_v2_v2((float *)GPU_vertbuf_raw_step(&g_batch_link.p3_step), points[3]);
char *colid = (char *)GPU_vertbuf_raw_step(&g_batch_link.colid_step);
- colid[0] = nodelink_get_color_id(th_col1);
- colid[1] = nodelink_get_color_id(th_col2);
- colid[2] = nodelink_get_color_id(th_col3);
- colid[3] = drawarrow;
- copy_v4_v4((float *)GPU_vertbuf_raw_step(&g_batch_link.start_color_step), start_color);
- copy_v4_v4((float *)GPU_vertbuf_raw_step(&g_batch_link.end_color_step), end_color);
+ colid[0] = nodelink_get_color_id(draw_config.th_col1);
+ colid[1] = nodelink_get_color_id(draw_config.th_col2);
+ colid[2] = nodelink_get_color_id(draw_config.th_col3);
+ colid[3] = draw_config.drawarrow;
+ copy_v4_v4((float *)GPU_vertbuf_raw_step(&g_batch_link.start_color_step),
+ draw_config.start_color);
+ copy_v4_v4((float *)GPU_vertbuf_raw_step(&g_batch_link.end_color_step), draw_config.end_color);
char *muted = (char *)GPU_vertbuf_raw_step(&g_batch_link.muted_step);
- muted[0] = drawmuted;
- *(float *)GPU_vertbuf_raw_step(&g_batch_link.dim_factor_step) = dim_factor;
- *(float *)GPU_vertbuf_raw_step(&g_batch_link.thickness_step) = thickness;
- *(float *)GPU_vertbuf_raw_step(&g_batch_link.dash_factor_step) = dash_factor;
- *(float *)GPU_vertbuf_raw_step(&g_batch_link.dash_alpha_step) = dash_alpha;
+ muted[0] = draw_config.drawmuted;
+ *(float *)GPU_vertbuf_raw_step(&g_batch_link.dim_factor_step) = draw_config.dim_factor;
+ *(float *)GPU_vertbuf_raw_step(&g_batch_link.thickness_step) = draw_config.thickness;
+ *(float *)GPU_vertbuf_raw_step(&g_batch_link.dash_factor_step) = draw_config.dash_factor;
+ *(float *)GPU_vertbuf_raw_step(&g_batch_link.dash_alpha_step) = draw_config.dash_alpha;
if (g_batch_link.count == NODELINK_GROUP_SIZE) {
nodelink_batch_draw(snode);
}
}
-void node_draw_link_bezier(const bContext &C,
- const View2D &v2d,
- const SpaceNode &snode,
- const bNodeLink &link,
- const int th_col1,
- const int th_col2,
- const int th_col3,
- const bool selected)
+static void node_draw_link_end_marker(const float2 center,
+ const float radius,
+ const ColorTheme4f &color)
+{
+ rctf rect;
+ BLI_rctf_init(&rect, center.x - radius, center.x + radius, center.y - radius, center.y + radius);
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_4fv(&rect, true, radius, color);
+ /* Roundbox disables alpha. Reenable it for node links that are drawn after this one. */
+ GPU_blend(GPU_BLEND_ALPHA);
+}
+
+static void node_draw_link_end_markers(const bNodeLink &link,
+ const NodeLinkDrawConfig &draw_config,
+ const std::array<float2, 4> &points,
+ const bool outline)
+{
+ const float radius = (outline ? 0.65f : 0.45f) * NODE_SOCKSIZE;
+ if (link.fromsock) {
+ node_draw_link_end_marker(
+ points[0], radius, outline ? draw_config.outline_color : draw_config.start_color);
+ }
+ if (link.tosock) {
+ node_draw_link_end_marker(
+ points[3], radius, outline ? draw_config.outline_color : draw_config.end_color);
+ }
+}
+
+static bool node_link_is_field_link(const SpaceNode &snode, const bNodeLink &link)
+{
+ if (snode.edittree->type != NTREE_GEOMETRY) {
+ return false;
+ }
+ if (link.fromsock && link.fromsock->display_shape == SOCK_DISPLAY_SHAPE_DIAMOND) {
+ return true;
+ }
+ return false;
+}
+
+static NodeLinkDrawConfig nodelink_get_draw_config(const bContext &C,
+ const View2D &v2d,
+ const SpaceNode &snode,
+ const bNodeLink &link,
+ const int th_col1,
+ const int th_col2,
+ const int th_col3,
+ const bool selected)
{
- const float dim_factor = selected ? 1.0f : node_link_dim_factor(v2d, link);
- float thickness = 1.5f;
- float dash_factor = 1.0f;
+ NodeLinkDrawConfig draw_config;
+
+ draw_config.th_col1 = th_col1;
+ draw_config.th_col2 = th_col2;
+ draw_config.th_col3 = th_col3;
+
+ draw_config.dim_factor = selected ? 1.0f : node_link_dim_factor(v2d, link);
bTheme *btheme = UI_GetTheme();
- const float dash_alpha = btheme->space_node.dash_alpha;
-
- if (snode.edittree->type == NTREE_GEOMETRY) {
- if (link.fromsock && link.fromsock->display_shape == SOCK_DISPLAY_SHAPE_DIAMOND) {
- /* Make field links a bit thinner. */
- thickness = 1.0f;
- /* Draw field as dashes. */
- dash_factor = 0.75f;
+ draw_config.dash_alpha = btheme->space_node.dash_alpha;
+
+ const bool field_link = node_link_is_field_link(snode, link);
+
+ draw_config.dash_factor = field_link ? 0.75f : 1.0f;
+
+ const float scale = UI_view2d_scale_get_x(&v2d);
+ /* Clamp the thickness to make the links more readable when zooming out. */
+ draw_config.thickness = max_ff(scale, 1.0f) * (field_link ? 0.7f : 1.0f);
+ draw_config.highlighted = link.flag & NODE_LINK_TEMP_HIGHLIGHT;
+ draw_config.drawarrow = ((link.tonode && (link.tonode->type == NODE_REROUTE)) &&
+ (link.fromnode && (link.fromnode->type == NODE_REROUTE)));
+ draw_config.drawmuted = (link.flag & NODE_LINK_MUTED);
+
+ UI_GetThemeColor4fv(th_col3, draw_config.outline_color);
+
+ if (snode.overlay.flag & SN_OVERLAY_SHOW_OVERLAYS &&
+ snode.overlay.flag & SN_OVERLAY_SHOW_WIRE_COLORS) {
+ PointerRNA from_node_ptr, to_node_ptr;
+ RNA_pointer_create((ID *)snode.edittree, &RNA_Node, link.fromnode, &from_node_ptr);
+ RNA_pointer_create((ID *)snode.edittree, &RNA_Node, link.tonode, &to_node_ptr);
+
+ if (link.fromsock) {
+ node_socket_color_get(
+ C, *snode.edittree, from_node_ptr, *link.fromsock, draw_config.start_color);
+ }
+ else {
+ node_socket_color_get(
+ C, *snode.edittree, to_node_ptr, *link.tosock, draw_config.start_color);
}
- }
- float vec[4][2];
- const bool highlighted = link.flag & NODE_LINK_TEMP_HIGHLIGHT;
- if (node_link_bezier_handles(&v2d, &snode, link, vec)) {
- int drawarrow = ((link.tonode && (link.tonode->type == NODE_REROUTE)) &&
- (link.fromnode && (link.fromnode->type == NODE_REROUTE)));
- int drawmuted = (link.flag & NODE_LINK_MUTED);
- if (g_batch_link.batch == nullptr) {
- nodelink_batch_init();
+ if (link.tosock) {
+ node_socket_color_get(C, *snode.edittree, to_node_ptr, *link.tosock, draw_config.end_color);
}
- /* Draw single link. */
- float colors[3][4] = {{0.0f}};
- if (th_col3 != -1) {
- UI_GetThemeColor4fv(th_col3, colors[0]);
+ else {
+ node_socket_color_get(
+ C, *snode.edittree, from_node_ptr, *link.fromsock, draw_config.end_color);
}
+ }
+ else {
+ UI_GetThemeColor4fv(th_col1, draw_config.start_color);
+ UI_GetThemeColor4fv(th_col2, draw_config.end_color);
+ }
+
+ /* Highlight links connected to selected nodes. */
+ if (selected) {
+ ColorTheme4f color_selected;
+ UI_GetThemeColor4fv(TH_EDGE_SELECT, color_selected);
+ const float alpha = color_selected.a;
- if (snode.overlay.flag & SN_OVERLAY_SHOW_OVERLAYS &&
- snode.overlay.flag & SN_OVERLAY_SHOW_WIRE_COLORS) {
- PointerRNA from_node_ptr, to_node_ptr;
- RNA_pointer_create((ID *)snode.edittree, &RNA_Node, link.fromnode, &from_node_ptr);
- RNA_pointer_create((ID *)snode.edittree, &RNA_Node, link.tonode, &to_node_ptr);
+ /* Interpolate color if highlight color is not fully transparent. */
+ if (alpha != 0.0) {
if (link.fromsock) {
- node_socket_color_get(C, *snode.edittree, from_node_ptr, *link.fromsock, colors[1]);
+ interp_v3_v3v3(draw_config.start_color, draw_config.start_color, color_selected, alpha);
}
- else {
- node_socket_color_get(C, *snode.edittree, to_node_ptr, *link.tosock, colors[1]);
- }
-
if (link.tosock) {
- node_socket_color_get(C, *snode.edittree, to_node_ptr, *link.tosock, colors[2]);
- }
- else {
- node_socket_color_get(C, *snode.edittree, from_node_ptr, *link.fromsock, colors[2]);
+ interp_v3_v3v3(draw_config.end_color, draw_config.end_color, color_selected, alpha);
}
}
- else {
- UI_GetThemeColor4fv(th_col1, colors[1]);
- UI_GetThemeColor4fv(th_col2, colors[2]);
- }
+ }
- /* Highlight links connected to selected nodes. */
- if (selected) {
- float color_selected[4];
- UI_GetThemeColor4fv(TH_EDGE_SELECT, color_selected);
- const float alpha = color_selected[3];
+ if (draw_config.highlighted) {
+ ColorTheme4f link_preselection_highlight_color;
+ UI_GetThemeColor4fv(TH_SELECT, link_preselection_highlight_color);
+ /* Multi sockets can only be inputs. So we only have to highlight the end of the link. */
+ copy_v4_v4(draw_config.end_color, link_preselection_highlight_color);
+ }
- /* Interpolate color if highlight color is not fully transparent. */
- if (alpha != 0.0) {
- if (link.fromsock) {
- interp_v3_v3v3(colors[1], colors[1], color_selected, alpha);
- }
- if (link.tosock) {
- interp_v3_v3v3(colors[2], colors[2], color_selected, alpha);
- }
- }
- }
+ return draw_config;
+}
- if (g_batch_link.enabled && !highlighted) {
- /* Add link to batch. */
- nodelink_batch_add_link(snode,
- vec[0],
- vec[1],
- vec[2],
- vec[3],
- th_col1,
- th_col2,
- th_col3,
- colors[1],
- colors[2],
- drawarrow,
- drawmuted,
- dim_factor,
- thickness,
- dash_factor,
- dash_alpha);
- }
- else {
- if (highlighted) {
- float link_preselection_highlight_color[4];
- UI_GetThemeColor4fv(TH_SELECT, link_preselection_highlight_color);
- copy_v4_v4(colors[2], link_preselection_highlight_color);
- }
+static void node_draw_link_bezier_ex(const SpaceNode &snode,
+ const NodeLinkDrawConfig &draw_config,
+ const std::array<float2, 4> &points)
+{
+ if (g_batch_link.batch == nullptr) {
+ nodelink_batch_init();
+ }
- NodeLinkData node_link_data;
- for (int i = 0; i < 4; i++) {
- copy_v2_v2(node_link_data.bezierPts[i], vec[i]);
- }
- for (int i = 0; i < 3; i++) {
- copy_v4_v4(node_link_data.colors[i], colors[i]);
- }
- node_link_data.doArrow = drawarrow;
- node_link_data.doMuted = drawmuted;
- node_link_data.dim_factor = dim_factor;
- node_link_data.thickness = thickness;
- node_link_data.dash_factor = dash_factor;
- node_link_data.dash_alpha = dash_alpha;
- node_link_data.expandSize = snode.runtime->aspect * LINK_WIDTH;
- node_link_data.arrowSize = ARROW_SIZE;
-
- GPUBatch *batch = g_batch_link.batch_single;
- GPUUniformBuf *ubo = GPU_uniformbuf_create_ex(
- sizeof(NodeLinkData), &node_link_data, __func__);
-
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK);
- GPU_batch_uniformbuf_bind(batch, "node_link_data", ubo);
- GPU_batch_draw(batch);
-
- GPU_uniformbuf_unbind(ubo);
- GPU_uniformbuf_free(ubo);
+ if (g_batch_link.enabled && !draw_config.highlighted) {
+ /* Add link to batch. */
+ nodelink_batch_add_link(snode, points, draw_config);
+ }
+ else {
+ NodeLinkData node_link_data;
+ for (const int i : IndexRange(points.size())) {
+ copy_v2_v2(node_link_data.bezierPts[i], points[i]);
}
+
+ copy_v4_v4(node_link_data.colors[0], draw_config.outline_color);
+ copy_v4_v4(node_link_data.colors[1], draw_config.start_color);
+ copy_v4_v4(node_link_data.colors[2], draw_config.end_color);
+
+ node_link_data.doArrow = draw_config.drawarrow;
+ node_link_data.doMuted = draw_config.drawmuted;
+ node_link_data.dim_factor = draw_config.dim_factor;
+ node_link_data.thickness = draw_config.thickness;
+ node_link_data.dash_factor = draw_config.dash_factor;
+ node_link_data.dash_alpha = draw_config.dash_alpha;
+ node_link_data.expandSize = snode.runtime->aspect * LINK_WIDTH;
+ node_link_data.arrowSize = ARROW_SIZE;
+
+ GPUBatch *batch = g_batch_link.batch_single;
+ GPUUniformBuf *ubo = GPU_uniformbuf_create_ex(sizeof(NodeLinkData), &node_link_data, __func__);
+
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK);
+ GPU_batch_uniformbuf_bind(batch, "node_link_data", ubo);
+ GPU_batch_draw(batch);
+
+ GPU_uniformbuf_unbind(ubo);
+ GPU_uniformbuf_free(ubo);
}
}
+void node_draw_link_bezier(const bContext &C,
+ const View2D &v2d,
+ const SpaceNode &snode,
+ const bNodeLink &link,
+ const int th_col1,
+ const int th_col2,
+ const int th_col3,
+ const bool selected)
+{
+ const std::array<float2, 4> points = node_link_bezier_points(link);
+ if (!node_link_draw_is_visible(v2d, points)) {
+ return;
+ }
+ const NodeLinkDrawConfig draw_config = nodelink_get_draw_config(
+ C, v2d, snode, link, th_col1, th_col2, th_col3, selected);
+
+ node_draw_link_bezier_ex(snode, draw_config, points);
+}
+
void node_draw_link(const bContext &C,
const View2D &v2d,
const SpaceNode &snode,
@@ -2133,34 +2170,29 @@ void node_draw_link(const bContext &C,
return;
}
- /* new connection */
- if (!link.fromsock || !link.tosock) {
- th_col1 = th_col2 = TH_ACTIVE;
+ /* going to give issues once... */
+ if (link.tosock->flag & SOCK_UNAVAIL) {
+ return;
+ }
+ if (link.fromsock->flag & SOCK_UNAVAIL) {
+ return;
}
- else {
- /* going to give issues once... */
- if (link.tosock->flag & SOCK_UNAVAIL) {
- return;
- }
- if (link.fromsock->flag & SOCK_UNAVAIL) {
- return;
- }
- if (link.flag & NODE_LINK_VALID) {
- /* special indicated link, on drop-node */
- if (link.flag & NODE_LINKFLAG_HILITE) {
- th_col1 = th_col2 = TH_ACTIVE;
- }
- else if (link.flag & NODE_LINK_MUTED) {
- th_col1 = th_col2 = TH_REDALERT;
- }
+ if (link.flag & NODE_LINK_VALID) {
+ /* special indicated link, on drop-node */
+ if (link.flag & NODE_LINKFLAG_HILITE) {
+ th_col1 = th_col2 = TH_ACTIVE;
}
- else {
- /* Invalid link. */
- th_col1 = th_col2 = th_col3 = TH_REDALERT;
- // th_col3 = -1; /* no shadow */
+ else if (link.flag & NODE_LINK_MUTED) {
+ th_col1 = th_col2 = TH_REDALERT;
}
}
+ else {
+ /* Invalid link. */
+ th_col1 = th_col2 = th_col3 = TH_REDALERT;
+ // th_col3 = -1; /* no shadow */
+ }
+
/* Links from field to non-field sockets are not allowed. */
if (snode.edittree->type == NTREE_GEOMETRY && !(link.flag & NODE_LINK_DRAGGED)) {
if ((link.fromsock && link.fromsock->display_shape == SOCK_DISPLAY_SHAPE_DIAMOND) &&
@@ -2172,6 +2204,38 @@ void node_draw_link(const bContext &C,
node_draw_link_bezier(C, v2d, snode, link, th_col1, th_col2, th_col3, selected);
}
+static std::array<float2, 4> node_link_bezier_points_dragged(const SpaceNode &snode,
+ const bNodeLink &link)
+{
+ const float2 cursor = snode.runtime->cursor * UI_DPI_FAC;
+ std::array<float2, 4> points;
+ points[0] = link.fromsock ? socket_link_connection_location(*link.fromsock, link) : cursor;
+ points[3] = link.tosock ? socket_link_connection_location(*link.tosock, link) : cursor;
+ calculate_inner_link_bezier_points(points);
+ return points;
+}
+
+void node_draw_link_dragged(const bContext &C,
+ const View2D &v2d,
+ const SpaceNode &snode,
+ const bNodeLink &link)
+{
+ if (link.fromsock == nullptr && link.tosock == nullptr) {
+ return;
+ }
+
+ const std::array<float2, 4> points = node_link_bezier_points_dragged(snode, link);
+
+ const NodeLinkDrawConfig draw_config = nodelink_get_draw_config(
+ C, v2d, snode, link, TH_ACTIVE, TH_ACTIVE, TH_WIRE, true);
+ /* End marker outline. */
+ node_draw_link_end_markers(link, draw_config, points, true);
+ /* Link. */
+ node_draw_link_bezier_ex(snode, draw_config, points);
+ /* End marker fill. */
+ node_draw_link_end_markers(link, draw_config, points, false);
+}
+
} // namespace blender::ed::space_node
void ED_node_draw_snap(View2D *v2d, const float cent[2], float size, NodeBorder border, uint pos)
diff --git a/source/blender/editors/space_node/link_drag_search.cc b/source/blender/editors/space_node/link_drag_search.cc
index c524de2c55d..553d4013324 100644
--- a/source/blender/editors/space_node/link_drag_search.cc
+++ b/source/blender/editors/space_node/link_drag_search.cc
@@ -232,6 +232,7 @@ static void link_drag_search_exec_fn(bContext *C, void *arg1, void *arg2)
PointerRNA ptr;
WM_operator_properties_create_ptr(&ptr, ot);
RNA_boolean_set(&ptr, "view2d_edge_pan", true);
+ RNA_boolean_set(&ptr, "remove_on_cancel", true);
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, nullptr);
WM_operator_properties_free(&ptr);
}
@@ -292,7 +293,7 @@ static uiBlock *create_search_popup_block(bContext *C, ARegion *region, void *ar
0,
nullptr);
- const int offset[2] = {0, -UI_UNIT_Y};
+ const int2 offset = {0, -UI_UNIT_Y};
UI_block_bounds_set_popup(block, 0.3f * U.widget_unit, offset);
return block;
}
diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc
index e96efb888f3..7e46877d0ba 100644
--- a/source/blender/editors/space_node/node_add.cc
+++ b/source/blender/editors/space_node/node_add.cc
@@ -5,6 +5,8 @@
* \ingroup spnode
*/
+#include <numeric>
+
#include "MEM_guardedalloc.h"
#include "DNA_collection_types.h"
@@ -20,6 +22,7 @@
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -49,231 +52,165 @@ namespace blender::ed::space_node {
/** \name Utilities
* \{ */
-bNode *node_add_node(const bContext &C, const char *idname, int type, float locx, float locy)
+static void position_node_based_on_mouse(bNode &node, const float2 &location)
+{
+ node.locx = location.x - NODE_DY * 1.5f / UI_DPI_FAC;
+ node.locy = location.y + NODE_DY * 0.5f / UI_DPI_FAC;
+}
+
+bNode *add_node(const bContext &C, const StringRef idname, const float2 &location)
{
SpaceNode &snode = *CTX_wm_space_node(&C);
Main &bmain = *CTX_data_main(&C);
- bNode *node = nullptr;
node_deselect_all(snode);
- if (idname) {
- node = nodeAddNode(&C, snode.edittree, idname);
- }
- else {
- node = nodeAddStaticNode(&C, snode.edittree, type);
- }
+ const std::string idname_str = idname;
+
+ bNode *node = nodeAddNode(&C, snode.edittree, idname_str.c_str());
BLI_assert(node && node->typeinfo);
- /* Position mouse in node header. */
- node->locx = locx - NODE_DY * 1.5f / UI_DPI_FAC;
- node->locy = locy + NODE_DY * 0.5f / UI_DPI_FAC;
+ position_node_based_on_mouse(*node, location);
nodeSetSelected(node, true);
-
ED_node_set_active(&bmain, &snode, snode.edittree, node, nullptr);
+
ED_node_tree_propagate_change(&C, &bmain, snode.edittree);
return node;
}
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Add Reroute Operator
- * \{ */
-
-static bool add_reroute_intersect_check(const bNodeLink &link,
- float mcoords[][2],
- int tot,
- float result[2])
+bNode *add_static_node(const bContext &C, int type, const float2 &location)
{
- float coord_array[NODE_LINK_RESOL + 1][2];
-
- if (node_link_bezier_points(nullptr, nullptr, link, coord_array, NODE_LINK_RESOL)) {
- for (int i = 0; i < tot - 1; i++) {
- for (int b = 0; b < NODE_LINK_RESOL; b++) {
- if (isect_seg_seg_v2_point(
- mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1], result) > 0) {
- return true;
- }
- }
- }
- }
- return false;
-}
+ SpaceNode &snode = *CTX_wm_space_node(&C);
+ Main &bmain = *CTX_data_main(&C);
-struct bNodeSocketLink {
- struct bNodeSocketLink *next, *prev;
+ node_deselect_all(snode);
- struct bNodeSocket *sock;
- struct bNodeLink *link;
- float point[2];
-};
+ bNode *node = nodeAddStaticNode(&C, snode.edittree, type);
+ BLI_assert(node && node->typeinfo);
-static bNodeSocketLink *add_reroute_insert_socket_link(ListBase *lb,
- bNodeSocket *sock,
- bNodeLink *link,
- const float point[2])
-{
- bNodeSocketLink *socklink, *prev;
+ position_node_based_on_mouse(*node, location);
- socklink = MEM_cnew<bNodeSocketLink>("socket link");
- socklink->sock = sock;
- socklink->link = link;
- copy_v2_v2(socklink->point, point);
+ nodeSetSelected(node, true);
+ ED_node_set_active(&bmain, &snode, snode.edittree, node, nullptr);
- for (prev = (bNodeSocketLink *)lb->last; prev; prev = prev->prev) {
- if (prev->sock == sock) {
- break;
- }
- }
- BLI_insertlinkafter(lb, prev, socklink);
- return socklink;
+ ED_node_tree_propagate_change(&C, &bmain, snode.edittree);
+ return node;
}
-static bNodeSocketLink *add_reroute_do_socket_section(bContext *C,
- bNodeSocketLink *socklink,
- int in_out)
-{
- SpaceNode *snode = CTX_wm_space_node(C);
- bNodeTree *ntree = snode->edittree;
- bNode *reroute_node = nullptr;
- bNodeSocket *cursock = socklink->sock;
- float insert_point[2];
- int num_links;
-
- zero_v2(insert_point);
- num_links = 0;
-
- while (socklink && socklink->sock == cursock) {
- if (!(socklink->link->flag & NODE_LINK_TEST)) {
- socklink->link->flag |= NODE_LINK_TEST;
-
- /* create the reroute node for this cursock */
- if (!reroute_node) {
- reroute_node = nodeAddStaticNode(C, ntree, NODE_REROUTE);
-
- /* add a single link to/from the reroute node to replace multiple links */
- if (in_out == SOCK_OUT) {
- nodeAddLink(ntree,
- socklink->link->fromnode,
- socklink->link->fromsock,
- reroute_node,
- (bNodeSocket *)reroute_node->inputs.first);
- }
- else {
- nodeAddLink(ntree,
- reroute_node,
- (bNodeSocket *)reroute_node->outputs.first,
- socklink->link->tonode,
- socklink->link->tosock);
- }
- }
-
- /* insert the reroute node into the link */
- if (in_out == SOCK_OUT) {
- socklink->link->fromnode = reroute_node;
- socklink->link->fromsock = (bNodeSocket *)reroute_node->outputs.first;
- }
- else {
- socklink->link->tonode = reroute_node;
- socklink->link->tosock = (bNodeSocket *)reroute_node->inputs.first;
- }
-
- add_v2_v2(insert_point, socklink->point);
- num_links++;
- }
- socklink = socklink->next;
- }
-
- if (num_links > 0) {
- /* average cut point from shared links */
- mul_v2_fl(insert_point, 1.0f / num_links);
+/** \} */
- reroute_node->locx = insert_point[0] / UI_DPI_FAC;
- reroute_node->locy = insert_point[1] / UI_DPI_FAC;
+/* -------------------------------------------------------------------- */
+/** \name Add Reroute Operator
+ * \{ */
- LISTBASE_FOREACH_BACKWARD (bNode *, frame_node, &ntree->nodes) {
- if (frame_node->type == NODE_FRAME && BLI_rctf_isect_pt_v(&frame_node->totr, insert_point)) {
- nodeAttachNode(reroute_node, frame_node);
- break;
+std::optional<float2> link_path_intersection(const bNodeLink &link, const Span<float2> path)
+{
+ std::array<float2, NODE_LINK_RESOL + 1> coords;
+ node_link_bezier_points_evaluated(link, coords);
+
+ for (const int i : path.index_range().drop_back(1)) {
+ for (const int j : IndexRange(NODE_LINK_RESOL)) {
+ float2 result;
+ if (isect_seg_seg_v2_point(path[i], path[i + 1], coords[j], coords[j + 1], result) > 0) {
+ return result;
}
}
}
- return socklink;
+ return std::nullopt;
}
+struct RerouteCutsForSocket {
+ /* The output socket's owner node. */
+ bNode *from_node;
+ /* Intersected links connected to the socket and their path intersection locations. */
+ Map<bNodeLink *, float2> links;
+};
+
static int add_reroute_exec(bContext *C, wmOperator *op)
{
+ const ARegion &region = *CTX_wm_region(C);
SpaceNode &snode = *CTX_wm_space_node(C);
- ARegion &region = *CTX_wm_region(C);
bNodeTree &ntree = *snode.edittree;
- float mcoords[256][2];
- int i = 0;
- /* Get the cut path */
+ Vector<float2> path;
RNA_BEGIN (op->ptr, itemptr, "path") {
- float loc[2];
-
- RNA_float_get_array(&itemptr, "loc", loc);
- UI_view2d_region_to_view(
- &region.v2d, (short)loc[0], (short)loc[1], &mcoords[i][0], &mcoords[i][1]);
- i++;
- if (i >= 256) {
+ float2 loc_region;
+ RNA_float_get_array(&itemptr, "loc", loc_region);
+ float2 loc_view;
+ UI_view2d_region_to_view(&region.v2d, loc_region.x, loc_region.y, &loc_view.x, &loc_view.y);
+ path.append(loc_view);
+ if (path.size() >= 256) {
break;
}
}
RNA_END;
- if (i > 1) {
- ListBase output_links, input_links;
- bNodeSocketLink *socklink;
- float insert_point[2];
-
- /* always first */
- ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
-
- node_deselect_all(snode);
+ if (path.is_empty()) {
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ }
- /* Find cut links and sort them by sockets */
- BLI_listbase_clear(&output_links);
- BLI_listbase_clear(&input_links);
+ ntree.ensure_topology_cache();
+ const Vector<bNode *> frame_nodes = ntree.nodes_by_type("NodeFrame");
- LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
- if (node_link_is_hidden_or_dimmed(region.v2d, *link)) {
- continue;
- }
- if (add_reroute_intersect_check(*link, mcoords, i, insert_point)) {
- add_reroute_insert_socket_link(&output_links, link->fromsock, link, insert_point);
- add_reroute_insert_socket_link(&input_links, link->tosock, link, insert_point);
+ ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
+ node_deselect_all(snode);
- /* Clear flag */
- link->flag &= ~NODE_LINK_TEST;
- }
- }
+ /* All link "cuts" that start at a particular output socket. Deduplicating new reroutes per
+ * output socket is useful because it allows reusing reroutes for connected intersections.
+ * Further deduplication using the second map means we only have one cut per link.*/
+ Map<bNodeSocket *, RerouteCutsForSocket> cuts_per_socket;
- /* Create reroute nodes for intersected links.
- * Only one reroute if links share the same input/output socket.
- */
- socklink = (bNodeSocketLink *)output_links.first;
- while (socklink) {
- socklink = add_reroute_do_socket_section(C, socklink, SOCK_OUT);
+ LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
+ if (node_link_is_hidden_or_dimmed(region.v2d, *link)) {
+ continue;
}
- socklink = (bNodeSocketLink *)input_links.first;
- while (socklink) {
- socklink = add_reroute_do_socket_section(C, socklink, SOCK_IN);
+ const std::optional<float2> intersection = link_path_intersection(*link, path);
+ if (!intersection) {
+ continue;
}
+ RerouteCutsForSocket &from_cuts = cuts_per_socket.lookup_or_add_default(link->fromsock);
+ from_cuts.from_node = link->fromnode;
+ from_cuts.links.add(link, *intersection);
+ }
+
+ for (const auto item : cuts_per_socket.items()) {
+ const Map<bNodeLink *, float2> &cuts = item.value.links;
+
+ bNode *reroute = nodeAddStaticNode(C, &ntree, NODE_REROUTE);
- BLI_freelistN(&output_links);
- BLI_freelistN(&input_links);
+ nodeAddLink(&ntree,
+ item.value.from_node,
+ item.key,
+ reroute,
+ static_cast<bNodeSocket *>(reroute->inputs.first));
- /* always last */
- ED_node_tree_propagate_change(C, CTX_data_main(C), &ntree);
- return OPERATOR_FINISHED;
+ /* Reconnect links from the original output socket to the new reroute. */
+ for (bNodeLink *link : cuts.keys()) {
+ link->fromnode = reroute;
+ link->fromsock = static_cast<bNodeSocket *>(reroute->outputs.first);
+ BKE_ntree_update_tag_link_changed(&ntree);
+ }
+
+ /* Place the new reroute at the average location of all connected cuts. */
+ const float2 loc = std::accumulate(cuts.values().begin(), cuts.values().end(), float2(0)) /
+ cuts.size() / UI_DPI_FAC;
+ reroute->locx = loc.x;
+ reroute->locy = loc.y;
+
+ /* Attach the reroute node to frame nodes behind it. */
+ for (const int i : frame_nodes.index_range()) {
+ bNode *frame_node = frame_nodes.last(i);
+ if (BLI_rctf_isect_pt_v(&frame_node->totr, loc)) {
+ nodeAttachNode(reroute, frame_node);
+ break;
+ }
+ }
}
- return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ ED_node_tree_propagate_change(C, CTX_data_main(C), &ntree);
+ return OPERATOR_FINISHED;
}
void NODE_OT_add_reroute(wmOperatorType *ot)
@@ -345,9 +282,9 @@ static int node_add_group_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
SpaceNode *snode = CTX_wm_space_node(C);
bNodeTree *ntree = snode->edittree;
- bNodeTree *node_group;
- if (!(node_group = node_add_group_get_and_poll_group_node_tree(bmain, op, ntree))) {
+ bNodeTree *node_group = node_add_group_get_and_poll_group_node_tree(bmain, op, ntree);
+ if (!node_group) {
return OPERATOR_CANCELLED;
}
@@ -359,12 +296,7 @@ static int node_add_group_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- bNode *group_node = node_add_node(*C,
- node_idname,
- (node_group->type == NTREE_CUSTOM) ? NODE_CUSTOM_GROUP :
- NODE_GROUP,
- snode->runtime->cursor[0],
- snode->runtime->cursor[1]);
+ bNode *group_node = add_node(*C, node_idname, snode->runtime->cursor);
if (!group_node) {
BKE_report(op->reports, RPT_WARNING, "Could not add node group");
return OPERATOR_CANCELLED;
@@ -452,8 +384,7 @@ static int node_add_object_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
- bNode *object_node = node_add_node(
- *C, nullptr, GEO_NODE_OBJECT_INFO, snode->runtime->cursor[0], snode->runtime->cursor[1]);
+ bNode *object_node = add_static_node(*C, GEO_NODE_OBJECT_INFO, snode->runtime->cursor);
if (!object_node) {
BKE_report(op->reports, RPT_WARNING, "Could not add node object");
return OPERATOR_CANCELLED;
@@ -529,7 +460,7 @@ static int node_add_collection_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
SpaceNode &snode = *CTX_wm_space_node(C);
- bNodeTree *ntree = snode.edittree;
+ bNodeTree &ntree = *snode.edittree;
Collection *collection = reinterpret_cast<Collection *>(
WM_operator_properties_id_lookup_from_name_or_session_uuid(bmain, op->ptr, ID_GR));
@@ -540,8 +471,7 @@ static int node_add_collection_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
- bNode *collection_node = node_add_node(
- *C, nullptr, GEO_NODE_COLLECTION_INFO, snode.runtime->cursor[0], snode.runtime->cursor[1]);
+ bNode *collection_node = add_static_node(*C, GEO_NODE_COLLECTION_INFO, snode.runtime->cursor);
if (!collection_node) {
BKE_report(op->reports, RPT_WARNING, "Could not add node collection");
return OPERATOR_CANCELLED;
@@ -557,8 +487,8 @@ static int node_add_collection_exec(bContext *C, wmOperator *op)
socket_data->value = collection;
id_us_plus(&collection->id);
- nodeSetActive(ntree, collection_node);
- ED_node_tree_propagate_change(C, bmain, ntree);
+ nodeSetActive(&ntree, collection_node);
+ ED_node_tree_propagate_change(C, bmain, &ntree);
DEG_relations_tag_update(bmain);
return OPERATOR_FINISHED;
@@ -624,11 +554,9 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
SpaceNode &snode = *CTX_wm_space_node(C);
- bNode *node;
- Image *ima;
int type = 0;
- ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
+ Image *ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
if (!ima) {
return OPERATOR_CANCELLED;
}
@@ -652,7 +580,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
- node = node_add_node(*C, nullptr, type, snode.runtime->cursor[0], snode.runtime->cursor[1]);
+ bNode *node = add_static_node(*C, type, snode.runtime->cursor);
if (!node) {
BKE_report(op->reports, RPT_WARNING, "Could not add an image node");
@@ -746,7 +674,6 @@ static int node_add_mask_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
SpaceNode &snode = *CTX_wm_space_node(C);
- bNode *node;
ID *mask = WM_operator_properties_id_lookup_from_name_or_session_uuid(bmain, op->ptr, ID_MSK);
if (!mask) {
@@ -755,8 +682,7 @@ static int node_add_mask_exec(bContext *C, wmOperator *op)
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
- node = node_add_node(
- *C, nullptr, CMP_NODE_MASK, snode.runtime->cursor[0], snode.runtime->cursor[1]);
+ bNode *node = add_static_node(*C, CMP_NODE_MASK, snode.runtime->cursor);
if (!node) {
BKE_report(op->reports, RPT_WARNING, "Could not add a mask node");
diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc
index 2cee7c4984a..225bae89c66 100644
--- a/source/blender/editors/space_node/node_draw.cc
+++ b/source/blender/editors/space_node/node_draw.cc
@@ -340,13 +340,13 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node,
bool add_output_space = false;
int buty;
- LISTBASE_FOREACH (bNodeSocket *, nsock, &node.outputs) {
- if (nodeSocketIsHidden(nsock)) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) {
+ if (nodeSocketIsHidden(socket)) {
continue;
}
PointerRNA sockptr;
- RNA_pointer_create(&ntree.id, &RNA_NodeSocket, nsock, &sockptr);
+ RNA_pointer_create(&ntree.id, &RNA_NodeSocket, socket, &sockptr);
uiLayout *layout = UI_block_layout(&block,
UI_LAYOUT_VERTICAL,
@@ -369,10 +369,10 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node,
/* Align output buttons to the right. */
uiLayout *row = uiLayoutRow(layout, true);
uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT);
- const char *socket_label = nodeSocketLabel(nsock);
- nsock->typeinfo->draw((bContext *)&C, row, &sockptr, &nodeptr, IFACE_(socket_label));
+ const char *socket_label = nodeSocketLabel(socket);
+ socket->typeinfo->draw((bContext *)&C, row, &sockptr, &nodeptr, IFACE_(socket_label));
- node_socket_add_tooltip(&ntree, &node, nsock, row);
+ node_socket_add_tooltip(ntree, node, *socket, *row);
UI_block_align_end(&block);
UI_block_layout_resolve(&block, nullptr, &buty);
@@ -381,11 +381,11 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node,
buty = min_ii(buty, dy - NODE_DY);
/* Round the socket location to stop it from jiggling. */
- nsock->locx = round(loc.x + NODE_WIDTH(node));
- nsock->locy = round(dy - NODE_DYS);
+ socket->locx = round(loc.x + NODE_WIDTH(node));
+ socket->locy = round(dy - NODE_DYS);
dy = buty;
- if (nsock->next) {
+ if (socket->next) {
dy -= NODE_SOCKDY;
}
@@ -463,20 +463,20 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node,
}
/* Input sockets. */
- LISTBASE_FOREACH (bNodeSocket *, nsock, &node.inputs) {
- if (nodeSocketIsHidden(nsock)) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
+ if (nodeSocketIsHidden(socket)) {
continue;
}
PointerRNA sockptr;
- RNA_pointer_create(&ntree.id, &RNA_NodeSocket, nsock, &sockptr);
+ RNA_pointer_create(&ntree.id, &RNA_NodeSocket, socket, &sockptr);
/* Add the half the height of a multi-input socket to cursor Y
* to account for the increased height of the taller sockets. */
float multi_input_socket_offset = 0.0f;
- if (nsock->flag & SOCK_MULTI_INPUT) {
- if (nsock->total_inputs > 2) {
- multi_input_socket_offset = (nsock->total_inputs - 2) * NODE_MULTI_INPUT_LINK_GAP;
+ if (socket->flag & SOCK_MULTI_INPUT) {
+ if (socket->total_inputs > 2) {
+ multi_input_socket_offset = (socket->total_inputs - 2) * NODE_MULTI_INPUT_LINK_GAP;
}
}
dy -= multi_input_socket_offset * 0.5f;
@@ -501,10 +501,10 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node,
uiLayout *row = uiLayoutRow(layout, true);
- const char *socket_label = nodeSocketLabel(nsock);
- nsock->typeinfo->draw((bContext *)&C, row, &sockptr, &nodeptr, IFACE_(socket_label));
+ const char *socket_label = nodeSocketLabel(socket);
+ socket->typeinfo->draw((bContext *)&C, row, &sockptr, &nodeptr, IFACE_(socket_label));
- node_socket_add_tooltip(&ntree, &node, nsock, row);
+ node_socket_add_tooltip(ntree, node, *socket, *row);
UI_block_align_end(&block);
UI_block_layout_resolve(&block, nullptr, &buty);
@@ -512,12 +512,12 @@ static void node_update_basis(const bContext &C, bNodeTree &ntree, bNode &node,
/* Ensure minimum socket height in case layout is empty. */
buty = min_ii(buty, dy - NODE_DY);
- nsock->locx = loc.x;
+ socket->locx = loc.x;
/* Round the socket vertical position to stop it from jiggling. */
- nsock->locy = round(dy - NODE_DYS);
+ socket->locy = round(dy - NODE_DYS);
dy = buty - multi_input_socket_offset * 0.5;
- if (nsock->next) {
+ if (socket->next) {
dy -= NODE_SOCKDY;
}
}
@@ -555,13 +555,13 @@ static void node_update_hidden(bNode &node, uiBlock &block)
loc.y = round(loc.y);
/* Calculate minimal radius. */
- LISTBASE_FOREACH (bNodeSocket *, nsock, &node.inputs) {
- if (!nodeSocketIsHidden(nsock)) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
+ if (!nodeSocketIsHidden(socket)) {
totin++;
}
}
- LISTBASE_FOREACH (bNodeSocket *, nsock, &node.outputs) {
- if (!nodeSocketIsHidden(nsock)) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) {
+ if (!nodeSocketIsHidden(socket)) {
totout++;
}
}
@@ -581,11 +581,11 @@ static void node_update_hidden(bNode &node, uiBlock &block)
float rad = (float)M_PI / (1.0f + (float)totout);
float drad = rad;
- LISTBASE_FOREACH (bNodeSocket *, nsock, &node.outputs) {
- if (!nodeSocketIsHidden(nsock)) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) {
+ if (!nodeSocketIsHidden(socket)) {
/* Round the socket location to stop it from jiggling. */
- nsock->locx = round(node.totr.xmax - hiddenrad + sinf(rad) * hiddenrad);
- nsock->locy = round(node.totr.ymin + hiddenrad + cosf(rad) * hiddenrad);
+ socket->locx = round(node.totr.xmax - hiddenrad + sinf(rad) * hiddenrad);
+ socket->locy = round(node.totr.ymin + hiddenrad + cosf(rad) * hiddenrad);
rad += drad;
}
}
@@ -593,11 +593,11 @@ static void node_update_hidden(bNode &node, uiBlock &block)
/* Input sockets. */
rad = drad = -(float)M_PI / (1.0f + (float)totin);
- LISTBASE_FOREACH (bNodeSocket *, nsock, &node.inputs) {
- if (!nodeSocketIsHidden(nsock)) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
+ if (!nodeSocketIsHidden(socket)) {
/* Round the socket location to stop it from jiggling. */
- nsock->locx = round(node.totr.xmin + hiddenrad + sinf(rad) * hiddenrad);
- nsock->locy = round(node.totr.ymin + hiddenrad + cosf(rad) * hiddenrad);
+ socket->locx = round(node.totr.xmin + hiddenrad + sinf(rad) * hiddenrad);
+ socket->locy = round(node.totr.ymin + hiddenrad + cosf(rad) * hiddenrad);
rad += drad;
}
}
@@ -720,8 +720,7 @@ static void node_socket_draw_multi_input(const float color[4],
const float color_outline[4],
const float width,
const float height,
- const int locx,
- const int locy)
+ const float2 location)
{
/* The other sockets are drawn with the keyframe shader. There, the outline has a base thickness
* that can be varied but always scales with the size the socket is drawn at. Using `U.dpi_fac`
@@ -731,10 +730,10 @@ static void node_socket_draw_multi_input(const float color[4],
/* UI_draw_roundbox draws the outline on the outer side, so compensate for the outline width. */
const rctf rect = {
- locx - width + outline_width * 0.5f,
- locx + width - outline_width * 0.5f,
- locy - height + outline_width * 0.5f,
- locy + height - outline_width * 0.5f,
+ location.x - width + outline_width * 0.5f,
+ location.x + width - outline_width * 0.5f,
+ location.y - height + outline_width * 0.5f,
+ location.y + height - outline_width * 0.5f,
};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
@@ -758,6 +757,7 @@ static void node_socket_outline_color_get(const bool selected,
}
else {
UI_GetThemeColor4fv(TH_WIRE, r_outline_color);
+ r_outline_color[3] = 1.0f;
}
}
@@ -775,9 +775,9 @@ void node_socket_color_get(const bContext &C,
}
struct SocketTooltipData {
- bNodeTree *ntree;
- bNode *node;
- bNodeSocket *socket;
+ const bNodeTree *ntree;
+ const bNode *node;
+ const bNodeSocket *socket;
};
static void create_inspection_string_for_generic_value(const GPointer value, std::stringstream &ss)
@@ -998,11 +998,11 @@ static void create_inspection_string_for_geometry(const geo_log::GeometryValueLo
}
}
-static std::optional<std::string> create_socket_inspection_string(bContext *C,
- bNode &node,
- bNodeSocket &socket)
+static std::optional<std::string> create_socket_inspection_string(const bContext &C,
+ const bNode &node,
+ const bNodeSocket &socket)
{
- SpaceNode *snode = CTX_wm_space_node(C);
+ const SpaceNode *snode = CTX_wm_space_node(&C);
if (snode == nullptr) {
return {};
};
@@ -1037,41 +1037,41 @@ static std::optional<std::string> create_socket_inspection_string(bContext *C,
return ss.str();
}
-static bool node_socket_has_tooltip(bNodeTree *ntree, bNodeSocket *socket)
+static bool node_socket_has_tooltip(const bNodeTree &ntree, const bNodeSocket &socket)
{
- if (ntree->type == NTREE_GEOMETRY) {
+ if (ntree.type == NTREE_GEOMETRY) {
return true;
}
- if (socket->runtime->declaration != nullptr) {
- const blender::nodes::SocketDeclaration &socket_decl = *socket->runtime->declaration;
+ if (socket.runtime->declaration != nullptr) {
+ const blender::nodes::SocketDeclaration &socket_decl = *socket.runtime->declaration;
return !socket_decl.description().is_empty();
}
return false;
}
-static char *node_socket_get_tooltip(bContext *C,
- bNodeTree *ntree,
- bNode *node,
- bNodeSocket *socket)
+static char *node_socket_get_tooltip(const bContext &C,
+ const bNodeTree &ntree,
+ const bNode &node,
+ const bNodeSocket &socket)
{
std::stringstream output;
- if (socket->runtime->declaration != nullptr) {
- const blender::nodes::SocketDeclaration &socket_decl = *socket->runtime->declaration;
+ if (socket.runtime->declaration != nullptr) {
+ const blender::nodes::SocketDeclaration &socket_decl = *socket.runtime->declaration;
blender::StringRef description = socket_decl.description();
if (!description.is_empty()) {
output << TIP_(description.data());
}
}
- if (ntree->type == NTREE_GEOMETRY) {
+ if (ntree.type == NTREE_GEOMETRY) {
if (!output.str().empty()) {
output << ".\n\n";
}
std::optional<std::string> socket_inspection_str = create_socket_inspection_string(
- C, *node, *socket);
+ C, node, socket);
if (socket_inspection_str.has_value()) {
output << *socket_inspection_str;
}
@@ -1081,28 +1081,31 @@ static char *node_socket_get_tooltip(bContext *C,
}
if (output.str().empty()) {
- output << nodeSocketLabel(socket);
+ output << nodeSocketLabel(&socket);
}
return BLI_strdup(output.str().c_str());
}
-void node_socket_add_tooltip(bNodeTree *ntree, bNode *node, bNodeSocket *sock, uiLayout *layout)
+void node_socket_add_tooltip(const bNodeTree &ntree,
+ const bNode &node,
+ const bNodeSocket &sock,
+ uiLayout &layout)
{
if (!node_socket_has_tooltip(ntree, sock)) {
return;
}
- SocketTooltipData *data = MEM_cnew<SocketTooltipData>(__func__);
- data->ntree = ntree;
- data->node = node;
- data->socket = sock;
+ SocketTooltipData *data = MEM_new<SocketTooltipData>(__func__);
+ data->ntree = &ntree;
+ data->node = &node;
+ data->socket = &sock;
uiLayoutSetTooltipFunc(
- layout,
+ &layout,
[](bContext *C, void *argN, const char *UNUSED(tip)) {
- SocketTooltipData *data = static_cast<SocketTooltipData *>(argN);
- return node_socket_get_tooltip(C, data->ntree, data->node, data->socket);
+ const SocketTooltipData *data = static_cast<SocketTooltipData *>(argN);
+ return node_socket_get_tooltip(*C, *data->ntree, *data->node, *data->socket);
},
data,
MEM_dupallocN,
@@ -1122,9 +1125,10 @@ static void node_socket_draw_nested(const bContext &C,
const float size,
const bool selected)
{
+ const float2 location(sock.locx, sock.locy);
+
float color[4];
float outline_color[4];
-
node_socket_color_get(C, ntree, node_ptr, sock, color);
node_socket_outline_color_get(selected, sock.type, outline_color);
@@ -1132,15 +1136,15 @@ static void node_socket_draw_nested(const bContext &C,
color,
outline_color,
size,
- sock.locx,
- sock.locy,
+ location.x,
+ location.y,
pos_id,
col_id,
shape_id,
size_id,
outline_col_id);
- if (!node_socket_has_tooltip(&ntree, &sock)) {
+ if (!node_socket_has_tooltip(ntree, sock)) {
return;
}
@@ -1152,8 +1156,8 @@ static void node_socket_draw_nested(const bContext &C,
UI_BTYPE_BUT,
0,
ICON_NONE,
- sock.locx - size / 2,
- sock.locy - size / 2,
+ location.x - size / 2.0f,
+ location.y - size / 2.0f,
size,
size,
nullptr,
@@ -1163,16 +1167,16 @@ static void node_socket_draw_nested(const bContext &C,
0,
nullptr);
- SocketTooltipData *data = (SocketTooltipData *)MEM_mallocN(sizeof(SocketTooltipData), __func__);
+ SocketTooltipData *data = MEM_new<SocketTooltipData>(__func__);
data->ntree = &ntree;
- data->node = (bNode *)node_ptr.data;
+ data->node = static_cast<const bNode *>(node_ptr.data);
data->socket = &sock;
UI_but_func_tooltip_set(
but,
[](bContext *C, void *argN, const char *UNUSED(tip)) {
SocketTooltipData *data = (SocketTooltipData *)argN;
- return node_socket_get_tooltip(C, data->ntree, data->node, data->socket);
+ return node_socket_get_tooltip(*C, *data->ntree, *data->node, *data->socket);
},
data,
MEM_freeN);
@@ -1307,7 +1311,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
}
/* Common handle function for operator buttons that need to select the node first. */
-static void node_toggle_button_cb(struct bContext *C, void *node_argv, void *op_argv)
+static void node_toggle_button_cb(bContext *C, void *node_argv, void *op_argv)
{
bNode *node = (bNode *)node_argv;
const char *opname = (const char *)op_argv;
@@ -1526,7 +1530,8 @@ static void node_draw_sockets(const View2D &v2d,
node_socket_color_get(C, ntree, node_ptr, *socket, color);
node_socket_outline_color_get(socket->flag & SELECT, socket->type, outline_color);
- node_socket_draw_multi_input(color, outline_color, width, height, socket->locx, socket->locy);
+ const float2 location(socket->locx, socket->locy);
+ node_socket_draw_multi_input(color, outline_color, width, height, location);
}
}
@@ -2263,6 +2268,7 @@ static void node_draw_basis(const bContext &C,
if (node.flag & NODE_MUTED) {
UI_GetThemeColor4fv(TH_WIRE, color_underline);
+ color_underline[3] = 1.0f;
}
else {
UI_GetThemeColorBlend4f(TH_BACK, color_id, 0.2f, color_underline);
@@ -2643,13 +2649,13 @@ static void reroute_node_prepare_for_draw(bNode &node)
const float2 loc = node_to_view(node, float2(0));
/* reroute node has exactly one input and one output, both in the same place */
- bNodeSocket *nsock = (bNodeSocket *)node.outputs.first;
- nsock->locx = loc.x;
- nsock->locy = loc.y;
+ bNodeSocket *socket = (bNodeSocket *)node.outputs.first;
+ socket->locx = loc.x;
+ socket->locy = loc.y;
- nsock = (bNodeSocket *)node.inputs.first;
- nsock->locx = loc.x;
- nsock->locy = loc.y;
+ socket = (bNodeSocket *)node.inputs.first;
+ socket->locx = loc.x;
+ socket->locy = loc.y;
const float size = 8.0f;
node.width = size * 2;
@@ -2766,7 +2772,7 @@ static void frame_node_draw_label(const bNodeTree &ntree,
BLF_wordwrap(fontid, line_width);
LISTBASE_FOREACH (const TextLine *, line, &text->lines) {
- struct ResultBLF info;
+ ResultBLF info;
if (line->line[0]) {
BLF_position(fontid, x, y, 0);
BLF_draw_ex(fontid, line->line, line->len, &info);
@@ -3021,8 +3027,9 @@ static void draw_nodetree(const bContext &C,
bNodeInstanceKey parent_key)
{
SpaceNode *snode = CTX_wm_space_node(&C);
+ ntree.ensure_topology_cache();
- Vector<bNode *> nodes = ntree.nodes;
+ Span<bNode *> nodes = ntree.all_nodes();
Array<uiBlock *> blocks = node_uiblocks_init(C, nodes);
@@ -3102,8 +3109,8 @@ void node_draw_space(const bContext &C, ARegion &region)
}
/* Current View2D center, will be set temporarily for parent node trees. */
- float center[2];
- UI_view2d_center_get(&v2d, &center[0], &center[1]);
+ float2 center;
+ UI_view2d_center_get(&v2d, &center.x, &center.y);
/* Store new view center in path and current edit tree. */
copy_v2_v2(path->view_center, center);
@@ -3142,7 +3149,7 @@ void node_draw_space(const bContext &C, ARegion &region)
GPU_line_smooth(true);
if (snode.runtime->linkdrag) {
for (const bNodeLink *link : snode.runtime->linkdrag->links) {
- node_draw_link(C, v2d, snode, *link, true);
+ node_draw_link_dragged(C, v2d, snode, *link);
}
}
GPU_line_smooth(false);
diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc
index 36836ed3691..5f92e514385 100644
--- a/source/blender/editors/space_node/node_edit.cc
+++ b/source/blender/editors/space_node/node_edit.cc
@@ -29,6 +29,8 @@
#include "BKE_scene.h"
#include "BKE_workspace.h"
+#include "BLT_translation.h"
+
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_query.h"
@@ -107,8 +109,7 @@ float2 node_link_calculate_multi_input_position(const float2 &socket_position,
{
const float offset = (total_inputs * NODE_MULTI_INPUT_LINK_GAP - NODE_MULTI_INPUT_LINK_GAP) *
0.5f;
- return {socket_position.x - NODE_SOCKSIZE * 0.5f,
- socket_position.y - offset + index * NODE_MULTI_INPUT_LINK_GAP};
+ return {socket_position.x, socket_position.y - offset + index * NODE_MULTI_INPUT_LINK_GAP};
}
static void compo_tag_output_nodes(bNodeTree *nodetree, int recalc_flags)
@@ -319,7 +320,7 @@ static void compo_completejob(void *cjv)
/** \name Composite Job C API
* \{ */
-void ED_node_composite_job(const bContext *C, struct bNodeTree *nodetree, Scene *scene_owner)
+void ED_node_composite_job(const bContext *C, bNodeTree *nodetree, Scene *scene_owner)
{
using namespace blender::ed::space_node;
@@ -463,22 +464,22 @@ void ED_node_set_tree_type(SpaceNode *snode, bNodeTreeType *typeinfo)
}
}
-bool ED_node_is_compositor(struct SpaceNode *snode)
+bool ED_node_is_compositor(SpaceNode *snode)
{
return STREQ(snode->tree_idname, ntreeType_Composite->idname);
}
-bool ED_node_is_shader(struct SpaceNode *snode)
+bool ED_node_is_shader(SpaceNode *snode)
{
return STREQ(snode->tree_idname, ntreeType_Shader->idname);
}
-bool ED_node_is_texture(struct SpaceNode *snode)
+bool ED_node_is_texture(SpaceNode *snode)
{
return STREQ(snode->tree_idname, ntreeType_Texture->idname);
}
-bool ED_node_is_geometry(struct SpaceNode *snode)
+bool ED_node_is_geometry(SpaceNode *snode)
{
return STREQ(snode->tree_idname, ntreeType_Geometry->idname);
}
@@ -549,7 +550,7 @@ void ED_node_shader_default(const bContext *C, ID *id)
}
}
-void ED_node_composit_default(const bContext *C, struct Scene *sce)
+void ED_node_composit_default(const bContext *C, Scene *sce)
{
/* but lets check it anyway */
if (sce->nodetree) {
@@ -920,7 +921,7 @@ static void edit_node_properties_get(
/** \name Node Generic
* \{ */
-static bool socket_is_occluded(const bNodeSocket &sock,
+static bool socket_is_occluded(const float2 &location,
const bNode &node_the_socket_belongs_to,
const SpaceNode &snode)
{
@@ -932,7 +933,7 @@ static bool socket_is_occluded(const bNodeSocket &sock,
rctf socket_hitbox;
const float socket_hitbox_radius = NODE_SOCKSIZE - 0.1f * U.widget_unit;
- BLI_rctf_init_pt_radius(&socket_hitbox, float2(sock.locx, sock.locy), socket_hitbox_radius);
+ BLI_rctf_init_pt_radius(&socket_hitbox, location, socket_hitbox_radius);
if (BLI_rctf_inside_rctf(&node->totr, &socket_hitbox)) {
return true;
}
@@ -955,14 +956,14 @@ struct NodeSizeWidget {
};
static void node_resize_init(
- bContext *C, wmOperator *op, const float cursor[2], const bNode *node, NodeResizeDirection dir)
+ bContext *C, wmOperator *op, const float2 &cursor, const bNode *node, NodeResizeDirection dir)
{
NodeSizeWidget *nsw = MEM_cnew<NodeSizeWidget>(__func__);
op->customdata = nsw;
- nsw->mxstart = cursor[0];
- nsw->mystart = cursor[1];
+ nsw->mxstart = cursor.x;
+ nsw->mystart = cursor.y;
/* store old */
nsw->oldlocx = node->locx;
@@ -1009,12 +1010,12 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
switch (event->type) {
case MOUSEMOVE: {
- int mval[2];
+ int2 mval;
WM_event_drag_start_mval(event, region, mval);
float mx, my;
- UI_view2d_region_to_view(&region->v2d, mval[0], mval[1], &mx, &my);
- float dx = (mx - nsw->mxstart) / UI_DPI_FAC;
- float dy = (my - nsw->mystart) / UI_DPI_FAC;
+ UI_view2d_region_to_view(&region->v2d, mval.x, mval.y, &mx, &my);
+ const float dx = (mx - nsw->mxstart) / UI_DPI_FAC;
+ const float dy = (my - nsw->mystart) / UI_DPI_FAC;
if (node) {
float *pwidth = &node->width;
@@ -1116,11 +1117,11 @@ static int node_resize_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
/* convert mouse coordinates to v2d space */
- float cursor[2];
- int mval[2];
+ float2 cursor;
+ int2 mval;
WM_event_drag_start_mval(event, region, mval);
- UI_view2d_region_to_view(&region->v2d, mval[0], mval[1], &cursor[0], &cursor[1]);
- const NodeResizeDirection dir = node_get_resize_direction(node, cursor[0], cursor[1]);
+ UI_view2d_region_to_view(&region->v2d, mval.x, mval.y, &cursor.x, &cursor.y);
+ const NodeResizeDirection dir = node_get_resize_direction(node, cursor.x, cursor.y);
if (dir == NODE_RESIZE_NONE) {
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
@@ -1198,21 +1199,22 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
}
/* checks snode->mouse position, and returns found node/socket */
-static bool cursor_isect_multi_input_socket(const float cursor[2], const bNodeSocket &socket)
+static bool cursor_isect_multi_input_socket(const float2 &cursor, const bNodeSocket &socket)
{
const float node_socket_height = node_socket_calculate_height(socket);
- rctf multi_socket_rect;
+ const float2 location(socket.locx, socket.locy);
/* `.xmax = socket->locx + NODE_SOCKSIZE * 5.5f`
* would be the same behavior as for regular sockets.
* But keep it smaller because for multi-input socket you
* sometimes want to drag the link to the other side, if you may
* accidentally pick the wrong link otherwise. */
+ rctf multi_socket_rect;
BLI_rctf_init(&multi_socket_rect,
- socket.locx - NODE_SOCKSIZE * 4.0f,
- socket.locx + NODE_SOCKSIZE * 2.0f,
- socket.locy - node_socket_height,
- socket.locy + node_socket_height);
- if (BLI_rctf_isect_pt(&multi_socket_rect, cursor[0], cursor[1])) {
+ location.x - NODE_SOCKSIZE * 4.0f,
+ location.x + NODE_SOCKSIZE * 2.0f,
+ location.y - node_socket_height,
+ location.y + node_socket_height);
+ if (BLI_rctf_isect_pt(&multi_socket_rect, cursor.x, cursor.y)) {
return true;
}
return false;
@@ -1250,17 +1252,18 @@ bool node_find_indicated_socket(SpaceNode &snode,
if (in_out & SOCK_IN) {
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
if (!nodeSocketIsHidden(sock)) {
+ const float2 location(sock->locx, sock->locy);
if (sock->flag & SOCK_MULTI_INPUT && !(node->flag & NODE_HIDDEN)) {
if (cursor_isect_multi_input_socket(cursor, *sock)) {
- if (!socket_is_occluded(*sock, *node, snode)) {
+ if (!socket_is_occluded(location, *node, snode)) {
*nodep = node;
*sockp = sock;
return true;
}
}
}
- else if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
- if (!socket_is_occluded(*sock, *node, snode)) {
+ else if (BLI_rctf_isect_pt(&rect, location.x, location.y)) {
+ if (!socket_is_occluded(location, *node, snode)) {
*nodep = node;
*sockp = sock;
return true;
@@ -1272,8 +1275,9 @@ bool node_find_indicated_socket(SpaceNode &snode,
if (in_out & SOCK_OUT) {
LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
if (!nodeSocketIsHidden(sock)) {
- if (BLI_rctf_isect_pt(&rect, sock->locx, sock->locy)) {
- if (!socket_is_occluded(*sock, *node, snode)) {
+ const float2 location(sock->locx, sock->locy);
+ if (BLI_rctf_isect_pt(&rect, location.x, location.y)) {
+ if (!socket_is_occluded(location, *node, snode)) {
*nodep = node;
*sockp = sock;
return true;
@@ -1299,11 +1303,12 @@ float node_link_dim_factor(const View2D &v2d, const bNodeLink &link)
return 1.0f;
}
+ const float2 from(link.fromsock->locx, link.fromsock->locy);
+ const float2 to(link.tosock->locx, link.tosock->locy);
+
const float min_endpoint_distance = std::min(
- std::max(BLI_rctf_length_x(&v2d.cur, link.fromsock->locx),
- BLI_rctf_length_y(&v2d.cur, link.fromsock->locy)),
- std::max(BLI_rctf_length_x(&v2d.cur, link.tosock->locx),
- BLI_rctf_length_y(&v2d.cur, link.tosock->locy)));
+ std::max(BLI_rctf_length_x(&v2d.cur, from.x), BLI_rctf_length_y(&v2d.cur, from.y)),
+ std::max(BLI_rctf_length_x(&v2d.cur, to.x), BLI_rctf_length_y(&v2d.cur, to.y)));
if (min_endpoint_distance == 0.0f) {
return 1.0f;
@@ -1362,7 +1367,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
bNode *lastnode = (bNode *)ntree->nodes.last;
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->flag & SELECT) {
- bNode *new_node = blender::bke::node_copy_with_mapping(
+ bNode *new_node = bke::node_copy_with_mapping(
ntree, *node, LIB_ID_COPY_DEFAULT, true, socket_map);
node_map.add_new(node, new_node);
changed = true;
@@ -2229,12 +2234,12 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
if (node->flag & SELECT) {
/* No ID refcounting, this node is virtual,
* detached from any actual Blender data currently. */
- bNode *new_node = blender::bke::node_copy_with_mapping(nullptr,
- *node,
- LIB_ID_CREATE_NO_USER_REFCOUNT |
- LIB_ID_CREATE_NO_MAIN,
- false,
- socket_map);
+ bNode *new_node = bke::node_copy_with_mapping(nullptr,
+ *node,
+ LIB_ID_CREATE_NO_USER_REFCOUNT |
+ LIB_ID_CREATE_NO_MAIN,
+ false,
+ socket_map);
node_map.add_new(node, new_node);
}
}
@@ -2354,11 +2359,11 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
node_deselect_all(*snode);
/* calculate "barycenter" for placing on mouse cursor */
- float center[2] = {0.0f, 0.0f};
+ float2 center = {0.0f, 0.0f};
int num_nodes = 0;
LISTBASE_FOREACH_INDEX (bNode *, node, clipboard_nodes_lb, num_nodes) {
- center[0] += BLI_rctf_cent_x(&node->totr);
- center[1] += BLI_rctf_cent_y(&node->totr);
+ center.x += BLI_rctf_cent_x(&node->totr);
+ center.y += BLI_rctf_cent_y(&node->totr);
}
mul_v2_fl(center, 1.0 / num_nodes);
@@ -2367,7 +2372,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
/* copy nodes from clipboard */
LISTBASE_FOREACH (bNode *, node, clipboard_nodes_lb) {
- bNode *new_node = blender::bke::node_copy_with_mapping(
+ bNode *new_node = bke::node_copy_with_mapping(
ntree, *node, LIB_ID_COPY_DEFAULT, true, socket_map);
node_map.add_new(node, new_node);
}
@@ -2442,7 +2447,7 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op)
const eNodeSocketInOut in_out = (eNodeSocketInOut)RNA_enum_get(op->ptr, "in_out");
ListBase *sockets = (in_out == SOCK_IN) ? &ntree->inputs : &ntree->outputs;
- const char *default_name = (in_out == SOCK_IN) ? "Input" : "Output";
+ const char *default_name = (in_out == SOCK_IN) ? DATA_("Input") : DATA_("Output");
bNodeSocket *active_sock = ntree_get_active_interface_socket(sockets);
bNodeSocket *sock;
diff --git a/source/blender/editors/space_node/node_gizmo.cc b/source/blender/editors/space_node/node_gizmo.cc
index 4f27f9baabc..f9126556b71 100644
--- a/source/blender/editors/space_node/node_gizmo.cc
+++ b/source/blender/editors/space_node/node_gizmo.cc
@@ -49,14 +49,14 @@ static void node_gizmo_calc_matrix_space(const SpaceNode *snode,
static void node_gizmo_calc_matrix_space_with_image_dims(const SpaceNode *snode,
const ARegion *region,
- const float image_dims[2],
+ const float2 &image_dims,
float matrix_space[4][4])
{
unit_m4(matrix_space);
- mul_v3_fl(matrix_space[0], snode->zoom * image_dims[0]);
- mul_v3_fl(matrix_space[1], snode->zoom * image_dims[1]);
- matrix_space[3][0] = ((region->winx / 2) + snode->xof) - ((image_dims[0] / 2.0f) * snode->zoom);
- matrix_space[3][1] = ((region->winy / 2) + snode->yof) - ((image_dims[1] / 2.0f) * snode->zoom);
+ mul_v3_fl(matrix_space[0], snode->zoom * image_dims.x);
+ mul_v3_fl(matrix_space[1], snode->zoom * image_dims.y);
+ matrix_space[3][0] = ((region->winx / 2) + snode->xof) - ((image_dims.x / 2.0f) * snode->zoom);
+ matrix_space[3][1] = ((region->winy / 2) + snode->yof) - ((image_dims.y / 2.0f) * snode->zoom);
}
/** \} */
@@ -135,7 +135,7 @@ static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmGizmoGroup *
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock);
if (ibuf) {
- const float dims[2] = {
+ const float2 dims = {
(ibuf->x > 0) ? ibuf->x : 64.0f,
(ibuf->y > 0) ? ibuf->y : 64.0f,
};
@@ -190,7 +190,7 @@ struct NodeCropWidgetGroup {
wmGizmo *border;
struct {
- float dims[2];
+ float2 dims;
} state;
struct {
@@ -206,10 +206,7 @@ static void gizmo_node_crop_update(struct NodeCropWidgetGroup *crop_group)
crop_group->update_data.context, &crop_group->update_data.ptr, crop_group->update_data.prop);
}
-static void two_xy_to_rect(const NodeTwoXYs *nxy,
- rctf *rect,
- const float dims[2],
- bool is_relative)
+static void two_xy_to_rect(const NodeTwoXYs *nxy, rctf *rect, const float2 &dims, bool is_relative)
{
if (is_relative) {
rect->xmin = nxy->fac_x1;
@@ -218,16 +215,16 @@ static void two_xy_to_rect(const NodeTwoXYs *nxy,
rect->ymax = nxy->fac_y2;
}
else {
- rect->xmin = nxy->x1 / dims[0];
- rect->xmax = nxy->x2 / dims[0];
- rect->ymin = nxy->y1 / dims[1];
- rect->ymax = nxy->y2 / dims[1];
+ rect->xmin = nxy->x1 / dims.x;
+ rect->xmax = nxy->x2 / dims.x;
+ rect->ymin = nxy->y1 / dims.y;
+ rect->ymax = nxy->y2 / dims.y;
}
}
static void two_xy_from_rect(NodeTwoXYs *nxy,
const rctf *rect,
- const float dims[2],
+ const float2 &dims,
bool is_relative)
{
if (is_relative) {
@@ -237,10 +234,10 @@ static void two_xy_from_rect(NodeTwoXYs *nxy,
nxy->fac_y2 = rect->ymax;
}
else {
- nxy->x1 = rect->xmin * dims[0];
- nxy->x2 = rect->xmax * dims[0];
- nxy->y1 = rect->ymin * dims[1];
- nxy->y2 = rect->ymax * dims[1];
+ nxy->x1 = rect->xmin * dims.x;
+ nxy->x2 = rect->xmax * dims.x;
+ nxy->y1 = rect->ymin * dims.y;
+ nxy->y2 = rect->ymax * dims.y;
}
}
@@ -321,9 +318,7 @@ static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmGizmoGroupType *UNUS
static void WIDGETGROUP_node_crop_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
- struct NodeCropWidgetGroup *crop_group = (NodeCropWidgetGroup *)MEM_mallocN(
- sizeof(struct NodeCropWidgetGroup), __func__);
-
+ NodeCropWidgetGroup *crop_group = MEM_new<NodeCropWidgetGroup>(__func__);
crop_group->border = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, nullptr);
RNA_enum_set(crop_group->border->ptr,
@@ -407,7 +402,7 @@ struct NodeSunBeamsWidgetGroup {
wmGizmo *gizmo;
struct {
- float dims[2];
+ float2 dims;
} state;
};
@@ -512,7 +507,7 @@ struct NodeCornerPinWidgetGroup {
wmGizmo *gizmos[4];
struct {
- float dims[2];
+ float2 dims;
} state;
};
diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc
index a926f7e8917..21def1bd9d7 100644
--- a/source/blender/editors/space_node/node_group.cc
+++ b/source/blender/editors/space_node/node_group.cc
@@ -25,6 +25,7 @@
#include "BKE_context.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
+#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "BKE_report.h"
@@ -45,7 +46,12 @@
#include "UI_resources.h"
#include "NOD_common.h"
+#include "NOD_composite.h"
+#include "NOD_geometry.h"
+#include "NOD_shader.h"
#include "NOD_socket.h"
+#include "NOD_texture.h"
+
#include "node_intern.hh" /* own include */
namespace blender::ed::space_node {
@@ -100,16 +106,16 @@ const char *node_group_idname(bContext *C)
SpaceNode *snode = CTX_wm_space_node(C);
if (ED_node_is_shader(snode)) {
- return "ShaderNodeGroup";
+ return ntreeType_Shader->group_idname;
}
if (ED_node_is_compositor(snode)) {
- return "CompositorNodeGroup";
+ return ntreeType_Composite->group_idname;
}
if (ED_node_is_texture(snode)) {
- return "TextureNodeGroup";
+ return ntreeType_Texture->group_idname;
}
if (ED_node_is_geometry(snode)) {
- return "GeometryNodeGroup";
+ return ntreeType_Geometry->group_idname;
}
return "";
@@ -457,8 +463,7 @@ static bool node_group_separate_selected(
bNode *newnode;
if (make_copy) {
/* make a copy */
- newnode = blender::bke::node_copy_with_mapping(
- &ngroup, *node, LIB_ID_COPY_DEFAULT, true, socket_map);
+ newnode = bke::node_copy_with_mapping(&ngroup, *node, LIB_ID_COPY_DEFAULT, true, socket_map);
node_map.add_new(node, newnode);
}
else {
@@ -648,7 +653,7 @@ static bool node_group_make_use_node(bNode &node, bNode *gnode)
static bool node_group_make_test_selected(bNodeTree &ntree,
bNode *gnode,
const char *ntree_idname,
- struct ReportList &reports)
+ ReportList &reports)
{
int ok = true;
@@ -712,13 +717,13 @@ static int node_get_selected_minmax(
INIT_MINMAX2(min, max);
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
if (node_group_make_use_node(*node, gnode)) {
- float loc[2];
- nodeToView(node, node->offsetx, node->offsety, &loc[0], &loc[1]);
- minmax_v2v2_v2(min, max, loc);
+ float2 loc;
+ nodeToView(node, node->offsetx, node->offsety, &loc.x, &loc.y);
+ math::min_max(loc, min, max);
if (use_size) {
- loc[0] += node->width;
- loc[1] -= node->height;
- minmax_v2v2_v2(min, max, loc);
+ loc.x += node->width;
+ loc.y -= node->height;
+ math::min_max(loc, min, max);
}
totselect++;
}
@@ -832,8 +837,8 @@ static void node_group_make_insert_selected(const bContext &C, bNodeTree &ntree,
/* relink external sockets */
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) {
- int fromselect = node_group_make_use_node(*link->fromnode, gnode);
- int toselect = node_group_make_use_node(*link->tonode, gnode);
+ const bool fromselect = node_group_make_use_node(*link->fromnode, gnode);
+ const bool toselect = node_group_make_use_node(*link->tonode, gnode);
if ((fromselect && link->tonode == gnode) || (toselect && link->fromnode == gnode)) {
/* remove all links to/from the gnode.
@@ -913,8 +918,8 @@ static void node_group_make_insert_selected(const bContext &C, bNodeTree &ntree,
/* move internal links */
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) {
- int fromselect = node_group_make_use_node(*link->fromnode, gnode);
- int toselect = node_group_make_use_node(*link->tonode, gnode);
+ const bool fromselect = node_group_make_use_node(*link->fromnode, gnode);
+ const bool toselect = node_group_make_use_node(*link->tonode, gnode);
if (fromselect && toselect) {
BLI_remlink(&ntree.links, link);
@@ -1037,9 +1042,6 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
nodeSetActive(&ntree, gnode);
if (ngroup) {
ED_node_tree_push(&snode, ngroup, gnode);
- LISTBASE_FOREACH (bNode *, node, &ngroup->nodes) {
- sort_multi_input_socket_links(snode, *node, nullptr, nullptr);
- }
}
}
diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh
index 924537d0e8a..6754673cffc 100644
--- a/source/blender/editors/space_node/node_intern.hh
+++ b/source/blender/editors/space_node/node_intern.hh
@@ -144,7 +144,10 @@ void node_socket_color_get(const bContext &C,
void node_draw_space(const bContext &C, ARegion &region);
-void node_socket_add_tooltip(bNodeTree *ntree, bNode *node, bNodeSocket *sock, uiLayout *layout);
+void node_socket_add_tooltip(const bNodeTree &ntree,
+ const bNode &node,
+ const bNodeSocket &sock,
+ uiLayout &layout);
/**
* Sort nodes by selection: unselected nodes first, then selected,
@@ -166,7 +169,7 @@ void node_keymap(wmKeyConfig *keyconf);
/* node_select.cc */
rctf node_frame_rect_inside(const bNode &node);
-bool node_or_socket_isect_event(bContext *C, const wmEvent *event);
+bool node_or_socket_isect_event(const bContext &C, const wmEvent &event);
void node_deselect_all(SpaceNode &snode);
void node_socket_select(bNode *node, bNodeSocket &sock);
@@ -214,6 +217,10 @@ void node_draw_link(const bContext &C,
const SpaceNode &snode,
const bNodeLink &link,
bool selected);
+void node_draw_link_dragged(const bContext &C,
+ const View2D &v2d,
+ const SpaceNode &snode,
+ const bNodeLink &link);
/**
* Don't do shadows if th_col3 is -1.
*/
@@ -225,19 +232,12 @@ void node_draw_link_bezier(const bContext &C,
int th_col2,
int th_col3,
bool selected);
-/** If v2d not nullptr, it clips and returns 0 if not visible. */
-bool node_link_bezier_points(const View2D *v2d,
- const SpaceNode *snode,
- const bNodeLink &link,
- float coord_array[][2],
- int resol);
-/**
- * Return quadratic beziers points for a given nodelink and clip if v2d is not nullptr.
- */
-bool node_link_bezier_handles(const View2D *v2d,
- const SpaceNode *snode,
- const bNodeLink &ink,
- float vec[4][2]);
+
+void node_link_bezier_points_evaluated(const bNodeLink &link,
+ std::array<float2, NODE_LINK_RESOL + 1> &coords);
+
+std::optional<float2> link_path_intersection(const bNodeLink &link, Span<float2> path);
+
void draw_nodespace_back_pix(const bContext &C,
ARegion &region,
SpaceNode &snode,
@@ -245,12 +245,9 @@ void draw_nodespace_back_pix(const bContext &C,
/* node_add.cc */
-/**
- * XXX Does some additional initialization on top of #nodeAddNode
- * Can be used with both custom and static nodes,
- * if `idname == nullptr` the static int type will be used instead.
- */
-bNode *node_add_node(const bContext &C, const char *idname, int type, float locx, float locy);
+bNode *add_node(const bContext &C, StringRef idname, const float2 &location);
+bNode *add_static_node(const bContext &C, int type, const float2 &location);
+
void NODE_OT_add_reroute(wmOperatorType *ot);
void NODE_OT_add_group(wmOperatorType *ot);
void NODE_OT_add_object(wmOperatorType *ot);
@@ -270,11 +267,6 @@ void NODE_OT_group_edit(wmOperatorType *ot);
/* node_relationships.cc */
-void sort_multi_input_socket_links(SpaceNode &snode,
- bNode &node,
- bNodeLink *drag_link,
- const float2 *cursor);
-
void NODE_OT_link(wmOperatorType *ot);
void NODE_OT_link_make(wmOperatorType *ot);
void NODE_OT_links_cut(wmOperatorType *ot);
diff --git a/source/blender/editors/space_node/node_ops.cc b/source/blender/editors/space_node/node_ops.cc
index ce000aba1da..c936f07a594 100644
--- a/source/blender/editors/space_node/node_ops.cc
+++ b/source/blender/editors/space_node/node_ops.cc
@@ -111,7 +111,7 @@ void node_operatortypes()
WM_operatortype_append(NODE_OT_cryptomatte_layer_remove);
}
-void node_keymap(struct wmKeyConfig *keyconf)
+void node_keymap( wmKeyConfig *keyconf)
{
/* Entire Editor only ----------------- */
WM_keymap_ensure(keyconf, "Node Generic", SPACE_NODE, 0);
diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc
index ce4ae421498..067c01dcc58 100644
--- a/source/blender/editors/space_node/node_relationships.cc
+++ b/source/blender/editors/space_node/node_relationships.cc
@@ -11,6 +11,7 @@
#include "DNA_node_types.h"
#include "BLI_easing.h"
+#include "BLI_stack.hh"
#include "BKE_anim_data.h"
#include "BKE_context.h"
@@ -18,6 +19,7 @@
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "BKE_screen.h"
@@ -46,19 +48,11 @@
#include "BLT_translation.h"
#include "NOD_node_declaration.hh"
-#include "NOD_node_tree_ref.hh"
#include "NOD_socket_declarations.hh"
#include "NOD_socket_declarations_geometry.hh"
#include "node_intern.hh" /* own include */
-using namespace blender::nodes::node_tree_ref_types;
-
-struct bNodeListItem {
- struct bNodeListItem *next, *prev;
- struct bNode *node;
-};
-
struct NodeInsertOfsData {
bNodeTree *ntree;
bNode *insert; /* inserted node */
@@ -79,6 +73,8 @@ static void clear_picking_highlight(ListBase *links)
namespace blender::ed::space_node {
+void update_multi_input_indices_for_removed_links(bNode &node);
+
/* -------------------------------------------------------------------- */
/** \name Add Node
* \{ */
@@ -109,11 +105,9 @@ static void pick_link(
nldrag.links.append(link);
nodeRemLink(snode.edittree, &link_to_pick);
-
+ snode.edittree->ensure_topology_cache();
BLI_assert(nldrag.last_node_hovered_while_dragging_a_link != nullptr);
-
- sort_multi_input_socket_links(
- snode, *nldrag.last_node_hovered_while_dragging_a_link, nullptr, nullptr);
+ update_multi_input_indices_for_removed_links(*nldrag.last_node_hovered_while_dragging_a_link);
/* Send changed event to original link->tonode. */
if (node) {
@@ -127,10 +121,8 @@ static void pick_input_link_by_link_intersect(const bContext &C,
const float2 &cursor)
{
SpaceNode *snode = CTX_wm_space_node(&C);
- const ARegion *region = CTX_wm_region(&C);
- const View2D *v2d = &region->v2d;
- float drag_start[2];
+ float2 drag_start;
RNA_float_get_array(op.ptr, "drag_start", drag_start);
bNode *node;
bNodeSocket *socket;
@@ -139,26 +131,16 @@ static void pick_input_link_by_link_intersect(const bContext &C,
/* Distance to test overlapping of cursor on link. */
const float cursor_link_touch_distance = 12.5f * UI_DPI_FAC;
- const int resolution = NODE_LINK_RESOL;
-
bNodeLink *link_to_pick = nullptr;
clear_picking_highlight(&snode->edittree->links);
LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
if (link->tosock == socket) {
/* Test if the cursor is near a link. */
- float vec[4][2];
- node_link_bezier_handles(v2d, snode, *link, vec);
-
- float data[NODE_LINK_RESOL * 2 + 2];
- BKE_curve_forward_diff_bezier(
- vec[0][0], vec[1][0], vec[2][0], vec[3][0], data, resolution, sizeof(float[2]));
- BKE_curve_forward_diff_bezier(
- vec[0][1], vec[1][1], vec[2][1], vec[3][1], data + 1, resolution, sizeof(float[2]));
-
- for (int i = 0; i < resolution * 2; i += 2) {
- float *l1 = &data[i];
- float *l2 = &data[i + 2];
- float distance = dist_squared_to_line_segment_v2(cursor, l1, l2);
+ std::array<float2, NODE_LINK_RESOL + 1> coords;
+ node_link_bezier_points_evaluated(*link, coords);
+
+ for (const int i : IndexRange(coords.size() - 1)) {
+ const float distance = dist_squared_to_line_segment_v2(cursor, coords[i], coords[i + 1]);
if (distance < cursor_link_touch_distance) {
link_to_pick = link;
nldrag.last_picked_multi_input_socket_link = link_to_pick;
@@ -310,35 +292,24 @@ struct LinkAndPosition {
float2 multi_socket_position;
};
-void sort_multi_input_socket_links(SpaceNode &snode,
- bNode &node,
- bNodeLink *drag_link,
- const float2 *cursor)
+static void sort_multi_input_socket_links_with_drag(bNode &node,
+ bNodeLink &drag_link,
+ const float2 &cursor)
{
- LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
- if (!(socket->flag & SOCK_MULTI_INPUT)) {
+ for (bNodeSocket *socket : node.input_sockets()) {
+ if (!socket->is_multi_input()) {
continue;
}
- Vector<LinkAndPosition, 8> links;
+ const float2 &socket_location = {socket->locx, socket->locy};
- LISTBASE_FOREACH (bNodeLink *, link, &snode.edittree->links) {
- if (link->tosock == socket) {
- links.append(
- {link,
- node_link_calculate_multi_input_position({link->tosock->locx, link->tosock->locy},
- link->multi_input_socket_index,
- link->tosock->total_inputs)});
- }
- }
+ Vector<LinkAndPosition, 8> links;
+ for (bNodeLink *link : socket->directly_linked_links()) {
+ const float2 location = node_link_calculate_multi_input_position(
+ socket_location, link->multi_input_socket_index, link->tosock->total_inputs);
+ links.append({link, location});
+ };
- if (drag_link) {
- LinkAndPosition link_and_position{};
- link_and_position.link = drag_link;
- if (cursor) {
- link_and_position.multi_socket_position = *cursor;
- }
- links.append(link_and_position);
- }
+ links.append({&drag_link, cursor});
std::sort(links.begin(), links.end(), [](const LinkAndPosition a, const LinkAndPosition b) {
return a.multi_socket_position.y < b.multi_socket_position.y;
@@ -350,6 +321,23 @@ void sort_multi_input_socket_links(SpaceNode &snode,
}
}
+void update_multi_input_indices_for_removed_links(bNode &node)
+{
+ for (bNodeSocket *socket : node.input_sockets()) {
+ if (!socket->is_multi_input()) {
+ continue;
+ }
+ Vector<bNodeLink *, 8> links = socket->directly_linked_links();
+ std::sort(links.begin(), links.end(), [](const bNodeLink *a, const bNodeLink *b) {
+ return a->multi_input_socket_index < b->multi_input_socket_index;
+ });
+
+ for (const int i : links.index_range()) {
+ links[i]->multi_input_socket_index = i;
+ }
+ }
+}
+
static void snode_autoconnect(SpaceNode &snode, const bool allow_multiple, const bool replace)
{
bNodeTree *ntree = snode.edittree;
@@ -434,18 +422,18 @@ namespace viewer_linking {
* \{ */
/* Depending on the node tree type, different socket types are supported by viewer nodes. */
-static bool socket_can_be_viewed(const OutputSocketRef &socket)
+static bool socket_can_be_viewed(const bNodeSocket &socket)
{
- if (nodeSocketIsHidden(socket.bsocket())) {
+ if (nodeSocketIsHidden(&socket)) {
return false;
}
- if (socket.idname() == "NodeSocketVirtual") {
+ if (STREQ(socket.idname, "NodeSocketVirtual")) {
return false;
}
- if (socket.tree().btree()->type != NTREE_GEOMETRY) {
+ if (socket.owner_tree().type != NTREE_GEOMETRY) {
return true;
}
- return ELEM(socket.typeinfo()->type,
+ return ELEM(socket.typeinfo->type,
SOCK_GEOMETRY,
SOCK_FLOAT,
SOCK_VECTOR,
@@ -502,15 +490,15 @@ static bNodeSocket *node_link_viewer_get_socket(bNodeTree &ntree,
return nullptr;
}
-static bool is_viewer_node(const NodeRef &node)
+static bool is_viewer_node(const bNode &node)
{
- return ELEM(node.bnode()->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER);
+ return ELEM(node.type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER, GEO_NODE_VIEWER);
}
-static Vector<const NodeRef *> find_viewer_nodes(const NodeTreeRef &tree)
+static Vector<const bNode *> find_viewer_nodes(const bNodeTree &tree)
{
- Vector<const NodeRef *> viewer_nodes;
- for (const NodeRef *node : tree.nodes()) {
+ Vector<const bNode *> viewer_nodes;
+ for (const bNode *node : tree.all_nodes()) {
if (is_viewer_node(*node)) {
viewer_nodes.append(node);
}
@@ -518,20 +506,20 @@ static Vector<const NodeRef *> find_viewer_nodes(const NodeTreeRef &tree)
return viewer_nodes;
}
-static bool is_viewer_socket_in_viewer(const InputSocketRef &socket)
+static bool is_viewer_socket_in_viewer(const bNodeSocket &socket)
{
- const NodeRef &node = socket.node();
+ const bNode &node = socket.owner_node();
BLI_assert(is_viewer_node(node));
- if (node.typeinfo()->type == GEO_NODE_VIEWER) {
+ if (node.typeinfo->type == GEO_NODE_VIEWER) {
return true;
}
return socket.index() == 0;
}
-static bool is_linked_to_viewer(const OutputSocketRef &socket, const NodeRef &viewer_node)
+static bool is_linked_to_viewer(const bNodeSocket &socket, const bNode &viewer_node)
{
- for (const InputSocketRef *target_socket : socket.directly_linked_sockets()) {
- if (&target_socket->node() != &viewer_node) {
+ for (const bNodeSocket *target_socket : socket.directly_linked_sockets()) {
+ if (&target_socket->owner_node() != &viewer_node) {
continue;
}
if (!target_socket->is_available()) {
@@ -561,39 +549,39 @@ static void remove_links_to_unavailable_viewer_sockets(bNodeTree &btree, bNode &
}
}
-static const NodeRef *get_existing_viewer(const NodeTreeRef &tree)
+static const bNode *get_existing_viewer(const bNodeTree &tree)
{
- Vector<const NodeRef *> viewer_nodes = find_viewer_nodes(tree);
+ Vector<const bNode *> viewer_nodes = find_viewer_nodes(tree);
/* Check if there is already an active viewer node that should be used. */
- for (const NodeRef *viewer_node : viewer_nodes) {
- if (viewer_node->bnode()->flag & NODE_DO_OUTPUT) {
+ for (const bNode *viewer_node : viewer_nodes) {
+ if (viewer_node->flag & NODE_DO_OUTPUT) {
return viewer_node;
}
}
/* If no active but non-active viewers exist, make one active. */
if (!viewer_nodes.is_empty()) {
- viewer_nodes[0]->bnode()->flag |= NODE_DO_OUTPUT;
+ const_cast<bNode *>(viewer_nodes[0])->flag |= NODE_DO_OUTPUT;
return viewer_nodes[0];
}
return nullptr;
}
-static const OutputSocketRef *find_output_socket_to_be_viewed(const NodeRef *active_viewer_node,
- const NodeRef &node_to_view)
+static const bNodeSocket *find_output_socket_to_be_viewed(const bNode *active_viewer_node,
+ const bNode &node_to_view)
{
/* Check if any of the output sockets is selected, which is the case when the user just clicked
* on the socket. */
- for (const OutputSocketRef *output_socket : node_to_view.outputs()) {
- if (output_socket->bsocket()->flag & SELECT) {
+ for (const bNodeSocket *output_socket : node_to_view.output_sockets()) {
+ if (output_socket->flag & SELECT) {
return output_socket;
}
}
- const OutputSocketRef *last_socket_linked_to_viewer = nullptr;
+ const bNodeSocket *last_socket_linked_to_viewer = nullptr;
if (active_viewer_node != nullptr) {
- for (const OutputSocketRef *output_socket : node_to_view.outputs()) {
+ for (const bNodeSocket *output_socket : node_to_view.output_sockets()) {
if (!socket_can_be_viewed(*output_socket)) {
continue;
}
@@ -604,7 +592,7 @@ static const OutputSocketRef *find_output_socket_to_be_viewed(const NodeRef *act
}
if (last_socket_linked_to_viewer == nullptr) {
/* If no output is connected to a viewer, use the first output that can be viewed. */
- for (const OutputSocketRef *output_socket : node_to_view.outputs()) {
+ for (const bNodeSocket *output_socket : node_to_view.output_sockets()) {
if (socket_can_be_viewed(*output_socket)) {
return output_socket;
}
@@ -612,10 +600,10 @@ static const OutputSocketRef *find_output_socket_to_be_viewed(const NodeRef *act
}
else {
/* Pick the next socket to be linked to the viewer. */
- const int tot_outputs = node_to_view.outputs().size();
+ const int tot_outputs = node_to_view.output_sockets().size();
for (const int offset : IndexRange(1, tot_outputs - 1)) {
const int index = (last_socket_linked_to_viewer->index() + offset) % tot_outputs;
- const OutputSocketRef &output_socket = node_to_view.output(index);
+ const bNodeSocket &output_socket = node_to_view.output_socket(index);
if (!socket_can_be_viewed(output_socket)) {
continue;
}
@@ -639,13 +627,9 @@ static int link_socket_to_viewer(const bContext &C,
if (viewer_bnode == nullptr) {
/* Create a new viewer node if none exists. */
const int viewer_type = get_default_viewer_type(&C);
- /* The socket location is in view space, so dividing by #UI_DPI_FAC
- * brings it into the coordinate space of the node editor. */
- viewer_bnode = node_add_node(C,
- nullptr,
- viewer_type,
- bsocket_to_view.locx / UI_DPI_FAC + 100,
- bsocket_to_view.locy / UI_DPI_FAC);
+ const float2 location{bsocket_to_view.locx / UI_DPI_FAC + 100,
+ bsocket_to_view.locy / UI_DPI_FAC};
+ viewer_bnode = add_static_node(C, viewer_type, location);
if (viewer_bnode == nullptr) {
return OPERATOR_CANCELLED;
}
@@ -687,20 +671,15 @@ static int node_link_viewer(const bContext &C, bNode &bnode_to_view)
{
SpaceNode &snode = *CTX_wm_space_node(&C);
bNodeTree *btree = snode.edittree;
+ btree->ensure_topology_cache();
- const NodeTreeRef tree{btree};
- const NodeRef &node_to_view = *tree.find_node(bnode_to_view);
- const NodeRef *active_viewer_node = get_existing_viewer(tree);
-
- const OutputSocketRef *socket_to_view = find_output_socket_to_be_viewed(active_viewer_node,
- node_to_view);
- if (socket_to_view == nullptr) {
+ bNode *active_viewer_bnode = const_cast<bNode *>(get_existing_viewer(*btree));
+ bNodeSocket *bsocket_to_view = const_cast<bNodeSocket *>(
+ find_output_socket_to_be_viewed(active_viewer_bnode, bnode_to_view));
+ if (bsocket_to_view == nullptr) {
return OPERATOR_FINISHED;
}
-
- bNodeSocket &bsocket_to_view = *socket_to_view->bsocket();
- bNode *viewer_bnode = active_viewer_node ? active_viewer_node->bnode() : nullptr;
- return link_socket_to_viewer(C, viewer_bnode, bnode_to_view, bsocket_to_view);
+ return link_socket_to_viewer(C, active_viewer_bnode, bnode_to_view, *bsocket_to_view);
}
/** \} */
@@ -954,6 +933,7 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur
if (nldrag->in_out == SOCK_OUT) {
bNode *tnode;
bNodeSocket *tsock = nullptr;
+ snode.edittree->ensure_topology_cache();
if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_IN)) {
for (bNodeLink *link : nldrag->links) {
/* skip if socket is on the same node as the fromsock */
@@ -980,19 +960,19 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur
continue;
}
if (link->tosock && link->tosock->flag & SOCK_MULTI_INPUT) {
- sort_multi_input_socket_links(snode, *tnode, link, &cursor);
+ sort_multi_input_socket_links_with_drag(*tnode, *link, cursor);
}
}
}
else {
for (bNodeLink *link : nldrag->links) {
- if (nldrag->last_node_hovered_while_dragging_a_link) {
- sort_multi_input_socket_links(
- snode, *nldrag->last_node_hovered_while_dragging_a_link, nullptr, &cursor);
- }
link->tonode = nullptr;
link->tosock = nullptr;
}
+ if (nldrag->last_node_hovered_while_dragging_a_link) {
+ update_multi_input_indices_for_removed_links(
+ *nldrag->last_node_hovered_while_dragging_a_link);
+ }
}
}
else {
@@ -1189,7 +1169,7 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
bool detach = RNA_boolean_get(op->ptr, "detach");
- int mval[2];
+ int2 mval;
WM_event_drag_start_mval(event, &region, mval);
float2 cursor;
@@ -1329,28 +1309,6 @@ void NODE_OT_link_make(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Node Link Intersect
- * \{ */
-
-static bool node_links_intersect(bNodeLink &link, const float mcoords[][2], int tot)
-{
- float coord_array[NODE_LINK_RESOL + 1][2];
-
- if (node_link_bezier_points(nullptr, nullptr, link, coord_array, NODE_LINK_RESOL)) {
- for (int i = 0; i < tot - 1; i++) {
- for (int b = 0; b < NODE_LINK_RESOL; b++) {
- if (isect_seg_seg_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0) {
- return true;
- }
- }
- }
- }
- return false;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Cut Link Operator
* \{ */
@@ -1358,56 +1316,63 @@ static int cut_links_exec(bContext *C, wmOperator *op)
{
Main &bmain = *CTX_data_main(C);
SpaceNode &snode = *CTX_wm_space_node(C);
- ARegion &region = *CTX_wm_region(C);
+ const ARegion &region = *CTX_wm_region(C);
- int i = 0;
- float mcoords[256][2];
+ Vector<float2> path;
RNA_BEGIN (op->ptr, itemptr, "path") {
- float loc[2];
-
- RNA_float_get_array(&itemptr, "loc", loc);
- UI_view2d_region_to_view(
- &region.v2d, (int)loc[0], (int)loc[1], &mcoords[i][0], &mcoords[i][1]);
- i++;
- if (i >= 256) {
+ float2 loc_region;
+ RNA_float_get_array(&itemptr, "loc", loc_region);
+ float2 loc_view;
+ UI_view2d_region_to_view(&region.v2d, loc_region.x, loc_region.y, &loc_view.x, &loc_view.y);
+ path.append(loc_view);
+ if (path.size() >= 256) {
break;
}
}
RNA_END;
- if (i > 1) {
- bool found = false;
+ if (path.is_empty()) {
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ }
- ED_preview_kill_jobs(CTX_wm_manager(C), &bmain);
+ bool found = false;
- LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &snode.edittree->links) {
- if (node_link_is_hidden_or_dimmed(region.v2d, *link)) {
- continue;
- }
+ ED_preview_kill_jobs(CTX_wm_manager(C), &bmain);
- if (node_links_intersect(*link, mcoords, i)) {
+ bNodeTree &node_tree = *snode.edittree;
- if (found == false) {
- /* TODO(sergey): Why did we kill jobs twice? */
- ED_preview_kill_jobs(CTX_wm_manager(C), &bmain);
- found = true;
- }
+ Set<bNode *> affected_nodes;
- bNode *to_node = link->tonode;
- nodeRemLink(snode.edittree, link);
- sort_multi_input_socket_links(snode, *to_node, nullptr, nullptr);
- }
+ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &node_tree.links) {
+ if (node_link_is_hidden_or_dimmed(region.v2d, *link)) {
+ continue;
}
- ED_node_tree_propagate_change(C, CTX_data_main(C), snode.edittree);
- if (found) {
- return OPERATOR_FINISHED;
+ if (link_path_intersection(*link, path)) {
+
+ if (!found) {
+ /* TODO(sergey): Why did we kill jobs twice? */
+ ED_preview_kill_jobs(CTX_wm_manager(C), &bmain);
+ found = true;
+ }
+
+ bNode *to_node = link->tonode;
+ nodeRemLink(snode.edittree, link);
+ affected_nodes.add(to_node);
}
+ }
- return OPERATOR_CANCELLED;
+ node_tree.ensure_topology_cache();
+ for (bNode *node : affected_nodes) {
+ update_multi_input_indices_for_removed_links(*node);
}
- return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ ED_node_tree_propagate_change(C, CTX_data_main(C), snode.edittree);
+ if (found) {
+ return OPERATOR_FINISHED;
+ }
+
+ return OPERATOR_CANCELLED;
}
void NODE_OT_links_cut(wmOperatorType *ot)
@@ -1441,69 +1406,99 @@ void NODE_OT_links_cut(wmOperatorType *ot)
/** \name Mute Links Operator
* \{ */
+static bool all_links_muted(const bNodeSocket &socket)
+{
+ for (const bNodeLink *link : socket.directly_linked_links()) {
+ if (!(link->flag & NODE_LINK_MUTED)) {
+ return false;
+ }
+ }
+ return true;
+}
+
static int mute_links_exec(bContext *C, wmOperator *op)
{
Main &bmain = *CTX_data_main(C);
SpaceNode &snode = *CTX_wm_space_node(C);
- ARegion &region = *CTX_wm_region(C);
+ const ARegion &region = *CTX_wm_region(C);
+ bNodeTree &ntree = *snode.edittree;
- int i = 0;
- float mcoords[256][2];
+ Vector<float2> path;
RNA_BEGIN (op->ptr, itemptr, "path") {
- float loc[2];
-
- RNA_float_get_array(&itemptr, "loc", loc);
- UI_view2d_region_to_view(
- &region.v2d, (int)loc[0], (int)loc[1], &mcoords[i][0], &mcoords[i][1]);
- i++;
- if (i >= 256) {
+ float2 loc_region;
+ RNA_float_get_array(&itemptr, "loc", loc_region);
+ float2 loc_view;
+ UI_view2d_region_to_view(&region.v2d, loc_region.x, loc_region.y, &loc_view.x, &loc_view.y);
+ path.append(loc_view);
+ if (path.size() >= 256) {
break;
}
}
RNA_END;
- if (i > 1) {
- ED_preview_kill_jobs(CTX_wm_manager(C), &bmain);
+ if (path.is_empty()) {
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ }
- /* Count intersected links and clear test flag. */
- int tot = 0;
- LISTBASE_FOREACH (bNodeLink *, link, &snode.edittree->links) {
- if (node_link_is_hidden_or_dimmed(region.v2d, *link)) {
- continue;
- }
- link->flag &= ~NODE_LINK_TEST;
- if (node_links_intersect(*link, mcoords, i)) {
- tot++;
- }
+ ED_preview_kill_jobs(CTX_wm_manager(C), &bmain);
+
+ ntree.ensure_topology_cache();
+
+ Set<bNodeLink *> affected_links;
+ LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) {
+ if (node_link_is_hidden_or_dimmed(region.v2d, *link)) {
+ continue;
}
- if (tot == 0) {
- return OPERATOR_CANCELLED;
+ if (!link_path_intersection(*link, path)) {
+ continue;
}
+ affected_links.add(link);
+ }
- /* Mute links. */
- LISTBASE_FOREACH (bNodeLink *, link, &snode.edittree->links) {
- if (node_link_is_hidden_or_dimmed(region.v2d, *link) || (link->flag & NODE_LINK_TEST)) {
- continue;
- }
+ if (affected_links.is_empty()) {
+ return OPERATOR_CANCELLED;
+ }
+
+ bke::node_tree_runtime::AllowUsingOutdatedInfo allow_outdated_info{ntree};
+
+ for (bNodeLink *link : affected_links) {
+ nodeLinkSetMute(&ntree, link, !(link->flag & NODE_LINK_MUTED));
+ const bool muted = link->flag & NODE_LINK_MUTED;
- if (node_links_intersect(*link, mcoords, i)) {
- nodeMuteLinkToggle(snode.edittree, link);
+ /* Propagate mute status downsteam past reroute nodes. */
+ if (link->tonode->is_reroute()) {
+ Stack<bNodeLink *> links;
+ links.push_multiple(link->tonode->output_sockets().first()->directly_linked_links());
+ while (!links.is_empty()) {
+ bNodeLink *link = links.pop();
+ nodeLinkSetMute(&ntree, link, muted);
+ if (!link->tonode->is_reroute()) {
+ continue;
+ }
+ links.push_multiple(link->tonode->output_sockets().first()->directly_linked_links());
}
}
-
- /* Clear remaining test flags. */
- LISTBASE_FOREACH (bNodeLink *, link, &snode.edittree->links) {
- if (node_link_is_hidden_or_dimmed(region.v2d, *link)) {
- continue;
+ /* Propagate mute status upstream past reroutes, but only if all outputs are muted. */
+ if (link->fromnode->is_reroute()) {
+ if (!muted || all_links_muted(*link->fromsock)) {
+ Stack<bNodeLink *> links;
+ links.push_multiple(link->fromnode->input_sockets().first()->directly_linked_links());
+ while (!links.is_empty()) {
+ bNodeLink *link = links.pop();
+ nodeLinkSetMute(&ntree, link, muted);
+ if (!link->fromnode->is_reroute()) {
+ continue;
+ }
+ if (!muted || all_links_muted(*link->fromsock)) {
+ links.push_multiple(link->fromnode->input_sockets().first()->directly_linked_links());
+ }
+ }
}
- link->flag &= ~NODE_LINK_TEST;
}
-
- ED_node_tree_propagate_change(C, CTX_data_main(C), snode.edittree);
- return OPERATOR_FINISHED;
}
- return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ ED_node_tree_propagate_change(C, CTX_data_main(C), &ntree);
+ return OPERATOR_FINISHED;
}
void NODE_OT_links_mute(wmOperatorType *ot)
@@ -1659,7 +1654,7 @@ static int node_join_exec(bContext *C, wmOperator *UNUSED(op))
SpaceNode &snode = *CTX_wm_space_node(C);
bNodeTree &ntree = *snode.edittree;
- /* XXX save selection: node_add_node call below sets the new frame as single
+ /* XXX save selection: add_static_node call below sets the new frame as single
* active+selected node */
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
if (node->flag & NODE_SELECT) {
@@ -1670,7 +1665,7 @@ static int node_join_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- bNode *frame = node_add_node(*C, nullptr, NODE_FRAME, 0.0f, 0.0f);
+ bNode *frame = add_static_node(*C, NODE_FRAME, float2(0));
/* reset tags */
LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
@@ -1719,11 +1714,11 @@ void NODE_OT_join(wmOperatorType *ot)
static bNode *node_find_frame_to_attach(ARegion &region,
const bNodeTree &ntree,
- const int mouse_xy[2])
+ const int2 mouse_xy)
{
/* convert mouse coordinates to v2d space */
- float cursor[2];
- UI_view2d_region_to_view(&region.v2d, UNPACK2(mouse_xy), &cursor[0], &cursor[1]);
+ float2 cursor;
+ UI_view2d_region_to_view(&region.v2d, mouse_xy.x, mouse_xy.y, &cursor.x, &cursor.y);
LISTBASE_FOREACH_BACKWARD (bNode *, frame, &ntree.nodes) {
/* skip selected, those are the nodes we want to attach */
@@ -1947,6 +1942,7 @@ static bool ed_node_link_conditions(ScrArea *area,
void ED_node_link_intersect_test(ScrArea *area, int test)
{
+ using namespace blender;
using namespace blender::ed::space_node;
bNode *select;
@@ -1970,36 +1966,34 @@ void ED_node_link_intersect_test(ScrArea *area, int test)
bNodeLink *selink = nullptr;
float dist_best = FLT_MAX;
LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) {
- float coord_array[NODE_LINK_RESOL + 1][2];
if (node_link_is_hidden_or_dimmed(region->v2d, *link)) {
continue;
}
- if (node_link_bezier_points(nullptr, nullptr, *link, coord_array, NODE_LINK_RESOL)) {
- float dist = FLT_MAX;
+ std::array<float2, NODE_LINK_RESOL + 1> coords;
+ node_link_bezier_points_evaluated(*link, coords);
+ float dist = FLT_MAX;
- /* loop over link coords to find shortest dist to
- * upper left node edge of a intersected line segment */
- for (int i = 0; i < NODE_LINK_RESOL; i++) {
- /* Check if the node rectangle intersects the line from this point to next one. */
- if (BLI_rctf_isect_segment(&select->totr, coord_array[i], coord_array[i + 1])) {
- /* store the shortest distance to the upper left edge
- * of all intersections found so far */
- const float node_xy[] = {select->totr.xmin, select->totr.ymax};
+ /* loop over link coords to find shortest dist to
+ * upper left node edge of a intersected line segment */
+ for (int i = 0; i < NODE_LINK_RESOL; i++) {
+ /* Check if the node rectangle intersects the line from this point to next one. */
+ if (BLI_rctf_isect_segment(&select->totr, coords[i], coords[i + 1])) {
+ /* store the shortest distance to the upper left edge
+ * of all intersections found so far */
+ const float node_xy[] = {select->totr.xmin, select->totr.ymax};
- /* to be precise coord_array should be clipped by select->totr,
- * but not done since there's no real noticeable difference */
- dist = min_ff(
- dist_squared_to_line_segment_v2(node_xy, coord_array[i], coord_array[i + 1]), dist);
- }
+ /* to be precise coords should be clipped by select->totr,
+ * but not done since there's no real noticeable difference */
+ dist = min_ff(dist_squared_to_line_segment_v2(node_xy, coords[i], coords[i + 1]), dist);
}
+ }
- /* we want the link with the shortest distance to node center */
- if (dist < dist_best) {
- dist_best = dist;
- selink = link;
- }
+ /* we want the link with the shortest distance to node center */
+ if (dist < dist_best) {
+ dist_best = dist;
+ selink = link;
}
}
@@ -2053,7 +2047,7 @@ static bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketIn
/* Try to get the main socket based on the socket declaration. */
nodeDeclarationEnsure(&ntree, &node);
- const nodes::NodeDeclaration *node_decl = node.runtime->declaration;
+ const nodes::NodeDeclaration *node_decl = node.declaration();
if (node_decl != nullptr) {
Span<nodes::SocketDeclarationPtr> socket_decls = (in_out == SOCK_IN) ? node_decl->inputs() :
node_decl->outputs();
diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc
index 9d73156edab..8cc3c80fdfd 100644
--- a/source/blender/editors/space_node/node_select.cc
+++ b/source/blender/editors/space_node/node_select.cc
@@ -48,7 +48,7 @@
namespace blender::ed::space_node {
-static bool is_event_over_node_or_socket(bContext *C, const wmEvent *event);
+static bool is_event_over_node_or_socket(const bContext &C, const wmEvent &event);
/**
* Function to detect if there is a visible view3d that uses workbench in texture mode.
@@ -100,17 +100,17 @@ rctf node_frame_rect_inside(const bNode &node)
return frame_inside;
}
-bool node_or_socket_isect_event(bContext *C, const wmEvent *event)
+bool node_or_socket_isect_event(const bContext &C, const wmEvent &event)
{
return is_event_over_node_or_socket(C, event);
}
-static bool node_frame_select_isect_mouse(bNode *node, const float2 &mouse)
+static bool node_frame_select_isect_mouse(const bNode &node, const float2 &mouse)
{
/* Frame nodes are selectable by their borders (including their whole rect - as for other nodes -
* would prevent e.g. box selection of nodes inside that frame). */
- const rctf frame_inside = node_frame_rect_inside(*node);
- if (BLI_rctf_isect_pt(&node->totr, mouse.x, mouse.y) &&
+ const rctf frame_inside = node_frame_rect_inside(node);
+ if (BLI_rctf_isect_pt(&node.totr, mouse.x, mouse.y) &&
!BLI_rctf_isect_pt(&frame_inside, mouse.x, mouse.y)) {
return true;
}
@@ -118,19 +118,18 @@ static bool node_frame_select_isect_mouse(bNode *node, const float2 &mouse)
return false;
}
-static bNode *node_under_mouse_select(bNodeTree &ntree, int mx, int my)
+static bNode *node_under_mouse_select(bNodeTree &ntree, const float2 mouse)
{
LISTBASE_FOREACH_BACKWARD (bNode *, node, &ntree.nodes) {
switch (node->type) {
case NODE_FRAME: {
- const float2 mouse{(float)mx, (float)my};
- if (node_frame_select_isect_mouse(node, mouse)) {
+ if (node_frame_select_isect_mouse(*node, mouse)) {
return node;
}
break;
}
default: {
- if (BLI_rctf_isect_pt(&node->totr, mx, my)) {
+ if (BLI_rctf_isect_pt(&node->totr, int(mouse.x), int(mouse.y))) {
return node;
}
break;
@@ -140,35 +139,32 @@ static bNode *node_under_mouse_select(bNodeTree &ntree, int mx, int my)
return nullptr;
}
-static bNode *node_under_mouse_tweak(bNodeTree &ntree, const float2 &mouse)
+static bool node_under_mouse_tweak(const bNodeTree &ntree, const float2 &mouse)
{
- using namespace blender::math;
-
- LISTBASE_FOREACH_BACKWARD (bNode *, node, &ntree.nodes) {
+ LISTBASE_FOREACH_BACKWARD (const bNode *, node, &ntree.nodes) {
switch (node->type) {
case NODE_REROUTE: {
- bNodeSocket *socket = (bNodeSocket *)node->inputs.first;
- const float2 location{socket->locx, socket->locy};
- if (distance(mouse, location) < 24.0f) {
- return node;
+ const float2 location = node_to_view(*node, {node->locx, node->locy});
+ if (math::distance(mouse, location) < 24.0f) {
+ return true;
}
break;
}
case NODE_FRAME: {
- if (node_frame_select_isect_mouse(node, mouse)) {
- return node;
+ if (node_frame_select_isect_mouse(*node, mouse)) {
+ return true;
}
break;
}
default: {
if (BLI_rctf_isect_pt(&node->totr, mouse.x, mouse.y)) {
- return node;
+ return true;
}
break;
}
}
}
- return nullptr;
+ return false;
}
static bool is_position_over_node_or_socket(SpaceNode &snode, const float2 &mouse)
@@ -187,17 +183,17 @@ static bool is_position_over_node_or_socket(SpaceNode &snode, const float2 &mous
return false;
}
-static bool is_event_over_node_or_socket(bContext *C, const wmEvent *event)
+static bool is_event_over_node_or_socket(const bContext &C, const wmEvent &event)
{
- SpaceNode *snode = CTX_wm_space_node(C);
- ARegion *region = CTX_wm_region(C);
- float2 mouse;
+ SpaceNode &snode = *CTX_wm_space_node(&C);
+ ARegion &region = *CTX_wm_region(&C);
- int mval[2];
- WM_event_drag_start_mval(event, region, mval);
+ int2 mval;
+ WM_event_drag_start_mval(&event, &region, mval);
- UI_view2d_region_to_view(&region->v2d, mval[0], mval[1], &mouse.x, &mouse.y);
- return is_position_over_node_or_socket(*snode, mouse);
+ float2 mouse;
+ UI_view2d_region_to_view(&region.v2d, mval.x, mval.y, &mouse.x, &mouse.y);
+ return is_position_over_node_or_socket(snode, mouse);
}
void node_socket_select(bNode *node, bNodeSocket &sock)
@@ -514,8 +510,8 @@ void node_select_single(bContext &C, bNode &node)
static bool node_mouse_select(bContext *C,
wmOperator *op,
- const int mval[2],
- struct SelectPick_Params *params)
+ const int2 mval,
+ SelectPick_Params *params)
{
Main &bmain = *CTX_data_main(C);
SpaceNode &snode = *CTX_wm_space_node(C);
@@ -526,7 +522,6 @@ static bool node_mouse_select(bContext *C,
bNode *node, *tnode;
bNodeSocket *sock = nullptr;
bNodeSocket *tsock;
- float cursor[2];
/* always do socket_select when extending selection. */
const bool socket_select = (params->sel_op == SEL_OP_XOR) ||
@@ -536,7 +531,8 @@ static bool node_mouse_select(bContext *C,
bool node_was_selected = false;
/* get mouse coordinates in view2d space */
- UI_view2d_region_to_view(&region.v2d, mval[0], mval[1], &cursor[0], &cursor[1]);
+ float2 cursor;
+ UI_view2d_region_to_view(&region.v2d, mval.x, mval.y, &cursor.x, &cursor.y);
/* first do socket selection, these generally overlap with nodes. */
if (socket_select) {
@@ -593,7 +589,7 @@ static bool node_mouse_select(bContext *C,
if (!sock) {
/* find the closest visible node */
- node = node_under_mouse_select(*snode.edittree, (int)cursor[0], (int)cursor[1]);
+ node = node_under_mouse_select(*snode.edittree, cursor);
found = (node != nullptr);
node_was_selected = node && (node->flag & SELECT);
@@ -667,10 +663,10 @@ static bool node_mouse_select(bContext *C,
static int node_select_exec(bContext *C, wmOperator *op)
{
/* get settings from RNA properties for operator */
- int mval[2];
+ int2 mval;
RNA_int_get_array(op->ptr, "location", mval);
- struct SelectPick_Params params = {};
+ SelectPick_Params params = {};
ED_select_pick_params_from_operator(op->ptr, &params);
/* perform the select */
@@ -787,7 +783,7 @@ static int node_box_select_invoke(bContext *C, wmOperator *op, const wmEvent *ev
{
const bool tweak = RNA_boolean_get(op->ptr, "tweak");
- if (tweak && is_event_over_node_or_socket(C, event)) {
+ if (tweak && is_event_over_node_or_socket(*C, *event)) {
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
@@ -836,7 +832,7 @@ static int node_circleselect_exec(bContext *C, wmOperator *op)
bNode *node;
int x, y, radius;
- float offset[2];
+ float2 offset;
float zoom = (float)(BLI_rcti_size_x(&region->winrct)) /
(float)(BLI_rctf_size_x(&region->v2d.cur));
@@ -854,7 +850,7 @@ static int node_circleselect_exec(bContext *C, wmOperator *op)
y = RNA_int_get(op->ptr, "y");
radius = RNA_int_get(op->ptr, "radius");
- UI_view2d_region_to_view(&region->v2d, x, y, &offset[0], &offset[1]);
+ UI_view2d_region_to_view(&region->v2d, x, y, &offset.x, &offset.y);
for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) {
switch (node->type) {
@@ -916,7 +912,7 @@ static int node_lasso_select_invoke(bContext *C, wmOperator *op, const wmEvent *
{
const bool tweak = RNA_boolean_get(op->ptr, "tweak");
- if (tweak && is_event_over_node_or_socket(C, event)) {
+ if (tweak && is_event_over_node_or_socket(*C, *event)) {
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
@@ -968,14 +964,14 @@ static bool do_lasso_select_node(bContext *C,
break;
}
default: {
- int screen_co[2];
- const float cent[2] = {BLI_rctf_cent_x(&node->totr), BLI_rctf_cent_y(&node->totr)};
+ int2 screen_co;
+ const float2 center = {BLI_rctf_cent_x(&node->totr), BLI_rctf_cent_y(&node->totr)};
/* marker in screen coords */
if (UI_view2d_view_to_region_clip(
- &region->v2d, cent[0], cent[1], &screen_co[0], &screen_co[1]) &&
- BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) &&
- BLI_lasso_is_point_inside(mcoords, mcoords_len, screen_co[0], screen_co[1], INT_MAX)) {
+ &region->v2d, center.x, center.y, &screen_co.x, &screen_co.y) &&
+ BLI_rcti_isect_pt(&rect, screen_co.x, screen_co.y) &&
+ BLI_lasso_is_point_inside(mcoords, mcoords_len, screen_co.x, screen_co.y, INT_MAX)) {
nodeSetSelected(node, select);
changed = true;
}
@@ -1298,7 +1294,7 @@ static void node_find_create_label(const bNode *node, char *str, int maxlen)
}
/* Generic search invoke. */
-static void node_find_update_fn(const struct bContext *C,
+static void node_find_update_fn(const bContext *C,
void *UNUSED(arg),
const char *str,
uiSearchItems *items,
@@ -1330,7 +1326,7 @@ static void node_find_update_fn(const struct bContext *C,
BLI_string_search_free(search);
}
-static void node_find_exec_fn(struct bContext *C, void *UNUSED(arg1), void *arg2)
+static void node_find_exec_fn(bContext *C, void *UNUSED(arg1), void *arg2)
{
SpaceNode *snode = CTX_wm_space_node(C);
bNode *active = (bNode *)arg2;
diff --git a/source/blender/editors/space_node/node_templates.cc b/source/blender/editors/space_node/node_templates.cc
index 58a313c328e..5fc194e02a4 100644
--- a/source/blender/editors/space_node/node_templates.cc
+++ b/source/blender/editors/space_node/node_templates.cc
@@ -758,43 +758,42 @@ namespace blender::ed::space_node {
/**************************** Node Tree Layout *******************************/
static void ui_node_draw_input(
- uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *input, int depth);
+ uiLayout &layout, bContext &C, bNodeTree &ntree, bNode &node, bNodeSocket &input, int depth);
static void ui_node_draw_node(
- uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, int depth)
+ uiLayout &layout, bContext &C, bNodeTree &ntree, bNode &node, int depth)
{
- bNodeSocket *input;
PointerRNA nodeptr;
- RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr);
+ RNA_pointer_create(&ntree.id, &RNA_Node, &node, &nodeptr);
- if (node->typeinfo->draw_buttons) {
- if (node->type != NODE_GROUP) {
- uiLayoutSetPropSep(layout, true);
- node->typeinfo->draw_buttons(layout, C, &nodeptr);
+ if (node.typeinfo->draw_buttons) {
+ if (node.type != NODE_GROUP) {
+ uiLayoutSetPropSep(&layout, true);
+ node.typeinfo->draw_buttons(&layout, &C, &nodeptr);
}
}
- for (input = (bNodeSocket *)node->inputs.first; input; input = input->next) {
- ui_node_draw_input(layout, C, ntree, node, input, depth + 1);
+ LISTBASE_FOREACH (bNodeSocket *, input, &node.inputs) {
+ ui_node_draw_input(layout, C, ntree, node, *input, depth + 1);
}
}
static void ui_node_draw_input(
- uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *input, int depth)
+ uiLayout &layout, bContext &C, bNodeTree &ntree, bNode &node, bNodeSocket &input, int depth)
{
PointerRNA inputptr, nodeptr;
- uiBlock *block = uiLayoutGetBlock(layout);
+ uiBlock *block = uiLayoutGetBlock(&layout);
uiLayout *row = nullptr;
bool dependency_loop;
- if (input->flag & SOCK_UNAVAIL) {
+ if (input.flag & SOCK_UNAVAIL) {
return;
}
/* to avoid eternal loops on cyclic dependencies */
- node->flag |= NODE_TEST;
- bNode *lnode = (input->link) ? input->link->fromnode : nullptr;
+ node.flag |= NODE_TEST;
+ bNode *lnode = (input.link) ? input.link->fromnode : nullptr;
dependency_loop = (lnode && (lnode->flag & NODE_TEST));
if (dependency_loop) {
@@ -802,10 +801,10 @@ static void ui_node_draw_input(
}
/* socket RNA pointer */
- RNA_pointer_create(&ntree->id, &RNA_NodeSocket, input, &inputptr);
- RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr);
+ RNA_pointer_create(&ntree.id, &RNA_NodeSocket, &input, &inputptr);
+ RNA_pointer_create(&ntree.id, &RNA_Node, &node, &nodeptr);
- row = uiLayoutRow(layout, true);
+ row = uiLayoutRow(&layout, true);
/* Decorations are added manually here. */
uiLayoutSetPropDecorate(row, false);
@@ -821,8 +820,8 @@ static void ui_node_draw_input(
if (lnode &&
(lnode->inputs.first || (lnode->typeinfo->draw_buttons && lnode->type != NODE_GROUP))) {
- int icon = (input->flag & SOCK_COLLAPSED) ? ICON_DISCLOSURE_TRI_RIGHT :
- ICON_DISCLOSURE_TRI_DOWN;
+ int icon = (input.flag & SOCK_COLLAPSED) ? ICON_DISCLOSURE_TRI_RIGHT :
+ ICON_DISCLOSURE_TRI_DOWN;
uiItemR(sub, &inputptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", icon);
}
@@ -831,7 +830,7 @@ static void ui_node_draw_input(
sub = uiLayoutRow(sub, true);
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
- uiItemL(sub, IFACE_(input->name), ICON_NONE);
+ uiItemL(sub, IFACE_(input.name), ICON_NONE);
}
if (dependency_loop) {
@@ -840,28 +839,28 @@ static void ui_node_draw_input(
}
else if (lnode) {
/* input linked to a node */
- uiTemplateNodeLink(row, C, ntree, node, input);
+ uiTemplateNodeLink(row, &C, &ntree, &node, &input);
add_dummy_decorator = true;
- if (depth == 0 || !(input->flag & SOCK_COLLAPSED)) {
+ if (depth == 0 || !(input.flag & SOCK_COLLAPSED)) {
if (depth == 0) {
- uiItemS(layout);
+ uiItemS(&layout);
}
- ui_node_draw_node(layout, C, ntree, lnode, depth);
+ ui_node_draw_node(layout, C, ntree, *lnode, depth);
}
}
else {
uiLayout *sub = uiLayoutRow(row, true);
- uiTemplateNodeLink(sub, C, ntree, node, input);
+ uiTemplateNodeLink(sub, &C, &ntree, &node, &input);
- if (input->flag & SOCK_HIDE_VALUE) {
+ if (input.flag & SOCK_HIDE_VALUE) {
add_dummy_decorator = true;
}
/* input not linked, show value */
else {
- switch (input->type) {
+ switch (input.type) {
case SOCK_VECTOR:
uiItemS(sub);
sub = uiLayoutColumn(sub, true);
@@ -876,11 +875,11 @@ static void ui_node_draw_input(
break;
case SOCK_STRING: {
const bNodeTree *node_tree = (const bNodeTree *)nodeptr.owner_id;
- SpaceNode *snode = CTX_wm_space_node(C);
+ SpaceNode *snode = CTX_wm_space_node(&C);
if (node_tree->type == NTREE_GEOMETRY && snode != nullptr) {
/* Only add the attribute search in the node editor, in other places there is not
* enough context. */
- node_geometry_add_attribute_search_button(*C, *node, inputptr, *sub);
+ node_geometry_add_attribute_search_button(C, node, inputptr, *sub);
}
else {
uiItemR(sub, &inputptr, "default_value", 0, "", ICON_NONE);
@@ -899,10 +898,10 @@ static void ui_node_draw_input(
uiItemDecoratorR(split_wrapper.decorate_column, nullptr, nullptr, 0);
}
- node_socket_add_tooltip(ntree, node, input, row);
+ node_socket_add_tooltip(ntree, node, input, *row);
/* clear */
- node->flag &= ~NODE_TEST;
+ node.flag &= ~NODE_TEST;
}
} // namespace blender::ed::space_node
@@ -924,9 +923,9 @@ void uiTemplateNodeView(
}
if (input) {
- ui_node_draw_input(layout, C, ntree, node, input, 0);
+ ui_node_draw_input(*layout, *C, *ntree, *node, *input, 0);
}
else {
- ui_node_draw_node(layout, C, ntree, node, 0);
+ ui_node_draw_node(*layout, *C, *ntree, *node, 0);
}
}
diff --git a/source/blender/editors/space_node/node_view.cc b/source/blender/editors/space_node/node_view.cc
index 6f30632244b..00756083580 100644
--- a/source/blender/editors/space_node/node_view.cc
+++ b/source/blender/editors/space_node/node_view.cc
@@ -177,7 +177,7 @@ void NODE_OT_view_selected(wmOperatorType *ot)
* \{ */
struct NodeViewMove {
- int mvalo[2];
+ int2 mvalo;
int xmin, ymin, xmax, ymax;
/** Original Offset for cancel. */
float xof_orig, yof_orig;
@@ -192,10 +192,10 @@ static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, const wmEvent *e
switch (event->type) {
case MOUSEMOVE:
- snode->xof -= (nvm->mvalo[0] - event->mval[0]);
- snode->yof -= (nvm->mvalo[1] - event->mval[1]);
- nvm->mvalo[0] = event->mval[0];
- nvm->mvalo[1] = event->mval[1];
+ snode->xof -= (nvm->mvalo.x - event->mval[0]);
+ snode->yof -= (nvm->mvalo.y - event->mval[1]);
+ nvm->mvalo.x = event->mval[0];
+ nvm->mvalo.y = event->mval[1];
/* prevent dragging image outside of the window and losing it! */
CLAMP(snode->xof, nvm->xmin, nvm->xmax);
@@ -252,10 +252,10 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *
return OPERATOR_CANCELLED;
}
- nvm = MEM_cnew<NodeViewMove>("NodeViewMove struct");
+ nvm = MEM_cnew<NodeViewMove>(__func__);
op->customdata = nvm;
- nvm->mvalo[0] = event->mval[0];
- nvm->mvalo[1] = event->mval[1];
+ nvm->mvalo.x = event->mval[0];
+ nvm->mvalo.y = event->mval[1];
nvm->xmin = -(region->winx / 2) - (ibuf->x * (0.5f * snode->zoom)) + pad;
nvm->xmax = (region->winx / 2) + (ibuf->x * (0.5f * snode->zoom)) - pad;
@@ -447,7 +447,7 @@ static void sample_draw(const bContext *C, ARegion *region, void *arg_info)
} // namespace blender::ed::space_node
bool ED_space_node_get_position(
- Main *bmain, SpaceNode *snode, struct ARegion *region, const int mval[2], float fpos[2])
+ Main *bmain, SpaceNode *snode, ARegion *region, const int mval[2], float fpos[2])
{
if (!ED_node_is_compositor(snode) || (snode->flag & SNODE_BACKDRAW) == 0) {
return false;
@@ -645,7 +645,7 @@ static int sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* Don't handle events intended for nodes (which rely on click/drag distinction).
* which this operator would use since sampling is normally activated on press, see: T98191. */
- if (node_or_socket_isect_event(C, event)) {
+ if (node_or_socket_isect_event(*C, *event)) {
return OPERATOR_PASS_THROUGH;
}
diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc
index 15afd024766..17fc02e98a8 100644
--- a/source/blender/editors/space_node/space_node.cc
+++ b/source/blender/editors/space_node/space_node.cc
@@ -302,7 +302,7 @@ static void node_free(SpaceLink *sl)
}
/* spacetype; init callback */
-static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *area)
+static void node_init(wmWindowManager *UNUSED(wm), ScrArea *area)
{
SpaceNode *snode = (SpaceNode *)area->spacedata.first;
@@ -362,7 +362,7 @@ static void node_area_tag_tree_recalc(SpaceNode *snode, ScrArea *area)
static void node_area_listener(const wmSpaceTypeListenerParams *params)
{
ScrArea *area = params->area;
- wmNotifier *wmn = params->notifier;
+ const wmNotifier *wmn = params->notifier;
/* NOTE: #ED_area_tag_refresh will re-execute compositor. */
SpaceNode *snode = (SpaceNode *)area->spacedata.first;
@@ -511,7 +511,7 @@ static void node_area_listener(const wmSpaceTypeListenerParams *params)
}
}
-static void node_area_refresh(const struct bContext *C, ScrArea *area)
+static void node_area_refresh(const bContext *C, ScrArea *area)
{
/* default now: refresh node is starting preview */
SpaceNode *snode = (SpaceNode *)area->spacedata.first;
@@ -526,7 +526,7 @@ static void node_area_refresh(const struct bContext *C, ScrArea *area)
if (snode->runtime->recalc_auto_compositing) {
snode->runtime->recalc_auto_compositing = false;
snode->runtime->recalc_regular_compositing = false;
- node_render_changed_exec((struct bContext *)C, nullptr);
+ node_render_changed_exec((bContext *)C, nullptr);
}
else if (snode->runtime->recalc_regular_compositing) {
snode->runtime->recalc_regular_compositing = false;
@@ -753,7 +753,7 @@ static void node_header_region_draw(const bContext *C, ARegion *region)
static void node_region_listener(const wmRegionListenerParams *params)
{
ARegion *region = params->region;
- wmNotifier *wmn = params->notifier;
+ const wmNotifier *wmn = params->notifier;
wmGizmoMap *gzmap = region->gizmo_map;
/* context changes */
@@ -973,9 +973,7 @@ static void node_id_remap_cb(ID *old_id, ID *new_id, void *user_data)
}
}
-static void node_id_remap(ScrArea *UNUSED(area),
- SpaceLink *slink,
- const struct IDRemapper *mappings)
+static void node_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, const IDRemapper *mappings)
{
/* Although we should be able to perform all the mappings in a single go this lead to issues when
* running the python test cases. Somehow the nodetree/edittree weren't updated to the new