diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-10-09 12:49:27 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-10-09 12:49:27 +0300 |
commit | a5b4b0f21c1ae8c96e4fea9abdcfac2fab1cf300 (patch) | |
tree | 0658d8bdfb8ec03652aa04f82ee8a4d243ec6370 /source/blender/editors/space_node | |
parent | d68f698cf0321477c0734474150eb4bc43c4e85f (diff) | |
parent | abcda06934aba054de8540b66b13c2bbc5f8f515 (diff) |
Merge branch '28' into custom-manipulatorscustom-manipulators
Diffstat (limited to 'source/blender/editors/space_node')
-rw-r--r-- | source/blender/editors/space_node/drawnode.c | 11 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_draw.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_edit.c | 6 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_group.c | 11 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_intern.h | 3 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_manipulators.c | 503 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_relationships.c | 13 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_templates.c | 5 | ||||
-rw-r--r-- | source/blender/editors/space_node/space_node.c | 6 |
9 files changed, 536 insertions, 26 deletions
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index bee2379cd81..67584fbe1f1 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2154,8 +2154,9 @@ static void node_composit_backdrop_viewer(SpaceNode *snode, ImBuf *backdrop, bNo if (node->custom1 == 0) { const float backdropWidth = backdrop->x; const float backdropHeight = backdrop->y; - const float cx = x + snode->zoom * backdropWidth * node->custom3; + const float cx = x + snode->zoom * backdropWidth * node->custom3; const float cy = y + snode->zoom * backdropHeight * node->custom4; + const float cross_size = 12 * U.pixelsize; Gwn_VertFormat *format = immVertexFormat(); unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); @@ -2165,10 +2166,10 @@ static void node_composit_backdrop_viewer(SpaceNode *snode, ImBuf *backdrop, bNo immUniformColor3f(1.0f, 1.0f, 1.0f); immBegin(GWN_PRIM_LINES, 4); - immVertex2f(pos, cx - 25, cy - 25); - immVertex2f(pos, cx + 25, cy + 25); - immVertex2f(pos, cx + 25, cy - 25); - immVertex2f(pos, cx - 25, cy + 25); + immVertex2f(pos, cx - cross_size, cy - cross_size); + immVertex2f(pos, cx + cross_size, cy + cross_size); + immVertex2f(pos, cx + cross_size, cy - cross_size); + immVertex2f(pos, cx - cross_size, cy + cross_size); immEnd(); immUnbindProgram(); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index d99d1c97653..231039b2e22 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -716,7 +716,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformThemeColorShadeAlpha(TH_BACK, -15, +100); - imm_draw_line_box(pos, draw_rect.xmin, draw_rect.ymin, draw_rect.xmax, draw_rect.ymax); + imm_draw_box_wire_2d(pos, draw_rect.xmin, draw_rect.ymin, draw_rect.xmax, draw_rect.ymax); immUnbindProgram(); } @@ -1090,7 +1090,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b // BLI_snprintf(showname, sizeof(showname), "[%s]", showname); /* XXX - don't print into self! */ uiDefBut(node->block, UI_BTYPE_LABEL, 0, showname, - iroundf(rct->xmin + NODE_MARGIN_X), iroundf(centy - NODE_DY * 0.5f), + round_fl_to_int(rct->xmin + NODE_MARGIN_X), round_fl_to_int(centy - NODE_DY * 0.5f), (short)(BLI_rctf_size_x(rct) - 18.0f - 12.0f), (short)NODE_DY, NULL, 0, 0, 0, 0, ""); } diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 33382af9087..a8bf68d92e2 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -399,8 +399,8 @@ void ED_node_shader_default(const bContext *C, ID *id) ma->nodetree = ntree; if (BKE_scene_uses_blender_eevee(scene)) { - output_type = SH_NODE_OUTPUT_EEVEE_MATERIAL; - shader_type = SH_NODE_EEVEE_METALLIC; + output_type = SH_NODE_OUTPUT_MATERIAL; + shader_type = SH_NODE_BSDF_PRINCIPLED; } else if (BKE_scene_use_new_shading_nodes(scene)) { output_type = SH_NODE_OUTPUT_MATERIAL; @@ -1326,7 +1326,7 @@ static int node_read_fullsamplelayers_exec(bContext *C, wmOperator *UNUSED(op)) Main *bmain = CTX_data_main(C); SpaceNode *snode = CTX_wm_space_node(C); Scene *curscene = CTX_data_scene(C); - Render *re = RE_NewRender(curscene->id.name); + Render *re = RE_NewSceneRender(curscene); WM_cursor_wait(1); RE_MergeFullSample(re, bmain, curscene, snode->nodetree); diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c index 914f8ffbe10..9d750bfe348 100644 --- a/source/blender/editors/space_node/node_group.c +++ b/source/blender/editors/space_node/node_group.c @@ -37,6 +37,7 @@ #include "DNA_anim_types.h" #include "BLI_listbase.h" +#include "BLI_linklist.h" #include "BLI_math.h" #include "BLT_translation.h" @@ -186,6 +187,7 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode) bNode *node, *nextnode; bNodeTree *ngroup, *wgroup; ListBase anim_basepaths = {NULL, NULL}; + LinkNode *nodes_delayed_free = NULL; ngroup = (bNodeTree *)gnode->id; @@ -208,8 +210,8 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode) * This also removes remaining links to and from interface nodes. */ if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) { - nodeFreeNode(wgroup, node); - continue; + /* We must delay removal since sockets will reference this node. see: T52092 */ + BLI_linklist_prepend(&nodes_delayed_free, node); } /* keep track of this node's RNA "base" path (the part of the path identifying the node) @@ -336,6 +338,11 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode) } } + while (nodes_delayed_free) { + node = BLI_linklist_pop(&nodes_delayed_free); + nodeFreeNode(ntree, node); + } + /* delete the group instance */ nodeFreeNode(ntree, gnode); diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index b425a92f601..12e3c33007e 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -221,6 +221,9 @@ void NODE_OT_clear_viewer_border(struct wmOperatorType *ot); /* node_widgets.c */ void NODE_WGT_backdrop_transform(struct wmManipulatorGroupType *wgt); +void NODE_WGT_backdrop_crop(struct wmManipulatorGroupType *wgt); +void NODE_WGT_backdrop_sun_beams(struct wmManipulatorGroupType *wgt); +void NODE_WGT_backdrop_corner_pin(struct wmManipulatorGroupType *wgt); extern const char *node_context_dir[]; diff --git a/source/blender/editors/space_node/node_manipulators.c b/source/blender/editors/space_node/node_manipulators.c index 8b4ebd70874..8e736e47963 100644 --- a/source/blender/editors/space_node/node_manipulators.c +++ b/source/blender/editors/space_node/node_manipulators.c @@ -22,9 +22,14 @@ * \ingroup spnode */ +#include <math.h> + #include "BKE_context.h" #include "BKE_image.h" +#include "BLI_math_matrix.h" +#include "BLI_math_vector.h" + #include "ED_screen.h" #include "ED_manipulator_library.h" @@ -40,6 +45,66 @@ #include "node_intern.h" +/* -------------------------------------------------------------------- */ + +/** \name Local Utilities + * \{ */ + +static void node_manipulator_calc_matrix_space( + const SpaceNode *snode, const ARegion *ar, float matrix_space[4][4]) +{ + unit_m4(matrix_space); + mul_v3_fl(matrix_space[0], snode->zoom); + mul_v3_fl(matrix_space[1], snode->zoom); + matrix_space[3][0] = (ar->winx / 2) + snode->xof; + matrix_space[3][1] = (ar->winy / 2) + snode->yof; +} + +static void node_manipulator_calc_matrix_space_with_image_dims( + const SpaceNode *snode, const ARegion *ar, const float image_dims[2], float matrix_space[4][4]) +{ + unit_m4(matrix_space); + mul_v3_fl(matrix_space[0], snode->zoom * image_dims[0]); + mul_v3_fl(matrix_space[1], snode->zoom * image_dims[1]); + matrix_space[3][0] = ((ar->winx / 2) + snode->xof) - ((image_dims[0] / 2.0f) * snode->zoom); + matrix_space[3][1] = ((ar->winy / 2) + snode->yof) - ((image_dims[1] / 2.0f) * snode->zoom); +} + +/** \} */ + + + +/* -------------------------------------------------------------------- */ + +/** \name Backdrop Manipulator + * \{ */ + +static void manipulator_node_backdrop_prop_matrix_get( + const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop, + void *value_p) +{ + float (*matrix)[4] = value_p; + BLI_assert(mpr_prop->type->array_length == 16); + const SpaceNode *snode = mpr_prop->custom_func.user_data; + matrix[0][0] = snode->zoom; + matrix[1][1] = snode->zoom; + matrix[3][0] = snode->xof; + matrix[3][1] = snode->yof; +} + +static void manipulator_node_backdrop_prop_matrix_set( + const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop, + const void *value_p) +{ + const float (*matrix)[4] = value_p; + BLI_assert(mpr_prop->type->array_length == 16); + SpaceNode *snode = mpr_prop->custom_func.user_data; + snode->zoom = matrix[0][0]; + snode->zoom = matrix[1][1]; + snode->xof = matrix[3][0]; + snode->yof = matrix[3][1]; +} + static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) { SpaceNode *snode = CTX_wm_space_node(C); @@ -51,7 +116,7 @@ static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmManipulatorGrou if (snode && snode->edittree && snode->edittree->type == NTREE_COMPOSIT) { bNode *node = nodeGetActive(snode->edittree); - if (node && node->type == CMP_NODE_VIEWER) { + if (node && ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { return true; } } @@ -63,10 +128,10 @@ static void WIDGETGROUP_node_transform_setup(const bContext *UNUSED(C), wmManipu { wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__); - wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, "backdrop_cage", NULL); + wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, NULL); RNA_enum_set(wwrapper->manipulator->ptr, "transform", - ED_MANIPULATOR_RECT_TRANSFORM_FLAG_TRANSLATE | ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM); + ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE | ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM); mgroup->customdata = wwrapper; } @@ -94,10 +159,21 @@ static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmManipulatorG /* need to set property here for undo. TODO would prefer to do this in _init */ SpaceNode *snode = CTX_wm_space_node(C); +#if 0 PointerRNA nodeptr; RNA_pointer_create(snode->id, &RNA_SpaceNodeEditor, snode, &nodeptr); WM_manipulator_target_property_def_rna(cage, "offset", &nodeptr, "backdrop_offset", -1); WM_manipulator_target_property_def_rna(cage, "scale", &nodeptr, "backdrop_zoom", -1); +#endif + + WM_manipulator_target_property_def_func( + cage, "matrix", + &(const struct wmManipulatorPropertyFnParams) { + .value_get_fn = manipulator_node_backdrop_prop_matrix_get, + .value_set_fn = manipulator_node_backdrop_prop_matrix_set, + .range_get_fn = NULL, + .user_data = snode, + }); } else { WM_manipulator_set_flag(cage, WM_MANIPULATOR_HIDDEN, true); @@ -108,7 +184,7 @@ static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmManipulatorG void NODE_WGT_backdrop_transform(wmManipulatorGroupType *wgt) { - wgt->name = "Backdrop Transform Widgets"; + wgt->name = "Backdrop Transform Widget"; wgt->idname = "NODE_WGT_backdrop_transform"; wgt->flag |= WM_MANIPULATORGROUPTYPE_PERSISTENT; @@ -117,3 +193,422 @@ void NODE_WGT_backdrop_transform(wmManipulatorGroupType *wgt) wgt->setup = WIDGETGROUP_node_transform_setup; wgt->refresh = WIDGETGROUP_node_transform_refresh; } + +/** \} */ + +/* -------------------------------------------------------------------- */ + +/** \name Crop Manipulator + * \{ */ + +struct NodeCropWidgetGroup { + wmManipulator *border; + + struct { + float dims[2]; + } state; + + struct { + PointerRNA ptr; + PropertyRNA *prop; + bContext *context; + } update_data; +}; + +static void manipulator_node_crop_update(struct NodeCropWidgetGroup *crop_group) +{ + RNA_property_update(crop_group->update_data.context, &crop_group->update_data.ptr, crop_group->update_data.prop); +} + +static void two_xy_to_rect(const NodeTwoXYs *nxy, rctf *rect, const float dims[2], bool is_relative) +{ + if (is_relative) { + rect->xmin = nxy->fac_x1; + rect->xmax = nxy->fac_x2; + rect->ymin = nxy->fac_y1; + rect->ymax = nxy->fac_y2; + } + else { + rect->xmin = nxy->x1 / dims[0]; + rect->xmax = nxy->x2 / dims[0]; + rect->ymin = nxy->y1 / dims[1]; + rect->ymax = nxy->y2 / dims[1]; + } +} + +static void two_xy_from_rect(NodeTwoXYs *nxy, const rctf *rect, const float dims[2], bool is_relative) +{ + if (is_relative) { + nxy->fac_x1 = rect->xmin; + nxy->fac_x2 = rect->xmax; + nxy->fac_y1 = rect->ymin; + nxy->fac_y2 = rect->ymax; + } + else { + nxy->x1 = rect->xmin * dims[0]; + nxy->x2 = rect->xmax * dims[0]; + nxy->y1 = rect->ymin * dims[1]; + nxy->y2 = rect->ymax * dims[1]; + } +} + +/* scale callbacks */ +static void manipulator_node_crop_prop_matrix_get( + const wmManipulator *mpr, wmManipulatorProperty *mpr_prop, + void *value_p) +{ + float (*matrix)[4] = value_p; + BLI_assert(mpr_prop->type->array_length == 16); + struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata; + const float *dims = crop_group->state.dims; + const bNode *node = mpr_prop->custom_func.user_data; + const NodeTwoXYs *nxy = node->storage; + bool is_relative = (bool)node->custom2; + rctf rct; + two_xy_to_rect(nxy, &rct, dims, is_relative); + matrix[0][0] = BLI_rctf_size_x(&rct); + matrix[1][1] = BLI_rctf_size_y(&rct); + matrix[3][0] = (BLI_rctf_cent_x(&rct) - 0.5f) * dims[0]; + matrix[3][1] = (BLI_rctf_cent_y(&rct) - 0.5f) * dims[1]; +} + +static void manipulator_node_crop_prop_matrix_set( + const wmManipulator *mpr, wmManipulatorProperty *mpr_prop, + const void *value_p) +{ + const float (*matrix)[4] = value_p; + BLI_assert(mpr_prop->type->array_length == 16); + struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata; + const float *dims = crop_group->state.dims; + bNode *node = mpr_prop->custom_func.user_data; + NodeTwoXYs *nxy = node->storage; + bool is_relative = (bool)node->custom2; + rctf rct; + two_xy_to_rect(nxy, &rct, dims, is_relative); + BLI_rctf_resize(&rct, matrix[0][0], matrix[1][1]); + BLI_rctf_recenter(&rct, (matrix[3][0] / dims[0]) + 0.5f, (matrix[3][1] / dims[1]) + 0.5f); + BLI_rctf_isect(&(rctf){.xmin = 0, .ymin = 0, .xmax = 1, .ymax = 1}, &rct, &rct); + two_xy_from_rect(nxy, &rct, dims, is_relative); + manipulator_node_crop_update(crop_group); +} + +static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + + if ((snode->flag & SNODE_BACKDRAW) == 0) { + return false; + } + + if (snode && snode->edittree && snode->edittree->type == NTREE_COMPOSIT) { + bNode *node = nodeGetActive(snode->edittree); + + if (node && ELEM(node->type, CMP_NODE_CROP)) { + /* ignore 'use_crop_size', we can't usefully edit the crop in this case. */ + if ((node->custom1 & (0 << 1)) == 0) { + return true; + } + } + } + + return false; +} + +static void WIDGETGROUP_node_crop_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup) +{ + struct NodeCropWidgetGroup *crop_group = MEM_mallocN(sizeof(struct NodeCropWidgetGroup), __func__); + + crop_group->border = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, NULL); + + RNA_enum_set(crop_group->border->ptr, "transform", + ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE | ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE); + + mgroup->customdata = crop_group; +} + +static void WIDGETGROUP_node_crop_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup) +{ + ARegion *ar = CTX_wm_region(C); + wmManipulator *mpr = mgroup->manipulators.first; + + SpaceNode *snode = CTX_wm_space_node(C); + + node_manipulator_calc_matrix_space(snode, ar, mpr->matrix_space); +} + +static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmManipulatorGroup *mgroup) +{ + struct NodeCropWidgetGroup *crop_group = mgroup->customdata; + wmManipulator *mpr = crop_group->border; + + void *lock; + Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + + if (ibuf) { + crop_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f; + crop_group->state.dims[1] = (ibuf->y > 0) ? ibuf->y : 64.0f; + + RNA_float_set_array(mpr->ptr, "dimensions", crop_group->state.dims); + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, false); + + SpaceNode *snode = CTX_wm_space_node(C); + bNode *node = nodeGetActive(snode->edittree); + + crop_group->update_data.context = (bContext *)C; + RNA_pointer_create((ID *)snode->edittree, &RNA_CompositorNodeCrop, node, &crop_group->update_data.ptr); + crop_group->update_data.prop = RNA_struct_find_property(&crop_group->update_data.ptr, "relative"); + + WM_manipulator_target_property_def_func( + mpr, "matrix", + &(const struct wmManipulatorPropertyFnParams) { + .value_get_fn = manipulator_node_crop_prop_matrix_get, + .value_set_fn = manipulator_node_crop_prop_matrix_set, + .range_get_fn = NULL, + .user_data = node, + }); + } + else { + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, true); + } + + BKE_image_release_ibuf(ima, ibuf, lock); +} + +void NODE_WGT_backdrop_crop(wmManipulatorGroupType *wgt) +{ + wgt->name = "Backdrop Crop Widget"; + wgt->idname = "NODE_WGT_backdrop_crop"; + + wgt->flag |= WM_MANIPULATORGROUPTYPE_PERSISTENT; + + wgt->poll = WIDGETGROUP_node_crop_poll; + wgt->setup = WIDGETGROUP_node_crop_setup; + wgt->draw_prepare = WIDGETGROUP_node_crop_draw_prepare; + wgt->refresh = WIDGETGROUP_node_crop_refresh; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ + +/** \name Sun Beams + * \{ */ + +struct NodeSunBeamsWidgetGroup { + wmManipulator *manipulator; + + struct { + float dims[2]; + } state; +}; + +static bool WIDGETGROUP_node_sbeam_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + + if ((snode->flag & SNODE_BACKDRAW) == 0) { + return false; + } + + if (snode && snode->edittree && snode->edittree->type == NTREE_COMPOSIT) { + bNode *node = nodeGetActive(snode->edittree); + + if (node && ELEM(node->type, CMP_NODE_SUNBEAMS)) { + return true; + } + } + + return false; +} + +static void WIDGETGROUP_node_sbeam_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup) +{ + struct NodeSunBeamsWidgetGroup *sbeam_group = MEM_mallocN(sizeof(struct NodeSunBeamsWidgetGroup), __func__); + + sbeam_group->manipulator = WM_manipulator_new("MANIPULATOR_WT_grab_3d", mgroup, NULL); + wmManipulator *mpr = sbeam_group->manipulator; + + RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_CROSS_2D); + + mpr->scale_basis = 0.05f; + + mgroup->customdata = sbeam_group; +} + +static void WIDGETGROUP_node_sbeam_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup) +{ + struct NodeSunBeamsWidgetGroup *sbeam_group = mgroup->customdata; + ARegion *ar = CTX_wm_region(C); + wmManipulator *mpr = mgroup->manipulators.first; + + SpaceNode *snode = CTX_wm_space_node(C); + + node_manipulator_calc_matrix_space_with_image_dims(snode, ar, sbeam_group->state.dims, mpr->matrix_space); +} + +static void WIDGETGROUP_node_sbeam_refresh(const bContext *C, wmManipulatorGroup *mgroup) +{ + struct NodeSunBeamsWidgetGroup *sbeam_group = mgroup->customdata; + wmManipulator *mpr = sbeam_group->manipulator; + + void *lock; + Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + + if (ibuf) { + sbeam_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f; + sbeam_group->state.dims[1] = (ibuf->y > 0) ? ibuf->y : 64.0f; + + SpaceNode *snode = CTX_wm_space_node(C); + bNode *node = nodeGetActive(snode->edittree); + + /* need to set property here for undo. TODO would prefer to do this in _init */ + PointerRNA nodeptr; + RNA_pointer_create((ID *)snode->edittree, &RNA_CompositorNodeSunBeams, node, &nodeptr); + WM_manipulator_target_property_def_rna(mpr, "offset", &nodeptr, "source", -1); + + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_MODAL, true); + } + else { + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, true); + } + + BKE_image_release_ibuf(ima, ibuf, lock); +} + +void NODE_WGT_backdrop_sun_beams(wmManipulatorGroupType *wgt) +{ + wgt->name = "Sun Beams Widget"; + wgt->idname = "NODE_WGT_sbeam"; + + wgt->flag |= WM_MANIPULATORGROUPTYPE_PERSISTENT; + + wgt->poll = WIDGETGROUP_node_sbeam_poll; + wgt->setup = WIDGETGROUP_node_sbeam_setup; + wgt->draw_prepare = WIDGETGROUP_node_sbeam_draw_prepare; + wgt->refresh = WIDGETGROUP_node_sbeam_refresh; +} + +/** \} */ + + + +/* -------------------------------------------------------------------- */ + +/** \name Corner Pin + * \{ */ + +struct NodeCornerPinWidgetGroup { + wmManipulator *manipulators[4]; + + struct { + float dims[2]; + } state; +}; + +static bool WIDGETGROUP_node_corner_pin_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt)) +{ + SpaceNode *snode = CTX_wm_space_node(C); + + if ((snode->flag & SNODE_BACKDRAW) == 0) { + return false; + } + + if (snode && snode->edittree && snode->edittree->type == NTREE_COMPOSIT) { + bNode *node = nodeGetActive(snode->edittree); + + if (node && ELEM(node->type, CMP_NODE_CORNERPIN)) { + return true; + } + } + + return false; +} + +static void WIDGETGROUP_node_corner_pin_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup) +{ + struct NodeCornerPinWidgetGroup *cpin_group = MEM_mallocN(sizeof(struct NodeCornerPinWidgetGroup), __func__); + const wmManipulatorType *wt_grab_3d = WM_manipulatortype_find("MANIPULATOR_WT_grab_3d", false); + + for (int i = 0; i < 4; i++) { + cpin_group->manipulators[i] = WM_manipulator_new_ptr(wt_grab_3d, mgroup, NULL); + wmManipulator *mpr = cpin_group->manipulators[i]; + + RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_CROSS_2D); + + mpr->scale_basis = 0.01f; + } + + mgroup->customdata = cpin_group; +} + +static void WIDGETGROUP_node_corner_pin_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup) +{ + struct NodeCornerPinWidgetGroup *cpin_group = mgroup->customdata; + ARegion *ar = CTX_wm_region(C); + + SpaceNode *snode = CTX_wm_space_node(C); + + float matrix_space[4][4]; + node_manipulator_calc_matrix_space_with_image_dims(snode, ar, cpin_group->state.dims, matrix_space); + + for (int i = 0; i < 4; i++) { + wmManipulator *mpr = cpin_group->manipulators[i]; + copy_m4_m4(mpr->matrix_space, matrix_space); + } +} + +static void WIDGETGROUP_node_corner_pin_refresh(const bContext *C, wmManipulatorGroup *mgroup) +{ + struct NodeCornerPinWidgetGroup *cpin_group = mgroup->customdata; + + void *lock; + Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + + if (ibuf) { + cpin_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f; + cpin_group->state.dims[1] = (ibuf->y > 0) ? ibuf->y : 64.0f; + + SpaceNode *snode = CTX_wm_space_node(C); + bNode *node = nodeGetActive(snode->edittree); + + /* need to set property here for undo. TODO would prefer to do this in _init */ + int i = 0; + for (bNodeSocket *sock = node->inputs.first; sock && i < 4; sock = sock->next) { + if (sock->type == SOCK_VECTOR) { + wmManipulator *mpr = cpin_group->manipulators[i++]; + + PointerRNA sockptr; + RNA_pointer_create((ID *)snode->edittree, &RNA_NodeSocket, sock, &sockptr); + WM_manipulator_target_property_def_rna(mpr, "offset", &sockptr, "default_value", -1); + + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_MODAL, true); + } + } + } + else { + for (int i = 0; i < 4; i++) { + wmManipulator *mpr = cpin_group->manipulators[i]; + WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, true); + } + } + + BKE_image_release_ibuf(ima, ibuf, lock); +} + +void NODE_WGT_backdrop_corner_pin(wmManipulatorGroupType *wgt) +{ + wgt->name = "Corner Pin Widget"; + wgt->idname = "NODE_WGT_backdrop_corner_pin"; + + wgt->flag |= WM_MANIPULATORGROUPTYPE_PERSISTENT; + + wgt->poll = WIDGETGROUP_node_corner_pin_poll; + wgt->setup = WIDGETGROUP_node_corner_pin_setup; + wgt->draw_prepare = WIDGETGROUP_node_corner_pin_draw_prepare; + wgt->refresh = WIDGETGROUP_node_corner_pin_refresh; +} + +/** \} */ diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c index 5f592431558..3b03399a5e7 100644 --- a/source/blender/editors/space_node/node_relationships.c +++ b/source/blender/editors/space_node/node_relationships.c @@ -567,7 +567,13 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links) ntree->is_updating = true; for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { bNodeLink *link = linkdata->data; - + + /* 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; + if (apply_links && link->tosock && link->fromsock) { /* before actually adding the link, * let nodes perform special link insertion handling @@ -593,11 +599,6 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links) } } 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); } } diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index ec525e684b0..5d0877a1eff 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -683,10 +683,11 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree, RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr); /* indented label */ - for (i = 0; i < indent; i++) + for (i = 0; i < indent; i++) { label[i] = ' '; + } label[indent] = '\0'; - BLI_snprintf(label, UI_MAX_NAME_STR, "%s%s:", label, IFACE_(input->name)); + BLI_snprintf(label + indent, UI_MAX_NAME_STR - indent, "%s:", IFACE_(input->name)); /* split in label and value */ split = uiLayoutSplit(layout, 0.35f, false); diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index c1099f38d92..7cb22dcc570 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -49,8 +49,6 @@ #include "ED_node.h" #include "ED_render.h" #include "ED_screen.h" -#include "WM_api.h" -#include "WM_types.h" #include "UI_resources.h" #include "UI_view2d.h" @@ -58,6 +56,7 @@ #include "RNA_access.h" #include "WM_api.h" +#include "WM_types.h" #include "node_intern.h" /* own include */ @@ -866,6 +865,9 @@ static void node_widgets(void) wmManipulatorMapType *mmap_type = WM_manipulatormaptype_ensure( &(const struct wmManipulatorMapType_Params){SPACE_NODE, RGN_TYPE_WINDOW}); WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_transform); + WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_crop); + WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_sun_beams); + WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_corner_pin); } static void node_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) |