MaterialXUSD 0.0.1
Utilities for using MaterialX with USD
Loading...
Searching...
No Matches
preprocess_mtlx.py
1# brief Script to prepare a MaterialX document fo conversion to USD
2# usage: python3 prepare_materialx_for_usd.py <input_materialx_file> <output_materialx_file>
3try:
4 import MaterialX as mx
5except ImportError:
6 print('MaterialX package not available. Please install MaterialX to use this utility.')
7 sys.exit(1)
8import sys
9import os
10import argparse
11import logging
12from materialxusd_utils import MaterialXUsdUtilities
13
14def main():
15 parser = argparse.ArgumentParser(description='Prepare a MaterialX document for conversion to USD')
16 parser.add_argument('input', type=str, help='Input MaterialX document')
17 parser.add_argument('-o', '--output', type=str, default='', help='Output MaterialX document. Default is input name with "_converted" appended.')
18 parser.add_argument('-ng', '--nodegraph', type=str, default='root_graph', help='Name of the new nodegraph to encapsulate the top level nodes. Default is "top_level_nodes"')
19 parser.add_argument('-k', '--keep', action='store_true', help='Keep the original top level nodes from the document. Default is True')
20 parser.add_argument('-v', '--verbose', action='store_true', help='Print verbose output')
21 parser.add_argument("-ip", "--imagepaths", default="", help="Comma separated list of search paths for image path resolving. ")
22 args = parser.parse_args()
23
24 logging.basicConfig(level=logging.INFO)
25 logger = logging.getLogger('prep_mtlx')
26
27 input_path = args.input
28 if not os.path.exists(input_path):
29 logger.info(f"Input file {input_path} does not exist.")
30 sys.exit(1)
31
32 output_path = args.output
33 if not output_path:
34 output_path = input_path.replace('.mtlx', '_converted.mtlx')
35
36 utils = MaterialXUsdUtilities()
37 doc = utils.create_document(input_path)
38
39 nodegraph_name = args.nodegraph
40 remove_original_nodes = not args.keep
41 try:
42 top_level_nodes_found = utils.encapsulate_top_level_nodes(doc, nodegraph_name, remove_original_nodes)
43 if top_level_nodes_found > 0:
44 logger.info(f"> Encapsulated {top_level_nodes_found} top level nodes.")
45
46 # Make implicit geometry streams explicit
47 doc.setDataLibrary(utils.get_standard_libraries())
48 implicit_nodes_added = utils.add_explicit_geometry_stream(doc)
49 if implicit_nodes_added > 0:
50 logger.info(f"> Added {implicit_nodes_added} implicit geometry nodes.")
51
52 materials_added = utils.add_downstream_materials(doc)
53 materials_added += utils.add_materials_for_shaders(doc)
54 if materials_added:
55 logger.info(f'> Added {materials_added} downstream materials.')
56 doc.setDataLibrary(None)
57
58 # Add explicit outputs to nodegraph outputs for shader connections
59 explicit_outputs_added = utils.add_nodegraph_output_qualifier_on_shaders(doc)
60 if explicit_outputs_added:
61 logger.info(f"> Added {explicit_outputs_added} explicit outputs to nodegraph outputs for shader connections")
62
63 # Resolve image file paths
64 # Include absolute path of the input file's folder
65 resolved_image_paths = False
66 image_paths = args.imagepaths.split(',') if args.imagepaths else []
67 image_paths.append(os.path.dirname(os.path.abspath(input_path)))
68 if image_paths:
69 beforeDoc = mx.prettyPrint(doc)
70 mx_image_search_path = utils.create_FileSearchPath(image_paths)
71 utils.resolve_image_file_paths(doc, mx_image_search_path)
72 afterDoc = mx.prettyPrint(doc)
73 if beforeDoc != afterDoc:
74 resolved_image_paths = True
75 logger.info(f"> Resolved image file paths using search paths: {mx_image_search_path.asString()}")
76 resolved_image_paths = True
77
78 if explicit_outputs_added or resolved_image_paths or materials_added> 0 or implicit_nodes_added > 0 or top_level_nodes_found > 0:
79 utils.write_document(doc, output_path)
80 logger.info(f"> Wrote modified document to {output_path}")
81 except Exception as e:
82 logger.error(f"> Failed to preprocess document. Error: {e}")
83
84if __name__ == '__main__':
85 main()
86
87
88