fix for error setting vector handles to free when both vector handles were selected...
authorCampbell Barton <ideasman42@gmail.com>
Tue, 1 Oct 2013 08:18:43 +0000 (08:18 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 1 Oct 2013 08:18:43 +0000 (08:18 +0000)
only one of the handles would be changed to the HD_FREE.

effected curves and fcurves.

source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/BKE_fcurve.h
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/fcurve.c
source/blender/editors/animation/keyframes_edit.c
source/blender/editors/space_view3d/view3d_buttons.c
source/blender/editors/space_view3d/view3d_snap.c
source/blender/editors/transform/transform_conversions.c

index ac114a62de6a646b1199889b141197b51a6b8d6c..07116979eab2703d3c48d3dcb5bb7a6b591addd1 100644 (file)
@@ -155,6 +155,7 @@ void BKE_nurb_handle_calc_simple(struct Nurb *nu, struct BezTriple *bezt);
 
 void BKE_nurb_handles_calc(struct Nurb *nu);
 void BKE_nurb_handles_autocalc(struct Nurb *nu, int flag);
-void BKE_nurb_handles_test(struct Nurb *nu);
+void BKE_nurb_bezt_handle_test(struct BezTriple *bezt, const bool use_handle);
+void BKE_nurb_handles_test(struct Nurb *nu, const bool use_handles);
 
 #endif  /* __BKE_CURVE_H__ */
index 64a6811bf519a1527351ce4017502de0d64a0c4e..6e64c2f60c56c7c14f45c80b0c22099ccda4875d 100644 (file)
@@ -234,7 +234,7 @@ short fcurve_is_keyframable(struct FCurve *fcu);
 /* -------- Curve Sanity --------  */
 
 void calchandles_fcurve(struct FCurve *fcu);
-void testhandles_fcurve(struct FCurve *fcu, const short use_handle);
+void testhandles_fcurve(struct FCurve *fcu, const bool use_handle);
 void sort_time_fcurve(struct FCurve *fcu);
 short test_time_fcurve(struct FCurve *fcu);
 
index 02b35794d28bb8a5597ac086a8daf2e1e709fb33..bfe575575b57e0796f4936a25c7d42b97fcc270f 100644 (file)
@@ -3102,46 +3102,67 @@ void BKE_nurb_handle_calc_simple(Nurb *nu, BezTriple *bezt)
        }
 }
 
-void BKE_nurb_handles_test(Nurb *nu)
-{
-       /* use when something has changed with handles.
-        * it treats all BezTriples with the following rules:
-        * PHASE 1: do types have to be altered?
-        *    Auto handles: become aligned when selection status is NOT(000 || 111)
-        *    Vector handles: become 'nothing' when (one half selected AND other not)
-        * PHASE 2: recalculate handles
-        */
-       BezTriple *bezt;
-       short flag, a;
+/**
+ * Use when something has changed handle positions.
+ *
+ * The caller needs to recalculate handles.
+ */
+void BKE_nurb_bezt_handle_test(BezTriple *bezt, const bool use_handle)
+{
+       short flag = 0;
 
-       if (nu->type != CU_BEZIER) return;
+#define SEL_F1 (1 << 0)
+#define SEL_F2 (1 << 1)
+#define SEL_F3 (1 << 2)
 
-       bezt = nu->bezt;
-       a = nu->pntsu;
-       while (a--) {
-               flag = 0;
-               if (bezt->f1 & SELECT)
-                       flag++;
-               if (bezt->f2 & SELECT)
-                       flag += 2;
-               if (bezt->f3 & SELECT)
-                       flag += 4;
+       if (use_handle) {
+               if (bezt->f1 & SELECT) flag |= SEL_F1;
+               if (bezt->f2 & SELECT) flag |= SEL_F2;
+               if (bezt->f3 & SELECT) flag |= SEL_F3;
+       }
+       else {
+               flag = (bezt->f2 & SELECT) ? (SEL_F1 | SEL_F2 | SEL_F3) : 0;
+       }
 
-               if (!(flag == 0 || flag == 7) ) {
-                       if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) {   /* auto */
-                               bezt->h1 = HD_ALIGN;
-                       }
-                       if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) {   /* auto */
-                               bezt->h2 = HD_ALIGN;
-                       }
+       /* check for partial selection */
+       if (!ELEM(flag, 0, SEL_F1 | SEL_F2 | SEL_F3)) {
+               if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) {
+                       bezt->h1 = HD_ALIGN;
+               }
+               if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) {
+                       bezt->h2 = HD_ALIGN;
+               }
 
-                       if (bezt->h1 == HD_VECT) {   /* vector */
-                               if (flag < 4) bezt->h1 = 0;
+               if (bezt->h1 == HD_VECT) {
+                       if ((!(flag & SEL_F1)) != (!(flag & SEL_F2))) {
+                               bezt->h1 = HD_FREE;
                        }
-                       if (bezt->h2 == HD_VECT) {   /* vector */
-                               if (flag > 3) bezt->h2 = 0;
+               }
+               if (bezt->h2 == HD_VECT) {
+                       if ((!(flag & SEL_F3)) != (!(flag & SEL_F2))) {
+                               bezt->h2 = HD_FREE;
                        }
                }
+       }
+
+#undef SEL_F1
+#undef SEL_F2
+#undef SEL_F3
+
+}
+
+void BKE_nurb_handles_test(Nurb *nu, const bool use_handle)
+{
+       BezTriple *bezt;
+       short a;
+
+       if (nu->type != CU_BEZIER)
+               return;
+
+       bezt = nu->bezt;
+       a = nu->pntsu;
+       while (a--) {
+               BKE_nurb_bezt_handle_test(bezt, use_handle);
                bezt++;
        }
 
@@ -3168,7 +3189,7 @@ void BKE_nurb_handles_autocalc(Nurb *nu, int flag)
 
                /* left handle: */
                if (flag == 0 || (bezt1->f1 & flag) ) {
-                       bezt1->h1 = 0;
+                       bezt1->h1 = HD_FREE;
                        /* distance too short: vectorhandle */
                        if (len_v3v3(bezt1->vec[1], bezt0->vec[1]) < 0.0001f) {
                                bezt1->h1 = HD_VECT;
@@ -3187,7 +3208,7 @@ void BKE_nurb_handles_autocalc(Nurb *nu, int flag)
                }
                /* right handle: */
                if (flag == 0 || (bezt1->f3 & flag) ) {
-                       bezt1->h2 = 0;
+                       bezt1->h2 = HD_FREE;
                        /* distance too short: vectorhandle */
                        if (len_v3v3(bezt1->vec[1], bezt2->vec[1]) < 0.0001f) {
                                bezt1->h2 = HD_VECT;
@@ -3203,15 +3224,15 @@ void BKE_nurb_handles_autocalc(Nurb *nu, int flag)
                        }
                }
                if (leftsmall && bezt1->h2 == HD_ALIGN)
-                       bezt1->h2 = 0;
+                       bezt1->h2 = HD_FREE;
                if (rightsmall && bezt1->h1 == HD_ALIGN)
-                       bezt1->h1 = 0;
+                       bezt1->h1 = HD_FREE;
 
                /* undesired combination: */
                if (bezt1->h1 == HD_ALIGN && bezt1->h2 == HD_VECT)
-                       bezt1->h1 = 0;
+                       bezt1->h1 = HD_FREE;
                if (bezt1->h2 == HD_ALIGN && bezt1->h1 == HD_VECT)
-                       bezt1->h2 = 0;
+                       bezt1->h2 = HD_FREE;
 
                bezt0 = bezt1;
                bezt1 = bezt2;
index 791c47cc551f335192ea33ddc50e4598a1365953..88539814c52b94b83db0681056b580eabca4c53f 100644 (file)
@@ -841,14 +841,7 @@ void calchandles_fcurve(FCurve *fcu)
        }
 }
 
-/* Use when F-Curve with handles has changed
- * It treats all BezTriples with the following rules:
- *  - PHASE 1: do types have to be altered?
- *      -> Auto handles: become aligned when selection status is NOT(000 || 111)
- *      -> Vector handles: become 'nothing' when (one half selected AND other not)
- *  - PHASE 2: recalculate handles
- */
-void testhandles_fcurve(FCurve *fcu, const short use_handle)
+void testhandles_fcurve(FCurve *fcu, const bool use_handle)
 {
        BezTriple *bezt;
        unsigned int a;
@@ -856,45 +849,10 @@ void testhandles_fcurve(FCurve *fcu, const short use_handle)
        /* only beztriples have handles (bpoints don't though) */
        if (ELEM(NULL, fcu, fcu->bezt))
                return;
-       
+
        /* loop over beztriples */
        for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) {
-               short flag = 0;
-               
-               /* flag is initialized as selection status
-                * of beztriple control-points (labelled 0, 1, 2)
-                */
-               if (bezt->f2 & SELECT) flag |= (1 << 1);  // == 2
-               if (use_handle == FALSE) {
-                       if (flag & 2) {
-                               flag |= (1 << 0) | (1 << 2);
-                       }
-               }
-               else {
-                       if (bezt->f1 & SELECT) flag |= (1 << 0);  // == 1
-                       if (bezt->f3 & SELECT) flag |= (1 << 2);  // == 4
-               }
-               
-               /* one or two handles selected only */
-               if (ELEM(flag, 0, 7) == 0) {
-                       /* auto handles become aligned */
-                       if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM))
-                               bezt->h1 = HD_ALIGN;
-                       if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM))
-                               bezt->h2 = HD_ALIGN;
-                       
-                       /* vector handles become 'free' when only one half selected */
-                       if (bezt->h1 == HD_VECT) {
-                               /* only left half (1 or 2 or 1+2) */
-                               if (flag < 4) 
-                                       bezt->h1 = 0;
-                       }
-                       if (bezt->h2 == HD_VECT) {
-                               /* only right half (4 or 2+4) */
-                               if (flag > 3) 
-                                       bezt->h2 = 0;
-                       }
-               }
+               BKE_nurb_bezt_handle_test(bezt, use_handle);
        }
 
        /* recalculate handles */
index decbc351cad3fa04edae66182aad209a7e16012c..71717284d8e1173174413f533f20944d47d358f7 100644 (file)
@@ -396,7 +396,7 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac)
        int filter;
        /* when not in graph view, don't use handles */
        SpaceIpo *sipo = (ac->spacetype == SPACE_IPO) ? (SpaceIpo *)ac->sl : NULL;
-       const short use_handle = sipo ? !(sipo->flag & SIPO_NOHANDLES) : FALSE;
+       const bool use_handle = sipo ? !(sipo->flag & SIPO_NOHANDLES) : false;
        
        /* filter animation data */
        filter = ANIMFILTER_DATA_VISIBLE;
index 75e7605df6b434a50cb87b152f2eeb3167063f6f..eea084b47505bcf62a960a74daadcc2d1c33a87a 100644 (file)
@@ -682,7 +682,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
                                        }
                                }
                                BKE_nurb_test2D(nu);
-                               BKE_nurb_handles_test(nu); /* test for bezier too */
+                               BKE_nurb_handles_test(nu, true); /* test for bezier too */
 
                                nu = nu->next;
                        }
index 5f988edb9504a8fd8f881d462544a61db3767c56..7c29ab01c246559f1e87457a07c61f7eebf128b2 100644 (file)
@@ -143,7 +143,7 @@ static void special_transvert_update(Object *obedit)
                                }
 
                                BKE_nurb_test2D(nu);
-                               BKE_nurb_handles_test(nu); /* test for bezier too */
+                               BKE_nurb_handles_test(nu, true); /* test for bezier too */
                                nu = nu->next;
                        }
                }
index 7110e7a66c51ddab11a5a01105e1c30987599188..35896f65668347ece662ffda21607449f79bea2f 100644 (file)
@@ -1571,7 +1571,7 @@ static void createTransCurveVerts(TransInfo *t)
                         * but for now just don't change handle types */
                        if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT) == 0) {
                                /* sets the handles based on their selection, do this after the data is copied to the TransData */
-                               BKE_nurb_handles_test(nu);
+                               BKE_nurb_handles_test(nu, !hide_handles);
                        }
                }
                else {