Fix "PEP8" coding style violations.
[OpenColorIO-Configs.git] / aces_1.0.0 / python / aces_ocio / aces_config.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 """
5 Defines objects creating the *ACES* configuration.
6 """
7
8 from __future__ import division
9
10 import copy
11 import os
12 import shutil
13 import sys
14
15 import PyOpenColorIO as ocio
16 from aces_ocio.colorspaces import aces
17 from aces_ocio.colorspaces import arri
18 from aces_ocio.colorspaces import canon
19 from aces_ocio.colorspaces import general
20 from aces_ocio.colorspaces import gopro
21 from aces_ocio.colorspaces import panasonic
22 from aces_ocio.colorspaces import red
23 from aces_ocio.colorspaces import sony
24 from aces_ocio.process import Process
25
26 from aces_ocio.utilities import (
27     ColorSpace,
28     colorspace_prefixed_name,
29     compact,
30     replace,
31     unpack_default)
32
33 __author__ = 'ACES Developers'
34 __copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'
35 __license__ = ''
36 __maintainer__ = 'ACES Developers'
37 __email__ = 'aces@oscars.org'
38 __status__ = 'Production'
39
40 __all__ = ['ACES_OCIO_CTL_DIRECTORY_ENVIRON',
41            'ACES_OCIO_CONFIGURATION_DIRECTORY_ENVIRON',
42            'set_config_default_roles',
43            'write_config',
44            'generate_OCIO_transform',
45            'add_colorspace_alias',
46            'create_config',
47            'generate_LUTs',
48            'generate_baked_LUTs',
49            'create_config_dir',
50            'create_ACES_config',
51            'main']
52
53 ACES_OCIO_CTL_DIRECTORY_ENVIRON = 'ACES_OCIO_CTL_DIRECTORY'
54 ACES_OCIO_CONFIGURATION_DIRECTORY_ENVIRON = 'ACES_OCIO_CONFIGURATION_DIRECTORY'
55
56
57 def set_config_default_roles(config,
58                              color_picking='',
59                              color_timing='',
60                              compositing_log='',
61                              data='',
62                              default='',
63                              matte_paint='',
64                              reference='',
65                              scene_linear='',
66                              texture_paint='',
67                              rendering='',
68                              compositing_linear=''):
69     """
70     Sets given *OCIO* configuration default roles.
71
72     Parameters
73     ----------
74     config : config
75         *OCIO* configuration.
76     color_picking : str or unicode
77         Color picking role title.
78     color_timing : str or unicode
79         Color timing role title.
80     compositing_log : str or unicode
81         Compositing log role title.
82     data : str or unicode
83         Data role title.
84     default : str or unicode
85         Default role title.
86     matte_paint : str or unicode
87         Matte painting role title.
88     reference : str or unicode
89         Reference role title.
90     scene_linear : str or unicode
91         Scene linear role title.
92     texture_paint : str or unicode
93         Texture painting role title.
94
95     Returns
96     -------
97     bool
98          Definition success.
99     """
100
101     if color_picking:
102         config.setRole(ocio.Constants.ROLE_COLOR_PICKING, color_picking)
103     if color_timing:
104         config.setRole(ocio.Constants.ROLE_COLOR_TIMING, color_timing)
105     if compositing_log:
106         config.setRole(ocio.Constants.ROLE_COMPOSITING_LOG, compositing_log)
107     if data:
108         config.setRole(ocio.Constants.ROLE_DATA, data)
109     if default:
110         config.setRole(ocio.Constants.ROLE_DEFAULT, default)
111     if matte_paint:
112         config.setRole(ocio.Constants.ROLE_MATTE_PAINT, matte_paint)
113     if reference:
114         config.setRole(ocio.Constants.ROLE_REFERENCE, reference)
115     if texture_paint:
116         config.setRole(ocio.Constants.ROLE_TEXTURE_PAINT, texture_paint)
117
118     # 'rendering' and 'compositing_linear' roles default to the 'scene_linear'
119     # value if not set explicitly
120     if rendering:
121         config.setRole('rendering', rendering)
122     if compositing_linear:
123         config.setRole('compositing_linear', compositing_linear)
124     if scene_linear:
125         config.setRole(ocio.Constants.ROLE_SCENE_LINEAR, scene_linear)
126         if not rendering:
127             config.setRole('rendering', scene_linear)
128         if not compositing_linear:
129             config.setRole('compositing_linear', scene_linear)
130
131     return True
132
133
134 def write_config(config, config_path, sanity_check=True):
135     """
136     Writes the configuration to given path.
137
138     Parameters
139     ----------
140     parameter : type
141         Parameter description.
142
143     Returns
144     -------
145     type
146          Return value description.
147     """
148
149     if sanity_check:
150         try:
151             config.sanityCheck()
152         except Exception, e:
153             print e
154             print 'Configuration was not written due to a failed Sanity Check'
155             return
156
157     with open(config_path, mode='w') as fp:
158         fp.write(config.serialize())
159
160
161 def generate_OCIO_transform(transforms):
162     """
163     Object description.
164
165     Parameters
166     ----------
167     parameter : type
168         Parameter description.
169
170     Returns
171     -------
172     type
173          Return value description.
174     """
175
176     interpolation_options = {
177         'linear': ocio.Constants.INTERP_LINEAR,
178         'nearest': ocio.Constants.INTERP_NEAREST,
179         'tetrahedral': ocio.Constants.INTERP_TETRAHEDRAL}
180
181     direction_options = {
182         'forward': ocio.Constants.TRANSFORM_DIR_FORWARD,
183         'inverse': ocio.Constants.TRANSFORM_DIR_INVERSE}
184
185     ocio_transforms = []
186
187     for transform in transforms:
188
189         # lutFile transform
190         if transform['type'] == 'lutFile':
191             # Create transforms
192             ocio_transform = ocio.FileTransform()
193
194             if 'path' in transform:
195                 ocio_transform.setSrc(transform['path'])
196
197             if 'cccid' in transform:
198                 ocio_transform.setCCCId(transform['cccid'])
199
200             if 'interpolation' in transform:
201                 ocio_transform.setInterpolation(transform['interpolation'])
202             else:
203                 ocio_transform.setInterpolation(ocio.Constants.INTERP_BEST)
204
205             if 'direction' in transform:
206                 ocio_transform.setDirection(
207                     direction_options[transform['direction']])
208
209             ocio_transforms.append(ocio_transform)
210
211         # matrix transform
212         elif transform['type'] == 'matrix':
213             ocio_transform = ocio.MatrixTransform()
214             # MatrixTransform member variables can't be initialized directly.
215             # Each must be set individually.
216             ocio_transform.setMatrix(transform['matrix'])
217
218             if 'offset' in transform:
219                 ocio_transform.setOffset(transform['offset'])
220
221             if 'direction' in transform:
222                 ocio_transform.setDirection(
223                     direction_options[transform['direction']])
224
225             ocio_transforms.append(ocio_transform)
226
227         # exponent transform
228         elif transform['type'] == 'exponent':
229             ocio_transform = ocio.ExponentTransform()
230
231             if 'value' in transform:
232                 ocio_transform.setValue(transform['value'])
233
234             ocio_transforms.append(ocio_transform)
235
236         # log transform
237         elif transform['type'] == 'log':
238             ocio_transform = ocio.LogTransform()
239
240             if 'base' in transform:
241                 ocio_transform.setBase(transform['base'])
242
243             if 'direction' in transform:
244                 ocio_transform.setDirection(
245                     direction_options[transform['direction']])
246
247             ocio_transforms.append(ocio_transform)
248
249         # color space transform
250         elif transform['type'] == 'colorspace':
251             ocio_transform = ocio.ColorSpaceTransform()
252
253             if 'src' in transform:
254                 ocio_transform.setSrc(transform['src'])
255
256             if 'dst' in transform:
257                 ocio_transform.setDst(transform['dst'])
258
259             if 'direction' in transform:
260                 ocio_transform.setDirection(
261                     direction_options[transform['direction']])
262
263             ocio_transforms.append(ocio_transform)
264
265         # look transform
266         elif transform['type'] == 'look':
267             ocio_transform = ocio.LookTransform()
268             if 'look' in transform:
269                 ocio_transform.setLooks(transform['look'])
270
271             if 'src' in transform:
272                 ocio_transform.setSrc(transform['src'])
273
274             if 'dst' in transform:
275                 ocio_transform.setDst(transform['dst'])
276
277             if 'direction' in transform:
278                 ocio_transform.setDirection(
279                     direction_options[transform['direction']])
280
281             ocio_transforms.append(ocio_transform)
282
283         # unknown type
284         else:
285             print('Ignoring unknown transform type : %s' % transform['type'])
286
287     if len(ocio_transforms) > 1:
288         group_transform = ocio.GroupTransform()
289         for transform in ocio_transforms:
290             group_transform.push_back(transform)
291         transform = group_transform
292     else:
293         transform = ocio_transforms[0]
294
295     return transform
296
297
298 def add_colorspace_aliases(config,
299                            reference_colorspace,
300                            colorspace,
301                            colorspace_alias_names,
302                            family='Aliases'):
303     """
304     Object description.
305
306     Parameters
307     ----------
308     parameter : type
309         Parameter description.
310
311     Returns
312     -------
313     type
314          Return value description.
315     """
316
317     for alias_name in colorspace_alias_names:
318         if alias_name.lower() == colorspace.name.lower():
319             print('Skipping alias creation for %s, alias %s, '
320                   'because lower cased names match' % (
321                 colorspace.name, alias_name))
322             continue
323
324         print('Adding alias colorspace space %s, alias to %s' % (
325             alias_name, colorspace.name))
326
327         compact_family_name = family
328
329         description = colorspace.description
330         if colorspace.aces_transform_id:
331             description += (
332                 '\n\nACES Transform ID : %s' % colorspace.aces_transform_id)
333
334         ocio_colorspace_alias = ocio.ColorSpace(
335             name=alias_name,
336             bitDepth=colorspace.bit_depth,
337             description=description,
338             equalityGroup=colorspace.equality_group,
339             family=compact_family_name,
340             isData=colorspace.is_data,
341             allocation=colorspace.allocation_type,
342             allocationVars=colorspace.allocation_vars)
343
344         if colorspace.to_reference_transforms:
345             print('\tGenerating To-Reference transforms')
346             ocio_transform = generate_OCIO_transform(
347                 [{'type': 'colorspace',
348                   'src': colorspace.name,
349                   'dst': reference_colorspace.name,
350                   'direction': 'forward'}])
351             ocio_colorspace_alias.setTransform(
352                 ocio_transform,
353                 ocio.Constants.COLORSPACE_DIR_TO_REFERENCE)
354
355         if colorspace.from_reference_transforms:
356             print('\tGenerating From-Reference transforms')
357             ocio_transform = generate_OCIO_transform(
358                 [{'type': 'colorspace',
359                   'src': reference_colorspace.name,
360                   'dst': colorspace.name,
361                   'direction': 'forward'}])
362             ocio_colorspace_alias.setTransform(
363                 ocio_transform,
364                 ocio.Constants.COLORSPACE_DIR_FROM_REFERENCE)
365
366         config.addColorSpace(ocio_colorspace_alias)
367
368
369 def add_look(config,
370              look,
371              prefix,
372              custom_lut_dir,
373              reference_name,
374              config_data,
375              multiple_displays=False):
376     """
377     Object description.
378
379     Parameters
380     ----------
381     parameter : type
382         Parameter description.
383
384     Returns
385     -------
386     type
387          Return value description.
388     """
389
390     look_name, look_colorspace, look_lut, look_cccid = unpack_default(look, 4)
391
392     print('Adding look %s - %s' % (look_name, ', '.join(look)))
393
394     #
395     # Copy look lut
396     #
397     if custom_lut_dir:
398         if '$' not in look_lut:
399             print('Getting ready to copy look lut : %s' % look_lut)
400             shutil.copy2(look_lut, custom_lut_dir)
401             look_lut = os.path.split(look_lut)[1]
402         else:
403             print('Skipping LUT copy because path contains a context variable')
404
405     #
406     # Create OCIO Look
407     #
408     # Look 1
409     print('Adding look to config')
410     lk1 = ocio.Look()
411     lk1.setName(look_name)
412     lk1.setProcessSpace(look_colorspace)
413
414     keys = {'type': 'lutFile',
415             'path': look_lut,
416             'direction': 'forward'}
417     if look_cccid:
418         keys['cccid'] = look_cccid
419
420     ocio_transform = generate_OCIO_transform([keys])
421     lk1.setTransform(ocio_transform)
422
423     # add to config
424     config.addLook(lk1)
425
426     print('Creating aliased colorspace')
427
428     #
429     # Create OCIO colorspace that references that look
430     # - Needed for some implementations that don't process looks well
431     # - Also needed for some implementations that don't expose looks well
432     #
433     look_aliases = ['look_%s' % compact(look_name)]
434     colorspace = ColorSpace(look_name,
435                             aliases=look_aliases,
436                             description='The %s Look colorspace' % look_name,
437                             family='Look')
438
439     colorspace.from_reference_transforms = [{'type': 'look',
440                                              'look': look_name,
441                                              'src': reference_name,
442                                              'dst': reference_name,
443                                              'direction': 'forward'}]
444
445     print('Adding colorspace %s, alias to look %s to config data' % (
446         look_name, look_name))
447
448     # Add this colorspace into the main list of colorspaces
449     config_data['colorSpaces'].append(colorspace)
450
451     print()
452
453
454 def integrate_looks_into_views(config,
455                                looks,
456                                reference_name,
457                                config_data,
458                                multiple_displays=False):
459     """
460     Object description.
461
462     Parameters
463     ----------
464     parameter : type
465         Parameter description.
466
467     Returns
468     -------
469     type
470          Return value description.
471     """
472     look_names = [look[0] for look in looks]
473
474     # Option 1 - Add a 'look' to each Display
475     # - Assumes there is a Display for each ACES Output Transform
476     if multiple_displays:
477         for look_name in look_names:
478             config_data['looks'].append(look_name)
479
480     # Option 2
481     # - Copy each Output Transform colorspace
482     # - For each copy, add a LookTransform at the head of the from_reference
483     #     transform list
484     # - Add these new copied colorspaces for the Displays / Views 
485     else:
486         for display, view_list in config_data['displays'].iteritems():
487             output_colorspace_c = None
488             look_names_string = ''
489             for view_name, output_colorspace in view_list.iteritems():
490                 if view_name == 'Output Transform':
491
492                     print('Adding new View that incorporates looks')
493
494                     # Make a copy of the output colorspace
495                     output_colorspace_c = copy.deepcopy(output_colorspace)
496
497                     # for look_name in look_names:
498                     for i in range(len(look_names)):
499                         look_name = look_names[i]
500
501                         # Add the LookTransform to the head of the
502                         # from_reference transform list.
503                         if output_colorspace_c.from_reference_transforms:
504                             output_colorspace_c.from_reference_transforms.insert(
505                                 i, {'type': 'look',
506                                     'look': look_name,
507                                     'src': reference_name,
508                                     'dst': reference_name,
509                                     'direction': 'forward'})
510
511                         # Add the LookTransform to the end of
512                         # the to_reference transform list.
513                         if output_colorspace_c.to_reference_transforms:
514                             inverse_look_name = look_names[
515                                 len(look_names) - 1 - i]
516
517                             output_colorspace_c.to_reference_transforms.append(
518                                 {'type': 'look',
519                                  'look': inverse_look_name,
520                                  'src': reference_name,
521                                  'dst': reference_name,
522                                  'direction': 'inverse'})
523
524                         if look_name not in config_data['looks']:
525                             config_data['looks'].append(look_name)
526
527                     look_names_string = ', '.join(look_names)
528                     output_colorspace_c.name = '%s with %s' % (
529                     output_colorspace.name, look_names_string)
530                     output_colorspace_c.aliases = [
531                         'out_%s' % compact(output_colorspace_c.name)]
532
533                     print('Colorspace that incorporates looks '
534                           'created : %s' % output_colorspace_c.name)
535
536                     config_data['colorSpaces'].append(output_colorspace_c)
537
538             if output_colorspace_c:
539                 print('Adding colorspace that incorporates looks '
540                       'into view list')
541
542                 # Change the name of the View
543                 view_list['Output Transform with %s' % look_names_string] = (
544                     output_colorspace_c)
545                 config_data['displays'][display] = view_list
546
547                 # print('Display : %s, View List : %s' % (
548                 # display, ', '.join(view_list)) )
549
550
551 def create_config(config_data,
552                   aliases=False,
553                   prefix=False,
554                   multiple_displays=False,
555                   look_info=None,
556                   custom_lut_dir=None):
557     """
558     Object description.
559
560     Parameters
561     ----------
562     parameter : type
563         Parameter description.
564
565     Returns
566     -------
567     type
568          Return value description.
569     """
570
571     if look_info is None:
572         look_info = []
573
574     prefixed_names = {}
575     alias_colorspaces = []
576
577     # Creating the *OCIO* configuration.
578     config = ocio.Config()
579
580     # Setting configuration description.
581     config.setDescription('An ACES config generated from python')
582
583     # Setting configuration search path.
584     searchPath = ['luts']
585     if custom_lut_dir:
586         searchPath.append('custom')
587     config.setSearchPath(':'.join(searchPath))
588
589     # Defining the reference colorspace.
590     reference_data = config_data['referenceColorSpace']
591
592     # Adding the color space Family into the name
593     # Helps with applications that present colorspaces as one long list
594     if prefix:
595         prefixed_name = colorspace_prefixed_name(reference_data)
596         prefixed_names[reference_data.name] = prefixed_name
597         reference_data.name = prefixed_name
598
599     print('Adding the reference color space : %s' % reference_data.name)
600
601     reference = ocio.ColorSpace(
602         name=reference_data.name,
603         bitDepth=reference_data.bit_depth,
604         description=reference_data.description,
605         equalityGroup=reference_data.equality_group,
606         family=reference_data.family,
607         isData=reference_data.is_data,
608         allocation=reference_data.allocation_type,
609         allocationVars=reference_data.allocation_vars)
610
611     config.addColorSpace(reference)
612
613     # Add alias
614     if aliases:
615         if reference_data.aliases:
616             # add_colorspace_alias(config, reference_data,
617             #                     reference_data, reference_data.aliases)
618             # defer adding alias colorspaces until end.
619             # Helps with some applications.
620             alias_colorspaces.append(
621                 [reference_data, reference_data, reference_data.aliases])
622
623     print()
624
625     # print('color spaces : %s' % [
626     # x.name for x in sorted(config_data['colorSpaces'])])
627
628     #
629     # Add Looks and Look colorspaces
630     #
631     if look_info:
632         print('Adding looks')
633
634         config_data['looks'] = []
635
636         # Add looks and colorspaces
637         for look in look_info:
638             add_look(config,
639                      look,
640                      prefix,
641                      custom_lut_dir,
642                      reference_data.name,
643                      config_data)
644
645         # Integrate looks with displays, views
646         integrate_looks_into_views(config,
647                                    look_info,
648                                    reference_data.name,
649                                    config_data,
650                                    multiple_displays)
651
652         print()
653
654     print('Adding the regular color spaces')
655
656     # Creating the remaining colorspaces.
657     for colorspace in sorted(config_data['colorSpaces']):
658         # Adding the color space Family into the name
659         # Helps with applications that present colorspaces as one long list
660         if prefix:
661             prefixed_name = colorspace_prefixed_name(colorspace)
662             prefixed_names[colorspace.name] = prefixed_name
663             colorspace.name = prefixed_name
664
665         print('Creating new color space : %s' % colorspace.name)
666
667         description = colorspace.description
668         if colorspace.aces_transform_id:
669             description += (
670                 '\n\nACES Transform ID : %s' % colorspace.aces_transform_id)
671
672         ocio_colorspace = ocio.ColorSpace(
673             name=colorspace.name,
674             bitDepth=colorspace.bit_depth,
675             description=description,
676             equalityGroup=colorspace.equality_group,
677             family=colorspace.family,
678             isData=colorspace.is_data,
679             allocation=colorspace.allocation_type,
680             allocationVars=colorspace.allocation_vars)
681
682         if colorspace.to_reference_transforms:
683             print('\tGenerating To-Reference transforms')
684             ocio_transform = generate_OCIO_transform(
685                 colorspace.to_reference_transforms)
686             ocio_colorspace.setTransform(
687                 ocio_transform,
688                 ocio.Constants.COLORSPACE_DIR_TO_REFERENCE)
689
690         if colorspace.from_reference_transforms:
691             print('\tGenerating From-Reference transforms')
692             ocio_transform = generate_OCIO_transform(
693                 colorspace.from_reference_transforms)
694             ocio_colorspace.setTransform(
695                 ocio_transform,
696                 ocio.Constants.COLORSPACE_DIR_FROM_REFERENCE)
697
698         config.addColorSpace(ocio_colorspace)
699
700         #
701         # Add alias to normal colorspace, using compact name
702         #
703         if aliases:
704             if colorspace.aliases:
705                 # add_colorspace_alias(config, reference_data,
706                 #                     colorspace, colorspace.aliases)
707                 # defer adding alias colorspaces until end.
708                 # Helps with some applications.
709                 alias_colorspaces.append(
710                     [reference_data, colorspace, colorspace.aliases])
711
712         print()
713
714     print()
715
716     #
717     # We add roles early so we can create alias colorspaces with the names
718     # of the roles before the rest of the colorspace aliases are added
719     # to the config.
720     print('Setting the roles')
721
722     if prefix:
723         set_config_default_roles(
724             config,
725             color_picking=prefixed_names[
726                 config_data['roles']['color_picking']],
727             color_timing=prefixed_names[config_data['roles']['color_timing']],
728             compositing_log=prefixed_names[
729                 config_data['roles']['compositing_log']],
730             data=prefixed_names[config_data['roles']['data']],
731             default=prefixed_names[config_data['roles']['default']],
732             matte_paint=prefixed_names[config_data['roles']['matte_paint']],
733             reference=prefixed_names[config_data['roles']['reference']],
734             scene_linear=prefixed_names[config_data['roles']['scene_linear']],
735             texture_paint=prefixed_names[
736                 config_data['roles']['texture_paint']])
737
738         # Not allowed for the moment. role names can not overlap
739         # with colorspace names.
740         """
741         # Add the aliased colorspaces for each role
742         for role_name, role_colorspace_name in config_data['roles'].iteritems():
743             role_colorspace_prefixed_name = prefixed_names[role_colorspace_name]
744
745             print( 'Finding colorspace : %s' % role_colorspace_prefixed_name )
746             # Find the colorspace pointed to by the role
747             role_colorspaces = [colorspace
748                 for colorspace in config_data['colorSpaces']
749                 if colorspace.name == role_colorspace_prefixed_name]
750             role_colorspace = None
751             if len(role_colorspaces) > 0:
752                 role_colorspace = role_colorspaces[0]
753             else:
754                 if reference_data.name == role_colorspace_prefixed_name:
755                     role_colorspace = reference_data
756
757             if role_colorspace:
758                 print( 'Adding an alias colorspace named %s, pointing to %s' % (
759                     role_name, role_colorspace.name))
760
761                 add_colorspace_aliases(
762                 config, reference_data, role_colorspace, [role_name], 'Roles')
763         """
764
765     else:
766         set_config_default_roles(
767             config,
768             color_picking=config_data['roles']['color_picking'],
769             color_timing=config_data['roles']['color_timing'],
770             compositing_log=config_data['roles']['compositing_log'],
771             data=config_data['roles']['data'],
772             default=config_data['roles']['default'],
773             matte_paint=config_data['roles']['matte_paint'],
774             reference=config_data['roles']['reference'],
775             scene_linear=config_data['roles']['scene_linear'],
776             texture_paint=config_data['roles']['texture_paint'])
777
778         # Not allowed for the moment. role names can not overlap
779         # with colorspace names.
780         """
781         # Add the aliased colorspaces for each role
782         for role_name, role_colorspace_name in config_data['roles'].iteritems():
783             # Find the colorspace pointed to by the role
784             role_colorspaces = [colorspace
785             for colorspace in config_data['colorSpaces']
786             if colorspace.name == role_colorspace_name]
787             role_colorspace = None
788             if len(role_colorspaces) > 0:
789                 role_colorspace = role_colorspaces[0]
790             else:
791                 if reference_data.name == role_colorspace_name:
792                     role_colorspace = reference_data
793
794             if role_colorspace:
795                 print( 'Adding an alias colorspace named %s, pointing to %s' % (
796                     role_name, role_colorspace.name))
797
798                 add_colorspace_aliases(
799                 config, reference_data, role_colorspace, [role_name], 'Roles')
800         """
801
802     print()
803
804     # We add these at the end as some applications use the order of the
805     # colorspaces definitions in the config to order the colorspaces
806     # in their selection lists.
807     # Other go alphabetically. This should keep the alias colorspaces out
808     # of the way for the apps that use the order of definition in the config.
809     print('Adding the alias colorspaces')
810     for reference, colorspace, aliases in alias_colorspaces:
811         add_colorspace_aliases(config, reference, colorspace, aliases)
812
813     print()
814
815     print('Adding the diplays and views')
816
817     # Set the color_picking role to be
818     # the first Display's Output Transform View.
819     default_display_name = config_data['defaultDisplay']
820     default_display_views = config_data['displays'][default_display_name]
821     default_display_colorspace = default_display_views['Output Transform']
822
823     set_config_default_roles(
824         config,
825         color_picking=default_display_colorspace.name)
826
827     # Defining the *views* and *displays*.
828     displays = []
829     views = []
830
831     # Defining a *generic* *display* and *view* setup.
832     if multiple_displays:
833         # Built list of looks to add to Displays
834         looks = config_data['looks'] if ('looks' in config_data) else []
835         looks = ', '.join(looks)
836         print('Creating multiple displays, with looks : %s' % looks)
837
838         # Note: We don't reorder the Displays to put the 'defaultDisplay' first
839         # because OCIO will order them alphabetically
840         # when the config is written to disk.
841
842         # Create Displays, Views
843         for display, view_list in config_data['displays'].iteritems():
844             for view_name, colorspace in view_list.iteritems():
845                 config.addDisplay(display, view_name, colorspace.name, looks)
846                 if 'Output Transform' in view_name and looks != '':
847                     # Add normal View, without looks
848                     config.addDisplay(display, view_name, colorspace.name)
849
850                     # Add View with looks
851                     view_name_with_looks = '%s with %s' % (view_name, looks)
852                     config.addDisplay(display, view_name_with_looks,
853                                       colorspace.name, looks)
854                 else:
855                     config.addDisplay(display, view_name, colorspace.name)
856                 if not (view_name in views):
857                     views.append(view_name)
858             displays.append(display)
859
860     # Defining the set of *views* and *displays* useful in a *GUI* context.
861     else:
862         single_display_name = 'ACES'
863         # single_display_name = config_data['roles']['scene_linear']
864         displays.append(single_display_name)
865
866         # Make sure the default display is first
867         display_names = sorted(config_data['displays'])
868         display_names.insert(0, display_names.pop(
869             display_names.index(default_display_name)))
870
871         # Built list of looks to add to Displays
872         looks = config_data['looks'] if ('looks' in config_data) else []
873         look_names = ', '.join(looks)
874
875         displays_views_colorspaces = []
876
877         # Create Displays, Views
878         for display in display_names:
879             view_list = config_data['displays'][display]
880             for view_name, colorspace in view_list.iteritems():
881                 if 'Output Transform' in view_name:
882                     # print( 'Adding view for %s' % colorspace.name )
883
884                     # We use the Display names as the View names in this case
885                     # as there is a single Display that contains all views.
886                     # This works for more applications than not,
887                     # as of the time of this implementation.
888
889                     # Maya 2016 doesn't like parentheses in View names
890                     display_cleaned = replace(display, {')': '', '(': ''})
891
892                     # If View includes looks
893                     if 'with' in view_name:
894                         # Integrate looks into view name
895                         display_cleaned = '%s with %s' % (
896                         display_cleaned, look_names)
897
898                         viewsWithLooksAtEnd = False
899                         # Storing combo of display, view and colorspace name
900                         # in a list so we can add them to the end of the list.
901                         if viewsWithLooksAtEnd:
902                             displays_views_colorspaces.append(
903                                 [single_display_name, display_cleaned,
904                                  colorspace.name])
905
906                         # Or add as normal
907                         else:
908                             config.addDisplay(single_display_name,
909                                               display_cleaned, colorspace.name)
910
911                             # Add to views list
912                             if not (display_cleaned in views):
913                                 views.append(display_cleaned)
914
915                     # A normal View
916                     else:
917                         config.addDisplay(single_display_name, display_cleaned,
918                                           colorspace.name)
919
920                         # Add to views list
921                         if not (display_cleaned in views):
922                             views.append(display_cleaned)
923
924         # Add to config any display, view combinations that were saved
925         # for later. This list will be empty unless viewsWithLooksAtEnd is
926         # set to True above.
927         for display_view_colorspace in displays_views_colorspaces:
928             single_display_name, display_cleaned, colorspace_name = (
929                 display_view_colorspace)
930
931             # Add to config
932             config.addDisplay(single_display_name, display_cleaned,
933                               colorspace_name)
934
935             # Add to views list
936             if not (display_cleaned in views):
937                 views.append(display_cleaned)
938
939
940         # Works with Nuke Studio and Mari, but not Nuke
941         # single_display_name = 'Utility'
942         # displays.append(single_display_name)
943
944         raw_display_space_name = config_data['roles']['data']
945         log_display_space_name = config_data['roles']['compositing_log']
946
947         # Find the newly-prefixed colorspace names
948         if prefix:
949             # print( prefixed_names )
950             raw_display_space_name = prefixed_names[raw_display_space_name]
951             log_display_space_name = prefixed_names[log_display_space_name]
952
953         config.addDisplay(single_display_name, 'Raw', raw_display_space_name)
954         views.append('Raw')
955         config.addDisplay(single_display_name, 'Log', log_display_space_name)
956         views.append('Log')
957
958     # Setting the active *displays* and *views*.
959     config.setActiveDisplays(','.join(sorted(displays)))
960     config.setActiveViews(','.join(views))
961
962     print()
963
964     # Make sure we didn't create a bad config
965     config.sanityCheck()
966
967     # Reset the colorspace names back to their non-prefixed versions
968     if prefix:
969         # Build the reverse lookup
970         prefixed_names_inverse = {}
971         for original, prefixed in prefixed_names.iteritems():
972             prefixed_names_inverse[prefixed] = original
973
974         # Reset the reference colorspace name
975         reference_data.name = prefixed_names_inverse[reference_data.name]
976
977         # Reset the rest of the colorspace names
978         try:
979             for colorspace in config_data['colorSpaces']:
980                 colorspace.name = prefixed_names_inverse[colorspace.name]
981         except:
982             print('Prefixed names')
983             for original, prefixed in prefixed_names.iteritems():
984                 print('%s, %s' % (original, prefixed))
985
986             print('\n')
987
988             print('Inverse Lookup of Prefixed names')
989             for prefixed, original in prefixed_names_inverse.iteritems():
990                 print('%s, %s' % (prefixed, original))
991             raise
992
993     return config
994
995
996 def generate_LUTs(odt_info,
997                   lmt_info,
998                   shaper_name,
999                   aces_ctl_directory,
1000                   lut_directory,
1001                   lut_resolution_1d=4096,
1002                   lut_resolution_3d=64,
1003                   cleanup=True):
1004     """
1005     Object description.
1006
1007     Parameters
1008     ----------
1009     parameter : type
1010         Parameter description.
1011
1012     Returns
1013     -------
1014     dict
1015          Colorspaces and transforms converting between those colorspaces and
1016          the reference colorspace, *ACES*.
1017     """
1018
1019     print('generateLUTs - begin')
1020     config_data = {}
1021
1022     # Initialize a few variables
1023     config_data['displays'] = {}
1024     config_data['colorSpaces'] = []
1025
1026     # -------------------------------------------------------------------------
1027     # *ACES Color Spaces*
1028     # -------------------------------------------------------------------------
1029
1030     # *ACES* colorspaces
1031     (aces_reference,
1032      aces_colorspaces,
1033      aces_displays,
1034      aces_log_display_space,
1035      aces_roles,
1036      aces_default_display) = aces.create_colorspaces(aces_ctl_directory,
1037                                                      lut_directory,
1038                                                      lut_resolution_1d,
1039                                                      lut_resolution_3d,
1040                                                      lmt_info,
1041                                                      odt_info,
1042                                                      shaper_name,
1043                                                      cleanup)
1044
1045     config_data['referenceColorSpace'] = aces_reference
1046     config_data['roles'] = aces_roles
1047
1048     for cs in aces_colorspaces:
1049         config_data['colorSpaces'].append(cs)
1050
1051     for name, data in aces_displays.iteritems():
1052         config_data['displays'][name] = data
1053
1054     config_data['defaultDisplay'] = aces_default_display
1055     config_data['linearDisplaySpace'] = aces_reference
1056     config_data['logDisplaySpace'] = aces_log_display_space
1057
1058     # -------------------------------------------------------------------------
1059     # *Camera Input Transforms*
1060     # -------------------------------------------------------------------------
1061
1062     # *ARRI Log-C* to *ACES*.
1063     arri_colorSpaces = arri.create_colorspaces(lut_directory,
1064                                                lut_resolution_1d)
1065     for cs in arri_colorSpaces:
1066         config_data['colorSpaces'].append(cs)
1067
1068     # *Canon-Log* to *ACES*.
1069     canon_colorspaces = canon.create_colorspaces(lut_directory,
1070                                                  lut_resolution_1d)
1071     for cs in canon_colorspaces:
1072         config_data['colorSpaces'].append(cs)
1073
1074     # *GoPro Protune* to *ACES*.
1075     gopro_colorspaces = gopro.create_colorspaces(lut_directory,
1076                                                  lut_resolution_1d)
1077     for cs in gopro_colorspaces:
1078         config_data['colorSpaces'].append(cs)
1079
1080     # *Panasonic V-Log* to *ACES*.
1081     panasonic_colorSpaces = panasonic.create_colorspaces(lut_directory,
1082                                                          lut_resolution_1d)
1083     for cs in panasonic_colorSpaces:
1084         config_data['colorSpaces'].append(cs)
1085
1086     # *RED* colorspaces to *ACES*.
1087     red_colorspaces = red.create_colorspaces(lut_directory,
1088                                              lut_resolution_1d)
1089     for cs in red_colorspaces:
1090         config_data['colorSpaces'].append(cs)
1091
1092     # *S-Log* to *ACES*.
1093     sony_colorSpaces = sony.create_colorspaces(lut_directory,
1094                                                lut_resolution_1d)
1095     for cs in sony_colorSpaces:
1096         config_data['colorSpaces'].append(cs)
1097
1098     # -------------------------------------------------------------------------
1099     # General Color Spaces
1100     # -------------------------------------------------------------------------
1101     general_colorSpaces = general.create_colorspaces(lut_directory,
1102                                                      lut_resolution_1d,
1103                                                      lut_resolution_3d)
1104     for cs in general_colorSpaces:
1105         config_data['colorSpaces'].append(cs)
1106
1107     # The *Raw* color space
1108     raw = general.create_raw()
1109     config_data['colorSpaces'].append(raw)
1110
1111     # Override certain roles, for now
1112     config_data['roles']['data'] = raw.name
1113     config_data['roles']['reference'] = raw.name
1114     config_data['roles']['texture_paint'] = raw.name
1115
1116     print('generateLUTs - end')
1117     return config_data
1118
1119
1120 def generate_baked_LUTs(odt_info,
1121                         shaper_name,
1122                         baked_directory,
1123                         config_path,
1124                         lut_resolution_1d,
1125                         lut_resolution_3d,
1126                         lut_resolution_shaper=1024,
1127                         prefix=False):
1128     """
1129     Object description.
1130
1131     Parameters
1132     ----------
1133     parameter : type
1134         Parameter description.
1135
1136     Returns
1137     -------
1138     type
1139          Return value description.
1140     """
1141
1142     odt_info_C = dict(odt_info)
1143
1144     # Uncomment if you would like to support the older behavior where ODTs
1145     # that have support for full and legal range output generate
1146     # a LUT for each.
1147     """
1148     # Create two entries for ODTs that have full and legal range support
1149     for odt_ctl_name, odt_values in odt_info.iteritems():
1150         if odt_values['transformHasFullLegalSwitch']:
1151             odt_name = odt_values['transformUserName']
1152
1153             odt_values_legal = dict(odt_values)
1154             odt_values_legal['transformUserName'] = '%s - Legal' % odt_name
1155             odt_info_C['%s - Legal' % odt_ctl_name] = odt_values_legal
1156
1157             odt_values_full = dict(odt_values)
1158             odt_values_full['transformUserName'] = '%s - Full' % odt_name
1159             odt_info_C['%s - Full' % odt_ctl_name] = odt_values_full
1160
1161             del (odt_info_C[odt_ctl_name])
1162     """
1163
1164     # Generate appropriate LUTs for each ODT
1165     for odt_ctl_name, odt_values in odt_info_C.iteritems():
1166         odt_prefix = odt_values['transformUserNamePrefix']
1167         odt_name = odt_values['transformUserName']
1168
1169         # *Photoshop*
1170         for input_space in ['ACEScc', 'ACESproxy']:
1171             args = ['--iconfig', config_path,
1172                     '-v']
1173             if prefix:
1174                 args += ['--inputspace', 'ACES - %s' % input_space]
1175                 args += ['--outputspace', 'Output - %s' % odt_name]
1176             else:
1177                 args += ['--inputspace', input_space]
1178                 args += ['--outputspace', odt_name]
1179
1180             args += ['--description',
1181                      '%s - %s for %s data' % (odt_prefix,
1182                                               odt_name,
1183                                               input_space)]
1184             if prefix:
1185                 args += ['--shaperspace', 'Utility - %s' % shaper_name,
1186                          '--shapersize', str(lut_resolution_shaper)]
1187             else:
1188                 args += ['--shaperspace', shaper_name,
1189                          '--shapersize', str(lut_resolution_shaper)]
1190             args += ['--cubesize', str(lut_resolution_3d)]
1191             args += ['--format',
1192                      'icc',
1193                      os.path.join(baked_directory,
1194                                   'photoshop',
1195                                   '%s for %s.icc' % (odt_name, input_space))]
1196
1197             bake_lut = Process(description='bake a LUT',
1198                                cmd='ociobakelut',
1199                                args=args)
1200             bake_lut.execute()
1201
1202         # *Flame*, *Lustre*
1203         for input_space in ['ACEScc', 'ACESproxy']:
1204             args = ['--iconfig', config_path,
1205                     '-v']
1206             if prefix:
1207                 args += ['--inputspace', 'ACES - %s' % input_space]
1208                 args += ['--outputspace', 'Output - %s' % odt_name]
1209             else:
1210                 args += ['--inputspace', input_space]
1211                 args += ['--outputspace', odt_name]
1212             args += ['--description',
1213                      '%s - %s for %s data' % (
1214                          odt_prefix, odt_name, input_space)]
1215             if prefix:
1216                 args += ['--shaperspace', 'Utility - %s' % shaper_name,
1217                          '--shapersize', str(lut_resolution_shaper)]
1218             else:
1219                 args += ['--shaperspace', shaper_name,
1220                          '--shapersize', str(lut_resolution_shaper)]
1221             args += ['--cubesize', str(lut_resolution_3d)]
1222
1223             fargs = ['--format',
1224                      'flame',
1225                      os.path.join(
1226                          baked_directory,
1227                          'flame',
1228                          '%s for %s Flame.3dl' % (odt_name, input_space))]
1229             bake_lut = Process(description='bake a LUT',
1230                                cmd='ociobakelut',
1231                                args=(args + fargs))
1232             bake_lut.execute()
1233
1234             largs = ['--format',
1235                      'lustre',
1236                      os.path.join(
1237                          baked_directory,
1238                          'lustre',
1239                          '%s for %s Lustre.3dl' % (odt_name, input_space))]
1240             bake_lut = Process(description='bake a LUT',
1241                                cmd='ociobakelut',
1242                                args=(args + largs))
1243             bake_lut.execute()
1244
1245         # *Maya*, *Houdini*
1246         for input_space in ['ACEScg', 'ACES2065-1']:
1247             args = ['--iconfig', config_path,
1248                     '-v']
1249             if prefix:
1250                 args += ['--inputspace', 'ACES - %s' % input_space]
1251                 args += ['--outputspace', 'Output - %s' % odt_name]
1252             else:
1253                 args += ['--inputspace', input_space]
1254                 args += ['--outputspace', odt_name]
1255             args += ['--description',
1256                      '%s - %s for %s data' % (
1257                          odt_prefix, odt_name, input_space)]
1258             if input_space == 'ACEScg':
1259                 lin_shaper_name = '%s - AP1' % shaper_name
1260             else:
1261                 lin_shaper_name = shaper_name
1262             if prefix:
1263                 lin_shaper_name = 'Utility - %s' % lin_shaper_name
1264             args += ['--shaperspace', lin_shaper_name,
1265                      '--shapersize', str(lut_resolution_shaper)]
1266
1267             args += ['--cubesize', str(lut_resolution_3d)]
1268
1269             margs = ['--format',
1270                      'cinespace',
1271                      os.path.join(
1272                          baked_directory,
1273                          'maya',
1274                          '%s for %s Maya.csp' % (odt_name, input_space))]
1275             bake_lut = Process(description='bake a LUT',
1276                                cmd='ociobakelut',
1277                                args=(args + margs))
1278             bake_lut.execute()
1279
1280             hargs = ['--format',
1281                      'houdini',
1282                      os.path.join(
1283                          baked_directory,
1284                          'houdini',
1285                          '%s for %s Houdini.lut' % (odt_name, input_space))]
1286             bake_lut = Process(description='bake a LUT',
1287                                cmd='ociobakelut',
1288                                args=(args + hargs))
1289             bake_lut.execute()
1290
1291
1292 def create_config_dir(config_directory,
1293                       bake_secondary_LUTs=False,
1294                       custom_lut_dir=None):
1295     """
1296     Object description.
1297
1298     Parameters
1299     ----------
1300     parameter : type
1301         Parameter description.
1302
1303     Returns
1304     -------
1305     type
1306          Return value description.
1307     """
1308
1309     lut_directory = os.path.join(config_directory, 'luts')
1310     dirs = [config_directory, lut_directory]
1311
1312     if bake_secondary_LUTs:
1313         dirs.extend([os.path.join(config_directory, 'baked'),
1314                      os.path.join(config_directory, 'baked', 'flame'),
1315                      os.path.join(config_directory, 'baked', 'photoshop'),
1316                      os.path.join(config_directory, 'baked', 'houdini'),
1317                      os.path.join(config_directory, 'baked', 'lustre'),
1318                      os.path.join(config_directory, 'baked', 'maya')])
1319
1320     if custom_lut_dir:
1321         dirs.append(os.path.join(config_directory, 'custom'))
1322
1323     for d in dirs:
1324         not os.path.exists(d) and os.mkdir(d)
1325
1326     return lut_directory
1327
1328
1329 def create_ACES_config(aces_ctl_directory,
1330                        config_directory,
1331                        lut_resolution_1d=4096,
1332                        lut_resolution_3d=64,
1333                        bake_secondary_LUTs=True,
1334                        multiple_displays=False,
1335                        look_info=None,
1336                        copy_custom_luts=True,
1337                        cleanup=True,
1338                        prefix_colorspaces_with_family_names=True):
1339     """
1340     Creates the ACES configuration.
1341
1342     Parameters
1343     ----------
1344     parameter : type
1345         Parameter description.
1346
1347     Returns
1348     -------
1349     type
1350          Return value description.
1351     """
1352
1353     if look_info is None:
1354         look_info = []
1355
1356     # Directory for custom LUTs
1357     custom_lut_dir = None
1358     if copy_custom_luts:
1359         custom_lut_dir = os.path.join(config_directory, 'custom')
1360
1361     lut_directory = create_config_dir(config_directory,
1362                                       bake_secondary_LUTs,
1363                                       custom_lut_dir)
1364
1365     odt_info = aces.get_ODTs_info(aces_ctl_directory)
1366     lmt_info = aces.get_LMTs_info(aces_ctl_directory)
1367
1368     shaper_name = 'Output Shaper'
1369     config_data = generate_LUTs(odt_info,
1370                                 lmt_info,
1371                                 shaper_name,
1372                                 aces_ctl_directory,
1373                                 lut_directory,
1374                                 lut_resolution_1d,
1375                                 lut_resolution_3d,
1376                                 cleanup)
1377
1378     print('Creating config - with prefixes, with aliases')
1379     config = create_config(config_data,
1380                            prefix=prefix_colorspaces_with_family_names,
1381                            aliases=True,
1382                            multiple_displays=multiple_displays,
1383                            look_info=look_info,
1384                            custom_lut_dir=custom_lut_dir)
1385     print('\n\n\n')
1386
1387     write_config(config,
1388                  os.path.join(config_directory, 'config.ocio'))
1389
1390     if bake_secondary_LUTs:
1391         generate_baked_LUTs(odt_info,
1392                             shaper_name,
1393                             os.path.join(config_directory, 'baked'),
1394                             os.path.join(config_directory, 'config.ocio'),
1395                             lut_resolution_1d,
1396                             lut_resolution_3d,
1397                             lut_resolution_1d,
1398                             prefix=prefix_colorspaces_with_family_names)
1399
1400     return True
1401
1402
1403 def main():
1404     """
1405     Object description.
1406
1407     Parameters
1408     ----------
1409     parameter : type
1410         Parameter description.
1411
1412     Returns
1413     -------
1414     type
1415          Return value description.
1416     """
1417
1418     import optparse
1419
1420     usage = '%prog [options]\n'
1421     usage += '\n'
1422     usage += 'An OCIO config generation script for ACES 1.0\n'
1423     usage += '\n'
1424     usage += 'Command line examples'
1425     usage += '\n'
1426     usage += ('Create a GUI-friendly ACES 1.0 config with no secondary, '
1427               'baked LUTs : \n')
1428     usage += ('\tcreate_aces_config -a /path/to/aces-dev/transforms/ctl '
1429               '--lutResolution1d 1024 --lutResolution3d 33 -c aces_1.0.0 '
1430               '--dontBakeSecondaryLUTs')
1431     usage += '\n'
1432     usage += 'Create a more OCIO-compliant ACES 1.0 config : \n'
1433     usage += ('\tcreate_aces_config -a /path/to/aces-dev/transforms/ctl '
1434               '--lutResolution1d 1024 --lutResolution3d 33 -c aces_1.0.0 '
1435               '--createMultipleDisplays')
1436     usage += '\n'
1437     usage += '\n'
1438     usage += 'Adding custom looks'
1439     usage += '\n'
1440     usage += ('Create a GUI-friendly ACES 1.0 config with an ACES-style CDL '
1441               '(will be applied in the ACEScc colorspace): \n')
1442     usage += ('\tcreate_aces_config -a /path/to/aces-dev/transforms/ctl '
1443               '--lutResolution1d 1024 --lutResolution3d 33 -c aces_1.0.0 '
1444               '\n\t\t--addACESLookCDL ACESCDLName '
1445               '/path/to/SampleCDL.ccc cc03345')
1446     usage += '\n'
1447     usage += 'Create a GUI-friendly ACES 1.0 config with an general CDL: \n'
1448     usage += ('\tcreate_aces_config -a /path/to/aces-dev/transforms/ctl '
1449               '--lutResolution1d 1024 --lutResolution3d 33 -c aces_1.0.0 '
1450               '\n\t\t--addCustomLookCDL CustomCDLName "ACES - ACEScc" '
1451               '/path/to/SampleCDL.ccc cc03345')
1452     usage += '\n'
1453     usage += ('\tIn this example, the CDL will be applied in the '
1454               'ACEScc colorspace, but the user could choose other spaces '
1455               'by changing the argument after the name of the look. \n')
1456     usage += '\n'
1457     usage += ('Create a GUI-friendly ACES 1.0 config with an ACES-style LUT '
1458               '(will be applied in the ACEScc colorspace): \n')
1459     usage += ('\tcreate_aces_config -a /path/to/aces-dev/transforms/ctl '
1460               '--lutResolution1d 1024 --lutResolution3d 33 -c aces_1.0.0 '
1461               '\n\t\t--addACESLookLUT ACESLUTName '
1462               '/path/to/SampleCDL.ccc cc03345')
1463     usage += '\n'
1464     usage += 'Create a GUI-friendly ACES 1.0 config with an general LUT: \n'
1465     usage += ('\tcreate_aces_config -a /path/to/aces-dev/transforms/ctl '
1466               '--lutResolution1d 1024 --lutResolution3d 33 -c aces_1.0.0 '
1467               '\n\t\t--addCustomLookLUT CustomLUTName "ACES - ACEScc" '
1468               '/path/to/SampleCDL.ccc cc03345')
1469     usage += '\n'
1470     usage += ('\tIn this example, the LUT will be applied in the '
1471               'ACEScc colorspace, but the user could choose other spaces '
1472               'by changing the argument after the name of the look. \n')
1473     usage += '\n'
1474
1475     look_info = []
1476
1477     def look_info_callback(option, opt_str, value, parser):
1478         print('look_info_callback')
1479         print(option, opt_str, value, parser)
1480         if opt_str == '--addCustomLookCDL':
1481             look_info.append(value)
1482         elif opt_str == '--addCustomLookLUT':
1483             look_info.append(value)
1484         elif opt_str == '--addACESLookCDL':
1485             look_info.append([value[0], 'ACES - ACEScc', value[1], value[2]])
1486         elif opt_str == '--addACESLookLUT':
1487             look_info.append([value[0], 'ACES - ACEScc', value[1]])
1488
1489     p = optparse.OptionParser(description='',
1490                               prog='create_aces_config',
1491                               version='create_aces_config 1.0',
1492                               usage=usage)
1493     p.add_option('--acesCTLDir', '-a', default=os.environ.get(
1494         ACES_OCIO_CTL_DIRECTORY_ENVIRON, None))
1495     p.add_option('--configDir', '-c', default=os.environ.get(
1496         ACES_OCIO_CONFIGURATION_DIRECTORY_ENVIRON, None))
1497     p.add_option('--lutResolution1d', default=4096)
1498     p.add_option('--lutResolution3d', default=64)
1499     p.add_option('--dontBakeSecondaryLUTs', action='store_true', default=False)
1500     p.add_option('--keepTempImages', action='store_true', default=False)
1501
1502     p.add_option('--createMultipleDisplays', action='store_true',
1503                  default=False)
1504
1505     p.add_option('--addCustomLookLUT', '', type='string', nargs=3,
1506                  action='callback', callback=look_info_callback)
1507     p.add_option('--addCustomLookCDL', '', type='string', nargs=4,
1508                  action='callback', callback=look_info_callback)
1509     p.add_option('--addACESLookLUT', '', type='string', nargs=2,
1510                  action='callback', callback=look_info_callback)
1511     p.add_option('--addACESLookCDL', '', type='string', nargs=3,
1512                  action='callback', callback=look_info_callback)
1513     p.add_option('--copyCustomLUTs', action='store_true', default=False)
1514
1515     options, arguments = p.parse_args()
1516
1517     aces_ctl_directory = options.acesCTLDir
1518     config_directory = options.configDir
1519     lut_resolution_1d = int(options.lutResolution1d)
1520     lut_resolution_3d = int(options.lutResolution3d)
1521     bake_secondary_luts = not options.dontBakeSecondaryLUTs
1522     cleanup_temp_images = not options.keepTempImages
1523     multiple_displays = options.createMultipleDisplays
1524     copy_custom_luts = options.copyCustomLUTs
1525
1526     print(look_info)
1527
1528     print('command line : \n%s\n' % ' '.join(sys.argv))
1529
1530     assert aces_ctl_directory is not None, (
1531         'process: No "{0}" environment variable defined or no "ACES CTL" '
1532         'directory specified'.format(
1533             ACES_OCIO_CTL_DIRECTORY_ENVIRON))
1534
1535     assert config_directory is not None, (
1536         'process: No "{0}" environment variable defined or no configuration '
1537         'directory specified'.format(
1538             ACES_OCIO_CONFIGURATION_DIRECTORY_ENVIRON))
1539
1540     return create_ACES_config(aces_ctl_directory,
1541                               config_directory,
1542                               lut_resolution_1d,
1543                               lut_resolution_3d,
1544                               bake_secondary_luts,
1545                               multiple_displays,
1546                               look_info,
1547                               copy_custom_luts,
1548                               cleanup_temp_images)
1549
1550
1551 if __name__ == '__main__':
1552     main()