Revert "VSE: Media transform redesign"

This reverts commit 0277579b28.

This commit caused build errors on Linux.
This commit is contained in:
Richard Antalik 2020-11-02 20:59:21 +01:00
parent b9ec6c305c
commit 6b3eca661d
11 changed files with 215 additions and 574 deletions

View File

@ -949,28 +949,54 @@ class SEQUENCER_PT_strip(SequencerButtonsPanel, Panel):
row.prop(strip, "mute", toggle=True, icon_only=True, emboss=False)
class SEQUENCER_PT_adjust_crop(SequencerButtonsPanel, Panel):
bl_label = "Crop"
class SEQUENCER_PT_adjust_transform_offset(SequencerButtonsPanel, Panel):
bl_label = "Offset"
bl_parent_id = "SEQUENCER_PT_adjust_transform"
bl_options = {'DEFAULT_CLOSED'}
bl_category = "Strip"
@classmethod
def poll(cls, context):
if not cls.has_sequencer(context):
return False
strip = act_strip(context)
if not strip:
return False
strip = act_strip(context)
return strip.type != 'SOUND'
def draw_header(self, context):
strip = act_strip(context)
self.layout.prop(strip, "use_translation", text="")
def draw(self, context):
strip = act_strip(context)
layout = self.layout
layout.use_property_split = True
layout.active = not strip.mute
layout.active = strip.use_translation and (not strip.mute)
col = layout.column(align=True)
col.prop(strip.transform, "offset_x", text="Position X")
col.prop(strip.transform, "offset_y", text="Y")
class SEQUENCER_PT_adjust_transform_crop(SequencerButtonsPanel, Panel):
bl_label = "Crop"
bl_parent_id = "SEQUENCER_PT_adjust_transform"
bl_options = {'DEFAULT_CLOSED'}
bl_category = "Strip"
@classmethod
def poll(cls, context):
strip = act_strip(context)
return strip.type != 'SOUND'
def draw_header(self, context):
strip = act_strip(context)
self.layout.prop(strip, "use_crop", text="")
def draw(self, context):
strip = act_strip(context)
layout = self.layout
layout.use_property_split = True
layout.active = strip.use_crop and (not strip.mute)
col = layout.column(align=True)
col.prop(strip.crop, "min_x")
@ -1564,19 +1590,21 @@ class SEQUENCER_PT_time(SequencerButtonsPanel, Panel):
split.label(text="%d-%d (%d)" % (sta, end, end - sta + 1), translate=False)
class SEQUENCER_PT_adjust(SequencerButtonsPanel, Panel):
bl_label = "Adjust"
bl_category = "Strip"
def draw(self, context):
pass
class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel):
bl_label = "Sound"
bl_parent_id = "SEQUENCER_PT_adjust"
bl_category = "Strip"
@classmethod
def poll(cls, context):
if not cls.has_sequencer(context):
return False
strip = act_strip(context)
if not strip:
return False
strip = act_strip(context)
return strip.type == 'SOUND'
@ -1608,17 +1636,11 @@ class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel):
class SEQUENCER_PT_adjust_comp(SequencerButtonsPanel, Panel):
bl_label = "Compositing"
bl_parent_id = "SEQUENCER_PT_adjust"
bl_category = "Strip"
@classmethod
def poll(cls, context):
if not cls.has_sequencer(context):
return False
strip = act_strip(context)
if not strip:
return False
strip = act_strip(context)
return strip.type != 'SOUND'
@ -1637,8 +1659,8 @@ class SEQUENCER_PT_adjust_comp(SequencerButtonsPanel, Panel):
class SEQUENCER_PT_adjust_transform(SequencerButtonsPanel, Panel):
bl_label = "Transform"
bl_parent_id = "SEQUENCER_PT_adjust"
bl_category = "Strip"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
@ -1649,26 +1671,23 @@ class SEQUENCER_PT_adjust_transform(SequencerButtonsPanel, Panel):
if not strip:
return False
strip = act_strip(context)
return strip.type != 'SOUND'
return strip.type in {
'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'MASK',
'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'TEXT',
'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY',
'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX'
}
def draw(self, context):
strip = act_strip(context)
layout = self.layout
strip = act_strip(context)
layout.use_property_split = True
layout.use_property_decorate = False
layout.active = not strip.mute
col = layout.column(align=True)
col.prop(strip.transform, "offset_x", text="Position X")
col.prop(strip.transform, "offset_y", text="Y")
col = layout.column(align=True)
col.prop(strip.transform, "scale_x", text="Scale X")
col.prop(strip.transform, "scale_y", text="Y")
col = layout.column(align=True)
col.prop(strip.transform, "rotation", text="Rotation")
row = layout.row(heading="Mirror")
sub = row.row(align=True)
sub.prop(strip, "use_flip_x", text="X", toggle=True)
@ -1677,6 +1696,7 @@ class SEQUENCER_PT_adjust_transform(SequencerButtonsPanel, Panel):
class SEQUENCER_PT_adjust_video(SequencerButtonsPanel, Panel):
bl_label = "Video"
bl_parent_id = "SEQUENCER_PT_adjust"
bl_options = {'DEFAULT_CLOSED'}
bl_category = "Strip"
@ -1725,6 +1745,7 @@ class SEQUENCER_PT_adjust_video(SequencerButtonsPanel, Panel):
class SEQUENCER_PT_adjust_color(SequencerButtonsPanel, Panel):
bl_label = "Color"
bl_parent_id = "SEQUENCER_PT_adjust"
bl_options = {'DEFAULT_CLOSED'}
bl_category = "Strip"
@ -2213,9 +2234,11 @@ classes = (
SEQUENCER_PT_effect_text_style,
SEQUENCER_PT_effect_text_layout,
SEQUENCER_PT_adjust,
SEQUENCER_PT_adjust_comp,
SEQUENCER_PT_adjust_transform,
SEQUENCER_PT_adjust_crop,
SEQUENCER_PT_adjust_transform_offset,
SEQUENCER_PT_adjust_transform_crop,
SEQUENCER_PT_adjust_video,
SEQUENCER_PT_adjust_color,
SEQUENCER_PT_adjust_sound,

View File

@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 2
#define BLENDER_FILE_SUBVERSION 1
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file

View File

@ -322,13 +322,9 @@ void mat4_to_size(float size[3], const float M[4][4]);
void mat4_to_size_fix_shear(float size[3], const float M[4][4]);
void translate_m3(float mat[3][3], float tx, float ty);
void translate_m4(float mat[4][4], float tx, float ty, float tz);
void rotate_m3(float mat[3][3], const float angle);
void rotate_m4(float mat[4][4], const char axis, const float angle);
void rescale_m3(float mat[3][3], const float scale[2]);
void rescale_m4(float mat[4][4], const float scale[3]);
void transform_pivot_set_m3(float mat[3][3], const float pivot[2]);
void transform_pivot_set_m4(float mat[4][4], const float pivot[3]);
void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3]);
@ -338,10 +334,6 @@ void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat
void mat3_polar_decompose(const float mat3[3][3], float r_U[3][3], float r_P[3][3]);
void loc_rot_size_to_mat3(float R[3][3],
const float loc[2],
const float angle,
const float size[2]);
void loc_rot_size_to_mat4(float R[4][4],
const float loc[3],
const float rot[3][3],

View File

@ -2223,12 +2223,6 @@ void scale_m4_fl(float R[4][4], float scale)
R[3][0] = R[3][1] = R[3][2] = 0.0;
}
void translate_m3(float mat[3][3], float tx, float ty)
{
mat[2][0] += (tx * mat[0][0] + ty * mat[1][0]);
mat[2][1] += (tx * mat[0][1] + ty * mat[1][1]);
}
void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
{
mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]);
@ -2236,18 +2230,6 @@ void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]);
}
void rotate_m3(float mat[3][3], const float angle)
{
const float angle_cos = cosf(angle);
const float angle_sin = sinf(angle);
for (int col = 0; col < 3; col++) {
float temp = angle_cos * mat[0][col] + angle_sin * mat[1][col];
mat[1][col] = -angle_sin * mat[0][col] + angle_cos * mat[1][col];
mat[0][col] = temp;
}
}
/* TODO: enum for axis? */
/**
* Rotate a matrix in-place.
@ -2293,12 +2275,6 @@ void rotate_m4(float mat[4][4], const char axis, const float angle)
}
}
void rescale_m3(float mat[3][3], const float scale[2])
{
mul_v3_fl(mat[0], scale[0]);
mul_v3_fl(mat[1], scale[1]);
}
/** Scale a matrix in-place. */
void rescale_m4(float mat[4][4], const float scale[3])
{
@ -2329,20 +2305,6 @@ void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
mul_m4_m4m4(mat, mat, tmat);
}
void transform_pivot_set_m3(float mat[3][3], const float pivot[2])
{
float tmat[3][3];
unit_m3(tmat);
copy_v2_v2(tmat[2], pivot);
mul_m3_m3m3(mat, tmat, mat);
/* invert the matrix */
negate_v2(tmat[2]);
mul_m3_m3m3(mat, mat, tmat);
}
void blend_m3_m3m3(float out[3][3],
const float dst[3][3],
const float src[3][3],
@ -2522,21 +2484,6 @@ bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
equals_v4v4(mat1[2], mat2[2]) && equals_v4v4(mat1[3], mat2[3]));
}
/**
* Make a 3x3 matrix out of 3 transform components.
* Matrices are made in the order: `loc * rot * scale`
*/
void loc_rot_size_to_mat3(float R[3][3],
const float loc[2],
const float angle,
const float size[2])
{
unit_m3(R);
translate_m3(R, loc[0], loc[1]);
rotate_m3(R, angle);
rescale_m3(R, size);
}
/**
* Make a 4x4 matrix out of 3 transform components.
* Matrices are made in the order: `scale * rot * loc`

View File

@ -44,14 +44,12 @@
#include "DNA_rigidbody_types.h"
#include "DNA_screen_types.h"
#include "DNA_shader_fx_types.h"
#include "DNA_space_types.h"
#include "DNA_tracking_types.h"
#include "DNA_workspace_types.h"
#include "BKE_animsys.h"
#include "BKE_collection.h"
#include "BKE_colortools.h"
#include "BKE_fcurve.h"
#include "BKE_gpencil.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
@ -61,154 +59,12 @@
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "SEQ_sequencer.h"
#include "BLO_readfile.h"
#include "readfile.h"
/* Make preferences read-only, use versioning_userdef.c. */
#define U (*((const UserDef *)&U))
/* image_size is width or height depending what RNA property is converted - X or Y. */
static void seq_convert_transform_animation(const Scene *scene,
const char *path,
const int image_size)
{
if (scene->adt == NULL || scene->adt->action == NULL) {
return;
}
FCurve *fcu = BKE_fcurve_find(&scene->adt->action->curves, path, 0);
if (fcu != NULL && !BKE_fcurve_is_empty(fcu)) {
BezTriple *bezt = fcu->bezt;
for (int i = 0; i < fcu->totvert; i++, bezt++) {
/* Same math as with old_image_center_*, but simplified. */
bezt->vec[1][1] = image_size / 2 + bezt->vec[1][1] - scene->r.xsch / 2;
}
}
}
static void seq_convert_transform_crop(const Scene *scene,
Sequence *seq,
const eSpaceSeq_Proxy_RenderSize render_size)
{
StripCrop *c = seq->strip->crop;
StripTransform *t = seq->strip->transform;
int old_image_center_x = scene->r.xsch / 2;
int old_image_center_y = scene->r.ysch / 2;
int image_size_x = scene->r.xsch;
int image_size_y = scene->r.ysch;
/* Hardcoded legacy bit-flags which has been removed. */
const uint32_t use_transform_flag = (1 << 16);
const uint32_t use_crop_flag = (1 << 17);
const StripElem *s_elem = BKE_sequencer_give_stripelem(seq, seq->start);
if (s_elem != NULL) {
image_size_x = s_elem->orig_width;
image_size_y = s_elem->orig_height;
if (SEQ_can_use_proxy(seq, SEQ_rendersize_to_proxysize(render_size))) {
image_size_x /= BKE_sequencer_rendersize_to_scale_factor(render_size);
image_size_y /= BKE_sequencer_rendersize_to_scale_factor(render_size);
}
}
/* Default scale. */
if (t->scale_x == 0.0f && t->scale_y == 0.0f) {
t->scale_x = 1.0f;
t->scale_y = 1.0f;
}
/* Clear crop if it was unused. This must happen before converting values. */
if ((seq->flag & use_crop_flag) == 0) {
c->bottom = c->top = c->left = c->right = 0;
}
if ((seq->flag & use_transform_flag) == 0) {
t->xofs = t->yofs = 0;
/* Reverse scale to fit for strips not using offset. */
float project_aspect = (float)scene->r.xsch / (float)scene->r.ysch;
float image_aspect = (float)image_size_x / (float)image_size_y;
if (project_aspect > image_aspect) {
t->scale_x = project_aspect / image_aspect;
}
else {
t->scale_y = image_aspect / project_aspect;
}
}
if ((seq->flag & use_crop_flag) != 0 && (seq->flag & use_transform_flag) == 0) {
/* Calculate image offset. */
float s_x = scene->r.xsch / image_size_x;
float s_y = scene->r.ysch / image_size_y;
old_image_center_x += c->right * s_x - c->left * s_x;
old_image_center_y += c->top * s_y - c->bottom * s_y;
/* Convert crop to scale. */
int cropped_image_size_x = image_size_x - c->right - c->left;
int cropped_image_size_y = image_size_y - c->top - c->bottom;
c->bottom = c->top = c->left = c->right = 0;
t->scale_x *= (float)image_size_x / (float)cropped_image_size_x;
t->scale_y *= (float)image_size_y / (float)cropped_image_size_y;
}
if ((seq->flag & use_transform_flag) != 0) {
/* Convert image offset. */
old_image_center_x = image_size_x / 2 - c->left + t->xofs;
old_image_center_y = image_size_y / 2 - c->bottom + t->yofs;
/* Preserve original image size. */
t->scale_x = t->scale_y = MAX2((float)image_size_x / (float)scene->r.xsch,
(float)image_size_y / (float)scene->r.ysch);
/* Convert crop. */
if ((seq->flag & use_crop_flag) != 0) {
c->top /= t->scale_x;
c->bottom /= t->scale_x;
c->left /= t->scale_x;
c->right /= t->scale_x;
}
}
t->xofs = old_image_center_x - scene->r.xsch / 2;
t->yofs = old_image_center_y - scene->r.ysch / 2;
/* Convert offset animation, but only if crop is not used. */
if ((seq->flag & use_transform_flag) != 0 && (seq->flag & use_crop_flag) == 0) {
char name_esc[(sizeof(seq->name) - 2) * 2], *path;
BLI_strescape(name_esc, seq->name + 2, sizeof(name_esc));
path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].transform.offset_x", name_esc);
seq_convert_transform_animation(scene, path, image_size_x);
MEM_freeN(path);
path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].transform.offset_y", name_esc);
seq_convert_transform_animation(scene, path, image_size_y);
MEM_freeN(path);
}
seq->flag &= ~use_transform_flag;
seq->flag &= ~use_crop_flag;
}
static void seq_convert_transform_crop_lb(const Scene *scene,
const ListBase *lb,
const eSpaceSeq_Proxy_RenderSize render_size)
{
LISTBASE_FOREACH (Sequence *, seq, lb) {
if (seq->type != SEQ_TYPE_SOUND_RAM) {
seq_convert_transform_crop(scene, seq, render_size);
}
if (seq->type == SEQ_TYPE_META) {
seq_convert_transform_crop_lb(scene, &seq->seqbase, render_size);
}
}
}
void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
{
if (!MAIN_VERSION_ATLEAST(bmain, 290, 1)) {
@ -436,31 +292,6 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 292, 2)) {
eSpaceSeq_Proxy_RenderSize render_size = 100;
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
switch (sl->spacetype) {
case SPACE_SEQ: {
SpaceSeq *sseq = (SpaceSeq *)sl;
render_size = sseq->render_size;
break;
}
}
}
}
}
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
if (scene->ed != NULL) {
seq_convert_transform_crop_lb(scene, &scene->ed->seqbase, render_size);
}
}
}
/**
* Versioning code until next subversion bump goes here.
*

View File

@ -684,8 +684,6 @@ void IMB_rectfill_area(struct ImBuf *ibuf,
int x2,
int y2,
struct ColorManagedDisplay *display);
void IMB_rectfill_area_replace(
const struct ImBuf *ibuf, const float col[4], int x1, int y1, int x2, int y2);
void IMB_rectfill_alpha(struct ImBuf *ibuf, const float value);
/* This should not be here, really,

View File

@ -1069,11 +1069,8 @@ void IMB_rectblend_threaded(ImBuf *dbuf,
}
}
/**
* Replace pixels of entire image with solid color.
* \param ibuf an image to be filled with color. It must be 4 channel image.
* \param col RGBA color, which is assigned directly to both byte (via scaling) and float buffers.
*/
/* fill */
void IMB_rectfill(ImBuf *drect, const float col[4])
{
int num;
@ -1106,61 +1103,6 @@ void IMB_rectfill(ImBuf *drect, const float col[4])
}
}
/**
* Replace pixels of image area with solid color.
* \param ibuf an image to be filled with color. It must be 4 channel image.
* \param col RGBA color, which is assigned directly to both byte (via scaling) and float buffers.
* \param x1, y1, x2, y2 (x1, y1) defines starting point of the rectangular area to be filled,
* (x2, y2) is the end point. Note that values are allowed to be loosely ordered, which means that
* x2 is allowed to be lower than x1, as well as y2 is allowed to be lower than y1. No matter the
* order the area between x1 and x2, and y1 and y2 is filled.
*/
void IMB_rectfill_area_replace(
const ImBuf *ibuf, const float col[4], int x1, int y1, int x2, int y2)
{
/* Sanity checks. */
BLI_assert(ibuf->channels == 4);
if (ibuf->channels != 4) {
return;
}
int width = ibuf->x;
int height = ibuf->y;
CLAMP(x1, 0, width);
CLAMP(x2, 0, width);
CLAMP(y1, 0, height);
CLAMP(y2, 0, height);
if (x1 > x2) {
SWAP(int, x1, x2);
}
if (y1 > y2) {
SWAP(int, y1, y2);
}
if (x1 == x2 || y1 == y2) {
return;
}
unsigned char col_char[4] = {col[0] * 255, col[1] * 255, col[2] * 255, col[3] * 255};
for (int y = y1; y < y2; y++) {
for (int x = x1; x < x2; x++) {
size_t offset = ((size_t)ibuf->x) * y * 4 + 4 * x;
if (ibuf->rect) {
unsigned char *rrect = (unsigned char *)ibuf->rect + offset;
memcpy(rrect, &col_char, sizeof(unsigned char) * 4);
}
if (ibuf->rect_float) {
float *rrectf = ibuf->rect_float + offset;
memcpy(rrectf, &col, sizeof(float) * 4);
}
}
}
}
void buf_rectfill_area(unsigned char *rect,
float *rectf,
int width,
@ -1272,21 +1214,6 @@ void buf_rectfill_area(unsigned char *rect,
}
}
/**
* Blend pixels of image area with solid color.
*
* For images with uchar buffer use color matching image colorspace.
* For images with float buffer use color display colorspace.
* If display colorspace can not be referenced, use color in SRGB colorspace.
*
* \param ibuf an image to be filled with color. It must be 4 channel image.
* \param col RGBA color.
* \param x1, y1, x2, y2 (x1, y1) defines starting point of the rectangular area to be filled,
* (x2, y2) is the end point. Note that values are allowed to be loosely ordered, which means that
* x2 is allowed to be lower than x1, as well as y2 is allowed to be lower than y1. No matter the
* order the area between x1 and x2, and y1 and y2 is filled.
* \param display colorspace reference for display space.
*/
void IMB_rectfill_area(ImBuf *ibuf,
const float col[4],
int x1,

View File

@ -68,9 +68,6 @@ typedef struct StripCrop {
typedef struct StripTransform {
int xofs;
int yofs;
float scale_x;
float scale_y;
float rotation;
} StripTransform;
typedef struct StripColorBalance {
@ -497,8 +494,8 @@ enum {
SEQ_MAKE_FLOAT = (1 << 13),
SEQ_LOCK = (1 << 14),
SEQ_USE_PROXY = (1 << 15),
SEQ_FLAG_UNUSED_23 = (1 << 16), /* cleared */
SEQ_FLAG_UNUSED_22 = (1 << 17), /* cleared */
SEQ_USE_TRANSFORM = (1 << 16),
SEQ_USE_CROP = (1 << 17),
SEQ_FLAG_UNUSED_18 = (1 << 18), /* cleared */
SEQ_FLAG_UNUSED_19 = (1 << 19), /* cleared */
SEQ_FLAG_UNUSED_21 = (1 << 21), /* cleared */

View File

@ -473,6 +473,34 @@ static void rna_Sequence_use_proxy_set(PointerRNA *ptr, bool value)
BKE_sequencer_proxy_set(seq, value != 0);
}
static void rna_Sequence_use_translation_set(PointerRNA *ptr, bool value)
{
Sequence *seq = (Sequence *)ptr->data;
if (value) {
seq->flag |= SEQ_USE_TRANSFORM;
if (seq->strip->transform == NULL) {
seq->strip->transform = MEM_callocN(sizeof(struct StripTransform), "StripTransform");
}
}
else {
seq->flag &= ~SEQ_USE_TRANSFORM;
}
}
static void rna_Sequence_use_crop_set(PointerRNA *ptr, bool value)
{
Sequence *seq = (Sequence *)ptr->data;
if (value) {
seq->flag |= SEQ_USE_CROP;
if (seq->strip->crop == NULL) {
seq->strip->crop = MEM_callocN(sizeof(struct StripCrop), "StripCrop");
}
}
else {
seq->flag &= ~SEQ_USE_CROP;
}
}
static int transform_seq_cmp_fn(Sequence *seq, void *arg_pt)
{
SequenceSearchData *data = arg_pt;
@ -1381,35 +1409,18 @@ static void rna_def_strip_transform(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Sequence Transform", "Transform parameters for a sequence strip");
RNA_def_struct_sdna(srna, "StripTransform");
prop = RNA_def_property(srna, "scale_x", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "scale_x");
RNA_def_property_ui_text(prop, "Scale X", "Scale along X axis");
RNA_def_property_ui_range(prop, 0, FLT_MAX, 3, 3);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
prop = RNA_def_property(srna, "scale_y", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "scale_y");
RNA_def_property_ui_text(prop, "Scale Y", "Scale along Y axis");
RNA_def_property_ui_range(prop, 0, FLT_MAX, 3, 3);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
prop = RNA_def_property(srna, "offset_x", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "xofs");
RNA_def_property_ui_text(prop, "Translate X", "Move along X axis");
RNA_def_property_ui_range(prop, INT_MIN, INT_MAX, 1, 6);
RNA_def_property_ui_text(
prop, "Offset X", "Amount to move the input on the X axis within its boundaries");
RNA_def_property_ui_range(prop, -4096, 4096, 1, -1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
prop = RNA_def_property(srna, "offset_y", PROP_INT, PROP_PIXEL);
RNA_def_property_int_sdna(prop, NULL, "yofs");
RNA_def_property_ui_text(prop, "Translate Y", "Move along Y axis");
RNA_def_property_ui_range(prop, INT_MIN, INT_MAX, 1, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "rotation");
RNA_def_property_ui_text(prop, "Rotation", "Rotate around image centr");
RNA_def_property_ui_text(
prop, "Offset Y", "Amount to move the input on the Y axis within its boundaries");
RNA_def_property_ui_range(prop, -4096, 4096, 1, -1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
RNA_def_struct_path_func(srna, "rna_SequenceTransform_path");
@ -2164,10 +2175,22 @@ static void rna_def_filter_video(StructRNA *srna)
RNA_def_property_ui_text(prop, "Strobe", "Only display every nth frame");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
prop = RNA_def_property(srna, "use_translation", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_USE_TRANSFORM);
RNA_def_property_ui_text(prop, "Use Translation", "Translate image before processing");
RNA_def_property_boolean_funcs(prop, NULL, "rna_Sequence_use_translation_set");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
prop = RNA_def_property(srna, "transform", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "strip->transform");
RNA_def_property_ui_text(prop, "Transform", "");
prop = RNA_def_property(srna, "use_crop", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_USE_CROP);
RNA_def_property_ui_text(prop, "Use Crop", "Crop image before processing");
RNA_def_property_boolean_funcs(prop, NULL, "rna_Sequence_use_crop_set");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update");
prop = RNA_def_property(srna, "crop", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "strip->crop");
RNA_def_property_ui_text(prop, "Crop", "");

View File

@ -44,7 +44,6 @@ struct TextVars;
struct bContext;
struct bSound;
struct SeqIndexBuildContext;
enum IMB_Proxy_Size;
/* Wipe effect */
enum {
@ -157,8 +156,6 @@ void BKE_sequencer_new_render_data(struct Main *bmain,
int preview_render_size,
int for_render,
SeqRenderData *r_context);
bool SEQ_can_use_proxy(struct Sequence *seq, enum IMB_Proxy_Size psize);
enum IMB_Proxy_Size SEQ_rendersize_to_proxysize(int render_size);
/* **********************************************************************
* sequencer.c

View File

@ -1631,7 +1631,7 @@ typedef struct SeqIndexBuildContext {
#define PROXY_MAXFILE (2 * FILE_MAXDIR + FILE_MAXFILE)
IMB_Proxy_Size SEQ_rendersize_to_proxysize(int render_size)
static IMB_Proxy_Size seq_rendersize_to_proxysize(int render_size)
{
switch (render_size) {
case SEQ_RENDER_SIZE_PROXY_25:
@ -1904,7 +1904,7 @@ static bool seq_proxy_get_fname(Editing *ed,
return true;
}
bool SEQ_can_use_proxy(Sequence *seq, IMB_Proxy_Size psize)
static bool seq_can_use_proxy(Sequence *seq, IMB_Proxy_Size psize)
{
if (seq->strip->proxy == NULL) {
return false;
@ -1922,7 +1922,7 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c
StripAnim *sanim;
/* only use proxies, if they are enabled (even if present!) */
if (!SEQ_can_use_proxy(seq, SEQ_rendersize_to_proxysize(psize))) {
if (!seq_can_use_proxy(seq, seq_rendersize_to_proxysize(psize))) {
return NULL;
}
@ -2653,28 +2653,6 @@ void BKE_sequencer_color_balance_apply(
* - Premultiply
*/
static bool sequencer_use_transform(const Sequence *seq)
{
const StripTransform *transform = seq->strip->transform;
if (transform->xofs != 0 || transform->yofs != 0 || transform->scale_x != 1 ||
transform->scale_y != 1 || transform->rotation != 0) {
return true;
}
return false;
}
static bool sequencer_use_crop(const Sequence *seq)
{
const StripCrop *crop = seq->strip->crop;
if (crop->left > 0 || crop->right > 0 || crop->top > 0 || crop->bottom > 0) {
return true;
}
return false;
}
bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context,
Sequence *seq,
float UNUSED(cfra))
@ -2685,8 +2663,8 @@ bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context,
return false;
}
if ((seq->flag & (SEQ_FILTERY | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_FLOAT)) ||
sequencer_use_crop(seq) || sequencer_use_transform(seq)) {
if (seq->flag &
(SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_FLOAT)) {
return true;
}
@ -2711,83 +2689,6 @@ bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context,
return false;
}
typedef struct ImageTransformThreadInitData {
ImBuf *ibuf_source;
ImBuf *ibuf_out;
StripTransform *transform;
float scale_to_fit;
float image_scale_factor;
bool for_render;
} ImageTransformThreadInitData;
typedef struct ImageTransformThreadData {
ImBuf *ibuf_source;
ImBuf *ibuf_out;
StripTransform *transform;
float scale_to_fit;
float image_scale_factor;
bool for_render;
int start_line;
int tot_line;
} ImageTransformThreadData;
static void sequencer_image_transform_init(void *handle_v,
int start_line,
int tot_line,
void *init_data_v)
{
ImageTransformThreadData *handle = (ImageTransformThreadData *)handle_v;
const ImageTransformThreadInitData *init_data = (ImageTransformThreadInitData *)init_data_v;
handle->ibuf_source = init_data->ibuf_source;
handle->ibuf_out = init_data->ibuf_out;
handle->transform = init_data->transform;
handle->scale_to_fit = init_data->scale_to_fit;
handle->image_scale_factor = init_data->image_scale_factor;
handle->for_render = init_data->for_render;
handle->start_line = start_line;
handle->tot_line = tot_line;
}
static void *sequencer_image_transform_do_thread(void *data_v)
{
const ImageTransformThreadData *data = (ImageTransformThreadData *)data_v;
const StripTransform *transform = data->transform;
const float scale_x = transform->scale_x * data->scale_to_fit;
const float scale_y = transform->scale_y * data->scale_to_fit;
const float scale_to_fit_offs_x = (data->ibuf_out->x - data->ibuf_source->x) / 2;
const float scale_to_fit_offs_y = (data->ibuf_out->y - data->ibuf_source->y) / 2;
const float translate_x = transform->xofs * data->image_scale_factor + scale_to_fit_offs_x;
const float translate_y = transform->yofs * data->image_scale_factor + scale_to_fit_offs_y;
const int width = data->ibuf_out->x;
const int height = data->ibuf_out->y;
const float pivot[2] = {width / 2 - scale_to_fit_offs_x, height / 2 - scale_to_fit_offs_y};
float transform_matrix[3][3];
loc_rot_size_to_mat3(transform_matrix,
(const float[]){translate_x, translate_y},
transform->rotation,
(const float[]){scale_x, scale_y});
invert_m3(transform_matrix);
transform_pivot_set_m3(transform_matrix, pivot);
for (int yi = data->start_line; yi < data->start_line + data->tot_line; yi++) {
for (int xi = 0; xi < width; xi++) {
float uv[2] = {xi, yi};
mul_v2_m3v2(uv, transform_matrix, uv);
if (data->for_render) {
bilinear_interpolation(data->ibuf_source, data->ibuf_out, uv[0], uv[1], xi, yi);
}
else {
nearest_interpolation(data->ibuf_source, data->ibuf_out, uv[0], uv[1], xi, yi);
}
}
}
return NULL;
}
static ImBuf *input_preprocess(const SeqRenderData *context,
Sequence *seq,
float cfra,
@ -2795,124 +2696,131 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
const bool is_proxy_image)
{
Scene *scene = context->scene;
ImBuf *preprocessed_ibuf = NULL;
float mul;
ibuf = IMB_makeSingleUser(ibuf);
/* Deinterlace. */
if ((seq->flag & SEQ_FILTERY) && !ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP)) {
/* Change original image pointer to avoid another duplication in SEQ_USE_TRANSFORM. */
preprocessed_ibuf = IMB_makeSingleUser(ibuf);
ibuf = preprocessed_ibuf;
IMB_filtery(preprocessed_ibuf);
IMB_filtery(ibuf);
}
/* Calculate scale factor, so image fits in preview area with original aspect ratio. */
const float scale_to_fit_factor = MIN2((float)context->rectx / (float)ibuf->x,
(float)context->recty / (float)ibuf->y);
if (seq->flag & (SEQ_USE_CROP | SEQ_USE_TRANSFORM)) {
StripCrop c = {0};
StripTransform t = {0};
/* Get scale factor if preview resolution doesn't match project resolution. */
float preview_scale_factor;
if (context->preview_render_size == SEQ_RENDER_SIZE_SCENE) {
preview_scale_factor = (float)scene->r.size / 100;
}
else {
preview_scale_factor = BKE_sequencer_rendersize_to_scale_factor(context->preview_render_size);
}
if (seq->flag & SEQ_USE_CROP && seq->strip->crop) {
c = *seq->strip->crop;
}
if (seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) {
t = *seq->strip->transform;
}
if (sequencer_use_crop(seq)) {
/* Change original image pointer to avoid another duplication in SEQ_USE_TRANSFORM. */
preprocessed_ibuf = IMB_makeSingleUser(ibuf);
ibuf = preprocessed_ibuf;
/* Calculate scale factor for current image if needed. */
double scale_factor, image_scale_factor = 1.0;
if (context->preview_render_size == SEQ_RENDER_SIZE_SCENE) {
scale_factor = image_scale_factor = (double)scene->r.size / 100;
}
else {
scale_factor = BKE_sequencer_rendersize_to_scale_factor(context->preview_render_size);
if (!is_proxy_image) {
image_scale_factor = scale_factor;
}
}
const int width = ibuf->x;
const int height = ibuf->y;
const StripCrop *c = seq->strip->crop;
if (image_scale_factor != 1.0) {
if (context->for_render) {
IMB_scaleImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor);
}
else {
IMB_scalefastImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor);
}
}
const int left = c->left / scale_to_fit_factor * preview_scale_factor;
const int right = c->right / scale_to_fit_factor * preview_scale_factor;
const int top = c->top / scale_to_fit_factor * preview_scale_factor;
const int bottom = c->bottom / scale_to_fit_factor * preview_scale_factor;
const float col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
t.xofs *= scale_factor;
t.yofs *= scale_factor;
c.left *= scale_factor;
c.right *= scale_factor;
c.top *= scale_factor;
c.bottom *= scale_factor;
/* Left. */
IMB_rectfill_area_replace(preprocessed_ibuf, col, 0, 0, left, height);
/* Bottom. */
IMB_rectfill_area_replace(preprocessed_ibuf, col, left, 0, width, bottom);
/* Right. */
IMB_rectfill_area_replace(preprocessed_ibuf, col, width - right, bottom, width, height);
/* Top. */
IMB_rectfill_area_replace(preprocessed_ibuf, col, left, height - top, width - right, height);
}
int sx, sy, dx, dy;
sx = ibuf->x - c.left - c.right;
sy = ibuf->y - c.top - c.bottom;
if (sequencer_use_transform(seq) || context->rectx != ibuf->x || context->recty != ibuf->y) {
const int x = context->rectx;
const int y = context->recty;
preprocessed_ibuf = IMB_allocImBuf(x, y, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
if (seq->flag & SEQ_USE_TRANSFORM) {
dx = context->rectx;
dy = context->recty;
}
else {
dx = sx;
dy = sy;
}
ImageTransformThreadInitData init_data = {NULL};
init_data.ibuf_source = ibuf;
init_data.ibuf_out = preprocessed_ibuf;
init_data.transform = seq->strip->transform;
init_data.scale_to_fit = scale_to_fit_factor;
init_data.image_scale_factor = preview_scale_factor;
init_data.for_render = context->for_render;
IMB_processor_apply_threaded(context->recty,
sizeof(ImageTransformThreadData),
&init_data,
sequencer_image_transform_init,
sequencer_image_transform_do_thread);
sequencer_imbuf_assign_spaces(scene, preprocessed_ibuf);
IMB_metadata_copy(preprocessed_ibuf, ibuf);
if (c.top + c.bottom >= ibuf->y || c.left + c.right >= ibuf->x || t.xofs >= dx ||
t.yofs >= dy) {
return NULL;
}
ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy);
sequencer_imbuf_assign_spaces(scene, i);
IMB_metadata_copy(i, ibuf);
IMB_freeImBuf(ibuf);
}
/* Duplicate ibuf if we still have original. */
if (preprocessed_ibuf == NULL) {
preprocessed_ibuf = IMB_makeSingleUser(ibuf);
ibuf = i;
}
if (seq->flag & SEQ_FLIPX) {
IMB_flipx(preprocessed_ibuf);
IMB_flipx(ibuf);
}
if (seq->flag & SEQ_FLIPY) {
IMB_flipy(preprocessed_ibuf);
IMB_flipy(ibuf);
}
if (seq->sat != 1.0f) {
IMB_saturation(preprocessed_ibuf, seq->sat);
IMB_saturation(ibuf, seq->sat);
}
if (seq->flag & SEQ_MAKE_FLOAT) {
if (!preprocessed_ibuf->rect_float) {
BKE_sequencer_imbuf_to_sequencer_space(scene, preprocessed_ibuf, true);
}
mul = seq->mul;
if (preprocessed_ibuf->rect) {
imb_freerectImBuf(preprocessed_ibuf);
}
}
float mul = seq->mul;
if (seq->blend_mode == SEQ_BLEND_REPLACE) {
mul *= seq->blend_opacity / 100.0f;
}
if (mul != 1.0f) {
multibuf(preprocessed_ibuf, mul);
}
if (seq->flag & SEQ_MAKE_FLOAT) {
if (!ibuf->rect_float) {
BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf, true);
}
if (seq->modifiers.first) {
ImBuf *ibuf_new = BKE_sequence_modifier_apply_stack(context, seq, preprocessed_ibuf, cfra);
if (ibuf_new != preprocessed_ibuf) {
IMB_metadata_copy(ibuf_new, preprocessed_ibuf);
IMB_freeImBuf(preprocessed_ibuf);
preprocessed_ibuf = ibuf_new;
if (ibuf->rect) {
imb_freerectImBuf(ibuf);
}
}
return preprocessed_ibuf;
if (mul != 1.0f) {
multibuf(ibuf, mul);
}
if (ibuf->x != context->rectx || ibuf->y != context->recty) {
if (context->for_render) {
IMB_scaleImBuf(ibuf, (short)context->rectx, (short)context->recty);
}
else {
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_metadata_copy(ibuf_new, ibuf);
IMB_freeImBuf(ibuf);
ibuf = ibuf_new;
}
}
return ibuf;
}
/*********************** strip rendering functions *************************/
@ -3282,11 +3190,11 @@ static ImBuf *seq_render_movie_strip_view(const SeqRenderData *context,
bool *r_is_proxy_image)
{
ImBuf *ibuf = NULL;
IMB_Proxy_Size psize = SEQ_rendersize_to_proxysize(context->preview_render_size);
IMB_Proxy_Size psize = seq_rendersize_to_proxysize(context->preview_render_size);
IMB_anim_set_preseek(sanim->anim, seq->anim_preseek);
if (SEQ_can_use_proxy(seq, psize)) {
if (seq_can_use_proxy(seq, psize)) {
/* Try to get a proxy image.
* Movie proxies are handled by ImBuf module with exception of `custom file` setting. */
if (context->scene->ed->proxy_storage != SEQ_EDIT_PROXY_DIR_STORAGE &&
@ -3418,7 +3326,7 @@ static ImBuf *seq_render_movieclip_strip(const SeqRenderData *context,
{
ImBuf *ibuf = NULL;
MovieClipUser user;
IMB_Proxy_Size psize = SEQ_rendersize_to_proxysize(context->preview_render_size);
IMB_Proxy_Size psize = seq_rendersize_to_proxysize(context->preview_render_size);
if (!seq->clip) {
return NULL;
@ -5439,8 +5347,6 @@ static Strip *seq_strip_alloc(int type)
if (ELEM(type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD) == 0) {
strip->transform = MEM_callocN(sizeof(struct StripTransform), "StripTransform");
strip->transform->scale_x = 1;
strip->transform->scale_y = 1;
strip->crop = MEM_callocN(sizeof(struct StripCrop), "StripCrop");
}