MaterialXWeb 0.0.2
Utilities for using MaterialX Packages with Web clients
Loading...
Searching...
No Matches
materialx_ocio_app.py
Go to the documentation of this file.
1'''
2@file materialx_ocio_app.py
3@brief __PYTHON_APP_DESCRIPTION__
4'''
5import argparse
6from flask import Flask, render_template
7from flask_socketio import SocketIO, emit
8
9import MaterialX as mx
10import PyOpenColorIO as OCIO
11from materialxocio import core as mxocio
12
14 def __init__(self, home):
15 self.home = home
16
17 # Initialize Flask and SocketIO
18 self.app = Flask(__name__)
19 self.socketio = SocketIO(self.app)
20
21 # Register routes and events
22 self._register_routes()
25
27 """
28 Register HTTP routes.
29 """
30 @self.app.route('/')
31 def home():
32 """
33 Render the home page.
34 """
35 #status_message = f'Startup: Using MaterialX version: {mx.getVersionString()}'
36 #self._emit_status_message(status_message)
37 return render_template(self.home)
38
40 """Pure virtual method: Must be implemented by subclasses."""
41 raise NotImplementedError("Subclasses must implement _setup_event_handler_map")
42
44 """
45 Register SocketIO events.
46 """
47 # Dynamically register event handlers
48 for event_name, handler in self.event_handlers.items():
49 self.socketio.on_event(event_name, handler)
50
51 def run(self, host, port, debug=True):
52 """
53 Run the Flask server with SocketIO.
54 """
55 self.socketio.run(self.app, host, port, debug=debug)
56
57
59 '''
60 '''
61 def __init__(self, homePage):
62 """
63 Initialize the Flask application and the MaterialX loader.
64 """
65 super().__init__(homePage)
66
67 # Check OCIO version
68 self.OCIO_version = OCIO.GetVersion()
69 ocioVersion = self.OCIO_version.split('.')
70 if len(ocioVersion) < 2:
71 print('> OCIO version is not in the expected format.')
72 if int(ocioVersion[0]) < 2 or int(ocioVersion[1]) < 2:
73 print('> OCIO version 2.2 or greater is required.')
74
75 print('> Using OCIO version:', self.OCIO_version)
76
77 self.materialx_version = mx.getVersionString()
78 print('> Using MaterialX version:', self.materialx_version)
79
80 self.generator = mxocio.OCIOMaterialaxGenerator()
81 #self.configs, self.aconfig = self.generator.getBuiltinConfigs()
82
83 def _emit_status_message(self, message):
84 """
85 Emit a status message to the client.
86 """
87 emit('status_message', { 'message': message }, broadcast=True)
88
89 def handle_get_config_info(self, data):
90 '''
91 Handle event and send back server information
92 '''
93 event_data = data.get('message', 'Message')
94 self.configs, self.aconfig = self.generator.getBuiltinConfigs()
95 self.config_info = self.generator.printConfigs(self.configs)
96
97 emit('server_message_get_config_info', { 'message': self.config_info }, broadcast=True)
98
99 def get_materialx_info(self, targetColorSpace, createGraphs):
100 configs, aconfig = self.generator.getBuiltinConfigs()
101
102 generator = self.generator
103
104 # Generate MaterialX definitions and implementations for all color spaces
105 # found in the ACES Cg Config and ACES Studio Config configurations.
106 nodedef_string = ''
107 nodedef_doc = mx.createDocument()
108 impl_string = ''
109 impl_doc = mx.createDocument()
110 source_string = ''
111 for c in configs:
112 config = configs[c][0]
113 for colorSpace in config.getColorSpaces():
114 aliases = colorSpace.getAliases()
115 trySource = ''
116 for alias in aliases:
117 # Get alias if it does not contain a space
118 if ' ' not in alias:
119 trySource = alias
120 if not trySource:
121 trySource = colorSpace.getName()
122 if trySource:
123 sourceColorSpace = trySource
124
125 # Skip if the source and target are the same
126 if sourceColorSpace == targetColorSpace:
127 continue
128
129 print('--- Generate transform for source color space:', trySource, '---')
130
131 # Generate source code
132 if not createGraphs:
133 definitionDoc = mx.createDocument()
134 implDoc = mx.createDocument()
135
136 definition, transformName, code, extension, target = generator.generateOCIO(aconfig, definitionDoc, implDoc, sourceColorSpace, targetColorSpace, 'color4')
137
138 # Write the definition, implementation and source code files
139 if definition:
140
141 #filename = outputPath / mx.FilePath(definition.getName() + '.' + 'mtlx')
142 #print('Write MaterialX definition file:', filename.asString())
143 #nodedef_string += mx.writeToXmlString(definitionDoc)
144 nodedef_doc.copyContentFrom(definitionDoc)
145
146 # Write the implementation document
147 #implFileName = outputPath / mx.FilePath('IM_' + transformName + '.' + 'mtlx')
148 #print('Write MaterialX implementation file:', implFileName.asString())
149 nodedef_doc.copyContentFrom(implDoc)
150 #implementationString = mx.writeToXmlString(implDoc)
151
152 #impl_string += implementationString
153
154 source_string += code
155 else:
156 # Generate node graph
157 outputType = 'color3'
158 graphDoc = generator.generateOCIOGraph(aconfig, sourceColorSpace, targetColorSpace, outputType)
159 if graphDoc:
160 nodedef_doc.copyContentFrom(graphDoc)
161
162 transformName = generator.createTransformName(sourceColorSpace, targetColorSpace, outputType, 'mxgraph_')
163 #filename = outputPath / mx.FilePath(transformName + '.' + 'mtlx')
164 #print('Write MaterialX node graph definition file:', filename.asString())
165 #nodedef_string = mx.writeToXmlString(nodedef_doc)
166
167 else:
168 print('Could not find suitable color space name to use: ' + colorSpace.getName())
169
170 nodedef_string = mx.writeToXmlString(nodedef_doc)
171 if len(impl_doc.getChildren()) > 0:
172 impl_string = mx.writeToXmlString(impl_doc)
173 else:
174 impl_string = None
175 return nodedef_string, impl_string, source_string
176
178 '''
179 Handle event and send back server message 2
180 '''
181 createGraphs = data.get('nodegraphs', 'Node Graphs')
182
183 targetColorSpace = 'lin_rec709'
184 #createGraphs = True
185 nodedef_string, impl_string, source_string = self.get_materialx_info(targetColorSpace, createGraphs)
186
187 print('> Generatated MaterialX', nodedef_string != None)
188
189 #server_message_get_mtlx_info = 'Using OCIO Version: ' + self.OCIO_version + '. MaterialX Version: ' + self.materialx_version
190 emit('server_message_get_mtlx_info',
191 { 'nodedef_string': nodedef_string,
192 'impl_string': impl_string,
193 'source_string': source_string
194 }, broadcast=True)
195
196 def handle_get_version_info(self, data):
197 print('> Get version information')
198 emit('server_message_version_info',
199 {
200 'ocio_version': self.OCIO_version,
201 'materialx_version': self.materialx_version
202 },
203 broadcast=True)
204
206 """
207 Set up dictionary of mapping event names to their handlers
208 """
209 self.event_handlers = {
210 'client_event_get_version_info': self.handle_get_version_info,
211 'client_event_get_config_info': self.handle_get_config_info,
212 'client_event_get_materialx_info': self.handle_get_materialx_info,
213 }
214
215# Main entry point
216def main():
217 parser = argparse.ArgumentParser(description="Application to use the OCIO package to extract out configuration information and generate MaterialX definitions")
218 parser.add_argument('--host', type=str, default='127.0.0.1', help="Host address to run the server on (default: 127.0.0.1)")
219 parser.add_argument('--port', type=int, default=5002, help="Port to run the server on (default: 5002)")
220 parser.add_argument('--home', type=str, default='materialx_ocio_app.html', help="Home page.")
221
222 args = parser.parse_args()
223
224 app = materialx_ocio_app(args.home)
225 app_host = args.host
226 app_port = args.port
227 app.run(host=app_host, port=app_port)
228
229if __name__ == '__main__':
230 main()
run(self, host, port, debug=True)
Run the Flask server with SocketIO.
_register_socket_events(self)
Register SocketIO events.
_setup_event_handler_map(self)
Pure virtual method: Must be implemented by subclasses.
_register_routes(self)
Register HTTP routes.
handle_get_materialx_info(self, data)
Handle event and send back server message 2.
get_materialx_info(self, targetColorSpace, createGraphs)
_setup_event_handler_map(self)
Set up dictionary of mapping event names to their handlers.
_emit_status_message(self, message)
Emit a status message to the client.
handle_get_config_info(self, data)
Handle event and send back server information.
__init__(self, homePage)
Initialize the Flask application and the MaterialX loader.