Nodes: Support for socket shapes other than circle

Previously there was already "draw_shape" property,
but it was doing nothing. This commit renames the
property to "display_shape". Furthermore, different
shapes like SQUARE and DIAMOND are supported now.

Currently, the shapes are drawn using the shader that also
draws keyframes. In the future we might want to separate
this.

The new shapes are not used anywhere yet, but they can
be used by addon developers and will probably be useful
when we want to support different kinds node systems later.
For example, different shapes can be used to distinguish
between data and control flow.

Differential Revision: https://developer.blender.org/D2829
This commit is contained in:
Charlie Jolly 2019-08-22 11:10:11 +02:00 committed by Jacques Lucke
parent 0356c8f25b
commit 2ba233a31f
Notes: blender-bot 2023-02-14 06:45:14 +01:00
Referenced by issue #69127, Node sockets location bug after a keyframe is inserted
8 changed files with 146 additions and 47 deletions

View File

@ -814,8 +814,10 @@ static void draw_keylist(View2D *v2d,
uint outline_color_id = GPU_vertformat_attr_add(
format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
GPU_program_point_size(true);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
immUniform1f("outline_scale", 1.0f);
immUniform2f(
"ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1);
immBegin(GPU_PRIM_POINTS, key_len);

View File

@ -317,8 +317,9 @@ static void vicon_keytype_draw_wrapper(
format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
GPU_program_point_size(true);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
immUniform1f("outline_scale", 1.0f);
immUniform2f("ViewportSize", -1.0f, -1.0f);
immBegin(GPU_PRIM_POINTS, 1);

View File

@ -222,8 +222,9 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene)
format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
GPU_program_point_size(true);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
immUniform1f("outline_scale", 1.0f);
immUniform2f(
"ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1);
immBegin(GPU_PRIM_POINTS, keyframe_len);

View File

@ -141,8 +141,10 @@ static void nla_action_draw_keyframes(
uint outline_color_id = GPU_vertformat_attr_add(
format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
GPU_program_point_size(true);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
immUniform1f("outline_scale", 1.0f);
immUniform2f("ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1);
immBegin(GPU_PRIM_POINTS, key_len);

View File

@ -713,15 +713,28 @@ static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node)
GPU_blend(false);
}
static void node_socket_circle_draw(const bContext *C,
bNodeTree *ntree,
PointerRNA node_ptr,
bNodeSocket *sock,
unsigned pos,
unsigned col)
/* flags used in gpu_shader_keyframe_diamond_frag.glsl */
#define MARKER_SHAPE_DIAMOND 0x1
#define MARKER_SHAPE_SQUARE 0xC
#define MARKER_SHAPE_CIRCLE 0x2
#define MARKER_SHAPE_INNER_DOT 0x10
static void node_socket_draw(const bContext *C,
bNodeTree *ntree,
PointerRNA node_ptr,
bNodeSocket *sock,
unsigned pos_id,
unsigned col_id,
unsigned shape_id,
unsigned size_id,
unsigned outline_col_id,
float size,
bool selected)
{
PointerRNA ptr;
float color[4];
float outline_color[4];
unsigned int flags = 0;
RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
sock->typeinfo->draw_color((bContext *)C, &ptr, &node_ptr, color);
@ -731,8 +744,44 @@ static void node_socket_circle_draw(const bContext *C,
color[3] *= 0.25f;
}
immAttr4fv(col, color);
immVertex2f(pos, sock->locx, sock->locy);
if (selected) {
UI_GetThemeColor4fv(TH_TEXT_HI, outline_color);
outline_color[3] = 0.9f;
}
else {
copy_v4_fl(outline_color, 0.0f);
outline_color[3] = 0.6f;
}
/* sets shape flags */
switch (sock->display_shape) {
case SOCK_DISPLAY_SHAPE_DIAMOND:
case SOCK_DISPLAY_SHAPE_DIAMOND_DOT:
flags = MARKER_SHAPE_DIAMOND;
break;
case SOCK_DISPLAY_SHAPE_SQUARE:
case SOCK_DISPLAY_SHAPE_SQUARE_DOT:
flags = MARKER_SHAPE_SQUARE;
break;
default:
case SOCK_DISPLAY_SHAPE_CIRCLE:
case SOCK_DISPLAY_SHAPE_CIRCLE_DOT:
flags = MARKER_SHAPE_CIRCLE;
break;
}
if (ELEM(sock->display_shape,
SOCK_DISPLAY_SHAPE_DIAMOND_DOT,
SOCK_DISPLAY_SHAPE_SQUARE_DOT,
SOCK_DISPLAY_SHAPE_CIRCLE_DOT)) {
flags |= MARKER_SHAPE_INNER_DOT;
}
immAttr4fv(col_id, color);
immAttr1u(shape_id, flags);
immAttr1f(size_id, size);
immAttr4fv(outline_col_id, outline_color);
immVertex2f(pos_id, sock->locx, sock->locy);
}
/* ************** Socket callbacks *********** */
@ -888,26 +937,26 @@ void node_draw_sockets(View2D *v2d,
PointerRNA node_ptr;
RNA_pointer_create((ID *)ntree, &RNA_Node, node, &node_ptr);
float scale;
UI_view2d_scale_get(v2d, &scale, NULL);
bool selected = false;
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint col_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
uint shape_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT);
uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
uint outline_col_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
GPU_blend(true);
GPU_program_point_size(true);
immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_VARYING_COLOR_OUTLINE_AA);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
immUniform1f("outline_scale", 0.7f);
/* set handle size */
immUniform1f("size", 2.0f * NODE_SOCKSIZE * scale); /* 2 * size to have diameter */
float scale;
UI_view2d_scale_get(v2d, &scale, NULL);
scale *= 2.25f * NODE_SOCKSIZE;
if (!select_all) {
/* outline for unselected sockets */
immUniform1f("outlineWidth", 1.0f);
immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 0.6f);
immBeginAtMost(GPU_PRIM_POINTS, total_input_len + total_output_len);
}
@ -923,7 +972,17 @@ void node_draw_sockets(View2D *v2d,
continue;
}
node_socket_circle_draw(C, ntree, node_ptr, sock, pos, col);
node_socket_draw(C,
ntree,
node_ptr,
sock,
pos_id,
col_id,
shape_id,
size_id,
outline_col_id,
scale,
selected);
}
/* socket outputs */
@ -938,7 +997,17 @@ void node_draw_sockets(View2D *v2d,
continue;
}
node_socket_circle_draw(C, ntree, node_ptr, sock, pos, col);
node_socket_draw(C,
ntree,
node_ptr,
sock,
pos_id,
col_id,
shape_id,
size_id,
outline_col_id,
scale,
selected);
}
}
@ -949,10 +1018,8 @@ void node_draw_sockets(View2D *v2d,
/* go back and draw selected sockets */
if (selected_input_len + selected_output_len > 0) {
/* outline for selected sockets */
float c[3];
UI_GetThemeColor3fv(TH_TEXT_HI, c);
immUniform4f("outlineColor", c[0], c[1], c[2], 1.0f);
immUniform1f("outlineWidth", 1.5f);
selected = true;
immBegin(GPU_PRIM_POINTS, selected_input_len + selected_output_len);
@ -963,7 +1030,17 @@ void node_draw_sockets(View2D *v2d,
continue;
}
if (select_all || (sock->flag & SELECT)) {
node_socket_circle_draw(C, ntree, node_ptr, sock, pos, col);
node_socket_draw(C,
ntree,
node_ptr,
sock,
pos_id,
col_id,
shape_id,
size_id,
outline_col_id,
scale,
selected);
if (--selected_input_len == 0) {
break; /* stop as soon as last one is drawn */
}
@ -978,7 +1055,17 @@ void node_draw_sockets(View2D *v2d,
continue;
}
if (select_all || (sock->flag & SELECT)) {
node_socket_circle_draw(C, ntree, node_ptr, sock, pos, col);
node_socket_draw(C,
ntree,
node_ptr,
sock,
pos_id,
col_id,
shape_id,
size_id,
outline_col_id,
scale,
selected);
if (--selected_output_len == 0) {
break; /* stop as soon as last one is drawn */
}

View File

@ -1,11 +1,11 @@
uniform mat4 ModelViewProjectionMatrix;
uniform vec2 ViewportSize = vec2(-1, -1);
uniform float outline_scale = 1.0;
const float line_falloff = 1.0;
const float circle_scale = sqrt(2.0 / 3.1416);
const float square_scale = sqrt(0.5);
const float diagonal_scale = sqrt(0.5);
in vec2 pos;
@ -58,7 +58,7 @@ void main()
float line_width = half_width + line_falloff;
/* Outline thresholds. */
thresholds.xy = line_thresholds(line_width);
thresholds.xy = line_thresholds(line_width * outline_scale);
/* Inner dot thresholds. */
thresholds.zw = line_thresholds(line_width * 1.6);

View File

@ -113,7 +113,7 @@ typedef struct bNodeSocket {
short stack_index;
/* XXX deprecated, kept for forward compatibility */
short stack_type DNA_DEPRECATED;
char draw_shape;
char display_shape;
char _pad[3];
/** Cached data from execution. */
@ -153,11 +153,14 @@ typedef enum eNodeSocketDatatype {
} eNodeSocketDatatype;
/* socket shape */
typedef enum eNodeSocketDrawShape {
SOCK_DRAW_SHAPE_CIRCLE = 0,
SOCK_DRAW_SHAPE_SQUARE = 1,
SOCK_DRAW_SHAPE_DIAMOND = 2,
} eNodeSocketDrawShape;
typedef enum eNodeSocketDisplayShape {
SOCK_DISPLAY_SHAPE_CIRCLE = 0,
SOCK_DISPLAY_SHAPE_SQUARE = 1,
SOCK_DISPLAY_SHAPE_DIAMOND = 2,
SOCK_DISPLAY_SHAPE_CIRCLE_DOT = 3,
SOCK_DISPLAY_SHAPE_SQUARE_DOT = 4,
SOCK_DISPLAY_SHAPE_DIAMOND_DOT = 5,
} eNodeSocketDisplayShape;
/* socket side (input/output) */
typedef enum eNodeSocketInOut {

View File

@ -63,10 +63,13 @@ const EnumPropertyItem rna_enum_node_socket_in_out_items[] = {
{SOCK_IN, "IN", 0, "Input", ""}, {SOCK_OUT, "OUT", 0, "Output", ""}, {0, NULL, 0, NULL, NULL}};
#ifndef RNA_RUNTIME
static const EnumPropertyItem rna_enum_node_socket_draw_shape_items[] = {
{SOCK_DRAW_SHAPE_CIRCLE, "CIRCLE", 0, "Circle", ""},
{SOCK_DRAW_SHAPE_SQUARE, "SQUARE", 0, "Square", ""},
{SOCK_DRAW_SHAPE_DIAMOND, "DIAMOND", 0, "Diamond", ""},
static const EnumPropertyItem rna_enum_node_socket_display_shape_items[] = {
{SOCK_DISPLAY_SHAPE_CIRCLE, "CIRCLE", 0, "Circle", ""},
{SOCK_DISPLAY_SHAPE_SQUARE, "SQUARE", 0, "Square", ""},
{SOCK_DISPLAY_SHAPE_DIAMOND, "DIAMOND", 0, "Diamond", ""},
{SOCK_DISPLAY_SHAPE_CIRCLE_DOT, "CIRCLE_DOT", 0, "Circle with inner dot", ""},
{SOCK_DISPLAY_SHAPE_SQUARE_DOT, "SQUARE_DOT", 0, "Square with inner dot", ""},
{SOCK_DISPLAY_SHAPE_DIAMOND_DOT, "DIAMOND_DOT", 0, "Diamond with inner dot", ""},
{0, NULL, 0, NULL, NULL}};
static const EnumPropertyItem node_socket_type_items[] = {
@ -7858,10 +7861,10 @@ static void rna_def_node_socket(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Type", "Data type");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");
prop = RNA_def_property(srna, "draw_shape", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "draw_shape");
RNA_def_property_enum_items(prop, rna_enum_node_socket_draw_shape_items);
RNA_def_property_enum_default(prop, SOCK_DRAW_SHAPE_CIRCLE);
prop = RNA_def_property(srna, "display_shape", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "display_shape");
RNA_def_property_enum_items(prop, rna_enum_node_socket_display_shape_items);
RNA_def_property_enum_default(prop, SOCK_DISPLAY_SHAPE_CIRCLE);
RNA_def_property_ui_text(prop, "Shape", "Socket shape");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocket_update");