Merging r50016 through r50021 from trunk into soc-2011-tomato

This commit is contained in:
Sergey Sharybin
2012-08-19 15:44:59 +00:00
19 changed files with 1761 additions and 272 deletions

View File

@@ -75,7 +75,7 @@ Example layouts:
* layout.row()
Use row(), when you want more than 1 propertey in one line.
Use row(), when you want more than 1 property in one line.
.. code-block:: python
@@ -145,7 +145,7 @@ Even though you're not looping on the list data **python is**, so you need to be
Modifying Lists
^^^^^^^^^^^^^^^
In python we can add and remove from a list, This is slower when the list length is modified, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place.
In python we can add and remove from a list, this is slower when the list length is modified, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place.
The most simple way to add onto the end of the list is to use ``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and the fastest way to remove an item is ``my_list.pop()`` or ``del my_list[-1]``.
@@ -154,13 +154,13 @@ To use an index you can use ``my_list.insert(index, list_item)`` or ``list.pop(i
Sometimes its faster (but more memory hungry) to just rebuild the list.
Say you want to remove all triangle faces in a list.
Say you want to remove all triangular faces in a list.
Rather than...
.. code-block:: python
faces = mesh.faces[:] # make a list copy of the meshes faces
faces = mesh.tessfaces[:] # make a list copy of the meshes faces
f_idx = len(faces) # Loop backwards
while f_idx: # while the value is not 0
f_idx -= 1
@@ -173,13 +173,13 @@ It's faster to build a new list with list comprehension.
.. code-block:: python
faces = [f for f in mesh.faces if len(f.vertices) != 3]
faces = [f for f in mesh.tessfaces if len(f.vertices) != 3]
Adding List Items
^^^^^^^^^^^^^^^^^
If you have a list that you want to add onto another list, rather then...
If you have a list that you want to add onto another list, rather than...
.. code-block:: python
@@ -205,6 +205,14 @@ This example shows a very sub-optimal way of making a reversed list.
reverse_list.insert(0, list_item)
Python provides more convenient ways to reverse a list using the slice method, but you may want to time this before relying on it too much:
.. code-block:: python
some_reversed_list = some_list[::-1]
Removing List Items
^^^^^^^^^^^^^^^^^^^
@@ -224,7 +232,7 @@ Here is an example of how to remove items in 1 loop, removing the last items fir
my_list.pop(list_index)
This example shows a fast way of removing items, for use in cases were where you can alter the list order without breaking the scripts functionality. This works by swapping 2 list items, so the item you remove is always last.
This example shows a fast way of removing items, for use in cases where you can alter the list order without breaking the scripts functionality. This works by swapping 2 list items, so the item you remove is always last.
.. code-block:: python
@@ -243,9 +251,9 @@ When removing many items in a large list this can provide a good speedup.
Avoid Copying Lists
^^^^^^^^^^^^^^^^^^^
When passing a list/dictionary to a function, it is faster to have the function modify the list rather then returning a new list so python doesn't have to duplicate the list in memory.
When passing a list/dictionary to a function, it is faster to have the function modify the list rather than returning a new list so python doesn't have to duplicate the list in memory.
Functions that modify a list in-place are more efficient then functions that create new lists.
Functions that modify a list in-place are more efficient than functions that create new lists.
This is generally slower so only use for functions when it makes sense not to modify the list in place.
@@ -273,22 +281,22 @@ Here are 3 ways of joining multiple strings into 1 string for writing
This really applies to any area of your code that involves a lot of string joining.
Pythons string addition, *don't use if you can help it, especially when writing data in a loop.*
Pythons string addition, *don't use if you can help it, especially when writing data in a loop.*
>>> file.write(str1 + " " + str2 + " " + str3 + "\n")
String formatting. Use this when you're writing string data from floats and int's
String formatting. Use this when you're writing string data from floats and ints
>>> file.write("%s %s %s\n" % (str1, str2, str3))
Pythons string joining function. To join a list of strings
Pythons string joining function. To join a list of strings
>>> file.write(" ".join([str1, str2, str3, "\n"]))
join is fastest on many strings, string formatting is quite fast too (better for converting data types). String arithmetic is slowest.
join is fastest on many strings, `string formatting <http://docs.python.org/py3k/library/string.html#string-formatting>`_ is quite fast too (better for converting data types). String arithmetic is slowest.
Parsing Strings (Import/Exporting)
@@ -296,12 +304,12 @@ Parsing Strings (Import/Exporting)
Since many file formats are ASCII, the way you parse/export strings can make a large difference in how fast your script runs.
When importing strings to make into blender there are a few ways to parse the string.
There are a few ways to parse strings when importing them into Blender.
Parsing Numbers
^^^^^^^^^^^^^^^
Use ``float(string)`` rather than ``eval(string)``, if you know the value will be an int then ``int(string)``, float() will work for an int too but its faster to read ints with int().
Use ``float(string)`` rather than ``eval(string)``, if you know the value will be an int then ``int(string)``, float() will work for an int too but it's faster to read ints with int().
Checking String Start/End
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -318,7 +326,7 @@ Using ``startswith()`` is slightly faster (approx 5%) and also avoids a possible
my_string.endswith("foo_bar") can be used for line endings too.
if your unsure whether the text is upper or lower case use lower or upper string function.
If you are unsure whether the text is upper or lower case use ``lower()`` or ``upper()`` string function.
>>> if line.lower().startswith("vert ")
@@ -328,7 +336,7 @@ Use try/except Sparingly
The **try** statement is useful to save time writing error checking code.
However **try** is significantly slower then an **if** since an exception has to be set each time, so avoid using **try** in areas of your code that execute in a loop and runs many times.
However **try** is significantly slower than an **if** since an exception has to be set each time, so avoid using **try** in areas of your code that execute in a loop and runs many times.
There are cases where using **try** is faster than checking whether the condition will raise an error, so it is worth experimenting.
@@ -336,7 +344,7 @@ There are cases where using **try** is faster than checking whether the conditio
Value Comparison
----------------
Python has two ways to compare values ``a == b`` and ``a is b``, The difference is that ``==`` may run the objects comparison function ``__cmp__()`` where as ``is`` compares identity, that both variables reference the same item in memory.
Python has two ways to compare values ``a == b`` and ``a is b``, the difference is that ``==`` may run the objects comparison function ``__cmp__()`` whereas ``is`` compares identity, that both variables reference the same item in memory.
In cases where you know you are checking for the same value which is referenced from multiple places, ``is`` is faster.
@@ -344,7 +352,7 @@ In cases where you know you are checking for the same value which is referenced
Time Your Code
--------------
While developing a script its good to time it to be aware of any changes in performance, this can be done simply.
While developing a script it's good to time it to be aware of any changes in performance, this can be done simply.
.. code-block:: python

View File

@@ -786,7 +786,7 @@ class IMAGE_PT_paint_curve(BrushButtonsPanel, Panel):
toolsettings = context.tool_settings.image_paint
brush = toolsettings.brush
layout.template_curve_mapping(brush, "curve")
layout.template_curve_mapping(brush, "curve", type='COLOR')
row = layout.row(align=True)
row.operator("brush.curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH'

View File

@@ -28,6 +28,29 @@ def act_strip(context):
return None
def draw_color_balance(layout, color_balance):
col = layout.column()
col.label(text="Lift:")
col.template_color_wheel(color_balance, "lift", value_slider=True, cubic=True)
row = col.row()
row.prop(color_balance, "lift", text="")
row.prop(color_balance, "invert_lift", text="Inverse")
col = layout.column()
col.label(text="Gamma:")
col.template_color_wheel(color_balance, "gamma", value_slider=True, lock_luminosity=True, cubic=True)
row = col.row()
row.prop(color_balance, "gamma", text="")
row.prop(color_balance, "invert_gamma", text="Inverse")
col = layout.column()
col.label(text="Gain:")
col.template_color_wheel(color_balance, "gain", value_slider=True, lock_luminosity=True, cubic=True)
row = col.row()
row.prop(color_balance, "gain", text="")
row.prop(color_balance, "invert_gain", text="Inverse")
class SEQUENCER_HT_header(Header):
bl_space_type = 'SEQUENCE_EDITOR'
@@ -442,7 +465,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
if strip.is_supports_mask:
col = layout.column()
col.prop_search(strip, "input_mask", sequencer, "sequences")
col.prop_search(strip, "input_mask_strip", sequencer, "sequences", text="Mask")
if strip.type == 'COLOR':
layout.prop(strip, "color")
@@ -772,26 +795,7 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel, Panel):
layout.prop(strip, "use_color_balance")
if strip.use_color_balance and strip.color_balance: # TODO - need to add this somehow
col = layout.column()
col.label(text="Lift:")
col.template_color_wheel(strip.color_balance, "lift", value_slider=True, cubic=True)
row = col.row()
row.prop(strip.color_balance, "lift", text="")
row.prop(strip.color_balance, "invert_lift", text="Inverse")
col = layout.column()
col.label(text="Gamma:")
col.template_color_wheel(strip.color_balance, "gamma", value_slider=True, lock_luminosity=True, cubic=True)
row = col.row()
row.prop(strip.color_balance, "gamma", text="")
row.prop(strip.color_balance, "invert_gamma", text="Inverse")
col = layout.column()
col.label(text="Gain:")
col.template_color_wheel(strip.color_balance, "gain", value_slider=True, lock_luminosity=True, cubic=True)
row = col.row()
row.prop(strip.color_balance, "gain", text="")
row.prop(strip.color_balance, "invert_gain", text="Inverse")
draw_color_balance(layout, strip.color_balance)
class SEQUENCER_PT_proxy(SequencerButtonsPanel, Panel):
@@ -884,5 +888,45 @@ class SEQUENCER_PT_view(SequencerButtonsPanel_Output, Panel):
col.template_colormanaged_view_settings(st, "view_settings", True)
class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel):
bl_label = "Modifiers"
def draw(self, context):
layout = self.layout
strip = act_strip(context)
sequencer = context.scene.sequence_editor
layout.operator_menu_enum("sequencer.strip_modifier_add", "type")
for mod in strip.modifiers:
box = layout.box()
row = box.row()
row.prop(mod, "show_expanded", text="", emboss=False)
row.prop(mod, "name")
row.prop(mod, "mute", text="")
props = row.operator("sequencer.strip_modifier_remove", text="", icon='X')
props.name = mod.name
if mod.show_expanded:
row = box.row()
row.prop(mod, "input_mask_type", expand=True)
if mod.input_mask_type == 'STRIP':
box.prop_search(mod, "input_mask_strip", sequencer, "sequences", text="Mask")
else:
box.prop(mod, "input_mask_id")
if mod.type == 'COLOR_BALANCE':
box.prop(mod, "color_multiply")
draw_color_balance(box, mod.color_balance)
elif mod.type == 'CURVES':
box.template_curve_mapping(mod, "curve_mapping", type='COLOR')
elif mod.type == 'HUE_CORRECT':
box.template_curve_mapping(mod, "curve_mapping", type='HUE')
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)

View File

@@ -50,8 +50,11 @@ struct rctf;
# define DO_INLINE static inline
#endif
void curvemapping_set_defaults(struct CurveMapping *cumap, int tot, float minx, float miny, float maxx, float maxy);
struct CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy);
void curvemapping_free_data(struct CurveMapping *cumap);
void curvemapping_free(struct CurveMapping *cumap);
void curvemapping_copy_data(struct CurveMapping *target, struct CurveMapping *cumap);
struct CurveMapping *curvemapping_copy(struct CurveMapping *cumap);
void curvemapping_set_black_white(struct CurveMapping *cumap, const float black[3], const float white[3]);
@@ -72,6 +75,7 @@ float curvemap_evaluateF(struct CurveMap *cuma, float value);
float curvemapping_evaluateF(struct CurveMapping *cumap, int cur, float value);
void curvemapping_evaluate3F(struct CurveMapping *cumap, float vecout[3], const float vecin[3]);
void curvemapping_evaluateRGBF(struct CurveMapping *cumap, float vecout[3], const float vecin[3]);
void curvemapping_evaluate_premulRGB(struct CurveMapping *cumap, unsigned char vecout_byte[3], const unsigned char vecin_byte[3]);
void curvemapping_evaluate_premulRGBF(struct CurveMapping *cumap, float vecout[3], const float vecin[3]);
void curvemapping_do_ibuf(struct CurveMapping *cumap, struct ImBuf *ibuf);
void curvemapping_premultiply(struct CurveMapping *cumap, int restore);

View File

@@ -31,11 +31,14 @@
*/
struct bContext;
struct StripColorBalance;
struct Editing;
struct ImBuf;
struct Main;
struct Mask;
struct Scene;
struct Sequence;
struct SequenceModifierData;
struct Strip;
struct StripElem;
struct bSound;
@@ -241,6 +244,10 @@ void BKE_sequencer_cache_put(SeqRenderData context, struct Sequence *seq, float
void BKE_sequencer_cache_cleanup_sequence(struct Sequence *seq);
struct ImBuf *BKE_sequencer_preprocessed_cache_get(SeqRenderData context, struct Sequence *seq, float cfra, seq_stripelem_ibuf_t type);
void BKE_sequencer_preprocessed_cache_put(SeqRenderData context, struct Sequence *seq, float cfra, seq_stripelem_ibuf_t type, struct ImBuf *ibuf);
void BKE_sequencer_preprocessed_cache_cleanup_sequence(struct Sequence *seq);
/* **********************************************************************
* seqeffects.c
*
@@ -289,6 +296,7 @@ int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char
int BKE_sequence_check_depend(struct Sequence *seq, struct Sequence *cur);
void BKE_sequence_invalidate_cache(struct Scene *scene, struct Sequence *seq);
void BKE_sequence_invalidate_cache_for_modifier(struct Scene *scene, struct Sequence *seq);
void BKE_sequencer_update_sound_bounds_all(struct Scene *scene);
void BKE_sequencer_update_sound_bounds(struct Scene *scene, struct Sequence *seq);
@@ -347,4 +355,46 @@ extern SequencerDrawView sequencer_view3d_cb;
extern ListBase seqbase_clipboard;
extern int seqbase_clipboard_frame;
/* modifiers */
typedef struct SequenceModifierTypeInfo {
/* default name for the modifier */
char name[64]; /* MAX_NAME */
/* DNA structure name used on load/save filed */
char struct_name[64]; /* MAX_NAME */
/* size of modifier data structure, used by allocation */
int struct_size;
/* data initialization */
void (*init_data) (struct SequenceModifierData *smd);
/* free data used by modifier,
* only modifier-specific data should be freed, modifier descriptor would
* be freed outside of this callback
*/
void (*free_data) (struct SequenceModifierData *smd);
/* copy data from one modifier to another */
void (*copy_data) (struct SequenceModifierData *smd, struct SequenceModifierData *target);
/* apply modifier on a given image buffer */
struct ImBuf* (*apply) (struct SequenceModifierData *smd, struct ImBuf *ibuf, struct ImBuf *mask);
} SequenceModifierTypeInfo;
struct SequenceModifierTypeInfo *BKE_sequence_modifier_type_info_get(int type);
void BKE_sequence_modifier_new(struct Sequence *seq, int type);
void BKE_sequence_modifier_free(struct SequenceModifierData *smd);
void BKE_sequence_modifier_unique_name(struct Sequence *seq, struct SequenceModifierData *smd);
struct SequenceModifierData *BKE_sequence_modifier_find_by_name(struct Sequence *seq, char *name);
struct ImBuf *BKE_sequence_modifier_apply_stack(SeqRenderData context, struct Sequence *seq, struct ImBuf *ibuf, int cfra);
void BKE_sequence_modifier_list_copy(struct Sequence *seqn, struct Sequence *seq);
int BKE_sequence_supports_modifiers(struct Sequence *seq);
/* internal filters */
struct ImBuf *BKE_sequencer_render_mask_input(SeqRenderData context, int mask_input_type, struct Sequence *mask_sequence, struct Mask *mask_id, int cfra, int make_float);
void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb, struct ImBuf *ibuf, float mul, short make_float, struct ImBuf *mask_input);
#endif /* __BKE_SEQUENCER_H__ */

View File

@@ -128,6 +128,7 @@ set(SRC
intern/script.c
intern/seqcache.c
intern/seqeffects.c
intern/seqmodifier.c
intern/sequencer.c
intern/shrinkwrap.c
intern/sketch.c

View File

@@ -57,13 +57,11 @@
/* ***************** operations on full struct ************* */
CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy)
void curvemapping_set_defaults(CurveMapping *cumap, int tot, float minx, float miny, float maxx, float maxy)
{
CurveMapping *cumap;
int a;
float clipminx, clipminy, clipmaxx, clipmaxy;
cumap = MEM_callocN(sizeof(CurveMapping), "new curvemap");
cumap->flag = CUMA_DO_CLIP;
if (tot == 4) cumap->cur = 3; /* rhms, hack for 'col' curve? */
@@ -90,38 +88,59 @@ CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, floa
}
cumap->changed_timestamp = 0;
}
CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy)
{
CurveMapping *cumap;
cumap = MEM_callocN(sizeof(CurveMapping), "new curvemap");
curvemapping_set_defaults(cumap, tot, minx, miny, maxx, maxy);
return cumap;
}
void curvemapping_free(CurveMapping *cumap)
void curvemapping_free_data(CurveMapping *cumap)
{
int a;
for (a = 0; a < CM_TOT; a++) {
if (cumap->cm[a].curve) MEM_freeN(cumap->cm[a].curve);
if (cumap->cm[a].table) MEM_freeN(cumap->cm[a].table);
if (cumap->cm[a].premultable) MEM_freeN(cumap->cm[a].premultable);
}
}
void curvemapping_free(CurveMapping *cumap)
{
if (cumap) {
for (a = 0; a < CM_TOT; a++) {
if (cumap->cm[a].curve) MEM_freeN(cumap->cm[a].curve);
if (cumap->cm[a].table) MEM_freeN(cumap->cm[a].table);
if (cumap->cm[a].premultable) MEM_freeN(cumap->cm[a].premultable);
}
curvemapping_free_data(cumap);
MEM_freeN(cumap);
}
}
void curvemapping_copy_data(CurveMapping *target, CurveMapping *cumap)
{
int a;
*target = *cumap;
for (a = 0; a < CM_TOT; a++) {
if (cumap->cm[a].curve)
target->cm[a].curve = MEM_dupallocN(cumap->cm[a].curve);
if (cumap->cm[a].table)
target->cm[a].table = MEM_dupallocN(cumap->cm[a].table);
if (cumap->cm[a].premultable)
target->cm[a].premultable = MEM_dupallocN(cumap->cm[a].premultable);
}
}
CurveMapping *curvemapping_copy(CurveMapping *cumap)
{
int a;
if (cumap) {
CurveMapping *cumapn = MEM_dupallocN(cumap);
for (a = 0; a < CM_TOT; a++) {
if (cumap->cm[a].curve)
cumapn->cm[a].curve = MEM_dupallocN(cumap->cm[a].curve);
if (cumap->cm[a].table)
cumapn->cm[a].table = MEM_dupallocN(cumap->cm[a].table);
if (cumap->cm[a].premultable)
cumapn->cm[a].premultable = MEM_dupallocN(cumap->cm[a].premultable);
}
curvemapping_copy_data(cumapn, cumap);
return cumapn;
}
return NULL;
@@ -783,6 +802,22 @@ void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float vecout[3], cons
vecout[2] = curvemap_evaluateF(cumap->cm + 2, fac);
}
/* same as above, byte version */
void curvemapping_evaluate_premulRGB(CurveMapping *cumap, unsigned char vecout_byte[3], const unsigned char vecin_byte[3])
{
float vecin[3], vecout[3];
vecin[0] = (float) vecin_byte[0] / 255.0f;
vecin[1] = (float) vecin_byte[1] / 255.0f;
vecin[2] = (float) vecin_byte[2] / 255.0f;
curvemapping_evaluate_premulRGBF(cumap, vecout, vecin);
vecout_byte[0] = FTOCHAR(vecout[0]);
vecout_byte[1] = FTOCHAR(vecout[1]);
vecout_byte[2] = FTOCHAR(vecout[2]);
}
/* only used for image editor curves */
void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf)

View File

@@ -37,8 +37,11 @@
#include "BKE_sequencer.h"
#include "IMB_moviecache.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "BLI_listbase.h"
typedef struct SeqCacheKey {
struct Sequence *seq;
SeqRenderData context;
@@ -46,7 +49,25 @@ typedef struct SeqCacheKey {
seq_stripelem_ibuf_t type;
} SeqCacheKey;
typedef struct SeqPreprocessCacheElem {
struct SeqPreprocessCacheElem *next, *prev;
struct Sequence *seq;
SeqRenderData context;
seq_stripelem_ibuf_t type;
ImBuf *ibuf;
} SeqPreprocessCacheElem;
typedef struct SeqPreprocessCache {
int cfra;
ListBase elems;
} SeqPreprocessCache;
static struct MovieCache *moviecache = NULL;
static struct SeqPreprocessCache *preprocess_cache = NULL;
static void preprocessed_cache_destruct(void);
static int seq_cmp_render_data(const SeqRenderData *a, const SeqRenderData *b)
{
@@ -160,6 +181,8 @@ void BKE_sequencer_cache_destruct(void)
{
if (moviecache)
IMB_moviecache_free(moviecache);
preprocessed_cache_destruct();
}
void BKE_sequencer_cache_cleanup(void)
@@ -219,3 +242,100 @@ void BKE_sequencer_cache_put(SeqRenderData context, Sequence *seq, float cfra, s
IMB_moviecache_put(moviecache, &key, i);
}
static void preprocessed_cache_clean(void)
{
SeqPreprocessCacheElem *elem;
if (!preprocess_cache)
return;
for (elem = preprocess_cache->elems.first; elem; elem = elem->next) {
IMB_freeImBuf(elem->ibuf);
}
BLI_freelistN(&preprocess_cache->elems);
preprocess_cache->elems.first = preprocess_cache->elems.last = NULL;
}
static void preprocessed_cache_destruct(void)
{
if (!preprocess_cache)
return;
preprocessed_cache_clean();
MEM_freeN(preprocess_cache);
preprocess_cache = NULL;
}
ImBuf *BKE_sequencer_preprocessed_cache_get(SeqRenderData context, Sequence *seq, float cfra, seq_stripelem_ibuf_t type)
{
SeqPreprocessCacheElem *elem;
if (!preprocess_cache)
return NULL;
if (preprocess_cache->cfra != cfra)
return NULL;
for (elem = preprocess_cache->elems.first; elem; elem = elem->next) {
if (elem->seq != seq)
continue;
if (elem->type != type)
continue;
if (seq_cmp_render_data(&elem->context, &context) != 0)
continue;
IMB_refImBuf(elem->ibuf);
return elem->ibuf;
}
return NULL;
}
void BKE_sequencer_preprocessed_cache_put(SeqRenderData context, Sequence *seq, float cfra, seq_stripelem_ibuf_t type, ImBuf *ibuf)
{
SeqPreprocessCacheElem *elem;
if (!preprocess_cache) {
preprocess_cache = MEM_callocN(sizeof(SeqPreprocessCache), "sequencer preprocessed cache");
}
else {
if (preprocess_cache->cfra != cfra)
preprocessed_cache_clean();
}
elem = MEM_callocN(sizeof(SeqPreprocessCacheElem), "sequencer preprocessed cache element");
elem->seq = seq;
elem->type = type;
elem->context = context;
elem->ibuf = ibuf;
preprocess_cache->cfra = cfra;
IMB_refImBuf(ibuf);
BLI_addtail(&preprocess_cache->elems, elem);
}
void BKE_sequencer_preprocessed_cache_cleanup_sequence(Sequence *seq)
{
SeqPreprocessCacheElem *elem, *elem_next;
if (!preprocess_cache)
return;
for (elem = preprocess_cache->elems.first; elem; elem = elem_next) {
elem_next = elem->next;
if (elem->seq == seq) {
IMB_freeImBuf(elem->ibuf);
BLI_freelinkN(&preprocess_cache->elems, elem);
}
}
}

View File

@@ -0,0 +1,522 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2012 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,
* Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/blenkernel/intern/seqmodifier.c
* \ingroup bke
*/
#include <stddef.h>
#include <string.h>
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "DNA_sequence_types.h"
#include "BKE_colortools.h"
#include "BKE_sequencer.h"
#include "BKE_utildefines.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
static SequenceModifierTypeInfo *modifiersTypes[NUM_SEQUENCE_MODIFIER_TYPES];
static int modifierTypesInit = FALSE;
/*********************** Modifiers *************************/
typedef void (*modifier_apply_threaded_cb) (int width, int height, unsigned char *rect, float *rect_float,
unsigned char *mask_rect, float *mask_rect_float, void *data_v);
typedef struct ModifierInitData {
ImBuf *ibuf;
ImBuf *mask;
void *user_data;
modifier_apply_threaded_cb apply_callback;
} ModifierInitData;
typedef struct ModifierThread {
int width, height;
unsigned char *rect, *mask_rect;
float *rect_float, *mask_rect_float;
void *user_data;
modifier_apply_threaded_cb apply_callback;
} ModifierThread;
static ImBuf *modifier_mask_get(SequenceModifierData *smd, SeqRenderData context, int cfra, int make_float)
{
return BKE_sequencer_render_mask_input(context, smd->mask_input_type, smd->mask_sequence, smd->mask_id, cfra, make_float);
}
static void modifier_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
{
ModifierThread *handle = (ModifierThread *) handle_v;
ModifierInitData *init_data = (ModifierInitData *) init_data_v;
ImBuf *ibuf = init_data->ibuf;
ImBuf *mask = init_data->mask;
int offset = 4 * start_line * ibuf->x;
memset(handle, 0, sizeof(ModifierThread));
handle->width = ibuf->x;
handle->height = tot_line;
handle->apply_callback = init_data->apply_callback;
handle->user_data = init_data->user_data;
if (ibuf->rect)
handle->rect = (unsigned char *) ibuf->rect + offset;
if (ibuf->rect_float)
handle->rect_float = ibuf->rect_float + offset;
if (mask) {
if (mask->rect)
handle->mask_rect = (unsigned char *) mask->rect + offset;
if (mask->rect_float)
handle->mask_rect_float = mask->rect_float + offset;
}
else {
handle->mask_rect = NULL;
handle->mask_rect_float = NULL;
}
}
static void *modifier_do_thread(void *thread_data_v)
{
ModifierThread *td = (ModifierThread *) thread_data_v;
td->apply_callback(td->width, td->height, td->rect, td->rect_float, td->mask_rect, td->mask_rect_float, td->user_data);
return NULL;
}
static void modifier_apply_threaded(ImBuf *ibuf, ImBuf *mask, modifier_apply_threaded_cb apply_callback, void *user_data)
{
ModifierInitData init_data;
init_data.ibuf = ibuf;
init_data.mask = mask;
init_data.user_data = user_data;
init_data.apply_callback = apply_callback;
IMB_processor_apply_threaded(ibuf->y, sizeof(ModifierThread), &init_data,
modifier_init_handle, modifier_do_thread);
}
/* **** Color Balance Modifier **** */
void colorBalance_init_data(SequenceModifierData *smd)
{
ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd;
int c;
cbmd->color_multiply = 1.0f;
for (c = 0; c < 3; c++) {
cbmd->color_balance.lift[c] = 1.0f;
cbmd->color_balance.gamma[c] = 1.0f;
cbmd->color_balance.gain[c] = 1.0f;
}
}
ImBuf *colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd;
ImBuf *ibuf_new = IMB_dupImBuf(ibuf);
BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf_new, cbmd->color_multiply, FALSE, mask);
return ibuf_new;
}
static SequenceModifierTypeInfo seqModifier_ColorBalance = {
"Color Balance", /* name */
"ColorBalanceModifierData", /* struct_name */
sizeof(ColorBalanceModifierData), /* struct_size */
colorBalance_init_data, /* init_data */
NULL, /* free_data */
NULL, /* copy_data */
colorBalance_apply /* apply */
};
/* **** Curves Modifier **** */
void curves_init_data(SequenceModifierData *smd)
{
CurvesModifierData *cmd = (CurvesModifierData *) smd;
curvemapping_set_defaults(&cmd->curve_mapping, 4, 0.0f, 0.0f, 1.0f, 1.0f);
}
void curves_free_data(SequenceModifierData *smd)
{
CurvesModifierData *cmd = (CurvesModifierData *) smd;
curvemapping_free_data(&cmd->curve_mapping);
}
void curves_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
{
CurvesModifierData *cmd = (CurvesModifierData *) smd;
CurvesModifierData *cmd_target = (CurvesModifierData *) target;
curvemapping_copy_data(&cmd_target->curve_mapping, &cmd->curve_mapping);
}
void curves_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
unsigned char *mask_rect, float *mask_rect_float, void *data_v)
{
CurveMapping *curve_mapping = (CurveMapping *) data_v;
int x, y;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
int pixel_index = (y * width + x) * 4;
if (rect_float) {
float *pixel = rect_float + pixel_index;
float result[3];
curvemapping_evaluate_premulRGBF(curve_mapping, result, pixel);
if (mask_rect_float) {
float *m = mask_rect_float + pixel_index;
pixel[0] = pixel[0] * (1.0f - m[0]) + result[0] * m[0];
pixel[1] = pixel[1] * (1.0f - m[1]) + result[1] * m[1];
pixel[2] = pixel[2] * (1.0f - m[2]) + result[2] * m[2];
}
else {
pixel[0] = result[0];
pixel[1] = result[1];
pixel[2] = result[2];
}
}
if (rect) {
unsigned char *pixel = rect + pixel_index;
unsigned char result[3];
curvemapping_evaluate_premulRGB(curve_mapping, result, pixel);
if (mask_rect) {
float t[3];
rgb_uchar_to_float(t, mask_rect + pixel_index);
pixel[0] = pixel[0] * (1.0f - t[0]) + result[0] * t[0];
pixel[1] = pixel[1] * (1.0f - t[1]) + result[1] * t[1];
pixel[2] = pixel[2] * (1.0f - t[2]) + result[2] * t[2];
}
else {
pixel[0] = result[0];
pixel[1] = result[1];
pixel[2] = result[2];
}
}
}
}
}
ImBuf *curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
CurvesModifierData *cmd = (CurvesModifierData *) smd;
ImBuf *ibuf_new = IMB_dupImBuf(ibuf);
float black[3] = {0.0f, 0.0f, 0.0f};
float white[3] = {1.0f, 1.0f, 1.0f};
curvemapping_initialize(&cmd->curve_mapping);
curvemapping_premultiply(&cmd->curve_mapping, 0);
curvemapping_set_black_white(&cmd->curve_mapping, black, white);
modifier_apply_threaded(ibuf_new, mask, curves_apply_threaded, &cmd->curve_mapping);
curvemapping_premultiply(&cmd->curve_mapping, 1);
return ibuf_new;
}
static SequenceModifierTypeInfo seqModifier_Curves = {
"Curves", /* name */
"CurvesModifierData", /* struct_name */
sizeof(CurvesModifierData), /* struct_size */
curves_init_data, /* init_data */
curves_free_data, /* free_data */
curves_copy_data, /* copy_data */
curves_apply /* apply */
};
/* **** Hue Correct Modifier **** */
void hue_correct_init_data(SequenceModifierData *smd)
{
HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
int c;
curvemapping_set_defaults(&hcmd->curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f);
hcmd->curve_mapping.preset = CURVE_PRESET_MID9;
for (c = 0; c < 3; c++) {
CurveMap *cuma = &hcmd->curve_mapping.cm[c];
curvemap_reset(cuma, &hcmd->curve_mapping.clipr, hcmd->curve_mapping.preset, CURVEMAP_SLOPE_POSITIVE);
}
/* default to showing Saturation */
hcmd->curve_mapping.cur = 1;
}
void hue_correct_free_data(SequenceModifierData *smd)
{
HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
curvemapping_free_data(&hcmd->curve_mapping);
}
void hue_correct_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
{
HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
HueCorrectModifierData *hcmd_target = (HueCorrectModifierData *) target;
curvemapping_copy_data(&hcmd_target->curve_mapping, &hcmd->curve_mapping);
}
void hue_correct_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
unsigned char *mask_rect, float *mask_rect_float, void *data_v)
{
CurveMapping *curve_mapping = (CurveMapping *) data_v;
int x, y;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
int pixel_index = (y * width + x) * 4;
float pixel[3], result[3], mask[3] = {1.0f, 1.0f, 1.0f};
float hsv[3], f;
if (rect_float)
copy_v3_v3(pixel, rect_float + pixel_index);
else
rgb_uchar_to_float(pixel, rect + pixel_index);
rgb_to_hsv(pixel[0], pixel[1], pixel[2], hsv, hsv + 1, hsv + 2);
/* adjust hue, scaling returned default 0.5 up to 1 */
f = curvemapping_evaluateF(curve_mapping, 0, hsv[0]);
hsv[0] += f - 0.5f;
/* adjust saturation, scaling returned default 0.5 up to 1 */
f = curvemapping_evaluateF(curve_mapping, 1, hsv[0]);
hsv[1] *= (f * 2.0f);
/* adjust value, scaling returned default 0.5 up to 1 */
f = curvemapping_evaluateF(curve_mapping, 2, hsv[0]);
hsv[2] *= (f * 2.f);
hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */
CLAMP(hsv[1], 0.0f, 1.0f);
/* convert back to rgb */
hsv_to_rgb(hsv[0], hsv[1], hsv[2], result, result + 1, result + 2);
if (mask_rect_float)
copy_v3_v3(mask, mask_rect_float + pixel_index);
else if (mask_rect)
rgb_uchar_to_float(mask, mask_rect + pixel_index);
result[0] = pixel[0] * (1.0f - mask[0]) + result[0] * mask[0];
result[1] = pixel[1] * (1.0f - mask[1]) + result[1] * mask[1];
result[2] = pixel[2] * (1.0f - mask[2]) + result[2] * mask[2];
if (rect_float)
copy_v3_v3(rect_float + pixel_index, result);
else
rgb_float_to_uchar(rect + pixel_index, result);
}
}
}
ImBuf *hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
ImBuf *ibuf_new = IMB_dupImBuf(ibuf);
curvemapping_initialize(&hcmd->curve_mapping);
modifier_apply_threaded(ibuf_new, mask, hue_correct_apply_threaded, &hcmd->curve_mapping);
return ibuf_new;
}
static SequenceModifierTypeInfo seqModifier_HueCorrect = {
"Hue Correct", /* name */
"HueCorrectModifierData", /* struct_name */
sizeof(HueCorrectModifierData), /* struct_size */
hue_correct_init_data, /* init_data */
hue_correct_free_data, /* free_data */
hue_correct_copy_data, /* copy_data */
hue_correct_apply /* apply */
};
/*********************** Modifier functions *************************/
static void sequence_modifier_type_info_init(void)
{
#define INIT_TYPE(typeName) (modifiersTypes[seqModifierType_##typeName] = &seqModifier_##typeName)
INIT_TYPE(ColorBalance);
INIT_TYPE(Curves);
INIT_TYPE(HueCorrect);
#undef INIT_TYPE
}
SequenceModifierTypeInfo *BKE_sequence_modifier_type_info_get(int type)
{
if (!modifierTypesInit) {
sequence_modifier_type_info_init();
modifierTypesInit = TRUE;
}
return modifiersTypes[type];
}
void BKE_sequence_modifier_new(Sequence *seq, int type)
{
SequenceModifierData *smd;
SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(type);
smd = MEM_callocN(smti->struct_size, "sequence modifier");
smd->type = type;
smd->flag |= SEQUENCE_MODIFIER_EXPANDED;
BLI_strncpy(smd->name, smti->name, sizeof(smd->name));
BLI_addtail(&seq->modifiers, smd);
BKE_sequence_modifier_unique_name(seq, smd);
if (smti->init_data)
smti->init_data(smd);
}
void BKE_sequence_modifier_free(SequenceModifierData *smd)
{
SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
if (smti && smti->free_data) {
smti->free_data(smd);
}
MEM_freeN(smd);
}
void BKE_sequence_modifier_unique_name(Sequence *seq, SequenceModifierData *smd)
{
SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
BLI_uniquename(&seq->modifiers, smd, smti->name, '.', offsetof(SequenceModifierData, name), sizeof(smd->name));
}
SequenceModifierData *BKE_sequence_modifier_find_by_name(Sequence *seq, char *name)
{
return BLI_findstring(&(seq->modifiers), name, offsetof(SequenceModifierData, name));
}
ImBuf *BKE_sequence_modifier_apply_stack(SeqRenderData context, Sequence *seq, ImBuf *ibuf, int cfra)
{
SequenceModifierData *smd;
ImBuf *processed_ibuf = ibuf;
for (smd = seq->modifiers.first; smd; smd = smd->next) {
SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
ImBuf *ibuf_new;
/* could happen if modifier is being removed or not exists in current version of blender */
if (!smti)
continue;
/* modifier is muted, do nothing */
if (smd->flag & SEQUENCE_MODIFIER_MUTE)
continue;
if (smti->apply) {
ImBuf *mask = modifier_mask_get(smd, context, cfra, ibuf->rect_float != NULL);
if (processed_ibuf == ibuf)
processed_ibuf = IMB_dupImBuf(ibuf);
ibuf_new = smti->apply(smd, processed_ibuf, mask);
if (ibuf_new != processed_ibuf) {
IMB_freeImBuf(processed_ibuf);
processed_ibuf = ibuf_new;
}
if (mask)
IMB_freeImBuf(mask);
}
}
return processed_ibuf;
}
void BKE_sequence_modifier_list_copy(Sequence *seqn, Sequence *seq)
{
SequenceModifierData *smd;
for (smd = seq->modifiers.first; smd; smd = smd->next) {
SequenceModifierData *smdn;
SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
smdn = MEM_dupallocN(smd);
if (smti && smti->copy_data)
smti->copy_data(smdn, smd);
smdn->next = smdn->prev = NULL;
BLI_addtail(&seqn->modifiers, smdn);
}
}
int BKE_sequence_supports_modifiers(Sequence *seq)
{
return !ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD);
}

View File

@@ -83,6 +83,7 @@
static ImBuf *seq_render_strip_stack(SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown);
static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra);
static void seq_free_animdata(Scene *scene, Sequence *seq);
static ImBuf *seq_render_mask(SeqRenderData context, Mask *mask, float nr, short make_float);
/* **** XXX ******** */
#define SELECT 1
@@ -203,7 +204,18 @@ void BKE_sequence_free(Scene *scene, Sequence *seq)
seq_free_animdata(scene, seq);
}
/* free modifiers */
if (seq->modifiers.first) {
SequenceModifierData *smd, *smd_next;
for (smd = seq->modifiers.first; smd; smd = smd_next) {
smd_next = smd->next;
BKE_sequence_modifier_free(smd);
}
}
BKE_sequencer_cache_cleanup_sequence(seq);
BKE_sequencer_preprocessed_cache_cleanup_sequence(seq);
MEM_freeN(seq);
}
@@ -1432,7 +1444,7 @@ static void make_cb_table_float(float lift, float gain, float gamma,
}
}
static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, unsigned char *mask_rect, int width, int height, float mul)
static void color_balance_byte_byte(StripColorBalance *cb_, unsigned char *rect, unsigned char *mask_rect, int width, int height, float mul)
{
unsigned char cb_tab[3][256];
int c;
@@ -1440,7 +1452,7 @@ static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, unsigned
unsigned char *e = p + width * 4 * height;
unsigned char *m = mask_rect;
StripColorBalance cb = calc_cb(seq->strip->color_balance);
StripColorBalance cb = calc_cb(cb_);
for (c = 0; c < 3; c++) {
make_cb_table_byte(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
@@ -1466,7 +1478,7 @@ static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, unsigned
}
}
static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float *rect_float, unsigned char *mask_rect, int width, int height, float mul)
static void color_balance_byte_float(StripColorBalance *cb_, unsigned char *rect, float *rect_float, unsigned char *mask_rect, int width, int height, float mul)
{
float cb_tab[4][256];
int c, i;
@@ -1478,7 +1490,7 @@ static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float *
o = rect_float;
cb = calc_cb(seq->strip->color_balance);
cb = calc_cb(cb_);
for (c = 0; c < 3; c++) {
make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul);
@@ -1510,12 +1522,12 @@ static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float *
}
}
static void color_balance_float_float(Sequence *seq, float *rect_float, float *mask_rect_float, int width, int height, float mul)
static void color_balance_float_float(StripColorBalance *cb_, float *rect_float, float *mask_rect_float, int width, int height, float mul)
{
float *p = rect_float;
float *e = rect_float + width * 4 * height;
float *m = mask_rect_float;
StripColorBalance cb = calc_cb(seq->strip->color_balance);
StripColorBalance cb = calc_cb(cb_);
while (p < e) {
int c;
@@ -1535,20 +1547,23 @@ static void color_balance_float_float(Sequence *seq, float *rect_float, float *m
}
typedef struct ColorBalanceInitData {
Sequence *seq;
StripColorBalance *cb;
ImBuf *ibuf;
float mul;
ImBuf *mask;
short make_float;
} ColorBalanceInitData;
typedef struct ColorBalanceThread {
Sequence *seq;
StripColorBalance *cb;
float mul;
int width, height;
unsigned char *rect, *mask_rect;
float *rect_float, *mask_rect_float;
short make_float;
} ColorBalanceThread;
static void color_balance_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
@@ -1562,10 +1577,11 @@ static void color_balance_init_handle(void *handle_v, int start_line, int tot_li
memset(handle, 0, sizeof(ColorBalanceThread));
handle->seq = init_data->seq;
handle->cb = init_data->cb;
handle->mul = init_data->mul;
handle->width = ibuf->x;
handle->height = tot_line;
handle->make_float = init_data->make_float;
if (ibuf->rect)
handle->rect = (unsigned char *) ibuf->rect + offset;
@@ -1589,7 +1605,7 @@ static void color_balance_init_handle(void *handle_v, int start_line, int tot_li
static void *color_balance_do_thread(void *thread_data_v)
{
ColorBalanceThread *thread_data = (ColorBalanceThread *) thread_data_v;
Sequence *seq = thread_data->seq;
StripColorBalance *cb = thread_data->cb;
int width = thread_data->width, height = thread_data->height;
unsigned char *rect = thread_data->rect;
unsigned char *mask_rect = thread_data->mask_rect;
@@ -1598,48 +1614,56 @@ static void *color_balance_do_thread(void *thread_data_v)
float mul = thread_data->mul;
if (rect_float) {
color_balance_float_float(seq, rect_float, mask_rect_float, width, height, mul);
color_balance_float_float(cb, rect_float, mask_rect_float, width, height, mul);
}
else if (seq->flag & SEQ_MAKE_FLOAT) {
color_balance_byte_float(seq, rect, rect_float, mask_rect, width, height, mul);
else if (thread_data->make_float) {
color_balance_byte_float(cb, rect, rect_float, mask_rect, width, height, mul);
}
else {
color_balance_byte_byte(seq, rect, mask_rect, width, height, mul);
color_balance_byte_byte(cb, rect, mask_rect, width, height, mul);
}
return NULL;
}
static void color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, float mul, int cfra)
ImBuf *BKE_sequencer_render_mask_input(SeqRenderData context, int mask_input_type, Sequence *mask_sequence, Mask *mask_id, int cfra, int make_float)
{
ColorBalanceInitData init_data;
ImBuf *mask_input = NULL;
if (!ibuf->rect_float && seq->flag & SEQ_MAKE_FLOAT)
imb_addrectfloatImBuf(ibuf);
if (mask_input_type == SEQUENCE_MASK_INPUT_STRIP) {
if (mask_sequence) {
mask_input = seq_render_strip(context, mask_sequence, cfra);
init_data.seq = seq;
init_data.ibuf = ibuf;
init_data.mul = mul;
init_data.mask = NULL;
if (seq->mask_sequence) {
if (seq->mask_sequence != seq && !BKE_sequence_check_depend(seq, seq->mask_sequence)) {
ImBuf *mask = seq_render_strip(context, seq->mask_sequence, cfra);
if (mask) {
if (ibuf->rect_float) {
if (!mask->rect_float)
IMB_float_from_rect(mask);
}
else {
if (!mask->rect)
IMB_rect_from_float(mask);
}
init_data.mask = mask;
if (make_float) {
if (!mask_input->rect_float)
IMB_float_from_rect(mask_input);
}
else {
if (!mask_input->rect)
IMB_rect_from_float(mask_input);
}
}
}
else if (mask_input_type == SEQUENCE_MASK_INPUT_ID) {
mask_input = seq_render_mask(context, mask_id, cfra, make_float);
}
return mask_input;
}
void BKE_sequencer_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float mul, short make_float, ImBuf *mask_input)
{
ColorBalanceInitData init_data;
if (!ibuf->rect_float && make_float)
imb_addrectfloatImBuf(ibuf);
init_data.cb = cb;
init_data.ibuf = ibuf;
init_data.mul = mul;
init_data.mask = NULL;
init_data.make_float = make_float;
init_data.mask = mask_input;
IMB_processor_apply_threaded(ibuf->y, sizeof(ColorBalanceThread), &init_data,
color_balance_init_handle, color_balance_do_thread);
@@ -1650,9 +1674,26 @@ static void color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, flo
*/
if (ibuf->rect_float && ibuf->rect)
imb_freerectImBuf(ibuf);
}
if (init_data.mask)
IMB_freeImBuf(init_data.mask);
static void sequence_color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, float mul, int cfra)
{
StripColorBalance *cb = seq->strip->color_balance;
ImBuf *mask_input = NULL;
short make_float = seq->flag & SEQ_MAKE_FLOAT;
if (seq->mask_sequence) {
if (seq->mask_sequence != seq && !BKE_sequence_check_depend(seq, seq->mask_sequence)) {
int make_float = ibuf->rect_float != NULL;
mask_input = BKE_sequencer_render_mask_input(context, SEQUENCE_MASK_INPUT_STRIP, seq->mask_sequence, NULL, cfra, make_float);
}
}
BKE_sequencer_color_balance_apply(cb, ibuf, mul, make_float, mask_input);
if (mask_input)
IMB_freeImBuf(mask_input);
}
/*
@@ -1696,6 +1737,10 @@ int BKE_sequencer_input_have_to_preprocess(SeqRenderData UNUSED(context), Sequen
if (seq->sat != 1.0f) {
return TRUE;
}
if (seq->modifiers.first) {
return TRUE;
}
return FALSE;
}
@@ -1795,7 +1840,7 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
}
if (seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
color_balance(context, seq, ibuf, mul, cfra);
sequence_color_balance(context, seq, ibuf, mul, cfra);
mul = 1.0;
}
@@ -1818,7 +1863,6 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
}
}
if (ibuf->x != context.rectx || ibuf->y != context.recty) {
if (context.scene->r.mode & R_OSA) {
IMB_scaleImBuf(ibuf, (short)context.rectx, (short)context.recty);
@@ -1827,6 +1871,16 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
IMB_scalefastImBuf(ibuf, (short)context.rectx, (short)context.recty);
}
}
if (seq->modifiers.first) {
ImBuf *ibuf_new = BKE_sequence_modifier_apply_stack(context, seq, ibuf, cfra);
if (ibuf_new != ibuf) {
IMB_freeImBuf(ibuf);
ibuf = ibuf_new;
}
}
return ibuf;
}
@@ -2098,23 +2152,23 @@ static ImBuf *seq_render_movieclip_strip(SeqRenderData context, Sequence *seq, f
}
static ImBuf *seq_render_mask_strip(SeqRenderData context, Sequence *seq, float nr)
static ImBuf *seq_render_mask(SeqRenderData context, Mask *mask, float nr, short make_float)
{
/* TODO - add option to rasterize to alpha imbuf? */
ImBuf *ibuf = NULL;
float *maskbuf;
int i;
if (!seq->mask) {
if (!mask) {
return NULL;
}
else {
Mask *mask_temp;
MaskRasterHandle *mr_handle;
mask_temp = BKE_mask_copy_nolib(seq->mask);
mask_temp = BKE_mask_copy_nolib(mask);
BKE_mask_evaluate(mask_temp, seq->mask->sfra + nr, TRUE);
BKE_mask_evaluate(mask_temp, mask->sfra + nr, TRUE);
maskbuf = MEM_mallocN(sizeof(float) * context.rectx * context.recty, __func__);
@@ -2131,7 +2185,7 @@ static ImBuf *seq_render_mask_strip(SeqRenderData context, Sequence *seq, float
}
if (seq->flag & SEQ_MAKE_FLOAT) {
if (make_float) {
/* pixels */
float *fp_src;
float *fp_dst;
@@ -2173,6 +2227,13 @@ static ImBuf *seq_render_mask_strip(SeqRenderData context, Sequence *seq, float
return ibuf;
}
static ImBuf *seq_render_mask_strip(SeqRenderData context, Sequence *seq, float nr)
{
short make_float = seq->flag & SEQ_MAKE_FLOAT;
return seq_render_mask(context, seq->mask, nr, make_float);
}
static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float nr)
{
ImBuf *ibuf = NULL;
@@ -2328,10 +2389,162 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
return ibuf;
}
static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, float cfra)
{
ImBuf *ibuf = NULL;
float nr = give_stripelem_index(seq, cfra);
int type = (seq->type & SEQ_TYPE_EFFECT && seq->type != SEQ_TYPE_SPEED) ? SEQ_TYPE_EFFECT : seq->type;
int use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
char name[FILE_MAX];
switch (type) {
case SEQ_TYPE_META:
{
ImBuf *meta_ibuf = NULL;
if (seq->seqbase.first)
meta_ibuf = seq_render_strip_stack(context, &seq->seqbase, seq->start + nr, 0);
if (meta_ibuf) {
ibuf = meta_ibuf;
if (ibuf && use_preprocess) {
ImBuf *i = IMB_dupImBuf(ibuf);
IMB_freeImBuf(ibuf);
ibuf = i;
}
}
break;
}
case SEQ_TYPE_SPEED:
{
ImBuf *child_ibuf = NULL;
float f_cfra;
SpeedControlVars *s = (SpeedControlVars *)seq->effectdata;
BKE_sequence_effect_speed_rebuild_map(context.scene, seq, 0);
/* weeek! */
f_cfra = seq->start + s->frameMap[(int)nr];
child_ibuf = seq_render_strip(context, seq->seq1, f_cfra);
if (child_ibuf) {
ibuf = child_ibuf;
if (ibuf && use_preprocess) {
ImBuf *i = IMB_dupImBuf(ibuf);
IMB_freeImBuf(ibuf);
ibuf = i;
}
}
break;
}
case SEQ_TYPE_EFFECT:
{
ibuf = seq_render_effect_strip_impl(context, seq, seq->start + nr);
break;
}
case SEQ_TYPE_IMAGE:
{
StripElem *s_elem = BKE_sequencer_give_stripelem(seq, cfra);
if (s_elem) {
BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
BLI_path_abs(name, G.main->name);
}
if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) {
/* we don't need both (speed reasons)! */
if (ibuf->rect_float && ibuf->rect)
imb_freerectImBuf(ibuf);
/* all sequencer color is done in SRGB space, linear gives odd crossfades */
if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
IMB_convert_profile(ibuf, IB_PROFILE_NONE);
copy_to_ibuf_still(context, seq, nr, ibuf);
s_elem->orig_width = ibuf->x;
s_elem->orig_height = ibuf->y;
}
break;
}
case SEQ_TYPE_MOVIE:
{
seq_open_anim_file(seq);
if (seq->anim) {
IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
ibuf = IMB_anim_absolute(seq->anim, nr + seq->anim_startofs,
seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
seq_rendersize_to_proxysize(context.preview_render_size));
/* we don't need both (speed reasons)! */
if (ibuf && ibuf->rect_float && ibuf->rect)
imb_freerectImBuf(ibuf);
if (ibuf) {
seq->strip->stripdata->orig_width = ibuf->x;
seq->strip->stripdata->orig_height = ibuf->y;
}
}
copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
case SEQ_TYPE_SCENE:
{
/* scene can be NULL after deletions */
ibuf = seq_render_scene_strip(context, seq, nr);
/* Scene strips update all animation, so we need to restore original state.*/
BKE_animsys_evaluate_all_animation(context.bmain, context.scene, cfra);
copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
case SEQ_TYPE_MOVIECLIP:
{
ibuf = seq_render_movieclip_strip(context, seq, nr);
if (ibuf && use_preprocess) {
ImBuf *i = IMB_dupImBuf(ibuf);
IMB_freeImBuf(ibuf);
ibuf = i;
}
copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
case SEQ_TYPE_MASK:
{
/* ibuf is alwats new */
ibuf = seq_render_mask_strip(context, seq, nr);
copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
}
return ibuf;
}
static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra)
{
ImBuf *ibuf = NULL;
char name[FILE_MAX];
int use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra);
int is_proxy_image = FALSE;
float nr = give_stripelem_index(seq, cfra);
@@ -2348,147 +2561,20 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra)
if (ibuf == NULL)
ibuf = copy_from_ibuf_still(context, seq, nr);
/* MOVIECLIPs have their own proxy management */
if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) {
ibuf = seq_proxy_fetch(context, seq, cfra);
is_proxy_image = (ibuf != NULL);
}
if (ibuf == NULL) switch (type) {
case SEQ_TYPE_META:
{
ImBuf *meta_ibuf = NULL;
if (ibuf == NULL) {
ibuf = BKE_sequencer_preprocessed_cache_get(context, seq, cfra, SEQ_STRIPELEM_IBUF);
if (seq->seqbase.first)
meta_ibuf = seq_render_strip_stack(
context, &seq->seqbase,
seq->start + nr, 0);
if (meta_ibuf) {
ibuf = meta_ibuf;
if (ibuf && use_preprocess) {
ImBuf *i = IMB_dupImBuf(ibuf);
IMB_freeImBuf(ibuf);
ibuf = i;
}
}
break;
if (ibuf == NULL) {
/* MOVIECLIPs have their own proxy management */
if (ibuf == NULL && seq->type != SEQ_TYPE_MOVIECLIP) {
ibuf = seq_proxy_fetch(context, seq, cfra);
is_proxy_image = (ibuf != NULL);
}
case SEQ_TYPE_SPEED:
{
ImBuf *child_ibuf = NULL;
float f_cfra;
SpeedControlVars *s = (SpeedControlVars *)seq->effectdata;
ibuf = do_render_strip_uncached(context, seq, cfra);
BKE_sequence_effect_speed_rebuild_map(context.scene, seq, 0);
/* weeek! */
f_cfra = seq->start + s->frameMap[(int)nr];
child_ibuf = seq_render_strip(context, seq->seq1, f_cfra);
if (child_ibuf) {
ibuf = child_ibuf;
if (ibuf && use_preprocess) {
ImBuf *i = IMB_dupImBuf(ibuf);
IMB_freeImBuf(ibuf);
ibuf = i;
}
}
break;
}
case SEQ_TYPE_EFFECT:
{
ibuf = seq_render_effect_strip_impl(context, seq, seq->start + nr);
break;
}
case SEQ_TYPE_IMAGE:
{
StripElem *s_elem = BKE_sequencer_give_stripelem(seq, cfra);
if (s_elem) {
BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name);
BLI_path_abs(name, G.main->name);
}
if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) {
/* we don't need both (speed reasons)! */
if (ibuf->rect_float && ibuf->rect)
imb_freerectImBuf(ibuf);
/* all sequencer color is done in SRGB space, linear gives odd crossfades */
if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
IMB_convert_profile(ibuf, IB_PROFILE_NONE);
copy_to_ibuf_still(context, seq, nr, ibuf);
s_elem->orig_width = ibuf->x;
s_elem->orig_height = ibuf->y;
}
break;
}
case SEQ_TYPE_MOVIE:
{
seq_open_anim_file(seq);
if (seq->anim) {
IMB_anim_set_preseek(seq->anim, seq->anim_preseek);
ibuf = IMB_anim_absolute(seq->anim, nr + seq->anim_startofs,
seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN,
seq_rendersize_to_proxysize(context.preview_render_size));
/* we don't need both (speed reasons)! */
if (ibuf && ibuf->rect_float && ibuf->rect)
imb_freerectImBuf(ibuf);
if (ibuf) {
seq->strip->stripdata->orig_width = ibuf->x;
seq->strip->stripdata->orig_height = ibuf->y;
}
}
copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
case SEQ_TYPE_SCENE:
{
/* scene can be NULL after deletions */
ibuf = seq_render_scene_strip(context, seq, nr);
/* Scene strips update all animation, so we need to restore original state.*/
BKE_animsys_evaluate_all_animation(context.bmain, context.scene, cfra);
copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
case SEQ_TYPE_MOVIECLIP:
{
ibuf = seq_render_movieclip_strip(context, seq, nr);
if (ibuf && use_preprocess) {
ImBuf *i = IMB_dupImBuf(ibuf);
IMB_freeImBuf(ibuf);
ibuf = i;
}
copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
case SEQ_TYPE_MASK:
{
/* ibuf is alwats new */
ibuf = seq_render_mask_strip(context, seq, nr);
copy_to_ibuf_still(context, seq, nr, ibuf);
break;
BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
}
}
@@ -2876,7 +2962,7 @@ int BKE_sequence_check_depend(Sequence *seq, Sequence *cur)
return TRUE;
}
void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidate_preprocess)
{
Editing *ed = scene->ed;
Sequence *cur;
@@ -2884,18 +2970,33 @@ void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
/* invalidate cache for current sequence */
BKE_sequencer_cache_cleanup_sequence(seq);
if (invalidate_preprocess)
BKE_sequencer_preprocessed_cache_cleanup_sequence(seq);
/* invalidate cache for all dependent sequences */
SEQ_BEGIN (ed, cur)
{
if (cur == seq)
continue;
if (BKE_sequence_check_depend(seq, cur))
if (BKE_sequence_check_depend(seq, cur)) {
BKE_sequencer_cache_cleanup_sequence(cur);
BKE_sequencer_preprocessed_cache_cleanup_sequence(cur);
}
}
SEQ_END
}
void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
{
sequence_invalidate_cache(scene, seq, TRUE);
}
void BKE_sequence_invalidate_cache_for_modifier(Scene *scene, Sequence *seq)
{
sequence_invalidate_cache(scene, seq, FALSE);
}
void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, int check_mem_usage, int keep_file_handles)
{
Sequence *seq;
@@ -3941,6 +4042,12 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
seqn->strip->color_balance = MEM_dupallocN(seq->strip->color_balance);
}
if (seqn->modifiers.first) {
seqn->modifiers.first = seqn->modifiers.last = NULL;
BKE_sequence_modifier_list_copy(seqn, seq);
}
if (seq->type == SEQ_TYPE_META) {
seqn->strip->stripdata = NULL;
@@ -4060,3 +4167,4 @@ int BKE_seqence_is_valid_check(Sequence *seq)
return TRUE;
}

View File

@@ -4785,6 +4785,16 @@ static void link_paint(FileData *fd, Scene *sce, Paint *p)
}
}
static void lib_link_sequence_modifiers(FileData *fd, Scene *scene, ListBase *lb)
{
SequenceModifierData *smd;
for (smd = lb->first; smd; smd = smd->next) {
if (smd->mask_id)
smd->mask_id = newlibadr_us(fd, scene->id.lib, smd->mask_id);
}
}
static void lib_link_scene(FileData *fd, Main *main)
{
Scene *sce;
@@ -4869,6 +4879,8 @@ static void lib_link_scene(FileData *fd, Main *main)
}
}
seq->anim = NULL;
lib_link_sequence_modifiers(fd, sce, &seq->modifiers);
}
SEQ_END
@@ -4925,6 +4937,29 @@ static void direct_link_paint(FileData *fd, Paint **paint)
(*paint)->num_input_samples = 1;
}
static void direct_link_sequence_modifiers(FileData *fd, ListBase *lb)
{
SequenceModifierData *smd;
link_list(fd, lb);
for (smd = lb->first; smd; smd = smd->next) {
if (smd->mask_sequence)
smd->mask_sequence = newdataadr(fd, smd->mask_sequence);
if (smd->type == seqModifierType_Curves) {
CurvesModifierData *cmd = (CurvesModifierData *) smd;
direct_link_curvemapping(fd, &cmd->curve_mapping);
}
else if (smd->type == seqModifierType_HueCorrect) {
HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
direct_link_curvemapping(fd, &hcmd->curve_mapping);
}
}
}
static void direct_link_scene(FileData *fd, Scene *sce)
{
Editing *ed;
@@ -5037,6 +5072,8 @@ static void direct_link_scene(FileData *fd, Scene *sce)
// seq->strip->color_balance->gui = 0; // XXX - peter, is this relevant in 2.5?
}
}
direct_link_sequence_modifiers(fd, &seq->modifiers);
}
SEQ_END

View File

@@ -646,15 +646,21 @@ static void write_animdata(WriteData *wd, AnimData *adt)
write_nladata(wd, &adt->nla_tracks);
}
static void write_curvemapping(WriteData *wd, CurveMapping *cumap)
static void write_curvemapping_curves(WriteData *wd, CurveMapping *cumap)
{
int a;
writestruct(wd, DATA, "CurveMapping", 1, cumap);
for (a=0; a<CM_TOT; a++)
for (a = 0; a < CM_TOT; a++)
writestruct(wd, DATA, "CurveMapPoint", cumap->cm[a].totpoint, cumap->cm[a].curve);
}
static void write_curvemapping(WriteData *wd, CurveMapping *cumap)
{
writestruct(wd, DATA, "CurveMapping", 1, cumap);
write_curvemapping_curves(wd, cumap);
}
static void write_node_socket(WriteData *wd, bNodeSocket *sock)
{
bNodeSocketType *stype= ntreeGetSocketType(sock->type);
@@ -2086,6 +2092,32 @@ static void write_lamps(WriteData *wd, ListBase *idbase)
}
}
static void write_sequence_modifiers(WriteData *wd, ListBase *modbase)
{
SequenceModifierData *smd;
for (smd = modbase->first; smd; smd = smd->next) {
SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
if (smti) {
writestruct(wd, DATA, smti->struct_name, 1, smd);
if (smd->type == seqModifierType_Curves) {
CurvesModifierData *cmd = (CurvesModifierData *) smd;
write_curvemapping(wd, &cmd->curve_mapping);
}
else if (smd->type == seqModifierType_HueCorrect) {
HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
write_curvemapping(wd, &hcmd->curve_mapping);
}
}
else {
writestruct(wd, DATA, "SequenceModifierData", 1, smd);
}
}
}
static void write_scenes(WriteData *wd, ListBase *scebase)
{
@@ -2192,6 +2224,8 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
strip->done = TRUE;
}
write_sequence_modifiers(wd, &seq->modifiers);
}
SEQ_END

View File

@@ -40,6 +40,7 @@ set(SRC
sequencer_buttons.c
sequencer_draw.c
sequencer_edit.c
sequencer_modifier.c
sequencer_ops.c
sequencer_scopes.c
sequencer_select.c

View File

@@ -177,5 +177,9 @@ struct ImBuf *make_histogram_view_from_ibuf(struct ImBuf * ibuf);
void sequencer_buttons_register(struct ARegionType *art);
void SEQUENCER_OT_properties(struct wmOperatorType *ot);
/* sequencer_modifiers.c */
void SEQUENCER_OT_strip_modifier_add(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_modifier_remove(struct wmOperatorType *ot);
#endif /* __SEQUENCER_INTERN_H__ */

View File

@@ -0,0 +1,164 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2012 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,
* Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/editors/space_sequencer/sequencer_modifier.c
* \ingroup spseq
*/
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_scene_types.h"
#include "DNA_mask_types.h"
#include "DNA_userdef_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_sequencer.h"
#include "BKE_movieclip.h"
#include "BKE_sequencer.h"
#include "BKE_mask.h"
#include "BKE_report.h"
#include "WM_api.h"
#include "WM_types.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "UI_interface.h"
#include "UI_resources.h"
/* own include */
#include "sequencer_intern.h"
/*********************** Add modifier operator *************************/
static int strip_modifier_active_poll(bContext *C)
{
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
if (ed) {
Sequence *seq = BKE_sequencer_active_get(scene);
if (seq)
return BKE_sequence_supports_modifiers(seq);
}
return FALSE;
}
static int strip_modifier_add_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Sequence *seq = BKE_sequencer_active_get(scene);
int type = RNA_enum_get(op->ptr, "type");
BKE_sequence_modifier_new(seq, type);
BKE_sequence_invalidate_cache(scene, seq);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
}
void SEQUENCER_OT_strip_modifier_add(wmOperatorType *ot)
{
PropertyRNA *prop;
/* TODO: de-duplicate from RNA */
static EnumPropertyItem sequence_modifier_type_items[] = {
{seqModifierType_ColorBalance, "COLOR_BALANCE", ICON_NONE, "Color Balance", ""},
{seqModifierType_Curves, "CURVES", ICON_NONE, "Curves", ""},
{seqModifierType_HueCorrect,"HUE_CORRECT", ICON_NONE, "Hue Correct", ""},
{0, NULL, 0, NULL, NULL}
};
/* identifiers */
ot->name = "Add Strip Modifier";
ot->idname = "SEQUENCER_OT_strip_modifier_add";
ot->description = "Add a modifier to strip";
/* api callbacks */
ot->exec = strip_modifier_add_exec;
ot->poll = strip_modifier_active_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
prop = RNA_def_enum(ot->srna, "type", sequence_modifier_type_items, seqModifierType_ColorBalance, "Type", "");
ot->prop = prop;
}
/*********************** Remove modifier operator *************************/
static int strip_modifier_remove_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Sequence *seq = BKE_sequencer_active_get(scene);
char name[MAX_NAME];
SequenceModifierData *smd;
RNA_string_get(op->ptr, "name", name);
smd = BKE_sequence_modifier_find_by_name(seq, name);
if (!smd)
return OPERATOR_CANCELLED;
BLI_remlink(&seq->modifiers, smd);
BKE_sequence_modifier_free(smd);
BKE_sequence_invalidate_cache(scene, seq);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
}
void SEQUENCER_OT_strip_modifier_remove(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Remove Strip Modifier";
ot->idname = "SEQUENCER_OT_strip_modifier_remove";
ot->description = "Add a modifier to strip";
/* api callbacks */
ot->exec = strip_modifier_remove_exec;
ot->poll = strip_modifier_active_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
RNA_def_string(ot->srna, "name", "Name", MAX_NAME, "Name", "Name of modifier to remove");
}

View File

@@ -114,6 +114,10 @@ void sequencer_operatortypes(void)
WM_operatortype_append(SEQUENCER_OT_copy);
WM_operatortype_append(SEQUENCER_OT_paste);
/* sequencer_modifiers.c */
WM_operatortype_append(SEQUENCER_OT_strip_modifier_add);
WM_operatortype_append(SEQUENCER_OT_strip_modifier_remove);
}

View File

@@ -34,6 +34,7 @@
#define __DNA_SEQUENCE_TYPES_H__
#include "DNA_defs.h"
#include "DNA_color_types.h"
#include "DNA_listBase.h"
#include "DNA_vec_types.h"
@@ -167,6 +168,9 @@ typedef struct Sequence {
/* is sfra needed anymore? - it looks like its only used in one place */
int sfra, pad; /* starting frame according to the timeline of the scene. */
/* modifiers */
ListBase modifiers;
} Sequence;
typedef struct MetaStack {
@@ -229,6 +233,40 @@ typedef struct SpeedControlVars {
int lastValidFrame;
} SpeedControlVars;
/* ***************** Sequence modifiers ****************** */
typedef struct SequenceModifierData {
struct SequenceModifierData *next, *prev;
int type, flag;
char name[64]; /* MAX_NAME */
/* mask input, either sequence or maks ID */
int mask_input_type, pad;
struct Sequence *mask_sequence;
struct Mask *mask_id;
} SequenceModifierData;
typedef struct ColorBalanceModifierData {
SequenceModifierData modifier;
StripColorBalance color_balance;
float color_multiply;
int pad;
} ColorBalanceModifierData;
typedef struct CurvesModifierData {
SequenceModifierData modifier;
struct CurveMapping curve_mapping;
} CurvesModifierData;
typedef struct HueCorrectModifierData {
SequenceModifierData modifier;
struct CurveMapping curve_mapping;
} HueCorrectModifierData;
#define MAXSEQ 32
#define SELECT 1
@@ -352,5 +390,26 @@ enum {
#define SEQ_HAS_PATH(_seq) (ELEM4((_seq)->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD))
#endif
/* modifiers */
/* SequenceModifierData->type */
enum {
seqModifierType_ColorBalance = 1,
seqModifierType_Curves = 2,
seqModifierType_HueCorrect = 3,
NUM_SEQUENCE_MODIFIER_TYPES
};
/* SequenceModifierData->flag */
enum {
SEQUENCE_MODIFIER_MUTE = (1 << 0),
SEQUENCE_MODIFIER_EXPANDED = (1 << 1),
};
enum {
SEQUENCE_MASK_INPUT_STRIP = 0,
SEQUENCE_MASK_INPUT_ID = 1
};
#endif

View File

@@ -332,8 +332,9 @@ static char *rna_SequenceTransform_path(PointerRNA *ptr)
return BLI_strdup("");
}
static void rna_SequenceTransform_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
static void rna_SequenceTransform_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
Sequence *seq = sequence_get_by_transform(ed, ptr->data);
@@ -376,8 +377,9 @@ static char *rna_SequenceCrop_path(PointerRNA *ptr)
return BLI_strdup("");
}
static void rna_SequenceCrop_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
static void rna_SequenceCrop_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
Sequence *seq = sequence_get_by_crop(ed, ptr->data);
@@ -613,8 +615,9 @@ static void rna_SequenceElement_filename_set(PointerRNA *ptr, const char *value)
}
#endif
static void rna_Sequence_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
static void rna_Sequence_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
if (ed) {
@@ -638,8 +641,9 @@ static int rna_Sequence_otherSequence_poll(PointerRNA *ptr, PointerRNA value)
return TRUE;
}
static void rna_Sequence_update_reopen_files(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
static void rna_Sequence_update_reopen_files(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
BKE_sequencer_free_imbuf(scene, &ed->seqbase, FALSE, FALSE);
@@ -648,16 +652,18 @@ static void rna_Sequence_update_reopen_files(Main *UNUSED(bmain), Scene *scene,
BKE_sequencer_update_sound_bounds(scene, ptr->data);
}
static void rna_Sequence_mute_update(Main *bmain, Scene *scene, PointerRNA *ptr)
static void rna_Sequence_mute_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
BKE_sequencer_update_muting(ed);
rna_Sequence_update(bmain, scene, ptr);
}
static void rna_Sequence_filepath_update(Main *bmain, Scene *scene, PointerRNA *ptr)
static void rna_Sequence_filepath_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
Sequence *seq = (Sequence *)(ptr->data);
BKE_sequence_reload_new_file(scene, seq, TRUE);
BKE_sequence_calc(scene, seq);
@@ -686,8 +692,9 @@ static Sequence *sequence_get_by_proxy(Editing *ed, StripProxy *proxy)
return data.seq;
}
static void rna_Sequence_tcindex_update(Main *bmain, Scene *scene, PointerRNA *ptr)
static void rna_Sequence_tcindex_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
Sequence *seq = sequence_get_by_proxy(ed, ptr->data);
@@ -695,8 +702,9 @@ static void rna_Sequence_tcindex_update(Main *bmain, Scene *scene, PointerRNA *p
rna_Sequence_frame_change_update(scene, seq);
}
static void rna_SequenceProxy_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
static void rna_SequenceProxy_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
Sequence *seq = sequence_get_by_proxy(ed, ptr->data);
@@ -724,6 +732,22 @@ static int colbalance_seq_cmp_cb(Sequence *seq, void *arg_pt)
data->seq = seq;
return -1; /* done so bail out */
}
if (seq->modifiers.first) {
SequenceModifierData *smd = seq->modifiers.first;
for (smd = seq->modifiers.first; smd; smd = smd->next) {
if (smd->type == seqModifierType_ColorBalance) {
ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd;
if (&cbmd->color_balance == data->data) {
data->seq = seq;
return -1; /* done so bail out */
}
}
}
}
return 1;
}
@@ -752,12 +776,16 @@ static char *rna_SequenceColorBalance_path(PointerRNA *ptr)
return BLI_strdup("");
}
static void rna_SequenceColorBalance_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
static void rna_SequenceColorBalance_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *scene = (Scene *) ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
Sequence *seq = sequence_get_by_colorbalance(ed, ptr->data);
BKE_sequence_invalidate_cache(scene, seq);
if (seq->strip->color_balance == ptr->data)
BKE_sequence_invalidate_cache(scene, seq);
else
BKE_sequence_invalidate_cache_for_modifier(scene, seq);
}
static void rna_SequenceEditor_overlay_lock_set(PointerRNA *ptr, int value)
@@ -825,6 +853,113 @@ static float rna_WipeSequence_angle_get(PointerRNA *ptr)
return DEG2RADF(((WipeVars *)seq->effectdata)->angle);
}
static int modifier_seq_cmp_cb(Sequence *seq, void *arg_pt)
{
SequenceSearchData *data = arg_pt;
if (BLI_findindex(&seq->modifiers, data->data) != -1) {
data->seq = seq;
return -1; /* done so bail out */
}
return 1;
}
static Sequence *sequence_get_by_modifier(Editing *ed, SequenceModifierData *smd)
{
SequenceSearchData data;
data.seq = NULL;
data.data = smd;
/* irritating we need to search for our sequence! */
BKE_sequencer_base_recursive_apply(&ed->seqbase, modifier_seq_cmp_cb, &data);
return data.seq;
}
static StructRNA *rna_SequenceModifier_refine(struct PointerRNA *ptr)
{
SequenceModifierData *smd = (SequenceModifierData *) ptr->data;
switch (smd->type) {
case seqModifierType_ColorBalance:
return &RNA_ColorBalanceModifier;
case seqModifierType_Curves:
return &RNA_CurvesModifier;
case seqModifierType_HueCorrect:
return &RNA_HueCorrectModifier;
default:
return &RNA_SequenceModifier;
}
}
static char *rna_SequenceModifier_path(PointerRNA *ptr)
{
Scene *scene = ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
SequenceModifierData *smd = ptr->data;
Sequence *seq = sequence_get_by_modifier(ed, smd);
if (seq && seq->name + 2)
return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].modifiers[\"%s\"]", seq->name + 2, smd->name);
else
return BLI_strdup("");
}
static void rna_SequenceModifier_name_set(PointerRNA *ptr, const char *value)
{
SequenceModifierData *smd = ptr->data;
Scene *scene = (Scene *) ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
Sequence *seq = sequence_get_by_modifier(ed, smd);
AnimData *adt;
char oldname[sizeof(smd->name)];
/* make a copy of the old name first */
BLI_strncpy(oldname, smd->name, sizeof(smd->name));
/* copy the new name into the name slot */
BLI_strncpy_utf8(smd->name, value, sizeof(smd->name));
/* make sure the name is truly unique */
BKE_sequence_modifier_unique_name(seq, smd);
/* fix all the animation data which may link to this */
adt = BKE_animdata_from_id(&scene->id);
if (adt) {
char path[1024];
BLI_snprintf(path, sizeof(path), "sequence_editor.sequences_all[\"%s\"].modifiers", seq->name);
BKE_animdata_fix_paths_rename(&scene->id, adt, NULL, path, oldname, smd->name + 2, 0, 0, 1);
}
}
static void rna_SequenceModifier_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
/* strip from other scenes could be modified, so using active scene is not reliable */
Scene *scene = (Scene *) ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
Sequence *seq = sequence_get_by_modifier(ed, ptr->data);
BKE_sequence_invalidate_cache_for_modifier(scene, seq);
}
static int rna_SequenceModifier_otherSequence_poll(PointerRNA *ptr, PointerRNA value)
{
Scene *scene = (Scene *) ptr->id.data;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
Sequence *seq = sequence_get_by_modifier(ed, ptr->data);
Sequence *cur = (Sequence *) value.data;
if (seq == cur)
return FALSE;
if (BKE_sequence_check_depend(seq, cur))
return FALSE;
return TRUE;
}
#else
@@ -991,13 +1126,13 @@ static void rna_def_strip_proxy(BlenderRNA *brna)
}
static void rna_def_strip_color_balance(BlenderRNA *brna)
static void rna_def_color_balance(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "SequenceColorBalance", NULL);
RNA_def_struct_ui_text(srna, "Sequence Color Balance", "Color balance parameters for a sequence strip");
srna = RNA_def_struct(brna, "SequenceColorBalanceData", NULL);
RNA_def_struct_ui_text(srna, "Sequence Color Balance Data", "Color balance parameters for a sequence strip and it's modifiers");
RNA_def_struct_sdna(srna, "StripColorBalance");
prop = RNA_def_property(srna, "lift", PROP_FLOAT, PROP_COLOR);
@@ -1005,19 +1140,19 @@ static void rna_def_strip_color_balance(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
prop = RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_COLOR);
RNA_def_property_ui_text(prop, "Gamma", "Color balance gamma (midtones)");
RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
prop = RNA_def_property(srna, "gain", PROP_FLOAT, PROP_COLOR);
RNA_def_property_ui_text(prop, "Gain", "Color balance gain (highlights)");
RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
prop = RNA_def_property(srna, "invert_gain", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_GAIN);
RNA_def_property_ui_text(prop, "Inverse Gain", "");
@@ -1033,15 +1168,13 @@ static void rna_def_strip_color_balance(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Inverse Lift", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
RNA_def_struct_path_func(srna, "rna_SequenceColorBalance_path");
/* not yet used */
#if 0
prop = RNA_def_property(srna, "exposure", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Exposure", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_ColorBabalnce_update");
prop = RNA_def_property(srna, "saturation", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Saturation", "");
@@ -1049,6 +1182,17 @@ static void rna_def_strip_color_balance(BlenderRNA *brna)
#endif
}
static void rna_def_strip_color_balance(BlenderRNA *brna)
{
StructRNA *srna;
srna = RNA_def_struct(brna, "SequenceColorBalance", "SequenceColorBalanceData");
RNA_def_struct_ui_text(srna, "Sequence Color Balance", "Color balance parameters for a sequence strip");
RNA_def_struct_sdna(srna, "StripColorBalance");
RNA_def_struct_path_func(srna, "rna_SequenceColorBalance_path");
}
EnumPropertyItem blend_mode_items[] = {
{SEQ_BLEND_REPLACE, "REPLACE", 0, "Replace", ""},
{SEQ_TYPE_CROSS, "CROSS", 0, "Cross", ""},
@@ -1062,6 +1206,18 @@ EnumPropertyItem blend_mode_items[] = {
{0, NULL, 0, NULL, NULL}
};
static void rna_def_sequence_modifiers(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
RNA_def_property_srna(cprop, "SequenceModifiers");
srna = RNA_def_struct(brna, "SequenceModifiers", NULL);
RNA_def_struct_sdna(srna, "Sequence");
RNA_def_struct_ui_text(srna, "Strip Modifiers", "Collection of strip modifiers");
/* TODO: implement new/remove/clear methods for modifier stack */
}
static void rna_def_sequence(BlenderRNA *brna)
{
StructRNA *srna;
@@ -1253,6 +1409,12 @@ static void rna_def_sequence(BlenderRNA *brna)
"to this frame");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
/* modifiers */
prop = RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "SequenceModifier");
RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting this strip");
rna_def_sequence_modifiers(brna, prop);
RNA_api_sequence_strip(srna);
}
@@ -1475,7 +1637,7 @@ static void rna_def_effect_inputs(StructRNA *srna, int count, int supports_mask)
*/
if (supports_mask) {
prop = RNA_def_property(srna, "input_mask", PROP_POINTER, PROP_NONE);
prop = RNA_def_property(srna, "input_mask_strip", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "mask_sequence");
RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Sequence_otherSequence_poll");
RNA_def_property_flag(prop, PROP_EDITABLE);
@@ -1963,8 +2125,138 @@ static void rna_def_effects(BlenderRNA *brna)
}
}
static void rna_def_modifier(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
static EnumPropertyItem sequence_modifier_type_items[] = {
{seqModifierType_ColorBalance, "COLOR_BALANCE", ICON_NONE, "Color Balance", ""},
{seqModifierType_Curves, "CURVES", ICON_NONE, "Curves", ""},
{seqModifierType_HueCorrect,"HUE_CORRECT", ICON_NONE, "Hue Correct", ""},
{0, NULL, 0, NULL, NULL}
};
static const EnumPropertyItem mask_input_type_items[] = {
{SEQUENCE_MASK_INPUT_STRIP, "STRIP", 0, "Strip", "Use sequencer strip as mask input"},
{SEQUENCE_MASK_INPUT_ID, "ID", 0, "Mask", "Use mask ID as mask input"},
{0, NULL, 0, NULL, NULL}
};
srna = RNA_def_struct(brna, "SequenceModifier", NULL);
RNA_def_struct_sdna(srna, "SequenceModifierData");
RNA_def_struct_ui_text(srna, "SequenceModifier", "Modifier for sequence strip");
RNA_def_struct_refine_func(srna, "rna_SequenceModifier_refine");
RNA_def_struct_path_func(srna, "rna_SequenceModifier_path");
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SequenceModifier_name_set");
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_struct_name_property(srna, prop);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, sequence_modifier_type_items);
RNA_def_property_ui_text(prop, "Type", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQUENCE_MODIFIER_MUTE);
RNA_def_property_ui_text(prop, "Mute", "Mute this modifier");
RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, 1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQUENCE_MODIFIER_EXPANDED);
RNA_def_property_ui_text(prop, "Expanded", "Mute expanded settings for the modifier");
RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
prop = RNA_def_property(srna, "input_mask_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mask_input_type");
RNA_def_property_enum_items(prop, mask_input_type_items);
RNA_def_property_ui_text(prop, "Mask Input Type", "Type of input data used for mask");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
prop = RNA_def_property(srna, "input_mask_strip", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "mask_sequence");
RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_SequenceModifier_otherSequence_poll");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Mask Strip", "Strip used as mask input for the modifier");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
prop = RNA_def_property(srna, "input_mask_id", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "mask_id");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Mask", "Mask ID used as mask input for the modifier");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
}
static void rna_def_colorbalance_modifier(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "ColorBalanceModifier", "SequenceModifier");
RNA_def_struct_sdna(srna, "ColorBalanceModifierData");
RNA_def_struct_ui_text(srna, "ColorBalanceModifier", "Color balance modifier for sequence strip");
prop = RNA_def_property(srna, "color_balance", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "SequenceColorBalanceData");
prop = RNA_def_property(srna, "color_multiply", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "color_multiply");
RNA_def_property_range(prop, 0.0f, 20.0f);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_ui_text(prop, "Multiply Colors", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
}
static void rna_def_curves_modifier(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "CurvesModifier", "SequenceModifier");
RNA_def_struct_sdna(srna, "CurvesModifierData");
RNA_def_struct_ui_text(srna, "CurvesModifier", "RGB curves modifier for sequence strip");
prop = RNA_def_property(srna, "curve_mapping", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "curve_mapping");
RNA_def_property_struct_type(prop, "CurveMapping");
RNA_def_property_ui_text(prop, "Curve Mapping", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
}
static void rna_def_hue_modifier(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "HueCorrectModifier", "SequenceModifier");
RNA_def_struct_sdna(srna, "HueCorrectModifierData");
RNA_def_struct_ui_text(srna, "HueCorrectModifier", "Hue correction modifier for sequence strip");
prop = RNA_def_property(srna, "curve_mapping", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "curve_mapping");
RNA_def_property_struct_type(prop, "CurveMapping");
RNA_def_property_ui_text(prop, "Curve Mapping", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
}
static void rna_def_modifiers(BlenderRNA *brna)
{
rna_def_modifier(brna);
rna_def_colorbalance_modifier(brna);
rna_def_curves_modifier(brna);
rna_def_hue_modifier(brna);
}
void RNA_def_sequencer(BlenderRNA *brna)
{
rna_def_color_balance(brna);
rna_def_strip_element(brna);
rna_def_strip_proxy(brna);
rna_def_strip_color_balance(brna);
@@ -1983,6 +2275,7 @@ void RNA_def_sequencer(BlenderRNA *brna)
rna_def_sound(brna);
rna_def_effect(brna);
rna_def_effects(brna);
rna_def_modifiers(brna);
}
#endif

View File

@@ -125,6 +125,7 @@ void RNA_api_ui_layout(StructRNA *srna)
{0, "NONE", 0, "None", ""},
{'v', "VECTOR", 0, "Vector", ""},
{'c', "COLOR", 0, "Color", ""},
{'h', "HUE", 0, "Hue", ""},
{0, NULL, 0, NULL, NULL}
};