MaterialXUSD 0.0.1
Utilities for using MaterialX with USD
Loading...
Searching...
No Matches
usd_mtlx_ref.py
1import sys
2import os
3from pxr import Usd, UsdShade, Sdf, UsdGeom
4#import MaterialX
5import argparse
6
7def create_material_reference(materialx_file, usda_file, geometry, flatten=False):
8 # Check if MaterialX file exists
9 if not os.path.exists(materialx_file):
10 print(f"Error: The MaterialX file '{materialx_file}' does not exist.")
11 sys.exit(1)
12
13 # Create a new USD stage (scene)
14 stage = Usd.Stage.CreateInMemory()
15
16 # Define a material in the USD stage (root location)
17 material_path = '/World/MaterialX'
18 if not flatten:
19 material_path += '/Materials'
20 #material_prim = UsdShade.Material.Define(stage, Sdf.Path(material_path))
21 material_prim = stage.DefinePrim(Sdf.Path(material_path))
22
23 # Reference the MaterialX file as the source for this material
24 # Create an SdfReference object to use in AddReference()
25 materialx_reference = Sdf.Reference(materialx_file, "/MaterialX")
26 material_prim.GetPrim().GetReferences().AddReference(materialx_reference)
27
28 stage.documentation = f"Stage referencing: {materialx_file}"
29 temp_stage = None
30 if flatten or geometry:
31 flattened_layer = stage.Flatten()
32 flattened_layer.documentation = f"Flattened stage referencing: {materialx_file}"
33 temp_stage = Usd.Stage.Open(flattened_layer)
34
35 # Set up a scene with a default sphere
36 scene_path = '/World/Scene'
37 SPHERE_PATH = '/World/Scene/Sphere'
38 if geometry:
39 scene_prim = stage.DefinePrim(Sdf.Path(scene_path), 'Xform')
40 sphere = UsdGeom.Sphere.Define(stage, SPHERE_PATH)
41 material_binding = UsdShade.MaterialBindingAPI.Apply(sphere.GetPrim())
42
43 # Iterate and find the first prim of type "Material" under the root
44 material = None
45 for child_prim in temp_stage.Traverse():
46 if child_prim.GetTypeName() == "Material":
47 material = UsdShade.Material(child_prim)
48 break
49 if material:
50 if usda_file:
51 print(f'# Bind material {material.GetPath()} to {sphere.GetPath()}')
52 # Bind in main stage
53 #print('>>>>>>>>>>>>> BIND main sphere...', sphere)
54 material_binding.Bind(material)
55 # Bind in temp stage
56 if temp_stage:
57 scene_prim = temp_stage.DefinePrim(Sdf.Path(scene_path), 'Xform')
58 sphere = UsdGeom.Sphere.Define(temp_stage, SPHERE_PATH)
59 #print('>>>>>>>>>>>>> BIND temp sphere...', sphere)
60 material_binding = UsdShade.MaterialBindingAPI.Apply(sphere.GetPrim())
61 material_binding.Bind(material)
62
63 if flatten:
64 usd_string = temp_stage.ExportToString()
65 else:
66 usd_string = stage.GetRootLayer().ExportToString()
67
68 # Save the stage as a USDA file
69 if usda_file:
70 # Save string to file
71 with open(usda_file, 'w') as f:
72 f.write(usd_string)
73 else:
74 print(usd_string)
75
76
77def main():
78 parser = argparse.ArgumentParser(description="Create a MaterialX reference in a USD file.")
79 parser.add_argument("input_materialx_file", type=str, help="The MaterialX file to reference.")
80 parser.add_argument("-o", "--output_usda_file", type=str, default=None, help="The output USD file to create.")
81 parser.add_argument("-g", "--geometry", type=str, default="_default_sphere_", help="The geometry to apply the material to.")
82 parser.add_argument("-f", "--flatten", action="store_true", help="Flatten the stage before saving.")
83 args = parser.parse_args()
84
85 materialx_file = args.input_materialx_file
86 usda_file = args.output_usda_file
87 flatten = args.flatten
88 # TODO Add geometry reference support ....
89 geometry = args.geometry
90 if geometry != "_default_sphere_":
91 geometry = ""
92 create_material_reference(materialx_file, usda_file, geometry, flatten)
93
94if __name__ == "__main__":
95 main()