Merge branch 'blender-v5.0-release'
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
44
source/blender/blenkernel/intern/scene_test.cc
Normal file
44
source/blender/blenkernel/intern/scene_test.cc
Normal 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
|
||||
@@ -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];
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user