== Sequencer ==
authorPeter Schlaile <peter@schlaile.de>
Thu, 9 Nov 2006 18:58:02 +0000 (18:58 +0000)
committerPeter Schlaile <peter@schlaile.de>
Thu, 9 Nov 2006 18:58:02 +0000 (18:58 +0000)
Added enhancements by blendix (Patch #4919: Insert sequence effect between)

It adds the following things:
- You can add a sequence strip afterwards in the middle of an effect chain
  (you have to move strips around before, so that there is "room" for it.
   Blender will ask you then, if you want to add in between or after the
   selected strips)
- In the case you messed it up and want your effect strips to be reassigned in
  a different way, there is the new "R"-key. Just select three arbitrary
  strips and press "R". If you don't create a cycle, those will be connected
  to a new effect chain.
- Fixed freeing of imbufs on changes to properly take into account dependencies.  An example of a simple case that went wrong is one image strip with two
  glow effects, changing the parameters of the first glow strip will not
  result in any updates. Basically only direct dependencies were taken into
  account, which resulted in the image preview not being updated in some cases.
- Let the sequencer detect an active sequence strip if none is defined, to
  get rid of annoying error messages when trying to add an effect to a
  selected sequence strip right after loading a file.
- Delete is less destructive. If you delete somewhere between other strips,
  Blender now tries to relink in a reasonable way.
- The active sequence strip is now displayed with a light instead of a dark
  outline, which makes it easier to spot, and is especially useful for the
  tools using the active sequence strip.
- Ability to view the final result when editing inside meta strip.
  The channel button was modified to also allow negative numbers,
  where -n is n levels up the meta stack. There is probably a nicer way to
  specify this, instead of (ab)using the channel button, but this seems to
  work quite efficient.
- Also a small bugfix: don't crash on loading files from newer versions with
  an unknown effect strip.

source/blender/include/BIF_editseq.h
source/blender/include/BSE_sequence.h
source/blender/makesdna/DNA_sequence_types.h
source/blender/src/drawseq.c
source/blender/src/editipo.c
source/blender/src/editseq.c
source/blender/src/header_seq.c
source/blender/src/seqeffects.c
source/blender/src/sequence.c
source/blender/src/space.c

index 3375559a83937c32bf695b14745a73be236bd822..335a131360e0dd6108a2daf0e9434c7773146a12 100644 (file)
@@ -40,11 +40,10 @@ void                                add_sequence(int type);
 void                           borderselect_seq(void);
 void                           boundbox_seq(void);
 void                           change_sequence(void);
-void                    update_seq_ipo_rect(struct Sequence * seq);
-struct Sequence*                get_last_seq();
-void                            set_last_seq_to_null();
-void                           clear_seq_belonging_to_ipo(struct Ipo * ipo);
-void                           clever_numbuts_seq(void);
+void                           update_seq_ipo_rect(struct Sequence * seq);
+struct Sequence*       get_last_seq();
+void                           set_last_seq(struct Sequence * seq);
+void                           clear_last_seq();
 void                           del_seq(void);
 void                           enter_meta(void);
 void                           exit_meta(void);
@@ -61,6 +60,7 @@ void                          touch_seq_files(void);
 void                           transform_seq(int mode, int context);
 void                           un_meta(void);
 void                           seq_cut(int cutframe);
+void                           reassign_inputs_seq_effect(void);
 
 /* drawseq.c */
 void do_seqbuttons(short);
index 65c55d950456dce639e86425ad891334f683aa2f..66fa22a5918ce87347dc782b39077d0bbec4f2fa 100644 (file)
@@ -55,6 +55,7 @@ void free_editing(struct Editing *ed);
 void calc_sequence(struct Sequence *seq);
 void sort_seq(void);
 void clear_scene_in_allseqs(struct Scene *sce);
+struct Sequence *get_shown_seq_from_metastrip(struct Sequence *seqm, int cfra);
 
 void make_black_ibuf(struct ImBuf *ibuf);
 void multibuf(struct ImBuf *ibuf, float fmul);
@@ -65,10 +66,12 @@ void set_meta_stripdata(struct Sequence *seqm);
 struct ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chansel); 
 /* chansel: render this channel. Default=0 (renders end result)*/
 
-void free_imbuf_effect_spec(int cfra);
 void free_imbuf_seq_except(int cfra);
+void free_imbuf_seq_with_ipo(struct Ipo * ipo);
 void free_imbuf_seq(void);
 
+void update_changed_seq_and_deps(struct Sequence *seq, int len_change, int ibuf_change);
+
 /* still bad level call... */
 struct RenderResult;
 void do_render_seq(struct RenderResult *rr, int cfra);
index 0213b8263ffb039b59a073604a5f52770883d5ca..84ca1f16006a7f8066393e5061469d66dc942da5 100644 (file)
@@ -176,15 +176,16 @@ typedef struct TransformVars {
 /* ***************** SEQUENCE ****************** */
 
 /* seq->flag */
-#define SEQ_LEFTSEL            2
-#define SEQ_RIGHTSEL   4
-#define SEQ_OVERLAP            8
-#define SEQ_FILTERY            16
-#define SEQ_MUTE               32
-#define SEQ_MAKE_PREMUL        64
-#define SEQ_REVERSE_FRAMES     128
-#define SEQ_IPO_FRAME_LOCKED    256
-#define SEQ_EFFECT_NOT_LOADED   512
+#define SEQ_LEFTSEL                            2
+#define SEQ_RIGHTSEL                   4
+#define SEQ_OVERLAP                            8
+#define SEQ_FILTERY                            16
+#define SEQ_MUTE                               32
+#define SEQ_MAKE_PREMUL                        64
+#define SEQ_REVERSE_FRAMES             128
+#define SEQ_IPO_FRAME_LOCKED   256
+#define SEQ_EFFECT_NOT_LOADED  512
+#define SEQ_FLAG_DELETE                        1024
 
 /* seq->type WATCH IT: SEQ_EFFECT BIT is used to determine if this is an effect strip!!! */
 #define SEQ_IMAGE              0
index 5492dd40ff5b7a58306015d34b7bde62ff85307e..5597e5f07da16d4edafd8af36d6ada4d4296efec 100644 (file)
@@ -671,6 +671,7 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq)
 {
        float x1, x2, y1, y2;
        char col[3];
+       Sequence *last_seq = get_last_seq();
 
        /* body */
        if(seq->startstill) x1= seq->start;
@@ -703,6 +704,7 @@ static void draw_seq_strip(Sequence *seq, ScrArea *sa, SpaceSeq *sseq)
                        col[0]= 255; col[1]= col[2]= 40;
                } else BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 120);
        }
+       else if (seq == last_seq) BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 120);
        else if (seq->flag & SELECT) BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -150);
        else BIF_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -60);
 
@@ -1004,17 +1006,13 @@ void do_seqbuttons(short val)
 
        switch(val) {
        case SEQ_BUT_PLUGIN:
-               new_stripdata(last_seq);
-               free_imbuf_effect_spec(CFRA);
+       case SEQ_BUT_EFFECT:
+               update_changed_seq_and_deps(last_seq, 0, 1);
                break;
 
        case SEQ_BUT_RELOAD:
                free_imbuf_seq();       // frees all
                break;
-       case SEQ_BUT_EFFECT:
-               new_stripdata(last_seq);
-               calc_sequence(last_seq);
-               break;
        }
 
        allqueue(REDRAWSEQ, 0);
index a2b75af6cfcd70556cc5a421a74dc4a8cb9a3835..05fd6e6dfe2675e911e2855130e69dea68656694 100644 (file)
 #include "BSE_drawview.h"
 #include "BSE_headerbuttons.h"
 #include "BSE_node.h"
+#include "BSE_sequence.h"
 
 #include "blendef.h"
 #include "mydevice.h"
@@ -325,7 +326,7 @@ void editipo_changed(SpaceIpo *si, int doredraw)
                        allqueue(REDRAWBUTSEDIT, 0);
                        allqueue(REDRAWVIEW3D, 0);
                }
-               else if(si->blocktype==ID_SEQ) clear_seq_belonging_to_ipo(si->ipo);
+               else if(si->blocktype==ID_SEQ) free_imbuf_seq_with_ipo(si->ipo);
                else if(si->blocktype==ID_PO) {
                        Object *ob= OBACT;
                        if(ob && ob->pose) {
index 848f6bc41ddf49ab74233ce0b8b1b368eb550392..3fe819dcd98c3e03a2c9ff27001be0815f8fee9c 100644 (file)
@@ -95,7 +95,8 @@
 #include "blendef.h"
 #include "mydevice.h"
 
-static Sequence *last_seq=0;
+static Sequence *_last_seq=0;
+static int _last_seq_init=0;
 
 #ifdef WIN32
 char last_imagename[FILE_MAXDIR+FILE_MAXFILE]= "c:\\";
@@ -110,20 +111,41 @@ char last_sounddir[FILE_MAXDIR+FILE_MAXFILE]= "";
 static int test_overlap_seq(Sequence *);
 static void shuffle_seq(Sequence *);
 
-Sequence * get_last_seq()
+Sequence *get_last_seq()
 {
-       return last_seq;
+       if(!_last_seq_init) {
+               Editing *ed;
+               Sequence *seq;
+
+               ed= G.scene->ed;
+               if(!ed) return NULL;
+
+               for(seq= ed->seqbasep->first; seq; seq=seq->next)
+                       if(seq->flag & SELECT)
+                               _last_seq= seq;
+
+               _last_seq_init = 1;
+       }
+
+       return _last_seq;
 }
 
-/* fixme: only needed by free_sequence... */
-void set_last_seq_to_null()
+void set_last_seq(Sequence *seq)
 {
-       last_seq = 0;
+       _last_seq = seq;
+       _last_seq_init = 1;
+}
+
+void clear_last_seq()
+{
+       _last_seq = NULL;
+       _last_seq_init = 0;
 }
 
 static void change_plugin_seq(char *str)       /* called from fileselect */
 {
        struct SeqEffectHandle sh;
+       Sequence *last_seq= get_last_seq();
 
        if(last_seq && last_seq->type != SEQ_PLUGIN) return;
 
@@ -248,34 +270,6 @@ void update_seq_ipo_rect(Sequence * seq)
        seq->ipo->cur.xmax= end;
 }
 
-void clear_seq_belonging_to_ipo(struct Ipo * ipo)
-{
-       /* from (example) ipo: when it is changed, also do effects with same ipo */
-       Sequence *seq;
-       Editing *ed;
-       StripElem *se;
-       int a;
-
-       ed= G.scene->ed;
-       if(ed==0) return;
-
-       WHILE_SEQ(&ed->seqbase) {
-               if(seq->ipo == ipo) {
-                       a= seq->len;
-                       se= seq->strip->stripdata;
-                       if(se) {
-                               while(a--) {
-                                       if(se->ibuf && se->ok != 2) IMB_freeImBuf(se->ibuf);
-                                       se->ibuf= 0;
-                                       se->ok= 1;
-                                       se++;
-                               }
-                       }
-               }
-       }
-       END_SEQ
-}
-
 static int test_overlap_seq(Sequence *test)
 {
        Sequence *seq;
@@ -345,6 +339,22 @@ static void shuffle_seq(Sequence *test)
        }
 }
 
+static int seq_is_parent(Sequence *par, Sequence *seq)
+{
+       return ((par->seq1 == seq) || (par->seq2 == seq) || (par->seq3 == seq));
+}
+
+static int seq_is_predecessor(Sequence *pred, Sequence *seq)
+{
+       if(pred == seq) return 0;
+       else if(seq_is_parent(pred, seq)) return 1;
+       else if(pred->seq1 && seq_is_predecessor(pred->seq1, seq)) return 1;
+       else if(pred->seq2 && seq_is_predecessor(pred->seq2, seq)) return 1;
+       else if(pred->seq3 && seq_is_predecessor(pred->seq3, seq)) return 1;
+
+       return 0;
+}
+
 static void deselect_all_seq(void)
 {
        Sequence *seq;
@@ -414,7 +424,7 @@ void mouse_select_seq(void)
        if(!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
 
        if(seq) {
-               last_seq= seq;
+               set_last_seq(seq);
 
                if ((seq->type == SEQ_IMAGE) || (seq->type == SEQ_MOVIE)) {
                        if(seq->strip) {
@@ -450,7 +460,7 @@ void mouse_select_seq(void)
 
        force_draw(0);
 
-       if(last_seq) allqueue(REDRAWIPO, 0);
+       if(get_last_seq()) allqueue(REDRAWIPO, 0);
        BIF_undo_push("Select Sequencer");
 
        std_rmouse_transform(transform_seq);
@@ -466,7 +476,7 @@ static Sequence *alloc_sequence(int cfra, int machine)
        seq= MEM_callocN( sizeof(Sequence), "addseq");
        BLI_addtail(ed->seqbasep, seq);
 
-       last_seq= seq;
+       set_last_seq(seq);
 
        *( (short *)seq->name )= ID_SEQ;
        seq->name[2]= 0;
@@ -939,6 +949,7 @@ static void reload_sound_strip(char *name)
        Editing *ed;
        Sequence *seq, *seqact;
        SpaceFile *sfile;
+       Sequence *last_seq= get_last_seq();
 
        ed= G.scene->ed;
 
@@ -981,6 +992,7 @@ static void reload_image_strip(char *name)
        Editing *ed;
        Sequence *seq, *seqact;
        SpaceFile *sfile;
+       Sequence *last_seq= get_last_seq();
 
        ed= G.scene->ed;
 
@@ -1006,17 +1018,7 @@ static void reload_image_strip(char *name)
                free_sequence(seq);
                BLI_remlink(ed->seqbasep, seq);
 
-               seq= ed->seqbasep->first;
-               while(seq) {
-                       if(seq->type & SEQ_EFFECT) {
-                               /* new_stripdata is clear */
-                               if(seq->seq1==seqact || seq->seq2==seqact || seq->seq3==seqact) {
-                                       calc_sequence(seq);
-                                       new_stripdata(seq);
-                               }
-                       }
-                       seq= seq->next;
-               }
+               update_changed_seq_and_deps(seqact, 1, 1);
        }
        waitcursor(0);
 
@@ -1040,24 +1042,37 @@ static int event_to_efftype(int event)
        return 0;
 }
 
-static int add_seq_effect(int type)
+static int can_insert_seq_between(Sequence *seq1, 
+                                 Sequence *seq2, Sequence *seq3)
 {
-       Editing *ed;
-       Sequence *seq, *seq1, *seq2, *seq3;
-       Strip *strip;
-       float x, y;
-       int cfra, machine;
-       short mval[2];
-       struct SeqEffectHandle sh;
+       Editing *ed= G.scene->ed;
+       Sequence *seq;
+       /* see if inserting inbetween would create a cycle */
+       if(seq_is_predecessor(seq1, seq2) || seq_is_predecessor(seq2, seq1) ||
+          seq_is_predecessor(seq2, seq3) || seq_is_predecessor(seq3, seq2) ||
+          seq_is_predecessor(seq3, seq1) || seq_is_predecessor(seq1, seq3))
+               return 0;
+
+       /* see if there is a parent that we can insert inbetween */
+       for(seq=ed->seqbasep->first; seq; seq=seq->next)
+               if((seq != seq1) && (seq != seq2) && (seq != seq3))
+                       if(seq_is_parent(seq, seq1) || 
+                         seq_is_parent(seq, seq2) ||
+                          seq_is_parent(seq, seq3))
+                               return 1;
+
+       return 0;
+}
 
-       if(G.scene->ed==0) return 0;
-       ed= G.scene->ed;
 
-       /* apart from last_seq there have to be 2 selected sequences */
-       seq1= seq3= 0;
-       seq2= last_seq;         /* last_seq changes with alloc_seq! */
-       seq= ed->seqbasep->first;
-       while(seq) {
+static int seq_effect_find_selected(Editing *ed, Sequence *activeseq, int type, Sequence **selseq1, Sequence **selseq2, Sequence **selseq3)
+{
+       Sequence *seq1= 0, *seq2= 0, *seq3= 0, *seq;
+       
+       if (!activeseq)
+               seq2= get_last_seq();
+
+       for(seq=ed->seqbasep->first; seq; seq=seq->next) {
                if(seq->flag & SELECT) {
                        if (seq->type == SEQ_RAM_SOUND
                            || seq->type == SEQ_HD_SOUND) { 
@@ -1065,27 +1080,30 @@ static int add_seq_effect(int type)
                                      "audio sequence strips");
                                return 0;
                        }
-                       if(seq != seq2) {
-                               if(seq1==0) seq1= seq;
-                               else if(seq3==0) seq3= seq;
-                               else {
-                                       seq1= 0;
-                                       break;
-                               }
+                       if((seq != activeseq) && (seq != seq2)) {
+                                if(seq2==0) seq2= seq;
+                                else if(seq1==0) seq1= seq;
+                                else if(seq3==0) seq3= seq;
+                                else {
+                                       error("Can't apply effect to more than 3 sequence strips");
+                                       return 0;
+                                }
                        }
                }
-               seq= seq->next;
        }
-       
-       /* make sequence selection a little bit more intuitive 
+       
+       /* make sequence selection a little bit more intuitive
           for 3 strips: the last-strip should be sequence3 */
        if (seq3 != 0 && seq2 != 0) {
+               Sequence *tmp = seq2;
                seq2 = seq3;
-               seq3 = last_seq;
+               seq3 = tmp;
        }
+       
 
-
-       if(type==10 || type==13 || type==14 || type==15) {      /* plugin: minimal 1 select */
+       if(type==SEQ_PLUGIN || type==SEQ_WIPE || 
+          type==SEQ_GLOW || type==SEQ_TRANSFORM) {
+         /* plugin: minimal 1 select */
                if(seq2==0)  {
                        error("Need at least one selected sequence strip");
                        return 0;
@@ -1101,6 +1119,71 @@ static int add_seq_effect(int type)
                if(seq3==0) seq3= seq2;
        }
 
+       *selseq1= seq1;
+       *selseq2= seq2;
+       *selseq3= seq3;
+
+       return 1;
+}
+
+static void insert_seq_between(Sequence *newseq, Sequence *seq1, Sequence *seq2, Sequence *seq3)
+{
+       Editing *ed= G.scene->ed;
+       Sequence *seq, *firstseq = NULL;
+       Sequence *oldseq[3];
+       int i;
+
+       oldseq[0]= seq1;
+       oldseq[1]= seq2;
+       oldseq[2]= seq3;
+
+       for(seq=ed->seqbasep->first; seq; seq=seq->next) {
+               if((seq != seq1) && (seq != seq2) && (seq != seq3)) {
+                       /* set pointers to new children */
+                       for(i=0; i < 3; i++) {
+                               if(seq_is_parent(seq, oldseq[i]) && (seq != newseq)) {
+                                       if(seq->seq1 == oldseq[i]) seq->seq1= newseq;
+                                       if(seq->seq2 == oldseq[i]) seq->seq2= newseq;
+                                       if(seq->seq3 == oldseq[i]) seq->seq3= newseq;
+                                       if(!firstseq) firstseq= seq;
+                               }
+                       }
+               }
+       }
+
+       /* reinsert sequence in the list before the first sequence depending on it,
+          this is needed for the strips to be evaluated in correct order */
+       if(firstseq) {
+               BLI_remlink(ed->seqbasep, newseq);
+               BLI_insertlinkbefore(ed->seqbasep, firstseq, newseq);
+       }
+}
+
+
+static int add_seq_effect(int type, char *str)
+{
+       Editing *ed;
+       Sequence *newseq, *seq1, *seq2, *seq3;
+       Strip *strip;
+       float x, y;
+       int cfra, machine;
+       short mval[2];
+       struct SeqEffectHandle sh;
+       int mode, insertbetween= 0;
+
+       if(G.scene->ed==0) return 0;
+       ed= G.scene->ed;
+
+       if(!seq_effect_find_selected(ed, NULL, event_to_efftype(type), &seq1, &seq2, &seq3))
+               return 0;
+
+        if (can_insert_seq_between(seq1, seq2, seq3)) {
+               force_draw(0); /* to make sure popup is not drawn over file select */
+               mode= pupmenu("Insert Between %x1|Insert After %x2");
+               if(mode == 1)
+                       insertbetween= 1;
+       }
+
        deselect_all_seq();
 
        /* where will it be (cfra is not realy needed) */
@@ -1109,53 +1192,60 @@ static int add_seq_effect(int type)
        cfra= (int)(x+0.5);
        machine= (int)(y+0.5);
 
-       seq= alloc_sequence(cfra, machine);
+       /* allocate and initialize */
+       newseq= alloc_sequence(cfra, machine);
+       newseq->type= event_to_efftype(type);
 
-       seq->type= event_to_efftype(type);
+       sh = get_sequence_effect(newseq);
 
-       sh = get_sequence_effect(seq);
+       newseq->seq1= seq1;
+       newseq->seq2= seq2;
+       newseq->seq3= seq3;
 
-       seq->seq1= seq1;
-       seq->seq2= seq2;
-       seq->seq3= seq3;
+       sh.init(newseq);
+       calc_sequence(newseq);
 
-       sh.init(seq);
+       newseq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
+       strip->len= newseq->len;
+       strip->us= 1;
+       if(newseq->len>0)
+               strip->stripdata= MEM_callocN(newseq->len*sizeof(StripElem), "stripelem");
 
-       calc_sequence(seq);
+       /* initialize plugin */
+       if(type==10) {
+               sh.init_plugin(newseq, str);
 
-       seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
-       strip->len= seq->len;
-       strip->us= 1;
-       if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
+               if(newseq->plugin==0) {
+                       BLI_remlink(ed->seqbasep, newseq);
+                       free_sequence(newseq);
+                       set_last_seq(NULL);
+                       return 0;
+               }
+       }
 
-       BIF_undo_push("Add effect strip Sequencer");
+       /* set find a free spot to but the strip */
+       newseq->machine= MAX3(newseq->seq1->machine, newseq->seq2->machine,
+               newseq->seq3->machine);
+       if(test_overlap_seq(newseq)) shuffle_seq(newseq);
 
-       return 1;
-}
+       /* set inbetween relation */
+       if(insertbetween)
+               insert_seq_between(newseq, seq1, seq2, seq3);
 
-static void load_plugin_seq(char *str)         /* called from fileselect */
-{
-       Editing *ed;
-       struct SeqEffectHandle sh;
+       update_changed_seq_and_deps(newseq, 1, 1);
 
-       add_seq_effect(10);             /* this sets last_seq */
+       /* push undo and go into grab mode */
+       if(type == 10) BIF_undo_push("Add plugin strip Sequencer");
+       else BIF_undo_push("Add effect strip Sequencer");
 
-       sh = get_sequence_effect(last_seq);
-       sh.init_plugin(last_seq, str);
+       transform_seq('g', 0);
 
-       if(last_seq->plugin==0) {
-               ed= G.scene->ed;
-               BLI_remlink(ed->seqbasep, last_seq);
-               free_sequence(last_seq);
-               last_seq= 0;
-       }
-       else {
-               last_seq->machine= MAX3(last_seq->seq1->machine, last_seq->seq2->machine, last_seq->seq3->machine);
-               if( test_overlap_seq(last_seq) ) shuffle_seq(last_seq);
+       return 1;
+}
 
-               BIF_undo_push("Add plugin strip Sequencer");
-               transform_seq('g', 0);
-       }
+static void load_plugin_seq(char *str)         /* called from fileselect */
+{
+       add_seq_effect(10, str);
 }
 
 void add_sequence(int type)
@@ -1334,13 +1424,12 @@ void add_sequence(int type)
        case 14:
        case 15:
 
-               if(last_seq==0) error("Need at least one active sequence strip");
-               else if(event==10) {
+               if(get_last_seq()==0)
+                       error("Need at least one active sequence strip");
+               else if(event==10)
                        activate_fileselect(FILE_SPECIAL, "Select Plugin", U.plugseqdir, load_plugin_seq);
-               }
-               else {
-                       if( add_seq_effect(event) ) transform_seq('g', 0);
-               }
+               else
+                       add_seq_effect(event, NULL);
 
                break;
        case 103:
@@ -1356,6 +1445,7 @@ void add_sequence(int type)
 
 void change_sequence(void)
 {
+       Sequence *last_seq= get_last_seq();
        Scene *sce;
        short event;
 
@@ -1404,7 +1494,8 @@ void change_sequence(void)
                                sh = get_sequence_effect(last_seq);
                                sh.init(last_seq);
                        }
-                       new_stripdata(last_seq);
+
+                       update_changed_seq_and_deps(last_seq, 0, 1);
                        allqueue(REDRAWSEQ, 0);
                        BIF_undo_push("Change effect Sequencer");
                }
@@ -1428,8 +1519,7 @@ void change_sequence(void)
 
                        last_seq->len= sce->r.efra - sce->r.sfra + 1;
                        last_seq->sfra= sce->r.sfra;
-                       new_stripdata(last_seq);
-                       calc_sequence(last_seq);
+                       update_changed_seq_and_deps(last_seq, 1, 1);
 
                        allqueue(REDRAWSEQ, 0);
                }
@@ -1437,37 +1527,87 @@ void change_sequence(void)
 
 }
 
-static int is_a_sequence(Sequence *test)
+void reassign_inputs_seq_effect()
 {
-       Sequence *seq;
-       Editing *ed;
+       Editing *ed= G.scene->ed;
+       Sequence *seq1, *seq2, *seq3, *last_seq = get_last_seq();
 
-       ed= G.scene->ed;
-       if(ed==0 || test==0) return 0;
+       if(last_seq==0 || !(last_seq->type & SEQ_EFFECT)) return;
+       if(ed==0) return;
 
-       seq= ed->seqbasep->first;
-       while(seq) {
-               if(seq==test) return 1;
-               seq= seq->next;
+       if(!seq_effect_find_selected(ed, last_seq, last_seq->type, &seq1, &seq2, &seq3))
+               return;
+
+       /* see reassigning would create a cycle */
+       if(seq_is_predecessor(seq1, last_seq) || seq_is_predecessor(seq2, last_seq) ||
+          seq_is_predecessor(seq3, last_seq)) {
+               error("Can't reassign inputs: no cycles allowed");
+               return;
        }
+       
+       last_seq->seq1 = seq1;
+       last_seq->seq2 = seq2;
+       last_seq->seq3 = seq3;
 
-       return 0;
+       update_changed_seq_and_deps(last_seq, 1, 1);
+
+       allqueue(REDRAWSEQ, 0);
+}
+
+static Sequence *del_seq_find_replace_recurs(Sequence *seq)
+{
+       Sequence *seq1, *seq2, *seq3;
+
+       /* try to find a replacement input sequence, and flag for later deletion if
+          no replacement can be found */
+
+       if(!seq)
+               return NULL;
+       else if(!(seq->type & SEQ_EFFECT))
+               return ((seq->flag & SELECT)? NULL: seq);
+       else if(!(seq->flag & SELECT)) {
+               /* try to find replacement for effect inputs */
+               seq1= del_seq_find_replace_recurs(seq->seq1);
+               seq2= del_seq_find_replace_recurs(seq->seq2);
+               seq3= del_seq_find_replace_recurs(seq->seq3);
+
+               if(seq1==seq->seq1 && seq2==seq->seq2 && seq3==seq->seq3);
+               else if(seq1 || seq2 || seq3) {
+                       seq->seq1= (seq1)? seq1: (seq2)? seq2: seq3;
+                       seq->seq2= (seq2)? seq2: (seq1)? seq1: seq3;
+                       seq->seq3= (seq3)? seq3: (seq1)? seq1: seq2;
+
+                       update_changed_seq_and_deps(seq, 1, 1);
+               }
+               else
+                       seq->flag |= SELECT; /* mark for delete */
+       }
+
+       if (seq->flag & SELECT) {
+               if((seq1 = del_seq_find_replace_recurs(seq->seq1))) return seq1;
+               if((seq2 = del_seq_find_replace_recurs(seq->seq2))) return seq2;
+               if((seq3 = del_seq_find_replace_recurs(seq->seq3))) return seq3;
+               else return NULL;
+       }
+       else
+               return seq;
 }
 
-static void recurs_del_seq(ListBase *lb)
+static void recurs_del_seq_flag(ListBase *lb, short flag, short deleteall)
 {
        Sequence *seq, *seqn;
+       Sequence *last_seq = get_last_seq();
 
        seq= lb->first;
        while(seq) {
                seqn= seq->next;
-               if(seq->flag & SELECT) {
+               if((seq->flag & flag) || deleteall) {
                        if(seq->type==SEQ_RAM_SOUND && seq->sound) 
                                seq->sound->id.us--;
 
                        BLI_remlink(lb, seq);
-                       if(seq==last_seq) last_seq= 0;
-                       if(seq->type==SEQ_META) recurs_del_seq(&seq->seqbase);
+                       if(seq==last_seq) set_last_seq(0);
+                       if(seq->type==SEQ_META) recurs_del_seq_flag(&seq->seqbase, flag, 1);
                        if(seq->ipo) seq->ipo->id.us--;
                        free_sequence(seq);
                }
@@ -1477,38 +1617,27 @@ static void recurs_del_seq(ListBase *lb)
 
 void del_seq(void)
 {
-       Sequence *seq, *seqn;
+       Sequence *seq;
        MetaStack *ms;
        Editing *ed;
-       int doit;
 
        if(okee("Erase selected")==0) return;
 
        ed= G.scene->ed;
        if(ed==0) return;
 
-       recurs_del_seq(ed->seqbasep);
+       /* free imbufs of all dependent strips */
+       for(seq=ed->seqbasep->first; seq; seq=seq->next)
+               if(seq->flag & SELECT)
+                       update_changed_seq_and_deps(seq, 1, 0);
 
-       /* test effects */
-       doit= 1;
-       while(doit) {
-               doit= 0;
-               seq= ed->seqbasep->first;
-               while(seq) {
-                       seqn= seq->next;
-                       if(seq->type & SEQ_EFFECT) {
-                               if(    is_a_sequence(seq->seq1)==0 
-                                   || is_a_sequence(seq->seq2)==0 
-                                   || is_a_sequence(seq->seq3)==0 ) {
-                                       BLI_remlink(ed->seqbasep, seq);
-                                       if(seq==last_seq) last_seq= 0;
-                                       free_sequence(seq);
-                                       doit= 1;
-                               }
-                       }
-                       seq= seqn;
-               }
-       }
+       /* for effects, try to find a replacement input */
+       for(seq=ed->seqbasep->first; seq; seq=seq->next)
+               if((seq->type & SEQ_EFFECT) && !(seq->flag & SELECT))
+                       del_seq_find_replace_recurs(seq);
+
+       /* delete all selected strips */
+       recurs_del_seq_flag(ed->seqbasep, SELECT, 0);
 
        /* updates lengths etc */
        seq= ed->seqbasep->first;
@@ -1529,8 +1658,6 @@ void del_seq(void)
        allqueue(REDRAWSEQ, 0);
 }
 
-
-
 static void recurs_dupli_seq(ListBase *old, ListBase *new)
 {
        Sequence *seq, *seqn;
@@ -1889,11 +2016,19 @@ void make_meta(void)
        allqueue(REDRAWSEQ, 0);
 }
 
+static int seq_depends_on_meta(Sequence *seq, Sequence *seqm)
+{
+       if (seq == seqm) return 1;
+       else if (seq->seq1 && seq_depends_on_meta(seq->seq1, seqm)) return 1;
+       else if (seq->seq2 && seq_depends_on_meta(seq->seq2, seqm)) return 1;
+       else if (seq->seq3 && seq_depends_on_meta(seq->seq3, seqm)) return 1;
+       else return 0;
+}
+
 void un_meta(void)
 {
        Editing *ed;
-       Sequence *seq, *seqn;
-       int doit;
+       Sequence *seq, *last_seq = get_last_seq();
 
        ed= G.scene->ed;
        if(ed==0) return;
@@ -1910,27 +2045,12 @@ void un_meta(void)
        BLI_remlink(ed->seqbasep, last_seq);
        free_sequence(last_seq);
 
-       /* test effects */
-       doit= 1;
-       while(doit) {
-               doit= 0;
-               seq= ed->seqbasep->first;
-               while(seq) {
-                       seqn= seq->next;
-                       if(seq->type & SEQ_EFFECT) {
-                               if(    is_a_sequence(seq->seq1)==0 
-                                   || is_a_sequence(seq->seq2)==0 
-                                   || is_a_sequence(seq->seq3)==0 ) {
-                                       BLI_remlink(ed->seqbasep, seq);
-                                       if(seq==last_seq) last_seq= 0;
-                                       free_sequence(seq);
-                                       doit= 1;
-                               }
-                       }
-                       seq= seqn;
-               }
-       }
+       /* emtpy meta strip, delete all effects depending on it */
+       for(seq=ed->seqbasep->first; seq; seq=seq->next)
+               if((seq->type & SEQ_EFFECT) && seq_depends_on_meta(seq, last_seq))
+                       seq->flag |= SEQ_FLAG_DELETE;
 
+       recurs_del_seq_flag(ed->seqbasep, SEQ_FLAG_DELETE, 0);
 
        /* test for effects and overlap */
        WHILE_SEQ(ed->seqbasep) {
@@ -1943,6 +2063,8 @@ void un_meta(void)
        }
        END_SEQ;
 
+       sort_seq();
+
        BIF_undo_push("Un-make Meta Sequencer");
        allqueue(REDRAWSEQ, 0);
 
@@ -1974,10 +2096,10 @@ void exit_meta(void)
                seq= seq->next;
        }
 
-       last_seq= ms->parseq;
+       set_last_seq(ms->parseq);
 
-       last_seq->flag= SELECT;
-       recurs_sel_seq(last_seq);
+       ms->parseq->flag= SELECT;
+       recurs_sel_seq(ms->parseq);
 
        MEM_freeN(ms);
        allqueue(REDRAWSEQ, 0);
@@ -1990,6 +2112,7 @@ void enter_meta(void)
 {
        MetaStack *ms;
        Editing *ed;
+       Sequence *last_seq= get_last_seq();
 
        ed= G.scene->ed;
        if(ed==0) return;
@@ -2006,7 +2129,7 @@ void enter_meta(void)
 
        ed->seqbasep= &last_seq->seqbase;
 
-       last_seq= 0;
+       set_last_seq(NULL);
        allqueue(REDRAWSEQ, 0);
        BIF_undo_push("Enter meta strip Sequence");
 }
@@ -2275,73 +2398,6 @@ void transform_seq(int mode, int context)
        allqueue(REDRAWSEQ, 0);
 }
 
-
-void clever_numbuts_seq(void)
-{
-       PluginSeq *pis;
-       StripElem *se;
-       VarStruct *varstr;
-       int a;
-
-       if(last_seq==0) return;
-       if(last_seq->type==SEQ_PLUGIN) {
-               pis= last_seq->plugin;
-               if(pis->vars==0) return;
-
-               varstr= pis->varstr;
-               if(varstr) {
-                       for(a=0; a<pis->vars; a++, varstr++) {
-                               add_numbut(a, varstr->type, varstr->name, varstr->min, varstr->max, &(pis->data[a]), varstr->tip);
-                       }
-
-                       if( do_clever_numbuts(pis->pname, pis->vars, REDRAW) ) {
-                               new_stripdata(last_seq);
-                               free_imbuf_effect_spec(CFRA);
-                               allqueue(REDRAWSEQ, 0);
-                       }
-               }
-       }
-       else if(last_seq->type==SEQ_MOVIE) {
-
-               if(last_seq->mul==0.0) last_seq->mul= 1.0;
-
-               add_numbut(0, TEX, "Name:", 0.0, 21.0, last_seq->name+2, 0);
-               add_numbut(1, TOG|SHO|BIT|4, "FilterY", 0.0, 1.0, &last_seq->flag, 0);
-               /* warning: only a single bit-button possible: we work at copied data! */
-               add_numbut(2, NUM|FLO, "Mul", 0.01, 5.0, &last_seq->mul, 0);
-
-               if( do_clever_numbuts("Movie", 3, REDRAW) ) {
-                       se= last_seq->curelem;
-
-                       if(se && se->ibuf ) {
-                               IMB_freeImBuf(se->ibuf);
-                               se->ibuf= 0;
-                       }
-                       allqueue(REDRAWSEQ, 0);
-               }
-       }
-       else if(last_seq->type==SEQ_RAM_SOUND || last_seq->type==SEQ_HD_SOUND) {
-
-               add_numbut(0, TEX, "Name:", 0.0, 21.0, last_seq->name+2, 0);
-               add_numbut(1, NUM|FLO, "Gain (dB):", -96.0, 6.0, &last_seq->level, 0);
-               add_numbut(2, NUM|FLO, "Pan:", -1.0, 1.0, &last_seq->pan, 0);
-               add_numbut(3, TOG|SHO|BIT|5, "Mute", 0.0, 1.0, &last_seq->flag, 0);
-
-               if( do_clever_numbuts("Audio", 4, REDRAW) ) {
-                       se= last_seq->curelem;
-                       allqueue(REDRAWSEQ, 0);
-               }
-       }
-       else if(last_seq->type==SEQ_META) {
-
-               add_numbut(0, TEX, "Name:", 0.0, 21.0, last_seq->name+2, 0);
-
-               if( do_clever_numbuts("Meta", 1, REDRAW) ) {
-                       allqueue(REDRAWSEQ, 0);
-               }
-       }
-}
-
 void seq_cut(int cutframe)
 {
        Editing *ed;
index c0fe272dc6c2e90fa15a69c32f4f554586a0865b..4f38650a5fd8b492c05ea578a2a7b212373c279d 100644 (file)
@@ -51,6 +51,7 @@
 #include "DNA_screen_types.h"
 #include "DNA_sequence_types.h"
 #include "DNA_space_types.h"
+#include "BLI_blenlib.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
 #include "BIF_drawseq.h"
@@ -373,6 +374,9 @@ static void do_seq_editmenu(void *arg, int event)
        case 13: /* Cut at Current Frame */
                seq_cut(CFRA);
                break;
+       case 14:
+               reassign_inputs_seq_effect();
+               break;
        }
 }
 
@@ -405,7 +409,10 @@ static uiBlock *seq_editmenu(void *arg_unused)
        if (last_seq != NULL && last_seq->type != SEQ_MOVIE) {
                uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 
-               if(last_seq->type >= SEQ_EFFECT) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Change Effect...|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+               if(last_seq->type >= SEQ_EFFECT) {
+                       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Change Effect...|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+                       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Reassing Inputs|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
+               }
                else if(last_seq->type == SEQ_IMAGE) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Change Image...|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
                else uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Change Scene...|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
        }
@@ -545,9 +552,14 @@ void seq_buttons()
        
        /* CHANNEL shown in 3D preview */
        if(sseq->mainb) {
+               int minchan = 0;
+
+               if (G.scene->ed && ((Editing*)G.scene->ed)->metastack.first)
+                       minchan = -BLI_countlist(&((Editing*)G.scene->ed)->metastack);
+
                uiDefButS(block, NUM, B_REDR, "Chan:",
                xco, 0, 3.5 * XIC,YIC,
-               &sseq->chanshown, 0, MAXSEQ, 0, 0,
+               &sseq->chanshown, minchan, MAXSEQ, 0, 0,
                "The channel number shown in the image preview. 0 is the result of all strips combined.");
                
                xco+= 8 + XIC*3.5;
index 02ad7f44a4a607f7e2a84b6e5491871f544a2f7b..dbef3b61ba50f31b545766ec5c534b8fc176d3ed 100644 (file)
 
 #include "MEM_guardedalloc.h"
 #include "PIL_dynlib.h"
-#include "BKE_plugin_types.h"
-
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
 
 #include "DNA_sequence_types.h"
-#include "BSE_seqeffects.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 
-#include "DNA_sequence_types.h"
+#include "BIF_interface.h"
+#include "BIF_toolbox.h"
+
+#include "BSE_seqeffects.h"
+#include "BSE_sequence.h"
 
-#include "BKE_utildefines.h"
 #include "BKE_global.h"
 #include "BKE_ipo.h"
+#include "BKE_plugin_types.h"
 #include "BKE_texture.h"
-#include "BIF_toolbox.h"
-#include "BIF_interface.h"
+#include "BKE_utildefines.h"
 
-#include "BSE_sequence.h"
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
 
 #include "RE_pipeline.h"               // talks to entire render API
 
@@ -2691,7 +2690,6 @@ static void do_glow_effect(Sequence * seq,int cfra,
        }
 }
 
-
 /* **********************************************************************
    sequence effect factory
    ********************************************************************** */
index ca9f9f48801f23f3bebad2c352f75d36fa471ca5..f81df5357f947a33fee72c1b19f7f7b65d3ac7c2 100644 (file)
@@ -109,7 +109,6 @@ void free_strip(Strip *strip)
 
 void new_stripdata(Sequence *seq)
 {
-
        if(seq->strip) {
                if(seq->strip->stripdata) free_stripdata(seq->strip->len, seq->strip->stripdata);
                seq->strip->stripdata= 0;
@@ -133,7 +132,7 @@ void free_sequence(Sequence *seq)
                sh.free(seq);
        }
 
-       if(seq==last_seq) set_last_seq_to_null();
+       if(seq==last_seq) set_last_seq(NULL);
 
        MEM_freeN(seq);
 }
@@ -200,6 +199,8 @@ void free_editing(Editing *ed)
        }
 
        MEM_freeN(ed);
+
+       clear_last_seq();
 }
 
 void calc_sequence(Sequence *seq)
@@ -348,7 +349,7 @@ void clear_scene_in_allseqs(Scene *sce)
 
 void make_black_ibuf(ImBuf *ibuf)
 {
-       int *rect;
+       unsigned int *rect;
        float *rect_float;
        int tot;
 
@@ -415,7 +416,7 @@ void do_effect(int cfra, Sequence *seq, StripElem *se)
        int x, y;
        struct SeqEffectHandle sh = get_sequence_effect(seq);
 
-       if(se->se1==0 || se->se2==0 || se->se3==0) {
+       if(!sh.execute || se->se1==0 || se->se2==0 || se->se3==0) {
                make_black_ibuf(se->ibuf);
                return;
        }
@@ -563,7 +564,7 @@ int evaluate_seq_frame(int cfra)
 
 }
 
-static Sequence * get_shown_seq_from_metastrip(Sequence * seqm, int cfra)
+Sequence *get_shown_seq_from_metastrip(Sequence * seqm, int cfra)
 {
        Sequence *seq, *seqim, *seqeff;
        Sequence *seq_arr[MAXSEQ+1];
@@ -657,10 +658,8 @@ static void do_seq_unref_cfra(ListBase *seqbase, int cfra)
                                else do_seq_unref_cfra(&seq->seqbase, cfra);
                        }
 
-                       if (seq->curelem && seq->curelem->ibuf 
-                          && seq->curelem->isneeded) {
+                       if (seq->curelem && seq->curelem->ibuf && seq->curelem->isneeded)
                                IMB_cache_limiter_unref(seq->curelem->ibuf);
-                       }
                }
                seq= seq->next;
        }
@@ -737,9 +736,7 @@ static void do_effect_depend(int cfra, Sequence * seq, StripElem *se)
 
 static void do_build_seq_depend(Sequence * seq, int cfra)
 {
-       StripElem *se;
-
-       se=seq->curelem= give_stripelem(seq, cfra);
+       StripElem *se = seq->curelem;
 
        if(se && !se->isneeded) {
                se->isneeded = 1;
@@ -762,11 +759,9 @@ static void do_build_seq_depend(Sequence * seq, int cfra)
 
 static void do_build_seq_ibuf(Sequence * seq, int cfra)
 {
-       StripElem *se;
+       StripElem *se = seq->curelem;
        char name[FILE_MAXDIR+FILE_MAXFILE];
 
-       se=seq->curelem= give_stripelem(seq, cfra);
-
        if(se && se->isneeded) {
                if(seq->type == SEQ_META) {
                        se->ok= 2;
@@ -788,7 +783,7 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra)
                                }
                        }
                        
-                       /* does the effect should be recalculated? */
+                       /* should the effect be recalculated? */
                        
                        if(se->ibuf==0 
                           || (se->se1 != seq->seq1->curelem) 
@@ -800,12 +795,13 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra)
                                
                                if(se->ibuf==NULL) {
                                        /* if one of two first inputs are rectfloat, output is float too */
-                                       if((se->se1->ibuf && se->se1->ibuf->rect_float) ||
+                                       if((se->se1->ibuf && se->se1->ibuf->rect_float) ||
                                           (se->se2->ibuf && se->se2->ibuf->rect_float))
                                                se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rectfloat, 0);
                                        else
                                                se->ibuf= IMB_allocImBuf((short)seqrectx, (short)seqrecty, 32, IB_rect, 0);
                                }
+
                                do_effect(cfra, seq, se);
                        }
                        
@@ -981,34 +977,38 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra)
        }
 }
 
+static void do_set_seq_curelem(ListBase *seqbase, int cfra)
+{
+       Sequence *seq;
+
+       for(seq=seqbase->first; seq; seq=seq->next) {
+               seq->curelem= give_stripelem(seq, cfra);
+
+               if (seq->curelem) {
+                       seq->curelem->isneeded= 0; /* nobody is needed a priori */
+
+                       if (seq->seqbase.first)
+                               do_set_seq_curelem(&seq->seqbase, cfra);
+               }
+       }
+}
+
 static void do_build_seqar_cfra(ListBase *seqbase, Sequence ***seqar, int cfra)
 {
        Sequence *seq;
-       StripElem *se;
 
        if(seqar==NULL) return;
        
        seq= seqbase->first;
        while(seq) {
-
-               /* set at zero because free_imbuf_seq... */
-               seq->curelem= 0;
-
                if ((seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) && (seq->ipo)
                    && (seq->startdisp <= cfra+2) && (seq->enddisp > cfra)) {
                        do_seq_ipo(seq);
                }
 
-               if(seq->startdisp <=cfra && seq->enddisp > cfra) {
+               if(seq->curelem) {
                        **seqar= seq;
                        (*seqar)++;
-
-                       /* nobody is needed a priori */
-                       se = seq->curelem= give_stripelem(seq, cfra);
-       
-                       if (se) {
-                               se->isneeded = 0;
-                       }
                }
 
                seq= seq->next;
@@ -1021,10 +1021,6 @@ static void do_build_seq_ibufs(ListBase *seqbase, int cfra)
 
        seq= seqbase->first;
        while(seq) {
-
-               /* set at zero because free_imbuf_seq... */
-               seq->curelem= 0;
-
                if ((seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) && (seq->ipo)
                    && (seq->startdisp <= cfra+2)  && (seq->enddisp > cfra)) {
                        do_seq_ipo(seq);
@@ -1052,7 +1048,8 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
        Sequence *seq, *seqfirst=0;/*  , *effirst=0; */
        Editing *ed;
        StripElem *se;
-       int seqnr, totseq;
+       int seqnr, totseq, count;
+       ListBase *seqbasep;
 
        /* we make recursively a 'stack' of sequences, these are
         * sorted nicely as well.
@@ -1063,7 +1060,16 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
        totseq= 0;
        ed= G.scene->ed;
        if(ed==0) return 0;
-       do_seq_count_cfra(ed->seqbasep, &totseq, cfra);
+
+       count = BLI_countlist(&ed->metastack);
+       if((chanshown < 0) && (count > 0)) {
+               count = MAX2(count + chanshown, 0);
+               seqbasep= ((MetaStack*)BLI_findlink(&ed->metastack, count))->oldbasep;
+       }
+       else
+               seqbasep= ed->seqbasep;
+
+       do_seq_count_cfra(seqbasep, &totseq, cfra);
 
        if(totseq==0) return 0;
 
@@ -1073,8 +1079,11 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
        /* tseqar is needed because in do_build_... the pointer changes */
        seqar= tseqar= MEM_callocN(sizeof(void *)*totseq, "seqar");
 
+       /* set curelem pointers to stripelem */
+       do_set_seq_curelem(seqbasep, cfra);
+
        /* this call creates the sequence order array */
-       do_build_seqar_cfra(ed->seqbasep, &seqar, cfra);
+       do_build_seqar_cfra(seqbasep, &seqar, cfra);
 
        seqar= tseqar;
 
@@ -1083,7 +1092,7 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
 
                se= seq->curelem;
                if((seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND) 
-                       && (se) && (chanshown == 0 || seq->machine == chanshown)) {
+                       && (se) && (chanshown <= 0 || seq->machine == chanshown)) {
                        if(seq->type==SEQ_META) {
 
                                /* bottom strip! */
@@ -1120,9 +1129,9 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
 
        if (seqfirst) {
                do_build_seq_depend(seqfirst, cfra);
-               do_build_seq_ibufs(ed->seqbasep, cfra);
-               do_seq_unref_cfra(ed->seqbasep, cfra);
-               do_seq_test_unref_cfra(ed->seqbasep, cfra);
+               do_build_seq_ibufs(seqbasep, cfra);
+               do_seq_unref_cfra(seqbasep, cfra);
+               do_seq_test_unref_cfra(seqbasep, cfra);
        }
 
        if(!seqfirst) return 0;
@@ -1131,116 +1140,139 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
 
 }
 
-void free_imbuf_effect_spec(int cfra)
+/* Functions to free imbuf and anim data on changes */
+
+static void free_imbuf_strip_elem(StripElem *se)
 {
+       if (se->ibuf) {
+               if (se->ok != 2)
+                       IMB_freeImBuf(se->ibuf);
+               se->ibuf= 0;
+               se->ok= 1;
+               se->se1= se->se2= se->se3= 0;
+       }
+}
+
+static void free_anim_seq(Sequence *seq)
+{
+       if(seq->anim) {
+               IMB_free_anim(seq->anim);
+               seq->anim = 0;
+       }
+}
+
+void free_imbuf_seq_except(int cfra)
+{
+       Editing *ed= G.scene->ed;
        Sequence *seq;
        StripElem *se;
-       Editing *ed;
        int a;
 
-       ed= G.scene->ed;
        if(ed==0) return;
 
        WHILE_SEQ(&ed->seqbase) {
-
                if(seq->strip) {
+                       for(a=0, se= seq->strip->stripdata; a<seq->len; a++, se++)
+                               if(se!=seq->curelem)
+                                       free_imbuf_strip_elem(se);
 
-                       if(seq->type & SEQ_EFFECT) {
-                               se= seq->strip->stripdata;
-                               for(a=0; a<seq->len; a++, se++) {
-                                       if(se==seq->curelem && se->ibuf) {
-                                               IMB_freeImBuf(se->ibuf);
-                                               se->ibuf= 0;
-                                               se->ok= 1;
-                                               se->se1= se->se2= se->se3= 0;
-                                       }
-                               }
-                       }
+                       if(seq->type==SEQ_MOVIE)
+                               if(seq->startdisp > cfra || seq->enddisp < cfra)
+                                       free_anim_seq(seq);
                }
        }
        END_SEQ
 }
 
-void free_imbuf_seq_except(int cfra)
+void free_imbuf_seq()
 {
+       Editing *ed= G.scene->ed;
        Sequence *seq;
        StripElem *se;
-       Editing *ed;
        int a;
 
-       ed= G.scene->ed;
        if(ed==0) return;
 
        WHILE_SEQ(&ed->seqbase) {
-
                if(seq->strip) {
+                       for(a=0, se= seq->strip->stripdata; a<seq->len; a++, se++)
+                               free_imbuf_strip_elem(se);
 
-                       if( seq->type==SEQ_META ) {
-                               ;
-                       }
-                       else {
-                               se= seq->strip->stripdata;
-                               for(a=0; a<seq->len; a++, se++) {
-                                       if(se!=seq->curelem && se->ibuf) {
-                                               IMB_freeImBuf(se->ibuf);
-                                               se->ibuf= 0;
-                                               se->ok= 1;
-                                               se->se1= se->se2= se->se3= 0;
-                                       }
-                               }
-                       }
-
-                       if(seq->type==SEQ_MOVIE) {
-                               if(seq->startdisp > cfra || seq->enddisp < cfra) {
-                                       if(seq->anim) {
-                                               IMB_free_anim(seq->anim);
-                                               seq->anim = 0;
-                                       }
-                               }
-                       }
+                       if(seq->type==SEQ_MOVIE)
+                               free_anim_seq(seq);
                }
        }
        END_SEQ
 }
 
-void free_imbuf_seq()
+void free_imbuf_seq_with_ipo(struct Ipo *ipo)
 {
+       /* force update of all sequences with this ipo, on ipo changes */
+       Editing *ed= G.scene->ed;
        Sequence *seq;
-       StripElem *se;
-       Editing *ed;
-       int a;
 
-       ed= G.scene->ed;
        if(ed==0) return;
 
        WHILE_SEQ(&ed->seqbase) {
+               if(seq->ipo == ipo)
+                       update_changed_seq_and_deps(seq, 0, 1);
+       }
+       END_SEQ
+}
 
-               if(seq->strip) {
+static int update_changed_seq_recurs(Sequence *seq, Sequence *changed_seq, int len_change, int ibuf_change)
+{
+       Sequence *subseq;
+       int a, free_imbuf = 0;
+       StripElem *se;
 
-                       if( seq->type==SEQ_META ) {
-                               ;
-                       }
-                       else {
-                               se= seq->strip->stripdata;
-                               for(a=0; a<seq->len; a++, se++) {
-                                       if(se->ibuf) {
-                                               IMB_freeImBuf(se->ibuf);
-                                               se->ibuf= 0;
-                                               se->ok= 1;
-                                               se->se1= se->se2= se->se3= 0;
-                                       }
-                               }
-                       }
+       /* recurs downwards to see if this seq depends on the changed seq */
 
-                       if(seq->type==SEQ_MOVIE) {
-                               if(seq->anim) {
-                                       IMB_free_anim(seq->anim);
-                                       seq->anim = 0;
-                               }
-                       }
+       if(seq == NULL)
+               return 0;
+
+       if(seq == changed_seq)
+               free_imbuf = 1;
+       
+       for(subseq=seq->seqbase.first; subseq; subseq=subseq->next)
+               if(update_changed_seq_recurs(subseq, changed_seq, len_change, ibuf_change))
+                       free_imbuf = 1;
+       
+       if(seq->seq1)
+               if(update_changed_seq_recurs(seq->seq1, changed_seq, len_change, ibuf_change))
+                       free_imbuf = 1;
+       if(seq->seq2 && (seq->seq2 != seq->seq1))
+               if(update_changed_seq_recurs(seq->seq2, changed_seq, len_change, ibuf_change))
+                       free_imbuf = 1;
+       if(seq->seq3 && (seq->seq3 != seq->seq1) && (seq->seq3 != seq->seq2))
+               if(update_changed_seq_recurs(seq->seq3, changed_seq, len_change, ibuf_change))
+                       free_imbuf = 1;
+       
+       if(free_imbuf) {
+               if(ibuf_change) {
+                       for(a=0, se= seq->strip->stripdata; a<seq->len; a++, se++)
+                               free_imbuf_strip_elem(se);
+               
+                       if(seq->type==SEQ_MOVIE)
+                               free_anim_seq(seq);
                }
+
+               if(len_change)
+                       calc_sequence(seq);
        }
-       END_SEQ
+       
+       return free_imbuf;
+}
+
+void update_changed_seq_and_deps(Sequence *changed_seq, int len_change, int ibuf_change)
+{
+       Editing *ed= G.scene->ed;
+       Sequence *seq;
+
+       if (!ed) return;
+
+       for (seq=ed->seqbase.first; seq; seq=seq->next)
+               update_changed_seq_recurs(seq, changed_seq, len_change, ibuf_change);
 }
 
 /* bad levell call... */
index 41d73597652515392adde660d7e84207aa7219ef..059f4959f76753deddd8acbd02472132462aeacb 100644 (file)
@@ -3964,6 +3964,9 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                scrarea_queue_winredraw(curarea);
                        }
                        break;
+               case RKEY:
+                       reassign_inputs_seq_effect();
+                       break;
                case SKEY:
                        if((G.qual==LR_SHIFTKEY))
                                seq_snap_menu();