[Bf-blender-cvs] [98e5a7c8a50] temp-vse-transform-overwrite: VSE: Transform overwrite mode
Richard Antalik
noreply at git.blender.org
Tue Aug 10 09:50:23 CEST 2021
Commit: 98e5a7c8a50eb348a7790d717d09061887a1f58c
Author: Richard Antalik
Date: Tue Aug 10 03:37:45 2021 +0200
Branches: temp-vse-transform-overwrite
https://developer.blender.org/rB98e5a7c8a50eb348a7790d717d09061887a1f58c
VSE: Transform overwrite mode
Add mode to overwrite strips on overlap instead of resolving overlap.
When overlap is created, 3 things can happen:
- On partial overlap, handles of overlapped strip are moved
- On complete overlap with smaller strip, overlapped strip is split
- On complete overlap with larger strip, overlapped strip is removed
This mode can be enabled in header.
---
Demonstration:
{F10226243}
Reviewed By: mano-wii
Differential Revision: https://developer.blender.org/D11805
===================================================================
M release/scripts/startup/bl_ui/space_sequencer.py
M source/blender/editors/transform/transform_convert_sequencer.c
M source/blender/editors/transform/transform_mode_edge_seq_slide.c
M source/blender/makesdna/DNA_scene_types.h
M source/blender/makesrna/intern/rna_scene.c
M source/blender/sequencer/SEQ_iterator.h
M source/blender/sequencer/SEQ_sequencer.h
M source/blender/sequencer/intern/iterator.c
M source/blender/sequencer/intern/sequencer.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 20fb39e8c1f..80fd47c0207 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -150,6 +150,9 @@ class SEQUENCER_HT_header(Header):
if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
tool_settings = context.tool_settings
+ sequencer_tool_settings = tool_settings.sequencer_tool_settings
+ row = layout.row(align=True)
+ row.prop(sequencer_tool_settings, "use_overwrite_mode", text="Overwrite Mode")
row = layout.row(align=True)
row.prop(tool_settings, "use_snap_sequencer", text="")
sub = row.row(align=True)
diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c
index 17512c79d03..5dec10059aa 100644
--- a/source/blender/editors/transform/transform_convert_sequencer.c
+++ b/source/blender/editors/transform/transform_convert_sequencer.c
@@ -27,12 +27,16 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_rect.h"
#include "BKE_context.h"
+#include "BKE_main.h"
#include "BKE_report.h"
#include "ED_markers.h"
+#include "SEQ_edit.h"
+#include "SEQ_effects.h"
#include "SEQ_iterator.h"
#include "SEQ_relations.h"
#include "SEQ_sequencer.h"
@@ -299,7 +303,20 @@ static SeqCollection *extract_standalone_strips(SeqCollection *transformed_strip
return collection;
}
-/* Query strips positioned after left edge of transformed strips boundbox. */
+static void seq_collection_boundbox(SeqCollection *collection, rcti *r_boundbox)
+{
+ BLI_rcti_init(r_boundbox, MAXFRAME, MINFRAME, INT_MAX, 0);
+
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, collection) {
+ r_boundbox->xmin = min_ii(r_boundbox->xmin, seq->startdisp);
+ r_boundbox->xmax = max_ii(r_boundbox->xmax, seq->enddisp);
+ r_boundbox->ymin = min_ii(r_boundbox->ymin, seq->machine);
+ r_boundbox->ymax = max_ii(r_boundbox->ymax, seq->machine);
+ }
+}
+
+/* Query strips positioned after left edge of transformed strips r_boundbox. */
static SeqCollection *query_right_side_strips(ListBase *seqbase, SeqCollection *transformed_strips)
{
int minframe = MAXFRAME;
@@ -341,12 +358,17 @@ static bool seq_transform_check_strip_effects(SeqCollection *transformed_strips)
return false;
}
-/* Offset all strips positioned after left edge of transformed strips boundbox by amount equal
+static ListBase *seqbase_from_trans_info(TransInfo *t)
+{
+ Editing *ed = SEQ_editing_get(t->scene, false);
+ return SEQ_active_seqbase_get(ed);
+}
+
+/* Offset all strips positioned after left edge of transformed strips r_boundbox by amount equal
* to overlap of transformed strips. */
static void seq_transform_handle_expand_to_fit(TransInfo *t, SeqCollection *transformed_strips)
{
- Editing *ed = SEQ_editing_get(t->scene, false);
- ListBase *seqbasep = SEQ_active_seqbase_get(ed);
+ ListBase *seqbasep = seqbase_from_trans_info(t);
ListBase *markers = &t->scene->markers;
const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag &
SEQ_MARKER_TRANS) != 0;
@@ -378,23 +400,192 @@ static void seq_transform_handle_expand_to_fit(TransInfo *t, SeqCollection *tran
SEQ_collection_free(right_side_strips);
}
+static SeqCollection *query_overwrite_targets(TransInfo *t, SeqCollection *transformed_strips)
+{
+ rcti transformed_boundbox;
+ seq_collection_boundbox(transformed_strips, &transformed_boundbox);
+ SeqCollection *collection = SEQ_query_unselected_strips(seqbase_from_trans_info(t));
+
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, collection) {
+ if (seq->enddisp < transformed_boundbox.xmin || seq->startdisp > transformed_boundbox.xmax) {
+ SEQ_collection_remove_strip(seq, collection);
+ }
+ }
+
+ /* In some cases effects of transformed strips are not selected. These must not be included. */
+ SEQ_ITERATOR_FOREACH (seq, transformed_strips) {
+ SEQ_collection_remove_strip(seq, collection);
+ }
+
+ return collection;
+}
+
+static bool is_same_channel(Sequence *transformed, Sequence *target)
+{
+ if (transformed->machine == target->machine) {
+ return true;
+ }
+ return false;
+}
+
+static bool is_full_overlap(Sequence *transformed, Sequence *target)
+{
+ if (transformed->startdisp <= target->startdisp && transformed->enddisp >= target->enddisp) {
+ return true;
+ }
+ return false;
+}
+
+static bool is_inside_overlap(Sequence *transformed, Sequence *target)
+{
+ if (transformed->startdisp > target->startdisp && transformed->enddisp < target->enddisp) {
+ return true;
+ }
+ return false;
+}
+
+typedef enum ePartialOvelapSide {
+ LEFT_SIDE_OVERLAP,
+ RIGHT_SIDE_OVERLAP,
+} ePartialOvelapSide;
+
+static bool is_partial_overlap(Sequence *transformed, Sequence *target, ePartialOvelapSide *r_side)
+{
+ if (transformed->startdisp <= target->startdisp && target->startdisp <= transformed->enddisp) {
+ *r_side = LEFT_SIDE_OVERLAP;
+ return true;
+ }
+ if (transformed->startdisp <= target->enddisp && target->enddisp <= transformed->enddisp) {
+ *r_side = RIGHT_SIDE_OVERLAP;
+ return true;
+ }
+ return false;
+}
+
+static void seq_transform_handle_overwrite_split(TransInfo *t,
+ Sequence *transformed,
+ Sequence *target)
+{
+ Main *bmain = CTX_data_main(t->context);
+ Scene *scene = t->scene;
+ ListBase *seqbase = seqbase_from_trans_info(t);
+
+ Sequence *split_strip = SEQ_edit_strip_split(
+ bmain, scene, seqbase, target, transformed->startdisp, SEQ_SPLIT_SOFT);
+ SEQ_edit_strip_split(bmain, scene, seqbase, split_strip, transformed->enddisp, SEQ_SPLIT_SOFT);
+ SEQ_edit_flag_for_removal(scene, seqbase_from_trans_info(t), split_strip);
+}
+
+/* BUG must handle overlap with non-effect more gracefully. */
+
+/* Trim strips by adjusting handle position.
+ * This is bit more complicated in case overlap happens on effect. */
+static void seq_transform_handle_overwrite_trim(TransInfo *t,
+ Sequence *transformed,
+ Sequence *target,
+ ePartialOvelapSide overlap_side)
+{
+ SeqCollection *targets = SEQ_collection_create(__func__);
+ SEQ_collection_append_strip(target, targets);
+
+ /* Expand collection by adding all target's children, effects and their children. */
+ if ((target->type & SEQ_TYPE_EFFECT) != 0) {
+ SEQ_collection_expand(seqbase_from_trans_info(t), targets, SEQ_query_strip_effect_chain);
+ }
+
+ /* Trim all non effects, that have influence on effect length which is overlapping. */
+ Sequence *seq;
+ SEQ_ITERATOR_FOREACH (seq, targets) {
+ if (SEQ_effect_get_num_inputs(seq->type) > 0) {
+ continue;
+ }
+ if (is_partial_overlap(transformed, seq, &overlap_side)) {
+ if (overlap_side == LEFT_SIDE_OVERLAP) {
+ SEQ_transform_set_left_handle_frame(seq, transformed->enddisp);
+ }
+ if (overlap_side == RIGHT_SIDE_OVERLAP) {
+ SEQ_transform_set_right_handle_frame(seq, transformed->startdisp);
+ }
+ }
+ SEQ_time_update_sequence(t->scene, seq);
+ }
+
+ SEQ_collection_free(targets);
+
+ /* Recalculate all effects influenced by target. */
+ SeqCollection *effects = SEQ_query_by_reference(
+ target, seqbase_from_trans_info(t), SEQ_query_strip_effect_chain);
+ SEQ_ITERATOR_FOREACH (seq, effects) {
+ SEQ_time_update_sequence(t->scene, seq);
+ }
+ SEQ_collection_free(effects);
+}
+
+static void seq_transform_handle_overwrite(TransInfo *t, SeqCollection *transformed_strips)
+{
+ SeqCollection *targets = query_overwrite_targets(t, transformed_strips);
+
+ ePartialOvelapSide overlap_side;
+ bool strips_delete = false;
+ Sequence *target;
+ Sequence *transformed;
+ SEQ_ITERATOR_FOREACH (target, targets) {
+ SEQ_ITERATOR_FOREACH (transformed, transformed_strips) {
+ if (!is_same_channel(transformed, target)) {
+ continue;
+ }
+
+ /* Remove covered strip. */
+ if (is_full_overlap(transformed, target)) {
+ SEQ_edit_flag_for_removal(t->scene, seqbase_from_trans_info(t), target);
+ strips_delete = true;
+ }
+ /* Split strip in 3 parts, remove middle part and fit transformed inside. */
+ else if (is_inside_overlap(transformed, target)) {
+ seq_transform_handle_overwrite_split(t, transformed, target);
+ strips_delete = true;
+ }
+ /* Nove handle by amount of overlap. */
+ else if (is_partial_overlap(transformed, target, &overlap_side)) {
+ seq_transform_handle_overwrite_trim(t, transformed, target, overlap_side);
+ }
+ }
+ }
+
+ SEQ_collection_free(targets);
+
+ if (strips_delete) {
+ SEQ_edit_remove_flagged_sequences(t->scene, seqbase_from_trans_info(t));
+ }
+}
+
+static void seq_transform_handle_overlap_shuffle(TransInfo *t, SeqCollection *transformed_strips)
+{
+ ListBase *seqbase = seqbase_from_trans_info(t);
+ ListBase *markers = &t->scene->markers;
+ const bool use_sync_markers = (((SpaceSeq *)t->area->spacedata.first)->flag &
+ SEQ_MARKER_TRANS) != 0;
+ /* Shuffle non strips with no effects attached. */
+ SeqCollection *standalone_strips = extract_standalone_strips(transformed_strips);
+ SEQ_transform_seqbase_shuffle_time(
+ standalone_strips, seqbase, t->scene, markers, use_sync_markers);
+ SEQ_collection_free(standalone_strips);
+}
+
static void seq_transform_handle_overlap(TransInfo *t, SeqCollection *transformed_strips)
{
- Editing *ed = SEQ_editing_get(t->scene, false);
- ListBase *seqbasep = SEQ_active_seqbase_get(ed);
+ ListBase *seqbasep = seqbase_from_trans_info(t);
+ eSeqOverlapMode overlap_mode = SEQ_tool_settings_overlap_mode_get(t->scene);
- if (t->flag & T_ALT_TRANSFORM) {
+ if ((overlap_mode & SEQ_OVERLAP_OVERWRITE) == 0 && t->flag & T_ALT_TRANSFORM) {
seq_transform_handle_expand_to_fit(t, transformed_strips);
}
+ else if ((ove
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list