-
Notifications
You must be signed in to change notification settings - Fork 60
/
ValueFuncs.py
123 lines (104 loc) · 5.67 KB
/
ValueFuncs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import numexpr
import torch
import numpy as np
import pandas as pd
import re
import json
from .ScheduleFuncs import check_is_number
def sanitize_value(value):
# Remove single quotes, double quotes, and parentheses
value = value.replace("'", "").replace('"', "").replace('(', "").replace(')', "")
return value
def get_inbetweens(key_frames, max_frames, integer=False, interp_method='Linear', is_single_string=False):
key_frame_series = pd.Series([np.nan for a in range(max_frames)])
max_f = max_frames - 1 # needed for numexpr even though it doesn't look like it's in use.
value_is_number = False
for i in range(0, max_frames):
if i in key_frames:
value = key_frames[i]
value_is_number = check_is_number(sanitize_value(value))
if value_is_number: # if it's only a number, leave the rest for the default interpolation
key_frame_series[i] = sanitize_value(value)
if not value_is_number:
t = i
# workaround for values formatted like 0:("I am test") //used for sampler schedules
key_frame_series[i] = numexpr.evaluate(value) if not is_single_string else sanitize_value(value)
elif is_single_string: # take previous string value and replicate it
key_frame_series[i] = key_frame_series[i - 1]
key_frame_series = key_frame_series.astype(float) if not is_single_string else key_frame_series # as string
if interp_method == 'Cubic' and len(key_frames.items()) <= 3:
interp_method = 'Quadratic'
if interp_method == 'Quadratic' and len(key_frames.items()) <= 2:
interp_method = 'Linear'
key_frame_series[0] = key_frame_series[key_frame_series.first_valid_index()]
key_frame_series[max_frames - 1] = key_frame_series[key_frame_series.last_valid_index()]
key_frame_series = key_frame_series.interpolate(method=interp_method.lower(), limit_direction='both')
if integer:
return key_frame_series.astype(int)
return key_frame_series
def parse_key_frames(string, max_frames):
# because math functions (i.e. sin(t)) can utilize brackets
# it extracts the value in form of some stuff
# which has previously been enclosed with brackets and
# with a comma or end of line existing after the closing one
frames = dict()
for match_object in string.split(","):
frameParam = match_object.split(":")
max_f = max_frames - 1 # needed for numexpr even though it doesn't look like it's in use.
frame_str = sanitize_value(frameParam[0].strip())
try:
if check_is_number(frame_str):
frame = int(frame_str)
else:
# Simplified expression evaluation
frame = int(numexpr.evaluate(frame_str))
except Exception as e:
raise RuntimeError(f"Error evaluating frame expression '{frame_str}': {e}")
frames[frame] = frameParam[1].strip()
if frames == {} and len(string) != 0:
raise RuntimeError('Key Frame string not correctly formatted')
return frames
def batch_get_inbetweens(key_frames, max_frames, integer=False, interp_method='Linear', is_single_string=False):
key_frame_series = pd.Series([np.nan for a in range(max_frames)])
max_f = max_frames - 1 # needed for numexpr even though it doesn't look like it's in use.
value_is_number = False
for i in range(0, max_frames):
if i in key_frames:
value = str(key_frames[i]) # Convert to string to ensure it's treated as an expression
value_is_number = check_is_number(sanitize_value(value))
if value_is_number:
key_frame_series[i] = sanitize_value(value)
if not value_is_number:
t = i
# workaround for values formatted like 0:("I am test") //used for sampler schedules
key_frame_series[i] = numexpr.evaluate(value) if not is_single_string else sanitize_value(value)
elif is_single_string: # take previous string value and replicate it
key_frame_series[i] = key_frame_series[i - 1]
key_frame_series = key_frame_series.astype(float) if not is_single_string else key_frame_series # as string
if interp_method == 'Cubic' and len(key_frames.items()) <= 3:
interp_method = 'Quadratic'
if interp_method == 'Quadratic' and len(key_frames.items()) <= 2:
interp_method = 'Linear'
key_frame_series[0] = key_frame_series[key_frame_series.first_valid_index()]
key_frame_series[max_frames - 1] = key_frame_series[key_frame_series.last_valid_index()]
key_frame_series = key_frame_series.interpolate(method=interp_method.lower(), limit_direction='both')
if integer:
return key_frame_series.astype(int)
return key_frame_series
def batch_parse_key_frames(string, max_frames):
# because math functions (i.e. sin(t)) can utilize brackets
# it extracts the value in form of some stuff
# which has previously been enclosed with brackets and
# with a comma or end of line existing after the closing one
string = re.sub(r',\s*$', '', string)
frames = dict()
for match_object in string.split(","):
frameParam = match_object.split(":")
max_f = max_frames - 1 # needed for numexpr even though it doesn't look like it's in use.
frame = int(sanitize_value(frameParam[0])) if check_is_number(
sanitize_value(frameParam[0].strip())) else int(numexpr.evaluate(
frameParam[0].strip().replace("'", "", 1).replace('"', "", 1)[::-1].replace("'", "", 1).replace('"', "",1)[::-1]))
frames[frame] = frameParam[1].strip()
if frames == {} and len(string) != 0:
raise RuntimeError('Key Frame string not correctly formatted')
return frames