Commit: 8c74ebb64f883701aecd291e5543b0f27ded8764
Author: Campbell Barton
Date:   Mon Aug 1 09:01:43 2016 +1000
Branches: master
https://developer.blender.org/rB8c74ebb64f883701aecd291e5543b0f27ded8764

Support Auto-Clamped Handle for Curve-Mapping

This patch supports auto-clamped handles for curves,
useful since without this it can be difficult to have 'flat' sections of a 
curve.

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

M       source/blender/blenkernel/BKE_colortools.h
M       source/blender/blenkernel/intern/colortools.c
M       source/blender/editors/interface/interface_templates.c
M       source/blender/makesdna/DNA_color_types.h
M       source/blender/makesrna/intern/rna_color.c

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

diff --git a/source/blender/blenkernel/BKE_colortools.h 
b/source/blender/blenkernel/BKE_colortools.h
index e5d3480..5b4f591 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -61,7 +61,7 @@ void                    curvemap_reset(struct CurveMap *cuma, 
const struct rctf
 void                    curvemap_remove(struct CurveMap *cuma, const short 
flag);
 bool                    curvemap_remove_point(struct CurveMap *cuma, struct 
CurveMapPoint *cmp);
 struct CurveMapPoint   *curvemap_insert(struct CurveMap *cuma, float x, float 
y);
-void                    curvemap_sethandle(struct CurveMap *cuma, int type);
+void                    curvemap_handle_set(struct CurveMap *cuma, int type);
 
 void                curvemapping_changed(struct CurveMapping *cumap, const 
bool rem_doubles);
 void                curvemapping_changed_all(struct CurveMapping *cumap);
diff --git a/source/blender/blenkernel/intern/colortools.c 
b/source/blender/blenkernel/intern/colortools.c
index 53a7402..4f3ffed 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -293,8 +293,8 @@ void curvemap_reset(CurveMap *cuma, const rctf *clipr, int 
preset, int slope)
                        cuma->curve[1].x = clipr->xmax;
                        cuma->curve[1].y = clipr->ymin;
                        if (slope == CURVEMAP_SLOPE_POS_NEG) {
-                               cuma->curve[0].flag |= CUMA_VECTOR;
-                               cuma->curve[1].flag |= CUMA_VECTOR;
+                               cuma->curve[0].flag |= CUMA_HANDLE_VECTOR;
+                               cuma->curve[1].flag |= CUMA_HANDLE_VECTOR;
                        }
                        break;
                case CURVE_PRESET_SHARP:
@@ -391,15 +391,25 @@ void curvemap_reset(CurveMap *cuma, const rctf *clipr, 
int preset, int slope)
        }
 }
 
-/* if type==1: vector, else auto */
-void curvemap_sethandle(CurveMap *cuma, int type)
+/**
+ * \param type: eBezTriple_Handle
+ */
+void curvemap_handle_set(CurveMap *cuma, int type)
 {
        int a;
        
        for (a = 0; a < cuma->totpoint; a++) {
                if (cuma->curve[a].flag & CUMA_SELECT) {
-                       if (type) cuma->curve[a].flag |= CUMA_VECTOR;
-                       else cuma->curve[a].flag &= ~CUMA_VECTOR;
+                       cuma->curve[a].flag &= ~(CUMA_HANDLE_VECTOR | 
CUMA_HANDLE_AUTO_ANIM);
+                       if (type == HD_VECT) {
+                               cuma->curve[a].flag |= CUMA_HANDLE_VECTOR;
+                       }
+                       else if (type == HD_AUTO_ANIM) {
+                               cuma->curve[a].flag |= CUMA_HANDLE_AUTO_ANIM;
+                       }
+                       else {
+                               /* pass */
+                       }
                }
        }
 }
@@ -457,7 +467,7 @@ static void calchandle_curvemap(
        if (len_a == 0.0f) len_a = 1.0f;
        if (len_b == 0.0f) len_b = 1.0f;
 
-       if (bezt->h1 == HD_AUTO || bezt->h2 == HD_AUTO) { /* auto */
+       if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) || ELEM(bezt->h2, HD_AUTO, 
HD_AUTO_ANIM)) {    /* auto */
                float tvec[2];
                tvec[0] = dvec_b[0] / len_b + dvec_a[0] / len_a;
                tvec[1] = dvec_b[1] / len_b + dvec_a[1] / len_a;
@@ -465,13 +475,57 @@ static void calchandle_curvemap(
                len = len_v2(tvec) * 2.5614f;
                if (len != 0.0f) {
                        
-                       if (bezt->h1 == HD_AUTO) {
+                       if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) {
                                len_a /= len;
                                madd_v2_v2v2fl(p2_h1, p2, tvec, -len_a);
+
+                               if ((bezt->h1 == HD_AUTO_ANIM) && next && prev) 
{ /* keep horizontal if extrema */
+                                       const float ydiff1 = prev->vec[1][1] - 
bezt->vec[1][1];
+                                       const float ydiff2 = next->vec[1][1] - 
bezt->vec[1][1];
+                                       if ((ydiff1 <= 0.0f && ydiff2 <= 0.0f) 
||
+                                           (ydiff1 >= 0.0f && ydiff2 >= 0.0f))
+                                       {
+                                               bezt->vec[0][1] = 
bezt->vec[1][1];
+                                       }
+                                       else { /* handles should not be beyond 
y coord of two others */
+                                               if (ydiff1 <= 0.0f) {
+                                                       if (prev->vec[1][1] > 
bezt->vec[0][1]) {
+                                                               bezt->vec[0][1] 
= prev->vec[1][1];
+                                                       }
+                                               }
+                                               else {
+                                                       if (prev->vec[1][1] < 
bezt->vec[0][1]) {
+                                                               bezt->vec[0][1] 
= prev->vec[1][1];
+                                                       }
+                                               }
+                                       }
+                               }
                        }
-                       if (bezt->h2 == HD_AUTO) {
+                       if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) {
                                len_b /= len;
                                madd_v2_v2v2fl(p2_h2, p2, tvec,  len_b);
+
+                               if ((bezt->h2 == HD_AUTO_ANIM) && next && prev) 
{ /* keep horizontal if extrema */
+                                       const float ydiff1 = prev->vec[1][1] - 
bezt->vec[1][1];
+                                       const float ydiff2 = next->vec[1][1] - 
bezt->vec[1][1];
+                                       if ((ydiff1 <= 0.0f && ydiff2 <= 0.0f)||
+                                           (ydiff1 >= 0.0f && ydiff2 >= 0.0f))
+                                       {
+                                               bezt->vec[2][1] = 
bezt->vec[1][1];
+                                       }
+                                       else { /* handles should not be beyond 
y coord of two others */
+                                               if (ydiff1 <= 0.0f) {
+                                                       if (next->vec[1][1] < 
bezt->vec[2][1]) {
+                                                               bezt->vec[2][1] 
= next->vec[1][1];
+                                                       }
+                                               }
+                                               else {
+                                                       if (next->vec[1][1] > 
bezt->vec[2][1]) {
+                                                               bezt->vec[2][1] 
= next->vec[1][1];
+                                                       }
+                                               }
+                                       }
+                               }
                        }
                }
        }
@@ -540,10 +594,15 @@ static void curvemap_make_table(CurveMap *cuma, const 
rctf *clipr)
                cuma->maxtable = max_ff(cuma->maxtable, cmp[a].x);
                bezt[a].vec[1][0] = cmp[a].x;
                bezt[a].vec[1][1] = cmp[a].y;
-               if (cmp[a].flag & CUMA_VECTOR)
+               if (cmp[a].flag & CUMA_HANDLE_VECTOR) {
                        bezt[a].h1 = bezt[a].h2 = HD_VECT;
-               else
+               }
+               else if (cmp[a].flag & CUMA_HANDLE_AUTO_ANIM) {
+                       bezt[a].h1 = bezt[a].h2 = HD_AUTO_ANIM;
+               }
+               else {
                        bezt[a].h1 = bezt[a].h2 = HD_AUTO;
+               }
        }
        
        const BezTriple *bezt_prev = NULL;
@@ -773,12 +832,12 @@ void curvemapping_changed(CurveMapping *cumap, const bool 
rem_doubles)
                        dy = cmp[a].y - cmp[a + 1].y;
                        if (sqrtf(dx * dx + dy * dy) < thresh) {
                                if (a == 0) {
-                                       cmp[a + 1].flag |= CUMA_VECTOR;
+                                       cmp[a + 1].flag |= CUMA_HANDLE_VECTOR;
                                        if (cmp[a + 1].flag & CUMA_SELECT)
                                                cmp[a].flag |= CUMA_SELECT;
                                }
                                else {
-                                       cmp[a].flag |= CUMA_VECTOR;
+                                       cmp[a].flag |= CUMA_HANDLE_VECTOR;
                                        if (cmp[a].flag & CUMA_SELECT)
                                                cmp[a + 1].flag |= CUMA_SELECT;
                                }
diff --git a/source/blender/editors/interface/interface_templates.c 
b/source/blender/editors/interface/interface_templates.c
index aec4065..58cadf5 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -1940,6 +1940,7 @@ enum {
        UICURVE_FUNC_RESET_VIEW,
        UICURVE_FUNC_HANDLE_VECTOR,
        UICURVE_FUNC_HANDLE_AUTO,
+       UICURVE_FUNC_HANDLE_AUTO_ANIM,
        UICURVE_FUNC_EXTEND_HOZ,
        UICURVE_FUNC_EXTEND_EXP,
 };
@@ -1960,13 +1961,16 @@ static void curvemap_tools_dofunc(bContext *C, void 
*cumap_v, int event)
                        cumap->curr = cumap->clipr;
                        break;
                case UICURVE_FUNC_HANDLE_VECTOR: /* set vector */
-                       curvemap_sethandle(cuma, 1);
+                       curvemap_handle_set(cuma, HD_VECT);
                        curvemapping_changed(cumap, false);
                        break;
                case UICURVE_FUNC_HANDLE_AUTO: /* set auto */
-                       curvemap_sethandle(cuma, 0);
+                       curvemap_handle_set(cuma, HD_AUTO);
                        curvemapping_changed(cumap, false);
                        break;
+               case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* set auto-clamped */
+                       curvemap_handle_set(cuma, HD_AUTO_ANIM);
+                       curvemapping_changed(cumap, false);
                case UICURVE_FUNC_EXTEND_HOZ: /* extend horiz */
                        cuma->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
                        curvemapping_changed(cumap, false);
@@ -2000,6 +2004,9 @@ static uiBlock *curvemap_tools_func(
                uiDefIconTextBut(
                        block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Auto 
Handle"),
                        0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 
0.0, 0, UICURVE_FUNC_HANDLE_AUTO, "");
+               uiDefIconTextBut(
+                       block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Auto 
Clamped Handle"),
+                       0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 
0.0, 0, UICURVE_FUNC_HANDLE_AUTO_ANIM, "");
        }
 
        if (show_extend) {
diff --git a/source/blender/makesdna/DNA_color_types.h 
b/source/blender/makesdna/DNA_color_types.h
index 1d88b01..f7ee1ff 100644
--- a/source/blender/makesdna/DNA_color_types.h
+++ b/source/blender/makesdna/DNA_color_types.h
@@ -49,7 +49,8 @@ typedef struct CurveMapPoint {
 /* curvepoint->flag */
 enum {
        CUMA_SELECT = 1,
-       CUMA_VECTOR = 2
+       CUMA_HANDLE_VECTOR = 2,
+       CUMA_HANDLE_AUTO_ANIM = 4,
 };
 
 typedef struct CurveMap {
diff --git a/source/blender/makesrna/intern/rna_color.c 
b/source/blender/makesrna/intern/rna_color.c
index 78e3bbe..24f2d81 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -690,7 +690,8 @@ static void rna_def_curvemappoint(BlenderRNA *brna)
        PropertyRNA *prop;
        static EnumPropertyItem prop_handle_type_items[] = {
                {0, "AUTO", 0, "Auto Handle", ""},
-               {CUMA_VECTOR, "VECTOR", 0, "Vector Handle", ""},
+               {CUMA_HANDLE_AUTO_ANIM, "AUTO_CLAMPED", 0, "Auto Clamped 
Handle", ""},
+               {CUMA_HANDLE_VECTOR, "VECTOR", 0, "Vector Handle", ""},
                {0, NULL, 0, NULL, NULL}
        };

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

Reply via email to