USD: Add tests for multiple materials assigned to single mesh

This includes tests for a "static" mesh where the materials have been
assigned and are expected to remain the same over time.

The test scenario also includes a "dynamic" mesh where both new faces
and new materials are assigned to the same mesh over time (inspired by
#118754). However, that cannot be tested right now due to missing
features of both the MeshSequenceCache and our USD IO code. No testing
will occur for that case until the features are implemented.

Pull Request: https://projects.blender.org/blender/blender/pulls/128341
This commit is contained in:
Jesse Yurkovich
2024-09-29 23:53:11 +02:00
committed by Jesse Yurkovich
parent 60acd02cf9
commit 4426526813
3 changed files with 69 additions and 1 deletions

View File

@@ -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())