import csv class BlendShapeParser: BLEND_SHAPE_KEYS = [ 'EyeBlinkLeft', 'EyeLookDownLeft', 'EyeLookInLeft', 'EyeLookOutLeft', 'EyeLookUpLeft', 'EyeSquintLeft', 'EyeWideLeft', 'EyeBlinkRight', 'EyeLookDownRight', 'EyeLookInRight', 'EyeLookOutRight', 'EyeLookUpRight', 'EyeSquintRight', 'EyeWideRight', 'JawForward', 'JawLeft', 'JawRight', 'JawOpen', 'MouthClose', 'MouthFunnel', 'MouthPucker', 'MouthLeft', 'MouthRight', 'MouthSmileLeft', 'MouthSmileRight', 'MouthFrownLeft', 'MouthFrownRight', 'MouthDimpleLeft', 'MouthDimpleRight', 'MouthStretchLeft', 'MouthStretchRight', 'MouthRollLower', 'MouthRollUpper', 'MouthShrugLower', 'MouthShrugUpper', 'MouthPressLeft', 'MouthPressRight', 'MouthLowerDownLeft', 'MouthLowerDownRight', 'MouthUpperUpLeft', 'MouthUpperUpRight', 'BrowDownLeft', 'BrowDownRight', 'BrowInnerUp', 'BrowOuterUpLeft', 'BrowOuterUpRight', 'CheekPuff', 'CheekSquintLeft', 'CheekSquintRight', 'NoseSneerLeft', 'NoseSneerRight', 'TongueOut' ] @staticmethod def csv_to_blend_shapes(csv_path: str): return list(BlendShapeParser.iter_csv_to_blend_shapes(csv_path)) @staticmethod def iter_csv_to_blend_shapes(csv_path: str): with open(csv_path, 'r') as f: reader = csv.DictReader(f) for row in reader: frame = {'timeCode': float(row['timeCode']), 'blendShapes': {}} for key in BlendShapeParser.BLEND_SHAPE_KEYS: col_name = f'blendShapes.{key}' if col_name in row: frame['blendShapes'][key] = float(row[col_name]) yield frame