From 875a08884ba670387299a0baef19ace90170d271 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 7 Feb 2009 14:03:34 +0000 Subject: 2.5 - Node editor: link cut back, now under ALT+LMB, to prevent accidents. Note it now nicely intersects the real curved noodles with a line you draw! - To make above work, replaced ogl curve draw with own bezier code. - Added new WM standard operator callback for lines-gesture, the Lasso gesture now draws a closed line. - Both callbacks have optional property 'cursor' to make it give modal info. For future also linestyle or color can be defined. - Changed 'pin' icon in Image header to something that looks less scary... but there's no pin icon yet? --- source/blender/editors/interface/interface_utils.c | 2 +- source/blender/editors/space_node/drawnode.c | 88 ++++++----- source/blender/editors/space_node/node_draw.c | 22 ++- source/blender/editors/space_node/node_edit.c | 162 +++++++++++---------- source/blender/editors/space_node/node_intern.h | 4 +- source/blender/editors/space_node/node_ops.c | 4 +- 6 files changed, 152 insertions(+), 130 deletions(-) (limited to 'source/blender/editors') diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 898115cdbbd..5c9ed4dd81d 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -503,7 +503,7 @@ int uiDefIDPoinButs(uiBlock *block, Main *bmain, ID *parid, ID **id_p, int id_co /* pin button */ if(id && (events & UI_ID_PIN)) { - but= uiDefIconButS(block, ICONTOG, (events & UI_ID_PIN), 0 /* XXX ICON_PIN_DEHLT */, x, y ,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, pin_p, 0, 0, 0, 0, "Keeps this view displaying the current data regardless of what object is selected"); + but= uiDefIconButS(block, ICONTOG, (events & UI_ID_PIN), ICON_KEY_DEHLT, x, y ,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, pin_p, 0, 0, 0, 0, "Keeps this view displaying the current data regardless of what object is selected"); uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_PIN)); x+= DEF_ICON_BUT_WIDTH; } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 4d5548baeab..0770bc54ca6 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -53,6 +53,7 @@ #include "DNA_userdef_types.h" #include "BKE_context.h" +#include "BKE_curve.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_library.h" @@ -2522,12 +2523,32 @@ static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode) } #endif -void node_draw_link_bezier(View2D *v2d, float vec[4][3], int th_col1, int th_col2, int do_shaded) +/* if v2d not NULL, it clips and returns 0 if not visible */ +int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol) { - float dist; + float dist, vec[4][2]; - dist= 0.5f*ABS(vec[0][0] - vec[3][0]); + /* in v0 and v3 we put begin/end points */ + if(link->fromsock) { + vec[0][0]= link->fromsock->locx; + vec[0][1]= link->fromsock->locy; + } + else { + if(snode==NULL) return 0; + vec[0][0]= snode->mx; + vec[0][1]= snode->my; + } + if(link->tosock) { + vec[3][0]= link->tosock->locx; + vec[3][1]= link->tosock->locy; + } + else { + if(snode==NULL) return 0; + vec[3][0]= snode->mx; + vec[3][1]= snode->my; + } + dist= 0.5f*ABS(vec[0][0] - vec[3][0]); /* check direction later, for top sockets */ vec[1][0]= vec[0][0]+dist; @@ -2535,33 +2556,47 @@ void node_draw_link_bezier(View2D *v2d, float vec[4][3], int th_col1, int th_col vec[2][0]= vec[3][0]-dist; vec[2][1]= vec[3][1]; - // printf("-> %f %f %f %f %f\n", dist, vec[0][0], vec[3][0], vec[1][0], vec[2][0]); - if( MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > v2d->cur.xmax); /* clipped */ - else if ( MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < v2d->cur.xmin); /* clipped */ + 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 { - float curve_res = 24, spline_step = 0.0f; + + /* always do all three, to prevent data hanging around */ + forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], coord_array[0], resol, 2); + forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0]+1, resol, 2); + + return 1; + } + return 0; +} + +#define LINK_RESOL 24 +void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int th_col2, int do_shaded) +{ + float coord_array[LINK_RESOL+1][2]; + + if(node_link_bezier_points(v2d, snode, link, coord_array, LINK_RESOL)) { + float dist, spline_step = 0.0f; + int i; /* we can reuse the dist variable here to increment the GL curve eval amount*/ - dist = 1.0f/curve_res; + dist = 1.0f/(float)LINK_RESOL; - glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, vec[0]); glBegin(GL_LINE_STRIP); - while (spline_step < 1.000001f) { - if(do_shaded) + for(i=0; ifromnode==NULL && link->tonode==NULL) @@ -2598,28 +2633,7 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link) } } - vec[0][2]= vec[1][2]= vec[2][2]= vec[3][2]= 0.0; /* only 2d spline, set the Z to 0*/ - - /* in v0 and v3 we put begin/end points */ - if(link->fromnode) { - vec[0][0]= link->fromsock->locx; - vec[0][1]= link->fromsock->locy; - } - else { - vec[0][0]= snode->mx; - vec[0][1]= snode->my; - } - if(link->tonode) { - vec[3][0]= link->tosock->locx; - vec[3][1]= link->tosock->locy; - } - else { - vec[3][0]= snode->mx; - vec[3][1]= snode->my; - } - - node_draw_link_bezier(v2d, vec, th_col1, th_col2, do_shaded); - // fdrawbezier(vec); + node_draw_link_bezier(v2d, snode, link, th_col1, th_col2, do_shaded); } #if 0 diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 06c4b6bacd1..ffb25339bc3 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -356,10 +356,10 @@ static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node) { bNodeSocket *valsock= NULL, *colsock= NULL, *vecsock= NULL; bNodeSocket *sock; - float vec[4][3]; + bNodeLink link; int a; - vec[0][2]= vec[1][2]= vec[2][2]= vec[3][2]= 0.0; /* only 2d spline, set the Z to 0*/ + memset(&link, 0, sizeof(bNodeLink)); /* connect the first value buffer in with first value out */ /* connect the first RGBA buffer in with first RGBA out */ @@ -381,25 +381,21 @@ static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node) if(valsock || colsock || vecsock) { for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { if(nodeCountSocketLinks(snode->edittree, sock)) { - vec[3][0]= sock->locx; - vec[3][1]= sock->locy; + link.tosock= sock; if(sock->type==SOCK_VALUE && valsock) { - vec[0][0]= valsock->locx; - vec[0][1]= valsock->locy; - node_draw_link_bezier(v2d, vec, TH_WIRE, TH_WIRE, 0); + link.fromsock= valsock; + node_draw_link_bezier(v2d, snode, &link, TH_WIRE, TH_WIRE, 0); valsock= NULL; } if(sock->type==SOCK_VECTOR && vecsock) { - vec[0][0]= vecsock->locx; - vec[0][1]= vecsock->locy; - node_draw_link_bezier(v2d, vec, TH_WIRE, TH_WIRE, 0); + link.fromsock= vecsock; + node_draw_link_bezier(v2d, snode, &link, TH_WIRE, TH_WIRE, 0); vecsock= NULL; } if(sock->type==SOCK_RGBA && colsock) { - vec[0][0]= colsock->locx; - vec[0][1]= colsock->locy; - node_draw_link_bezier(v2d, vec, TH_WIRE, TH_WIRE, 0); + link.fromsock= colsock; + node_draw_link_bezier(v2d, snode, &link, TH_WIRE, TH_WIRE, 0); colsock= NULL; } } diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 7ab0ca96755..22e90d949e3 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -2077,84 +2077,94 @@ void node_make_link(SpaceNode *snode) // XXX snode_handle_recalc(snode); } +#endif + +/* ********************** Cut Link operator ***************** */ -static void node_border_link_delete(SpaceNode *snode) +#define LINK_RESOL 12 +static int cut_links_intersect(bNodeLink *link, float mcoords[][2], int tot) { - rcti rect; - short val, mval[2], mvalo[2]; + float coord_array[LINK_RESOL+1][2]; + int i, b; + + if(node_link_bezier_points(NULL, NULL, link, coord_array, LINK_RESOL)) { - /* to make this work more friendly, we first wait for a mouse move */ - getmouseco_areawin(mvalo); - while (get_mbut() & L_MOUSE) { - getmouseco_areawin(mval); - if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) - break; - else BIF_wait_for_statechange(); + for(i=0; i 0) + return 1; } - if((get_mbut() & L_MOUSE)==0) - return; + return 0; +} + +static int cut_links_exec(bContext *C, wmOperator *op) +{ + SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C); + ARegion *ar= CTX_wm_region(C); + float mcoords[256][2]; + int i= 0; - /* now change cursor and draw border */ - setcursor_space(SPACE_NODE, CURSOR_VPAINT); + RNA_BEGIN(op->ptr, itemptr, "path") { + float loc[2]; + + RNA_float_get_array(&itemptr, "loc", loc); + UI_view2d_region_to_view(&ar->v2d, (short)loc[0], (short)loc[1], + &mcoords[i][0], &mcoords[i][1]); + i++; + if(i>= 256) break; + } + RNA_END; - if ( (val = get_border(&rect, 2)) ) { - if(rect.xminv2d, mval, &rectf.xmin, &rectf.ymin); - mval[0]= rect.xmax; - mval[1]= rect.ymax; - areamouseco_to_ipoco(&snode->v2d, mval, &rectf.xmax, &rectf.ymax); - - glLoadIdentity(); - myortho2(rectf.xmin, rectf.xmax, rectf.ymin, rectf.ymax); - - glSelectBuffer(256, buffer); - glRenderMode(GL_SELECT); - glInitNames(); - glPushName(-1); - - /* draw links */ - for(link= snode->edittree->links.first; link; link= link->next) { - glLoadName(code++); - node_draw_link(snode, link); - } + if(i>1) { + bNodeLink *link, *next; + + for(link= snode->edittree->links.first; link; link= link->next) { + next= link->next; - hits= glRenderMode(GL_RENDER); - glPopName(); - if(hits>0) { - int a; - for(a=0; aedittree->links, buffer[ (4 * a) + 3]); - if(link) - link->fromnode= NULL; /* first tag for delete, otherwise indices are wrong */ - } - for(link= snode->edittree->links.first; link; link= next) { - next= link->next; - if(link->fromnode==NULL) { - NodeTagChanged(snode->edittree, link->tonode); - nodeRemLink(snode->edittree, link); - } - } - ntreeSolveOrder(snode->edittree); - snode_verify_groups(snode); - // XXX snode_handle_recalc(snode); + if(cut_links_intersect(link, mcoords, i)) { + NodeTagChanged(snode->edittree, link->tonode); + nodeRemLink(snode->edittree, link); } } + + ntreeSolveOrder(snode->edittree); + snode_verify_groups(snode); + snode_handle_recalc(C, snode); + + return OPERATOR_FINISHED; } - setcursor_space(SPACE_NODE, CURSOR_STD); + return OPERATOR_PASS_THROUGH;; } +void NODE_OT_links_cut(wmOperatorType *ot) +{ + PropertyRNA *prop; + + ot->name= "Cut links"; + ot->idname= "NODE_OT_links_cut"; + + ot->invoke= WM_gesture_lines_invoke; + ot->modal= WM_gesture_lines_modal; + ot->exec= cut_links_exec; + + ot->poll= ED_operator_node_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath); + /* internal */ + RNA_def_int(ot->srna, "cursor", BC_KNIFECURSOR, 0, INT_MAX, "Cursor", "", 0, INT_MAX); +} + +/* ******************************** */ + /* goes over all scenes, reads render layerss */ void node_read_renderlayers(SpaceNode *snode) { + Scene *curscene= NULL; // XXX Scene *scene; bNode *node; @@ -2165,36 +2175,32 @@ void node_read_renderlayers(SpaceNode *snode) for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->type==CMP_NODE_R_LAYERS) { ID *id= node->id; - if(id==NULL) id= (ID *)G.scene; if(id->flag & LIB_DOIT) { - RE_ReadRenderResult(G.scene, (Scene *)id); + RE_ReadRenderResult(curscene, (Scene *)id); ntreeCompositTagRender((Scene *)id); id->flag &= ~LIB_DOIT; } } } - /* own render result should be read/allocated */ - if(G.scene->id.flag & LIB_DOIT) - RE_ReadRenderResult(G.scene, G.scene); - // XXX snode_handle_recalc(snode); } void node_read_fullsamplelayers(SpaceNode *snode) { - Render *re= RE_NewRender(G.scene->id.name); + Scene *curscene= NULL; // XXX + Render *re= RE_NewRender(curscene->id.name); - waitcursor(1); + WM_cursor_wait(1); - BIF_init_render_callbacks(re, 1); - RE_MergeFullSample(re, G.scene, snode->nodetree); - BIF_end_render_callbacks(); + //BIF_init_render_callbacks(re, 1); + RE_MergeFullSample(re, curscene, snode->nodetree); + //BIF_end_render_callbacks(); // allqueue(REDRAWNODE, 1); // allqueue(REDRAWIMAGE, 1); - waitcursor(0); + WM_cursor_wait(0); } /* called from header_info, when deleting a scene @@ -2271,7 +2277,7 @@ void node_make_group(SpaceNode *snode) bNode *gnode; if(snode->edittree!=snode->nodetree) { - error("Can not add a new Group in a Group"); +// XXX error("Can not add a new Group in a Group"); return; } @@ -2283,14 +2289,14 @@ void node_make_group(SpaceNode *snode) break; } if(gnode) { - error("Can not add RenderLayer in a Group"); +// XXX error("Can not add RenderLayer in a Group"); return; } } gnode= nodeMakeGroupFromSelected(snode->nodetree); if(gnode==NULL) { - error("Can not make Group"); +// XXX error("Can not make Group"); } else { nodeSetActive(snode->nodetree, gnode); @@ -2298,6 +2304,8 @@ void node_make_group(SpaceNode *snode) } } +#if 0 + /* ******************** main event loop ****************** */ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index e9d5f1e755a..069f25fdbdb 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -62,7 +62,8 @@ void NODE_OT_border_select(struct wmOperatorType *ot); /* drawnode.c */ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link); -void node_draw_link_bezier(View2D *v2d, float vec[][3], int th_col1, int th_col2, int do_shaded); +void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int th_col2, int do_shaded); +int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol); void draw_nodespace_back_pix(ScrArea *sa, SpaceNode *snode); /* node_edit.c */ @@ -82,6 +83,7 @@ bNode *snode_get_editgroup(SpaceNode *snode); void NODE_OT_link(struct wmOperatorType *ot); void NODE_OT_delete_selection(struct wmOperatorType *ot); void NODE_OT_size_widget(struct wmOperatorType *ot); +void NODE_OT_links_cut(struct wmOperatorType *ot); // XXXXXX diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 43dd6356ccf..dc6ae03cef9 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -58,6 +58,7 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_delete_selection); WM_operatortype_append(NODE_OT_link); WM_operatortype_append(NODE_OT_size_widget); + WM_operatortype_append(NODE_OT_links_cut); } void node_keymap(struct wmWindowManager *wm) @@ -72,7 +73,8 @@ void node_keymap(struct wmWindowManager *wm) WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_size_widget", LEFTMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "NODE_OT_visibility_toggle", ACTIONMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "NODE_OT_visibility_toggle", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "NODE_OT_links_cut", LEFTMOUSE, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "NODE_OT_fit_all", HOMEKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_border_select", BKEY, KM_PRESS, 0, 0); -- cgit v1.2.3