diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-05-10 19:10:51 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-05-10 19:10:51 +0400 |
commit | efde4dbba868c3717e21fe87a8c28314129e8fb4 (patch) | |
tree | f58152eb37d5675c1171ee13c445186f294fe81a /source/blender/makesrna/intern/rna_sequencer_api.c | |
parent | f91fa9d2ce57ee6488b86260b9617db7fca3cb33 (diff) |
patch [#30871] VSE py-api
from Dan Eicher (dna)
--- message from the tracker
Classes for all effect types with proper input attributes
Added new/delete functions for SequenceEditor.sequences.
push/pop functions for ImageSequence.elements to add/remove images
Moved waveform from the base class to SoundSequence (probably should be renamed use_waveform or show_waveform)
Fixed user count for scene and movie clip types
--- my own comments
- dont have blending mode argument from sequencer.new_*() functions. Better edit this after.
- dont change waveform attribute, seems unrelated change and should be kept for sound afaik.
- dont apply scene, clip usercount changes - Sergey dealt with these separately.
Diffstat (limited to 'source/blender/makesrna/intern/rna_sequencer_api.c')
-rw-r--r-- | source/blender/makesrna/intern/rna_sequencer_api.c | 506 |
1 files changed, 504 insertions, 2 deletions
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index 20ceaec8974..7a406a02d3f 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -24,8 +24,6 @@ * \ingroup RNA */ - - #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -39,10 +37,30 @@ #include "DNA_scene_types.h" #include "DNA_sequence_types.h" +extern EnumPropertyItem blend_mode_items[]; + #ifdef RNA_RUNTIME +//#include "DNA_anim_types.h" +#include "DNA_image_types.h" +#include "DNA_scene_types.h" +#include "DNA_sequence_types.h" +#include "DNA_sound_types.h" + +#include "BLI_path_util.h" /* BLI_split_dirfile */ + +#include "BKE_image.h" +#include "BKE_library.h" /* id_us_plus */ +#include "BKE_movieclip.h" + #include "BKE_report.h" #include "BKE_sequencer.h" +#include "BKE_sound.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "WM_api.h" static void rna_Sequence_swap_internal(Sequence *seq_self, ReportList *reports, Sequence *seq_other) { @@ -52,6 +70,317 @@ static void rna_Sequence_swap_internal(Sequence *seq_self, ReportList *reports, BKE_report(reports, RPT_ERROR, error_msg); } +static Sequence *alloc_generic_sequence(Editing *ed, const char *name, int start_frame, + int channel, int type, const char *file) +{ + Sequence *seq; + Strip *strip; + StripElem *se; + + seq = alloc_sequence(ed->seqbasep, start_frame, channel); + seq->type = type; + + BLI_strncpy(seq->name + 2, name, sizeof(seq->name) - 2); + seqbase_unique_name_recursive(&ed->seqbase, seq); + + seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); + seq->strip->us = 1; + + if (file) { + strip->stripdata = se = MEM_callocN(sizeof(StripElem), "stripelem"); + BLI_split_dirfile(file, strip->dir, se->name, sizeof(strip->dir), sizeof(se->name)); + } + else { + strip->stripdata = NULL; + } + + return seq; +} + +static Scene *editing_get_scene(Main *bmain, Editing *ed) +{ + Scene *scene; + for (scene = bmain->scene.first; scene; scene = scene->id.next) + if (scene->ed == ed) + break; + return scene; +} + +static Sequence *rna_Sequences_new_clip(Editing *ed, Main *bmain, bContext *C, ReportList *reports, + const char *name, MovieClip *clip, int channel, + int start_frame) +{ + Sequence *seq; + Scene *scene = editing_get_scene(bmain, ed); + + seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_MOVIECLIP, clip->name); + seq->clip = clip; + seq->len = BKE_movieclip_get_duration(clip); + id_us_plus((ID *)clip); + + calc_sequence_disp(scene, seq); + + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); + + return seq; +} + +static Sequence *rna_Sequences_new_scene(Editing *ed, Main *bmain, bContext *C, ReportList *reports, + const char *name, Scene *sce_seq, int channel, + int start_frame) +{ + Sequence *seq; + + Scene *scene = editing_get_scene(bmain, ed); + + seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_SCENE, NULL); + seq->scene = sce_seq; + seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1; + seq->scene_sound = sound_scene_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0); + id_us_plus((ID *)sce_seq); + + calc_sequence_disp(scene, seq); + + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); + + return seq; +} + +static Sequence *rna_Sequences_new_image(Editing *ed, Main *bmain, bContext *C, ReportList *reports, + const char *name, const char* file, int channel, + int start_frame) +{ + Sequence *seq; + + Scene *scene = editing_get_scene(bmain, ed); + + seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_IMAGE, file); + seq->len = 1; + + if (seq->strip->stripdata->name[0] == '\0') { + BKE_report(reports, RPT_ERROR, "Sequences.new_image: unable to open image file"); + BLI_remlink(&ed->seqbase, seq); + seq_free_sequence(scene, seq); + return NULL; + } + + calc_sequence_disp(scene, seq); + + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); + + return seq; +} + +static Sequence *rna_Sequences_new_movie(Editing *ed, Main *bmain, bContext *C, ReportList *reports, + const char *name, const char* file, int channel, + int start_frame) +{ + Sequence *seq; + + Scene *scene; + struct anim *an = openanim(file, IB_rect, 0); + + if (an == NULL) { + BKE_report(reports, RPT_ERROR, "Sequences.new_movie: unable to open movie file"); + return NULL; + } + + scene = editing_get_scene(bmain, ed); + + seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_MOVIE, file); + seq->anim = an; + seq->anim_preseek = IMB_anim_get_preseek(an); + seq->len = IMB_anim_get_duration(an, IMB_TC_RECORD_RUN); + + calc_sequence_disp(scene, seq); + + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); + + return seq; +} + +#ifdef WITH_AUDASPACE +static Sequence *rna_Sequences_new_sound(Editing *ed, Main *bmain, bContext *C, ReportList *reports, + const char *name, const char* file, int channel, int start_frame) +{ + Sequence *seq; + + Scene *scene = editing_get_scene(bmain, ed); + bSound *sound = sound_new_file(bmain, file); + + if (sound == NULL || sound->playback_handle == NULL) { + BKE_report(reports, RPT_ERROR, "Sequences.new_sound: unable to open sound file"); + return NULL; + } + + seq = alloc_generic_sequence(ed, name, start_frame, channel, SEQ_SOUND, sound->name); + seq->sound = sound; + seq->len = ceil(sound_get_length(sound) * FPS); + + seq->scene_sound = sound_add_scene_sound(scene, seq, start_frame, start_frame + seq->len, 0); + + calc_sequence_disp(scene, seq); + + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); + + return seq; +} +#else /* WITH_AUDASPACE */ +static Sequence *rna_Sequences_new_sound(Editing *ed, Main *bmain, bContext *C, ReportList *reports, + const char *name, bSound *sound, int channel, int start_frame) +{ + (void)ed; + (void)bmain; + (void)C; + (void)name; + (void)sound; + channel = start_frame = 0; + + BKE_report(reports, RPT_ERROR, "Blender compiled without Audaspace support."); + return NULL; +} +#endif /* WITH_AUDASPACE */ + +static Sequence *rna_Sequences_new_effect(Editing *ed, Main *bmain, bContext *C, ReportList *reports, + const char *name, int type, int channel, + int start_frame, int end_frame, + Sequence *seq1, Sequence *seq2, Sequence *seq3) +{ + Sequence *seq; + struct SeqEffectHandle sh; + Scene *scene = editing_get_scene(bmain, ed); + + switch (get_sequence_effect_num_inputs(type)) { + case 0: + if (end_frame <= start_frame) { + BKE_report(reports, RPT_ERROR, + "Sequences.new_effect: End frame not set"); + return NULL; + } + break; + case 1: + if (seq1 == NULL) { + BKE_report(reports, RPT_ERROR, + "Sequences.new_effect: Effect takes 1 input sequence"); + return NULL; + } + break; + case 2: + if (seq1 == NULL || seq2 == NULL) { + BKE_report(reports, RPT_ERROR, + "Sequences.new_effect: Effect takes 2 input sequences"); + return NULL; + } + break; + case 3: + if (seq1 == NULL || seq2 == NULL || seq3 == NULL) { + BKE_report(reports, RPT_ERROR, + "Sequences.new_effect: Effect takes 3 input sequences"); + return NULL; + } + break; + default: + BKE_report(reports, RPT_ERROR, + "Sequences.new_effect: get_sequence_effect_num_inputs() > 3 (should never happen)"); + return NULL; + } + + seq = alloc_generic_sequence(ed, name, start_frame, channel, type, NULL); + + sh = get_sequence_effect(seq); + + seq->seq1 = seq1; + seq->seq2 = seq2; + seq->seq3 = seq3; + + sh.init(seq); + + if (!seq1) { /* effect has no deps */ + seq->len = 1; + seq_tx_set_final_right(seq, end_frame); + } + + seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE; + + calc_sequence(scene, seq); + + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); + + return seq; +} + +static void rna_Sequences_remove(Editing *ed, Main *bmain, bContext *C, Sequence *seq) +{ + Scene *scene; + + for (scene = bmain->scene.first; scene; scene = scene->id.next) + if (scene->ed == ed) + break; + + BLI_remlink(&ed->seqbase, seq); + seq_free_sequence(scene, seq); + + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); +} + +static StripElem *rna_SequenceElements_push(Sequence *seq, Main *bmain, bContext *C, const char* filename) +{ + Sequence *seqn; + Scene *scene; + StripElem *se; + + for (scene = bmain->scene.first; scene; scene = scene->id.next) { + Editing *ed = seq_give_editing(scene, FALSE); + if (ed) { + for (seqn = ed->seqbase.first; seqn; seqn = seqn->next) { + if (seqn == seq) + break; + } + } + } + + seq->strip->stripdata = se = MEM_reallocN(seq->strip->stripdata, sizeof(StripElem)*(seq->len+1)); + se += seq->len; + BLI_strncpy(se->name, filename, sizeof(se->name)); + seq->len++; + + calc_sequence_disp(scene, seq); + + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); + + return se; +} + +static void rna_SequenceElements_pop(Sequence *seq, Main *bmain, bContext *C, ReportList *reports) +{ + Sequence *seqn; + Scene *scene; + + if (seq->len == 1) { + BKE_report(reports, RPT_ERROR, "SequenceElements.pop: can not pop the last element"); + return; + } + + for (scene = bmain->scene.first; scene; scene = scene->id.next) { + Editing *ed = seq_give_editing(scene, FALSE); + if (ed) { + for (seqn = ed->seqbase.first; seqn; seqn = seqn->next) { + if (seqn == seq) + break; + } + } + } + + /* just chop off the end ...what could possibly go wrong? */ + seq->strip->stripdata = MEM_reallocN(seq->strip->stripdata, sizeof(StripElem)*(seq->len-1)); + seq->len--; + + calc_sequence_disp(scene, seq); + + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); +} + + #else void RNA_api_sequence_strip(StructRNA *srna) @@ -73,4 +402,177 @@ void RNA_api_sequence_strip(StructRNA *srna) RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL); } +void RNA_api_sequence_elements(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + PropertyRNA *parm; + FunctionRNA *func; + + RNA_def_property_srna(cprop, "SequenceElements"); + srna = RNA_def_struct(brna, "SequenceElements", NULL); + RNA_def_struct_sdna(srna, "Sequence"); + RNA_def_struct_ui_text(srna, "SequenceElements", "Collection of SequenceElement"); + + func = RNA_def_function(srna, "push", "rna_SequenceElements_push"); + RNA_def_function_flag(func, FUNC_USE_MAIN|FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Push an image from ImageSequence.directory"); + parm = RNA_def_string(func, "file", "File", 0, "", "Filepath to image"); + RNA_def_property_flag(parm, PROP_REQUIRED); + /* return type */ + parm = RNA_def_pointer(func, "elem", "SequenceElement", "", "New SequenceElement"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "pop", "rna_SequenceElements_pop"); + RNA_def_function_flag(func, FUNC_USE_REPORTS|FUNC_USE_MAIN|FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Pop an image off the collection"); +} + +void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + PropertyRNA *parm; + FunctionRNA *func; + + static EnumPropertyItem seq_effect_items[] = { + {SEQ_CROSS, "CROSS", 0, "Cross", ""}, + {SEQ_ADD, "ADD", 0, "Add", ""}, + {SEQ_SUB, "SUBTRACT", 0, "Subtract", ""}, + {SEQ_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", ""}, + {SEQ_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", ""}, + {SEQ_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", ""}, + {SEQ_MUL, "MULTIPLY", 0, "Multiply", ""}, + {SEQ_OVERDROP, "OVER_DROP", 0, "Over Drop", ""}, + // {SEQ_PLUGIN, "PLUGIN", 0, "Plugin", ""}, + {SEQ_WIPE, "WIPE", 0, "Wipe", ""}, + {SEQ_GLOW, "GLOW", 0, "Glow", ""}, + {SEQ_TRANSFORM, "TRANSFORM", 0, "Transform", ""}, + {SEQ_COLOR, "COLOR", 0, "Color", ""}, + {SEQ_SPEED, "SPEED", 0, "Speed", ""}, + {SEQ_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""}, + {SEQ_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""}, + {0, NULL, 0, NULL, NULL} + }; + + RNA_def_property_srna(cprop, "Sequences"); + srna = RNA_def_struct(brna, "Sequences", NULL); + RNA_def_struct_sdna(srna, "Editing"); + RNA_def_struct_ui_text(srna, "Sequences", "Collection of Sequences"); + + func = RNA_def_function(srna, "new_clip", "rna_Sequences_new_clip"); + RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_MAIN | FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Add a new movie clip sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_pointer(func, "clip", "MovieClip", "", "Movie clip to add"); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL); + parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", + "The channel for the new sequence", 0, MAXSEQ - 1); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + "The start frame for the new sequence", -MAXFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); + /* return type */ + parm = RNA_def_pointer(func, "sequence", "Sequence", "", "New Sequence"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "new_scene", "rna_Sequences_new_scene"); + RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_MAIN | FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Add a new scene sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene to add"); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL); + parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", + "The channel for the new sequence", 0, MAXSEQ - 1); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + "The start frame for the new sequence", -MAXFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); + /* return type */ + parm = RNA_def_pointer(func, "sequence", "Sequence", "", "New Sequence"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "new_image", "rna_Sequences_new_image"); + RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_MAIN | FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Add a new image sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to image"); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", + "The channel for the new sequence", 0, MAXSEQ - 1); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + "The start frame for the new sequence", -MAXFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); + /* return type */ + parm = RNA_def_pointer(func, "sequence", "Sequence", "", "New Sequence"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "new_movie", "rna_Sequences_new_movie"); + RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_MAIN | FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Add a new movie sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to movie"); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", + "The channel for the new sequence", 0, MAXSEQ - 1); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + "The start frame for the new sequence", -MAXFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); + /* return type */ + parm = RNA_def_pointer(func, "sequence", "Sequence", "", "New Sequence"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "new_sound", "rna_Sequences_new_sound"); + RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_MAIN | FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Add a new movie clip sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to movie"); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", + "The channel for the new sequence", 0, MAXSEQ - 1); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + "The start frame for the new sequence", -MAXFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); + /* return type */ + parm = RNA_def_pointer(func, "sequence", "Sequence", "", "New Sequence"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "new_effect", "rna_Sequences_new_effect"); + RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_MAIN | FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Add a new effect sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_enum(func, "type", seq_effect_items, 0, "Type", + "type for the new sequence"); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "channel", 0, 0, MAXSEQ - 1, "Channel", + "The channel for the new sequence", 0, MAXSEQ - 1); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", + "The start frame for the new sequence", -MAXFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "end_frame", 0, -MAXFRAME, MAXFRAME, "", + "The end frame for the new sequence", -MAXFRAME, MAXFRAME); + parm = RNA_def_pointer(func, "seq1", "Sequence", "", "Sequence 1 for effect"); + parm = RNA_def_pointer(func, "seq2", "Sequence", "", "Sequence 2 for effect"); + parm = RNA_def_pointer(func, "seq3", "Sequence", "", "Sequence 3 for effect"); + /* return type */ + parm = RNA_def_pointer(func, "sequence", "Sequence", "", "New Sequence"); + RNA_def_function_return(func, parm); + + + func = RNA_def_function(srna, "remove", "rna_Sequences_remove"); + RNA_def_function_flag(func, FUNC_USE_MAIN|FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, "Remove a Sequence"); + parm = RNA_def_pointer(func, "sequence", "Sequence", "", "Sequence to remove"); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL); +} + + #endif |