Commit: d7905dab6a858570258daf4a502820b340a52dbc
Author: Campbell Barton
Date:   Fri Aug 4 16:45:33 2017 +1000
Branches: blender2.8
https://developer.blender.org/rBd7905dab6a858570258daf4a502820b340a52dbc

Manipulator: add compositor crop manipulator

===================================================================

M       source/blender/editors/space_node/node_intern.h
M       source/blender/editors/space_node/node_manipulators.c
M       source/blender/editors/space_node/space_node.c
M       source/blender/editors/space_view3d/view3d_manipulator_camera.c

===================================================================

diff --git a/source/blender/editors/space_node/node_intern.h 
b/source/blender/editors/space_node/node_intern.h
index b425a92f601..7e8d092cdbe 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -221,6 +221,7 @@ 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);
 
 
 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 7bc029ea660..8f614137a84 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,11 @@
 #include "node_intern.h"
 
 
+/* -------------------------------------------------------------------- */
+
+/** \name Backdrop Manipulator
+ * \{ */
+
 static bool WIDGETGROUP_node_transform_poll(const bContext *C, 
wmManipulatorGroupType *UNUSED(wgt))
 {
        SpaceNode *snode = CTX_wm_space_node(C);
@@ -51,7 +61,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;
                }
        }
@@ -108,7 +118,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 +127,249 @@ 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_size_get(
+        const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+        void *value_p)
+{
+       float *value = value_p;
+       struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata;
+       const float *dims = crop_group->state.dims;
+       BLI_assert(mpr_prop->type->array_length == 2);
+       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);
+       value[0] = BLI_rctf_size_x(&rct);
+       value[1] = BLI_rctf_size_y(&rct);
+}
+
+static void manipulator_node_crop_prop_size_set(
+        const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+        const void *value_p)
+{
+       const float *value = value_p;
+       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;
+       BLI_assert(mpr_prop->type->array_length == 2);
+       rctf rct;
+       two_xy_to_rect(nxy, &rct, dims, is_relative);
+       BLI_rctf_resize(&rct, value[0], value[1]);
+       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);
+}
+
+/* offset callbacks */
+static void manipulator_node_crop_prop_offset_get(
+        const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+        void *value_p)
+{
+       float *value = value_p;
+       struct NodeCropWidgetGroup *crop_group = mpr->parent_mgroup->customdata;
+       const float *dims = crop_group->state.dims;
+       BLI_assert(mpr_prop->type->array_length == 2);
+       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);
+       value[0] = (BLI_rctf_cent_x(&rct) - 0.5f) * dims[0];
+       value[1] = (BLI_rctf_cent_y(&rct) - 0.5f) * dims[1];
+}
+
+static void manipulator_node_crop_prop_offset_set(
+        const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+        const void *value_p)
+{
+       const float *value = value_p;
+       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;
+       BLI_assert(mpr_prop->type->array_length == 2);
+       rctf rct;
+       two_xy_to_rect(nxy, &rct, dims, is_relative);
+       BLI_rctf_recenter(&rct, (value[0] / dims[0]) + 0.5f, (value[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_RECT_TRANSFORM_FLAG_TRANSLATE | 
ED_MANIPULATOR_RECT_TRANSFORM_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);
+
+       unit_m4(mpr->matrix_space);
+       mul_v3_fl(mpr->matrix_space[0], snode->zoom);
+       mul_v3_fl(mpr->matrix_space[1], snode->zoom);
+       mpr->matrix_space[3][0] = (ar->winx / 2) + snode->xof;
+       mpr->matrix_space[3][1] = (ar->winy / 2) + snode->yof;
+}
+
+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, "offset",
+                       &(const struct wmManipulatorPropertyFnParams) {
+                           .value_get_fn = 
manipulator_node_crop_prop_offset_get,
+                           .value_set_fn = 
manipulator_node_crop_prop_offset_set,
+                           .range_get_fn = NULL,
+                           .user_data = node,
+                       });
+
+               WM_manipulator_target_property_def_func(
+                       mpr, "scale",
+                       &(const struct wmManipulatorPropertyFnParams) {
+                           .value_get_fn = manipulator_node_crop_prop_size_get,
+                           .value_set_fn = manipulator_node_crop_prop_size_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_p

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to