[Bf-blender-cvs] [c99d7677350] master: Fix some naming and comments in F-Curve smoothing code.

Alexander Gavrilov noreply at git.blender.org
Sat Nov 28 13:57:31 CET 2020


Commit: c99d76773509516f1543190d422fb3be4c3021a4
Author: Alexander Gavrilov
Date:   Sat Nov 28 14:50:03 2020 +0300
Branches: master
https://developer.blender.org/rBc99d76773509516f1543190d422fb3be4c3021a4

Fix some naming and comments in F-Curve smoothing code.

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

M	source/blender/blenkernel/intern/curve.c
M	source/blender/blenkernel/intern/fcurve.c
M	source/blender/makesdna/DNA_curve_types.h

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

diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 091d542c43d..3ad94853078 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -3205,7 +3205,7 @@ static void calchandleNurb_intern(BezTriple *bezt,
   const float eps = 1e-5;
 
   /* assume normal handle until we check */
-  bezt->f5 = HD_AUTOTYPE_NORMAL;
+  bezt->auto_handle_type = HD_AUTOTYPE_NORMAL;
 
   if (bezt->h1 == 0 && bezt->h2 == 0) {
     return;
@@ -3298,7 +3298,7 @@ static void calchandleNurb_intern(BezTriple *bezt,
           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];
-            bezt->f5 = HD_AUTOTYPE_SPECIAL;
+            bezt->auto_handle_type = HD_AUTOTYPE_LOCKED_FINAL;
           }
           else { /* handles should not be beyond y coord of two others */
             if (ydiff1 <= 0.0f) {
@@ -3325,7 +3325,7 @@ static void calchandleNurb_intern(BezTriple *bezt,
           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];
-            bezt->f5 = HD_AUTOTYPE_SPECIAL;
+            bezt->auto_handle_type = HD_AUTOTYPE_LOCKED_FINAL;
           }
           else { /* handles should not be beyond y coord of two others */
             if (ydiff1 <= 0.0f) {
@@ -3673,24 +3673,33 @@ static bool tridiagonal_solve_with_limits(float *a,
  * |    |      |          |            |        |
  * |    |      |          |            |        |
  * |    |      |          |            |        |
- * |-------t1---------t2--------- ~ --------tN-------------------> time (co 0)
+ * |------dx1--------dx2--------- ~ -------dxN-------------------> time (co 0)
+ *
+ * Notation:
+ *
+ *   x[i], y[i] - keyframe coordinates
+ *   h[i]       - right handle y offset from y[i]
+ *
+ *   dx[i] = x[i] - x[i-1]
+ *   dy[i] = y[i] - y[i-1]
+ *
  * Mathematical basis:
  *
  * 1. Handle lengths on either side of each point are connected by a factor
  *    ensuring continuity of the first derivative:
  *
- *    l[i] = t[i+1]/t[i]
+ *    l[i] = dx[i+1]/dx[i]
  *
  * 2. The tridiagonal system is formed by the following equation, which is derived
  *    by differentiating the bezier curve and specifies second derivative continuity
  *    at every point:
  *
- *    l[i]^2 * h[i-1] + (2*l[i]+2) * h[i] + 1/l[i+1] * h[i+1] = (y[i]-y[i-1])*l[i]^2 + y[i+1]-y[i]
+ *    l[i]^2 * h[i-1] + (2*l[i]+2) * h[i] + 1/l[i+1] * h[i+1] = dy[i]*l[i]^2 + dy[i+1]
  *
  * 3. If this point is adjacent to a manually set handle with X size not equal to 1/3
  *    of the horizontal interval, this equation becomes slightly more complex:
  *
- *    l[i]^2 * h[i-1] + (3*(1-R[i-1])*l[i] + 3*(1-L[i+1])) * h[i] + 1/l[i+1] * h[i+1] = (y[i]-y[i-1])*l[i]^2 + y[i+1]-y[i]
+ *    l[i]^2 * h[i-1] + (3*(1-R[i-1])*l[i] + 3*(1-L[i+1])) * h[i] + 1/l[i+1] * h[i+1] = dy[i]*l[i]^2 + dy[i+1]
  *
  *    The difference between equations amounts to this, and it's obvious that when R[i-1]
  *    and L[i+1] are both 1/3, it becomes zero:
@@ -3699,6 +3708,14 @@ static bool tridiagonal_solve_with_limits(float *a,
  *
  * 4. The equations for zero acceleration border conditions are basically the above
  *    equation with parts omitted, so the handle size correction also applies.
+ *
+ * 5. The fully cyclic curve case is handled by eliminating one of the end points,
+ *    and instead of border conditions connecting the curve via a set of equations:
+ *
+ *    l[0] = l[N] = dx[1] / dx[N]
+ *    dy[0] = dy[N]
+ *    Continuity equation (item 2) for i = 0.
+ *    Substitute h[0] for h[N] and h[N-1] for h[-1]
  */
 /* clang-format on */
 
@@ -3801,8 +3818,8 @@ static void bezier_output_handle(BezTriple *bezt, bool right, float dy, bool end
 
 static bool bezier_check_solve_end_handle(BezTriple *bezt, char htype, bool end)
 {
-  return (htype == HD_VECT) ||
-         (end && ELEM(htype, HD_AUTO, HD_AUTO_ANIM) && bezt->f5 == HD_AUTOTYPE_NORMAL);
+  return (htype == HD_VECT) || (end && ELEM(htype, HD_AUTO, HD_AUTO_ANIM) &&
+                                bezt->auto_handle_type == HD_AUTOTYPE_NORMAL);
 }
 
 static float bezier_calc_handle_adj(float hsize[2], float dx)
@@ -3995,7 +4012,7 @@ static void bezier_handle_calc_smooth_fcurve(
 
 static bool is_free_auto_point(BezTriple *bezt)
 {
-  return BEZT_IS_AUTOH(bezt) && bezt->f5 == HD_AUTOTYPE_NORMAL;
+  return BEZT_IS_AUTOH(bezt) && bezt->auto_handle_type == HD_AUTOTYPE_NORMAL;
 }
 
 void BKE_nurb_handle_smooth_fcurve(BezTriple *bezt, int total, bool cyclic)
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index bcd2fe098b7..ce710e2f7d4 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1285,14 +1285,14 @@ void calchandles_fcurve_ex(FCurve *fcu, eBezTriple_Flag handle_sel_flag)
         if (fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) {
           bezt->vec[0][1] = bezt->vec[2][1] = bezt->vec[1][1];
           /* Remember that these keyframes are special, they don't need to be adjusted. */
-          bezt->f5 = HD_AUTOTYPE_SPECIAL;
+          bezt->auto_handle_type = HD_AUTOTYPE_LOCKED_FINAL;
         }
       }
     }
 
     /* Avoid total smoothing failure on duplicate keyframes (can happen during grab). */
     if (prev && prev->vec[1][0] >= bezt->vec[1][0]) {
-      prev->f5 = bezt->f5 = HD_AUTOTYPE_SPECIAL;
+      prev->auto_handle_type = bezt->auto_handle_type = HD_AUTOTYPE_LOCKED_FINAL;
     }
 
     /* Advance pointers for next iteration. */
@@ -1309,10 +1309,11 @@ void calchandles_fcurve_ex(FCurve *fcu, eBezTriple_Flag handle_sel_flag)
   }
 
   /* If cyclic extrapolation and Auto Clamp has triggered, ensure it is symmetric. */
-  if (cycle && (first->f5 != HD_AUTOTYPE_NORMAL || last->f5 != HD_AUTOTYPE_NORMAL)) {
+  if (cycle && (first->auto_handle_type != HD_AUTOTYPE_NORMAL ||
+                last->auto_handle_type != HD_AUTOTYPE_NORMAL)) {
     first->vec[0][1] = first->vec[2][1] = first->vec[1][1];
     last->vec[0][1] = last->vec[2][1] = last->vec[1][1];
-    first->f5 = last->f5 = HD_AUTOTYPE_SPECIAL;
+    first->auto_handle_type = last->auto_handle_type = HD_AUTOTYPE_LOCKED_FINAL;
   }
 
   /* Do a second pass for auto handle: compute the handle to have 0 acceleration step. */
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 372cfb225fa..3bf58203bef 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -133,8 +133,8 @@ typedef struct BezTriple {
   /** BEZT_IPO_ELASTIC. */
   float amplitude, period;
 
-  /** F5: used for auto handle to distinguish between normal handle and exception (extrema). */
-  char f5;
+  /** Used during auto handle calculation to mark special cases (local extremes). */
+  char auto_handle_type;
   char _pad[3];
 } BezTriple;
 
@@ -465,10 +465,14 @@ typedef enum eBezTriple_Handle {
   HD_ALIGN_DOUBLESIDE = 5, /* align handles, displayed both of them. used for masks */
 } eBezTriple_Handle;
 
-/* f5 (beztriple) */
+/* auto_handle_type (beztriple) */
 typedef enum eBezTriple_Auto_Type {
+  /* Normal automatic handle that can be refined further. */
   HD_AUTOTYPE_NORMAL = 0,
-  HD_AUTOTYPE_SPECIAL = 1,
+  /* Handle locked horizontal due to being an Auto Clamped local
+   * extreme or a curve endpoint with Constant extrapolation.
+   * Further smoothing is disabled. */
+  HD_AUTOTYPE_LOCKED_FINAL = 1,
 } eBezTriple_Auto_Type;
 
 /* interpolation modes (used only for BezTriple->ipo) */



More information about the Bf-blender-cvs mailing list