diff options
Diffstat (limited to 'source/blender/editors/space_node')
-rw-r--r-- | source/blender/editors/space_node/drawnode.c | 67 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_draw.c | 15 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_edit.c | 106 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_group.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_intern.h | 5 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_ops.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_select.c | 6 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_templates.c | 19 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_view.c | 9 | ||||
-rw-r--r-- | source/blender/editors/space_node/space_node.c | 6 |
10 files changed, 193 insertions, 46 deletions
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 6fa164a483f..7f35884cb65 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -703,7 +703,9 @@ static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr, uiItemR(col, ptr, "use_auto_refresh", 0, NULL, ICON_NONE); } - if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER) { + if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER && + RNA_boolean_get(ptr, "has_layers")) + { col = uiLayoutColumn(layout, false); uiItemR(col, ptr, "layer", 0, NULL, ICON_NONE); } @@ -829,7 +831,7 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA static void node_shader_buts_tex_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) { PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user"); - uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0); + uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0, 0); } static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, PointerRNA *ptr) @@ -862,14 +864,15 @@ static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, P if (!(ELEM(ima->source, IMA_SRC_GENERATED, IMA_SRC_VIEWER))) { uiLayout *row = uiLayoutRow(layout, true); + const bool is_packed = BKE_image_has_packedfile(ima); - if (ima->packedfile) + if (is_packed) uiItemO(row, "", ICON_PACKAGE, "image.unpack"); else uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack"); row = uiLayoutRow(row, true); - uiLayoutSetEnabled(row, ima->packedfile == NULL); + uiLayoutSetEnabled(row, !is_packed); uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE); uiItemO(row, "", ICON_FILE_REFRESH, "image.reload"); } @@ -1214,6 +1217,24 @@ static void node_shader_set_butfunc(bNodeType *ntype) /* ****************** BUTTON CALLBACKS FOR COMPOSITE NODES ***************** */ +static void node_buts_image_views(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr, + PointerRNA *imaptr) +{ + uiLayout *col; + + if (!imaptr->data) + return; + + col = uiLayoutColumn(layout, false); + + if (RNA_boolean_get(ptr, "has_views")) { + if (RNA_enum_get(ptr, "view") == 0) + uiItemR(col, ptr, "view", 0, NULL, ICON_CAMERA_STEREO); + else + uiItemR(col, ptr, "view", 0, NULL, ICON_SCENE); + } +} + static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr) { bNode *node = ptr->data; @@ -1227,6 +1248,8 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA * imaptr = RNA_pointer_get(ptr, "image"); node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr); + + node_buts_image_views(layout, C, ptr, &imaptr); } static void node_composit_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) @@ -1236,7 +1259,7 @@ static void node_composit_buts_image_ex(uiLayout *layout, bContext *C, PointerRN RNA_pointer_create((ID *)ptr->id.data, &RNA_ImageUser, node->storage, &iuserptr); uiLayoutSetContextPointer(layout, "image_user", &iuserptr); - uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0); + uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0, 1); } static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr) @@ -1717,8 +1740,8 @@ static void node_composit_buts_id_mask(uiLayout *layout, bContext *UNUSED(C), Po static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { PointerRNA imfptr = RNA_pointer_get(ptr, "format"); - int multilayer = (RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER); - + const bool multilayer = RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER; + if (multilayer) uiItemL(layout, IFACE_("Path:"), ICON_NONE); else @@ -1727,15 +1750,22 @@ static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C) } static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, PointerRNA *ptr) { + Scene *scene = CTX_data_scene(C); PointerRNA imfptr = RNA_pointer_get(ptr, "format"); PointerRNA active_input_ptr, op_ptr; uiLayout *row, *col; int active_index; - int multilayer = (RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER); + const bool multilayer = RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER; + const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0; node_composit_buts_file_output(layout, C, ptr); uiTemplateImageSettings(layout, &imfptr, false); + /* disable stereo output for multilayer, too much work for something that no one will use */ + /* if someone asks for that we can implement it */ + if (is_multiview) + uiTemplateImageFormatViews(layout, &imfptr, NULL); + uiItemS(layout); uiItemO(layout, IFACE_("Add Input"), ICON_ZOOMIN, "NODE_OT_output_file_add_socket"); @@ -1797,6 +1827,9 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi col = uiLayoutColumn(layout, false); uiLayoutSetActive(col, RNA_boolean_get(&active_input_ptr, "use_node_format") == false); uiTemplateImageSettings(col, &imfptr, false); + + if (is_multiview) + uiTemplateImageFormatViews(layout, &imfptr, NULL); } } } @@ -2090,6 +2123,18 @@ static void node_composit_buts_switch(uiLayout *layout, bContext *UNUSED(C), Poi uiItemR(layout, ptr, "check", 0, NULL, ICON_NONE); } +static void node_composit_buts_switch_view_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *UNUSED(ptr)) +{ + PointerRNA op_ptr; + wmOperatorType *ot = WM_operatortype_find("NODE_OT_switch_view_update", 1); + + BLI_assert(ot != 0); + + WM_operator_properties_create_ptr(&op_ptr, ot); + + uiItemFullO_ptr(layout, ot, "Update Views", ICON_FILE_REFRESH, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); +} + static void node_composit_buts_boxmask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiLayout *row; @@ -2587,6 +2632,9 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_SWITCH: ntype->draw_buttons = node_composit_buts_switch; break; + case CMP_NODE_SWITCH_VIEW: + ntype->draw_buttons_ex = node_composit_buts_switch_view_ex; + break; case CMP_NODE_MASK_BOX: ntype->draw_buttons = node_composit_buts_boxmask; ntype->draw_backdrop = node_composit_backdrop_boxmask; @@ -2739,7 +2787,7 @@ static void node_texture_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA PointerRNA iuserptr; RNA_pointer_create((ID *)ptr->id.data, &RNA_ImageUser, node->storage, &iuserptr); - uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0); + uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0, 0); } static void node_texture_buts_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -2959,6 +3007,7 @@ static void node_file_output_socket_draw(bContext *C, uiLayout *layout, PointerR imfptr = RNA_pointer_get(node_ptr, "format"); imtype = RNA_enum_get(&imfptr, "file_format"); + if (imtype == R_IMF_IMTYPE_MULTILAYER) { NodeImageMultiFileSocket *input = sock->storage; RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotLayer, input, &inputptr); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 87a64e95e63..34efba00b86 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -123,7 +123,14 @@ void ED_node_tag_update_id(ID *id) bNodeTree *ntree = node_tree_from_ID(id); if (id == NULL || ntree == NULL) return; - + + /* TODO(sergey): With the new dependency graph it + * should be just enough to only tag ntree itself, + * all the users of this tree will have update + * flushed from the tree, + */ + DAG_id_tag_update(&ntree->id, 0); + if (ntree->type == NTREE_SHADER) { DAG_id_tag_update(id, 0); @@ -163,14 +170,14 @@ void ED_node_tag_update_nodetree(Main *bmain, bNodeTree *ntree) ntreeTexCheckCyclics(ntree); } -static int compare_nodes(bNode *a, bNode *b) +static bool compare_nodes(const bNode *a, const bNode *b) { bNode *parent; /* These tell if either the node or any of the parent nodes is selected. * A selected parent means an unselected node is also in foreground! */ - int a_select = (a->flag & NODE_SELECT), b_select = (b->flag & NODE_SELECT); - int a_active = (a->flag & NODE_ACTIVE), b_active = (b->flag & NODE_ACTIVE); + bool a_select = (a->flag & NODE_SELECT) != 0, b_select = (b->flag & NODE_SELECT) != 0; + bool a_active = (a->flag & NODE_ACTIVE) != 0, b_active = (b->flag & NODE_ACTIVE) != 0; /* if one is an ancestor of the other */ /* XXX there might be a better sorting algorithm for stable topological sort, this is O(n^2) worst case */ diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index f79d6e26f22..ffd51bcc44e 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -93,7 +93,6 @@ typedef struct CompoJob { const short *stop; short *do_update; float *progress; - short need_sync; int recalc_flags; } CompoJob; @@ -162,13 +161,12 @@ static int compo_breakjob(void *cjv) ); } -/* called by compo, wmJob sends notifier, old compositor system only */ -static void compo_statsdrawjob(void *cjv, char *UNUSED(str)) +/* called by compo, wmJob sends notifier */ +static void compo_statsdrawjob(void *cjv, const char *UNUSED(str)) { CompoJob *cj = cjv; *(cj->do_update) = true; - cj->need_sync = true; } /* called by compo, wmJob sends notifier */ @@ -202,17 +200,8 @@ static void compo_initjob(void *cjv) } /* called before redraw notifiers, it moves finished previews over */ -static void compo_updatejob(void *cjv) +static void compo_updatejob(void *UNUSED(cjv)) { - CompoJob *cj = cjv; - - if (cj->need_sync) { - /* was used by old compositor system only */ - ntreeLocalSync(cj->localtree, cj->ntree); - - cj->need_sync = false; - } - WM_main_add_notifier(NC_SCENE | ND_COMPO_RESULT, NULL); } @@ -223,13 +212,13 @@ static void compo_progressjob(void *cjv, float progress) *(cj->progress) = progress; } - /* only this runs inside thread */ static void compo_startjob(void *cjv, short *stop, short *do_update, float *progress) { CompoJob *cj = cjv; bNodeTree *ntree = cj->localtree; Scene *scene = cj->scene; + SceneRenderView *srv; if (scene->use_nodes == false) return; @@ -249,7 +238,16 @@ static void compo_startjob(void *cjv, short *stop, short *do_update, float *prog // XXX BIF_store_spare(); /* 1 is do_previews */ - ntreeCompositExecTree(cj->scene, ntree, &cj->scene->r, false, true, &scene->view_settings, &scene->display_settings); + + if ((cj->scene->r.scemode & R_MULTIVIEW) == 0) { + ntreeCompositExecTree(cj->scene, ntree, &cj->scene->r, false, true, &scene->view_settings, &scene->display_settings, ""); + } + else { + for (srv = scene->r.views.first; srv; srv = srv->next) { + if (BKE_scene_multiview_is_render_view_active(&scene->r, srv) == false) continue; + ntreeCompositExecTree(cj->scene, ntree, &cj->scene->r, false, true, &scene->view_settings, &scene->display_settings, srv->name); + } + } ntree->test_break = NULL; ntree->stats_draw = NULL; @@ -742,6 +740,34 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) } } +void ED_node_id_unref(SpaceNode *snode, const ID *id) +{ + if (GS(id->name) == ID_SCE) { + if (snode->id == id) { + /* nasty DNA logic for SpaceNode: + * ideally should be handled by editor code, but would be bad level call + */ + bNodeTreePath *path, *path_next; + for (path = snode->treepath.first; path; path = path_next) { + path_next = path->next; + MEM_freeN(path); + } + BLI_listbase_clear(&snode->treepath); + + snode->id = NULL; + snode->from = NULL; + snode->nodetree = NULL; + snode->edittree = NULL; + } + } + else if (GS(id->name) == ID_OB) { + if (snode->from == id) { + snode->flag &= ~SNODE_PIN; + snode->from = NULL; + } + } +} + void ED_node_post_apply_transform(bContext *UNUSED(C), bNodeTree *UNUSED(ntree)) { /* XXX This does not work due to layout functions relying on node->block, @@ -1671,6 +1697,54 @@ void NODE_OT_delete(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/* ****************** Switch View ******************* */ + +static int node_switch_view_poll(bContext *C) +{ + SpaceNode *snode = CTX_wm_space_node(C); + + if (snode && snode->edittree) + return true; + + return false; +} + +static int node_switch_view_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNode *node, *next; + + for (node = snode->edittree->nodes.first; node; node = next) { + next = node->next; + if (node->flag & SELECT) { + /* call the update function from the Switch View node */ + node->update = NODE_UPDATE_OPERATOR; + } + } + + ntreeUpdateTree(CTX_data_main(C), snode->edittree); + + snode_notify(C, snode); + snode_dag_update(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_switch_view_update(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Update Views"; + ot->description = "Update views of selected node"; + ot->idname = "NODE_OT_switch_view_update"; + + /* api callbacks */ + ot->exec = node_switch_view_exec; + ot->poll = node_switch_view_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /* ****************** Delete with reconnect ******************* */ static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op)) { diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c index b69808d4e81..f1d9d4efcc6 100644 --- a/source/blender/editors/space_node/node_group.c +++ b/source/blender/editors/space_node/node_group.c @@ -456,8 +456,8 @@ static int node_group_separate_selected(bNodeTree *ntree, bNodeTree *ngroup, flo /* add internal links to the ntree */ for (link = ngroup->links.first; link; link = link_next) { - int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT)); - int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT)); + const bool fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT)); + const bool toselect = (link->tonode && (link->tonode->flag & NODE_SELECT)); link_next = link->next; if (make_copy) { diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 27c3ab813ae..b15e9025a82 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -42,12 +42,9 @@ struct ARegionType; struct View2D; struct bContext; struct wmWindow; -struct wmWindowManager; -struct wmEvent; struct bNode; struct bNodeSocket; struct bNodeLink; -struct Main; struct wmKeyConfig; /* temp data to pass on to modal */ @@ -203,6 +200,8 @@ void NODE_OT_output_file_add_socket(struct wmOperatorType *ot); void NODE_OT_output_file_remove_active_socket(struct wmOperatorType *ot); void NODE_OT_output_file_move_active_socket(struct wmOperatorType *ot); +void NODE_OT_switch_view_update (struct wmOperatorType *ot); + /* Note: clipboard_cut is a simple macro of copy + delete */ void NODE_OT_clipboard_copy(struct wmOperatorType *ot); void NODE_OT_clipboard_paste(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index e2d83c243a2..474ad4db4af 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -123,6 +123,8 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_viewer_border); WM_operatortype_append(NODE_OT_clear_viewer_border); + WM_operatortype_append(NODE_OT_switch_view_update); + WM_operatortype_append(NODE_OT_tree_socket_add); WM_operatortype_append(NODE_OT_tree_socket_remove); WM_operatortype_append(NODE_OT_tree_socket_move); diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index 25f9d56c8f0..78302fedd97 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -249,9 +249,9 @@ static bool node_select_grouped_name(SpaceNode *snode, bNode *node_act, const bo bool changed = false; const unsigned int delims[] = {'.', '-', '_', '\0'}; size_t pref_len_act, pref_len_curr; - char *sep, *suf_act, *suf_curr; + const char *sep, *suf_act, *suf_curr; - pref_len_act = BLI_str_partition_ex_utf8(node_act->name, delims, &sep, &suf_act, from_right); + pref_len_act = BLI_str_partition_ex_utf8(node_act->name, NULL, delims, &sep, &suf_act, from_right); /* Note: in case we are searching for suffix, and found none, use whole name as suffix. */ if (from_right && !(sep && suf_act)) { @@ -263,7 +263,7 @@ static bool node_select_grouped_name(SpaceNode *snode, bNode *node_act, const bo if (node->flag & SELECT) { continue; } - pref_len_curr = BLI_str_partition_ex_utf8(node->name, delims, &sep, &suf_curr, from_right); + pref_len_curr = BLI_str_partition_ex_utf8(node->name, NULL, delims, &sep, &suf_curr, from_right); /* Same as with active node name! */ if (from_right && !(sep && suf_curr)) { diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 8b68ac013c2..a7fd624d2aa 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -24,6 +24,7 @@ * \ingroup edinterface */ +#include <stdlib.h> #include <string.h> #include "MEM_guardedalloc.h" @@ -214,8 +215,22 @@ static void node_socket_add_replace(const bContext *C, bNodeTree *ntree, bNode * } else if (!node_from) { node_from = nodeAddStaticNode(C, ntree, type); - node_from->locx = node_to->locx - (node_from->typeinfo->width + 50); - node_from->locy = node_to->locy; + if (node_prev != NULL) { + /* If we're replacing existing node, use it's location. */ + node_from->locx = node_prev->locx; + node_from->locy = node_prev->locy; + node_from->offsetx = node_prev->offsetx; + node_from->offsety = node_prev->offsety; + } + else { + /* Avoid exact intersection of nodes. + * TODO(sergey): Still not ideal, but better than nothing. + */ + int index = BLI_findindex(&node_to->inputs, sock_to); + BLI_assert(index != -1); + node_from->locx = node_to->locx - (node_from->typeinfo->width + 50); + node_from->locy = node_to->locy - (node_from->typeinfo->height * index); + } node_link_item_apply(node_from, item); } diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c index 3491ecc86af..8c5d2d82468 100644 --- a/source/blender/editors/space_node/node_view.c +++ b/source/blender/editors/space_node/node_view.c @@ -292,7 +292,7 @@ void NODE_OT_backimage_move(wmOperatorType *ot) ot->cancel = snode_bg_viewmove_cancel; /* flags */ - ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER; + ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR; } static int backimage_zoom_exec(bContext *C, wmOperator *op) @@ -609,8 +609,11 @@ static int sample_modal(bContext *C, wmOperator *op, const wmEvent *event) switch (event->type) { case LEFTMOUSE: case RIGHTMOUSE: // XXX hardcoded - sample_exit(C, op); - return OPERATOR_CANCELLED; + if (event->val == KM_RELEASE) { + sample_exit(C, op); + return OPERATOR_CANCELLED; + } + break; case MOUSEMOVE: sample_apply(C, op, event); break; diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 62cb0bc73cd..de90c417bdd 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -203,12 +203,10 @@ void ED_node_tree_path_get_fixedbuf(SpaceNode *snode, char *value, int max_lengt value[0] = '\0'; for (path = snode->treepath.first, i = 0; path; path = path->next, ++i) { if (i == 0) { - BLI_strncpy(value, path->node_name, max_length); - size = strlen(path->node_name); + size = BLI_strncpy_rlen(value, path->node_name, max_length); } else { - BLI_snprintf(value, max_length, "/%s", path->node_name); - size = strlen(path->node_name) + 1; + size = BLI_snprintf_rlen(value, max_length, "/%s", path->node_name); } max_length -= size; if (max_length <= 0) |