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:
authorHans Goudey <h.goudey@me.com>2021-12-06 00:45:41 +0300
committerHans Goudey <h.goudey@me.com>2021-12-06 00:45:41 +0300
commit338c1060d5d7b6a8bd3ec5632f543738de4c103c (patch)
treeb8ca72de9e4381dca31f681e604c2469e3a5a74e
parent0578921063fbb081239439062215f2538a31af4b (diff)
Cleanup: Remove unnecessary node type callbacks for drawing
Currently there are a few callbacks on `bNodeType` that do the same thing for every node type except reroutes and frame nodes. Having a callback for basic things complicates code and makes it harder to understand, and reroutes and frames are special cases in larger way. Arguably frame nodes shouldn't even be drawn like regular nodes, given that it adds a case of O(N^2) looping through all nodes. "Unrolling" the callbacks makes it easier to see what's happening, and therefore easier to optimize. Differential Revision: https://developer.blender.org/D13463
-rw-r--r--source/blender/blenkernel/BKE_node.h21
-rw-r--r--source/blender/editors/space_node/drawnode.cc171
-rw-r--r--source/blender/editors/space_node/node_draw.cc120
-rw-r--r--source/blender/editors/space_node/node_edit.cc2
-rw-r--r--source/blender/editors/space_node/node_intern.hh12
-rw-r--r--source/blender/editors/space_node/node_select.cc15
6 files changed, 141 insertions, 200 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 85699e4c28d..0584a8c811f 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -25,7 +25,6 @@
#include "BLI_compiler_compat.h"
#include "BLI_ghash.h"
-#include "BLI_utildefines.h"
#include "DNA_listBase.h"
@@ -223,16 +222,6 @@ typedef int (*NodeGPUExecFunction)(struct GPUMaterial *mat,
struct GPUNodeStack *in,
struct GPUNodeStack *out);
-typedef enum NodeResizeDirection {
- NODE_RESIZE_NONE = 0,
- NODE_RESIZE_TOP = (1 << 0),
- NODE_RESIZE_BOTTOM = (1 << 1),
- NODE_RESIZE_RIGHT = (1 << 2),
- NODE_RESIZE_LEFT = (1 << 3),
-} NodeResizeDirection;
-
-ENUM_OPERATORS(NodeResizeDirection, NODE_RESIZE_LEFT);
-
/**
* \brief Defines a node type.
*
@@ -265,10 +254,6 @@ typedef struct bNodeType {
struct bNodeTree *ntree,
struct bNode *node,
bNodeInstanceKey key);
- /* Updates the node geometry attributes according to internal state before actual drawing */
- void (*draw_nodetype_prepare)(const struct bContext *C,
- struct bNodeTree *ntree,
- struct bNode *node);
/* Draw the option buttons on the node */
void (*draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr);
@@ -284,12 +269,6 @@ typedef struct bNodeType {
* \note Used as a fallback when #bNode.label isn't set.
*/
void (*labelfunc)(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen);
- /** Optional custom resize handle polling. */
- NodeResizeDirection (*resize_area_func)(const struct bNode *node, int x, int y);
- /** Optional selection area polling. */
- int (*select_area_func)(struct bNode *node, int x, int y);
- /** Optional tweak area polling (for grabbing). */
- int (*tweak_area_func)(struct bNode *node, int x, int y);
/** Called when the node is updated in the editor. */
void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node);
diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc
index cdce876f57a..b031067ab14 100644
--- a/source/blender/editors/space_node/drawnode.cc
+++ b/source/blender/editors/space_node/drawnode.cc
@@ -250,11 +250,39 @@ static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *pt
uiItemR(layout, ptr, "use_clamp", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
-static NodeResizeDirection node_resize_area_default(const bNode *node, const int x, const int y)
+NodeResizeDirection node_get_resize_direction(const bNode *node, const int x, const int y)
{
+ if (node->type == NODE_FRAME) {
+ const float size = 10.0f;
+ NodeFrame *data = (NodeFrame *)node->storage;
+
+ /* shrinking frame size is determined by child nodes */
+ if (!(data->flag & NODE_FRAME_RESIZEABLE)) {
+ return NODE_RESIZE_NONE;
+ }
+
+ NodeResizeDirection dir = NODE_RESIZE_NONE;
+
+ const rctf &totr = node->totr;
+ if (x >= totr.xmax - size && x < totr.xmax && y >= totr.ymin && y < totr.ymax) {
+ dir |= NODE_RESIZE_RIGHT;
+ }
+ if (x >= totr.xmin && x < totr.xmin + size && y >= totr.ymin && y < totr.ymax) {
+ dir |= NODE_RESIZE_LEFT;
+ }
+ if (x >= totr.xmin && x < totr.xmax && y >= totr.ymax - size && y < totr.ymax) {
+ dir |= NODE_RESIZE_TOP;
+ }
+ if (x >= totr.xmin && x < totr.xmax && y >= totr.ymin && y < totr.ymin + size) {
+ dir |= NODE_RESIZE_BOTTOM;
+ }
+
+ return dir;
+ }
+
if (node->flag & NODE_HIDDEN) {
- rctf totr = node->totr;
/* right part of node */
+ rctf totr = node->totr;
totr.xmin = node->totr.xmax - 1.0f * U.widget_unit;
if (BLI_rctf_isect_pt(&totr, x, y)) {
return NODE_RESIZE_RIGHT;
@@ -284,59 +312,6 @@ static void node_draw_buttons_group(uiLayout *layout, bContext *C, PointerRNA *p
layout, C, ptr, "node_tree", nullptr, nullptr, nullptr, UI_TEMPLATE_ID_FILTER_ALL, nullptr);
}
-/* XXX Does a bounding box update by iterating over all children.
- * Not ideal to do this in every draw call, but doing as transform callback doesn't work,
- * since the child node totr rects are not updated properly at that point.
- */
-static void node_draw_frame_prepare(const bContext *UNUSED(C), bNodeTree *ntree, bNode *node)
-{
- const float margin = 1.5f * U.widget_unit;
- NodeFrame *data = (NodeFrame *)node->storage;
-
- /* init rect from current frame size */
- rctf rect;
- node_to_view(*node, node->offsetx, node->offsety, &rect.xmin, &rect.ymax);
- node_to_view(
- *node, node->offsetx + node->width, node->offsety - node->height, &rect.xmax, &rect.ymin);
-
- /* frame can be resized manually only if shrinking is disabled or no children are attached */
- data->flag |= NODE_FRAME_RESIZEABLE;
- /* for shrinking bbox, initialize the rect from first child node */
- bool bbinit = (data->flag & NODE_FRAME_SHRINK);
- /* fit bounding box to all children */
- LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) {
- if (tnode->parent != node) {
- continue;
- }
-
- /* add margin to node rect */
- rctf noderect = tnode->totr;
- noderect.xmin -= margin;
- noderect.xmax += margin;
- noderect.ymin -= margin;
- noderect.ymax += margin;
-
- /* first child initializes frame */
- if (bbinit) {
- bbinit = false;
- rect = noderect;
- data->flag &= ~NODE_FRAME_RESIZEABLE;
- }
- else {
- BLI_rctf_union(&rect, &noderect);
- }
- }
-
- /* now adjust the frame size from view-space bounding box */
- node_from_view(*node, rect.xmin, rect.ymax, &node->offsetx, &node->offsety);
- float xmax, ymax;
- node_from_view(*node, rect.xmax, rect.ymin, &xmax, &ymax);
- node->width = xmax - node->offsetx;
- node->height = -ymax + node->offsety;
-
- node->totr = rect;
-}
-
static void node_draw_frame_label(bNodeTree &ntree, bNode &node, SpaceNode &snode)
{
const float aspect = snode.runtime->aspect;
@@ -478,35 +453,6 @@ static void node_draw_frame(const bContext *C,
node->block = nullptr;
}
-static NodeResizeDirection node_resize_area_frame(const bNode *node, const int x, const int y)
-{
- const float size = 10.0f;
- NodeFrame *data = (NodeFrame *)node->storage;
- rctf totr = node->totr;
-
- /* shrinking frame size is determined by child nodes */
- if (!(data->flag & NODE_FRAME_RESIZEABLE)) {
- return NODE_RESIZE_NONE;
- }
-
- NodeResizeDirection dir = NODE_RESIZE_NONE;
-
- if (x >= totr.xmax - size && x < totr.xmax && y >= totr.ymin && y < totr.ymax) {
- dir |= NODE_RESIZE_RIGHT;
- }
- if (x >= totr.xmin && x < totr.xmin + size && y >= totr.ymin && y < totr.ymax) {
- dir |= NODE_RESIZE_LEFT;
- }
- if (x >= totr.xmin && x < totr.xmax && y >= totr.ymax - size && y < totr.ymax) {
- dir |= NODE_RESIZE_TOP;
- }
- if (x >= totr.xmin && x < totr.xmax && y >= totr.ymin && y < totr.ymin + size) {
- dir |= NODE_RESIZE_BOTTOM;
- }
-
- return dir;
-}
-
static void node_buts_frame_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "label_size", DEFAULT_FLAGS, IFACE_("Label Size"), ICON_NONE);
@@ -514,33 +460,6 @@ static void node_buts_frame_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA
uiItemR(layout, ptr, "text", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
-#define NODE_REROUTE_SIZE 8.0f
-
-static void node_draw_reroute_prepare(const bContext *UNUSED(C),
- bNodeTree *UNUSED(ntree),
- bNode *node)
-{
- /* get "global" coords */
- float locx, locy;
- node_to_view(*node, 0.0f, 0.0f, &locx, &locy);
-
- /* reroute node has exactly one input and one output, both in the same place */
- bNodeSocket *nsock = (bNodeSocket *)node->outputs.first;
- nsock->locx = locx;
- nsock->locy = locy;
-
- nsock = (bNodeSocket *)node->inputs.first;
- nsock->locx = locx;
- nsock->locy = locy;
-
- const float size = NODE_REROUTE_SIZE;
- node->width = size * 2;
- node->totr.xmin = locx - size;
- node->totr.xmax = locx + size;
- node->totr.ymax = locy + size;
- node->totr.ymin = locy - size;
-}
-
static void node_draw_reroute(const bContext *C,
ARegion *region,
SpaceNode *UNUSED(snode),
@@ -588,20 +507,6 @@ static void node_draw_reroute(const bContext *C,
node->block = nullptr;
}
-/* Special tweak area for reroute node.
- * Since this node is quite small, we use a larger tweak area for grabbing than for selection.
- */
-static int node_tweak_area_reroute(bNode *node, int x, int y)
-{
- /* square of tweak radius */
- const float tweak_radius_sq = square_f(24.0f);
-
- bNodeSocket *sock = (bNodeSocket *)node->inputs.first;
- float dx = sock->locx - x;
- float dy = sock->locy - y;
- return (dx * dx + dy * dy <= tweak_radius_sq);
-}
-
static void node_common_set_butfunc(bNodeType *ntype)
{
switch (ntype->type) {
@@ -610,14 +515,10 @@ static void node_common_set_butfunc(bNodeType *ntype)
break;
case NODE_FRAME:
ntype->draw_nodetype = node_draw_frame;
- ntype->draw_nodetype_prepare = node_draw_frame_prepare;
ntype->draw_buttons_ex = node_buts_frame_ex;
- ntype->resize_area_func = node_resize_area_frame;
break;
case NODE_REROUTE:
ntype->draw_nodetype = node_draw_reroute;
- ntype->draw_nodetype_prepare = node_draw_reroute_prepare;
- ntype->tweak_area_func = node_tweak_area_reroute;
break;
}
}
@@ -3373,12 +3274,8 @@ void ED_node_init_butfuncs(void)
/* default ui functions */
NodeTypeUndefined.draw_nodetype = node_draw_default;
- NodeTypeUndefined.draw_nodetype_prepare = node_update_default;
- NodeTypeUndefined.select_area_func = node_select_area_default;
- NodeTypeUndefined.tweak_area_func = node_tweak_area_default;
NodeTypeUndefined.draw_buttons = nullptr;
NodeTypeUndefined.draw_buttons_ex = nullptr;
- NodeTypeUndefined.resize_area_func = node_resize_area_default;
NodeSocketTypeUndefined.draw = node_socket_undefined_draw;
NodeSocketTypeUndefined.draw_color = node_socket_undefined_draw_color;
@@ -3389,10 +3286,6 @@ void ED_node_init_butfuncs(void)
NODE_TYPES_BEGIN (ntype) {
/* default ui functions */
ntype->draw_nodetype = node_draw_default;
- ntype->draw_nodetype_prepare = node_update_default;
- ntype->select_area_func = node_select_area_default;
- ntype->tweak_area_func = node_tweak_area_default;
- ntype->resize_area_func = node_resize_area_default;
node_common_set_butfunc(ntype);
@@ -3416,10 +3309,6 @@ void ED_init_custom_node_type(bNodeType *ntype)
{
/* default ui functions */
ntype->draw_nodetype = node_draw_default;
- ntype->draw_nodetype_prepare = node_update_default;
- ntype->resize_area_func = node_resize_area_default;
- ntype->select_area_func = node_select_area_default;
- ntype->tweak_area_func = node_tweak_area_default;
}
void ED_init_custom_node_socket_type(bNodeSocketType *stype)
diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc
index fd07e6e0aba..c2187d1d479 100644
--- a/source/blender/editors/space_node/node_draw.cc
+++ b/source/blender/editors/space_node/node_draw.cc
@@ -663,26 +663,6 @@ static void node_update_hidden(bNode &node)
node.totr.ymax);
}
-void node_update_default(const bContext *C, bNodeTree *ntree, bNode *node)
-{
- if (node->flag & NODE_HIDDEN) {
- node_update_hidden(*node);
- }
- else {
- node_update_basis(*C, *ntree, *node);
- }
-}
-
-int node_select_area_default(bNode *node, int x, int y)
-{
- return BLI_rctf_isect_pt(&node->totr, x, y);
-}
-
-int node_tweak_area_default(bNode *node, int x, int y)
-{
- return BLI_rctf_isect_pt(&node->totr, x, y);
-}
-
int node_get_colorid(bNode &node)
{
switch (node.typeinfo->nclass) {
@@ -2323,7 +2303,7 @@ void node_set_cursor(wmWindow &win, SpaceNode &snode, const float2 &cursor)
}
}
if (node) {
- NodeResizeDirection dir = node->typeinfo->resize_area_func(node, cursor[0], cursor[1]);
+ NodeResizeDirection dir = node_get_resize_direction(node, cursor[0], cursor[1]);
wmcursor = node_get_resize_cursor(dir);
}
@@ -2346,13 +2326,6 @@ void node_draw_default(const bContext *C,
}
}
-static void node_update(const bContext &C, bNodeTree &ntree, bNode &node)
-{
- if (node.typeinfo->draw_nodetype_prepare) {
- node.typeinfo->draw_nodetype_prepare(&C, &ntree, &node);
- }
-}
-
static void count_multi_input_socket_links(bNodeTree &ntree, SpaceNode &snode)
{
Map<bNodeSocket *, int> counts;
@@ -2381,6 +2354,82 @@ static void count_multi_input_socket_links(bNodeTree &ntree, SpaceNode &snode)
}
}
+/* XXX Does a bounding box update by iterating over all children.
+ * Not ideal to do this in every draw call, but doing as transform callback doesn't work,
+ * since the child node totr rects are not updated properly at that point.
+ */
+static void frame_node_prepare_for_draw(bNodeTree &ntree, bNode &node)
+{
+ const float margin = 1.5f * U.widget_unit;
+ NodeFrame *data = (NodeFrame *)node.storage;
+
+ /* init rect from current frame size */
+ rctf rect;
+ node_to_view(node, node.offsetx, node.offsety, &rect.xmin, &rect.ymax);
+ node_to_view(
+ node, node.offsetx + node.width, node.offsety - node.height, &rect.xmax, &rect.ymin);
+
+ /* frame can be resized manually only if shrinking is disabled or no children are attached */
+ data->flag |= NODE_FRAME_RESIZEABLE;
+ /* for shrinking bbox, initialize the rect from first child node */
+ bool bbinit = (data->flag & NODE_FRAME_SHRINK);
+ /* fit bounding box to all children */
+ LISTBASE_FOREACH (bNode *, tnode, &ntree.nodes) {
+ if (tnode->parent != &node) {
+ continue;
+ }
+
+ /* add margin to node rect */
+ rctf noderect = tnode->totr;
+ noderect.xmin -= margin;
+ noderect.xmax += margin;
+ noderect.ymin -= margin;
+ noderect.ymax += margin;
+
+ /* first child initializes frame */
+ if (bbinit) {
+ bbinit = false;
+ rect = noderect;
+ data->flag &= ~NODE_FRAME_RESIZEABLE;
+ }
+ else {
+ BLI_rctf_union(&rect, &noderect);
+ }
+ }
+
+ /* now adjust the frame size from view-space bounding box */
+ node_from_view(node, rect.xmin, rect.ymax, &node.offsetx, &node.offsety);
+ float xmax, ymax;
+ node_from_view(node, rect.xmax, rect.ymin, &xmax, &ymax);
+ node.width = xmax - node.offsetx;
+ node.height = -ymax + node.offsety;
+
+ node.totr = rect;
+}
+
+static void reroute_node_prepare_for_draw(bNode &node)
+{
+ /* get "global" coords */
+ float locx, locy;
+ node_to_view(node, 0.0f, 0.0f, &locx, &locy);
+
+ /* reroute node has exactly one input and one output, both in the same place */
+ bNodeSocket *nsock = (bNodeSocket *)node.outputs.first;
+ nsock->locx = locx;
+ nsock->locy = locy;
+
+ nsock = (bNodeSocket *)node.inputs.first;
+ nsock->locx = locx;
+ nsock->locy = locy;
+
+ const float size = 8.0f;
+ node.width = size * 2;
+ node.totr.xmin = locx - size;
+ node.totr.xmax = locx + size;
+ node.totr.ymax = locy + size;
+ node.totr.ymin = locy - size;
+}
+
void node_update_nodetree(const bContext &C, bNodeTree &ntree)
{
/* Make sure socket "used" tags are correct, for displaying value buttons. */
@@ -2391,7 +2440,20 @@ void node_update_nodetree(const bContext &C, bNodeTree &ntree)
/* Update nodes front to back, so children sizes get updated before parents. */
LISTBASE_FOREACH_BACKWARD (bNode *, node, &ntree.nodes) {
- node_update(C, ntree, *node);
+ if (node->type == NODE_FRAME) {
+ frame_node_prepare_for_draw(ntree, *node);
+ }
+ else if (node->type == NODE_REROUTE) {
+ reroute_node_prepare_for_draw(*node);
+ }
+ else {
+ if (node->flag & NODE_HIDDEN) {
+ node_update_hidden(*node);
+ }
+ else {
+ node_update_basis(C, ntree, *node);
+ }
+ }
}
}
diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc
index f856347e09a..5a598a1bd04 100644
--- a/source/blender/editors/space_node/node_edit.cc
+++ b/source/blender/editors/space_node/node_edit.cc
@@ -1099,7 +1099,7 @@ static int node_resize_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* convert mouse coordinates to v2d space */
float cursor[2];
UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &cursor[0], &cursor[1]);
- const NodeResizeDirection dir = node->typeinfo->resize_area_func(node, cursor[0], cursor[1]);
+ const NodeResizeDirection dir = node_get_resize_direction(node, cursor[0], cursor[1]);
if (dir == NODE_RESIZE_NONE) {
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh
index 91cf2fb33a5..980611cc909 100644
--- a/source/blender/editors/space_node/node_intern.hh
+++ b/source/blender/editors/space_node/node_intern.hh
@@ -80,6 +80,15 @@ struct SpaceNode_Runtime {
struct NodeInsertOfsData *iofsd;
};
+enum NodeResizeDirection {
+ NODE_RESIZE_NONE = 0,
+ NODE_RESIZE_TOP = (1 << 0),
+ NODE_RESIZE_BOTTOM = (1 << 1),
+ NODE_RESIZE_RIGHT = (1 << 2),
+ NODE_RESIZE_LEFT = (1 << 3),
+};
+ENUM_OPERATORS(NodeResizeDirection, NODE_RESIZE_LEFT);
+
/* Transform between View2Ds in the tree path. */
blender::float2 space_node_group_offset(const SpaceNode &snode);
@@ -106,8 +115,7 @@ void node_draw_sockets(const View2D &v2d,
bNode &node,
const bool draw_outputs,
const bool select_all);
-void node_update_default(const bContext *C, bNodeTree *ntree, bNode *node);
-int node_select_area_default(bNode *node, int x, int y);
+NodeResizeDirection node_get_resize_direction(const bNode *node, const int x, const int y);
int node_tweak_area_default(bNode *node, int x, int y);
void node_socket_color_get(const bContext &C,
const bNodeTree &ntree,
diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc
index 414ba7be40e..3bf3ed9974e 100644
--- a/source/blender/editors/space_node/node_select.cc
+++ b/source/blender/editors/space_node/node_select.cc
@@ -103,10 +103,8 @@ static bool has_workbench_in_texture_color(const wmWindowManager *wm,
static bNode *node_under_mouse_select(bNodeTree &ntree, int mx, int my)
{
LISTBASE_FOREACH_BACKWARD (bNode *, node, &ntree.nodes) {
- if (node->typeinfo->select_area_func) {
- if (node->typeinfo->select_area_func(node, mx, my)) {
- return node;
- }
+ if (BLI_rctf_isect_pt(&node->totr, mx, my)) {
+ return node;
}
}
return nullptr;
@@ -115,11 +113,16 @@ static bNode *node_under_mouse_select(bNodeTree &ntree, int mx, int my)
static bNode *node_under_mouse_tweak(bNodeTree &ntree, const float2 &mouse)
{
LISTBASE_FOREACH_BACKWARD (bNode *, node, &ntree.nodes) {
- if (node->typeinfo->tweak_area_func) {
- if (node->typeinfo->tweak_area_func(node, (int)mouse.x, (int)mouse.y)) {
+ if (node->type == NODE_REROUTE) {
+ bNodeSocket *socket = (bNodeSocket *)node->inputs.first;
+ const float2 location{socket->locx, socket->locy};
+ if (float2::distance(mouse, location) < 24.0f) {
return node;
}
}
+ if (BLI_rctf_isect_pt(&node->totr, mouse.x, mouse.y)) {
+ return node;
+ }
}
return nullptr;
}