From efde4dbba868c3717e21fe87a8c28314129e8fb4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 10 May 2012 15:10:51 +0000 Subject: [PATCH] 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. --- source/blender/blenkernel/BKE_sound.h | 4 +- source/blender/blenkernel/intern/sound.c | 10 +- source/blender/makesrna/intern/rna_internal.h | 2 + source/blender/makesrna/intern/rna_scene.c | 9 + .../blender/makesrna/intern/rna_sequencer.c | 242 +++++---- .../makesrna/intern/rna_sequencer_api.c | 506 +++++++++++++++++- 6 files changed, 672 insertions(+), 101 deletions(-) diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h index 5234f10ddb3..6f78e374423 100644 --- a/source/blender/blenkernel/BKE_sound.h +++ b/source/blender/blenkernel/BKE_sound.h @@ -136,6 +136,8 @@ void sound_read_waveform(struct bSound* sound); void sound_update_scene(struct Scene* scene); -void* sound_get_factory(void* sound); +void *sound_get_factory(void* sound); + +float sound_get_length(struct bSound *sound); #endif diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 896d0f4cf08..e4aa60805ee 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -756,6 +756,14 @@ void *sound_get_factory(void *sound) return ((struct bSound *) sound)->playback_handle; } +/* stupid wrapper because AUD_C-API.h includes Python.h which makesrna doesn't like */ +float sound_get_length(struct bSound* sound) +{ + AUD_SoundInfo info = AUD_getInfo(sound->playback_handle); + + return info.length; +} + #else // WITH_AUDASPACE #include "BLI_utildefines.h" @@ -797,5 +805,5 @@ void sound_set_scene_sound_volume(void* handle, float volume, char animated) { ( void sound_set_scene_sound_pan(void* handle, float pan, char animated) { (void)handle; (void)pan; (void)animated; } void sound_set_scene_volume(struct Scene *scene, float volume) { (void)scene; (void)volume; } void sound_set_scene_sound_pitch(void* handle, float pitch, char animated) { (void)handle; (void)pitch; (void)animated; } - +float sound_get_length(struct bSound* sound) { (void)sound; return 0; } #endif // WITH_AUDASPACE diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 155c9c67e4a..cf00764cd4e 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -267,6 +267,8 @@ void RNA_api_controller(struct StructRNA *srna); void RNA_api_actuator(struct StructRNA *srna); void RNA_api_texture(struct StructRNA *srna); void RNA_api_environment_map(struct StructRNA *srna); +void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop); +void RNA_api_sequence_elements(BlenderRNA *brna, PropertyRNA *cprop); /* main collection functions */ void RNA_def_main_cameras(BlenderRNA *brna, PropertyRNA *cprop); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 2cb89ec25e9..787b8ea9d22 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -625,6 +625,14 @@ static void rna_Scene_all_keyingsets_next(CollectionPropertyIterator *iter) iter->valid = (internal->link != NULL); } +static PointerRNA rna_Scene_sequence_editor_get(PointerRNA *ptr) +{ + Scene *scene = (Scene *)ptr->data; + /* mallocs an Editing (if it doesn't exist) so you can access + * Scene.sequence_editor functions without having to manually + * add a Sequence using the UI to create the SequenceEditor */ + return rna_pointer_inherit_refine(ptr, &RNA_SequenceEditor, seq_give_editing(scene, TRUE)); +} static char *rna_RenderSettings_path(PointerRNA *UNUSED(ptr)) { @@ -4307,6 +4315,7 @@ void RNA_def_scene(BlenderRNA *brna) /* Sequencer */ prop = RNA_def_property(srna, "sequence_editor", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "ed"); + RNA_def_property_pointer_funcs(prop, "rna_Scene_sequence_editor_get", NULL, NULL, NULL); RNA_def_property_struct_type(prop, "SequenceEditor"); RNA_def_property_ui_text(prop, "Sequence Editor", ""); diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 8cb44da250b..c362a117d3f 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -49,6 +49,15 @@ #include "WM_types.h" #include "BLI_math.h" +typedef struct EffectInfo +{ + const char *struct_name; + const char *ui_name; + const char *ui_desc; + void (*func)(StructRNA*); + int inputs; +} EffectInfo; + #ifdef RNA_RUNTIME /* build a temp referene to the parent */ @@ -401,14 +410,21 @@ static StructRNA* rna_Sequence_refine(struct PointerRNA *ptr) case SEQ_SOUND: return &RNA_SoundSequence; case SEQ_CROSS: + return &RNA_CrossSequence; case SEQ_ADD: + return &RNA_AddSequence; case SEQ_SUB: + return &RNA_SubtractSequence; case SEQ_ALPHAOVER: + return &RNA_AlphaOverSequence; case SEQ_ALPHAUNDER: + return &RNA_AlphaUnderSequence; case SEQ_GAMCROSS: + return &RNA_GammaCrossSequence; case SEQ_MUL: + return &RNA_MultiplySequence; case SEQ_OVERDROP: - return &RNA_EffectSequence; + return &RNA_OverDropSequence; case SEQ_MULTICAM: return &RNA_MulticamSequence; case SEQ_ADJUSTMENT: @@ -944,6 +960,19 @@ static void rna_def_strip_color_balance(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); */ } +EnumPropertyItem blend_mode_items[] = { + {SEQ_BLEND_REPLACE, "REPLACE", 0, "Replace", ""}, + {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", ""}, + {0, NULL, 0, NULL, NULL} +}; + static void rna_def_sequence(BlenderRNA *brna) { StructRNA *srna; @@ -973,18 +1002,6 @@ static void rna_def_sequence(BlenderRNA *brna) {SEQ_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""}, {SEQ_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""}, {0, NULL, 0, NULL, NULL}}; - - static const EnumPropertyItem blend_mode_items[] = { - {SEQ_BLEND_REPLACE, "REPLACE", 0, "Replace", ""}, - {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", ""}, - {0, NULL, 0, NULL, NULL}}; srna = RNA_def_struct(brna, "Sequence", NULL); RNA_def_struct_ui_text(srna, "Sequence", "Sequence strip in the sequence editor"); @@ -1004,11 +1021,8 @@ static void rna_def_sequence(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Type", ""); RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); - /*prop= RNA_def_property(srna, "ipo", PROP_POINTER, PROP_NONE); */ - /*RNA_def_property_ui_text(prop, "IPO Curves", "IPO curves used by this sequence"); */ /* flags */ - prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT); RNA_def_property_ui_text(prop, "Select", ""); @@ -1034,13 +1048,7 @@ static void rna_def_sequence(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Lock", "Lock strip so that it can't be transformed"); RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, NULL); - prop = RNA_def_property(srna, "waveform", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_AUDIO_DRAW_WAVEFORM); - RNA_def_property_ui_text(prop, "Draw Waveform", "Whether to draw the sound's waveform"); - RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, NULL); - /* strip positioning */ - prop = RNA_def_property(srna, "frame_final_duration", PROP_INT, PROP_TIME); RNA_def_property_range(prop, 1, MAXFRAME); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -1154,24 +1162,6 @@ static void rna_def_sequence(BlenderRNA *brna) "to this frame"); RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); - /* effect strip inputs */ - - prop = RNA_def_property(srna, "input_count", PROP_INT, PROP_UNSIGNED); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_int_funcs(prop, "rna_Sequence_input_count_get", NULL, NULL); - - prop = RNA_def_property(srna, "input_1", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "seq1"); - RNA_def_property_ui_text(prop, "Input 1", "First input for the effect strip"); - - prop = RNA_def_property(srna, "input_2", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "seq2"); - RNA_def_property_ui_text(prop, "Input 2", "Second input for the effect strip"); - - prop = RNA_def_property(srna, "input_3", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "seq1"); - RNA_def_property_ui_text(prop, "Input 3", "Third input for the effect strip"); - RNA_api_sequence_strip(srna); } @@ -1189,6 +1179,7 @@ static void rna_def_editor(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "seqbase", NULL); RNA_def_property_struct_type(prop, "Sequence"); RNA_def_property_ui_text(prop, "Sequences", ""); + RNA_api_sequences(brna, prop); prop = RNA_def_property(srna, "sequences_all", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "seqbase", NULL); @@ -1207,6 +1198,7 @@ static void rna_def_editor(BlenderRNA *brna) prop = RNA_def_property(srna, "active_strip", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "act_seq"); RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Active Strip", "Sequencer's active strip"); prop = RNA_def_property(srna, "show_overlay", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "over_flag", SEQ_EDIT_OVERLAY_SHOW); @@ -1225,7 +1217,6 @@ static void rna_def_editor(BlenderRNA *brna) RNA_def_property_int_funcs(prop, "rna_SequenceEditor_overlay_frame_get", "rna_SequenceEditor_overlay_frame_set", NULL); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_SEQUENCER, NULL); - RNA_def_property_ui_text(prop, "Active Strip", "Sequencer's active strip"); } static void rna_def_filter_video(StructRNA *srna) @@ -1355,6 +1346,36 @@ static void rna_def_input(StructRNA *srna) RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); } +static void rna_def_effect_inputs(StructRNA *srna, int count) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "input_count", PROP_INT, PROP_UNSIGNED); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_int_funcs(prop, "rna_Sequence_input_count_get", NULL, NULL); + + if (count >= 1) { + prop = RNA_def_property(srna, "input_1", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "seq1"); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_NULL); + RNA_def_property_ui_text(prop, "Input 1", "First input for the effect strip"); + } + + if (count >= 2) { + prop = RNA_def_property(srna, "input_2", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "seq2"); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_NULL); + RNA_def_property_ui_text(prop, "Input 2", "Second input for the effect strip"); + } + + if (count == 3) { /* not used by any effects ...except maybe plugins? */ + prop = RNA_def_property(srna, "input_3", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "seq3"); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_NULL); + RNA_def_property_ui_text(prop, "Input 3", "Third input for the effect strip"); + } +} + static void rna_def_image(BlenderRNA *brna) { StructRNA *srna; @@ -1376,6 +1397,7 @@ static void rna_def_image(BlenderRNA *brna) RNA_def_property_collection_funcs(prop, "rna_SequenceEditor_elements_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_SequenceEditor_elements_length", NULL, NULL, NULL); + RNA_api_sequence_elements(brna, prop); rna_def_filter_video(srna); rna_def_proxy(srna); @@ -1532,6 +1554,11 @@ static void rna_def_sound(BlenderRNA *brna) RNA_def_property_string_funcs(prop, "rna_Sequence_filepath_get", "rna_Sequence_filepath_length", "rna_Sequence_filepath_set"); RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_filepath_update"); + + prop = RNA_def_property(srna, "waveform", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_AUDIO_DRAW_WAVEFORM); + RNA_def_property_ui_text(prop, "Draw Waveform", "Whether to draw the sound's waveform"); + RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, NULL); rna_def_input(srna); } @@ -1549,45 +1576,21 @@ static void rna_def_effect(BlenderRNA *brna) rna_def_proxy(srna); } -static void rna_def_multicam(BlenderRNA *brna) +static void rna_def_multicam(StructRNA *srna) { - StructRNA *srna; PropertyRNA *prop; - srna = RNA_def_struct(brna, "MulticamSequence", "Sequence"); - RNA_def_struct_ui_text(srna, "Multicam Select Sequence", - "Sequence strip to perform multicam editing: select channel from below"); - RNA_def_struct_sdna(srna, "Sequence"); - prop = RNA_def_property(srna, "multicam_source", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "multicam_source"); RNA_def_property_range(prop, 0, MAXSEQ-1); RNA_def_property_ui_text(prop, "Multicam Source Channel", ""); RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); - rna_def_filter_video(srna); - rna_def_proxy(srna); rna_def_input(srna); } -static void rna_def_adjustment(BlenderRNA *brna) +static void rna_def_wipe(StructRNA *srna) { - StructRNA *srna; -/* PropertyRNA *prop; */ - - srna = RNA_def_struct(brna, "AdjustmentSequence", "Sequence"); - RNA_def_struct_ui_text(srna, "Adjustment Layer Sequence", - "Sequence strip to perform filter adjustments to layers below"); - RNA_def_struct_sdna(srna, "Sequence"); - - rna_def_filter_video(srna); - rna_def_proxy(srna); - rna_def_input(srna); -} - -static void rna_def_wipe(BlenderRNA *brna) -{ - StructRNA *srna; PropertyRNA *prop; static const EnumPropertyItem wipe_type_items[] = { @@ -1606,8 +1609,6 @@ static void rna_def_wipe(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - srna = RNA_def_struct(brna, "WipeSequence", "EffectSequence"); - RNA_def_struct_ui_text(srna, "Wipe Sequence", "Sequence strip creating a wipe transition"); RNA_def_struct_sdna_from(srna, "WipeVars", "effectdata"); prop = RNA_def_property(srna, "blur_width", PROP_FLOAT, PROP_UNSIGNED); @@ -1642,13 +1643,10 @@ static void rna_def_wipe(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); } -static void rna_def_glow(BlenderRNA *brna) +static void rna_def_glow(StructRNA *srna) { - StructRNA *srna; PropertyRNA *prop; - - srna = RNA_def_struct(brna, "GlowSequence", "EffectSequence"); - RNA_def_struct_ui_text(srna, "Glow Sequence", "Sequence strip creating a glow effect"); + RNA_def_struct_sdna_from(srna, "GlowVars", "effectdata"); prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_NONE); @@ -1687,9 +1685,8 @@ static void rna_def_glow(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); } -static void rna_def_transform(BlenderRNA *brna) +static void rna_def_transform(StructRNA *srna) { - StructRNA *srna; PropertyRNA *prop; static const EnumPropertyItem interpolation_items[] = { @@ -1705,11 +1702,8 @@ static void rna_def_transform(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - srna = RNA_def_struct(brna, "TransformSequence", "EffectSequence"); - RNA_def_struct_ui_text(srna, "Transform Sequence", - "Sequence strip applying affine transformations to other strips"); RNA_def_struct_sdna_from(srna, "TransformVars", "effectdata"); - + prop = RNA_def_property(srna, "scale_start_x", PROP_FLOAT, PROP_UNSIGNED); RNA_def_property_float_sdna(prop, NULL, "ScalexIni"); RNA_def_property_ui_text(prop, "Scale X", ""); @@ -1759,30 +1753,24 @@ static void rna_def_transform(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); } -static void rna_def_solid_color(BlenderRNA *brna) +static void rna_def_solid_color(StructRNA *srna) { - StructRNA *srna; PropertyRNA *prop; - srna = RNA_def_struct(brna, "ColorSequence", "EffectSequence"); - RNA_def_struct_ui_text(srna, "Color Sequence", "Sequence strip creating an image filled with a single color"); RNA_def_struct_sdna_from(srna, "SolidColorVars", "effectdata"); - + prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "col"); RNA_def_property_ui_text(prop, "Color", ""); RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); } -static void rna_def_speed_control(BlenderRNA *brna) +static void rna_def_speed_control(StructRNA *srna) { - StructRNA *srna; PropertyRNA *prop; - srna = RNA_def_struct(brna, "SpeedControlSequence", "EffectSequence"); - RNA_def_struct_ui_text(srna, "SpeedControl Sequence", "Sequence strip to control the speed of other strips"); RNA_def_struct_sdna_from(srna, "SpeedControlVars", "effectdata"); - + prop = RNA_def_property(srna, "multiply_speed", PROP_FLOAT, PROP_UNSIGNED); RNA_def_property_float_sdna(prop, NULL, "globalSpeed"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* seq->facf0 is used to animate this */ @@ -1806,6 +1794,72 @@ static void rna_def_speed_control(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update"); } +static EffectInfo def_effects[] = { + {"AddSequence", "Add Sequence", + "Add Sequence", + NULL, 2}, + {"AdjustmentSequence", "Adjustment Layer Sequence", + "Sequence strip to perform filter adjustments to layers below", + rna_def_input, 0}, + {"AlphaOverSequence", "Alpha Over Sequence", + "Alpha Over Sequence", + NULL, 2}, + {"AlphaUnderSequence", "Alpha Under Sequence", + "Alpha Under Sequence", + NULL, 2}, + {"ColorSequence", "Color Sequence", + "Sequence strip creating an image filled with a single color", + rna_def_solid_color, 0}, + {"CrossSequence", "Cross Sequence", + "Cross Sequence", + NULL, 2}, + {"GammaCrossSequence", "Gamma Cross Sequence", + "Gamma Cross Sequence", + NULL, 2}, + {"GlowSequence", "Glow Sequence", + "Sequence strip creating a glow effect", + rna_def_glow, 1}, + {"MulticamSequence", "Multicam Select Sequence", + "Sequence strip to perform multicam editing", + rna_def_multicam, 0}, + {"MultiplySequence", "Multiply Sequence", + "Multiply Sequence", + NULL, 2}, + {"OverDropSequence", "Over Drop Sequence", + "Over Drop Sequence", + NULL, 2}, + {"SpeedControlSequence", "SpeedControl Sequence", + "Sequence strip to control the speed of other strips", + rna_def_speed_control, 1}, + {"SubtractSequence", "Subtract Sequence", + "Subtract Sequence", + NULL, 2}, + {"TransformSequence", "Transform Sequence", + "Sequence strip applying affine transformations to other strips", + rna_def_transform, 1}, + {"WipeSequence", "Wipe Sequence", + "Sequence strip creating a wipe transition", + rna_def_wipe, 1}, + {"", "", "", NULL, 0} +}; + +static void rna_def_effects(BlenderRNA *brna) +{ + StructRNA *srna; + EffectInfo *effect; + + for (effect = def_effects; effect->struct_name[0] != '\0'; effect++) { + srna = RNA_def_struct(brna, effect->struct_name, "EffectSequence"); + RNA_def_struct_ui_text(srna, effect->ui_name, effect->ui_desc); + RNA_def_struct_sdna(srna, "Sequence"); + + rna_def_effect_inputs(srna, effect->inputs); + + if (effect->func) + effect->func(srna); + } +} + void RNA_def_sequencer(BlenderRNA *brna) { rna_def_strip_element(brna); @@ -1824,13 +1878,7 @@ void RNA_def_sequencer(BlenderRNA *brna) rna_def_movieclip(brna); rna_def_sound(brna); rna_def_effect(brna); - rna_def_multicam(brna); - rna_def_adjustment(brna); - rna_def_wipe(brna); - rna_def_glow(brna); - rna_def_transform(brna); - rna_def_solid_color(brna); - rna_def_speed_control(brna); + rna_def_effects(brna); } #endif 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 #include #include @@ -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