From 53d203dea8230da4e80f3cc61468a4e24ff6759c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 7 Aug 2020 16:43:42 +0200 Subject: Tests: move remaining gtests into their own module folders And make them part of the blender_test runner. The one exception is blenlib performance tests, which we don't want to run by default. They remain in their own executable. Differential Revision: https://developer.blender.org/D8498 --- source/blender/io/alembic/CMakeLists.txt | 14 + source/blender/io/alembic/tests/abc_export_test.cc | 161 ++++++++++++ source/blender/io/alembic/tests/abc_matrix_test.cc | 292 +++++++++++++++++++++ source/blender/io/common/CMakeLists.txt | 5 +- .../intern/abstract_hierarchy_iterator_test.cc | 3 +- 5 files changed, 473 insertions(+), 2 deletions(-) create mode 100644 source/blender/io/alembic/tests/abc_export_test.cc create mode 100644 source/blender/io/alembic/tests/abc_matrix_test.cc (limited to 'source/blender/io') diff --git a/source/blender/io/alembic/CMakeLists.txt b/source/blender/io/alembic/CMakeLists.txt index 681d6d04acd..de99a2c9d65 100644 --- a/source/blender/io/alembic/CMakeLists.txt +++ b/source/blender/io/alembic/CMakeLists.txt @@ -110,3 +110,17 @@ list(APPEND LIB ) blender_add_lib(bf_alembic "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") + +if(WITH_GTESTS) + set(TEST_SRC + tests/abc_export_test.cc + tests/abc_matrix_test.cc + ) + set(TEST_INC + ) + set(TEST_LIB + bf_alembic + ) + include(GTestTesting) + blender_add_test_lib(bf_io_alembic_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}") +endif() diff --git a/source/blender/io/alembic/tests/abc_export_test.cc b/source/blender/io/alembic/tests/abc_export_test.cc new file mode 100644 index 00000000000..5c2b505958e --- /dev/null +++ b/source/blender/io/alembic/tests/abc_export_test.cc @@ -0,0 +1,161 @@ +#include "testing/testing.h" + +// Keep first since utildefines defines AT which conflicts with STL +#include "exporter/abc_archive.h" +#include "intern/abc_util.h" + +#include "BKE_main.h" +#include "BLI_fileops.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" +#include "DNA_scene_types.h" + +#include "DEG_depsgraph.h" + +namespace blender { +namespace io { +namespace alembic { + +class AlembicExportTest : public testing::Test { + protected: + ABCArchive *abc_archive; + + AlembicExportParams params; + Scene scene; + Depsgraph *depsgraph; + Main *bmain; + + virtual void SetUp() + { + abc_archive = nullptr; + + /* Fake a 25 FPS scene with a nonzero base (because that's sometimes forgotten) */ + scene.r.frs_sec = 50; + scene.r.frs_sec_base = 2; + strcpy(scene.id.name, "SCTestScene"); + + bmain = BKE_main_new(); + + /* TODO(sergey): Pass scene layer somehow? */ + ViewLayer *view_layer = (ViewLayer *)scene.view_layers.first; + depsgraph = DEG_graph_new(bmain, &scene, view_layer, DAG_EVAL_RENDER); + } + + virtual void TearDown() + { + BKE_main_free(bmain); + DEG_graph_free(depsgraph); + deleteArchive(); + } + + // Call after setting up the parameters. + void createArchive() + { + if (abc_archive != nullptr) { + deleteArchive(); + } + abc_archive = new ABCArchive(bmain, &scene, params, "somefile.abc"); + } + + void deleteArchive() + { + delete abc_archive; + if (BLI_exists("somefile.abc")) { + BLI_delete("somefile.abc", false, false); + } + abc_archive = nullptr; + } +}; + +TEST_F(AlembicExportTest, TimeSamplesFullShutterUniform) +{ + /* Test 5 samples per frame, for 2 frames. */ + params.shutter_open = 0.0; + params.shutter_close = 1.0; + params.frame_start = 31.0; + params.frame_end = 32.0; + params.frame_samples_xform = params.frame_samples_shape = 5; + createArchive(); + std::vector frames(abc_archive->frames_begin(), abc_archive->frames_end()); + EXPECT_EQ(10, frames.size()); + EXPECT_NEAR(31.0, frames[0], 1e-5); + EXPECT_NEAR(31.2, frames[1], 1e-5); + EXPECT_NEAR(31.4, frames[2], 1e-5); + EXPECT_NEAR(31.6, frames[3], 1e-5); + EXPECT_NEAR(31.8, frames[4], 1e-5); + EXPECT_NEAR(32.0, frames[5], 1e-5); + EXPECT_NEAR(32.2, frames[6], 1e-5); + EXPECT_NEAR(32.4, frames[7], 1e-5); + EXPECT_NEAR(32.6, frames[8], 1e-5); + EXPECT_NEAR(32.8, frames[9], 1e-5); + + for (double frame : frames) { + EXPECT_TRUE(abc_archive->is_xform_frame(frame)); + EXPECT_TRUE(abc_archive->is_shape_frame(frame)); + } +} + +TEST_F(AlembicExportTest, TimeSamplesFullShutterDifferent) +{ + /* Test 3 samples per frame for transforms, and 2 per frame for shapes, for 2 frames. */ + params.shutter_open = 0.0; + params.shutter_close = 1.0; + params.frame_start = 31.0; + params.frame_end = 32.0; + params.frame_samples_xform = 3; + params.frame_samples_shape = 2; + createArchive(); + std::vector frames(abc_archive->frames_begin(), abc_archive->frames_end()); + EXPECT_EQ(8, frames.size()); + EXPECT_NEAR(31.0, frames[0], 1e-5); // transform + shape + EXPECT_TRUE(abc_archive->is_xform_frame(frames[0])); + EXPECT_TRUE(abc_archive->is_shape_frame(frames[0])); + EXPECT_NEAR(31.33333, frames[1], 1e-5); // transform + EXPECT_TRUE(abc_archive->is_xform_frame(frames[1])); + EXPECT_FALSE(abc_archive->is_shape_frame(frames[1])); + EXPECT_NEAR(31.5, frames[2], 1e-5); // shape + EXPECT_FALSE(abc_archive->is_xform_frame(frames[2])); + EXPECT_TRUE(abc_archive->is_shape_frame(frames[2])); + EXPECT_NEAR(31.66666, frames[3], 1e-5); // transform + EXPECT_TRUE(abc_archive->is_xform_frame(frames[3])); + EXPECT_FALSE(abc_archive->is_shape_frame(frames[3])); + EXPECT_NEAR(32.0, frames[4], 1e-5); // transform + shape + EXPECT_TRUE(abc_archive->is_xform_frame(frames[4])); + EXPECT_TRUE(abc_archive->is_shape_frame(frames[4])); + EXPECT_NEAR(32.33333, frames[5], 1e-5); // transform + EXPECT_TRUE(abc_archive->is_xform_frame(frames[5])); + EXPECT_FALSE(abc_archive->is_shape_frame(frames[5])); + EXPECT_NEAR(32.5, frames[6], 1e-5); // shape + EXPECT_FALSE(abc_archive->is_xform_frame(frames[6])); + EXPECT_TRUE(abc_archive->is_shape_frame(frames[6])); + EXPECT_NEAR(32.66666, frames[7], 1e-5); // transform + EXPECT_TRUE(abc_archive->is_xform_frame(frames[7])); + EXPECT_FALSE(abc_archive->is_shape_frame(frames[7])); +} + +TEST_F(AlembicExportTest, TimeSamples180degShutter) +{ + /* Test 5 samples per frame, for 2 frames. */ + params.shutter_open = -0.25; + params.shutter_close = 0.25; + params.frame_start = 31.0; + params.frame_end = 32.0; + params.frame_samples_xform = params.frame_samples_shape = 5; + createArchive(); + std::vector frames(abc_archive->frames_begin(), abc_archive->frames_end()); + EXPECT_EQ(10, frames.size()); + EXPECT_NEAR(31 - 0.25, frames[0], 1e-5); + EXPECT_NEAR(31 - 0.15, frames[1], 1e-5); + EXPECT_NEAR(31 - 0.05, frames[2], 1e-5); + EXPECT_NEAR(31 + 0.05, frames[3], 1e-5); + EXPECT_NEAR(31 + 0.15, frames[4], 1e-5); + EXPECT_NEAR(32 - 0.25, frames[5], 1e-5); + EXPECT_NEAR(32 - 0.15, frames[6], 1e-5); + EXPECT_NEAR(32 - 0.05, frames[7], 1e-5); + EXPECT_NEAR(32 + 0.05, frames[8], 1e-5); + EXPECT_NEAR(32 + 0.15, frames[9], 1e-5); +} + +} // namespace alembic +} // namespace io +} // namespace blender diff --git a/source/blender/io/alembic/tests/abc_matrix_test.cc b/source/blender/io/alembic/tests/abc_matrix_test.cc new file mode 100644 index 00000000000..b58e989b1a1 --- /dev/null +++ b/source/blender/io/alembic/tests/abc_matrix_test.cc @@ -0,0 +1,292 @@ +#include "testing/testing.h" + +// Keep first since utildefines defines AT which conflicts with STL +#include "intern/abc_axis_conversion.h" + +#include "BLI_math.h" +#include "BLI_utildefines.h" + +namespace blender { +namespace io { +namespace alembic { + +TEST(abc_matrix, CreateRotationMatrixY_YfromZ) +{ + // Input variables + float rot_x_mat[3][3]; + float rot_y_mat[3][3]; + float rot_z_mat[3][3]; + float euler[3] = {0.f, M_PI_4, 0.f}; + + // Construct expected matrices + float unit[3][3]; + float rot_z_min_quart_pi[3][3]; // rotation of -pi/4 radians over z-axis + + unit_m3(unit); + unit_m3(rot_z_min_quart_pi); + rot_z_min_quart_pi[0][0] = M_SQRT1_2; + rot_z_min_quart_pi[0][1] = -M_SQRT1_2; + rot_z_min_quart_pi[1][0] = M_SQRT1_2; + rot_z_min_quart_pi[1][1] = M_SQRT1_2; + + // Run tests + create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, ABC_YUP_FROM_ZUP); + + EXPECT_M3_NEAR(rot_x_mat, unit, 1e-5f); + EXPECT_M3_NEAR(rot_y_mat, unit, 1e-5f); + EXPECT_M3_NEAR(rot_z_mat, rot_z_min_quart_pi, 1e-5f); +} + +TEST(abc_matrix, CreateRotationMatrixZ_YfromZ) +{ + // Input variables + float rot_x_mat[3][3]; + float rot_y_mat[3][3]; + float rot_z_mat[3][3]; + float euler[3] = {0.f, 0.f, M_PI_4}; + + // Construct expected matrices + float unit[3][3]; + float rot_y_quart_pi[3][3]; // rotation of pi/4 radians over y-axis + + unit_m3(unit); + unit_m3(rot_y_quart_pi); + rot_y_quart_pi[0][0] = M_SQRT1_2; + rot_y_quart_pi[0][2] = -M_SQRT1_2; + rot_y_quart_pi[2][0] = M_SQRT1_2; + rot_y_quart_pi[2][2] = M_SQRT1_2; + + // Run tests + create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, ABC_YUP_FROM_ZUP); + + EXPECT_M3_NEAR(rot_x_mat, unit, 1e-5f); + EXPECT_M3_NEAR(rot_y_mat, rot_y_quart_pi, 1e-5f); + EXPECT_M3_NEAR(rot_z_mat, unit, 1e-5f); +} + +TEST(abc_matrix, CreateRotationMatrixXYZ_YfromZ) +{ + // Input variables + float rot_x_mat[3][3]; + float rot_y_mat[3][3]; + float rot_z_mat[3][3]; + // in degrees: X=10, Y=20, Z=30 + float euler[3] = {0.17453292012214f, 0.34906581044197f, 0.52359879016876f}; + + // Construct expected matrices + float rot_x_p10[3][3]; // rotation of +10 degrees over x-axis + float rot_y_p30[3][3]; // rotation of +30 degrees over y-axis + float rot_z_m20[3][3]; // rotation of -20 degrees over z-axis + + unit_m3(rot_x_p10); + rot_x_p10[1][1] = 0.9848077297210693f; + rot_x_p10[1][2] = 0.1736481785774231f; + rot_x_p10[2][1] = -0.1736481785774231f; + rot_x_p10[2][2] = 0.9848077297210693f; + + unit_m3(rot_y_p30); + rot_y_p30[0][0] = 0.8660253882408142f; + rot_y_p30[0][2] = -0.5f; + rot_y_p30[2][0] = 0.5f; + rot_y_p30[2][2] = 0.8660253882408142f; + + unit_m3(rot_z_m20); + rot_z_m20[0][0] = 0.9396926164627075f; + rot_z_m20[0][1] = -0.3420201241970062f; + rot_z_m20[1][0] = 0.3420201241970062f; + rot_z_m20[1][1] = 0.9396926164627075f; + + // Run tests + create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, ABC_YUP_FROM_ZUP); + + EXPECT_M3_NEAR(rot_x_mat, rot_x_p10, 1e-5f); + EXPECT_M3_NEAR(rot_y_mat, rot_y_p30, 1e-5f); + EXPECT_M3_NEAR(rot_z_mat, rot_z_m20, 1e-5f); +} + +TEST(abc_matrix, CreateRotationMatrixXYZ_ZfromY) +{ + // Input variables + float rot_x_mat[3][3]; + float rot_y_mat[3][3]; + float rot_z_mat[3][3]; + // in degrees: X=10, Y=20, Z=30 + float euler[3] = {0.1745329201221466f, 0.3490658104419708f, 0.5235987901687622f}; + + // Construct expected matrices + float rot_x_p10[3][3]; // rotation of +10 degrees over x-axis + float rot_y_m30[3][3]; // rotation of -30 degrees over y-axis + float rot_z_p20[3][3]; // rotation of +20 degrees over z-axis + + unit_m3(rot_x_p10); + rot_x_p10[1][1] = 0.9848077297210693f; + rot_x_p10[1][2] = 0.1736481785774231f; + rot_x_p10[2][1] = -0.1736481785774231f; + rot_x_p10[2][2] = 0.9848077297210693f; + + unit_m3(rot_y_m30); + rot_y_m30[0][0] = 0.8660253882408142f; + rot_y_m30[0][2] = 0.5f; + rot_y_m30[2][0] = -0.5f; + rot_y_m30[2][2] = 0.8660253882408142f; + + unit_m3(rot_z_p20); + rot_z_p20[0][0] = 0.9396926164627075f; + rot_z_p20[0][1] = 0.3420201241970062f; + rot_z_p20[1][0] = -0.3420201241970062f; + rot_z_p20[1][1] = 0.9396926164627075f; + + // Run tests + create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, ABC_ZUP_FROM_YUP); + + EXPECT_M3_NEAR(rot_x_mat, rot_x_p10, 1e-5f); + EXPECT_M3_NEAR(rot_y_mat, rot_y_m30, 1e-5f); + EXPECT_M3_NEAR(rot_z_mat, rot_z_p20, 1e-5f); +} + +TEST(abc_matrix, CopyM44AxisSwap_YfromZ) +{ + float result[4][4]; + + /* Construct an input matrix that performs a rotation like the tests + * above. This matrix was created by rotating a cube in Blender over + * (X=10, Y=20, Z=30 degrees in XYZ order) and translating over (1, 2, 3) */ + float input[4][4] = { + {0.81379765272f, 0.4698463380336f, -0.342020124197f, 0.f}, + {-0.44096961617f, 0.8825641274452f, 0.163175910711f, 0.f}, + {0.37852230668f, 0.0180283170193f, 0.925416588783f, 0.f}, + {1.f, 2.f, 3.f, 1.f}, + }; + + copy_m44_axis_swap(result, input, ABC_YUP_FROM_ZUP); + + /* Check the resulting rotation & translation. */ + float trans[4] = {1.f, 3.f, -2.f, 1.f}; + EXPECT_V4_NEAR(trans, result[3], 1e-5f); + + /* This matrix was created by rotating a cube in Blender over + * (X=10, Y=30, Z=-20 degrees in XZY order) and translating over (1, 3, -2) */ + float expect[4][4] = { + {0.813797652721f, -0.342020124197f, -0.469846338033f, 0.f}, + {0.378522306680f, 0.925416588783f, -0.018028317019f, 0.f}, + {0.440969616174f, -0.163175910711f, 0.882564127445f, 0.f}, + {1.f, 3.f, -2.f, 1.f}, + }; + EXPECT_M4_NEAR(expect, result, 1e-5f); +} + +TEST(abc_matrix, CopyM44AxisSwapWithScale_YfromZ) +{ + float result[4][4]; + + /* Construct an input matrix that performs a rotation like the tests + * above. This matrix was created by rotating a cube in Blender over + * (X=10, Y=20, Z=30 degrees in XYZ order), translating over (1, 2, 3), + * and scaling by (4, 5, 6). */ + float input[4][4] = { + {3.25519061088f, 1.8793853521347f, -1.368080496788f, 0.f}, + {-2.20484805107f, 4.4128208160400f, 0.815879583358f, 0.f}, + {2.27113389968f, 0.1081698983907f, 5.552499771118f, 0.f}, + {1.f, 2.f, 3.f, 1.f}, + }; + + copy_m44_axis_swap(result, input, ABC_YUP_FROM_ZUP); + + /* This matrix was created by rotating a cube in Blender over + * (X=10, Y=30, Z=-20 degrees in XZY order), translating over (1, 3, -2) + * and scaling over (4, 6, 5). */ + float expect[4][4] = { + {3.255190610885f, -1.368080496788f, -1.879385352134f, 0.f}, + {2.271133899688f, 5.552499771118f, -0.108169898390f, 0.f}, + {2.204848051071f, -0.815879583358f, 4.412820816040f, 0.f}, + {1.f, 3.f, -2.f, 1.f}, + }; + EXPECT_M4_NEAR(expect, result, 1e-5f); +} + +TEST(abc_matrix, CopyM44AxisSwap_ZfromY) +{ + float result[4][4]; + + /* This matrix was created by rotating a cube in Blender over + * (X=10, Y=30, Z=-20 degrees in XZY order) and translating over (1, 3, -2) */ + float input[4][4] = { + {0.813797652721f, -0.342020124197f, -0.469846338033f, 0.f}, + {0.378522306680f, 0.925416588783f, -0.018028317019f, 0.f}, + {0.440969616174f, -0.163175910711f, 0.882564127445f, 0.f}, + {1.f, 3.f, -2.f, 1.f}, + }; + + copy_m44_axis_swap(result, input, ABC_ZUP_FROM_YUP); + + /* This matrix was created by rotating a cube in Blender over + * (X=10, Y=20, Z=30 degrees in XYZ order) and translating over (1, 2, 3) */ + float expect[4][4] = { + {0.813797652721f, 0.469846338033f, -0.342020124197f, 0.f}, + {-0.44096961617f, 0.882564127445f, 0.163175910711f, 0.f}, + {0.378522306680f, 0.018028317019f, 0.925416588783f, 0.f}, + {1.f, 2.f, 3.f, 1.f}, + }; + + EXPECT_M4_NEAR(expect, result, 1e-5f); +} + +TEST(abc_matrix, CopyM44AxisSwapWithScale_ZfromY) +{ + float result[4][4]; + + /* This matrix was created by rotating a cube in Blender over + * (X=10, Y=30, Z=-20 degrees in XZY order), translating over (1, 3, -2) + * and scaling over (4, 6, 5). */ + float input[4][4] = { + {3.2551906108f, -1.36808049678f, -1.879385352134f, 0.f}, + {2.2711338996f, 5.55249977111f, -0.108169898390f, 0.f}, + {2.2048480510f, -0.81587958335f, 4.412820816040f, 0.f}, + {1.f, 3.f, -2.f, 1.f}, + }; + + copy_m44_axis_swap(result, input, ABC_ZUP_FROM_YUP); + + /* This matrix was created by rotating a cube in Blender over + * (X=10, Y=20, Z=30 degrees in XYZ order), translating over (1, 2, 3), + * and scaling by (4, 5, 6). */ + float expect[4][4] = { + {3.25519061088f, 1.879385352134f, -1.36808049678f, 0.f}, + {-2.2048480510f, 4.412820816040f, 0.81587958335f, 0.f}, + {2.27113389968f, 0.108169898390f, 5.55249977111f, 0.f}, + {1.f, 2.f, 3.f, 1.f}, + }; + + EXPECT_M4_NEAR(expect, result, 1e-5f); +} + +TEST(abc_matrix, CopyM44AxisSwapWithScale_gimbal_ZfromY) +{ + float result[4][4]; + + /* This matrix represents a rotation over (-90, -0, -0) degrees, + * and a translation over (-0, -0.1, -0). It is in Y=up. */ + float input[4][4] = { + {1.000f, 0.000f, 0.000f, 0.000f}, + {0.000f, 0.000f, -1.000f, 0.000f}, + {0.000f, 1.000f, 0.000f, 0.000f}, + {-0.000f, -0.100f, -0.000f, 1.000f}, + }; + + copy_m44_axis_swap(result, input, ABC_ZUP_FROM_YUP); + + /* Since the rotation is only over the X-axis, it should not change. + * The translation does change. */ + float expect[4][4] = { + {1.000f, 0.000f, 0.000f, 0.000f}, + {0.000f, 0.000f, -1.000f, 0.000f}, + {0.000f, 1.000f, 0.000f, 0.000f}, + {-0.000f, 0.000f, -0.100f, 1.000f}, + }; + + EXPECT_M4_NEAR(expect, result, 1e-5f); +} + +} // namespace alembic +} // namespace io +} // namespace blender diff --git a/source/blender/io/common/CMakeLists.txt b/source/blender/io/common/CMakeLists.txt index d3341767f8b..7e39af32f11 100644 --- a/source/blender/io/common/CMakeLists.txt +++ b/source/blender/io/common/CMakeLists.txt @@ -55,8 +55,11 @@ if(WITH_GTESTS) intern/hierarchy_context_order_test.cc intern/object_identifier_test.cc ) + set(TEST_INC + ../../blenloader + ) set(TEST_LIB - bf_blenloader_test + bf_blenloader_tests bf_io_common ) include(GTestTesting) diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc index 2bc7560e177..cbb2e63a99f 100644 --- a/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc +++ b/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc @@ -17,7 +17,8 @@ * All rights reserved. */ #include "IO_abstract_hierarchy_iterator.h" -#include "blenloader/blendfile_loading_base_test.h" + +#include "tests/blendfile_loading_base_test.h" #include "BLI_math.h" #include "DEG_depsgraph.h" -- cgit v1.2.3