def test_uniform(self): # Test dynamic exposure and gamma config = OCIO.Config() tr = OCIO.ExposureContrastTransform(dynamicExposure=True, dynamicGamma=True) proc = config.getProcessor(tr) desc = OCIO.GpuShaderDesc.CreateShaderDesc() gpu_proc = proc.getDefaultGPUProcessor() gpu_proc.extractGpuShaderInfo(desc) uniforms = desc.getUniforms() self.assertEqual(len(uniforms), 2) self.assertEqual(uniforms[0][0], "ocio_exposure_contrast_exposureVal") self.assertEqual(uniforms[0][1].type, OCIO.UNIFORM_DOUBLE) self.assertEqual(uniforms[0][1].getDouble(), 0.0) self.assertEqual(uniforms[1][0], "ocio_exposure_contrast_gammaVal") self.assertEqual(uniforms[1][1].type, OCIO.UNIFORM_DOUBLE) self.assertEqual(uniforms[1][1].getDouble(), 1.0) # Can dynamically modify uniforms dyn_exposure = desc.getDynamicProperty(OCIO.DYNAMIC_PROPERTY_EXPOSURE) dyn_exposure.setDouble(2.0) self.assertEqual(uniforms[0][1].getDouble(), 2.0) dyn_gamma = desc.getDynamicProperty(OCIO.DYNAMIC_PROPERTY_GAMMA) dyn_gamma.setDouble(0.5) self.assertEqual(uniforms[1][1].getDouble(), 0.5) # Uniforms are present in shader src text = desc.getShaderText() self.assertEqual(text.count("uniform float"), 2) # Iterates uniform name and data for name, uniform_data in uniforms: self.assertIsInstance(name, STRING_TYPES) self.assertIsInstance(uniform_data, OCIO.GpuShaderDesc.UniformData)
def test_canonical_name(self): # Test these Config function: getCanonicalName. cfg = OCIO.Config().CreateRaw() # add a named transform and a color space. nt = OCIO.NamedTransform(name='nt1', aliases=['alias1', 'test1'], forwardTransform=OCIO.RangeTransform()) cfg.addNamedTransform(nt) cs = OCIO.ColorSpace(name='cs1', aliases=['cs test', 'other']) cs.setTransform(OCIO.RangeTransform(), OCIO.COLORSPACE_DIR_TO_REFERENCE) cfg.addColorSpace(cs) cfg.setRole('role', 'cs1') self.assertEqual(cfg.getCanonicalName(''), '') self.assertEqual(cfg.getCanonicalName('not found'), '') self.assertEqual(cfg.getCanonicalName('roLE'), 'cs1') self.assertEqual(cfg.getCanonicalName('CS1'), 'cs1') self.assertEqual(cfg.getCanonicalName('Other'), 'cs1') self.assertEqual(cfg.getCanonicalName('CS test'), 'cs1') self.assertEqual(cfg.getCanonicalName('NT1'), 'nt1') self.assertEqual(cfg.getCanonicalName('Alias1'), 'nt1') self.assertEqual(cfg.getCanonicalName('Test1'), 'nt1')
def test_apply_inverse(self): """ Test applying transform with inversion. """ gtt = OCIO.GradingToneTransform(OCIO.GRADING_LOG) vals = OCIO.GradingTone(OCIO.GRADING_LOG) vals.midtones = OCIO.GradingRGBMSW(1.6, 0.5, 1.5, 0.7, 0.1, 1.2) vals.scontrast = 1.4 gtt.setValue(vals) cfg = OCIO.Config().CreateRaw() proc = cfg.getProcessor(gtt) cpu = proc.getDefaultCPUProcessor() # Apply the transform and keep the result. pixel = [0.48, 0.18, 0.18] rgb1 = cpu.applyRGB(pixel) # The processing did something. self.assertAlmostEqual(0.645454, rgb1[0], delta=1e-5) self.assertAlmostEqual(0.076331, rgb1[1], delta=1e-5) self.assertAlmostEqual(0.130564, rgb1[2], delta=1e-5) # Invert. gtt.setDirection(OCIO.TRANSFORM_DIR_INVERSE) proc = cfg.getProcessor(gtt) cpu = proc.getDefaultCPUProcessor() pixel2 = cpu.applyRGB(rgb1) # Invert back to original value. self.assertAlmostEqual(pixel[0], pixel2[0], delta=1e-5) self.assertAlmostEqual(pixel[1], pixel2[1], delta=1e-5) self.assertAlmostEqual(pixel[2], pixel2[2], delta=1e-5)
def test_create_group_transform(self): # Test createGroupTransform() function. cfg = OCIO.Config().CreateRaw() group = OCIO.GroupTransform() m = OCIO.MatrixTransform(offset=[1., 1., 1., 0.]) group.appendTransform(m) p = cfg.getProcessor(group) procGroup = p.createGroupTransform() self.assertEqual(len(procGroup), 1) iterProcGroup = iter(procGroup) t1 = next(iterProcGroup) self.assertEqual(t1.getTransformType(), OCIO.TRANSFORM_TYPE_MATRIX) ec = OCIO.ExposureContrastTransform(exposure=1.1, contrast=1.2) group.appendTransform(ec) p = cfg.getProcessor(group) procGroup = p.createGroupTransform() self.assertEqual(len(procGroup), 2) iterProcGroup = iter(procGroup) t1 = next(iterProcGroup) self.assertEqual(t1.getTransformType(), OCIO.TRANSFORM_TYPE_MATRIX) t2 = next(iterProcGroup) self.assertEqual(t2.getTransformType(), OCIO.TRANSFORM_TYPE_EXPOSURE_CONTRAST)
def make_config(self): self.config = OCIO.Config() self.config.setSearchPath('luts') self.set_role() self.set_color_space() self.set_display() self.flush_config()
def test_interface(self): bake = OCIO.Baker() bakee = bake.createEditableCopy() cfg = OCIO.Config().CreateFromStream(self.SIMPLE_PROFILE) self.assertEqual(2, cfg.getNumColorSpaces()) bakee.setConfig(cfg) cfg2 = bakee.getConfig() self.assertEqual(2, cfg2.getNumColorSpaces()) bakee.setFormat("cinespace") self.assertEqual("cinespace", bakee.getFormat()) bakee.setType("3D") self.assertEqual("3D", bakee.getType()) bakee.setMetadata("this is some metadata!") self.assertEqual("this is some metadata!", bakee.getMetadata()) bakee.setInputSpace("lnh") self.assertEqual("lnh", bakee.getInputSpace()) bakee.setLooks("foo, +bar") self.assertEqual("foo, +bar", bakee.getLooks()) bakee.setLooks("") bakee.setTargetSpace("test") self.assertEqual("test", bakee.getTargetSpace()) bakee.setShaperSize(4) self.assertEqual(4, bakee.getShaperSize()) bakee.setCubeSize(2) self.assertEqual(2, bakee.getCubeSize()) output = bakee.bake() if self.useSSE == True: self.assertEqual(self.EXPECTED_LUT_SSE, output) else: self.assertEqual(self.EXPECTED_LUT_NONSSE, output) self.assertEqual(8, bakee.getNumFormats()) self.assertEqual("cinespace", bakee.getFormatNameByIndex(2)) self.assertEqual("3dl", bakee.getFormatExtensionByIndex(1))
def test_apply_inverse(self): """ Test applying transform with inversion. """ gpt = OCIO.GradingPrimaryTransform(OCIO.GRADING_LOG) val = OCIO.GradingPrimary(OCIO.GRADING_LOG) val.gamma = OCIO.GradingRGBM(1.2, 1.4, 1.1, 0.7) val.saturation = 1.5 gpt.setValue(val) cfg = OCIO.Config().CreateRaw() proc = cfg.getProcessor(gpt) cpu = proc.getDefaultCPUProcessor() # Apply the transform and keep the result. pixel = [0.48, 0.18, 0.18] rgb1 = cpu.applyRGB(pixel) # The processing did something. self.assertAlmostEqual(0.515640, rgb1[0], delta=1e-5) self.assertAlmostEqual(0.150299, rgb1[1], delta=1e-5) self.assertAlmostEqual(0.051360, rgb1[2], delta=1e-5) # Invert. gpt.setDirection(OCIO.TRANSFORM_DIR_INVERSE) proc = cfg.getProcessor(gpt) cpu = proc.getDefaultCPUProcessor() pixel2 = cpu.applyRGB(rgb1) # Invert back to original value. self.assertAlmostEqual(pixel[0], pixel2[0], delta=1e-5) self.assertAlmostEqual(pixel[1], pixel2[1], delta=1e-5) self.assertAlmostEqual(pixel[2], pixel2[2], delta=1e-5)
def test_copy(self): """ Test the deepcopy() method. """ cfg = OCIO.Config().CreateFromStream(self.SIMPLE_PROFILE) bake = OCIO.Baker() bake.setConfig(cfg) bake.setFormat("cinespace") bake.setInputSpace("lnh") bake.setLooks("foo, +bar") bake.setTargetSpace("test") bake.setShaperSize(4) bake.setCubeSize(2) other = copy.deepcopy(bake) self.assertFalse(other is bake) self.assertEqual(other.getConfig(), bake.getConfig()) self.assertEqual(other.getFormat(), bake.getFormat()) self.assertEqual(other.getInputSpace(), bake.getInputSpace()) self.assertEqual(other.getLooks(), bake.getLooks()) self.assertEqual(other.getTargetSpace(), bake.getTargetSpace()) self.assertEqual(other.getShaperSize(), bake.getShaperSize()) self.assertEqual(other.getCubeSize(), bake.getCubeSize())
def test_named_transform(self): # Test these Config functions: addNamedTransform, getNamedTransforms, # getNamedTransformNames, clearNamedTransforms. cfg = OCIO.Config().CreateRaw() nt_names = cfg.getNamedTransformNames() self.assertEqual(0, len(nt_names)) nts = cfg.getNamedTransforms() self.assertEqual(0, len(nts)) # Add named transform. # Missing name. nt = OCIO.NamedTransform(forwardTransform=OCIO.RangeTransform()) with self.assertRaises(OCIO.Exception): cfg.addNamedTransform(nt) # Missing forward or inverse transform. nt = OCIO.NamedTransform(name="namedTransform") with self.assertRaises(OCIO.Exception): cfg.addNamedTransform(nt) # Legal named transform can be added. nt = OCIO.NamedTransform(name="namedTransform", forwardTransform=OCIO.RangeTransform()) cfg.addNamedTransform(nt) nt = OCIO.NamedTransform(name="other", inverseTransform=OCIO.RangeTransform()) cfg.addNamedTransform(nt) nt_names = cfg.getNamedTransformNames() self.assertEqual(2, len(nt_names)) self.assertEqual('namedTransform', next(nt_names)) self.assertEqual('other', next(nt_names)) nts = cfg.getNamedTransforms() self.assertEqual(2, len(nts)) nt = next(nts) self.assertEqual('namedTransform', nt.getName()) cur_tr = nt.getTransform(OCIO.TRANSFORM_DIR_FORWARD) self.assertIsInstance(cur_tr, OCIO.RangeTransform) cur_tr = nt.getTransform(OCIO.TRANSFORM_DIR_INVERSE) self.assertEqual(cur_tr, None) nt = next(nts) self.assertEqual('other', nt.getName()) cur_tr = nt.getTransform(OCIO.TRANSFORM_DIR_FORWARD) self.assertEqual(cur_tr, None) cur_tr = nt.getTransform(OCIO.TRANSFORM_DIR_INVERSE) self.assertIsInstance(cur_tr, OCIO.RangeTransform) nts = cfg.getNamedTransforms() self.assertEqual(2, len(nts)) cfg.clearNamedTransforms() nts = cfg.getNamedTransforms() self.assertEqual(0, len(nts))
def test_cache_id(self): # Test getCacheID() function. cfg = OCIO.Config().CreateRaw() ec = OCIO.ExposureContrastTransform() # Make the transform dynamic. ec.makeContrastDynamic() p = cfg.getProcessor(ec) self.assertEqual(p.getCacheID(), '$3686dc0e9e639d52b07172b7b0a5c61b')
def test_cache_id(self): # Test getCacheID() function. cfg = OCIO.Config().CreateRaw() ec = OCIO.ExposureContrastTransform() # Make the transform dynamic. ec.makeContrastDynamic() p = cfg.getProcessor(ec) self.assertEqual(p.getCacheID(), '$4c4a89725a9a2164f1f8afe60c8967a0')
def test_is_editable(self): cfg = OCIO.Config().CreateFromStream(self.SIMPLE_PROFILE) self.assertEqual(cfg.isEditable(), False) cfg = cfg.createEditableCopy() self.assertEqual(cfg.isEditable(), True) ctx = cfg.getCurrentContext() self.assertEqual(ctx.isEditable(), False) ctx = ctx.createEditableCopy() self.assertEqual(ctx.isEditable(), True) ctx.setEnvironmentMode(OCIO.Constants.ENV_ENVIRONMENT_LOAD_ALL)
def load_aces_ref_config(): """ Return an OCIO config object for the ACES reference config required to decode transform IDs. """ ACES_REF_CONFIG = 'config-aces-reference.yaml' import os # Get the path to this script, see if the config is in the same directory. file_path = os.path.realpath(__file__) prefix = os.path.dirname(file_path) config_path = os.path.join(prefix, ACES_REF_CONFIG) config = ocio.Config().CreateFromFile(config_path) # TODO: Try other ways of finding the config. return config
def test_get_processor_errors(self): """ Test the getProcessor function failures. """ cfg = OCIO.Config().CreateRaw() pipeline = OCIO.LegacyViewingPipeline() # No DisplayViewTransform. with self.assertRaises(OCIO.Exception): pipeline.getProcessor(cfg) # DisplayViewTransform refers to elements that are not part of config. dvt = OCIO.DisplayViewTransform(src='colorspace1', display='sRGB', view='view1') pipeline.setDisplayViewTransform(dvt) with self.assertRaises(OCIO.Exception): pipeline.getProcessor(cfg) # Add display and view. cfg.addDisplayView(display='sRGB', view='view1', colorSpaceName='colorspace1') with self.assertRaises(OCIO.Exception): pipeline.getProcessor(cfg) # Add color space. cs = OCIO.ColorSpace(name='colorspace1') cfg.addColorSpace(cs) # Processor can now be created. pipeline.getProcessor(cfg) mat = OCIO.MatrixTransform() mat.setOffset([0.1, 0.2, 0.3, 0.]) pipeline.setLinearCC(mat) # Scene_linear role is missing. with self.assertRaises(OCIO.Exception): pipeline.getProcessor(cfg) cfg.setRole(role='scene_linear', colorSpaceName='colorspace1') # Processor can now be created. pipeline.getProcessor(cfg) # Print the pipeline. self.assertEqual(str(pipeline), ( 'DisplayViewTransform: <DisplayViewTransform direction=forward, ' 'src=colorspace1, display=sRGB, view=view1, , looksBypass=1>, ' 'LinearCC: <MatrixTransform direction=forward, fileindepth=unknown, ' 'fileoutdepth=unknown, matrix=1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1, offset=0.1 0.2 0.3 0>' ))
def test_interface(self): """ Test similar to C++ CPU test. """ bake = OCIO.Baker() cfg = OCIO.Config().CreateFromStream(self.SIMPLE_PROFILE) cs = cfg.getColorSpaces() self.assertEqual(len(cs), 2) bake.setConfig(cfg) cfg2 = bake.getConfig() cs2 = cfg2.getColorSpaces() self.assertEqual(len(cs2), 2) bake.setFormat("cinespace") self.assertEqual("cinespace", bake.getFormat()) bake.setInputSpace("lnh") self.assertEqual("lnh", bake.getInputSpace()) bake.setLooks("foo, +bar") self.assertEqual("foo, +bar", bake.getLooks()) bake.setLooks("") bake.setTargetSpace("test") self.assertEqual("test", bake.getTargetSpace()) bake.setShaperSize(4) self.assertEqual(4, bake.getShaperSize()) bake.setCubeSize(2) self.assertEqual(2, bake.getCubeSize()) output = bake.bake() lines = output.splitlines() expected_lines = self.EXPECTED_LUT.splitlines() self.assertEqual(len(lines), len(expected_lines)) # Text compare for the first lines. for i in range(6): self.assertEqual(lines[i], expected_lines[i]) # Compare values after (results might be slightly different on some plaforms). for i in range(6, len(lines)): # Skip blank lines. if lines[i] == '': continue # Line 16 is the cube size. if i == 16: self.assertEqual(lines[i], expected_lines[i]) continue lf = lines[i].split(' ') elf = expected_lines[i].split(' ') for j in range(len(lf)): self.assertAlmostEqual(float(lf[j]), float(elf[j]), delta=0.00001) fmts = bake.getFormats() self.assertEqual(len(fmts), 10) self.assertEqual("cinespace", fmts[4][0]) self.assertEqual("3dl", fmts[1][1])
def test_is_noop(self): # Test isNoOp() function. cfg = OCIO.Config().CreateRaw() ec = OCIO.ExposureContrastTransform() p = cfg.getProcessor(ec) self.assertTrue(p.isNoOp()) # Make the transform dynamic. ec.makeContrastDynamic() p = cfg.getProcessor(ec) self.assertFalse(p.isNoOp())
def test_interface(self): OCIO.ClearAllCaches() #self.assertEqual("1.0.8", OCIO.version) #self.assertEqual(16779264, OCIO.hexversion) self.assertEqual(OCIO.Constants.LOGGING_LEVEL_INFO, OCIO.GetLoggingLevel()) OCIO.SetLoggingLevel(OCIO.Constants.LOGGING_LEVEL_NONE) self.assertEqual(OCIO.Constants.LOGGING_LEVEL_NONE, OCIO.GetLoggingLevel()) foo = OCIO.GetCurrentConfig() self.assertEqual(self.FOO, foo.serialize()) OCIO.SetLoggingLevel(OCIO.Constants.LOGGING_LEVEL_INFO) bar = OCIO.Config().CreateFromStream(foo.serialize()) OCIO.SetCurrentConfig(bar) wee = OCIO.GetCurrentConfig()
def test_vector_uniform(self): if not np: logger.warning("NumPy not found. Skipping test!") return # Test dynamic GradingRGBCurve a_curve = OCIO.GradingBSplineCurve([1.0, 2.0, 3.0, 4.0]) rgb_curve = OCIO.GradingRGBCurve(a_curve, a_curve, a_curve, a_curve) tr = OCIO.GradingRGBCurveTransform(values=rgb_curve, dynamic=True) config = OCIO.Config() proc = config.getProcessor(tr) desc = OCIO.GpuShaderDesc.CreateShaderDesc() gpu_proc = proc.getDefaultGPUProcessor() gpu_proc.extractGpuShaderInfo(desc) uniforms = desc.getUniforms() self.assertEqual(len(uniforms), 5) self.assertEqual(uniforms[0][0], "ocio_grading_rgbcurve_knotsOffsets") self.assertEqual(uniforms[0][1].type, OCIO.UNIFORM_VECTOR_INT) vector_int = uniforms[0][1].getVectorInt() self.assertTrue(isinstance(vector_int, np.ndarray)) self.assertEqual(vector_int.dtype, np.intc) self.assertTrue( np.array_equal(vector_int, np.array([0, 2, 2, 2, 4, 2, 6, 2], dtype=np.intc))) self.assertEqual(uniforms[1][0], "ocio_grading_rgbcurve_knots") self.assertEqual(uniforms[1][1].type, OCIO.UNIFORM_VECTOR_FLOAT) vector_float = uniforms[1][1].getVectorFloat() self.assertTrue(isinstance(vector_float, np.ndarray)) self.assertEqual(vector_float.dtype, np.float32) self.assertTrue( np.array_equal( vector_float, np.array([1.0, 3.0, 1.0, 3.0, 1.0, 3.0, 1.0, 3.0], dtype=np.float32))) # Can dynamically modify uniforms b_curve = OCIO.GradingBSplineCurve([5.0, 6.0, 7.0, 8.0]) dyn_rgb_curve = desc.getDynamicProperty( OCIO.DYNAMIC_PROPERTY_GRADING_RGBCURVE) dyn_rgb_curve.setGradingRGBCurve( OCIO.GradingRGBCurve(b_curve, b_curve, b_curve, b_curve)) self.assertTrue( np.array_equal( uniforms[1][1].getVectorFloat(), np.array([5.0, 7.0, 5.0, 7.0, 5.0, 7.0, 5.0, 7.0], dtype=np.float32)))
def test_has_channel_crosstalk(self): # Test hasChannelCrosstalk() function. cfg = OCIO.Config().CreateRaw() m = OCIO.MatrixTransform( [1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 2., 0., 0., 0., 0., 1.]) p = cfg.getProcessor(m) self.assertFalse(p.hasChannelCrosstalk()) m = OCIO.MatrixTransform( [1., 0., 0., 0., 1., 1., 0., 0., 0., 0., 2., 0., 0., 0., 0., 1.]) p = cfg.getProcessor(m) self.assertTrue(p.hasChannelCrosstalk())
def test_config(self): """ Test the viewing rules object from an OCIO config. """ # Get simple config file from UnitTestUtils.py cfg = OCIO.Config().CreateFromStream(SIMPLE_CONFIG) # Test ViewingRules class object getters from config rules = cfg.getViewingRules() self.assertEqual(4, rules.getNumEntries()) iterator = rules.getColorSpaces(0) self.assertEqual(1, len(iterator)) self.assertEqual("c1", next(iterator)) self.assertEqual(2, rules.getNumCustomKeys(0)) self.assertEqual("key0", rules.getCustomKeyName(0, 0)) self.assertEqual("value0", rules.getCustomKeyValue(0, 0)) self.assertEqual("key1", rules.getCustomKeyName(0, 1)) self.assertEqual("value1", rules.getCustomKeyValue(0, 1)) iterator = rules.getColorSpaces(1) self.assertEqual(2, len(iterator)) self.assertEqual("c2", next(iterator)) self.assertEqual("c3", next(iterator)) self.assertEqual(0, rules.getNumCustomKeys(1)) iterator = rules.getEncodings(2) self.assertEqual(1, len(iterator)) self.assertEqual("log", next(iterator)) self.assertEqual(0, rules.getNumCustomKeys(2)) iterator = rules.getEncodings(3) self.assertEqual(2, len(iterator)) self.assertEqual("log", next(iterator)) self.assertEqual("scene-linear", next(iterator)) self.assertEqual(2, rules.getNumCustomKeys(3)) self.assertEqual("key1", rules.getCustomKeyName(3, 0)) self.assertEqual("value2", rules.getCustomKeyValue(3, 0)) self.assertEqual("key2", rules.getCustomKeyName(3, 1)) self.assertEqual("value0", rules.getCustomKeyValue(3, 1)) # Add a new rule. rules.insertRule(0, 'newRule') rules.addEncoding(0, 'log') rules.addEncoding(0, 'scene-linear') # Set the modified rules, get them back and verify there are now 5 rules. cfg.setViewingRules(rules) rules = cfg.getViewingRules() self.assertEqual(5, rules.getNumEntries())
def RegisterOCIOLut(): if not hasattr(mari.gl_render, "createPostFilter"): print "Error: This version of Mari does not support the mari.gl_render.createPostFilter API" return config = OCIO.Config() transform = OCIO.FileTransform( src=os.path.realpath(LUT_FILENAME), interpolation=OCIO.Constants.INTERP_LINEAR, direction=OCIO.Constants.TRANSFORM_DIR_FORWARD) processor = config.getProcessor(transform) shaderDesc = dict([('language', OCIO.Constants.GPU_LANGUAGE_GLSL_1_3), ('functionName', 'display_ocio_$ID_'), ('lut3DEdgeLen', LUT3D_SIZE)]) shaderText = processor.getGpuShaderText(shaderDesc) lut3d = processor.getGpuLut3D(shaderDesc) # Clear the existing color managment filter stack mari.gl_render.clearPostFilterStack() # Create variable pre-declarations desc = "sampler3D lut3d_ocio_$ID_;\n" desc += shaderText # Set the body of the filter body = "{ Out = display_ocio_$ID_(Out, lut3d_ocio_$ID_); }" # HACK: Increment a counter by 1 each time to force a refresh if not hasattr(mari, "ocio_lut_counter_hack"): mari.ocio_lut_counter_hack = 0 else: mari.ocio_lut_counter_hack += 1 ocio_lut_counter_hack = mari.ocio_lut_counter_hack # Create a new filter name = "OCIO %s v%d" % (os.path.basename(LUT_FILENAME), ocio_lut_counter_hack) postfilter = mari.gl_render.createPostFilter(name, desc, body) # Set the texture to use for the given sampler on this filter postfilter.setTexture3D("lut3d_ocio_$ID_", LUT3D_SIZE, LUT3D_SIZE, LUT3D_SIZE, postfilter.FORMAT_RGB, lut3d) # Append the filter to the end of the current list of filters mari.gl_render.appendPostFilter(postfilter)
def make_config(config_filename="config.ocio", scene_linear_role="ACES - ACEScg"): """Generate OCIO config""" config = OCIO.Config() config.setSearchPath(":".join(["luts", "matrices"])) config.addColorSpace(aces_2065_1_colorspace()) config.addColorSpace(acescg_colorspace()) config.addColorSpace(acesproxy_colorspace()) config.addColorSpace(acescc_colorspace()) config.addColorSpace(acescct_colorspace()) config.addColorSpace(linear_srgb_colorspace()) config.addColorSpace(srgb_colorspace()) config.addColorSpace(rec709_colorspace()) config.addColorSpace(raw_colorspace()) config.addColorSpace(aces_rec709_output()) config.addColorSpace(aces_srgb_output()) display_spaces = [["ACES Rec. 709", "Output - ACES Rec. 709"], ["ACES sRGB", "Output - ACES sRGB"], ["Raw", "Utility - Raw"]] for name, colorspace in display_spaces: config.addDisplay("default", name, colorspace) config.setActiveViews(','.join(["ACES Rec. 709", "ACES sRGB", "Raw"])) config.setActiveDisplays(','.join(["default"])) config.setRole(OCIO.Constants.ROLE_SCENE_LINEAR, scene_linear_role) config.setRole(OCIO.Constants.ROLE_REFERENCE, "ACES - ACES2065-1") config.setRole(OCIO.Constants.ROLE_COLOR_TIMING, "ACES - ACEScct") config.setRole(OCIO.Constants.ROLE_COMPOSITING_LOG, "ACES - ACEScct") config.setRole(OCIO.Constants.ROLE_DATA, "Utility - Raw") config.setRole(OCIO.Constants.ROLE_DEFAULT, "Utility - Raw") config.setRole(OCIO.Constants.ROLE_COLOR_PICKING, "Utility - Raw") config.setRole(OCIO.Constants.ROLE_MATTE_PAINT, "Utility - Raw") config.setRole(OCIO.Constants.ROLE_TEXTURE_PAINT, "Utility - Raw") config.setRole("rendering", scene_linear_role) config.setRole("compositing_linear", scene_linear_role) config.sanityCheck() with open(config_filename, "w") as fhandle: fhandle.write(config.serialize()) print("Wrote {0} successfully".format(config_filename)) return
def test_optimize_processor(self): # Test getOptimizedProcessor() function. cfg = OCIO.Config().CreateRaw() group = OCIO.GroupTransform() m = OCIO.MatrixTransform(offset=[1., 1., 1., 0.]) group.appendTransform(m) m = OCIO.MatrixTransform(offset=[2., 1., 0.5, 0.]) group.appendTransform(m) p = cfg.getProcessor(group) # Optimize processor. pOptimized = p.getOptimizedProcessor(OCIO.OPTIMIZATION_LOSSLESS) procGroup = pOptimized.createGroupTransform() self.assertEqual(len(procGroup), 1) iterProcGroup = iter(procGroup) t1 = next(iterProcGroup) self.assertEqual(t1.getTransformType(), OCIO.TRANSFORM_TYPE_MATRIX) self.assertEqual(t1.getOffset(), [3, 2, 1.5, 0])
def test_dynamic_properties(self): # Test dynamic property related functions. cfg = OCIO.Config().CreateRaw() ec = OCIO.ExposureContrastTransform() ec.setContrast(1.1) ec.setExposure(1.2) p = cfg.getProcessor(ec) # Processor created from non-dynamic transform is not dynamic. self.assertFalse(p.isDynamic()) # Make the transform dynamic. ec.makeContrastDynamic() p = cfg.getProcessor(ec) # Processor is dynamic. self.assertTrue(p.isDynamic()) # Contrast is dynamic. self.assertTrue(p.hasDynamicProperty(OCIO.DYNAMIC_PROPERTY_CONTRAST)) # Exposure is not dynamic. self.assertFalse(p.hasDynamicProperty(OCIO.DYNAMIC_PROPERTY_EXPOSURE)) # Only dynamic Dynamic Properties (i.e. isDynamic returns true) may be modified after the # processor is created. As Dynamic Properties are decoupled between instances and # processor types, the value change only affects this instance so a corresponding CPU # processing instance will not have the new value. dpc = p.getDynamicProperty(OCIO.DYNAMIC_PROPERTY_CONTRAST) # Accessing a Dynamic Property that does not exist triggers an exception. with self.assertRaises(OCIO.Exception): p.getDynamicProperty(OCIO.DYNAMIC_PROPERTY_EXPOSURE) self.assertEqual(dpc.getType(), OCIO.DYNAMIC_PROPERTY_CONTRAST) # Initial contrast value. self.assertEqual(dpc.getDouble(), 1.1) dpc.setDouble(1.15) self.assertEqual(dpc.getDouble(), 1.15) # Value can be accessed only using the appropriate accessor. DYNAMIC_PROPERTY_CONTRAST is # a double, so get/setDouble should be used. Trying to get a different type throws an # error. with self.assertRaises(OCIO.Exception): dpc.getGradingPrimary()
def test_config(self): """ Test the ColorSpace object from an OCIO config. """ # Get simple config file from UnitTestUtils.py cfg = OCIO.Config().CreateFromStream(SIMPLE_CONFIG) # Test ColorSpace class object getters from config cs = cfg.getColorSpace('vd8') self.assertEqual(cs.getName(), 'vd8') self.assertEqual(cs.getDescription(), 'how many transforms can we use?') self.assertEqual(cs.getFamily(), 'vd8') self.assertEqual(cs.getAllocation(), OCIO.ALLOCATION_UNIFORM) self.assertEqual(cs.getAllocationVars(), []) self.assertEqual(cs.getEqualityGroup(), '') self.assertEqual(cs.getBitDepth(), OCIO.BIT_DEPTH_UINT8) self.assertFalse(cs.isData()) to_ref = cs.getTransform(OCIO.COLORSPACE_DIR_TO_REFERENCE) self.assertIsInstance(to_ref, OCIO.GroupTransform) self.assertEqual(len(to_ref), 3)
def test_apply_dynamic(self): """ Test applying transform with dynamic properties. """ gpt1 = OCIO.GradingPrimaryTransform(OCIO.GRADING_LOG) gpt1.makeDynamic() gpt2 = OCIO.GradingPrimaryTransform(OCIO.GRADING_LOG) val2 = OCIO.GradingPrimary(OCIO.GRADING_LOG) val2.gamma = OCIO.GradingRGBM(1.2, 1.4, 1.1, 1.0) val2.saturation = 1.5 gpt2.setValue(val2) group = OCIO.GroupTransform() group.appendTransform(gpt1) group.appendTransform(gpt2) cfg = OCIO.Config().CreateRaw() proc = cfg.getProcessor(group) cpu = proc.getDefaultCPUProcessor() dp = cpu.getDynamicProperty(OCIO.DYNAMIC_PROPERTY_GRADING_PRIMARY) self.assertEqual(dp.getType(), OCIO.DYNAMIC_PROPERTY_GRADING_PRIMARY) # Apply the transform and keep the result. pixel = [0.48, 0.18, 0.18] rgb1 = cpu.applyRGB(pixel) # Change the transform through the dynamic property. val1 = OCIO.GradingPrimary(OCIO.GRADING_LOG) val1.gamma = OCIO.GradingRGBM(1.1, 1.2, 1.3, 1.0) dp.setGradingPrimary(val1) # Apply the transform to the same pixel and verify result is different. rgb2 = cpu.applyRGB(pixel) self.assertNotEqual(rgb1[0], rgb2[0]) self.assertNotEqual(rgb1[1], rgb2[1]) self.assertNotEqual(rgb1[2], rgb2[2])
def test_apply_inverse(self): """ Test applying transform with inversion. """ gct = OCIO.GradingRGBCurveTransform(OCIO.GRADING_LOG) vals = OCIO.GradingRGBCurve(OCIO.GRADING_LOG) vals.red = OCIO.GradingBSplineCurve( [0, 0, 0.4, 0.2, 0.5, 0.7, 0.6, 1.5, 1, 2.1]) vals.green = OCIO.GradingBSplineCurve([-0.1, -0.5, 0.5, 0.2, 1.5, 1.1]) vals.blue = OCIO.GradingBSplineCurve([0, 0, 1, 1]) vals.master = OCIO.GradingBSplineCurve( [0, -0.2, 0.3, 0.7, 1.2, 1.5, 2.5, 2.2]) gct.setValue(vals) cfg = OCIO.Config().CreateRaw() proc = cfg.getProcessor(gct) cpu = proc.getDefaultCPUProcessor() # Apply the transform and keep the result. pixel = [0.48, 0.18, 0.18] rgb1 = cpu.applyRGB(pixel) # The processing did something. self.assertAlmostEqual(1.010323, rgb1[0], delta=1e-5) self.assertAlmostEqual(-0.770639, rgb1[1], delta=1e-5) self.assertAlmostEqual(0.398450, rgb1[2], delta=1e-5) # Invert. gct.setDirection(OCIO.TRANSFORM_DIR_INVERSE) proc = cfg.getProcessor(gct) cpu = proc.getDefaultCPUProcessor() pixel2 = cpu.applyRGB(rgb1) # Invert back to original value. self.assertAlmostEqual(pixel[0], pixel2[0], delta=1e-5) self.assertAlmostEqual(pixel[1], pixel2[1], delta=1e-5) self.assertAlmostEqual(pixel[2], pixel2[2], delta=1e-5)
def test_apply_with_slopes(self): """ Test applying transform with supplied slopes. """ gct = OCIO.GradingRGBCurveTransform(OCIO.GRADING_LOG) vals = OCIO.GradingRGBCurve(OCIO.GRADING_LOG) vals.master = OCIO.GradingBSplineCurve([ -5.26017743, -4., -3.75502745, -3.57868829, -2.24987747, -1.82131329, -0.74472749, 0.68124124, 1.06145248, 2.87457742, 2.86763245, 3.83406206, 4.67381243, 4. ]) gct.setValue(vals) self.assertEqual(gct.slopesAreDefault(OCIO.RGB_MASTER), True) slopes = [0., 0.55982688, 1.77532247, 1.55, 0.8787017, 0.18374463, 0.] for i in range(0, len(slopes)): gct.setSlope(OCIO.RGB_MASTER, i, slopes[i]) gct.validate() self.assertAlmostEqual(1.55, gct.getSlope(OCIO.RGB_MASTER, 3), delta=1e-5) self.assertEqual(gct.slopesAreDefault(OCIO.RGB_MASTER), False) self.assertEqual(gct.slopesAreDefault(OCIO.RGB_RED), True) cfg = OCIO.Config().CreateRaw() proc = cfg.getProcessor(gct) cpu = proc.getDefaultCPUProcessor() # Apply the transform and keep the result. pixel = [-3., -1., 1.] rgb1 = cpu.applyRGB(pixel) # Test that the slopes were used (the values are significantly different without slopes). self.assertAlmostEqual(-2.92582282, rgb1[0], delta=1e-5) self.assertAlmostEqual(0.28069129, rgb1[1], delta=1e-5) self.assertAlmostEqual(2.81987724, rgb1[2], delta=1e-5)
def build_config(output_path): """Generate OCIO config""" config = OCIO.Config() config.setSearchPath(":".join(["luts", "mtx"])) # add colorspaces config.addColorSpace(aces_colorspace()) config.addColorSpace(flog_colorspace()) config.addColorSpace(ncd_colorspace()) # add displays display_spaces = [ ["F-Log", "flog", ""], ["No LUT", "ncd", ""], ] for name, colorspace, look in display_spaces: config.addDisplay("default", name, colorspace, look) config.setActiveViews(",".join(["No LUT", "F-Log"])) config.setActiveDisplays(",".join(["default"])) # set roles config.setRole(OCIO.Constants.ROLE_SCENE_LINEAR, "aces") config.setRole(OCIO.Constants.ROLE_REFERENCE, "aces") config.setRole(OCIO.Constants.ROLE_DATA, "ncd") config.setRole(OCIO.Constants.ROLE_DEFAULT, "ncd") config.setRole(OCIO.Constants.ROLE_COLOR_PICKING, "ncd") config.setRole(OCIO.Constants.ROLE_TEXTURE_PAINT, "flog") config.setRole(OCIO.Constants.ROLE_MATTE_PAINT, "flog") config.setRole(OCIO.Constants.ROLE_COLOR_TIMING, "flog") config.setRole(OCIO.Constants.ROLE_COMPOSITING_LOG, "flog") config.sanityCheck() with open(output_path, "w") as fhandle: fhandle.write(config.serialize()) print("Wrote {} successfully".format(output_path))
def test_interface(self): _cfg = OCIO.Config().CreateFromStream(self.SIMPLE_PROFILE) _cfge = _cfg.createEditableCopy() _cfge.clearEnvironmentVars() self.assertEqual(0, _cfge.getNumEnvironmentVars()) _cfge.addEnvironmentVar("FOO", "test1") _cfge.addEnvironmentVar("FOO2", "test2${FOO}") self.assertEqual(2, _cfge.getNumEnvironmentVars()) self.assertEqual("FOO", _cfge.getEnvironmentVarNameByIndex(0)) self.assertEqual("FOO2", _cfge.getEnvironmentVarNameByIndex(1)) self.assertEqual("test1", _cfge.getEnvironmentVarDefault("FOO")) self.assertEqual("test2${FOO}", _cfge.getEnvironmentVarDefault("FOO2")) self.assertEqual("test2test1", _cfge.getCurrentContext().resolveStringVar("${FOO2}")) self.assertEqual({ 'FOO': 'test1', 'FOO2': 'test2${FOO}' }, _cfge.getEnvironmentVarDefaults()) _cfge.clearEnvironmentVars() self.assertEqual(0, _cfge.getNumEnvironmentVars()) self.assertEqual("luts", _cfge.getSearchPath()) _cfge.setSearchPath("otherdir") self.assertEqual("otherdir", _cfge.getSearchPath()) _cfge.sanityCheck() _cfge.setDescription("testdesc") self.assertEqual("testdesc", _cfge.getDescription()) self.assertEqual(self.SIMPLE_PROFILE, _cfg.serialize()) #self.assertEqual("$07d1fb1509eeae1837825fd4242f8a69:$885ad1683add38a11f7bbe34e8bf9ac0", # _cfg.getCacheID()) con = _cfg.getCurrentContext() self.assertNotEqual(0, con.getNumStringVars()) #self.assertEqual("", _cfg.getCacheID(con)) #self.assertEqual("", _cfge.getWorkingDir()) _cfge.setWorkingDir("/foobar") self.assertEqual("/foobar", _cfge.getWorkingDir()) self.assertEqual(3, _cfge.getNumColorSpaces()) self.assertEqual("lnh", _cfge.getColorSpaceNameByIndex(1)) lnh = _cfge.getColorSpace("lnh") self.assertEqual("ln", lnh.getFamily()) self.assertEqual(0, _cfge.getIndexForColorSpace("foobar")) cs = OCIO.ColorSpace() cs.setName("blah") _cfge.addColorSpace(cs) self.assertEqual(3, _cfge.getIndexForColorSpace("blah")) #_cfge.clearColorSpaces() #_cfge.parseColorSpaceFromString("foo") self.assertEqual(False, _cfg.isStrictParsingEnabled()) _cfge.setStrictParsingEnabled(True) self.assertEqual(True, _cfge.isStrictParsingEnabled()) self.assertEqual(2, _cfge.getNumRoles()) self.assertEqual(False, _cfg.hasRole("foo")) _cfge.setRole("foo", "vd8") self.assertEqual(3, _cfge.getNumRoles()) self.assertEqual(True, _cfge.hasRole("foo")) self.assertEqual("foo", _cfge.getRoleName(1)) self.assertEqual("sRGB", _cfge.getDefaultDisplay()) self.assertEqual(1, _cfge.getNumDisplays()) self.assertEqual("sRGB", _cfge.getDisplay(0)) self.assertEqual("Film1D", _cfge.getDefaultView("sRGB")) self.assertEqual(2, _cfge.getNumViews("sRGB")) self.assertEqual("Raw", _cfge.getView("sRGB", 1)) self.assertEqual("vd8", _cfge.getDisplayColorSpaceName("sRGB", "Film1D")) self.assertEqual("", _cfg.getDisplayLooks("sRGB", "Film1D")) _cfge.addDisplay("foo", "bar", "foo", "wee") _cfge.clearDisplays() _cfge.setActiveDisplays("sRGB") self.assertEqual("sRGB", _cfge.getActiveDisplays()) _cfge.setActiveViews("Film1D") self.assertEqual("Film1D", _cfge.getActiveViews()) luma = _cfge.getDefaultLumaCoefs() self.assertAlmostEqual(0.2126, luma[0], delta=1e-8) _cfge.setDefaultLumaCoefs([0.1, 0.2, 0.3]) tnewluma = _cfge.getDefaultLumaCoefs() self.assertAlmostEqual(0.1, tnewluma[0], delta=1e-8) self.assertEqual(0, _cfge.getNumLooks()) lk = OCIO.Look() lk.setName("coollook") lk.setProcessSpace("somespace") et = OCIO.ExponentTransform() et.setValue([0.1, 0.2, 0.3, 0.4]) lk.setTransform(et) iet = OCIO.ExponentTransform() iet.setValue([-0.1, -0.2, -0.3, -0.4]) lk.setInverseTransform(iet) _cfge.addLook(lk) self.assertEqual(1, _cfge.getNumLooks()) self.assertEqual("coollook", _cfge.getLookNameByIndex(0)) glk = _cfge.getLook("coollook") self.assertEqual("somespace", glk.getProcessSpace()) _cfge.clearLooks() self.assertEqual(0, _cfge.getNumLooks()) #getProcessor(context, srcColorSpace, dstColorSpace) #getProcessor(context, srcName,dstName); #getProcessor(transform); #getProcessor(transform, direction); #getProcessor(context, transform, direction); _proc = _cfg.getProcessor("lnh", "vd8") self.assertEqual(False, _proc.isNoOp()) self.assertEqual(True, _proc.hasChannelCrosstalk()) #float packedpix[] = new float[]{0.48f, 0.18f, 0.9f, 1.0f, # 0.48f, 0.18f, 0.18f, 1.0f, # 0.48f, 0.18f, 0.18f, 1.0f, # 0.48f, 0.18f, 0.18f, 1.0f }; #FloatBuffer buf = ByteBuffer.allocateDirect(2 * 2 * 4 * Float.SIZE / 8).asFloatBuffer(); #buf.put(packedpix); #PackedImageDesc foo = new PackedImageDesc(buf, 2, 2, 4); #_proc.apply(foo); #FloatBuffer wee = foo.getData(); #self.assertEqual(-2.4307251581696764E-35f, wee.get(2), 1e-8); # TODO: these should work in-place rgbfoo = _proc.applyRGB([0.48, 0.18, 0.18]) self.assertAlmostEqual(1.9351075, rgbfoo[0], delta=1e-7) # TODO: these should work in-place rgbafoo = _proc.applyRGBA([0.48, 0.18, 0.18, 1.0]) self.assertAlmostEqual(1.0, rgbafoo[3], delta=1e-8) #self.assertEqual("$a92ef63abd9edf61ad5a7855da064648", _proc.getCpuCacheID()) del _cfge del _cfg