[Bf-blender-cvs] [fa57c691f66] master: USD IO CI Tests
Michael Kowalski
noreply at git.blender.org
Wed Jan 25 20:52:23 CET 2023
Commit: fa57c691f663bf4b446ccf0f91ce82ed9a2078b2
Author: Michael Kowalski
Date: Wed Jan 25 14:51:39 2023 -0500
Branches: master
https://developer.blender.org/rBfa57c691f663bf4b446ccf0f91ce82ed9a2078b2
USD IO CI Tests
Various new CI tests for USD Import / Export functionalty:
Import:
- Added mesh import tests for topology types and multiple UV sets. (Python)
Export:
- Added a verification tests for mesh topology. (C++)
- Added a test to make sure UsdPreviewSurface export conversion of materials
is correct. (C++)
Reviewed by: Sybren and Hans.
Differential Revision: https://developer.blender.org/D16274
===================================================================
M source/blender/blenloader/tests/blendfile_loading_base_test.cc
M source/blender/io/usd/CMakeLists.txt
M source/blender/io/usd/intern/usd_capi_export.cc
M source/blender/io/usd/intern/usd_capi_import.cc
M source/blender/io/usd/intern/usd_writer_material.cc
M source/blender/io/usd/intern/usd_writer_material.h
A source/blender/io/usd/tests/usd_export_test.cc
M tests/python/bl_usd_import_test.py
===================================================================
diff --git a/source/blender/blenloader/tests/blendfile_loading_base_test.cc b/source/blender/blenloader/tests/blendfile_loading_base_test.cc
index 6f190ce427e..6613c65c42a 100644
--- a/source/blender/blenloader/tests/blendfile_loading_base_test.cc
+++ b/source/blender/blenloader/tests/blendfile_loading_base_test.cc
@@ -103,8 +103,8 @@ void BlendfileLoadingBaseTest::TearDownTestCase()
void BlendfileLoadingBaseTest::TearDown()
{
BKE_mball_cubeTable_free();
- depsgraph_free();
blendfile_free();
+ depsgraph_free();
testing::Test::TearDown();
}
diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt
index ebd292782c0..862bd41c087 100644
--- a/source/blender/io/usd/CMakeLists.txt
+++ b/source/blender/io/usd/CMakeLists.txt
@@ -163,13 +163,18 @@ target_link_libraries(bf_usd INTERFACE ${TBB_LIBRARIES})
if(WITH_GTESTS)
set(TEST_SRC
tests/usd_stage_creation_test.cc
+ tests/usd_export_test.cc
tests/usd_tests_common.cc
tests/usd_tests_common.h
+
+ intern/usd_writer_material.h
)
if(USD_IMAGING_HEADERS)
list(APPEND TEST_SRC tests/usd_imaging_test.cc)
endif()
+ include_directories(intern)
+
set(TEST_INC
)
set(TEST_LIB
diff --git a/source/blender/io/usd/intern/usd_capi_export.cc b/source/blender/io/usd/intern/usd_capi_export.cc
index 28da9e388c5..1d33ca3a13c 100644
--- a/source/blender/io/usd/intern/usd_capi_export.cc
+++ b/source/blender/io/usd/intern/usd_capi_export.cc
@@ -66,7 +66,9 @@ static void export_startjob(void *customdata,
data->start_time = timeit::Clock::now();
G.is_rendering = true;
- WM_set_locked_interface(data->wm, true);
+ if (data->wm) {
+ WM_set_locked_interface(data->wm, true);
+ }
G.is_break = false;
/* Construct the depsgraph for exporting. */
@@ -160,7 +162,9 @@ static void export_endjob(void *customdata)
}
G.is_rendering = false;
- WM_set_locked_interface(data->wm, false);
+ if (data->wm) {
+ WM_set_locked_interface(data->wm, false);
+ }
report_job_duration(data);
}
diff --git a/source/blender/io/usd/intern/usd_capi_import.cc b/source/blender/io/usd/intern/usd_capi_import.cc
index 66319a7f04e..fb870eb154c 100644
--- a/source/blender/io/usd/intern/usd_capi_import.cc
+++ b/source/blender/io/usd/intern/usd_capi_import.cc
@@ -207,6 +207,7 @@ static void import_startjob(void *customdata, bool *stop, bool *do_update, float
if (!stage) {
WM_reportf(RPT_ERROR, "USD Import: unable to open stage to read %s", data->filepath);
data->import_ok = false;
+ data->error_code = USD_ARCHIVE_FAIL;
return;
}
diff --git a/source/blender/io/usd/intern/usd_writer_material.cc b/source/blender/io/usd/intern/usd_writer_material.cc
index 98cd4036fd0..7e744b74f61 100644
--- a/source/blender/io/usd/intern/usd_writer_material.cc
+++ b/source/blender/io/usd/intern/usd_writer_material.cc
@@ -748,4 +748,16 @@ static void export_texture(bNode *node,
}
}
+const pxr::TfToken token_for_input(const char *input_name)
+{
+ const InputSpecMap &input_map = preview_surface_input_map();
+ const InputSpecMap::const_iterator it = input_map.find(input_name);
+
+ if (it == input_map.end()) {
+ return pxr::TfToken();
+ }
+
+ return it->second.input_name;
+}
+
} // namespace blender::io::usd
diff --git a/source/blender/io/usd/intern/usd_writer_material.h b/source/blender/io/usd/intern/usd_writer_material.h
index fdfd13871ff..c6123b3cce2 100644
--- a/source/blender/io/usd/intern/usd_writer_material.h
+++ b/source/blender/io/usd/intern/usd_writer_material.h
@@ -14,6 +14,10 @@ namespace blender::io::usd {
struct USDExporterContext;
+/* Returns a USDPreviewSurface token name for a given Blender shader Socket name,
+ * or an empty TfToken if the input name is not found in the map. */
+const pxr::TfToken token_for_input(const char *input_name);
+
/**
* Entry point to create an approximate USD Preview Surface network from a Cycles node graph.
* Due to the limited nodes in the USD Preview Surface specification, only the following nodes
diff --git a/source/blender/io/usd/tests/usd_export_test.cc b/source/blender/io/usd/tests/usd_export_test.cc
new file mode 100644
index 00000000000..c13da695c87
--- /dev/null
+++ b/source/blender/io/usd/tests/usd_export_test.cc
@@ -0,0 +1,314 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "testing/testing.h"
+#include "tests/blendfile_loading_base_test.h"
+
+#include <pxr/base/plug/registry.h>
+#include <pxr/base/tf/stringUtils.h>
+#include <pxr/base/vt/types.h>
+#include <pxr/base/vt/value.h>
+#include <pxr/usd/sdf/types.h>
+#include <pxr/usd/usd/prim.h>
+#include <pxr/usd/usd/stage.h>
+#include <pxr/usd/usdGeom/mesh.h>
+#include <pxr/usd/usdGeom/subset.h>
+#include <pxr/usd/usdGeom/tokens.h>
+
+#include "DNA_image_types.h"
+#include "DNA_material_types.h"
+#include "DNA_node_types.h"
+
+#include "BKE_context.h"
+#include "BKE_lib_id.h"
+#include "BKE_main.h"
+#include "BKE_mesh.h"
+#include "BKE_node.h"
+#include "BLI_fileops.h"
+#include "BLI_math.h"
+#include "BLI_path_util.h"
+#include "BLI_math_vector_types.hh"
+#include "BLO_readfile.h"
+
+#include "BKE_node_runtime.hh"
+
+#include "DEG_depsgraph.h"
+
+#include "WM_api.h"
+
+#include "usd.h"
+#include "usd_tests_common.h"
+#include "usd_writer_material.h"
+
+namespace blender::io::usd {
+
+const StringRefNull simple_scene_filename = "usd/usd_simple_scene.blend";
+const StringRefNull materials_filename = "usd/usd_materials_export.blend";
+const StringRefNull output_filename = "output.usd";
+
+
+static const bNode *find_node_for_type_in_graph(const bNodeTree *nodetree,
+ const blender::StringRefNull type_idname);
+
+
+class UsdExportTest : public BlendfileLoadingBaseTest {
+ protected:
+ struct bContext *context = nullptr;
+
+ public:
+ bool load_file_and_depsgraph(const StringRefNull &filepath,
+ const eEvaluationMode eval_mode = DAG_EVAL_VIEWPORT)
+ {
+ if (!blendfile_load(filepath.c_str())) {
+ return false;
+ }
+ depsgraph_create(eval_mode);
+
+ context = CTX_create();
+ CTX_data_main_set(context, bfile->main);
+ CTX_data_scene_set(context, bfile->curscene);
+
+ return true;
+ }
+
+ virtual void SetUp() override
+ {
+ BlendfileLoadingBaseTest::SetUp();
+ std::string usd_plugin_path = register_usd_plugins_for_tests();
+ if (usd_plugin_path.empty()) {
+ FAIL() << "Unable to find the USD Plugins path.";
+ }
+ }
+
+ virtual void TearDown() override
+ {
+ BlendfileLoadingBaseTest::TearDown();
+ CTX_free(context);
+ context = nullptr;
+
+ if (BLI_exists(output_filename.c_str())) {
+ BLI_delete(output_filename.c_str(), false, false);
+ }
+ }
+
+ const pxr::UsdPrim get_first_child_mesh(const pxr::UsdPrim prim)
+ {
+ for (auto child : prim.GetChildren()) {
+ if (child.IsA<pxr::UsdGeomMesh>()) {
+ return child;
+ }
+ }
+ return pxr::UsdPrim();
+ }
+
+ /*
+ * Loop the sockets on the Blender bNode, and fail if any of their values do
+ * not match the equivalent Attribtue values on the UsdPrim.
+ */
+ const void compare_blender_node_to_usd_prim(const bNode *bsdf_node, const pxr::UsdPrim& bsdf_prim) {
+ ASSERT_NE(bsdf_node, nullptr);
+ ASSERT_TRUE(bool(bsdf_prim));
+
+ for (auto socket : bsdf_node->input_sockets()) {
+ const pxr::TfToken attribute_token = blender::io::usd::token_for_input(socket->name);
+ if (attribute_token.IsEmpty()) {
+ /* This socket is not translated between Blender and USD. */
+ continue;
+ }
+
+ const pxr::UsdAttribute bsdf_attribute = bsdf_prim.GetAttribute(attribute_token);
+ pxr::SdfPathVector paths;
+ bsdf_attribute.GetConnections(&paths);
+ if (!paths.empty() || !bsdf_attribute.IsValid()) {
+ /* Skip if the attribute is connected or has an error. */
+ continue;
+ }
+
+ const float socket_value_f = *socket->default_value_typed<float>();
+ const float3 socket_value_3f = *socket->default_value_typed<float3>();
+ float attribute_value_f;
+ pxr::GfVec3f attribute_value_3f;
+
+ switch (socket->type) {
+ case SOCK_FLOAT:
+ bsdf_attribute.Get(&attribute_value_f, 0.0);
+ EXPECT_FLOAT_EQ(socket_value_f, attribute_value_f);
+ break;
+
+ case SOCK_VECTOR:
+ bsdf_attribute.Get(&attribute_value_3f, 0.0);
+ EXPECT_FLOAT_EQ(socket_value_3f[0], attribute_value_3f[0]);
+ EXPECT_FLOAT_EQ(socket_value_3f[1], attribute_value_3f[1]);
+ EXPECT_FLOAT_EQ(socket_value_3f[2], attribute_value_3f[2]);
+ break;
+
+ case SOCK_RGBA:
+ bsdf_attribute.Get(&attribute_value_3f, 0.0);
+ EXPECT_FLOAT_EQ(socket_value_3f[0], attribute_value_3f[0]);
+ EXPECT_FLOAT_EQ(socket_value_3f[1], attribute_value_3f[1]);
+ EXPECT_FLOAT_EQ(socket_value_3f[2], attribute_value_3f[2]);
+ break;
+
+ default:
+ FAIL() << "Socket " << socket->name << " has unsupported type " << socket->type;
+ break;
+ }
+ }
+ }
+
+ const void compare_blender_image_to_usd_image_shader(const bNode *image_node, const pxr::UsdPrim& image_prim) {
+ const Image *image = reinterpret_cast<Image *>(image_node->id);
+
+ const pxr::UsdShadeShader image_shader(image_prim);
+ const pxr::UsdShadeInput file_input = image_shader.GetInput(pxr::TfToken("file"));
+ EXPECT_TRUE(bool(file_input));
+
+ pxr::VtValue file_val;
+ EXPECT_TRUE(file_input.Get(&file_val));
+ EXPECT_TRUE(file_val.IsHolding<pxr::SdfAssetPath>());
+
+ pxr::SdfAssetPath image_prim_asset = file_val.Get<pxr::SdfAssetPath>();
+
+ /* The path is expected to be relative, but that means in Blender the
+ * path will start with //.
+ */
+ EXPECT_EQ(BLI_path_cmp_normalized(image->filepath+2, image_prim_asset.GetAssetPath().c_str()), 0);
+ }
+
+ /*
+ * Determine if a Blender Mesh matches a UsdGeomMesh prim by checking counts
+ * on vertices, faces, face indices, and normals.
+ */
+ const void compare_blender_mesh_to_usd_prim(const Mesh *mesh, const pxr::UsdGeomMesh& mesh_prim) {
+ pxr::VtIntArray face_indices;
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list