diff options
-rw-r--r-- | source/blender/editors/include/ED_node.h | 2 | ||||
-rw-r--r-- | source/blender/editors/space_node/drawnode.c | 3 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_draw.c | 25 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_edit.c | 33 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_relationships.c | 106 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_templates.c | 6 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_ops.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_color.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 29 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_texture.c | 2 |
11 files changed, 167 insertions, 45 deletions
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index 1445308c485..7fe9a0c320c 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -80,7 +80,7 @@ void ED_node_draw_snap(struct View2D *v2d, const float cent[2], float size, Node /* node_draw.c */ void ED_node_tree_update(const struct bContext *C); void ED_node_tag_update_id(struct ID *id); -void ED_node_tag_update_nodetree(struct Main *bmain, struct bNodeTree *ntree); +void ED_node_tag_update_nodetree(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node); void ED_node_sort(struct bNodeTree *ntree); float ED_node_grid_size(void); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index ed207e2da02..623afb2ab80 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2884,7 +2884,8 @@ static void node_texture_set_butfunc(bNodeType *ntype) static void node_property_update_default(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { bNodeTree *ntree = ptr->id.data; - ED_node_tag_update_nodetree(bmain, ntree); + bNode *node = ptr->data; + ED_node_tag_update_nodetree(bmain, ntree, node); } static void node_socket_template_properties_update(bNodeType *ntype, bNodeSocketTemplate *stemp) diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index a4e2d5406f4..85c8f50fcd3 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -153,18 +153,27 @@ void ED_node_tag_update_id(ID *id) } } -void ED_node_tag_update_nodetree(Main *bmain, bNodeTree *ntree) +void ED_node_tag_update_nodetree(Main *bmain, bNodeTree *ntree, bNode *node) { if (!ntree) return; - + + bool do_tag_update = true; + if (node != NULL) { + if (!node_connected_to_output(ntree, node)) { + do_tag_update = false; + } + } + /* look through all datablocks, to support groups */ - FOREACH_NODETREE(bmain, tntree, id) { - /* check if nodetree uses the group */ - if (ntreeHasTree(tntree, ntree)) - ED_node_tag_update_id(id); - } FOREACH_NODETREE_END - + if (do_tag_update) { + FOREACH_NODETREE(bmain, tntree, id) { + /* check if nodetree uses the group */ + if (ntreeHasTree(tntree, ntree)) + ED_node_tag_update_id(id); + } FOREACH_NODETREE_END + } + if (ntree->type == NTREE_TEXTURE) ntreeTexCheckCyclics(ntree); } diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index ba5bea464d9..62431b30b2e 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -657,10 +657,10 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) node->flag |= NODE_DO_OUTPUT; if (was_output == 0) - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, node); } else if (do_update) - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, node); /* if active texture changed, free glsl materials */ if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) { @@ -692,7 +692,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) node->flag |= NODE_DO_OUTPUT; if (was_output == 0) - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, node); /* addnode() doesnt link this yet... */ node->id = (ID *)BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); @@ -722,11 +722,11 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) tnode->flag &= ~NODE_DO_OUTPUT; node->flag |= NODE_DO_OUTPUT; - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, node); } } else if (do_update) - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, node); } else if (ntree->type == NTREE_TEXTURE) { // XXX @@ -1177,7 +1177,8 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) bNode *node, *newnode, *lastnode; bNodeLink *link, *newlink, *lastlink; const bool keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs"); - + bool do_tag_update = false; + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); lastnode = ntree->nodes.last; @@ -1254,6 +1255,8 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) nodeSetSelected(node, false); node->flag &= ~NODE_ACTIVE; nodeSetSelected(newnode, true); + + do_tag_update |= (do_tag_update || node_connected_to_output(ntree, newnode)); } /* make sure we don't copy new nodes again! */ @@ -1264,7 +1267,9 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) ntreeUpdateTree(CTX_data_main(C), snode->edittree); snode_notify(C, snode); - snode_dag_update(C, snode); + if (do_tag_update) { + snode_dag_update(C, snode); + } return OPERATOR_FINISHED; } @@ -1623,6 +1628,7 @@ static int node_mute_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode = CTX_wm_space_node(C); bNode *node; + bool do_tag_update = false; ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); @@ -1631,11 +1637,14 @@ static int node_mute_exec(bContext *C, wmOperator *UNUSED(op)) if ((node->flag & SELECT) && node->typeinfo->update_internal_links) { node->flag ^= NODE_MUTED; snode_update(snode, node); + do_tag_update |= (do_tag_update || node_connected_to_output(snode->edittree, node)); } } snode_notify(C, snode); - snode_dag_update(C, snode); + if (do_tag_update) { + snode_dag_update(C, snode); + } return OPERATOR_FINISHED; } @@ -1661,13 +1670,15 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode = CTX_wm_space_node(C); bNode *node, *next; - + bool do_tag_update = false; + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); for (node = snode->edittree->nodes.first; node; node = next) { next = node->next; if (node->flag & SELECT) { /* check id user here, nodeFreeNode is called for free dbase too */ + do_tag_update |= (do_tag_update || node_connected_to_output(snode->edittree, node)); if (node->id) id_us_min(node->id); nodeFreeNode(snode->edittree, node); @@ -1677,7 +1688,9 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op)) ntreeUpdateTree(CTX_data_main(C), snode->edittree); snode_notify(C, snode); - snode_dag_update(C, snode); + if (do_tag_update) { + snode_dag_update(C, snode); + } return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 444e81155d8..6b8fa0b88fe 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -155,6 +155,8 @@ void NODE_OT_group_edit(struct wmOperatorType *ot); /* node_relationships.c */ +bool node_connected_to_output(struct bNodeTree *ntree, struct bNode *node); + void NODE_OT_link(struct wmOperatorType *ot); void NODE_OT_link_make(struct wmOperatorType *ot); void NODE_OT_links_cut(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c index 0852b6164d3..50d7df6ee20 100644 --- a/source/blender/editors/space_node/node_relationships.c +++ b/source/blender/editors/space_node/node_relationships.c @@ -59,6 +59,55 @@ #include "node_intern.h" /* own include */ +/* ****************** Relations helpers *********************** */ + +static bool ntree_check_nodes_connected_dfs(bNodeTree *ntree, + bNode *from, + bNode *to) +{ + if (from->flag & NODE_TEST) { + return false; + } + from->flag |= NODE_TEST; + for (bNodeLink *link = ntree->links.first; link != NULL; link = link->next) { + if (link->fromnode == from) { + if (link->tonode == to) { + return true; + } + else { + if (ntree_check_nodes_connected_dfs(ntree, link->tonode, to)) { + return true; + } + } + } + } + return false; +} + +static bool ntree_check_nodes_connected(bNodeTree *ntree, bNode *from, bNode *to) +{ + if (from == to) { + return true; + } + ntreeNodeFlagSet(ntree, NODE_TEST, false); + return ntree_check_nodes_connected_dfs(ntree, from, to); +} + +bool node_connected_to_output(bNodeTree *ntree, bNode *node) +{ + for (bNode *current_node = ntree->nodes.first; + current_node != NULL; + current_node = current_node->next) + { + if (current_node->flag & NODE_DO_OUTPUT) { + if (ntree_check_nodes_connected(ntree, node, current_node)) { + return true; + } + } + } + return false; +} + /* ****************** Add *********************** */ @@ -468,7 +517,8 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links) bNodeTree *ntree = snode->edittree; bNodeLinkDrag *nldrag = op->customdata; LinkData *linkdata; - + bool do_tag_update = false; + /* avoid updates while applying links */ ntree->is_updating = true; for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { @@ -493,15 +543,27 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links) /* we might need to remove a link */ node_remove_extra_links(snode, link); + + if (link->tonode) { + do_tag_update |= (do_tag_update || node_connected_to_output(ntree, link->tonode)); + } } - else + else { + /* See note below, but basically TEST flag means that the link + * was connected to output (or to a node which affects the + * output). + */ + do_tag_update |= (link->flag & NODE_LINK_TEST) != 0; nodeRemLink(ntree, link); + } } ntree->is_updating = false; ntreeUpdateTree(CTX_data_main(C), ntree); snode_notify(C, snode); - snode_dag_update(C, snode); + if (do_tag_update) { + snode_dag_update(C, snode); + } BLI_remlink(&snode->linkdrag, nldrag); /* links->data pointers are either held by the tree or freed already */ @@ -632,7 +694,18 @@ static bNodeLinkDrag *node_link_init(SpaceNode *snode, float cursor[2], bool det *oplink = *link; oplink->next = oplink->prev = NULL; oplink->flag |= NODE_LINK_VALID; - + + /* The link could be disconnected and in that case we + * wouldn't be able to check whether tag update is + * needed or not when releasing mouse button. So we + * cache whether the link affects output or not here + * using TEST flag. + */ + oplink->flag &= ~NODE_LINK_TEST; + if (node_connected_to_output(snode->edittree, link->tonode)) { + oplink->flag |= NODE_LINK_TEST; + } + BLI_addtail(&nldrag->links, linkdata); nodeRemLink(snode->edittree, link); } @@ -647,7 +720,11 @@ static bNodeLinkDrag *node_link_init(SpaceNode *snode, float cursor[2], bool det oplink->fromnode = node; oplink->fromsock = sock; oplink->flag |= NODE_LINK_VALID; - + oplink->flag &= ~NODE_LINK_TEST; + if (node_connected_to_output(snode->edittree, node)) { + oplink->flag |= NODE_LINK_TEST; + } + BLI_addtail(&nldrag->links, linkdata); } } @@ -668,7 +745,11 @@ static bNodeLinkDrag *node_link_init(SpaceNode *snode, float cursor[2], bool det *oplink = *link; oplink->next = oplink->prev = NULL; oplink->flag |= NODE_LINK_VALID; - + oplink->flag &= ~NODE_LINK_TEST; + if (node_connected_to_output(snode->edittree, link->tonode)) { + oplink->flag |= NODE_LINK_TEST; + } + BLI_addtail(&nldrag->links, linkdata); nodeRemLink(snode->edittree, link); @@ -687,7 +768,11 @@ static bNodeLinkDrag *node_link_init(SpaceNode *snode, float cursor[2], bool det oplink->tonode = node; oplink->tosock = sock; oplink->flag |= NODE_LINK_VALID; - + oplink->flag &= ~NODE_LINK_TEST; + if (node_connected_to_output(snode->edittree, node)) { + oplink->flag |= NODE_LINK_TEST; + } + BLI_addtail(&nldrag->links, linkdata); } } @@ -817,6 +902,7 @@ static int cut_links_exec(bContext *C, wmOperator *op) ARegion *ar = CTX_wm_region(C); float mcoords[256][2]; int i = 0; + bool do_tag_update = false; RNA_BEGIN (op->ptr, itemptr, "path") { @@ -849,6 +935,8 @@ static int cut_links_exec(bContext *C, wmOperator *op) found = true; } + do_tag_update |= (do_tag_update || node_connected_to_output(snode->edittree, link->tonode)); + snode_update(snode, link->tonode); nodeRemLink(snode->edittree, link); } @@ -857,7 +945,9 @@ static int cut_links_exec(bContext *C, wmOperator *op) if (found) { ntreeUpdateTree(CTX_data_main(C), snode->edittree); snode_notify(C, snode); - snode_dag_update(C, snode); + if (do_tag_update) { + snode_dag_update(C, snode); + } return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index d8dca7b63d4..0cbb7ea0220 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -168,7 +168,7 @@ static void node_socket_disconnect(Main *bmain, bNodeTree *ntree, bNode *node_to nodeUpdate(ntree, node_to); ntreeUpdateTree(bmain, ntree); - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, node_to); } /* remove all nodes connected to this socket, if they aren't connected to other nodes */ @@ -183,7 +183,7 @@ static void node_socket_remove(Main *bmain, bNodeTree *ntree, bNode *node_to, bN nodeUpdate(ntree, node_to); ntreeUpdateTree(bmain, ntree); - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, node_to); } /* add new node connected to this socket, or replace an existing one */ @@ -279,7 +279,7 @@ static void node_socket_add_replace(const bContext *C, bNodeTree *ntree, bNode * nodeUpdate(ntree, node_to); ntreeUpdateTree(CTX_data_main(C), ntree); - ED_node_tag_update_nodetree(CTX_data_main(C), ntree); + ED_node_tag_update_nodetree(CTX_data_main(C), ntree, node_to); } /****************************** Node Link Menu *******************************/ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 1a106b40f32..1071e0f12e8 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -170,7 +170,7 @@ void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *i if (node && is_image_texture_node(node)) { node->id = &ima->id; - ED_node_tag_update_nodetree(bmain, ma->nodetree); + ED_node_tag_update_nodetree(bmain, ma->nodetree, node); } } diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index c418ef3ceb6..021bc608564 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -326,7 +326,7 @@ static void rna_ColorRamp_update(Main *bmain, Scene *UNUSED(scene), PointerRNA * for (node = ntree->nodes.first; node; node = node->next) { if (ELEM(node->type, SH_NODE_VALTORGB, CMP_NODE_VALTORGB, TEX_NODE_VALTORGB)) { - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, node); } } break; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 7561a7405f7..a701cf6182d 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -657,11 +657,12 @@ static bool rna_NodeTree_check(bNodeTree *ntree, ReportList *reports) static void rna_NodeTree_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->id.data; + bNode *node = (bNode *)ptr->data; WM_main_add_notifier(NC_NODE | NA_EDITED, NULL); WM_main_add_notifier(NC_SCENE | ND_NODES, &ntree->id); - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, node); } static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *reports, const char *type) @@ -1048,7 +1049,7 @@ static void rna_NodeTree_interface_update(bNodeTree *ntree, bContext *C) ntree->update |= NTREE_UPDATE_GROUP; ntreeUpdateTree(G.main, ntree); - ED_node_tag_update_nodetree(CTX_data_main(C), ntree); + ED_node_tag_update_nodetree(CTX_data_main(C), ntree, NULL); } @@ -1545,12 +1546,13 @@ static int rna_Node_parent_poll(PointerRNA *ptr, PointerRNA value) static void rna_Node_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->id.data; - ED_node_tag_update_nodetree(bmain, ntree); + bNode *node = (bNode *)ptr->data; + ED_node_tag_update_nodetree(bmain, ntree, node); } -static void rna_Node_socket_value_update(ID *id, bNode *UNUSED(node), bContext *C) +static void rna_Node_socket_value_update(ID *id, bNode *node, bContext *C) { - ED_node_tag_update_nodetree(CTX_data_main(C), (bNodeTree *)id); + ED_node_tag_update_nodetree(CTX_data_main(C), (bNodeTree *)id, node); } static void rna_Node_select_set(PointerRNA *ptr, int value) @@ -1916,7 +1918,11 @@ static PointerRNA rna_NodeSocket_node_get(PointerRNA *ptr) static void rna_NodeSocket_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->id.data; - ED_node_tag_update_nodetree(bmain, ntree); + bNodeSocket *sock = (bNodeSocket *)ptr->data; + bNode *node; + if (nodeFindNode(ntree, sock, &node, NULL)) { + ED_node_tag_update_nodetree(bmain, ntree, node); + } } static int rna_NodeSocket_is_output_get(PointerRNA *ptr) @@ -2182,7 +2188,7 @@ static void rna_NodeSocketInterface_update(Main *bmain, Scene *UNUSED(scene), Po ntree->update |= NTREE_UPDATE_GROUP; ntreeUpdateTree(G.main, ntree); - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, NULL); } @@ -2438,8 +2444,9 @@ static void rna_CompositorNode_tag_need_exec(bNode *node) static void rna_Node_tex_image_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->id.data; + bNode *node = (bNode *)ptr->data; - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, node); WM_main_add_notifier(NC_IMAGE, NULL); } @@ -2451,7 +2458,7 @@ static void rna_Node_material_update(Main *bmain, Scene *UNUSED(scene), PointerR if (node->id) nodeSetActive(ntree, node); - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, node); } static void rna_NodeGroup_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) @@ -2462,7 +2469,7 @@ static void rna_NodeGroup_update(Main *bmain, Scene *UNUSED(scene), PointerRNA * if (node->id) ntreeUpdateTree(bmain, (bNodeTree *)node->id); - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, node); } static void rna_NodeGroup_node_tree_set(PointerRNA *ptr, const PointerRNA value) @@ -2972,7 +2979,7 @@ static void rna_ShaderNodeScript_update(Main *bmain, Scene *scene, PointerRNA *p RE_engine_free(engine); } - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, node); } static void rna_ShaderNodeSubsurface_update(Main *bmain, Scene *scene, PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 71069dc9751..b44482dc2c1 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -174,7 +174,7 @@ static void rna_Texture_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *pt } else if (GS(id->name) == ID_NT) { bNodeTree *ntree = ptr->id.data; - ED_node_tag_update_nodetree(bmain, ntree); + ED_node_tag_update_nodetree(bmain, ntree, NULL); } } |