[Bf-blender-cvs] [2e7e13442c9] master: Fix T76872: Mask created after existing keyframe gets broken handles

Sergey Sharybin noreply at git.blender.org
Mon Mar 29 16:19:41 CEST 2021


Commit: 2e7e13442c914a4e9610def67eb199ab40f6b2b1
Author: Sergey Sharybin
Date:   Mon Mar 29 16:11:33 2021 +0200
Branches: master
https://developer.blender.org/rB2e7e13442c914a4e9610def67eb199ab40f6b2b1

Fix T76872: Mask created after existing keyframe gets broken handles

The issue was caused by handles not being written to the new mask
spline shape: it was always written as (0, 0), which was making the
handle calculation go wrong later on.

Solved by allocating a temporary array of bezier points and calculating
handles for them. While this is an extra array allocation it is only
done for a small amount of points and it is not in the critical code
path. Having this as an extra array helps to overcome a limitation of
the current mask shape API.

Additionally, disable the interpolation for the shape change:
the spline is brand new, there is nothing to be interpolated there.

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

M	source/blender/editors/mask/mask_add.c

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

diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index 1226cc57359..36edbbe31d6 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -26,6 +26,7 @@
 #include "BLI_math.h"
 
 #include "BKE_context.h"
+#include "BKE_curve.h"
 #include "BKE_mask.h"
 
 #include "DEG_depsgraph.h"
@@ -692,6 +693,33 @@ void MASK_OT_add_feather_vertex(wmOperatorType *ot)
 
 /******************** common primitive functions *********************/
 
+static BezTriple *points_to_bezier(const float (*points)[2],
+                                   const int num_points,
+                                   const char handle_type,
+                                   const float scale,
+                                   const float location[2])
+{
+  BezTriple *bezier_points = MEM_calloc_arrayN(num_points, sizeof(BezTriple), __func__);
+  for (int i = 0; i < num_points; i++) {
+    copy_v2_v2(bezier_points[i].vec[1], points[i]);
+    mul_v2_fl(bezier_points[i].vec[1], scale);
+    add_v2_v2(bezier_points[i].vec[1], location);
+
+    bezier_points[i].h1 = handle_type;
+    bezier_points[i].h2 = handle_type;
+  }
+
+  for (int i = 0; i < num_points; i++) {
+    BKE_nurb_handle_calc(&bezier_points[i],
+                         &bezier_points[(i - 1 + num_points) % num_points],
+                         &bezier_points[(i + 1) % num_points],
+                         false,
+                         false);
+  }
+
+  return bezier_points;
+}
+
 static int create_primitive_from_points(
     bContext *C, wmOperator *op, const float (*points)[2], int num_points, char handle_type)
 {
@@ -734,25 +762,25 @@ static int create_primitive_from_points(
 
   const int spline_index = BKE_mask_layer_shape_spline_to_index(mask_layer, new_spline);
 
+  BezTriple *bezier_points = points_to_bezier(points, num_points, handle_type, scale, location);
+
   for (int i = 0; i < num_points; i++) {
     new_spline->tot_point = i + 1;
 
     MaskSplinePoint *new_point = &new_spline->points[i];
     BKE_mask_parent_init(&new_point->parent);
 
-    copy_v2_v2(new_point->bezt.vec[1], points[i]);
-    mul_v2_fl(new_point->bezt.vec[1], scale);
-    add_v2_v2(new_point->bezt.vec[1], location);
+    new_point->bezt = bezier_points[i];
 
-    new_point->bezt.h1 = handle_type;
-    new_point->bezt.h2 = handle_type;
     BKE_mask_point_select_set(new_point, true);
 
     if (mask_layer->splines_shapes.first) {
-      BKE_mask_layer_shape_changed_add(mask_layer, spline_index + i, true, true);
+      BKE_mask_layer_shape_changed_add(mask_layer, spline_index + i, true, false);
     }
   }
 
+  MEM_freeN(bezier_points);
+
   if (added_mask) {
     WM_event_add_notifier(C, NC_MASK | NA_ADDED, NULL);
   }



More information about the Bf-blender-cvs mailing list