[Bf-blender-cvs] [657e3443517] master: GPencil: Bake mesh animation for selected keyframes only

Antonio Vazquez noreply at git.blender.org
Wed Oct 21 19:17:06 CEST 2020


Commit: 657e344351740daf97ff28f4fc53d448e3de75ee
Author: Antonio Vazquez
Date:   Wed Oct 21 19:15:18 2020 +0200
Branches: master
https://developer.blender.org/rB657e344351740daf97ff28f4fc53d448e3de75ee

GPencil: Bake mesh animation for selected keyframes only

This new option allows to bake the animation of the selected frames and not the full range of keyframes.

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

M	release/scripts/startup/bl_operators/gpencil_mesh_bake.py
M	source/blender/editors/gpencil/gpencil_mesh.c

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

diff --git a/release/scripts/startup/bl_operators/gpencil_mesh_bake.py b/release/scripts/startup/bl_operators/gpencil_mesh_bake.py
index d4b1b11ed69..251e0af5854 100644
--- a/release/scripts/startup/bl_operators/gpencil_mesh_bake.py
+++ b/release/scripts/startup/bl_operators/gpencil_mesh_bake.py
@@ -99,6 +99,11 @@ class GPENCIL_OT_mesh_bake(Operator):
         description="Export faces as filled strokes",
         default=True,
     )
+    only_selected: BoolProperty(
+        name="Only Selected Keyframes",
+        description="Convert only selected keyframes",
+        default=False,
+    )
     target: EnumProperty(
         name="Target Object",
         description="Grease Pencil Object",
@@ -139,6 +144,7 @@ class GPENCIL_OT_mesh_bake(Operator):
             thickness=self.thickness,
             seams=self.seams,
             faces=self.faces,
+            only_selected=self.only_selected,
             offset=self.offset,
             target=self.target,
             frame_target=self.frame_target,
diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c
index e4862617d12..7cf4325d03b 100644
--- a/source/blender/editors/gpencil/gpencil_mesh.c
+++ b/source/blender/editors/gpencil/gpencil_mesh.c
@@ -25,12 +25,15 @@
 #include "MEM_guardedalloc.h"
 
 #include "BLI_blenlib.h"
+#include "BLI_ghash.h"
 #include "BLI_math.h"
 
+#include "DNA_anim_types.h"
 #include "DNA_gpencil_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 
+#include "BKE_anim_data.h"
 #include "BKE_context.h"
 #include "BKE_duplilist.h"
 #include "BKE_global.h"
@@ -86,6 +89,35 @@ typedef struct GpBakeOb {
   Object *ob;
 } GpBakeOb;
 
+/* Get list of keyframes used by selected objects. */
+static void animdata_keyframe_list_get(ListBase *ob_list,
+                                       const bool only_selected,
+                                       GHash *r_keyframes)
+{
+  /* Loop all objects to get the list of keyframes used. */
+  LISTBASE_FOREACH (GpBakeOb *, elem, ob_list) {
+    Object *ob = elem->ob;
+    AnimData *adt = BKE_animdata_from_id(&ob->id);
+    if ((adt == NULL) || (adt->action == NULL)) {
+      continue;
+    }
+    LISTBASE_FOREACH (FCurve *, fcurve, &adt->action->curves) {
+      int i;
+      BezTriple *bezt;
+      for (i = 0, bezt = fcurve->bezt; i < fcurve->totvert; i++, bezt++) {
+        /* Keyframe number is x value of point. */
+        if ((bezt->f2 & SELECT) || (!only_selected)) {
+          /* Insert only one key for each keyframe number. */
+          int key = (int)bezt->vec[1][0];
+          if (!BLI_ghash_haskey(r_keyframes, POINTER_FROM_INT(key))) {
+            BLI_ghash_insert(r_keyframes, POINTER_FROM_INT(key), POINTER_FROM_INT(key));
+          }
+        }
+      }
+    }
+  }
+}
+
 static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *list)
 {
   GpBakeOb *elem = NULL;
@@ -161,13 +193,13 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
   View3D *v3d = CTX_wm_view3d(C);
   Object *ob_gpencil = NULL;
 
-  ListBase list = {NULL, NULL};
-  gpencil_bake_ob_list(C, depsgraph, scene, &list);
+  ListBase ob_selected_list = {NULL, NULL};
+  gpencil_bake_ob_list(C, depsgraph, scene, &ob_selected_list);
 
   /* Cannot check this in poll because the active object changes. */
-  if (list.first == NULL) {
+  if (ob_selected_list.first == NULL) {
     BKE_report(op->reports, RPT_INFO, "No valid object selected");
-    gpencil_bake_free_ob_list(&list);
+    gpencil_bake_free_ob_list(&ob_selected_list);
     return OPERATOR_CANCELLED;
   }
 
@@ -186,6 +218,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
   const int thickness = RNA_int_get(op->ptr, "thickness");
   const bool use_seams = RNA_boolean_get(op->ptr, "seams");
   const bool use_faces = RNA_boolean_get(op->ptr, "faces");
+  const bool only_selected = RNA_boolean_get(op->ptr, "only_selected");
   const float offset = RNA_float_get(op->ptr, "offset");
   const int frame_offset = RNA_int_get(op->ptr, "frame_target") - frame_start;
   char target[64];
@@ -206,7 +239,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
 
   if ((ob_gpencil == NULL) || (ob_gpencil->type != OB_GPENCIL)) {
     BKE_report(op->reports, RPT_ERROR, "Target grease pencil object not valid");
-    gpencil_bake_free_ob_list(&list);
+    gpencil_bake_free_ob_list(&ob_selected_list);
     return OPERATOR_CANCELLED;
   }
 
@@ -237,6 +270,13 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
   /* Loop all frame range. */
   int oldframe = (int)DEG_get_ctime(depsgraph);
   int key = -1;
+
+  /* Get list of keyframes. */
+  GHash *keyframe_list = BLI_ghash_int_new(__func__);
+  if (only_selected) {
+    animdata_keyframe_list_get(&ob_selected_list, only_selected, keyframe_list);
+  }
+
   for (int i = frame_start; i < frame_end + 1; i++) {
     key++;
     /* Jump if not step limit but include last frame always. */
@@ -244,12 +284,17 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
       continue;
     }
 
+    /* Check if frame is in the list of frames to be exported. */
+    if ((only_selected) && (!BLI_ghash_haskey(keyframe_list, POINTER_FROM_INT(i)))) {
+      continue;
+    }
+
     /* Move scene to new frame. */
     CFRA = i;
     BKE_scene_graph_update_for_newframe(depsgraph);
 
     /* Loop all objects in the list. */
-    LISTBASE_FOREACH (GpBakeOb *, elem, &list) {
+    LISTBASE_FOREACH (GpBakeOb *, elem, &ob_selected_list) {
       Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, elem->ob);
 
       /* Generate strokes. */
@@ -270,13 +315,14 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
       if (project_type != GP_REPROJECT_KEEP) {
         LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
           bGPDframe *gpf = gpl->actframe;
-          if (gpf != NULL) {
-            LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
-              if ((gps->flag & GP_STROKE_TAG) == 0) {
-                ED_gpencil_stroke_reproject(
-                    depsgraph, &gsc, sctx, gpl, gpf, gps, project_type, false);
-                gps->flag |= GP_STROKE_TAG;
-              }
+          if (gpf == NULL) {
+            continue;
+          }
+          LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+            if ((gps->flag & GP_STROKE_TAG) == 0) {
+              ED_gpencil_stroke_reproject(
+                  depsgraph, &gsc, sctx, gpl, gpf, gps, project_type, false);
+              gps->flag |= GP_STROKE_TAG;
             }
           }
         }
@@ -314,10 +360,14 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
   }
 
   /* Free memory. */
-  gpencil_bake_free_ob_list(&list);
+  gpencil_bake_free_ob_list(&ob_selected_list);
   if (sctx != NULL) {
     ED_transform_snap_object_context_destroy(sctx);
   }
+  /* Free temp hash table. */
+  if (keyframe_list != NULL) {
+    BLI_ghash_free(keyframe_list, NULL, NULL);
+  }
 
   /* notifiers */
   if (newob) {
@@ -394,6 +444,8 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
   RNA_def_int(ot->srna, "thickness", 1, 1, 100, "Thickness", "", 1, 100);
   RNA_def_boolean(ot->srna, "seams", 0, "Only Seam Edges", "Convert only seam edges");
   RNA_def_boolean(ot->srna, "faces", 1, "Export Faces", "Export faces as filled strokes");
+  RNA_def_boolean(
+      ot->srna, "only_selected", 0, "Only Selected Keyframes", "Convert only selected keyframes");
   RNA_def_float_distance(
       ot->srna, "offset", 0.001f, 0.0, 100.0, "Offset", "Offset strokes from fill", 0.0, 100.00);
   RNA_def_int(ot->srna, "frame_target", 1, 1, 100000, "Frame Target", "", 1, 100000);



More information about the Bf-blender-cvs mailing list