diff --git a/tests/data b/tests/data index 0ff59eafc76..46d451fcb7d 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit 0ff59eafc7658787b55db167b4157e7eed40bc6c +Subproject commit 46d451fcb7d6a7fca7c612c1658afb1836b79d5a diff --git a/tests/python/bl_usd_export_test.py b/tests/python/bl_usd_export_test.py index 59d44561fce..057a0ea3280 100644 --- a/tests/python/bl_usd_export_test.py +++ b/tests/python/bl_usd_export_test.py @@ -221,6 +221,43 @@ class USDExportTest(AbstractUSDTest): self.assertEqual(opacity_input.HasConnectedSource(), True, "Alpha input should be connected") self.assertAlmostEqual(opacity_thresh_input.Get(), 0.2, 2, "Opacity threshold input should be 0.2") + def test_export_material_subsets(self): + """Validate multiple materials assigned to the same mesh work correctly.""" + + bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "usd_materials_multi.blend")) + + # Ensure the simulation zone data is baked for all relevant frames... + for frame in range(1, 5): + bpy.context.scene.frame_set(frame) + bpy.context.scene.frame_set(1) + + export_path = self.tempdir / "usd_materials_multi.usda" + res = bpy.ops.wm.usd_export(filepath=str(export_path), export_animation=True, evaluation_mode="RENDER") + self.assertEqual({'FINISHED'}, res, f"Unable to export to {export_path}") + + stage = Usd.Stage.Open(str(export_path)) + + # The static mesh should have 4 materials each assigned to 4 faces (16 faces total) + static_mesh_prim = UsdGeom.Mesh(stage.GetPrimAtPath("/root/static_mesh/static_mesh")) + geom_subsets = UsdGeom.Subset.GetGeomSubsets(static_mesh_prim) + self.assertEqual(len(geom_subsets), 4) + + unique_face_indices = set() + for subset in geom_subsets: + face_indices = subset.GetIndicesAttr().Get() + self.assertEqual(len(face_indices), 4) + unique_face_indices.update(face_indices) + self.assertEqual(len(unique_face_indices), 16) + + # The dynamic mesh varies over time (currently blocked, see #124554 and #118754) + # - Frame 1: 1 face and 1 material [mat2] + # - Frame 2: 2 faces and 2 materials [mat2, mat3] + # - Frame 3: 4 faces and 3 materials [mat2, mat3, mat2, mat1] + # - Frame 4: 4 faces and 2 materials [mat2, mat3, mat2, mat3] + dynamic_mesh_prim = UsdGeom.Mesh(stage.GetPrimAtPath("/root/dynamic_mesh/dynamic_mesh")) + geom_subsets = UsdGeom.Subset.GetGeomSubsets(dynamic_mesh_prim) + self.assertEqual(len(geom_subsets), 0) + def check_primvar(self, prim, pv_name, pv_typeName, pv_interp, elements_len): pv = UsdGeom.PrimvarsAPI(prim).GetPrimvar(pv_name) self.assertTrue(pv.HasValue()) diff --git a/tests/python/bl_usd_import_test.py b/tests/python/bl_usd_import_test.py index b20adafe440..fa2c0e021c8 100644 --- a/tests/python/bl_usd_import_test.py +++ b/tests/python/bl_usd_import_test.py @@ -264,6 +264,37 @@ class USDImportTest(AbstractUSDTest): self.assertEqual(self.round_vector(node.inputs[1].default_value), [2, -2, 2]) self.assertEqual(self.round_vector(node.inputs[2].default_value), [-1, 1, -1]) + def test_import_material_subsets(self): + """Validate multiple materials assigned to the same mesh work correctly.""" + + # Use the existing materials test file to create the USD file + # for import. It is validated as part of the bl_usd_export test. + bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "usd_materials_multi.blend")) + # Ensure the simulation zone data is baked for all relevant frames... + for frame in range(1, 5): + bpy.context.scene.frame_set(frame) + bpy.context.scene.frame_set(1) + + testfile = str(self.tempdir / "usd_materials_multi.usda") + res = bpy.ops.wm.usd_export(filepath=testfile, export_animation=True, 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}") + + # The static mesh should have 4 materials each assigned to 4 faces (16 faces total) + static_mesh = bpy.data.objects["static_mesh"].data + material_index_attr = static_mesh.attributes["material_index"] + self.assertEqual(len(static_mesh.materials), 4) + self.assertEqual(len(static_mesh.polygons), 16) + self.assertEqual(len(material_index_attr.data), 16) + + for mat_index in range(0, 4): + face_indices = [i for i, d in enumerate(material_index_attr.data) if d.value == mat_index] + self.assertEqual(len(face_indices), 4, f"Incorrect number of faces with material index {mat_index}") + def test_import_shader_varname_with_connection(self): """Test importing USD shader where uv primvar is a connection"""