X-Git-Url: http://users.mur.at/ms/git/gitweb/?a=blobdiff_plain;f=aces_1.0.0%2Fpython%2Faces_ocio%2Fcreate_aces_config.py;h=5a579ca040f565f69d43fdc0d371027974eeac48;hb=24460c4f42d9e44101d414ef15579e5f7d250bb7;hp=cde204785931d34e948d5388bd5fa8f24ab862be;hpb=cf95d5c0a20737d4628197974038cec795ece2e7;p=OpenColorIO-Configs.git diff --git a/aces_1.0.0/python/aces_ocio/create_aces_config.py b/aces_1.0.0/python/aces_ocio/create_aces_config.py index cde2047..5a579ca 100755 --- a/aces_1.0.0/python/aces_ocio/create_aces_config.py +++ b/aces_1.0.0/python/aces_ocio/create_aces_config.py @@ -5,12 +5,9 @@ Defines objects creating the *ACES* configuration. """ -import math -#import numpy +from __future__ import division + import os -#import pprint -import shutil -import string import sys import PyOpenColorIO as ocio @@ -18,16 +15,13 @@ import PyOpenColorIO as ocio import aces_ocio.create_aces_colorspaces as aces import aces_ocio.create_arri_colorspaces as arri import aces_ocio.create_canon_colorspaces as canon +import aces_ocio.create_gopro_colorspaces as gopro +import aces_ocio.create_panasonic_colorspaces as panasonic import aces_ocio.create_red_colorspaces as red import aces_ocio.create_sony_colorspaces as sony import aces_ocio.create_general_colorspaces as general -from aces_ocio.generate_lut import ( - generate_1d_LUT_from_CTL, - generate_3d_LUT_from_CTL, - write_SPI_1d) from aces_ocio.process import Process -from aces_ocio.utilities import ColorSpace, mat44_from_mat33, sanitize_path, compact __author__ = 'ACES Developers' __copyright__ = 'Copyright (C) 2014 - 2015 - ACES Developers' @@ -41,13 +35,11 @@ __all__ = ['ACES_OCIO_CTL_DIRECTORY_ENVIRON', 'set_config_default_roles', 'write_config', 'generate_OCIO_transform', + 'add_colorspace_alias', 'create_config', 'generate_LUTs', 'generate_baked_LUTs', 'create_config_dir', - 'get_transform_info', - 'get_ODT_info', - 'get_LMT_info', 'create_ACES_config', 'main'] @@ -164,12 +156,11 @@ def generate_OCIO_transform(transforms): interpolation_options = { 'linear': ocio.Constants.INTERP_LINEAR, 'nearest': ocio.Constants.INTERP_NEAREST, - 'tetrahedral': ocio.Constants.INTERP_TETRAHEDRAL - } + 'tetrahedral': ocio.Constants.INTERP_TETRAHEDRAL} + direction_options = { 'forward': ocio.Constants.TRANSFORM_DIR_FORWARD, - 'inverse': ocio.Constants.TRANSFORM_DIR_INVERSE - } + 'inverse': ocio.Constants.TRANSFORM_DIR_INVERSE} ocio_transforms = [] @@ -183,7 +174,7 @@ def generate_OCIO_transform(transforms): transform['interpolation']], direction=direction_options[transform['direction']]) ocio_transforms.append(ocio_transform) - + # matrix transform elif transform['type'] == 'matrix': ocio_transform = ocio.MatrixTransform() @@ -216,11 +207,12 @@ def generate_OCIO_transform(transforms): # color space transform elif transform['type'] == 'colorspace': - ocio_transform = ocio.ColorSpaceTransform( src=transform['src'], - dst=transform['dst'], - direction=direction_options['forward'] ) + ocio_transform = ocio.ColorSpaceTransform(src=transform['src'], + dst=transform['dst'], + direction= + direction_options[ + 'forward']) ocio_transforms.append(ocio_transform) - # unknown type else: print("Ignoring unknown transform type : %s" % transform['type']) @@ -235,7 +227,11 @@ def generate_OCIO_transform(transforms): return transform -def add_colorspace_alias(config, reference_colorspace, colorspace, colorspace_alias_names): + +def add_colorspace_alias(config, + reference_colorspace, + colorspace, + colorspace_alias_names): """ Object description. @@ -254,10 +250,10 @@ def add_colorspace_alias(config, reference_colorspace, colorspace, colorspace_al if alias_name == colorspace.name.lower(): return - print( "Adding alias colorspace space %s, alias to %s" % ( + print('Adding alias colorspace space %s, alias to %s' % ( alias_name, colorspace.name)) - compact_family_name = "Aliases" + compact_family_name = 'Aliases' ocio_colorspace_alias = ocio.ColorSpace( name=alias_name, @@ -269,26 +265,24 @@ def add_colorspace_alias(config, reference_colorspace, colorspace, colorspace_al allocation=colorspace.allocation_type, allocationVars=colorspace.allocation_vars) - if colorspace.to_reference_transforms != []: - print("Generating To-Reference transforms") - ocio_transform = generate_OCIO_transform([{ - 'type': 'colorspace', - 'src': colorspace.name, - 'dst': reference_colorspace.name, - 'direction': 'forward' - }]) + if not colorspace.to_reference_transforms: + print('Generating To-Reference transforms') + ocio_transform = generate_OCIO_transform( + [{'type': 'colorspace', + 'src': colorspace.name, + 'dst': reference_colorspace.name, + 'direction': 'forward'}]) ocio_colorspace_alias.setTransform( ocio_transform, ocio.Constants.COLORSPACE_DIR_TO_REFERENCE) - if colorspace.from_reference_transforms != []: - print("Generating From-Reference transforms") - ocio_transform = generate_OCIO_transform([{ - 'type': 'colorspace', - 'src': reference_colorspace.name, - 'dst': colorspace.name, - 'direction': 'forward' - }]) + if not colorspace.from_reference_transforms: + print('Generating From-Reference transforms') + ocio_transform = generate_OCIO_transform( + [{'type': 'colorspace', + 'src': reference_colorspace.name, + 'dst': colorspace.name, + 'direction': 'forward'}]) ocio_colorspace_alias.setTransform( ocio_transform, ocio.Constants.COLORSPACE_DIR_FROM_REFERENCE) @@ -337,7 +331,7 @@ def create_config(config_data, nuke=False): # Add alias if reference_data.aliases != []: add_colorspace_alias(config, reference_data, - reference_data, reference_data.aliases) + reference_data, reference_data.aliases) print("") @@ -377,8 +371,8 @@ def create_config(config_data, nuke=False): # Add alias to normal colorspace, using compact name # if colorspace.aliases != []: - add_colorspace_alias(config, reference_data, - colorspace, colorspace.aliases) + add_colorspace_alias(config, reference_data, + colorspace, colorspace.aliases) print('') @@ -397,22 +391,25 @@ def create_config(config_data, nuke=False): # Defining the *Nuke* specific set of *views* and *displays*. else: - for display, view_list in config_data['displays'].iteritems(): + display_name = 'Output' + displays.append(display_name) + + display_names = sorted(config_data['displays']) + for display in display_names: + view_list = config_data['displays'][display] for view_name, colorspace in view_list.iteritems(): if view_name == 'Output Transform': - view_name = 'View' - config.addDisplay(display, view_name, colorspace.name) - if not (view_name in views): - views.append(view_name) - displays.append(display) + config.addDisplay(display_name, display, colorspace.name) + if not (display in views): + views.append(display) linear_display_space_name = config_data['linearDisplaySpace'].name log_display_space_name = config_data['logDisplaySpace'].name - config.addDisplay('linear', 'View', linear_display_space_name) - displays.append('linear') - config.addDisplay('log', 'View', log_display_space_name) - displays.append('log') + config.addDisplay(display_name, 'Linear', linear_display_space_name) + views.append('Linear') + config.addDisplay(display_name, 'Log', log_display_space_name) + views.append('Log') # Setting the active *displays* and *views*. config.setActiveDisplays(','.join(sorted(displays))) @@ -420,24 +417,25 @@ def create_config(config_data, nuke=False): set_config_default_roles( config, - color_picking=reference.getName(), - color_timing=reference.getName(), - compositing_log=reference.getName(), - data=reference.getName(), - default=reference.getName(), - matte_paint=reference.getName(), - reference=reference.getName(), - scene_linear=reference.getName(), - texture_paint=reference.getName()) + color_picking=config_data['roles']['color_picking'], + color_timing=config_data['roles']['color_timing'], + compositing_log=config_data['roles']['compositing_log'], + data=config_data['roles']['data'], + default=config_data['roles']['default'], + matte_paint=config_data['roles']['matte_paint'], + reference=config_data['roles']['reference'], + scene_linear=config_data['roles']['scene_linear'], + texture_paint=config_data['roles']['texture_paint']) config.sanityCheck() return config + def generate_LUTs(odt_info, lmt_info, shaper_name, - aces_CTL_directory, + aces_ctl_directory, lut_directory, lut_resolution_1d=4096, lut_resolution_3d=64, @@ -470,18 +468,20 @@ def generate_LUTs(odt_info, # *ACES* colorspaces (aces_reference, - aces_colorspaces, + aces_colorspaces, aces_displays, - aces_log_display_space) = aces.create_colorspaces(aces_CTL_directory, - lut_directory, - lut_resolution_1d, - lut_resolution_3d, - lmt_info, - odt_info, - shaper_name, - cleanup) + aces_log_display_space, + aces_roles) = aces.create_colorspaces(aces_ctl_directory, + lut_directory, + lut_resolution_1d, + lut_resolution_3d, + lmt_info, + odt_info, + shaper_name, + cleanup) config_data['referenceColorSpace'] = aces_reference + config_data['roles'] = aces_roles for cs in aces_colorspaces: config_data['colorSpaces'].append(cs) @@ -496,7 +496,7 @@ def generate_LUTs(odt_info, # *Camera Input Transforms* # ------------------------------------------------------------------------- - # *Log-C* to *ACES*. + # *ARRI Log-C* to *ACES*. arri_colorSpaces = arri.create_colorspaces(lut_directory, lut_resolution_1d) for cs in arri_colorSpaces: @@ -508,8 +508,20 @@ def generate_LUTs(odt_info, for cs in canon_colorspaces: config_data['colorSpaces'].append(cs) + # *GoPro Protune* to *ACES*. + gopro_colorspaces = gopro.create_colorspaces(lut_directory, + lut_resolution_1d) + for cs in gopro_colorspaces: + config_data['colorSpaces'].append(cs) + + # *Panasonic V-Log* to *ACES*. + panasonic_colorSpaces = panasonic.create_colorspaces(lut_directory, + lut_resolution_1d) + for cs in panasonic_colorSpaces: + config_data['colorSpaces'].append(cs) + # *RED* colorspaces to *ACES*. - red_colorspaces = red.create_colorspaces(lut_directory, + red_colorspaces = red.create_colorspaces(lut_directory, lut_resolution_1d) for cs in red_colorspaces: config_data['colorSpaces'].append(cs) @@ -529,6 +541,18 @@ def generate_LUTs(odt_info, for cs in general_colorSpaces: config_data['colorSpaces'].append(cs) + # The *Raw* color space + raw = general.create_raw() + config_data['colorSpaces'].append(raw) + + # Override 'linear' display + config_data['linearDisplaySpace'] = raw + + # Override certain roles, for now + config_data['roles']['data'] = raw.name + config_data['roles']['reference'] = raw.name + config_data['roles']['texture_paint'] = raw.name + print('generateLUTs - end') return config_data @@ -554,24 +578,24 @@ def generate_baked_LUTs(odt_info, Return value description. """ + # Create two entries for ODTs that have full and legal range support odt_info_C = dict(odt_info) - for odt_CTL_name, odt_values in odt_info.iteritems(): - if odt_CTL_name in ['Academy.Rec2020_100nits_dim.a1.0.0', - 'Academy.Rec709_100nits_dim.a1.0.0', - 'Academy.Rec709_D60sim_100nits_dim.a1.0.0']: + for odt_ctl_name, odt_values in odt_info.iteritems(): + if odt_values['transformHasFullLegalSwitch']: odt_name = odt_values['transformUserName'] odt_values_legal = dict(odt_values) odt_values_legal['transformUserName'] = '%s - Legal' % odt_name - odt_info_C['%s - Legal' % odt_CTL_name] = odt_values_legal + odt_info_C['%s - Legal' % odt_ctl_name] = odt_values_legal odt_values_full = dict(odt_values) odt_values_full['transformUserName'] = '%s - Full' % odt_name - odt_info_C['%s - Full' % odt_CTL_name] = odt_values_full + odt_info_C['%s - Full' % odt_ctl_name] = odt_values_full - del (odt_info_C[odt_CTL_name]) + del (odt_info_C[odt_ctl_name]) - for odt_CTL_name, odt_values in odt_info_C.iteritems(): + # Generate appropriate LUTs for each ODT + for odt_ctl_name, odt_values in odt_info_C.iteritems(): odt_prefix = odt_values['transformUserNamePrefix'] odt_name = odt_values['transformUserName'] @@ -594,10 +618,10 @@ def generate_baked_LUTs(odt_info, 'photoshop', '%s for %s.icc' % (odt_name, input_space))] - bake_LUT = Process(description='bake a LUT', + bake_lut = Process(description='bake a LUT', cmd='ociobakelut', args=args) - bake_LUT.execute() + bake_lut.execute() # *Flame*, *Lustre* for input_space in ['ACEScc', 'ACESproxy']: @@ -618,10 +642,10 @@ def generate_baked_LUTs(odt_info, baked_directory, 'flame', '%s for %s Flame.3dl' % (odt_name, input_space))] - bake_LUT = Process(description='bake a LUT', + bake_lut = Process(description='bake a LUT', cmd='ociobakelut', args=(args + fargs)) - bake_LUT.execute() + bake_lut.execute() largs = ['--format', 'lustre', @@ -629,10 +653,10 @@ def generate_baked_LUTs(odt_info, baked_directory, 'lustre', '%s for %s Lustre.3dl' % (odt_name, input_space))] - bake_LUT = Process(description='bake a LUT', + bake_lut = Process(description='bake a LUT', cmd='ociobakelut', args=(args + largs)) - bake_LUT.execute() + bake_lut.execute() # *Maya*, *Houdini* for input_space in ['ACEScg', 'ACES2065-1']: @@ -658,10 +682,10 @@ def generate_baked_LUTs(odt_info, baked_directory, 'maya', '%s for %s Maya.csp' % (odt_name, input_space))] - bake_LUT = Process(description='bake a LUT', + bake_lut = Process(description='bake a LUT', cmd='ociobakelut', args=(args + margs)) - bake_LUT.execute() + bake_lut.execute() hargs = ['--format', 'houdini', @@ -669,10 +693,10 @@ def generate_baked_LUTs(odt_info, baked_directory, 'houdini', '%s for %s Houdini.lut' % (odt_name, input_space))] - bake_LUT = Process(description='bake a LUT', + bake_lut = Process(description='bake a LUT', cmd='ociobakelut', args=(args + hargs)) - bake_LUT.execute() + bake_lut.execute() def create_config_dir(config_directory, bake_secondary_LUTs): @@ -705,206 +729,8 @@ def create_config_dir(config_directory, bake_secondary_LUTs): return lut_directory -def get_transform_info(ctl_transform): - """ - Object description. - - Parameters - ---------- - parameter : type - Parameter description. - - Returns - ------- - type - Return value description. - """ - - with open(ctl_transform, 'rb') as fp: - lines = fp.readlines() - - # Retrieving the *transform ID* and *User Name*. - transform_id = lines[1][3:].split('<')[1].split('>')[1].strip() - transform_user_name = '-'.join( - lines[2][3:].split('<')[1].split('>')[1].split('-')[1:]).strip() - transform_user_name_prefix = ( - lines[2][3:].split('<')[1].split('>')[1].split('-')[0].strip()) - - return transform_id, transform_user_name, transform_user_name_prefix - - -def get_ODT_info(aces_CTL_directory): - """ - Object description. - - For versions after WGR9. - - Parameters - ---------- - parameter : type - Parameter description. - - Returns - ------- - type - Return value description. - """ - - # TODO: Investigate usage of *files_walker* definition here. - # Credit to *Alex Fry* for the original approach here. - odt_dir = os.path.join(aces_CTL_directory, 'odt') - all_odt = [] - for dir_name, subdir_list, file_list in os.walk(odt_dir): - for fname in file_list: - all_odt.append((os.path.join(dir_name, fname))) - - odt_CTLs = [x for x in all_odt if - ('InvODT' not in x) and (os.path.split(x)[-1][0] != '.')] - - odts = {} - - for odt_CTL in odt_CTLs: - odt_tokens = os.path.split(odt_CTL) - - # Handling nested directories. - odt_path_tokens = os.path.split(odt_tokens[-2]) - odt_dir = odt_path_tokens[-1] - while odt_path_tokens[-2][-3:] != 'odt': - odt_path_tokens = os.path.split(odt_path_tokens[-2]) - odt_dir = os.path.join(odt_path_tokens[-1], odt_dir) - - # Building full name, - transform_CTL = odt_tokens[-1] - odt_name = string.join(transform_CTL.split('.')[1:-1], '.') - - # Finding id, user name and user name prefix. - (transform_ID, - transform_user_name, - transform_user_name_prefix) = get_transform_info( - os.path.join(aces_CTL_directory, 'odt', odt_dir, transform_CTL)) - - # Finding inverse. - transform_CTL_inverse = 'InvODT.%s.ctl' % odt_name - if not os.path.exists( - os.path.join(odt_tokens[-2], transform_CTL_inverse)): - transform_CTL_inverse = None - - # Add to list of ODTs - odts[odt_name] = {} - odts[odt_name]['transformCTL'] = os.path.join(odt_dir, transform_CTL) - if transform_CTL_inverse is not None: - odts[odt_name]['transformCTLInverse'] = os.path.join( - odt_dir, transform_CTL_inverse) - - odts[odt_name]['transformID'] = transform_ID - odts[odt_name]['transformUserNamePrefix'] = transform_user_name_prefix - odts[odt_name]['transformUserName'] = transform_user_name - - forward_CTL = odts[odt_name]['transformCTL'] - - print('ODT : %s' % odt_name) - print('\tTransform ID : %s' % transform_ID) - print('\tTransform User Name Prefix : %s' % transform_user_name_prefix) - print('\tTransform User Name : %s' % transform_user_name) - print('\tForward ctl : %s' % forward_CTL) - if 'transformCTLInverse' in odts[odt_name]: - inverse_CTL = odts[odt_name]['transformCTLInverse'] - print('\tInverse ctl : %s' % inverse_CTL) - else: - print('\tInverse ctl : %s' % 'None') - - print('\n') - - return odts - - -def get_LMT_info(aces_CTL_directory): - """ - Object description. - - For versions after WGR9. - - Parameters - ---------- - parameter : type - Parameter description. - - Returns - ------- - type - Return value description. - """ - - # TODO: Investigate refactoring with previous definition. - - # Credit to Alex Fry for the original approach here - lmt_dir = os.path.join(aces_CTL_directory, 'lmt') - all_lmt = [] - for dir_name, subdir_list, file_list in os.walk(lmt_dir): - for fname in file_list: - all_lmt.append((os.path.join(dir_name, fname))) - - lmt_CTLs = [x for x in all_lmt if - ('InvLMT' not in x) and ('README' not in x) and ( - os.path.split(x)[-1][0] != '.')] - - lmts = {} - - for lmt_CTL in lmt_CTLs: - lmt_tokens = os.path.split(lmt_CTL) - - # Handlimg nested directories. - lmt_path_tokens = os.path.split(lmt_tokens[-2]) - lmt_dir = lmt_path_tokens[-1] - while lmt_path_tokens[-2][-3:] != 'ctl': - lmt_path_tokens = os.path.split(lmt_path_tokens[-2]) - lmt_dir = os.path.join(lmt_path_tokens[-1], lmt_dir) - - # Building full name. - transform_CTL = lmt_tokens[-1] - lmt_name = string.join(transform_CTL.split('.')[1:-1], '.') - - # Finding id, user name and user name prefix. - (transform_ID, - transform_user_name, - transform_user_name_prefix) = get_transform_info( - os.path.join(aces_CTL_directory, lmt_dir, transform_CTL)) - - # Finding inverse. - transform_CTL_inverse = 'InvLMT.%s.ctl' % lmt_name - if not os.path.exists( - os.path.join(lmt_tokens[-2], transform_CTL_inverse)): - transform_CTL_inverse = None - - lmts[lmt_name] = {} - lmts[lmt_name]['transformCTL'] = os.path.join(lmt_dir, transform_CTL) - if transform_CTL_inverse is not None: - lmts[lmt_name]['transformCTLInverse'] = os.path.join( - lmt_dir, transform_CTL_inverse) - - lmts[lmt_name]['transformID'] = transform_ID - lmts[lmt_name]['transformUserNamePrefix'] = transform_user_name_prefix - lmts[lmt_name]['transformUserName'] = transform_user_name - - forward_CTL = lmts[lmt_name]['transformCTL'] - - print('LMT : %s' % lmt_name) - print('\tTransform ID : %s' % transform_ID) - print('\tTransform User Name Prefix : %s' % transform_user_name_prefix) - print('\tTransform User Name : %s' % transform_user_name) - print('\t Forward ctl : %s' % forward_CTL) - if 'transformCTLInverse' in lmts[lmt_name]: - inverse_CTL = lmts[lmt_name]['transformCTLInverse'] - print('\t Inverse ctl : %s' % inverse_CTL) - else: - print('\t Inverse ctl : %s' % 'None') - - print('\n') - - return lmts - -def create_ACES_config(aces_CTL_directory, +def create_ACES_config(aces_ctl_directory, config_directory, lut_resolution_1d=4096, lut_resolution_3d=64, @@ -926,14 +752,14 @@ def create_ACES_config(aces_CTL_directory, lut_directory = create_config_dir(config_directory, bake_secondary_LUTs) - odt_info = get_ODT_info(aces_CTL_directory) - lmt_info = get_LMT_info(aces_CTL_directory) + odt_info = aces.get_ODTs_info(aces_ctl_directory) + lmt_info = aces.get_LMTs_info(aces_ctl_directory) shaper_name = 'Output Shaper' config_data = generate_LUTs(odt_info, lmt_info, shaper_name, - aces_CTL_directory, + aces_ctl_directory, lut_directory, lut_resolution_1d, lut_resolution_3d, @@ -997,11 +823,11 @@ def main(): options, arguments = p.parse_args() - aces_CTL_directory = options.acesCTLDir + aces_ctl_directory = options.acesCTLDir config_directory = options.configDir lut_resolution_1d = int(options.lutResolution1d) lut_resolution_3d = int(options.lutResolution3d) - bake_secondary_LUTs = not options.dontBakeSecondaryLUTs + bake_secondary_luts = not options.dontBakeSecondaryLUTs cleanup_temp_images = not options.keepTempImages # TODO: Investigate the following statements. @@ -1014,7 +840,7 @@ def main(): print('command line : \n%s\n' % ' '.join(sys.argv)) - assert aces_CTL_directory is not None, ( + assert aces_ctl_directory is not None, ( 'process: No "{0}" environment variable defined or no "ACES CTL" ' 'directory specified'.format( ACES_OCIO_CTL_DIRECTORY_ENVIRON)) @@ -1024,11 +850,11 @@ def main(): 'directory specified'.format( ACES_OCIO_CONFIGURATION_DIRECTORY_ENVIRON)) - return create_ACES_config(aces_CTL_directory, + return create_ACES_config(aces_ctl_directory, config_directory, lut_resolution_1d, lut_resolution_3d, - bake_secondary_LUTs, + bake_secondary_luts, cleanup_temp_images)