Merge branch 'master' into sculpt-dev

This commit is contained in:
Pablo Dobarro 2020-12-16 21:02:04 +01:00
commit 6b42781319
19 changed files with 549 additions and 56 deletions

View File

@ -142,7 +142,8 @@ const GHOST_TUns8 *GHOST_SystemPathsUnix::getUserSpecialDir(GHOST_TUserSpecialDi
}
static string path = "";
string command = string("xdg-user-dir ") + type_str;
/* Pipe stderr to /dev/null to avoid error prints. We will fail gracefully still. */
string command = string("xdg-user-dir ") + type_str + " 2> /dev/null";
FILE *fstream = popen(command.c_str(), "r");
if (fstream == NULL) {
@ -163,7 +164,7 @@ const GHOST_TUns8 *GHOST_SystemPathsUnix::getUserSpecialDir(GHOST_TUserSpecialDi
}
path = path_stream.str();
return (const GHOST_TUns8 *)path.c_str();
return path[0] ? (const GHOST_TUns8 *)path.c_str() : NULL;
}
const GHOST_TUns8 *GHOST_SystemPathsUnix::getBinaryDir() const

View File

@ -129,6 +129,8 @@ class SEQUENCER_HT_header(Header):
layout = self.layout
st = context.space_data
scene = context.scene
sequencer_tool_settings = context.tool_settings.sequencer_tool_settings
show_region_tool_header = st.show_region_tool_header
@ -139,9 +141,15 @@ class SEQUENCER_HT_header(Header):
SEQUENCER_MT_editor_menus.draw_collapsible(context, layout)
layout.separator_spacer()
if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
layout.separator_spacer()
row = layout.row(align=True)
row.prop(sequencer_tool_settings, "fit_method", text="")
layout.separator_spacer()
if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
if st.view_type == 'PREVIEW':
layout.separator_spacer()
layout.prop(st, "display_mode", text="", icon_only=True)
layout.prop(st, "preview_channels", text="", icon_only=True)
@ -700,6 +708,22 @@ class SEQUENCER_MT_add_effect(Menu):
col.enabled = selected_sequences_len(context) != 0
class SEQUENCER_MT_strip_image_transform(Menu):
bl_label = "Image Transform"
def draw(self, _context):
layout = self.layout
layout.operator("sequencer.strip_transform_fit", text="Scale To Fit").fit_method = 'FIT'
layout.operator("sequencer.strip_transform_fit", text="Scale to Fill").fit_method = 'FILL'
layout.operator("sequencer.strip_transform_fit", text="Stretch To Fill").fit_method = 'STRETCH'
layout.separator()
layout.operator("sequencer.strip_transform_clear", text="Clear Position").property = 'POSITION'
layout.operator("sequencer.strip_transform_clear", text="Clear Scale").property = 'SCALE'
layout.operator("sequencer.strip_transform_clear", text="Clear Rotation").property = 'ROTATION'
layout.operator("sequencer.strip_transform_clear", text="Clear All").property = 'ALL'
class SEQUENCER_MT_strip_transform(Menu):
bl_label = "Transform"
@ -794,6 +818,7 @@ class SEQUENCER_MT_strip(Menu):
layout.separator()
layout.menu("SEQUENCER_MT_strip_transform")
layout.menu("SEQUENCER_MT_strip_image_transform")
layout.separator()
layout.operator("sequencer.split", text="Split").type = 'SOFT'
@ -2285,6 +2310,7 @@ classes = (
SEQUENCER_MT_strip_effect,
SEQUENCER_MT_strip_movie,
SEQUENCER_MT_strip,
SEQUENCER_MT_strip_image_transform,
SEQUENCER_MT_strip_transform,
SEQUENCER_MT_strip_input,
SEQUENCER_MT_strip_lock_mute,

View File

@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 7
#define BLENDER_FILE_SUBVERSION 8
/* 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

@ -222,6 +222,7 @@ static void scene_init_data(ID *id)
/* Curve Profile */
scene->toolsettings->custom_bevel_profile_preset = BKE_curveprofile_add(PROF_PRESET_LINE);
scene->toolsettings->sequencer_tool_settings = SEQ_tool_settings_init();
for (size_t i = 0; i < ARRAY_SIZE(scene->orientation_slots); i++) {
scene->orientation_slots[i].index_custom = -1;
@ -862,6 +863,9 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres
if (tos->custom_bevel_profile_preset) {
BKE_curveprofile_blend_write(writer, tos->custom_bevel_profile_preset);
}
if (tos->sequencer_tool_settings) {
BLO_write_struct(writer, SequencerToolSettings, tos->sequencer_tool_settings);
}
BKE_paint_blend_write(writer, &tos->imapaint.paint);
@ -1121,6 +1125,8 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
if (sce->toolsettings->custom_bevel_profile_preset) {
BKE_curveprofile_blend_read(reader, sce->toolsettings->custom_bevel_profile_preset);
}
BLO_read_data_address(reader, &sce->toolsettings->sequencer_tool_settings);
}
if (sce->ed) {
@ -1792,6 +1798,8 @@ ToolSettings *BKE_toolsettings_copy(ToolSettings *toolsettings, const int flag)
ts->gp_sculpt.cur_primitive = BKE_curvemapping_copy(ts->gp_sculpt.cur_primitive);
ts->custom_bevel_profile_preset = BKE_curveprofile_copy(ts->custom_bevel_profile_preset);
ts->sequencer_tool_settings = SEQ_tool_settings_copy(ts->sequencer_tool_settings);
return ts;
}
@ -1850,6 +1858,10 @@ void BKE_toolsettings_free(ToolSettings *toolsettings)
BKE_curveprofile_free(toolsettings->custom_bevel_profile_preset);
}
if (toolsettings->sequencer_tool_settings) {
SEQ_tool_settings_free(toolsettings->sequencer_tool_settings);
}
MEM_freeN(toolsettings);
}

View File

@ -74,6 +74,29 @@
/* Make preferences read-only, use versioning_userdef.c. */
#define U (*((const UserDef *)&U))
static eSpaceSeq_Proxy_RenderSize get_sequencer_render_size(Main *bmain)
{
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;
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
render_size = sseq->render_size;
break;
}
}
}
}
}
}
return render_size;
}
/* 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,
@ -212,6 +235,90 @@ static void seq_convert_transform_crop_lb(const Scene *scene,
}
}
static void seq_convert_transform_animation_2(const Scene *scene,
const char *path,
const float scale_to_fit_factor)
{
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] *= scale_to_fit_factor;
}
}
}
static void seq_convert_transform_crop_2(const Scene *scene,
Sequence *seq,
const eSpaceSeq_Proxy_RenderSize render_size)
{
const StripElem *s_elem = SEQ_render_give_stripelem(seq, seq->start);
if (s_elem == NULL) {
return;
}
StripCrop *c = seq->strip->crop;
StripTransform *t = seq->strip->transform;
int image_size_x = s_elem->orig_width;
int image_size_y = s_elem->orig_height;
if (SEQ_can_use_proxy(seq, SEQ_rendersize_to_proxysize(render_size))) {
image_size_x /= SEQ_rendersize_to_scale_factor(render_size);
image_size_y /= SEQ_rendersize_to_scale_factor(render_size);
}
/* Calculate scale factor, so image fits in preview area with original aspect ratio. */
const float scale_to_fit_factor = MIN2((float)scene->r.xsch / (float)image_size_x,
(float)scene->r.ysch / (float)image_size_y);
t->scale_x *= scale_to_fit_factor;
t->scale_y *= scale_to_fit_factor;
c->top /= scale_to_fit_factor;
c->bottom /= scale_to_fit_factor;
c->left /= scale_to_fit_factor;
c->right /= scale_to_fit_factor;
char name_esc[(sizeof(seq->name) - 2) * 2], *path;
BLI_str_escape(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_2(scene, path, scale_to_fit_factor);
MEM_freeN(path);
path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].transform.offset_y", name_esc);
seq_convert_transform_animation_2(scene, path, scale_to_fit_factor);
MEM_freeN(path);
path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].crop.min_x", name_esc);
seq_convert_transform_animation_2(scene, path, 1 / scale_to_fit_factor);
MEM_freeN(path);
path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].crop.max_x", name_esc);
seq_convert_transform_animation_2(scene, path, 1 / scale_to_fit_factor);
MEM_freeN(path);
path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].crop.min_y", name_esc);
seq_convert_transform_animation_2(scene, path, 1 / scale_to_fit_factor);
MEM_freeN(path);
path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].crop.max_x", name_esc);
seq_convert_transform_animation_2(scene, path, 1 / scale_to_fit_factor);
MEM_freeN(path);
}
static void seq_convert_transform_crop_lb_2(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_2(scene, seq, render_size);
}
if (seq->type == SEQ_TYPE_META) {
seq_convert_transform_crop_lb_2(scene, &seq->seqbase, render_size);
}
}
}
void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
{
if (!MAIN_VERSION_ATLEAST(bmain, 290, 1)) {
@ -441,21 +548,7 @@ 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;
}
}
}
}
}
eSpaceSeq_Proxy_RenderSize render_size = get_sequencer_render_size(bmain);
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
if (scene->ed != NULL) {
@ -464,6 +557,30 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 292, 8)) {
/* Systematically rebuild posebones to ensure consistent ordering matching the one of bones in
* Armature obdata. */
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
if (ob->type == OB_ARMATURE) {
BKE_pose_rebuild(bmain, ob, ob->data, true);
}
}
/* Wet Paint Radius Factor */
for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
if (br->ob_mode & OB_MODE_SCULPT && br->wet_paint_radius_factor == 0.0f) {
br->wet_paint_radius_factor = 1.0f;
}
}
eSpaceSeq_Proxy_RenderSize render_size = get_sequencer_render_size(bmain);
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
if (scene->ed != NULL) {
seq_convert_transform_crop_lb_2(scene, &scene->ed->seqbase, render_size);
}
}
}
/**
* Versioning code until next subversion bump goes here.
*
@ -476,21 +593,6 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
*/
{
/* Keep this block, even when empty. */
/* Systematically rebuild posebones to ensure consistent ordering matching the one of bones in
* Armature obdata. */
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
if (ob->type == OB_ARMATURE) {
BKE_pose_rebuild(bmain, ob, ob->data, true);
}
}
}
/* Wet Paint Radius Factor */
for (Brush *br = bmain->brushes.first; br; br = br->id.next) {
if (br->ob_mode & OB_MODE_SCULPT && br->wet_paint_radius_factor == 0.0f) {
br->wet_paint_radius_factor = 1.0f;
}
}
}
@ -1305,6 +1407,22 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 292, 8)) {
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (STREQ(node->idname, "GeometryNodeRandomAttribute")) {
STRNCPY(node->idname, "GeometryNodeAttributeRandomize");
}
}
}
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
if (scene->ed != NULL) {
scene->toolsettings->sequencer_tool_settings = SEQ_tool_settings_init();
}
}
}
/**
* Versioning code until next subversion bump goes here.
*
@ -1316,13 +1434,5 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
*/
{
/* Keep this block, even when empty. */
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (STREQ(node->idname, "GeometryNodeRandomAttribute")) {
STRNCPY(node->idname, "GeometryNodeAttributeRandomize");
}
}
}
}
}

View File

@ -741,6 +741,9 @@ const EnumPropertyItem *ED_object_vgroup_selection_itemf_helper(const bContext *
RNA_enum_items_add_value(
&item, &totitem, WT_vertex_group_select_item, WT_VGROUP_BONE_SELECT);
}
}
if (BKE_modifiers_is_deformed_by_armature(ob)) {
if (selection_mask & (1 << WT_VGROUP_BONE_DEFORM)) {
RNA_enum_items_add_value(
&item, &totitem, WT_vertex_group_select_item, WT_VGROUP_BONE_DEFORM);

View File

@ -81,9 +81,18 @@ typedef struct SequencerAddData {
#define SEQPROP_ENDFRAME (1 << 1)
#define SEQPROP_NOPATHS (1 << 2)
#define SEQPROP_NOCHAN (1 << 3)
#define SEQPROP_FIT_METHOD (1 << 4)
#define SELECT 1
static const EnumPropertyItem scale_fit_methods[] = {
{SEQ_SCALE_TO_FIT, "FIT", 0, "Scale to Fit", "Scale image to fit within the canvas"},
{SEQ_SCALE_TO_FILL, "FILL", 0, "Scale to Fill", "Scale image to completely fill the canvas"},
{SEQ_STRETCH_TO_FILL, "STRETCH", 0, "Stretch to Fill", "Stretch image to fill the canvas"},
{SEQ_USE_ORIGINAL_SIZE, "ORIGINAL", 0, "Use Original Size", "Keep image at its original size"},
{0, NULL, 0, NULL, NULL},
};
static void sequencer_generic_props__internal(wmOperatorType *ot, int flag)
{
PropertyRNA *prop;
@ -123,6 +132,15 @@ static void sequencer_generic_props__internal(wmOperatorType *ot, int flag)
prop = RNA_def_boolean(
ot->srna, "overlap", 0, "Allow Overlap", "Don't correct overlap on new sequence strips");
RNA_def_property_flag(prop, PROP_HIDDEN);
if (flag & SEQPROP_FIT_METHOD) {
ot->prop = RNA_def_enum(ot->srna,
"fit_method",
scale_fit_methods,
SEQ_SCALE_TO_FIT,
"Fit Method",
"Scale fit method");
}
}
static void sequencer_generic_invoke_path__internal(bContext *C,
@ -206,6 +224,8 @@ static void seq_load_operator_info(SeqLoadInfo *seq_load, bContext *C, wmOperato
seq_load->end_frame = seq_load->start_frame;
seq_load->channel = RNA_int_get(op->ptr, "channel");
seq_load->len = 1;
seq_load->fit_method = RNA_enum_get(op->ptr, "fit_method");
SEQ_tool_settings_fit_method_set(CTX_data_scene(C), seq_load->fit_method);
if ((prop = RNA_struct_find_property(op->ptr, "filepath"))) {
/* Full path, file is set by the caller. */
@ -659,6 +679,7 @@ static int sequencer_add_movie_strip_invoke(bContext *C,
if (ed && ed->seqbasep && ed->seqbasep->first) {
RNA_boolean_set(op->ptr, "use_framerate", false);
}
RNA_enum_set(op->ptr, "fit_method", SEQ_tool_settings_fit_method_get(scene));
/* This is for drag and drop. */
if ((RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) ||
@ -725,7 +746,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY,
FILE_DEFAULTDISPLAY,
FILE_SORT_DEFAULT);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_FIT_METHOD);
RNA_def_boolean(ot->srna, "sound", true, "Sound", "Load sound with the movie");
RNA_def_boolean(ot->srna,
"use_framerate",
@ -928,6 +949,9 @@ static int sequencer_add_image_strip_invoke(bContext *C,
PropertyRNA *prop;
Scene *scene = CTX_data_scene(C);
const SequencerToolSettings *tool_settings = scene->toolsettings->sequencer_tool_settings;
RNA_enum_set(op->ptr, "fit_method", tool_settings->fit_method);
/* Name set already by drag and drop. */
if (RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) {
sequencer_generic_invoke_xy__internal(
@ -972,7 +996,8 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot)
WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY,
FILE_DEFAULTDISPLAY,
FILE_SORT_DEFAULT);
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME);
sequencer_generic_props__internal(ot,
SEQPROP_STARTFRAME | SEQPROP_ENDFRAME | SEQPROP_FIT_METHOD);
RNA_def_boolean(ot->srna,
"use_placeholders",

View File

@ -3414,3 +3414,148 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Clear Strip Transform Operator
* \{ */
enum {
STRIP_TRANSFORM_POSITION,
STRIP_TRANSFORM_SCALE,
STRIP_TRANSFORM_ROTATION,
STRIP_TRANSFORM_ALL,
};
static const EnumPropertyItem transform_reset_properties[] = {
{STRIP_TRANSFORM_POSITION, "POSITION", 0, "Position", "Reset strip transform location"},
{STRIP_TRANSFORM_SCALE, "SCALE", 0, "Scale", "Reset strip transform scale"},
{STRIP_TRANSFORM_ROTATION, "ROTATION", 0, "Rotation", "Reset strip transform rotation"},
{STRIP_TRANSFORM_ALL, "ALL", 0, "All", "Reset strip transform location, scale and rotation"},
{0, NULL, 0, NULL, NULL},
};
static int sequencer_strip_transform_clear_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
const Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
const int property = RNA_enum_get(op->ptr, "property");
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if (seq->flag & SELECT && seq->type != SEQ_TYPE_SOUND_RAM) {
StripTransform *transform = seq->strip->transform;
switch (property) {
case STRIP_TRANSFORM_POSITION:
transform->xofs = 0;
transform->yofs = 0;
break;
case STRIP_TRANSFORM_SCALE:
transform->scale_x = 1.0f;
transform->scale_y = 1.0f;
break;
case STRIP_TRANSFORM_ROTATION:
transform->rotation = 0.0f;
break;
case STRIP_TRANSFORM_ALL:
transform->xofs = 0;
transform->yofs = 0;
transform->scale_x = 1.0f;
transform->scale_y = 1.0f;
transform->rotation = 0.0f;
break;
}
BKE_sequence_invalidate_cache_preprocessed(scene, seq);
}
}
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
}
void SEQUENCER_OT_strip_transform_clear(struct wmOperatorType *ot)
{
/* Identifiers. */
ot->name = "Clear Strip Transform";
ot->idname = "SEQUENCER_OT_strip_transform_clear";
ot->description = "Reset image transformation to default value";
/* Api callbacks. */
ot->exec = sequencer_strip_transform_clear_exec;
ot->poll = sequencer_edit_poll;
/* Flags. */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ot->prop = RNA_def_enum(ot->srna,
"property",
transform_reset_properties,
STRIP_TRANSFORM_ALL,
"Property",
"Strip transform property to be reset");
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Transform Set Fit Operator
* \{ */
static const EnumPropertyItem scale_fit_methods[] = {
{SEQ_SCALE_TO_FIT, "FIT", 0, "Scale to Fit", "Scale image so fits in preview"},
{SEQ_SCALE_TO_FILL, "FILL", 0, "Scale to Fill", "Scale image so it fills preview completely"},
{SEQ_STRETCH_TO_FILL, "STRETCH", 0, "Stretch to Fill", "Stretch image so it fills preview"},
{0, NULL, 0, NULL, NULL},
};
static int sequencer_strip_transform_fit_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
const Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
const eSeqImageFitMethod fit_method = RNA_enum_get(op->ptr, "fit_method");
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
if (seq->flag & SELECT && seq->type != SEQ_TYPE_SOUND_RAM) {
const int timeline_frame = CFRA;
StripElem *strip_elem = SEQ_render_give_stripelem(seq, timeline_frame);
if (strip_elem == NULL) {
continue;
}
SEQ_set_scale_to_fit(seq,
strip_elem->orig_width,
strip_elem->orig_height,
scene->r.xsch,
scene->r.ysch,
fit_method);
BKE_sequence_invalidate_cache_preprocessed(scene, seq);
}
}
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
}
void SEQUENCER_OT_strip_transform_fit(struct wmOperatorType *ot)
{
/* Identifiers. */
ot->name = "Strip Transform Set Fit";
ot->idname = "SEQUENCER_OT_strip_transform_fit";
/* Api callbacks. */
ot->exec = sequencer_strip_transform_fit_exec;
ot->poll = sequencer_edit_poll;
/* Flags. */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ot->prop = RNA_def_enum(ot->srna,
"fit_method",
scale_fit_methods,
SEQ_SCALE_TO_FIT,
"Fit Method",
"Scale fit fit_method");
}
/** \} */

View File

@ -144,6 +144,8 @@ void SEQUENCER_OT_enable_proxies(struct wmOperatorType *ot);
void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot);
void SEQUENCER_OT_set_range_to_strips(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_transform_clear(struct wmOperatorType *ot);
void SEQUENCER_OT_strip_transform_fit(struct wmOperatorType *ot);
/* sequencer_select.c */
void SEQUENCER_OT_select_all(struct wmOperatorType *ot);

View File

@ -81,6 +81,8 @@ void sequencer_operatortypes(void)
WM_operatortype_append(SEQUENCER_OT_change_path);
WM_operatortype_append(SEQUENCER_OT_set_range_to_strips);
WM_operatortype_append(SEQUENCER_OT_strip_transform_clear);
WM_operatortype_append(SEQUENCER_OT_strip_transform_fit);
/* sequencer_select.c */
WM_operatortype_append(SEQUENCER_OT_select_all);

View File

@ -382,6 +382,8 @@ bool IMB_anim_can_produce_frames(const struct anim *anim);
int ismovie(const char *filepath);
void IMB_anim_set_preseek(struct anim *anim, int preseek);
int IMB_anim_get_preseek(struct anim *anim);
int IMB_anim_get_image_width(struct anim *anim);
int IMB_anim_get_image_height(struct anim *anim);
/**
*

View File

@ -1506,3 +1506,13 @@ int IMB_anim_get_preseek(struct anim *anim)
{
return anim->preseek;
}
int IMB_anim_get_image_width(struct anim *anim)
{
return anim->x;
}
int IMB_anim_get_image_height(struct anim *anim)
{
return anim->y;
}

View File

@ -1343,6 +1343,18 @@ typedef struct MeshStatVis {
float sharp_min, sharp_max;
} MeshStatVis;
typedef struct SequencerToolSettings {
/* eSeqImageFitMethod */
int fit_method;
} SequencerToolSettings;
typedef enum eSeqImageFitMethod {
SEQ_SCALE_TO_FIT,
SEQ_SCALE_TO_FILL,
SEQ_STRETCH_TO_FILL,
SEQ_USE_ORIGINAL_SIZE,
} eSeqImageFitMethod;
/* *************************************************************** */
/* Tool Settings */
@ -1517,6 +1529,9 @@ typedef struct ToolSettings {
* Temporary until there is a proper preset system that stores the profiles or maybe stores
* entire bevel configurations. */
struct CurveProfile *custom_bevel_profile_preset;
struct SequencerToolSettings *sequencer_tool_settings;
} ToolSettings;
/* *************************************************************** */

View File

@ -2200,6 +2200,11 @@ static char *rna_CurvePaintSettings_path(PointerRNA *UNUSED(ptr))
return BLI_strdup("tool_settings.curve_paint_settings");
}
static char *rna_SequencerToolSettings_path(PointerRNA *UNUSED(ptr))
{
return BLI_strdup("tool_settings.sequencer_tool_settings");
}
/* generic function to recalc geometry */
static void rna_EditMesh_update(bContext *C, PointerRNA *UNUSED(ptr))
{
@ -3584,6 +3589,38 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "custom_bevel_profile_preset");
RNA_def_property_struct_type(prop, "CurveProfile");
RNA_def_property_ui_text(prop, "Curve Profile Widget", "Used for defining a profile's path");
/* Sequencer tool settings */
prop = RNA_def_property(srna, "sequencer_tool_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "SequencerToolSettings");
RNA_def_property_ui_text(prop, "Sequencer Tool Settings", NULL);
}
static void rna_def_sequencer_tool_settings(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
static const EnumPropertyItem scale_fit_methods[] = {
{SEQ_SCALE_TO_FIT, "FIT", 0, "Scale to Fit", "Scale image to fit within the canvas"},
{SEQ_SCALE_TO_FILL, "FILL", 0, "Scale to Fill", "Scale image to completely fill the canvas"},
{SEQ_STRETCH_TO_FILL, "STRETCH", 0, "Stretch to Fill", "Stretch image to fill the canvas"},
{SEQ_USE_ORIGINAL_SIZE,
"ORIGINAL",
0,
"Use Original Size",
"Keep image at its original size"},
{0, NULL, 0, NULL, NULL},
};
srna = RNA_def_struct(brna, "SequencerToolSettings", NULL);
RNA_def_struct_path_func(srna, "rna_SequencerToolSettings_path");
RNA_def_struct_ui_text(srna, "Sequencer Tool Settings", "");
prop = RNA_def_property(srna, "fit_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, scale_fit_methods);
RNA_def_property_ui_text(prop, "Fit Method", "Scale fit method");
}
static void rna_def_unified_paint_settings(BlenderRNA *brna)
@ -7968,6 +8005,7 @@ void RNA_def_scene(BlenderRNA *brna)
rna_def_gpencil_interpolate(brna);
rna_def_unified_paint_settings(brna);
rna_def_curve_paint_settings(brna);
rna_def_sequencer_tool_settings(brna);
rna_def_statvis(brna);
rna_def_unit_settings(brna);
rna_def_scene_image_format_data(brna);

View File

@ -23,6 +23,8 @@
* \ingroup sequencer
*/
#include "DNA_scene_types.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -47,6 +49,10 @@ struct StripElem;
struct TextVars;
struct bContext;
struct bSound;
struct BlendWriter;
struct BlendDataReader;
struct BlendLibReader;
struct SequencerToolSettings;
/* Wipe effect */
enum {
@ -179,6 +185,12 @@ void SEQ_render_pixel_from_sequencer_space_v4(struct Scene *scene, float pixel[4
* Sequencer scene functions
* ********************************************************************** */
struct SequencerToolSettings *SEQ_tool_settings_init(void);
void SEQ_tool_settings_free(struct SequencerToolSettings *tool_settings);
eSeqImageFitMethod SEQ_tool_settings_fit_method_get(struct Scene *scene);
void SEQ_tool_settings_fit_method_set(struct Scene *scene, eSeqImageFitMethod fit_method);
struct SequencerToolSettings *SEQ_tool_settings_copy(struct SequencerToolSettings *tool_settings);
struct Editing *BKE_sequencer_editing_get(struct Scene *scene, bool alloc);
struct Editing *BKE_sequencer_editing_ensure(struct Scene *scene);
void BKE_sequencer_editing_free(struct Scene *scene, const bool do_id_user);
@ -360,6 +372,20 @@ void BKE_sequence_invalidate_cache_in_range(struct Scene *scene,
int invalidate_types);
void BKE_sequencer_all_free_anim_ibufs(struct Scene *scene, int timeline_frame);
/* **********************************************************************
* util.c
*
* Add strips
* **********************************************************************
*/
void SEQ_set_scale_to_fit(const struct Sequence *seq,
const int image_width,
const int image_height,
const int preview_width,
const int preview_height,
const eSeqImageFitMethod fit_method);
/* **********************************************************************
* sequencer.c
*
@ -376,6 +402,7 @@ typedef struct SeqLoadInfo {
int type;
int len; /* only for image strips */
char path[1024]; /* 1024 = FILE_MAX */
eSeqImageFitMethod fit_method;
/* multiview */
char views_format;

View File

@ -528,7 +528,6 @@ static void sequencer_image_transform_init(void *handle_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;
@ -540,8 +539,8 @@ 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_x = transform->scale_x * data->image_scale_factor;
const float scale_y = transform->scale_y * data->image_scale_factor;
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;
@ -626,10 +625,6 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
IMB_filtery(preprocessed_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);
/* Get scale factor if preview resolution doesn't match project resolution. */
float preview_scale_factor;
if (context->preview_render_size == SEQ_RENDER_SIZE_SCENE) {
@ -648,10 +643,10 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
const int height = ibuf->y;
const StripCrop *c = seq->strip->crop;
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 int left = c->left;
const int right = c->right;
const int top = c->top;
const int bottom = c->bottom;
const float col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* Left. */
@ -673,7 +668,6 @@ static ImBuf *input_preprocess(const SeqRenderData *context,
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,

View File

@ -301,6 +301,32 @@ static void seq_new_fix_links_recursive(Sequence *seq)
}
}
}
SequencerToolSettings *SEQ_tool_settings_init(void)
{
SequencerToolSettings *tool_settings = MEM_callocN(sizeof(SequencerToolSettings),
"Sequencer tool settings");
tool_settings->fit_method = SEQ_SCALE_TO_FIT;
return tool_settings;
}
void SEQ_tool_settings_free(SequencerToolSettings *tool_settings)
{
MEM_freeN(tool_settings);
}
eSeqImageFitMethod SEQ_tool_settings_fit_method_get(Scene *scene)
{
const SequencerToolSettings *tool_settings = scene->toolsettings->sequencer_tool_settings;
return tool_settings->fit_method;
}
void SEQ_tool_settings_fit_method_set(Scene *scene, eSeqImageFitMethod fit_method)
{
SequencerToolSettings *tool_settings = scene->toolsettings->sequencer_tool_settings;
tool_settings->fit_method = fit_method;
}
/** \} */
/* -------------------------------------------------------------------- */
@ -609,4 +635,11 @@ static void seq_free_animdata(Scene *scene, Sequence *seq)
}
#undef SEQ_RNAPATH_MAXSTR
SequencerToolSettings *SEQ_tool_settings_copy(SequencerToolSettings *tool_settings)
{
SequencerToolSettings *tool_settings_copy = MEM_dupallocN(tool_settings);
return tool_settings_copy;
}
/** \} */

View File

@ -118,6 +118,15 @@ Sequence *BKE_sequencer_add_image_strip(bContext *C, ListBase *seqbasep, SeqLoad
seq->flag |= seq_load->flag & SEQ_USE_VIEWS;
seq_load_apply(CTX_data_main(C), scene, seq, seq_load);
char file_path[FILE_MAX];
BLI_join_dirfile(file_path, sizeof(file_path), seq_load->path, seq_load->name);
ImBuf *ibuf = IMB_loadiffname(file_path, IB_rect, seq->strip->colorspace_settings.name);
if (ibuf != NULL) {
SEQ_set_scale_to_fit(seq, ibuf->x, ibuf->y, scene->r.xsch, scene->r.ysch, seq_load->fit_method);
IMB_freeImBuf(ibuf);
}
BKE_sequence_invalidate_cache_composite(scene, seq);
return seq;
@ -275,6 +284,11 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
IMB_anim_load_metadata(anim_arr[0]);
seq->anim_preseek = IMB_anim_get_preseek(anim_arr[0]);
const float width = IMB_anim_get_image_width(anim_arr[0]);
const float height = IMB_anim_get_image_height(anim_arr[0]);
SEQ_set_scale_to_fit(seq, width, height, scene->r.xsch, scene->r.ysch, seq_load->fit_method);
BLI_strncpy(seq->name + 2, "Movie", SEQ_NAME_MAXSTR - 2);
BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);

View File

@ -36,6 +36,7 @@
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_image.h"
#include "BKE_main.h"
@ -547,3 +548,36 @@ bool sequencer_seq_generates_image(Sequence *seq)
}
return false;
}
void SEQ_set_scale_to_fit(const Sequence *seq,
const int image_width,
const int image_height,
const int preview_width,
const int preview_height,
const eSeqImageFitMethod fit_method)
{
StripTransform *transform = seq->strip->transform;
switch (fit_method) {
case SEQ_SCALE_TO_FIT:
transform->scale_x = transform->scale_y = MIN2((float)preview_width / (float)image_width,
(float)preview_height / (float)image_height);
break;
case SEQ_SCALE_TO_FILL:
transform->scale_x = transform->scale_y = MAX2((float)preview_width / (float)image_width,
(float)preview_height / (float)image_height);
break;
case SEQ_STRETCH_TO_FILL:
transform->scale_x = (float)preview_width / (float)image_width;
transform->scale_y = (float)preview_height / (float)image_height;
break;
case SEQ_USE_ORIGINAL_SIZE:
transform->scale_x = 1.0f;
transform->scale_y = 1.0f;
break;
}
return;
}