Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/gtests/CMakeLists.txt3
-rw-r--r--tests/gtests/usd/CMakeLists.txt87
-rw-r--r--tests/gtests/usd/abstract_hierarchy_iterator_test.cc202
-rw-r--r--tests/gtests/usd/hierarchy_context_order_test.cc123
-rw-r--r--tests/gtests/usd/usd_stage_creation_test.cc72
5 files changed, 487 insertions, 0 deletions
diff --git a/tests/gtests/CMakeLists.txt b/tests/gtests/CMakeLists.txt
index 54a1ee41198..7da65bcc8b9 100644
--- a/tests/gtests/CMakeLists.txt
+++ b/tests/gtests/CMakeLists.txt
@@ -19,4 +19,7 @@ if(WITH_GTESTS)
if(WITH_ALEMBIC)
add_subdirectory(alembic)
endif()
+ if(WITH_USD)
+ add_subdirectory(usd)
+ endif()
endif()
diff --git a/tests/gtests/usd/CMakeLists.txt b/tests/gtests/usd/CMakeLists.txt
new file mode 100644
index 00000000000..e2768509ec4
--- /dev/null
+++ b/tests/gtests/usd/CMakeLists.txt
@@ -0,0 +1,87 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# The Original Code is Copyright (C) 2019, Blender Foundation
+# All rights reserved.
+# ***** END GPL LICENSE BLOCK *****
+
+# This suppresses the warning "This file includes at least one deprecated or antiquated
+# header which may be removed without further notice at a future date", which is caused
+# by the USD library including <ext/hash_set> on Linux. This has been reported at:
+# https://github.com/PixarAnimationStudios/USD/issues/1057.
+if(UNIX AND NOT APPLE)
+ add_definitions(-D_GLIBCXX_PERMIT_BACKWARD_HASH)
+endif()
+if(WIN32)
+ add_definitions(-DNOMINMAX)
+endif()
+add_definitions(-DPXR_STATIC)
+
+set(INC
+ .
+ ..
+ ../../../source/blender/blenlib
+ ../../../source/blender/blenkernel
+ ../../../source/blender/usd
+ ../../../source/blender/makesdna
+ ../../../source/blender/depsgraph
+ ${USD_INCLUDE_DIRS}
+ ${BOOST_INCLUDE_DIR}
+ ${TBB_INCLUDE_DIR}
+)
+
+set(LIB
+ bf_blenloader_test
+ bf_blenloader
+
+ # Should not be needed but gives windows linker errors if the ocio libs are linked before this:
+ bf_intern_opencolorio
+ bf_gpu
+
+ bf_usd
+)
+
+include_directories(${INC})
+
+setup_libdirs()
+get_property(BLENDER_SORTED_LIBS GLOBAL PROPERTY BLENDER_SORTED_LIBS_PROP)
+
+set(SRC
+ abstract_hierarchy_iterator_test.cc
+ hierarchy_context_order_test.cc
+)
+
+if(UNIX AND NOT APPLE)
+ # TODO(Sybren): This unit test has only been tested on Linux, and should possibly be
+ # restructured to support other platforms as well.
+ list(APPEND SRC usd_stage_creation_test.cc)
+endif()
+
+
+if(WITH_BUILDINFO)
+ list(APPEND SRC "$<TARGET_OBJECTS:buildinfoobj>")
+endif()
+
+BLENDER_SRC_GTEST_EX(
+ NAME usd
+ SRC "${SRC}"
+ EXTRA_LIBS "${LIB}"
+ COMMAND_ARGS
+ --test-assets-dir "${CMAKE_SOURCE_DIR}/../lib/tests"
+ --test-blender-executable-dir "${EXECUTABLE_OUTPUT_PATH}"
+)
+
+setup_liblinks(usd_test)
diff --git a/tests/gtests/usd/abstract_hierarchy_iterator_test.cc b/tests/gtests/usd/abstract_hierarchy_iterator_test.cc
new file mode 100644
index 00000000000..e87ef547052
--- /dev/null
+++ b/tests/gtests/usd/abstract_hierarchy_iterator_test.cc
@@ -0,0 +1,202 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+#include "blenloader/blendfile_loading_base_test.h"
+#include "intern/abstract_hierarchy_iterator.h"
+
+extern "C" {
+#include "BLI_math.h"
+#include "DEG_depsgraph.h"
+#include "DNA_object_types.h"
+}
+
+#include <map>
+#include <set>
+
+/* Mapping from ID.name to set of export hierarchy path. Duplicated objects can be exported
+ * multiple times, hence the set. */
+typedef std::map<std::string, std::set<std::string>> created_writers;
+
+using namespace USD;
+
+class TestHierarchyWriter : public AbstractHierarchyWriter {
+ public:
+ created_writers &writers_map;
+
+ TestHierarchyWriter(created_writers &writers_map) : writers_map(writers_map)
+ {
+ }
+
+ void write(HierarchyContext &context) override
+ {
+ const char *id_name = context.object->id.name;
+ created_writers::mapped_type &writers = writers_map[id_name];
+
+ BLI_assert(writers.find(context.export_path) == writers.end());
+ writers.insert(context.export_path);
+ }
+};
+
+void debug_print_writers(const char *label, const created_writers &writers_map)
+{
+ printf("%s:\n", label);
+ for (auto idname_writers : writers_map) {
+ printf(" %s:\n", idname_writers.first.c_str());
+ for (const std::string &export_path : idname_writers.second) {
+ printf(" - %s\n", export_path.c_str());
+ }
+ }
+}
+
+class TestingHierarchyIterator : public AbstractHierarchyIterator {
+ public: /* Public so that the test cases can directly inspect the created writers. */
+ created_writers transform_writers;
+ created_writers data_writers;
+ created_writers hair_writers;
+ created_writers particle_writers;
+
+ public:
+ explicit TestingHierarchyIterator(Depsgraph *depsgraph) : AbstractHierarchyIterator(depsgraph)
+ {
+ }
+ virtual ~TestingHierarchyIterator()
+ {
+ }
+
+ protected:
+ AbstractHierarchyWriter *create_transform_writer(const HierarchyContext *context) override
+ {
+ return new TestHierarchyWriter(transform_writers);
+ }
+ AbstractHierarchyWriter *create_data_writer(const HierarchyContext *context) override
+ {
+ return new TestHierarchyWriter(data_writers);
+ }
+ AbstractHierarchyWriter *create_hair_writer(const HierarchyContext *context) override
+ {
+ return new TestHierarchyWriter(hair_writers);
+ }
+ AbstractHierarchyWriter *create_particle_writer(const HierarchyContext *context) override
+ {
+ return new TestHierarchyWriter(particle_writers);
+ }
+
+ void delete_object_writer(AbstractHierarchyWriter *writer) override
+ {
+ delete writer;
+ }
+};
+
+class USDHierarchyIteratorTest : public BlendfileLoadingBaseTest {
+ protected:
+ TestingHierarchyIterator *iterator;
+
+ virtual void SetUp()
+ {
+ BlendfileLoadingBaseTest::SetUp();
+ iterator = nullptr;
+ }
+
+ virtual void TearDown()
+ {
+ iterator_free();
+ BlendfileLoadingBaseTest::TearDown();
+ }
+
+ /* Create a test iterator. */
+ void iterator_create()
+ {
+ iterator = new TestingHierarchyIterator(depsgraph);
+ }
+ /* Free the test iterator if it is not nullptr. */
+ void iterator_free()
+ {
+ if (iterator == nullptr) {
+ return;
+ }
+ delete iterator;
+ iterator = nullptr;
+ }
+};
+
+TEST_F(USDHierarchyIteratorTest, ExportHierarchyTest)
+{
+ /* Load the test blend file. */
+ if (!blendfile_load("usd/usd_hierarchy_export_test.blend")) {
+ return;
+ }
+ depsgraph_create(DAG_EVAL_RENDER);
+ iterator_create();
+
+ iterator->iterate_and_write();
+
+ // Mapping from object name to set of export paths.
+ created_writers expected_transforms = {
+ {"OBCamera", {"/Camera"}},
+ {"OBDupli1", {"/Dupli1"}},
+ {"OBDupli2", {"/ParentOfDupli2/Dupli2"}},
+ {"OBGEO_Ear_L",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_L-1",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_L",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_L-1"}},
+ {"OBGEO_Ear_R",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_R-2",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_R",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_R-2"}},
+ {"OBGEO_Head",
+ {"/Dupli1/GEO_Head-0",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0"}},
+ {"OBGEO_Nose",
+ {"/Dupli1/GEO_Head-0/GEO_Nose-3",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Nose",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Nose-3"}},
+ {"OBGround plane", {"/Ground plane"}},
+ {"OBOutsideDupliGrandParent", {"/Ground plane/OutsideDupliGrandParent"}},
+ {"OBOutsideDupliParent", {"/Ground plane/OutsideDupliGrandParent/OutsideDupliParent"}},
+ {"OBParentOfDupli2", {"/ParentOfDupli2"}}};
+ EXPECT_EQ(expected_transforms, iterator->transform_writers);
+
+ created_writers expected_data = {
+ {"OBCamera", {"/Camera/Camera"}},
+ {"OBGEO_Ear_L",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_L-1/Ear",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_L/Ear",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_L-1/Ear"}},
+ {"OBGEO_Ear_R",
+ {"/Dupli1/GEO_Head-0/GEO_Ear_R-2/Ear",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Ear_R/Ear",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Ear_R-2/Ear"}},
+ {"OBGEO_Head",
+ {"/Dupli1/GEO_Head-0/Face",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/Face",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/Face"}},
+ {"OBGEO_Nose",
+ {"/Dupli1/GEO_Head-0/GEO_Nose-3/Nose",
+ "/Ground plane/OutsideDupliGrandParent/OutsideDupliParent/GEO_Head/GEO_Nose/Nose",
+ "/ParentOfDupli2/Dupli2/GEO_Head-0/GEO_Nose-3/Nose"}},
+ {"OBGround plane", {"/Ground plane/Plane"}},
+ {"OBParentOfDupli2", {"/ParentOfDupli2/Icosphere"}},
+ };
+
+ EXPECT_EQ(expected_data, iterator->data_writers);
+
+ // The scene has no hair or particle systems.
+ EXPECT_EQ(0, iterator->hair_writers.size());
+ EXPECT_EQ(0, iterator->particle_writers.size());
+}
diff --git a/tests/gtests/usd/hierarchy_context_order_test.cc b/tests/gtests/usd/hierarchy_context_order_test.cc
new file mode 100644
index 00000000000..ce3b43484e7
--- /dev/null
+++ b/tests/gtests/usd/hierarchy_context_order_test.cc
@@ -0,0 +1,123 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+#include "intern/abstract_hierarchy_iterator.h"
+
+#include "testing/testing.h"
+
+extern "C" {
+#include "BLI_utildefines.h"
+}
+
+using namespace USD;
+
+class HierarchyContextOrderTest : public testing::Test {
+};
+
+static Object *fake_pointer(int value)
+{
+ return static_cast<Object *>(POINTER_FROM_INT(value));
+}
+
+TEST_F(HierarchyContextOrderTest, ObjectPointerTest)
+{
+ HierarchyContext ctx_a;
+ ctx_a.object = fake_pointer(1);
+ ctx_a.duplicator = nullptr;
+
+ HierarchyContext ctx_b;
+ ctx_b.object = fake_pointer(2);
+ ctx_b.duplicator = nullptr;
+
+ EXPECT_EQ(true, ctx_a < ctx_b);
+ EXPECT_EQ(false, ctx_b < ctx_a);
+ EXPECT_EQ(false, ctx_a < ctx_a);
+}
+
+TEST_F(HierarchyContextOrderTest, DuplicatorPointerTest)
+{
+ HierarchyContext ctx_a;
+ ctx_a.object = fake_pointer(1);
+ ctx_a.duplicator = fake_pointer(1);
+ ctx_a.export_name = "A";
+
+ HierarchyContext ctx_b;
+ ctx_b.object = fake_pointer(1);
+ ctx_b.duplicator = fake_pointer(1);
+ ctx_b.export_name = "B";
+
+ EXPECT_EQ(true, ctx_a < ctx_b);
+ EXPECT_EQ(false, ctx_b < ctx_a);
+ EXPECT_EQ(false, ctx_a < ctx_a);
+}
+
+TEST_F(HierarchyContextOrderTest, ExportParentTest)
+{
+ HierarchyContext ctx_a;
+ ctx_a.object = fake_pointer(1);
+ ctx_a.export_parent = fake_pointer(1);
+
+ HierarchyContext ctx_b;
+ ctx_b.object = fake_pointer(1);
+ ctx_b.export_parent = fake_pointer(2);
+
+ EXPECT_EQ(true, ctx_a < ctx_b);
+ EXPECT_EQ(false, ctx_b < ctx_a);
+ EXPECT_EQ(false, ctx_a < ctx_a);
+}
+
+TEST_F(HierarchyContextOrderTest, TransitiveTest)
+{
+ HierarchyContext ctx_a;
+ ctx_a.object = fake_pointer(1);
+ ctx_a.export_parent = fake_pointer(1);
+ ctx_a.duplicator = nullptr;
+ ctx_a.export_name = "A";
+
+ HierarchyContext ctx_b;
+ ctx_b.object = fake_pointer(2);
+ ctx_b.export_parent = nullptr;
+ ctx_b.duplicator = fake_pointer(1);
+ ctx_b.export_name = "B";
+
+ HierarchyContext ctx_c;
+ ctx_c.object = fake_pointer(2);
+ ctx_c.export_parent = fake_pointer(2);
+ ctx_c.duplicator = fake_pointer(1);
+ ctx_c.export_name = "C";
+
+ HierarchyContext ctx_d;
+ ctx_d.object = fake_pointer(2);
+ ctx_d.export_parent = fake_pointer(3);
+ ctx_d.duplicator = nullptr;
+ ctx_d.export_name = "D";
+
+ EXPECT_EQ(true, ctx_a < ctx_b);
+ EXPECT_EQ(true, ctx_a < ctx_c);
+ EXPECT_EQ(true, ctx_a < ctx_d);
+ EXPECT_EQ(true, ctx_b < ctx_c);
+ EXPECT_EQ(true, ctx_b < ctx_d);
+ EXPECT_EQ(true, ctx_c < ctx_d);
+
+ EXPECT_EQ(false, ctx_b < ctx_a);
+ EXPECT_EQ(false, ctx_c < ctx_a);
+ EXPECT_EQ(false, ctx_d < ctx_a);
+ EXPECT_EQ(false, ctx_c < ctx_b);
+ EXPECT_EQ(false, ctx_d < ctx_b);
+ EXPECT_EQ(false, ctx_d < ctx_c);
+}
diff --git a/tests/gtests/usd/usd_stage_creation_test.cc b/tests/gtests/usd/usd_stage_creation_test.cc
new file mode 100644
index 00000000000..fcf1e93ea7d
--- /dev/null
+++ b/tests/gtests/usd/usd_stage_creation_test.cc
@@ -0,0 +1,72 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2019 Blender Foundation.
+ * All rights reserved.
+ */
+#include "testing/testing.h"
+#include <pxr/usd/usd/stage.h>
+
+#include <string>
+
+extern "C" {
+#include "BLI_path_util.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_appdir.h"
+
+/* Workaround to make it possible to pass a path at runtime to USD. See creator.c. */
+void usd_initialise_plugin_path(const char *datafiles_usd_path);
+}
+
+DEFINE_string(test_blender_executable_dir, "", "Blender's installation directory.");
+
+class USDStageCreationTest : public testing::Test {
+};
+
+TEST_F(USDStageCreationTest, JSONFileLoadingTest)
+{
+ std::string filename = "usd-stage-creation-test.usdc";
+
+ if (FLAGS_test_blender_executable_dir.empty()) {
+ FAIL() << "Pass the flag";
+ }
+
+ /* Required on Linux to make BKE_appdir_folder_id() find the datafiles.
+ * Without going to this directory, Blender looks for the datafiles in
+ * .../bin/tests instead of .../bin */
+ const char *blender_executable_dir = FLAGS_test_blender_executable_dir.c_str();
+ if (chdir(blender_executable_dir) < 0) {
+ FAIL() << "unable to change directory to " << FLAGS_test_blender_executable_dir;
+ }
+
+ const char *usd_datafiles_relpath = BKE_appdir_folder_id(BLENDER_DATAFILES, "usd");
+ EXPECT_NE(usd_datafiles_relpath, nullptr) << "Unable to find datafiles/usd";
+
+ char usd_datafiles_abspath[FILE_MAX];
+ BLI_path_join(usd_datafiles_abspath,
+ sizeof(usd_datafiles_abspath),
+ blender_executable_dir,
+ usd_datafiles_relpath,
+ NULL);
+
+ usd_initialise_plugin_path(usd_datafiles_abspath);
+
+ /* Simply the ability to create a USD Stage for a specific filename means that the extension has
+ * been recognised by the USD library, and that a USD plugin has been loaded to write such files.
+ * Practically, this is a test to see whether the USD JSON files can be found and loaded. */
+ pxr::UsdStageRefPtr usd_stage = pxr::UsdStage::CreateNew(filename);
+ EXPECT_TRUE(usd_stage) << "unable to find suitable USD plugin to write " << filename;
+}