VSE: Draw f-curves for opacity and volume values on the strips
authorRichard Antalik <richardantalik@gmail.com>
Sun, 5 Apr 2020 22:38:48 +0000 (00:38 +0200)
committerRichard Antalik <richardantalik@gmail.com>
Sun, 5 Apr 2020 22:52:29 +0000 (00:52 +0200)
Feature can be enabled or disabled in timeline view menu item "Show F-Curves".

Author a.monti

Reviewed By: ISS

Differential Revision: https://developer.blender.org/D7205

release/scripts/startup/bl_ui/space_sequencer.py
source/blender/blenloader/intern/versioning_280.c
source/blender/blenloader/intern/versioning_defaults.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/space_sequencer/space_sequencer.c
source/blender/makesdna/DNA_space_types.h
source/blender/makesrna/intern/rna_space.c

index f1a349d49b46f6d0fb1863ee47865082b9343a3f..c0a2b8a123000a57a9589b0e44ce14cee682c504 100644 (file)
@@ -309,6 +309,7 @@ class SEQUENCER_MT_view(Menu):
             layout.prop(st, "show_seconds")
             layout.prop(st, "show_locked_time")
             layout.prop(st, "show_strip_offset")
+            layout.prop(st, "show_fcurves")
             layout.separator()
             layout.prop(st, "show_markers")
 
index ff87756f436bf59a61a955fc98c621a686319dd7..a95cb74af5171187c7d6c4c3a7e816bc497d67c8 100644 (file)
@@ -665,6 +665,17 @@ static void do_versions_area_ensure_tool_region(Main *bmain,
         }
       }
     }
+    /* Activate fcurves drawing in the vse. */
+    for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+      for (ScrArea *area = screen->areabase.first; area; area = area->next) {
+        for (SpaceLink *sl = area->spacedata.first; sl; sl = sl->next) {
+          if (sl->spacetype == SPACE_SEQ) {
+            SpaceSeq *sseq = (SpaceSeq *)sl;
+            sseq->flag |= SEQ_SHOW_FCURVES;
+          }
+        }
+      }
+    }
   }
 }
 
index 035e6c88faa3385a5142365492d4eb8482757563..f4288b1d174b5c7ca0cfd156f215853515d91612 100644 (file)
@@ -174,7 +174,7 @@ static void blo_update_defaults_screen(bScreen *screen,
     }
     else if (area->spacetype == SPACE_SEQ) {
       SpaceSeq *seq = area->spacedata.first;
-      seq->flag |= SEQ_SHOW_MARKERS;
+      seq->flag |= SEQ_SHOW_MARKERS | SEQ_SHOW_FCURVES;
     }
     else if (area->spacetype == SPACE_TEXT) {
       /* Show syntax and line numbers in Script workspace text editor. */
index 2887113bdbee26be8ba6a0243e73b8cfd704d45f..a2f4ab001e2d5fd2e29ec3602362b276af7d5f06 100644 (file)
@@ -968,6 +968,99 @@ static void calculate_seq_text_offsets(
   }
 }
 
+static void fcurve_batch_add_verts(GPUVertBuf *vbo,
+                                   float y1,
+                                   float y2,
+                                   float y_height,
+                                   int cfra,
+                                   float curve_val,
+                                   unsigned int *vert_count)
+{
+  float vert_pos[2][2];
+
+  copy_v2_fl2(vert_pos[0], cfra, (curve_val * y_height) + y1);
+  copy_v2_fl2(vert_pos[1], cfra, y2);
+
+  GPU_vertbuf_vert_set(vbo, *vert_count, vert_pos[0]);
+  GPU_vertbuf_vert_set(vbo, *vert_count + 1, vert_pos[1]);
+  *vert_count += 2;
+}
+
+/* Draw f-curves as darkened regions of the strip.
+ *   - Volume for sound strips.
+ *   - Opacity for the other types. */
+static void draw_seq_fcurve(
+    Scene *scene, View2D *v2d, Sequence *seq, float x1, float y1, float x2, float y2, float pixelx)
+{
+  FCurve *fcu;
+
+  if (seq->type == SEQ_TYPE_SOUND_RAM) {
+    fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, NULL);
+  }
+  else {
+    fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "blend_alpha", 0, NULL);
+  }
+
+  if (fcu && !BKE_fcurve_is_empty(fcu)) {
+
+    /* Clamp curve evaluation to the editor's borders. */
+    int eval_start = max_ff(x1, v2d->cur.xmin);
+    int eval_end = min_ff(x2, v2d->cur.xmax + 1);
+
+    int eval_step = max_ii(1, floor(pixelx));
+
+    if (eval_start >= eval_end) {
+      return;
+    }
+
+    GPUVertFormat format = {0};
+    GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+    GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+
+    uint max_verts = 2 * ((eval_end - eval_start) / eval_step + 1);
+    GPU_vertbuf_data_alloc(vbo, max_verts);
+    uint vert_count = 0;
+
+    const float y_height = y2 - y1;
+    float curve_val;
+    float prev_val = INT_MIN;
+    bool skip = false;
+
+    for (int cfra = eval_start; cfra <= eval_end; cfra += eval_step) {
+      curve_val = evaluate_fcurve(fcu, cfra);
+      CLAMP(curve_val, 0.0f, 1.0f);
+
+      /* Avoid adding adjacent verts that have the same value. */
+      if (curve_val == prev_val && cfra < eval_end - eval_step) {
+        skip = true;
+        continue;
+      }
+
+      /* If some frames were skipped above, we need to close the shape.  */
+      if (skip) {
+        fcurve_batch_add_verts(vbo, y1, y2, y_height, cfra - eval_step, prev_val, &vert_count);
+        skip = false;
+      }
+
+      fcurve_batch_add_verts(vbo, y1, y2, y_height, cfra, curve_val, &vert_count);
+      prev_val = curve_val;
+    }
+
+    GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
+    GPU_vertbuf_data_len_set(vbo, vert_count);
+    GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
+    GPU_batch_uniform_4f(batch, "color", 0.0f, 0.0f, 0.0f, 0.15f);
+    GPU_blend(true);
+
+    if (vert_count > 0) {
+      GPU_batch_draw(batch);
+    }
+
+    GPU_blend(false);
+    GPU_batch_discard(batch);
+  }
+}
+
 /* Draw visible strips. */
 static void draw_seq_strip(const bContext *C,
                            SpaceSeq *sseq,
@@ -1024,6 +1117,10 @@ static void draw_seq_strip(const bContext *C,
     drawmeta_contents(scene, seq, x1, y1, x2, y2);
   }
 
+  if (sseq->flag & SEQ_SHOW_FCURVES) {
+    draw_seq_fcurve(scene, v2d, seq, x1, y1, x2, y2, pixelx);
+  }
+
   /* Draw sound strip waveform. */
   if ((seq->type == SEQ_TYPE_SOUND_RAM) && (sseq->flag & SEQ_NO_WAVEFORMS) == 0) {
     draw_seq_waveform(v2d,
index e40fe91ae999cf054d294837cbff35f348328953..f52cfdd34c099a042b1d7b9f3fe36657c7c92469 100644 (file)
@@ -96,7 +96,7 @@ static SpaceLink *sequencer_new(const ScrArea *UNUSED(area), const Scene *scene)
   sseq->chanshown = 0;
   sseq->view = SEQ_VIEW_SEQUENCE;
   sseq->mainb = SEQ_DRAW_IMG_IMBUF;
-  sseq->flag = SEQ_SHOW_GPENCIL | SEQ_USE_ALPHA | SEQ_SHOW_MARKERS;
+  sseq->flag = SEQ_SHOW_GPENCIL | SEQ_USE_ALPHA | SEQ_SHOW_MARKERS | SEQ_SHOW_FCURVES;
 
   /* Tool header. */
   region = MEM_callocN(sizeof(ARegion), "tool header for sequencer");
index 3020e5a170870103c71d91e9c54920081799b3cd..648d35c9a2df05ea00a3cd15f6223f0596ae0dfb 100644 (file)
@@ -606,7 +606,7 @@ typedef enum eSpaceSeq_Flag {
   SEQ_DRAW_COLOR_SEPARATED = (1 << 2),
   SEQ_SHOW_SAFE_MARGINS = (1 << 3),
   SEQ_SHOW_GPENCIL = (1 << 4),
-  /* SEQ_NO_DRAW_CFRANUM = (1 << 5), DEPRECATED */
+  SEQ_SHOW_FCURVES = (1 << 5),
   SEQ_USE_ALPHA = (1 << 6),     /* use RGBA display mode for preview */
   SEQ_ALL_WAVEFORMS = (1 << 7), /* draw all waveforms */
   SEQ_NO_WAVEFORMS = (1 << 8),  /* draw no waveforms */
index f69ba1a38c97bdadddcfcabd157ffd225d692edc..1f072d2eb2629531c6957ea48bd75fe39928f37c 100644 (file)
@@ -4831,6 +4831,11 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
   RNA_def_property_boolean_sdna(prop, NULL, "draw_flag", SEQ_DRAW_OFFSET_EXT);
   RNA_def_property_ui_text(prop, "Show Offsets", "Display strip in/out offsets");
   RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
+
+  prop = RNA_def_property(srna, "show_fcurves", PROP_BOOLEAN, PROP_NONE);
+  RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SHOW_FCURVES);
+  RNA_def_property_ui_text(prop, "Show F-Curves", "Display strip opacity/volume curve");
+  RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
 }
 
 static void rna_def_space_text(BlenderRNA *brna)