2 # -*- coding: utf-8 -*-
5 Defines objects creating the *ACES* configuration.
8 from __future__ import division
13 import PyOpenColorIO as ocio
14 from aces_ocio.colorspaces import aces
15 from aces_ocio.colorspaces import arri
16 from aces_ocio.colorspaces import canon
17 from aces_ocio.colorspaces import general
18 from aces_ocio.colorspaces import gopro
19 from aces_ocio.colorspaces import panasonic
20 from aces_ocio.colorspaces import red
21 from aces_ocio.colorspaces import sony
22 from aces_ocio.process import Process
24 from aces_ocio.utilities import replace
26 __author__ = 'ACES Developers'
27 __copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers'
29 __maintainer__ = 'ACES Developers'
30 __email__ = 'aces@oscars.org'
31 __status__ = 'Production'
33 __all__ = ['ACES_OCIO_CTL_DIRECTORY_ENVIRON',
34 'ACES_OCIO_CONFIGURATION_DIRECTORY_ENVIRON',
35 'set_config_default_roles',
37 'generate_OCIO_transform',
38 'add_colorspace_alias',
41 'generate_baked_LUTs',
46 ACES_OCIO_CTL_DIRECTORY_ENVIRON = 'ACES_OCIO_CTL_DIRECTORY'
47 ACES_OCIO_CONFIGURATION_DIRECTORY_ENVIRON = 'ACES_OCIO_CONFIGURATION_DIRECTORY'
50 def set_config_default_roles(config,
61 compositing_linear=''):
63 Sets given *OCIO* configuration default roles.
69 color_picking : str or unicode
70 Color picking role title.
71 color_timing : str or unicode
72 Color timing role title.
73 compositing_log : str or unicode
74 Compositing log role title.
77 default : str or unicode
79 matte_paint : str or unicode
80 Matte painting role title.
81 reference : str or unicode
83 scene_linear : str or unicode
84 Scene linear role title.
85 texture_paint : str or unicode
86 Texture painting role title.
95 config.setRole(ocio.Constants.ROLE_COLOR_PICKING, color_picking)
97 config.setRole(ocio.Constants.ROLE_COLOR_TIMING, color_timing)
99 config.setRole(ocio.Constants.ROLE_COMPOSITING_LOG, compositing_log)
101 config.setRole(ocio.Constants.ROLE_DATA, data)
103 config.setRole(ocio.Constants.ROLE_DEFAULT, default)
105 config.setRole(ocio.Constants.ROLE_MATTE_PAINT, matte_paint)
107 config.setRole(ocio.Constants.ROLE_REFERENCE, reference)
109 config.setRole(ocio.Constants.ROLE_TEXTURE_PAINT, texture_paint)
111 # 'rendering' and 'compositing_linear' roles default to the 'scene_linear'
112 # value if not set explicitly
114 config.setRole("rendering", rendering)
115 if compositing_linear:
116 config.setRole("compositing_linear", compositing_linear)
118 config.setRole(ocio.Constants.ROLE_SCENE_LINEAR, scene_linear)
120 config.setRole("rendering", scene_linear)
121 if not compositing_linear:
122 config.setRole("compositing_linear", scene_linear)
127 def write_config(config, config_path, sanity_check=True):
129 Writes the configuration to given path.
134 Parameter description.
139 Return value description.
147 print 'Configuration was not written due to a failed Sanity Check'
150 with open(config_path, mode='w') as fp:
151 fp.write(config.serialize())
154 def generate_OCIO_transform(transforms):
161 Parameter description.
166 Return value description.
169 interpolation_options = {
170 'linear': ocio.Constants.INTERP_LINEAR,
171 'nearest': ocio.Constants.INTERP_NEAREST,
172 'tetrahedral': ocio.Constants.INTERP_TETRAHEDRAL}
174 direction_options = {
175 'forward': ocio.Constants.TRANSFORM_DIR_FORWARD,
176 'inverse': ocio.Constants.TRANSFORM_DIR_INVERSE}
180 for transform in transforms:
183 if transform['type'] == 'lutFile':
184 ocio_transform = ocio.FileTransform(
185 src=transform['path'],
186 interpolation=interpolation_options[
187 transform['interpolation']],
188 direction=direction_options[transform['direction']])
189 ocio_transforms.append(ocio_transform)
192 elif transform['type'] == 'matrix':
193 ocio_transform = ocio.MatrixTransform()
194 # MatrixTransform member variables can't be initialized directly.
195 # Each must be set individually.
196 ocio_transform.setMatrix(transform['matrix'])
198 if 'offset' in transform:
199 ocio_transform.setOffset(transform['offset'])
201 if 'direction' in transform:
202 ocio_transform.setDirection(
203 direction_options[transform['direction']])
205 ocio_transforms.append(ocio_transform)
208 elif transform['type'] == 'exponent':
209 ocio_transform = ocio.ExponentTransform()
210 ocio_transform.setValue(transform['value'])
211 ocio_transforms.append(ocio_transform)
214 elif transform['type'] == 'log':
215 ocio_transform = ocio.LogTransform(
216 base=transform['base'],
217 direction=direction_options[transform['direction']])
219 ocio_transforms.append(ocio_transform)
221 # color space transform
222 elif transform['type'] == 'colorspace':
223 ocio_transform = ocio.ColorSpaceTransform(src=transform['src'],
224 dst=transform['dst'],
228 ocio_transforms.append(ocio_transform)
231 print("Ignoring unknown transform type : %s" % transform['type'])
233 if len(ocio_transforms) > 1:
234 group_transform = ocio.GroupTransform()
235 for transform in ocio_transforms:
236 group_transform.push_back(transform)
237 transform = group_transform
239 transform = ocio_transforms[0]
244 def add_colorspace_alias(config,
245 reference_colorspace,
247 colorspace_alias_names):
254 Parameter description.
259 Return value description.
262 for alias_name in colorspace_alias_names:
263 if alias_name.lower() == colorspace.name.lower():
264 print('Skipping alias creation for %s, alias %s, because lower cased names match' % (
265 colorspace.name, alias_name) )
268 print('Adding alias colorspace space %s, alias to %s' % (
269 alias_name, colorspace.name))
271 compact_family_name = 'Aliases'
273 ocio_colorspace_alias = ocio.ColorSpace(
275 bitDepth=colorspace.bit_depth,
276 description=colorspace.description,
277 equalityGroup=colorspace.equality_group,
278 family=compact_family_name,
279 isData=colorspace.is_data,
280 allocation=colorspace.allocation_type,
281 allocationVars=colorspace.allocation_vars)
283 if colorspace.to_reference_transforms:
284 print('Generating To-Reference transforms')
285 ocio_transform = generate_OCIO_transform(
286 [{'type': 'colorspace',
287 'src': colorspace.name,
288 'dst': reference_colorspace.name,
289 'direction': 'forward'}])
290 ocio_colorspace_alias.setTransform(
292 ocio.Constants.COLORSPACE_DIR_TO_REFERENCE)
294 if colorspace.from_reference_transforms:
295 print('Generating From-Reference transforms')
296 ocio_transform = generate_OCIO_transform(
297 [{'type': 'colorspace',
298 'src': reference_colorspace.name,
299 'dst': colorspace.name,
300 'direction': 'forward'}])
301 ocio_colorspace_alias.setTransform(
303 ocio.Constants.COLORSPACE_DIR_FROM_REFERENCE)
305 config.addColorSpace(ocio_colorspace_alias)
307 def colorspace_prefixed_name(colorspace):
308 prefix = colorspace.family.replace("/", " - ")
309 return "%s - %s" % (prefix, colorspace.name)
311 def create_config(config_data,
314 multiple_displays=False):
321 Parameter description.
326 Return value description.
330 alias_colorspaces = []
332 # Creating the *OCIO* configuration.
333 config = ocio.Config()
335 # Setting configuration overall values.
336 config.setDescription('An ACES config generated from python')
337 config.setSearchPath('luts')
339 # Defining the reference colorspace.
340 reference_data = config_data['referenceColorSpace']
342 # Adding the color space Family into the name
343 # Helps with applications that present colorspaces as one long list
345 prefixed_name = colorspace_prefixed_name(reference_data)
346 prefixed_names[reference_data.name] = prefixed_name
347 reference_data.name = prefixed_name
349 print('Adding the reference color space : %s' % reference_data.name)
351 reference = ocio.ColorSpace(
352 name=reference_data.name,
353 bitDepth=reference_data.bit_depth,
354 description=reference_data.description,
355 equalityGroup=reference_data.equality_group,
356 family=reference_data.family,
357 isData=reference_data.is_data,
358 allocation=reference_data.allocation_type,
359 allocationVars=reference_data.allocation_vars)
361 config.addColorSpace(reference)
365 if reference_data.aliases != []:
366 #add_colorspace_alias(config, reference_data,
367 # reference_data, reference_data.aliases)
368 # defer adding alias colorspaces until end. Helps with some applications
369 alias_colorspaces.append([reference_data, reference_data, reference_data.aliases])
374 #print( "color spaces : %s" % [x.name for x in sorted(config_data['colorSpaces'])])
376 print('Adding the regular color spaces')
378 # Creating the remaining colorspaces.
379 for colorspace in sorted(config_data['colorSpaces']):
380 # Adding the color space Family into the name
381 # Helps with applications that present colorspaces as one long list
383 prefixed_name = colorspace_prefixed_name(colorspace)
384 prefixed_names[colorspace.name] = prefixed_name
385 colorspace.name = prefixed_name
387 print('Creating new color space : %s' % colorspace.name)
389 ocio_colorspace = ocio.ColorSpace(
390 name=colorspace.name,
391 bitDepth=colorspace.bit_depth,
392 description=colorspace.description,
393 equalityGroup=colorspace.equality_group,
394 family=colorspace.family,
395 isData=colorspace.is_data,
396 allocation=colorspace.allocation_type,
397 allocationVars=colorspace.allocation_vars)
399 if colorspace.to_reference_transforms:
400 print('Generating To-Reference transforms')
401 ocio_transform = generate_OCIO_transform(
402 colorspace.to_reference_transforms)
403 ocio_colorspace.setTransform(
405 ocio.Constants.COLORSPACE_DIR_TO_REFERENCE)
407 if colorspace.from_reference_transforms:
408 print('Generating From-Reference transforms')
409 ocio_transform = generate_OCIO_transform(
410 colorspace.from_reference_transforms)
411 ocio_colorspace.setTransform(
413 ocio.Constants.COLORSPACE_DIR_FROM_REFERENCE)
415 config.addColorSpace(ocio_colorspace)
418 # Add alias to normal colorspace, using compact name
421 if colorspace.aliases != []:
422 #add_colorspace_alias(config, reference_data,
423 # colorspace, colorspace.aliases)
424 # defer adding alias colorspaces until end. Helps with some applications
425 alias_colorspaces.append([reference_data, colorspace, colorspace.aliases])
431 # We add these at the end as some applications use the order of the colorspaces
432 # definitions in the config to order the colorspaces in their selection lists.
433 # Other go alphabetically. This should keep the alias colorspaces out of the way
434 # for the apps that use the order of definition in the config.
435 print('Adding the alias colorspaces')
436 for reference, colorspace, aliases in alias_colorspaces:
437 add_colorspace_alias(config, reference, colorspace, aliases)
441 print('Adding the diplays and views')
443 # Defining the *views* and *displays*.
448 # Defining a *generic* *display* and *view* setup.
449 if multiple_displays:
450 for display, view_list in config_data['displays'].iteritems():
451 for view_name, colorspace in view_list.iteritems():
452 config.addDisplay(display, view_name, colorspace.name)
453 if not (view_name in views):
454 views.append(view_name)
455 displays.append(display)
458 # Defining the set of *views* and *displays* useful in a *GUI* context.
459 #display_name = 'ACES'
460 display_name = config_data['roles']['scene_linear']
461 displays.append(display_name)
463 display_names = sorted(config_data['displays'])
465 # Make sure the default display is first
466 default_display = config_data['defaultDisplay']
467 display_names.insert(0, display_names.pop(display_names.index(default_display)))
469 for display in display_names:
470 view_list = config_data['displays'][display]
471 for view_name, colorspace in view_list.iteritems():
472 if view_name == 'Output Transform':
473 display_cleaned = replace(display, {')': '', '(': ''})
474 config.addDisplay(display_name, display_cleaned, colorspace.name)
475 if not (display_cleaned in views):
476 views.append(display_cleaned)
478 # Works with Nuke Studio and Mari, but not Nuke
479 # display_name = 'Utility'
480 # displays.append(display_name)
482 linear_display_space_name = config_data['roles']['scene_linear']
483 log_display_space_name = config_data['roles']['compositing_log']
485 # Find the newly-prefixed colorspace names
487 #print( prefixed_names )
488 linear_display_space_name = prefixed_names[linear_display_space_name]
489 log_display_space_name = prefixed_names[log_display_space_name]
491 config.addDisplay(display_name, 'Linear', linear_display_space_name)
492 views.append('Linear')
493 config.addDisplay(display_name, 'Log', log_display_space_name)
496 # Setting the active *displays* and *views*.
497 config.setActiveDisplays(','.join(sorted(displays)))
498 config.setActiveViews(','.join(views))
502 print('Setting the roles')
505 set_config_default_roles(
507 color_picking=prefixed_names[config_data['roles']['color_picking']],
508 color_timing=prefixed_names[config_data['roles']['color_timing']],
509 compositing_log=prefixed_names[config_data['roles']['compositing_log']],
510 data=prefixed_names[config_data['roles']['data']],
511 default=prefixed_names[config_data['roles']['default']],
512 matte_paint=prefixed_names[config_data['roles']['matte_paint']],
513 reference=prefixed_names[config_data['roles']['reference']],
514 scene_linear=prefixed_names[config_data['roles']['scene_linear']],
515 texture_paint=prefixed_names[config_data['roles']['texture_paint']])
517 set_config_default_roles(
519 color_picking=config_data['roles']['color_picking'],
520 color_timing=config_data['roles']['color_timing'],
521 compositing_log=config_data['roles']['compositing_log'],
522 data=config_data['roles']['data'],
523 default=config_data['roles']['default'],
524 matte_paint=config_data['roles']['matte_paint'],
525 reference=config_data['roles']['reference'],
526 scene_linear=config_data['roles']['scene_linear'],
527 texture_paint=config_data['roles']['texture_paint'])
531 # Make sure we didn't create a bad config
534 # Reset the colorspace names back to their non-prefixed versions
536 # Build the reverse lookup
537 prefixed_names_inverse = {}
538 for original, prefixed in prefixed_names.iteritems():
539 prefixed_names_inverse[prefixed] = original
541 # Reet the reference colorspace name
542 reference_data.name = prefixed_names_inverse[reference_data.name]
544 # Reset the rest of the colorspace names
545 for colorspace in config_data['colorSpaces']:
546 colorspace.name = prefixed_names_inverse[colorspace.name]
551 def generate_LUTs(odt_info,
556 lut_resolution_1d=4096,
557 lut_resolution_3d=64,
565 Parameter description.
570 Colorspaces and transforms converting between those colorspaces and
571 the reference colorspace, *ACES*.
574 print('generateLUTs - begin')
577 # Initialize a few variables
578 config_data['displays'] = {}
579 config_data['colorSpaces'] = []
581 # -------------------------------------------------------------------------
582 # *ACES Color Spaces*
583 # -------------------------------------------------------------------------
589 aces_log_display_space,
591 aces_default_display) = aces.create_colorspaces(aces_ctl_directory,
600 config_data['referenceColorSpace'] = aces_reference
601 config_data['roles'] = aces_roles
603 for cs in aces_colorspaces:
604 config_data['colorSpaces'].append(cs)
606 for name, data in aces_displays.iteritems():
607 config_data['displays'][name] = data
609 config_data['defaultDisplay'] = aces_default_display
610 config_data['linearDisplaySpace'] = aces_reference
611 config_data['logDisplaySpace'] = aces_log_display_space
613 # -------------------------------------------------------------------------
614 # *Camera Input Transforms*
615 # -------------------------------------------------------------------------
617 # *ARRI Log-C* to *ACES*.
618 arri_colorSpaces = arri.create_colorspaces(lut_directory,
620 for cs in arri_colorSpaces:
621 config_data['colorSpaces'].append(cs)
623 # *Canon-Log* to *ACES*.
624 canon_colorspaces = canon.create_colorspaces(lut_directory,
626 for cs in canon_colorspaces:
627 config_data['colorSpaces'].append(cs)
629 # *GoPro Protune* to *ACES*.
630 gopro_colorspaces = gopro.create_colorspaces(lut_directory,
632 for cs in gopro_colorspaces:
633 config_data['colorSpaces'].append(cs)
635 # *Panasonic V-Log* to *ACES*.
636 panasonic_colorSpaces = panasonic.create_colorspaces(lut_directory,
638 for cs in panasonic_colorSpaces:
639 config_data['colorSpaces'].append(cs)
641 # *RED* colorspaces to *ACES*.
642 red_colorspaces = red.create_colorspaces(lut_directory,
644 for cs in red_colorspaces:
645 config_data['colorSpaces'].append(cs)
648 sony_colorSpaces = sony.create_colorspaces(lut_directory,
650 for cs in sony_colorSpaces:
651 config_data['colorSpaces'].append(cs)
653 # -------------------------------------------------------------------------
654 # General Color Spaces
655 # -------------------------------------------------------------------------
656 general_colorSpaces = general.create_colorspaces(lut_directory,
659 for cs in general_colorSpaces:
660 config_data['colorSpaces'].append(cs)
662 # The *Raw* color space
663 raw = general.create_raw()
664 config_data['colorSpaces'].append(raw)
666 # Override certain roles, for now
667 config_data['roles']['data'] = raw.name
668 config_data['roles']['reference'] = raw.name
669 config_data['roles']['texture_paint'] = raw.name
671 print('generateLUTs - end')
675 def generate_baked_LUTs(odt_info,
681 lut_resolution_shaper=1024):
688 Parameter description.
693 Return value description.
696 # Create two entries for ODTs that have full and legal range support
697 odt_info_C = dict(odt_info)
698 for odt_ctl_name, odt_values in odt_info.iteritems():
699 if odt_values['transformHasFullLegalSwitch']:
700 odt_name = odt_values['transformUserName']
702 odt_values_legal = dict(odt_values)
703 odt_values_legal['transformUserName'] = '%s - Legal' % odt_name
704 odt_info_C['%s - Legal' % odt_ctl_name] = odt_values_legal
706 odt_values_full = dict(odt_values)
707 odt_values_full['transformUserName'] = '%s - Full' % odt_name
708 odt_info_C['%s - Full' % odt_ctl_name] = odt_values_full
710 del (odt_info_C[odt_ctl_name])
712 # Generate appropriate LUTs for each ODT
713 for odt_ctl_name, odt_values in odt_info_C.iteritems():
714 odt_prefix = odt_values['transformUserNamePrefix']
715 odt_name = odt_values['transformUserName']
718 for input_space in ['ACEScc', 'ACESproxy']:
719 args = ['--iconfig', config_path,
721 '--inputspace', input_space]
722 args += ['--outputspace', '%s' % odt_name]
723 args += ['--description',
724 '%s - %s for %s data' % (odt_prefix,
727 args += ['--shaperspace', shaper_name,
728 '--shapersize', str(lut_resolution_shaper)]
729 args += ['--cubesize', str(lut_resolution_3d)]
732 os.path.join(baked_directory,
734 '%s for %s.icc' % (odt_name, input_space))]
736 bake_lut = Process(description='bake a LUT',
742 for input_space in ['ACEScc', 'ACESproxy']:
743 args = ['--iconfig', config_path,
745 '--inputspace', input_space]
746 args += ['--outputspace', '%s' % odt_name]
747 args += ['--description',
748 '%s - %s for %s data' % (
749 odt_prefix, odt_name, input_space)]
750 args += ['--shaperspace', shaper_name,
751 '--shapersize', str(lut_resolution_shaper)]
752 args += ['--cubesize', str(lut_resolution_3d)]
759 '%s for %s Flame.3dl' % (odt_name, input_space))]
760 bake_lut = Process(description='bake a LUT',
770 '%s for %s Lustre.3dl' % (odt_name, input_space))]
771 bake_lut = Process(description='bake a LUT',
777 for input_space in ['ACEScg', 'ACES2065-1']:
778 args = ['--iconfig', config_path,
780 '--inputspace', input_space]
781 args += ['--outputspace', '%s' % odt_name]
782 args += ['--description',
783 '%s - %s for %s data' % (
784 odt_prefix, odt_name, input_space)]
785 if input_space == 'ACEScg':
786 lin_shaper_name = '%s - AP1' % shaper_name
788 lin_shaper_name = shaper_name
789 args += ['--shaperspace', lin_shaper_name,
790 '--shapersize', str(lut_resolution_shaper)]
792 args += ['--cubesize', str(lut_resolution_3d)]
799 '%s for %s Maya.csp' % (odt_name, input_space))]
800 bake_lut = Process(description='bake a LUT',
810 '%s for %s Houdini.lut' % (odt_name, input_space))]
811 bake_lut = Process(description='bake a LUT',
817 def create_config_dir(config_directory, bake_secondary_LUTs):
824 Parameter description.
829 Return value description.
832 lut_directory = os.path.join(config_directory, 'luts')
833 dirs = [config_directory, lut_directory]
834 if bake_secondary_LUTs:
835 dirs.extend([os.path.join(config_directory, 'baked'),
836 os.path.join(config_directory, 'baked', 'flame'),
837 os.path.join(config_directory, 'baked', 'photoshop'),
838 os.path.join(config_directory, 'baked', 'houdini'),
839 os.path.join(config_directory, 'baked', 'lustre'),
840 os.path.join(config_directory, 'baked', 'maya')])
843 not os.path.exists(d) and os.mkdir(d)
848 def create_ACES_config(aces_ctl_directory,
850 lut_resolution_1d=4096,
851 lut_resolution_3d=64,
852 bake_secondary_LUTs=True,
853 multiple_displays=False,
856 Creates the ACES configuration.
861 Parameter description.
866 Return value description.
869 lut_directory = create_config_dir(config_directory, bake_secondary_LUTs)
871 odt_info = aces.get_ODTs_info(aces_ctl_directory)
872 lmt_info = aces.get_LMTs_info(aces_ctl_directory)
874 shaper_name = 'Output Shaper'
875 config_data = generate_LUTs(odt_info,
884 print('Creating config - with prefixes, with aliases')
885 config = create_config(config_data,
886 prefix=True, aliases=True, multiple_displays=multiple_displays)
890 os.path.join(config_directory, 'config.ocio'))
892 if bake_secondary_LUTs:
893 generate_baked_LUTs(odt_info,
895 os.path.join(config_directory, 'baked'),
896 os.path.join(config_directory, 'config.ocio'),
911 Parameter description.
916 Return value description.
921 usage = '%prog [options]\n'
923 usage += 'An OCIO config generation script for ACES 1.0\n'
925 usage += 'Command line examples'
927 usage += 'Create a GUI-friendly ACES 1.0 config with no secondary, baked LUTs : \n'
928 usage += '\tcreate_aces_config -a /path/to/aces-dev/transforms/ctl --lutResolution1d 1024 --lutResolution3d 33 -c aces_1.0.0 --dontBakeSecondaryLUTs'
930 usage += 'Create a traditional ACES 1.0 config with secondary, baked LUTs : \n'
931 usage += '\tcreate_aces_config -a /path/to/aces-dev/transforms/ctl --lutResolution1d 1024 --lutResolution3d 33 -c aces_1.0.0 --createMultipleDisplays'
934 p = optparse.OptionParser(description='',
935 prog='create_aces_config',
936 version='create_aces_config 1.0',
938 p.add_option('--acesCTLDir', '-a', default=os.environ.get(
939 ACES_OCIO_CTL_DIRECTORY_ENVIRON, None))
940 p.add_option('--configDir', '-c', default=os.environ.get(
941 ACES_OCIO_CONFIGURATION_DIRECTORY_ENVIRON, None))
942 p.add_option('--lutResolution1d', default=4096)
943 p.add_option('--lutResolution3d', default=64)
944 p.add_option('--dontBakeSecondaryLUTs', action='store_true', default=False)
945 p.add_option('--keepTempImages', action='store_true', default=False)
946 p.add_option('--createMultipleDisplays', action='store_true', default=False)
948 options, arguments = p.parse_args()
950 aces_ctl_directory = options.acesCTLDir
951 config_directory = options.configDir
952 lut_resolution_1d = int(options.lutResolution1d)
953 lut_resolution_3d = int(options.lutResolution3d)
954 bake_secondary_luts = not options.dontBakeSecondaryLUTs
955 cleanup_temp_images = not options.keepTempImages
956 multiple_displays = options.createMultipleDisplays
958 # TODO: Investigate the following statements.
960 args_start = sys.argv.index('--') + 1
961 args = sys.argv[args_start:]
963 args_start = len(sys.argv) + 1
966 print('command line : \n%s\n' % ' '.join(sys.argv))
968 assert aces_ctl_directory is not None, (
969 'process: No "{0}" environment variable defined or no "ACES CTL" '
970 'directory specified'.format(
971 ACES_OCIO_CTL_DIRECTORY_ENVIRON))
973 assert config_directory is not None, (
974 'process: No "{0}" environment variable defined or no configuration '
975 'directory specified'.format(
976 ACES_OCIO_CONFIGURATION_DIRECTORY_ENVIRON))
978 return create_ACES_config(aces_ctl_directory,
986 if __name__ == '__main__':