diff options
-rw-r--r-- | source/blender/io/usd/CMakeLists.txt | 28 | ||||
-rw-r--r-- | source/blender/io/usd/tests/usd_imaging_test.cc | 71 | ||||
-rw-r--r-- | source/blender/io/usd/tests/usd_stage_creation_test.cc | 19 | ||||
-rw-r--r-- | source/blender/io/usd/tests/usd_tests_common.cc | 45 | ||||
-rw-r--r-- | source/blender/io/usd/tests/usd_tests_common.h | 20 |
5 files changed, 169 insertions, 14 deletions
diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt index 2b5ea39617e..e2e959814fa 100644 --- a/source/blender/io/usd/CMakeLists.txt +++ b/source/blender/io/usd/CMakeLists.txt @@ -16,6 +16,24 @@ add_definitions(-DPXR_STATIC) # USD headers use deprecated TBB headers, silence warning. add_definitions(-DTBB_SUPPRESS_DEPRECATED_MESSAGES=1) +# Check if USD has the imaging headers available, if they are +# add a USD_HAS_IMAGING define so code can dynamically detect this. +# Cleanup of this variable is done at the end of the file since +# test code further down uses it to add imaging tests. +FIND_FILE(USD_IMAGING_HEADERS + NAMES + capsuleAdapter.h + PATHS + ${USD_INCLUDE_DIRS} + PATH_SUFFIXES + pxr/usdImaging/usdImaging/ + NO_DEFAULT_PATH +) + +if(USD_IMAGING_HEADERS) + add_definitions(-DUSD_HAS_IMAGING) +endif() + set(INC . ../common @@ -129,7 +147,13 @@ target_link_libraries(bf_usd INTERFACE ${TBB_LIBRARIES}) if(WITH_GTESTS) set(TEST_SRC tests/usd_stage_creation_test.cc + tests/usd_tests_common.cc + tests/usd_tests_common.h ) + if(USD_IMAGING_HEADERS) + LIST(APPEND TEST_SRC tests/usd_imaging_test.cc) + endif() + set(TEST_INC ) set(TEST_LIB @@ -137,3 +161,7 @@ if(WITH_GTESTS) include(GTestTesting) blender_add_test_lib(bf_io_usd_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}") endif() + +# In cmake version 3.21 and up, we can instead use the NO_CACHE option for +# find_file so we don't need to clear it from the cache here. +unset(USD_IMAGING_HEADERS CACHE) diff --git a/source/blender/io/usd/tests/usd_imaging_test.cc b/source/blender/io/usd/tests/usd_imaging_test.cc new file mode 100644 index 00000000000..497319c59bd --- /dev/null +++ b/source/blender/io/usd/tests/usd_imaging_test.cc @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. All rights reserved. */ +#include "testing/testing.h" + +#include "usd_tests_common.h" + +#include <pxr/usd/usd/stage.h> +#include <pxr/usd/usdGeom/capsule.h> +#include <pxr/usdImaging/usdImaging/capsuleAdapter.h> + +namespace blender::io::usd { + +class USDImagingTest : public testing::Test { +}; + +TEST_F(USDImagingTest, CapsuleAdapterTest) +{ + /* A simple test to exercise the UsdImagingGprimAdapter API to + * ensure the code compiles, links and returns reasonable results. + * We create a capsule shape on an in-memory stage and attempt + * to access the shape's points and topology. */ + + /* We must register USD plugin paths before creating the stage + * to avoid a crash in the USD asset resolver initialization code. */ + if (register_usd_plugins_for_tests().empty()) { + FAIL(); + return; + } + + pxr::UsdStageRefPtr stage = pxr::UsdStage::CreateInMemory(); + + if (!stage) { + FAIL() << "Couldn't create in-memory stage."; + return; + } + + pxr::UsdGeomCapsule capsule = pxr::UsdGeomCapsule::Define(stage, pxr::SdfPath("/Capsule")); + + if (!capsule) { + FAIL() << "Couldn't create UsdGeomCapsule."; + return; + } + + pxr::UsdImagingCapsuleAdapter capsule_adapter; + pxr::VtValue points_value = capsule_adapter.GetMeshPoints(capsule.GetPrim(), + pxr::UsdTimeCode::Default()); + if (!points_value.IsHolding<pxr::VtArray<pxr::GfVec3f>>()) { + FAIL() << "Mesh points value holding unexpected type."; + return; + } + + pxr::VtArray<pxr::GfVec3f> points = points_value.Get<pxr::VtArray<pxr::GfVec3f>>(); + EXPECT_FALSE(points.empty()); + + pxr::VtValue topology_value = capsule_adapter.GetMeshTopology(); + + if (!topology_value.IsHolding<pxr::HdMeshTopology>()) { + FAIL() << "Mesh topology value holding unexpected type."; + return; + } + + pxr::HdMeshTopology topology = topology_value.Get<pxr::HdMeshTopology>(); + + pxr::VtArray<int> vertex_counts = topology.GetFaceVertexCounts(); + EXPECT_FALSE(vertex_counts.empty()); + + pxr::VtArray<int> vertex_indices = topology.GetFaceVertexIndices(); + EXPECT_FALSE(vertex_indices.empty()); +} + +} // namespace blender::io::usd diff --git a/source/blender/io/usd/tests/usd_stage_creation_test.cc b/source/blender/io/usd/tests/usd_stage_creation_test.cc index dbe5f8cd9ce..1aa6f9691ff 100644 --- a/source/blender/io/usd/tests/usd_stage_creation_test.cc +++ b/source/blender/io/usd/tests/usd_stage_creation_test.cc @@ -2,6 +2,8 @@ * Copyright 2019 Blender Foundation. All rights reserved. */ #include "testing/testing.h" +#include "usd_tests_common.h" + #include <pxr/base/plug/registry.h> #include <pxr/usd/usd/stage.h> @@ -19,23 +21,12 @@ class USDStageCreationTest : public testing::Test { TEST_F(USDStageCreationTest, JSONFileLoadingTest) { - const std::string &release_dir = blender::tests::flags_test_release_dir(); - if (release_dir.empty()) { + std::string usd_datafiles_dir = register_usd_plugins_for_tests(); + if (usd_datafiles_dir.empty()) { FAIL(); + return; } - char usd_datafiles_dir[FILE_MAX]; - const size_t path_len = BLI_path_join( - usd_datafiles_dir, FILE_MAX, release_dir.c_str(), "datafiles", "usd", nullptr); - - /* #BLI_path_join removes trailing slashes, but the USD library requires one in order to - * recognize the path as directory. */ - BLI_assert(path_len + 1 < FILE_MAX); - usd_datafiles_dir[path_len] = '/'; - usd_datafiles_dir[path_len + 1] = '\0'; - - pxr::PlugRegistry::GetInstance().RegisterPlugins(usd_datafiles_dir); - /* Simply the ability to create a USD Stage for a specific filename means that the extension * has been recognized 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 diff --git a/source/blender/io/usd/tests/usd_tests_common.cc b/source/blender/io/usd/tests/usd_tests_common.cc new file mode 100644 index 00000000000..9f18a289433 --- /dev/null +++ b/source/blender/io/usd/tests/usd_tests_common.cc @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. All rights reserved. */ + +#include "usd_tests_common.h" + +#include "testing/testing.h" + +#include <pxr/base/plug/registry.h> + +#include "BLI_path_util.h" +#include "BLI_utildefines.h" + +#include "BKE_appdir.h" + +namespace blender::io::usd { + +std::string register_usd_plugins_for_tests() +{ + static char usd_datafiles_dir[FILE_MAX] = {'\0'}; + static bool plugin_path_registered = false; + if (plugin_path_registered) { + return usd_datafiles_dir; + } + plugin_path_registered = true; + + const std::string &release_dir = blender::tests::flags_test_release_dir(); + if (release_dir.empty()) { + return ""; + } + + const size_t path_len = BLI_path_join( + usd_datafiles_dir, FILE_MAX, release_dir.c_str(), "datafiles", "usd", nullptr); + + /* #BLI_path_join removes trailing slashes, but the USD library requires one in order to + * recognize the path as directory. */ + BLI_assert(path_len + 1 < FILE_MAX); + usd_datafiles_dir[path_len] = '/'; + usd_datafiles_dir[path_len + 1] = '\0'; + + pxr::PlugRegistry::GetInstance().RegisterPlugins(usd_datafiles_dir); + + return usd_datafiles_dir; +} + +} // namespace blender::io::usd diff --git a/source/blender/io/usd/tests/usd_tests_common.h b/source/blender/io/usd/tests/usd_tests_common.h new file mode 100644 index 00000000000..b298a253ddc --- /dev/null +++ b/source/blender/io/usd/tests/usd_tests_common.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. All rights reserved. */ +#pragma once + +#include <string> + +namespace blender::io::usd { + +/* Calls the function to load the USD plugins from the + * USD data directory under the Blender bin directory + * that was supplied as the --test-release-dir flag to ctest. + * Thus function must be called before instantiating a USD + * stage to avoid errors. The returned string is the path to + * the USD data files directory from which the plugins were + * loaded. If the USD data files directory can't be determined, + * plugin registration is skipped and the empty string is + * returned. */ +std::string register_usd_plugins_for_tests(); + +} // namespace blender::io::usd |