Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Antalik <richardantalik@gmail.com>2020-11-03 00:15:52 +0300
committerRichard Antalik <richardantalik@gmail.com>2020-11-03 00:15:52 +0300
commite1665c3d31906aed195bfdc10a4dd7582f31b1f5 (patch)
tree98da1c84116144388be1beb81e762ccaee3b8aab /source/blender/blenloader/intern/versioning_290.c
parent6b3eca661dc2d0791ecf07b94ef51f13c3aa6d25 (diff)
VSE: Media transform redesign
This patch changes behavior of strip transform and crop feature. Purpose of this change is to allow display arbitrary portion of input image, simplify user interface and workflow. Offset and Crop values in old files are converted in versioning. Offset animation is also converted. Crop animation and animation of crop or offset enable properties is not taken into account Changes in behavior and interface: - If image is added to timeline it is scaled to fit inside preview area while maintaining aspect ratio. Image is centered. This is considered as a baseline for further transformation. - Scale and rotation was added, so it is possible to transform image at it's original resolution. - Crop will not affect image transformation (does not move image). - Values of Crop and Transform Position are in pixels, these values are corrected if preview is fraction of project resolution. - Transform and Mirror panel has been removed and new Transform panel and Crop panel is moved to Adjust panel. Mirror is now part of new Transform panel. Technical changes: - Preprocessing stage must work on duplicated image, because original is cached. Previously Crop and Offset could run at once and required only one duplication of image. This is not the case with new algorithms, so duplication on demand is implemented. Transformation can read original image and will output new image that is safe to modify. It should be possible to add crop step to transform algorithm, so that Crop won't require previous duplication though. - Use Crop and Use Translation checkboxes were removed. Individual values are compared to default values to check if image needs to be processed. In case of transform this will be done also if resolution of source. Reviewed By: sergey Differential Revision: https://developer.blender.org/D8393
Diffstat (limited to 'source/blender/blenloader/intern/versioning_290.c')
-rw-r--r--source/blender/blenloader/intern/versioning_290.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index 37987b2c31d..d3d6eeeb3dd 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -44,12 +44,14 @@
#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"
@@ -59,12 +61,154 @@
#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)) {
@@ -292,6 +436,31 @@ 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.
*