Merge branch 'blender-v5.0-release'

This commit is contained in:
Bastien Montagne
2025-10-15 15:20:17 +02:00
7 changed files with 96 additions and 9 deletions

View File

@@ -138,7 +138,7 @@ const char *BKE_scene_find_marker_name(const Scene *scene, int frame);
*/
const char *BKE_scene_find_last_marker_name(const Scene *scene, int frame);
int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int frame);
float BKE_scene_frame_snap_by_seconds(const Scene *scene, double interval_in_seconds, float frame);
/**
* Checks for cycle, returns true if it's all OK.

View File

@@ -814,6 +814,7 @@ if(WITH_GTESTS)
intern/main_test.cc
intern/nla_test.cc
intern/path_templates_test.cc
intern/scene_test.cc
intern/subdiv_ccg_test.cc
intern/tracking_test.cc
intern/volume_test.cc

View File

@@ -2306,14 +2306,19 @@ const char *BKE_scene_find_last_marker_name(const Scene *scene, int frame)
return best_marker ? best_marker->name : nullptr;
}
int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int frame)
float BKE_scene_frame_snap_by_seconds(const Scene *scene,
const double interval_in_seconds,
const float frame)
{
const int fps = round_db_to_int(scene->frames_per_second() * interval_in_seconds);
const int second_prev = frame - mod_i(frame, fps);
const int second_next = second_prev + fps;
const int delta_prev = frame - second_prev;
const int delta_next = second_next - frame;
return (delta_prev < delta_next) ? second_prev : second_next;
BLI_assert(interval_in_seconds > 0);
BLI_assert(scene->frames_per_second() > 0);
const double interval_in_frames = scene->frames_per_second() * interval_in_seconds;
const double second_prev = interval_in_frames * floor(frame / interval_in_frames);
const double second_next = second_prev + ceil(interval_in_frames);
const double delta_prev = frame - second_prev;
const double delta_next = second_next - frame;
return float((delta_prev < delta_next) ? second_prev : second_next);
}
void BKE_scene_remove_rigidbody_object(Main *bmain, Scene *scene, Object *ob, const bool free_us)

View File

@@ -0,0 +1,44 @@
/* SPDX-FileCopyrightText: 2025 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BKE_scene.hh"
#include "DNA_scene_types.h"
#include "testing/testing.h"
namespace blender::bke::tests {
TEST(scene, frame_snap_by_seconds)
{
Scene fake_scene = {};
/* Regular 24 FPS snapping. */
fake_scene.r.frs_sec = 24;
fake_scene.r.frs_sec_base = 1.0;
EXPECT_FLOAT_EQ(48.0, BKE_scene_frame_snap_by_seconds(&fake_scene, 1.0, 47));
EXPECT_FLOAT_EQ(48.0, BKE_scene_frame_snap_by_seconds(&fake_scene, 1.0, 49));
EXPECT_FLOAT_EQ(48.0, BKE_scene_frame_snap_by_seconds(&fake_scene, 1.0, 59));
EXPECT_FLOAT_EQ(72.0, BKE_scene_frame_snap_by_seconds(&fake_scene, 1.0, 60));
EXPECT_FLOAT_EQ(9984.0, BKE_scene_frame_snap_by_seconds(&fake_scene, 2.0, 10000.0));
/* 12 FPS snapping by incrementing the base. */
fake_scene.r.frs_sec = 24;
fake_scene.r.frs_sec_base = 2.0;
EXPECT_FLOAT_EQ(48.0, BKE_scene_frame_snap_by_seconds(&fake_scene, 1.0, 47));
EXPECT_FLOAT_EQ(48.0, BKE_scene_frame_snap_by_seconds(&fake_scene, 1.0, 49));
EXPECT_FLOAT_EQ(48.0, BKE_scene_frame_snap_by_seconds(&fake_scene, 1.0, 53));
EXPECT_FLOAT_EQ(60.0, BKE_scene_frame_snap_by_seconds(&fake_scene, 1.0, 54));
EXPECT_FLOAT_EQ(9996.0, BKE_scene_frame_snap_by_seconds(&fake_scene, 1.0, 10000.0));
/* 0.1 FPS snapping to 2-second intervals. */
fake_scene.r.frs_sec = 1;
fake_scene.r.frs_sec_base = 10.0;
EXPECT_FLOAT_EQ(48.0, BKE_scene_frame_snap_by_seconds(&fake_scene, 2.0, 48.0));
EXPECT_FLOAT_EQ(48.0, BKE_scene_frame_snap_by_seconds(&fake_scene, 2.0, 48.1));
EXPECT_FLOAT_EQ(48.2, BKE_scene_frame_snap_by_seconds(&fake_scene, 2.0, 48.2));
EXPECT_FLOAT_EQ(10000.0, BKE_scene_frame_snap_by_seconds(&fake_scene, 2.0, 10000.0));
}
} // namespace blender::bke::tests

View File

@@ -3501,6 +3501,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
* later during 5.0 development process. */
version_system_idprops_nodes_generate(main);
}
if (!MAIN_VERSION_FILE_ATLEAST(main, 500, 110)) {
/* Same as above, but children bones were missed by initial versioning code, attempt to
* transfer idprops data still in case they have no system properties defined yet. */
version_system_idprops_children_bones_generate(main);
}
if (G.debug & G_DEBUG) {
char build_commit_datetime[32];

View File

@@ -130,8 +130,16 @@ void version_system_idprops_generate(Main *bmain)
for (BoneCollection *bcoll : armature->collections_span()) {
idprops_process(bcoll->prop, &bcoll->system_properties);
}
LISTBASE_FOREACH (Bone *, bone, &armature->bonebase) {
/* There is no way to iterate directly over all bones of an armature currently, use a recursive
* approach instead. */
auto process_bone_recursive = [](const auto &process_bone_recursive, Bone *bone) -> void {
idprops_process(bone->prop, &bone->system_properties);
LISTBASE_FOREACH (Bone *, bone_it, &bone->childbase) {
process_bone_recursive(process_bone_recursive, bone_it);
}
};
LISTBASE_FOREACH (Bone *, bone_it, &armature->bonebase) {
process_bone_recursive(process_bone_recursive, bone_it);
}
}
}
@@ -145,6 +153,29 @@ void version_system_idprops_nodes_generate(Main *bmain)
}
FOREACH_NODETREE_END;
}
/* Separate callback for non-root bones, because they were missed in the initial implementation. */
void version_system_idprops_children_bones_generate(Main *bmain)
{
LISTBASE_FOREACH (bArmature *, armature, &bmain->armatures) {
/* There is no way to iterate directly over all bones of an armature currently, use a recursive
* approach instead. */
auto process_bone_recursive = [](const auto &process_bone_recursive, Bone *bone) -> void {
/* Do not overwrite children bones' system properties if they were already defined by some
* scripts or add-on e.g. */
if (bone->system_properties == nullptr) {
idprops_process(bone->prop, &bone->system_properties);
}
LISTBASE_FOREACH (Bone *, bone_it, &bone->childbase) {
process_bone_recursive(process_bone_recursive, bone_it);
}
};
LISTBASE_FOREACH (Bone *, bone_it, &armature->bonebase) {
LISTBASE_FOREACH (Bone *, bone_child_it, &bone_it->childbase) {
process_bone_recursive(process_bone_recursive, bone_child_it);
}
}
}
}
static CustomDataLayer *find_old_seam_layer(CustomData &custom_data, const blender::StringRef name)
{

View File

@@ -218,6 +218,7 @@ bNode *version_eevee_output_node_get(bNodeTree *ntree, int16_t node_type);
*/
void version_system_idprops_generate(Main *bmain);
void version_system_idprops_nodes_generate(Main *bmain);
void version_system_idprops_children_bones_generate(Main *bmain);
bool all_scenes_use(Main *bmain, const blender::Span<const char *> engines);