Merge branch 'blender-v4.5-release'

This commit is contained in:
Christoph Lendenfeld
2025-06-12 14:33:58 +02:00
6 changed files with 40 additions and 16 deletions

View File

@@ -46,8 +46,10 @@
#include "BKE_object.hh"
#include "BKE_particle.h"
#include "BKE_report.hh"
#include "BKE_scene.hh"
#include "ANIM_bone_collections.hh"
#include "ANIM_keyframing.hh"
#include "DEG_depsgraph.hh"
#include "DEG_depsgraph_build.hh"
@@ -299,6 +301,8 @@ static void outliner_object_set_flag_recursive_fn(bContext *C,
ptr = RNA_pointer_create_discrete(&scene->id, &RNA_ObjectBase, base_iter);
}
RNA_property_boolean_set(&ptr, base_or_object_prop, value);
blender::animrig::autokeyframe_property(
C, scene, &ptr, base_or_object_prop, -1, BKE_scene_frame_get(scene), true);
}
}

View File

@@ -27,8 +27,8 @@ void MOV_exit();
*/
bool MOV_is_movie_file(const char *filepath);
/** Checks whether given FFMpegCodecData supports alpha channel (RGBA). */
bool MOV_codec_supports_alpha(const FFMpegCodecData &ff_codec_data);
/** Checks whether given FFMPEG codec and profile combination supports alpha channel (RGBA). */
bool MOV_codec_supports_alpha(int av_codec_id, int ffmpeg_profile);
/**
* Checks whether given FFMPEG video AVCodecID supports CRF (i.e. "quality level")

View File

@@ -508,21 +508,20 @@ void MOV_validate_output_settings(RenderData *rd, const ImageFormatData *imf)
#endif
}
bool MOV_codec_supports_alpha(const FFMpegCodecData &ff_codec_data)
bool MOV_codec_supports_alpha(int av_codec_id, int ffmpeg_profile)
{
#ifdef WITH_FFMPEG
if (ff_codec_data.codec == AV_CODEC_ID_PRORES) {
return ELEM(
ff_codec_data.ffmpeg_prores_profile, FFM_PRORES_PROFILE_4444, FFM_PRORES_PROFILE_4444_XQ);
if (av_codec_id == AV_CODEC_ID_PRORES) {
return ELEM(ffmpeg_profile, FFM_PRORES_PROFILE_4444, FFM_PRORES_PROFILE_4444_XQ);
}
return ELEM(ff_codec_data.codec,
return ELEM(av_codec_id,
AV_CODEC_ID_FFV1,
AV_CODEC_ID_QTRLE,
AV_CODEC_ID_PNG,
AV_CODEC_ID_VP9,
AV_CODEC_ID_HUFFYUV);
#else
UNUSED_VARS(ff_codec_data);
UNUSED_VARS(av_codec_id, ffmpeg_profile);
return false;
#endif
}

View File

@@ -23,6 +23,7 @@
# include "BLI_fileops.h"
# include "BLI_math_base.h"
# include "BLI_math_color.h"
# include "BLI_path_utils.hh"
# include "BLI_string.h"
# include "BLI_threads.h"
@@ -231,7 +232,9 @@ static AVFrame *generate_video_frame(MovieWriter *context, const ImBuf *image)
if (use_float) {
/* Float image: need to split up the image into a planar format,
* because `libswscale` does not support RGBA->YUV conversions from
* packed float formats. */
* packed float formats.
* Unpremultiply the image if the output format supports alpha, to
* match the format of the byte image. */
BLI_assert_msg(rgb_frame->linesize[1] == linesize_dst &&
rgb_frame->linesize[2] == linesize_dst &&
rgb_frame->linesize[3] == linesize_dst,
@@ -243,12 +246,26 @@ static AVFrame *generate_video_frame(MovieWriter *context, const ImBuf *image)
float *dst_r = reinterpret_cast<float *>(rgb_frame->data[2] + dst_offset);
float *dst_a = reinterpret_cast<float *>(rgb_frame->data[3] + dst_offset);
const float *src = pixels_fl + image->x * y * 4;
for (int x = 0; x < image->x; x++) {
*dst_r++ = src[0];
*dst_g++ = src[1];
*dst_b++ = src[2];
*dst_a++ = src[3];
src += 4;
if (MOV_codec_supports_alpha(context->ffmpeg_codec, context->ffmpeg_profile)) {
for (int x = 0; x < image->x; x++) {
float tmp[4];
premul_to_straight_v4_v4(tmp, src);
*dst_r++ = tmp[0];
*dst_g++ = tmp[1];
*dst_b++ = tmp[2];
*dst_a++ = tmp[3];
src += 4;
}
}
else {
for (int x = 0; x < image->x; x++) {
*dst_r++ = src[0];
*dst_g++ = src[1];
*dst_b++ = src[2];
*dst_a++ = src[3];
src += 4;
}
}
}
}

View File

@@ -1431,7 +1431,7 @@ static const EnumPropertyItem *rna_ImageFormatSettings_color_mode_itemf(bContext
Scene *scene = (Scene *)ptr->owner_id;
RenderData *rd = &scene->r;
if (MOV_codec_supports_alpha(rd->ffcodecdata)) {
if (MOV_codec_supports_alpha(rd->ffcodecdata.codec, rd->ffcodecdata.ffmpeg_prores_profile)) {
chan_flag |= IMA_CHAN_FLAG_RGBA;
}
}

View File

@@ -55,6 +55,10 @@ class OffsetCornerInFaceFieldInput final : public bke::MeshFieldInput {
mask.foreach_index_optimized<int>(GrainSize(2048), [&](const int selection_i) {
const int corner = corner_indices[selection_i];
const int offset = offsets[selection_i];
if (!corner_to_face.index_range().contains(corner)) {
offset_corners[selection_i] = 0;
return;
}
const IndexRange face = faces[corner_to_face[corner]];
const int corner_index_in_face = corner - face.start();
offset_corners[selection_i] = face.start() + math::mod_periodic<int>(