[docs]classAYONHieroEffectsFileProcessor(object):"""Class for processing an AYON Hiero effects file. Arguments: filepath (Path): Path to the effects file. """filepath:Path=None_wrapper_class_members=dict(inspect.getmembers(operators,inspect.isclass))_color_ops:List=[]_repo_ops:List=[]def__init__(self,filepath:Path)->None:self.filepath=filepath@propertydefcolor_operators(self)->List:"""List of color operators to be processed."""ops=[]foropinself._color_ops:ops.extend(op.to_ocio_obj())returnops@propertydefrepo_operators(self)->Dict:"""List of repositioning operators to be processed."""returnself._repo_opsdef_load(self)->None:effect_file_path=self.filepath.resolve().as_posix()# get all relative files recursively so we can make sure files in# transforms are having correct pathall_relative_files={f.name:fforfinPath(self.filepath.parent).rglob("*")}withopen(effect_file_path,"r")asf:ops_data=json.load(f)all_ops=[vfor_,vinops_data.items()ifisinstance(v,dict)]# TODO: what if there are multiple layer citizens with subTrackIndexall_ops.sort(key=lambdaop:op["subTrackIndex"])forvalueinall_ops:class_name=value["class"]ifclass_namenotinself._wrapper_class_members.keys():continueifnotvalue.get("node"):continuenode_value=value["node"]ifnode_value.get("file"):self._sanitize_file_path(node_value,all_relative_files)class_obj=self._wrapper_class_members[class_name]class_obj=class_obj.from_node_data(node_value)# separate color ops from repo opsif"color"inclass_obj.__class__.__module__:self._color_ops.append(class_obj)else:self._repo_ops.append(class_obj)def_sanitize_file_path(self,node_value:dict,all_relative_files:dict)->None:filepath=Path(node_value["file"])iffilepath.exists():node_value["file"]=filepath.as_posix()returniffilepath.namenotinall_relative_files.keys():returnrelative_file=all_relative_files[filepath.name]log.warning(f"File not found: {filepath.name}. Using file from "f"relative path instead: {relative_file.as_posix()}")node_value["file"]=relative_file.resolve().as_posix()
[docs]defclear_operators(self)->None:"""Clears lists of all operators."""self._color_ops=[]self._repo_ops=[]
[docs]defload(self)->None:"""Loads the effects file. Attention: This method clears the lists of all operators before loading. """self.clear_operators()self._load()
[docs]defget_oiiotool_cmd(self)->List[str]:"""Returns arguments for oiiotool command."""args=[]foropinself.color_operators:ifisinstance(op,OCIO.FileTransform):lut=Path(op.getSrc()).resolve()args.extend(["--ociofiletransform",f"{lut.as_posix()}"])ifisinstance(op,OCIO.ColorSpaceTransform):args.extend(["--colorconvert",op.getSrc(),op.getDst()])foropinself.repo_operators:args.extend(op.to_oiio_args())returnargs