3@brief A Flask application that connects with the GPUOpen MaterialX server to allow downloading and extracting of materials by regular expression.
7from flask
import Flask, render_template
9from flask_socketio
import SocketIO, emit
10from materialxMaterials
import GPUOpenLoader
as gpuo
13 import MaterialX
as mx
15except ImportError
as e:
16 print(
"MaterialX module not found.")
23 @brief Base Flask application class for MaterialX GPUOpen server interactions.
27 Initialize the Flask application and SocketIO.
28 @param home The home page template to render.
33 self.
app = Flask(__name__)
50 status_message = f
'Startup: Using MaterialX version: {mx.getVersionString()}'
53 return render_template(self.
home)
56 """Pure virtual method: Must be implemented by subclasses."""
57 raise NotImplementedError(
"Subclasses must implement _setup_event_handler_map")
61 Register SocketIO events.
64 for event_name, handler
in self.event_handlers.items():
65 self.
socketio.on_event(event_name, handler)
67 def run(self, host, port, debug=True):
69 Run the Flask server with SocketIO.
70 @param host The host address to run the server on.
71 @param port The port to run the server on.
72 @param debug Whether to run the server in debug mode.
79 A Flask application that connects with the GPUOpen MaterialX server to allow downloading
80 and extracting of materials by regular expression.
84 Initialize the Flask application and the MaterialX loader.
85 @param homePage The home page template to render.
97 @brief Emit a status message to the client. The message emitted is of the form:
98 { 'message': 'message string' }
100 @param message The status message to emit.
102 emit(
'materialx_status', {
'message': message }, broadcast=
True)
103 print(
'Python:', message)
107 @brief Handle the 'download_materialx' event, initialize the loader, and send materials data to the client.
109 { 'materialCount': int,
110 'materialNames': list of strings,
111 'materialsList': list of material data in JSON format
113 @param data The data received from the client (not used in this handler).
116 status_message = f
'Downloaded materials...'
120 self.
loader = gpuo.GPUOpenMaterialLoader()
121 from_package = data.get(
'frompackage',
False)
123 self.
loader.readPackageFiles()
132 merged_results = {
"results": [] }
133 for mat_json
in self.
loader.getMaterialsAsJsonString():
134 mat_obj = json.loads(mat_json)
136 results = mat_obj.get(
'results', [])
137 for result
in results:
138 title = result.get(
'title')
139 result[
'url'] = self.
loader.getMaterialPreviewURL(title)
140 merged_results[
"results"].append(result)
143 merged_results[
"results"].sort(key=
lambda x: x.get(
'title',
''))
144 materials_list.append(json.dumps(merged_results, indent=2))
149 status_message = f
'Downloaded {self.material_count} materials.'
153 emit(
'materialx_downloaded', {
156 'materialsList': materials_list
161 @brief Handle the 'extract_material' event, extract material data, and send it back to the client.
162 @param data The data received from the client, expected to contain:
163 { 'expression': string, 'update_materialx': bool }
169 emit(
'materialx_extracted', {
'extractedData': return_list}, broadcast=
True)
173 expression = data.get(
'expression',
'Default Expression')
174 update_mtlx = data.get(
'update_materialx',
False)
177 data_items = self.
loader.downloadPackageByExpression(expression)
179 for data_item
in data_items:
180 status_message = f
'Extracting material: {data_item[1]}'
182 package = data_item[0]
184 extracted_data = self.
loader.extractPackageData(package,
None)
188 for item
in extracted_data:
189 file_name = item[
'file_name']
190 if item[
'type'] ==
'mtlx':
192 mx_string = item[
'data']
195 doc = mx.createDocument()
196 readOptions = mx.XmlReadOptions()
197 readOptions.readComments =
True
198 readOptions.readNewlines =
True
199 readOptions.upgradeVersion =
True
200 mx.readFromXmlString(doc, mx_string, mx.FileSearchPath(), readOptions)
201 mx_string = mx.writeToXmlString(doc)
203 return_data[file_name] = mx_string
204 elif item[
"type"] ==
'image':
207 image_base64 = self.
loader.convertPilImageToBase64(image)
208 return_data[file_name] = image_base64
210 if len(return_data) > 0:
211 url = self.
loader.getMaterialPreviewURL(title)
213 return_list.append({
'title': title,
'data': return_data,
'url': url})
215 if len(return_list) == 0:
217 emit(
'materialx_extracted', {
'extractedData': return_list}, broadcast=
True)
219 status_message = f
'Extracted {len(return_list)} materials'
221 emit(
'materialx_extracted', {
'extractedData': return_list}, broadcast=
True)
225 Set up dictionary of mapping event names to their handlers
235 @brief Main entry point for the application. Parses command-line arguments and starts the Flask server.
236 @detail Argument parameters are:
237 -h/--host: Host address to run the server on (default: 127.0.0.1)
238 -po/--port: Port to run the server on (default: 8080)
239 -ho/--home: Home page template (default: MaterialXGPUOpenApp.html)
241 parser = argparse.ArgumentParser(description=
"GPUOpen MaterialX Application")
242 parser.add_argument(
'-hs',
'--host', type=str, default=
'127.0.0.1', help=
"Host address to run the server on (default: 127.0.0.1)")
243 parser.add_argument(
'-p',
'--port', type=int, default=8080, help=
"Port to run the server on (default: 8080)")
244 parser.add_argument(
'-ho',
'--home', type=str, default=
'MaterialXGPUOpenApp.html', help=
"Home page.")
246 args = parser.parse_args()
251 app.run(host=app_host, port=app_port)
253if __name__ ==
'__main__':
Base Flask application class for MaterialX GPUOpen server interactions.
run(self, host, port, debug=True)
Run the Flask server with SocketIO.
_register_socket_events(self)
Register SocketIO events.
_register_routes(self)
Register HTTP routes.
__init__(self, home)
Initialize the Flask application and SocketIO.
_setup_event_handler_map(self)
Pure virtual method: Must be implemented by subclasses.
A Flask application that connects with the GPUOpen MaterialX server to allow downloading and extracti...
__init__(self, homePage)
Initialize the Flask application and the MaterialX loader.
handle_extract_material(self, data)
Handle the 'extract_material' event, extract material data, and send it back to the client.
_emit_status_message(self, message)
Emit a status message to the client.
handle_download_materialx(self, data)
Handle the 'download_materialx' event, initialize the loader, and send materials data to the client.
_setup_event_handler_map(self)
Set up dictionary of mapping event names to their handlers.