USD: on_material_import() and texture IO hooks
Supporting a new on_material_import() USDHook callback. Also added support for import_texture() and export_texture() utility functions which can be called from on_material_import() and on_material_export() Python implementations, respectively. Pull Request: https://projects.blender.org/blender/blender/pulls/131559
This commit is contained in:
committed by
Michael Kowalski
parent
f8b914e004
commit
74512cc5cb
@@ -1124,6 +1124,86 @@ class USDExportTest(AbstractUSDTest):
|
||||
|
||||
self.assertTupleEqual(expected, actual)
|
||||
|
||||
def test_texture_export_hook(self):
|
||||
"""Exporting textures from on_material_export USD hook."""
|
||||
|
||||
# Clear USD hook results.
|
||||
ExportTextureUSDHook.exported_textures = {}
|
||||
|
||||
bpy.utils.register_class(ExportTextureUSDHook)
|
||||
bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "usd_materials_export.blend"))
|
||||
|
||||
export_path = self.tempdir / "usd_materials_export.usda"
|
||||
|
||||
self.export_and_validate(
|
||||
filepath=str(export_path),
|
||||
export_materials=True,
|
||||
generate_preview_surface=False,
|
||||
)
|
||||
|
||||
# Verify that the exported texture paths were returned as expected.
|
||||
expected = {'/root/_materials/Transforms': './textures/test_grid_<UDIM>.png',
|
||||
'/root/_materials/Clip_With_Round': './textures/test_grid_<UDIM>.png',
|
||||
'/root/_materials/NormalMap': './textures/test_normal.exr',
|
||||
'/root/_materials/Material': './textures/test_grid_<UDIM>.png',
|
||||
'/root/_materials/Clip_With_LessThanInvert': './textures/test_grid_<UDIM>.png',
|
||||
'/root/_materials/NormalMap_Scale_Bias': './textures/test_normal_invertY.exr'}
|
||||
|
||||
self.assertDictEqual(ExportTextureUSDHook.exported_textures,
|
||||
expected,
|
||||
"Unexpected texture export paths")
|
||||
|
||||
bpy.utils.unregister_class(ExportTextureUSDHook)
|
||||
|
||||
# Verify that the texture files were copied as expected.
|
||||
tex_names = ['test_grid_1001.png', 'test_grid_1002.png',
|
||||
'test_normal.exr', 'test_normal_invertY.exr']
|
||||
|
||||
for name in tex_names:
|
||||
tex_path = self.tempdir / "textures" / name
|
||||
self.assertTrue(tex_path.exists(),
|
||||
f"Exported texture {tex_path} doesn't exist")
|
||||
|
||||
def test_inmem_pack_texture_export_hook(self):
|
||||
"""Exporting packed and in memory textures from on_material_export USD hook."""
|
||||
|
||||
# Clear hook results.
|
||||
ExportTextureUSDHook.exported_textures = {}
|
||||
|
||||
bpy.utils.register_class(ExportTextureUSDHook)
|
||||
bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "usd_materials_inmem_pack.blend"))
|
||||
|
||||
export_path = self.tempdir / "usd_materials_inmem_pack.usda"
|
||||
|
||||
self.export_and_validate(
|
||||
filepath=str(export_path),
|
||||
export_materials=True,
|
||||
generate_preview_surface=False,
|
||||
)
|
||||
|
||||
# Verify that the exported texture paths were returned as expected.
|
||||
expected = {'/root/_materials/MAT_pack_udim': './textures/test_grid_<UDIM>.png',
|
||||
'/root/_materials/MAT_pack_single': './textures/test_single.png',
|
||||
'/root/_materials/MAT_inmem_udim': './textures/inmem_udim.<UDIM>.png',
|
||||
'/root/_materials/MAT_inmem_single': './textures/inmem_single.png'}
|
||||
|
||||
self.assertDictEqual(ExportTextureUSDHook.exported_textures,
|
||||
expected,
|
||||
"Unexpected texture export paths")
|
||||
|
||||
bpy.utils.unregister_class(ExportTextureUSDHook)
|
||||
|
||||
# Verify that the texture files were copied as expected.
|
||||
tex_names = ['test_grid_1001.png', 'test_grid_1002.png',
|
||||
'test_single.png',
|
||||
'inmem_udim.1001.png', 'inmem_udim.1002.png',
|
||||
'inmem_single.png']
|
||||
|
||||
for name in tex_names:
|
||||
tex_path = self.tempdir / "textures" / name
|
||||
self.assertTrue(tex_path.exists(),
|
||||
f"Exported texture {tex_path} doesn't exist")
|
||||
|
||||
|
||||
class USDHookBase():
|
||||
instructions = {}
|
||||
@@ -1208,6 +1288,36 @@ class USDHook2(USDHookBase, bpy.types.USDHook):
|
||||
return USDHookBase.do_on_import(USDHook2.bl_label, import_context)
|
||||
|
||||
|
||||
class ExportTextureUSDHook(bpy.types.USDHook):
|
||||
bl_idname = "export_texture_usd_hook"
|
||||
bl_label = "Export Texture USD Hook"
|
||||
|
||||
exported_textures = {}
|
||||
|
||||
@staticmethod
|
||||
def on_material_export(export_context, bl_material, usd_material):
|
||||
"""
|
||||
If a texture image node exists in the given material's
|
||||
node tree, call exprt_texture() on the image and cache
|
||||
the returned path.
|
||||
"""
|
||||
tex_image_node = None
|
||||
if bl_material and bl_material.node_tree:
|
||||
for node in bl_material.node_tree.nodes:
|
||||
if node.type == 'TEX_IMAGE':
|
||||
tex_image_node = node
|
||||
|
||||
if tex_image_node is None:
|
||||
return False
|
||||
|
||||
tex_path = export_context.export_texture(tex_image_node.image)
|
||||
|
||||
ExportTextureUSDHook.exported_textures[usd_material.GetPath()
|
||||
.pathString] = tex_path
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
global args
|
||||
import argparse
|
||||
|
||||
Reference in New Issue
Block a user