#include "testing/testing.h" // Keep first since utildefines defines AT which conflicts with STL #include "intern/abc_exporter.h" #include "intern/abc_util.h" extern "C" { #include "BKE_main.h" #include "BLI_math.h" #include "BLI_utildefines.h" #include "DNA_scene_types.h" } #include "DEG_depsgraph.h" class TestableAbcExporter : public AbcExporter { public: TestableAbcExporter(Main *bmain, const char *filename, ExportSettings &settings) : AbcExporter(bmain, filename, settings) { } void getShutterSamples(unsigned int nr_of_samples, bool time_relative, std::vector &samples) { AbcExporter::getShutterSamples(nr_of_samples, time_relative, samples); } void getFrameSet(unsigned int nr_of_samples, std::set &frames) { AbcExporter::getFrameSet(nr_of_samples, frames); } }; class AlembicExportTest : public testing::Test { protected: ExportSettings settings; Scene scene; Depsgraph *depsgraph; TestableAbcExporter *exporter; Main *bmain; virtual void SetUp() { settings.frame_start = 31.0; settings.frame_end = 223.0; /* 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; bmain = BKE_main_new(); /* TODO(sergey): Pass scene layer somehow? */ ViewLayer *view_layer = (ViewLayer *)scene.view_layers.first; settings.depsgraph = depsgraph = DEG_graph_new(bmain, &scene, view_layer, DAG_EVAL_VIEWPORT); settings.scene = &scene; settings.view_layer = view_layer; exporter = NULL; } virtual void TearDown() { BKE_main_free(bmain); DEG_graph_free(depsgraph); delete exporter; } // Call after setting up the settings. void createExporter() { exporter = new TestableAbcExporter(bmain, "somefile.abc", settings); } }; TEST_F(AlembicExportTest, TimeSamplesFullShutter) { settings.shutter_open = 0.0; settings.shutter_close = 1.0; createExporter(); std::vector samples; /* test 5 samples per frame */ exporter->getShutterSamples(5, true, samples); EXPECT_EQ(5, samples.size()); EXPECT_NEAR(1.240, samples[0], 1e-5f); EXPECT_NEAR(1.248, samples[1], 1e-5f); EXPECT_NEAR(1.256, samples[2], 1e-5f); EXPECT_NEAR(1.264, samples[3], 1e-5f); EXPECT_NEAR(1.272, samples[4], 1e-5f); /* test same, but using frame number offset instead of time */ exporter->getShutterSamples(5, false, samples); EXPECT_EQ(5, samples.size()); EXPECT_NEAR(0.0, samples[0], 1e-5f); EXPECT_NEAR(0.2, samples[1], 1e-5f); EXPECT_NEAR(0.4, samples[2], 1e-5f); EXPECT_NEAR(0.6, samples[3], 1e-5f); EXPECT_NEAR(0.8, samples[4], 1e-5f); /* use the same setup to test getFrameSet() */ std::set frames; exporter->getFrameSet(5, frames); EXPECT_EQ(965, frames.size()); EXPECT_EQ(1, frames.count(31.0)); EXPECT_EQ(1, frames.count(31.2)); EXPECT_EQ(1, frames.count(31.4)); EXPECT_EQ(1, frames.count(31.6)); EXPECT_EQ(1, frames.count(31.8)); } TEST_F(AlembicExportTest, TimeSamples180degShutter) { settings.shutter_open = -0.25; settings.shutter_close = 0.25; createExporter(); std::vector samples; /* test 5 samples per frame */ exporter->getShutterSamples(5, true, samples); EXPECT_EQ(5, samples.size()); EXPECT_NEAR(1.230, samples[0], 1e-5f); EXPECT_NEAR(1.234, samples[1], 1e-5f); EXPECT_NEAR(1.238, samples[2], 1e-5f); EXPECT_NEAR(1.242, samples[3], 1e-5f); EXPECT_NEAR(1.246, samples[4], 1e-5f); /* test same, but using frame number offset instead of time */ exporter->getShutterSamples(5, false, samples); EXPECT_EQ(5, samples.size()); EXPECT_NEAR(-0.25, samples[0], 1e-5f); EXPECT_NEAR(-0.15, samples[1], 1e-5f); EXPECT_NEAR(-0.05, samples[2], 1e-5f); EXPECT_NEAR(0.05, samples[3], 1e-5f); EXPECT_NEAR(0.15, samples[4], 1e-5f); /* Use the same setup to test getFrameSet(). * Here only a few numbers are tested, due to rounding issues. */ std::set frames; exporter->getFrameSet(5, frames); EXPECT_EQ(965, frames.size()); EXPECT_EQ(1, frames.count(30.75)); EXPECT_EQ(1, frames.count(30.95)); EXPECT_EQ(1, frames.count(31.15)); }