7from flask
import Flask, render_template
8from flask_socketio
import SocketIO, emit
15 from usdmtlx
import convertMtlxToUsd
16 have_usd_converter =
True
18 print(
'Cannot import usdmtlx')
19 have_usd_converter =
False
23 from gltf_materialx_converter
import converter
as MxGLTFPT
24 from gltf_materialx_converter
import utilities
as MxGLTFPTUtil
25 have_gltf_converter =
True
27 print(
'Cannot import gltf_materialx_converter')
28 have_gltf_converter =
False
32 'os': platform.system(),
33 'release': platform.release(),
34 'architecture': platform.machine()
38 def __init__(self, home):
42 self.
app = Flask(__name__)
51 print(f
'* Initialized on deployment plaform: {self.deployment_platform}')
53 print(f
" * OS: {self.os_details['os']}")
54 print(f
" * Release: {self.os_details['release']}")
55 print(f
" * Architecture: {self.os_details['architecture']}")
68 return render_template(self.
home)
71 '''Pure virtual method: Must be implemented by subclasses.'''
72 raise NotImplementedError(
"Subclasses must implement _setup_event_handler_map")
76 Register SocketIO events.
79 for event_name, handler
in self.event_handlers.items():
80 self.
socketio.on_event(event_name, handler)
82 def run(self, host, port, deployment_platform, debug=True):
84 Run the Flask server with SocketIO.
100 Set up dictionary of mapping event names to their handlers
116 Handle page load / startup feedback
118 status =
'> Using MaterialX version: ' + mx.getVersionString()
119 emit(
'materialx_version', {
'status': status}, broadcast=
True)
123 Handle loading in of MaterialX document
125 materialx_file = data.get(
'materialxFile',
'Default MaterialX File')
126 print(
'> Server: load materialx event received. File:', materialx_file)
127 materialx_content = data.get(
'content',
'MaterialX content')
128 doc = mx.createDocument()
129 if len(materialx_content) == 0:
131 mx.readFromXmlString(doc, materialx_content)
132 print(
'>> MaterialX Document loaded')
133 doc_string = mx.writeToXmlString(doc)
134 emit(
'materialx_loaded', {
'materialxDocument': doc_string}, broadcast=
True)
138 Handle request to render MaterialX document
140 materialx_string = data.get(
'materialxDocument',
'MaterialX content')
141 print(
'> Server: render_materialx event received')
144 ilm_viewer = os.getenv(
'MATERIALX_DEFAULT_VIEWER',
'')
145 if len(ilm_viewer) == 0:
146 print(
'>> MATERIALX_DEFAULT_VIEWER environment variable not set')
149 doc = mx.createDocument()
150 if len(materialx_string) == 0:
153 stdlib = mx.createDocument()
154 mx.loadLibraries(mx.getDefaultDataLibraryFolders(), mx.getDefaultDataSearchPath(), stdlib)
155 doc.importLibrary(stdlib)
156 mx.readFromXmlString(doc, materialx_string)
159 temp_location = os.getenv(
'TEMP',
'/tmp')
160 if not os.path.exists(temp_location):
161 temp_location =
'/tmp'
163 temp_name = datetime.datetime.now().strftime(
'%Y%m%d%H%M%S') +
'.mtlx'
164 temp_file = f
'{temp_location}/{temp_name}'
165 mx.writeToXmlFile(doc, temp_file)
166 capture_filename = temp_file.replace(
".mtlx",
".png")
167 cmd = f
'{ilm_viewer} --screenWidth 512 --screenHeight 512 '
168 cmd += f
' --captureFilename {capture_filename} --material {temp_file}'
169 print(
'>> Rendering:', cmd)
175 os.remove(capture_filename)
176 print(
'>> Emit materialx_rendered event')
177 emit(
'materialx_rendered', {
'image': image_base64}, broadcast=
True)
181 Handle request to convert MaterialX to USD
183 if not have_usd_converter:
184 emit(
'usd_converted', {
'usdDocument':
''}, broadcast=
True)
187 materialx_string = data.get(
'materialxDocument',
'')
188 print(
'> Server: convert-to-usd event received')
189 doc = mx.createDocument()
190 if len(materialx_string) == 0:
193 mx.readFromXmlString(doc, materialx_string)
194 print(
'>> MaterialX document loaded')
195 stage_string = convertMtlxToUsd(doc,
True)
196 print(
'>> USD stage created.')
197 emit(
'usd_converted', {
'usdDocument': stage_string}, broadcast=
True)
198 except Exception
as e:
199 print(f
'>> Error during USD conversion: {e}')
200 emit(
'usd_converted', {
'usdDocument':
''}, broadcast=
True)
204 Handle request to convert MaterialX to glTF Texture Procedural
207 if not have_gltf_converter:
208 emit(
'gltf_converted', {
'document':
'{}'}, broadcast=
True)
211 materialx_string = data.get(
'materialxDocument',
'')
212 print(
'> Server: convert_to_glTF event received')
213 stdlib, _ = MxGLTFPTUtil.load_standard_libraries()
214 doc = MxGLTFPTUtil.create_working_document([stdlib])
215 if len(materialx_string) == 0:
217 mx.readFromXmlString(doc, materialx_string)
218 print(
'>> MaterialX document loaded')
219 converter = MxGLTFPT.glTFMaterialXConverter()
220 json_string, status = converter.materialX_to_glTF(doc)
222 print(
'>> Error converting to glTF:', status)
224 print(
'>> glTF JSON created:')
225 emit(
'gltf_converted', {
'document': json_string}, broadcast=
True)
229 Handle query to see if glTF converter is available
231 emit(
'have_gltf_converter', {
'have_gltf_converter': have_gltf_converter}, broadcast=
True)
236 Utility to load in png image from disk and return Base64
239 with open(file_path,
"rb")
as image_file:
240 binary_data = image_file.read()
241 return base64.b64encode(binary_data).decode(
'utf-8')
243def deployment_platform():
246 if os.environ.get(
'RENDER_SERVICE_ID'):
248 elif os.environ.get(
'HEROKU'):
250 elif os.environ.get(
'AWS_EXECUTION_ENV'):
258 Main command line interface
260 parser = argparse.ArgumentParser(description=
"GPUOpen MaterialX Application")
261 parser.add_argument(
'--host', type=str, default=
'127.0.0.1', help=
"Host address to run the server on (default: 127.0.0.1)")
262 parser.add_argument(
'--port', type=int, default=
None, help=
"Port to run the server on (default: 8000)")
263 parser.add_argument(
'--home', type=str, default=
'MaterialXConversionApp.html', help=
"Home page.")
265 args = parser.parse_args()
268 deploy_platform = deployment_platform()
269 if deployment_platform() ==
"Render":
274 app_port = int(os.environ.get(
'PORT', 8080))
275 if args.port
is not None:
279 app.run(host=app_host, port=app_port, deployment_platform=deployment_platform)
281if __name__ ==
"__main__":
handle_convert_to_glTF(self, data)
Handle request to convert MaterialX to glTF Texture Procedural graph.
_setup_event_handler_map(self)
Set up dictionary of mapping event names to their handlers.
handle_page_loaded(self, data)
Handle page load / startup feedback.
handle_load_materialx(self, data)
Handle loading in of MaterialX document.
__init__(self, homePage)
Constructor.
handle_convert_to_usd(self, data)
Handle request to convert MaterialX to USD.
handle_render_materialx(self, data)
Handle request to render MaterialX document.
convert_png_to_base64(file_path)
Utility to load in png image from disk and return Base64 representation.
handle_have_gltf_converter(self)
Handle query to see if glTF converter is available.
_setup_event_handler_map(self)
Pure virtual method: Must be implemented by subclasses.
run(self, host, port, deployment_platform, debug=True)
Run the Flask server with SocketIO.
_register_socket_events(self)
Register SocketIO events.
_register_routes(self)
Register HTTP routes.