MaterialXglTF 1.39.0.1
Loading...
Searching...
No Matches
mtlx2gltf.py
1#!/usr/bin/env python
2'''
3Utility and command line interface to convert from a MaterialX file to a glTF file
4'''
5import os
6import argparse
7
8from core import *
9
10def mtlx2gltf(materialXFileName, gltfOutputFileName, options=MTLX2GLTFOptions()):
11 '''
12 Utility to convert a MaterialX file to glTF file
13 @param materialXFileName Path to MaterialX file to convert
14 @param gltfOutputFileName Path to glTF file to write
15 @param options Options for conversion
16 '''
17 mtlx2glTFWriter = MTLX2GLTFWriter()
18 doc, libFiles = Util.createMaterialXDoc()
19 if libFiles:
20 print('- Loaded %d library files.' % len(libFiles))
21 else:
22 print('- No library files loaded.')
23 mx.readFromXmlFile(doc, materialXFileName, options['searchPath'])
24
25 mtlx2glTFWriter.setOptions(options)
26
27 # Perform shader translation and baking if necessary
28 if options['translateShaders']:
29 translatedCount = mtlx2glTFWriter.translateShaders(doc)
30 print('- Translated %d shaders.' % translatedCount)
31 if options['bakeTextures']:
32 print('- Baking start {')
33 materialXFileName = materialXFileName + '_baked.mtlx'
34 bakeResolution = 256
35 if options['bakeResolution']:
36 bakeResolution = options['bakeResolution']
37 mtlx2glTFWriter.bakeTextures(doc, False, bakeResolution, bakeResolution, False,
38 False, False, materialXFileName)
39 print(' - Baked textures to: ', materialXFileName)
40 doc, libFiles = Util.createMaterialXDoc()
41 mx.readFromXmlFile(doc, materialXFileName, options['searchPath'])
42 remappedUris = Util.makeFilePathsRelative(doc, materialXFileName)
43 for uri in remappedUris:
44 print(' - Remapped URI: %s to %s' % (uri[0], uri[1]))
45 Util.writeMaterialXDoc(doc, materialXFileName)
46 print('- Baking end.')
47
48 gltfString = mtlx2glTFWriter.convert(doc)
49 if len(gltfString) > 0:
50 print('> Write glTF to: ', gltfOutputFileName)
51 f = open(gltfOutputFileName, 'w')
52 f.write(gltfString)
53 f.close()
54 else:
55 return False, mtlx2glTFWriter.getLog()
56
57 if options['packageBinary']:
58 binaryFileName = str(gltfOutputFileName)
59 binaryFileName = binaryFileName.replace('.gltf', '.glb')
60 print('- Packaging GLB file...')
61 saved, images, buffers = mtlx2glTFWriter.packageGLTF(gltfOutputFileName, binaryFileName)
62 print('- Save GLB file:' + binaryFileName + '. Status:' + str(saved))
63 for image in images:
64 print(' - Embedded image: %s' % image)
65 for buffer in buffers:
66 print(' - Embedded buffer: %s' % buffer)
67
68 return True, ''
69
70def main():
71 '''
72 Command line utility to convert a MaterialX file to a glTF file
73 '''
74 parser = argparse.ArgumentParser(description='Utility to convert a MaterialX file to a glTF file')
75 parser.add_argument(dest='mtlxFileName', help='Path containing MaterialX file to convert.')
76 parser.add_argument('--gltfFileName', dest='gltfFileName', default='', help='Name of MaterialX output file. If not specified the glTF name with "_tomtlx.mtlx" suffix will be used')
77 parser.add_argument('--gltfGeomFileName', dest='gltfGeomFileName', default='', help='Name of MaterialX output file. If not specified the glTF name with "_tomtlx.mtlx" suffix will be used')
78 parser.add_argument('--primsPerMaterial', dest='primsPerMaterial', type=mx.stringToBoolean, default=False, help='Create a new primitive per material and assign the material. Default is False')
79 parser.add_argument('--packageBinary', dest='packageBinary', type=mx.stringToBoolean, default=False, help='Create a biary packaged GLB file. Default is False')
80 parser.add_argument('--translateShaders', dest='translateShaders', type=mx.stringToBoolean, default=False, help='Translate shaders to glTF. Default is False')
81 parser.add_argument('--bakeTextures', dest='bakeTextures', type=mx.stringToBoolean, default=False, help='Bake pattern graphs as textures. Default is False')
82 parser.add_argument('--bakeResolution', dest='bakeResolution', type=int, default=256, help='Bake image resolution. Default is 256')
83 parser.add_argument('--writeDefaultInputs', dest='writeDefaultInputs', type=mx.stringToBoolean, default=False, help='Write default inputs on shader nodes. Default is False')
84
85 opts = parser.parse_args()
86
87 # Check input glTF file
88 mtlxFileName = opts.mtlxFileName
89 if not os.path.exists(mtlxFileName):
90 print('Cannot find input file: ', mtlxFileName)
91 exit(-1)
92
93 # If a folder is specified then collect all MaterialX files in the folder
94 mtlxFiles = []
95 ignoreGltfFileName = False
96 if mx.FilePath(mtlxFileName).isDirectory():
97 for file in os.listdir(mtlxFileName):
98 if file.endswith('.mtlx'):
99 mtlxFiles.append(os.path.join(mtlxFileName, file))
100 if len(mtlxFiles) == 0:
101 print('No MaterialX files found in folder: ', mtlxFileName)
102 exit(-1)
103 ignoreGltfFileName = True
104 else:
105 mtlxFiles.append(mtlxFileName)
106
107 for mtlxFileName in mtlxFiles:
108 if len(mtlxFiles) > 1:
109 print('*** Converting MaterialX file:', mtlxFileName)
110
111 # Set up MTLX file name
112 gltfFileName = mtlxFileName + '.gltf'
113 if not ignoreGltfFileName and len(opts.gltfFileName) > 0:
114 gltfFileName = opts.gltfFileName
115
116 # Perform conversion
117 options = MTLX2GLTFOptions()
118 options['primsPerMaterial'] = opts.primsPerMaterial
119 options['packageBinary'] = opts.packageBinary
120 gltfGeomFileName = opts.gltfGeomFileName
121 if len(gltfGeomFileName) > 0:
122 if not mx.FilePath(gltfGeomFileName).isAbsolute():
123 gltfGeomFileName = os.path.abspath(gltfGeomFileName)
124 options['geometryFile'] = opts.gltfGeomFileName
125 options['translateShaders'] = opts.translateShaders
126 options['bakeTextures'] = opts.bakeTextures
127 options['bakeResolution'] = opts.bakeResolution
128 options['writeDefaultInputs'] = opts.writeDefaultInputs
129
130 # Set search path to default library path as well as folder containing MaterialX file
131 # and current path
132 searchPath = mx.getDefaultDataSearchPath()
133 if not mx.FilePath(mtlxFileName).isAbsolute():
134 mtlxFileName = os.path.abspath(mtlxFileName)
135 searchPath.append(mx.FilePath(mtlxFileName).getParentPath())
136 searchPath.append(mx.FilePath.getCurrentPath())
137 searchPath.append(mx.FilePath(gltfGeomFileName).getParentPath())
138 options['searchPath'] = searchPath
139
140 print("- Search path set to:", searchPath.asString())
141 converted, err = mtlx2gltf(mtlxFileName, gltfFileName, options)
142 print('Converted MaterialX file %s to gltf file: %s. Status: %s.' % (mtlxFileName, gltfFileName, converted))
143 if not converted:
144 print('- Error: ', err)
145
146if __name__ == "__main__":
147 main()
Class to hold options for MaterialX to glTF conversion.
Definition core.py:1114
Class to read in a MaterialX document and write to a glTF document.
Definition core.py:1146
main()
Command line utility to convert a MaterialX file to a glTF file.
Definition mtlx2gltf.py:70