[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [47319] trunk/blender/source/blender: Reroute nodes, by Jeroen Bakker (patch #28443).
Lukas Toenne
lukas.toenne at googlemail.com
Fri Jun 1 14:38:03 CEST 2012
Revision: 47319
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=47319
Author: lukastoenne
Date: 2012-06-01 12:38:03 +0000 (Fri, 01 Jun 2012)
Log Message:
-----------
Reroute nodes, by Jeroen Bakker (patch #28443).
By holding shift and "cutting" a node link a new reroute helper node can be inserted. This consists of a single socket that can be used to insert additional connection points into a link. This can be used to keep a connection point in the tree when deleting a node, or to control the path of long connections for layout cleanup.
Modified Paths:
--------------
trunk/blender/source/blender/blenkernel/BKE_node.h
trunk/blender/source/blender/blenkernel/intern/node.c
trunk/blender/source/blender/editors/space_node/drawnode.c
trunk/blender/source/blender/editors/space_node/node_draw.c
trunk/blender/source/blender/editors/space_node/node_edit.c
trunk/blender/source/blender/editors/space_node/node_intern.h
trunk/blender/source/blender/editors/space_node/node_ops.c
trunk/blender/source/blender/editors/space_node/node_select.c
trunk/blender/source/blender/nodes/composite/node_composite_tree.c
trunk/blender/source/blender/nodes/intern/node_common.c
trunk/blender/source/blender/nodes/shader/node_shader_tree.c
trunk/blender/source/blender/nodes/texture/node_texture_tree.c
Modified: trunk/blender/source/blender/blenkernel/BKE_node.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_node.h 2012-06-01 12:34:44 UTC (rev 47318)
+++ trunk/blender/source/blender/blenkernel/BKE_node.h 2012-06-01 12:38:03 UTC (rev 47319)
@@ -156,6 +156,10 @@
const char *(*labelfunc)(struct bNode *);
/// Optional custom resize handle polling.
int (*resize_area_func)(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);
@@ -434,6 +438,7 @@
#define NODE_FORLOOP 3
#define NODE_WHILELOOP 4
#define NODE_FRAME 5
+#define NODE_REROUTE 6
/* look up a socket on a group node by the internal group socket */
struct bNodeSocket *node_group_find_input(struct bNode *gnode, struct bNodeSocket *gsock);
@@ -449,6 +454,7 @@
/* in node_common.c */
void register_node_type_frame(struct bNodeTreeType *ttype);
+void register_node_type_reroute(struct bNodeTreeType *ttype);
/* ************** SHADER NODES *************** */
Modified: trunk/blender/source/blender/blenkernel/intern/node.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/node.c 2012-06-01 12:34:44 UTC (rev 47318)
+++ trunk/blender/source/blender/blenkernel/intern/node.c 2012-06-01 12:38:03 UTC (rev 47319)
@@ -1822,6 +1822,7 @@
static void registerCompositNodes(bNodeTreeType *ttype)
{
register_node_type_frame(ttype);
+ register_node_type_reroute(ttype);
register_node_type_cmp_group(ttype);
// register_node_type_cmp_forloop(ttype);
@@ -1914,6 +1915,7 @@
static void registerShaderNodes(bNodeTreeType *ttype)
{
register_node_type_frame(ttype);
+ register_node_type_reroute(ttype);
register_node_type_sh_group(ttype);
//register_node_type_sh_forloop(ttype);
@@ -1986,6 +1988,7 @@
static void registerTextureNodes(bNodeTreeType *ttype)
{
register_node_type_frame(ttype);
+ register_node_type_reroute(ttype);
register_node_type_tex_group(ttype);
// register_node_type_tex_forloop(ttype);
Modified: trunk/blender/source/blender/editors/space_node/drawnode.c
===================================================================
--- trunk/blender/source/blender/editors/space_node/drawnode.c 2012-06-01 12:34:44 UTC (rev 47318)
+++ trunk/blender/source/blender/editors/space_node/drawnode.c 2012-06-01 12:38:03 UTC (rev 47319)
@@ -681,9 +681,9 @@
/* node and group socket circles */
if (sock)
- node_socket_circle_draw(ntree, sock, socket_size);
+ node_socket_circle_draw(ntree, sock, socket_size, sock->flag & SELECT);
if (gsock)
- node_socket_circle_draw(ngroup, gsock, socket_size);
+ node_socket_circle_draw(ngroup, gsock, socket_size, gsock->flag & SELECT);
/* socket name */
offset = (in_out == SOCK_IN ? col1 : cor3);
@@ -1048,6 +1048,105 @@
uiItemR(layout, ptr, "shrink", 0, "Shrink", ICON_NONE);
}
+
+#define NODE_REROUTE_SIZE 8.0f
+
+static void node_update_reroute(const bContext *UNUSED(C), bNodeTree *UNUSED(ntree), bNode *node)
+{
+ bNodeSocket *nsock;
+ float locx, locy;
+ float size = NODE_REROUTE_SIZE;
+
+ /* get "global" coords */
+ nodeToView(node, 0.0f, 0.0f, &locx, &locy);
+
+ /* reroute node has exactly one input and one output, both in the same place */
+ nsock= node->outputs.first;
+ nsock->locx= locx;
+ nsock->locy= locy;
+
+ nsock= node->inputs.first;
+ nsock->locx= locx;
+ nsock->locy= locy;
+
+ 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 *ar, SpaceNode *UNUSED(snode), bNodeTree *ntree, bNode *node)
+{
+ bNodeSocket *sock;
+ #if 0 /* UNUSED */
+ rctf *rct= &node->totr;
+ float size = NODE_REROUTE_SIZE;
+ #endif
+ float socket_size= NODE_SOCKSIZE;
+
+ /* skip if out of view */
+ if (node->totr.xmax < ar->v2d.cur.xmin || node->totr.xmin > ar->v2d.cur.xmax ||
+ node->totr.ymax < ar->v2d.cur.ymin || node->totr.ymin > ar->v2d.cur.ymax) {
+
+ uiEndBlock(C, node->block);
+ node->block= NULL;
+ return;
+ }
+
+ /* XXX only kept for debugging
+ * selection state is indicated by socket outline below!
+ */
+ #if 0
+ /* body */
+ uiSetRoundBox(15);
+ UI_ThemeColor4(TH_NODE);
+ glEnable(GL_BLEND);
+ uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, size);
+ glDisable(GL_BLEND);
+
+ /* outline active and selected emphasis */
+ if( node->flag & (NODE_ACTIVE|SELECT) ) {
+ glEnable(GL_BLEND);
+ glEnable( GL_LINE_SMOOTH );
+ /* using different shades of TH_TEXT_HI for the empasis, like triangle */
+ if( node->flag & NODE_ACTIVE )
+ UI_ThemeColorShadeAlpha(TH_TEXT_HI, 0, -40);
+ else
+ UI_ThemeColorShadeAlpha(TH_TEXT_HI, -20, -120);
+ uiDrawBox(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size);
+
+ glDisable( GL_LINE_SMOOTH );
+ glDisable(GL_BLEND);
+ }
+ #endif
+
+ /* only draw input socket. as they all are placed on the same position.
+ * highlight also if node itself is selected, since we don't display the node body separately!
+ */
+ for(sock= node->inputs.first; sock; sock= sock->next) {
+ node_socket_circle_draw(ntree, sock, socket_size, (sock->flag & SELECT) || (node->flag & SELECT));
+ }
+
+ uiEndBlock(C, node->block);
+ uiDrawBlock(C, node->block);
+ node->block= NULL;
+}
+
+/* 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 */
+ static const float tweak_radius_sq = 576; /* 24*24 */
+
+ bNodeSocket *sock = 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) {
@@ -1072,6 +1171,11 @@
ntype->uifuncbut = node_buts_frame_details;
ntype->resize_area_func = node_resize_area_frame;
break;
+ case NODE_REROUTE:
+ ntype->drawfunc= node_draw_reroute;
+ ntype->drawupdatefunc= node_update_reroute;
+ ntype->tweak_area_func= node_tweak_area_reroute;
+ break;
}
}
@@ -2653,6 +2757,8 @@
/* default ui functions */
ntype->drawfunc = node_draw_default;
ntype->drawupdatefunc = node_update_default;
+ ntype->select_area_func = node_select_area_default;
+ ntype->tweak_area_func = node_tweak_area_default;
ntype->uifunc = NULL;
ntype->uifuncbut = NULL;
ntype->drawinputfunc = node_draw_input_default;
@@ -2847,36 +2953,61 @@
int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
{
float dist, vec[4][2];
-
+ float deltax, deltay;
+ int toreroute, fromreroute;
/* in v0 and v3 we put begin/end points */
if (link->fromsock) {
vec[0][0] = link->fromsock->locx;
vec[0][1] = link->fromsock->locy;
+ fromreroute = (link->fromnode && link->fromnode->type == NODE_REROUTE);
}
else {
if (snode == NULL) return 0;
vec[0][0] = snode->mx;
vec[0][1] = snode->my;
+ fromreroute = 0;
}
if (link->tosock) {
vec[3][0] = link->tosock->locx;
vec[3][1] = link->tosock->locy;
+ toreroute = (link->tonode && link->tonode->type == NODE_REROUTE);
}
else {
if (snode == NULL) return 0;
vec[3][0] = snode->mx;
vec[3][1] = snode->my;
+ toreroute = 0;
}
dist = UI_GetThemeValue(TH_NODE_CURVING) * 0.10f * ABS(vec[0][0] - vec[3][0]);
-
+ deltax = vec[3][0] - vec[0][0];
+ deltay = vec[3][1] - vec[0][1];
/* check direction later, for top sockets */
- vec[1][0] = vec[0][0] + dist;
- vec[1][1] = vec[0][1];
-
- vec[2][0] = vec[3][0] - dist;
- vec[2][1] = vec[3][1];
-
+ if (fromreroute) {
+ if (ABS(deltax)>ABS(deltay)) {
+ vec[1][1]= vec[0][1];
+ vec[1][0]= vec[0][0]+(deltax>0?dist:-dist);
+ } else {
+ vec[1][0]= vec[0][0];
+ vec[1][1]= vec[0][1]+(deltay>0?dist:-dist);
+ }
+ } else {
+ vec[1][0] = vec[0][0] + dist;
+ vec[1][1] = vec[0][1];
+ }
+ if (toreroute) {
+ if (ABS(deltax)>ABS(deltay)) {
+ vec[2][1]= vec[3][1];
+ vec[2][0]= vec[3][0]+ (deltax>0?-dist:dist);
+ } else {
+ vec[2][0]= vec[3][0];
+ vec[2][1]= vec[3][1]+(deltay>0?-dist:dist);
+ }
+
+ } else {
+ vec[2][0] = vec[3][0] - dist;
+ vec[2][1] = vec[3][1];
+ }
if (v2d && MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax) ; /* clipped */
else if (v2d && MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin) ; /* clipped */
else {
@@ -2891,6 +3022,8 @@
}
#define LINK_RESOL 24
+#define LINK_ARROW 12 /* position of arrow on the link, LINK_RESOL/2 */
+#define ARROW_SIZE 7
void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3)
{
float coord_array[LINK_RESOL + 1][2];
@@ -2898,9 +3031,10 @@
if (node_link_bezier_points(v2d, snode, link, coord_array, LINK_RESOL)) {
float dist, spline_step = 0.0f;
int i;
-
+ int drawarrow;
/* store current linewidth */
float linew;
+ float arrow[2], arrow1[2], arrow2[2];
glGetFloatv(GL_LINE_WIDTH, &linew);
/* we can reuse the dist variable here to increment the GL curve eval amount*/
@@ -2908,6 +3042,22 @@
glEnable(GL_LINE_SMOOTH);
+ drawarrow = (link->tonode && (link->tonode->type == NODE_REROUTE)) && (link->fromnode && (link->fromnode->type == NODE_REROUTE));
+ if (drawarrow) {
+ // draw arrow in line segment LINK_ARROW
+ float dx, dy, len;
+ dx = coord_array[LINK_ARROW][0]-coord_array[LINK_ARROW-1][0];
+ dy = coord_array[LINK_ARROW][1]-coord_array[LINK_ARROW-1][1];
+ len = sqrtf(dx*dx+dy*dy);
+ dx = dx /len*ARROW_SIZE;
+ dy = dy /len*ARROW_SIZE;
+ arrow1[0] = coord_array[LINK_ARROW][0]-dx+dy;
+ arrow1[1] = coord_array[LINK_ARROW][1]-dy-dx;
+ arrow2[0] = coord_array[LINK_ARROW][0]-dx-dy;
+ arrow2[1] = coord_array[LINK_ARROW][1]-dy+dx;
+ arrow[0] = coord_array[LINK_ARROW][0];
+ arrow[1] = coord_array[LINK_ARROW][1];
+ }
if (do_triple) {
UI_ThemeColorShadeAlpha(th_col3, -80, -120);
glLineWidth(4.0f);
@@ -2917,6 +3067,14 @@
glVertex2fv(coord_array[i]);
}
glEnd();
+ if (drawarrow) {
+ glBegin(GL_LINE_STRIP);
+ glVertex2fv(arrow1);
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list