From 7dae89d276d94bc71ee185fa32ccc6734a3725fa Mon Sep 17 00:00:00 2001 From: Jesse Yurkovich Date: Thu, 2 May 2024 03:57:25 +0200 Subject: [PATCH] USD: Add test to cover import of mesh attributes Adds a test to validate the import of Mesh attributes for USD. It reuses the recently added export attribute test file to generate the USD file to load. The test validates the current behavior in `main`. Missing data and bugs are noted in comments and can be addressed afterwards. Pull Request: https://projects.blender.org/blender/blender/pulls/121327 --- tests/python/bl_usd_export_test.py | 6 +-- tests/python/bl_usd_import_test.py | 62 ++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/tests/python/bl_usd_export_test.py b/tests/python/bl_usd_export_test.py index 4074106cd17..e0edc5c20c6 100644 --- a/tests/python/bl_usd_export_test.py +++ b/tests/python/bl_usd_export_test.py @@ -210,11 +210,7 @@ class USDExportTest(AbstractUSDTest): def test_export_attributes(self): bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "usd_attribute_test.blend")) export_path = self.tempdir / "usd_attribute_test.usda" - res = bpy.ops.wm.usd_export( - filepath=str(export_path), - export_materials=True, - evaluation_mode="RENDER", - ) + res = bpy.ops.wm.usd_export(filepath=str(export_path), evaluation_mode="RENDER") self.assertEqual({'FINISHED'}, res, f"Unable to export to {export_path}") stage = Usd.Stage.Open(str(export_path)) diff --git a/tests/python/bl_usd_import_test.py b/tests/python/bl_usd_import_test.py index 341e9148cde..2ca645aa2cb 100644 --- a/tests/python/bl_usd_import_test.py +++ b/tests/python/bl_usd_import_test.py @@ -675,6 +675,68 @@ class USDImportTest(AbstractUSDTest): self.assertEqual(blender_light.shape, 'DISK') self.assertAlmostEqual(blender_light.size, 2, 3) + def check_attribute(self, blender_data, attribute_name, domain, data_type, elements_len): + attr = blender_data.attributes[attribute_name] + self.assertEqual(attr.domain, domain) + self.assertEqual(attr.data_type, data_type) + self.assertEqual(len(attr.data), elements_len) + + def check_attribute_missing(self, blender_data, attribute_name): + self.assertFalse(attribute_name in blender_data.attributes) + + def test_import_attributes(self): + testfile = str(self.tempdir / "usd_attribute_test.usda") + + # Use the existing attributes file to create the USD test file + # for import. It is validated as part of the bl_usd_export test. + bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "usd_attribute_test.blend")) + res = bpy.ops.wm.usd_export(filepath=testfile, evaluation_mode="RENDER") + self.assertEqual({'FINISHED'}, res, f"Unable to export to {testfile}") + + # Reload the empty file and import back in + bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "empty.blend")) + res = bpy.ops.wm.usd_import(filepath=testfile) + self.assertEqual({'FINISHED'}, res, f"Unable to import USD file {testfile}") + + # Verify all attributes on the Mesh + # Note: USD does not support signed 8-bit types so there is + # currently no equivalent to Blender's INT8 data type + # TODO: Blender is missing support for reading USD quat/matrix data types + mesh = bpy.data.objects["Mesh"].data + + self.check_attribute(mesh, "p_bool", 'POINT', 'BOOLEAN', 4) + self.check_attribute(mesh, "p_int8", 'POINT', 'INT', 4) + self.check_attribute(mesh, "p_int32", 'POINT', 'INT', 4) + self.check_attribute(mesh, "p_float", 'POINT', 'FLOAT', 4) + self.check_attribute(mesh, "p_byte_color", 'POINT', 'FLOAT_COLOR', 4) + self.check_attribute(mesh, "p_color", 'POINT', 'FLOAT_COLOR', 4) + self.check_attribute(mesh, "p_vec2", 'CORNER', 'FLOAT2', 4) # TODO: Bug - wrong domain + self.check_attribute(mesh, "p_vec3", 'POINT', 'FLOAT_VECTOR', 4) + self.check_attribute_missing(mesh, "p_quat") + self.check_attribute_missing(mesh, "p_mat4x4") + + self.check_attribute(mesh, "f_bool", 'FACE', 'BOOLEAN', 1) + self.check_attribute(mesh, "f_int8", 'FACE', 'INT', 1) + self.check_attribute(mesh, "f_int32", 'FACE', 'INT', 1) + self.check_attribute(mesh, "f_float", 'FACE', 'FLOAT', 1) + self.check_attribute_missing(mesh, "f_byte_color") # Not supported? + self.check_attribute_missing(mesh, "f_color") # Not supported? + self.check_attribute(mesh, "f_vec2", 'FACE', 'FLOAT2', 1) + self.check_attribute(mesh, "f_vec3", 'FACE', 'FLOAT_VECTOR', 1) + self.check_attribute_missing(mesh, "f_quat") + self.check_attribute_missing(mesh, "f_mat4x4") + + self.check_attribute(mesh, "fc_bool", 'CORNER', 'BOOLEAN', 4) + self.check_attribute(mesh, "fc_int8", 'CORNER', 'INT', 4) + self.check_attribute(mesh, "fc_int32", 'CORNER', 'INT', 4) + self.check_attribute(mesh, "fc_float", 'CORNER', 'FLOAT', 4) + self.check_attribute(mesh, "fc_byte_color", 'CORNER', 'FLOAT_COLOR', 4) + self.check_attribute(mesh, "fc_color", 'CORNER', 'FLOAT_COLOR', 4) + self.check_attribute(mesh, "fc_vec2", 'CORNER', 'FLOAT2', 4) + self.check_attribute(mesh, "fc_vec3", 'CORNER', 'FLOAT_VECTOR', 4) + self.check_attribute_missing(mesh, "fc_quat") + self.check_attribute_missing(mesh, "fc_mat4x4") + def main(): global args