-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathUpscaleAFXScenes.jsx
305 lines (284 loc) · 11.2 KB
/
UpscaleAFXScenes.jsx
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
var projectFolder = new Folder(new File($.fileName).path);
$.evalFile(projectFolder.fullName + "/lib_ParseConfig.jsx");
var configFile = new File(projectFolder.fullName + "/Config.ini");
var config = parseConfig(configFile);
var upscaleFactor = parseInt(config.upscaleFactor, 10);
$.evalFile(projectFolder.fullName + "/lib_ParseSceneList.js");
var sceneListFile = new File(projectFolder.fullName + "/SceneList.txt");
sceneListFile.open("r");
var sceneList = parseSceneList(sceneListFile.read().split(/\r?\n/));
sceneListFile.close();
for (var i = 0; i < sceneList.afxScenes.length; i++)
{
upscaleScene(sceneList.afxScenes[i]);
}
function upscaleScene(scene)
{
var sceneAFXFolder = new Folder(projectFolder.fullName + "/scenes/" + scene + "/afx");
var sceneAepFiles = sceneAFXFolder.getFiles("*.aep");
var sceneAepFile;
for (var i = 0; i < sceneAepFiles.length; i++)
{
var file = sceneAepFiles[i];
if (file.name.indexOf(scene + ".aep") !== -1)
{
sceneAepFile = file;
break;
}
}
if (!sceneAepFile)
{
alert("Scene " + scene + " doesn't have scene .aep file!");
return;
}
app.open(sceneAepFile);
upscaleSceneItems();
var upscaledFileName = sceneAepFile.name.substring(0, sceneAepFile.name.lastIndexOf(".")) + "_UPSCALED.aep";
app.project.save(new File(sceneAepFile.path + "/" + upscaledFileName));
app.project.close(CloseOptions.DO_NOT_SAVE_CHANGES);
}
function upscaleSceneItems()
{
for (var i = 1; i <= app.project.numItems; i++)
{
var item = app.project.item(i);
if (item instanceof CompItem)
{
item.width = Math.floor(item.width * upscaleFactor);
item.height = Math.floor(item.height * upscaleFactor);
for (var j = 1; j <= item.numLayers; j++)
{
var layer = item.layer(j);
if (!layer.hasVideo) continue;
processLayerProperties(layer);
}
}
else if (item instanceof FootageItem && item.mainSource instanceof SolidSource)
{
item.width = Math.floor(item.width * upscaleFactor);
item.height = Math.floor(item.height * upscaleFactor);
}
}
}
function processLayerProperties(layer)
{
//Default process funcs
var mulByUpscaleFactor = function(v) { return v * upscaleFactor; }
var mulByUpscaleFactorArr2 = function(v)
{
v[0] *= upscaleFactor;
v[1] *= upscaleFactor;
return v;
}
var transformGroup = layer.property("ADBE Transform Group");
//Don't change comp and solid layers scale because it'll be done automatically
if (!(layer.source instanceof CompItem || (layer.source instanceof FootageItem && layer.source.mainSource instanceof SolidSource)))
{
processProperty(transformGroup.property("ADBE Scale"), mulByUpscaleFactorArr2);
}
processProperty(transformGroup.property("ADBE Position"), mulByUpscaleFactorArr2);
var effectsGroup = layer.property("ADBE Effect Parade");
for (var i = 1; i <= effectsGroup.numProperties; i++)
{
var effect = effectsGroup.property(i);
switch (effect.matchName)
{
case "ADBE Wave Warp":
//Wave Height
processProperty(effect.property("ADBE Wave Warp-0002"), mulByUpscaleFactor);
//Wave Width
processProperty(effect.property("ADBE Wave Warp-0003"), mulByUpscaleFactor);
break;
case "ADBE Slider Control":
//Magic FX controls
if (effect.name === "Inner Blur")
{
processProperty(effect.property("ADBE Slider Control-0001"), mulByUpscaleFactor);
}
break;
case "ADBE Motion Blur":
//Blur Length
processProperty(effect.property("ADBE Motion Blur-0002"), mulByUpscaleFactor);
break;
case "ADBE Fast Blur":
//Bluriness
processProperty(effect.property("ADBE Fast Blur-0001"), mulByUpscaleFactor);
break;
case "ADBE Radial Blur":
//Amount
processProperty(effect.property("ADBE Radial Blur-0001"), mulByUpscaleFactor);
break;
case "CC Radial Blur":
//Amount
processProperty(effect.property("CC Radial Blur-0002"), mulByUpscaleFactor);
break;
case "ADBE Glo2":
//Glow Radius
processProperty(effect.property("ADBE Glo2-0003"), mulByUpscaleFactor);
break;
case "ADBE Cell Pattern":
//Size
processProperty(effect.property("ADBE Cell Pattern-0006"), mulByUpscaleFactor);
break;
case "ADBE Cartoonify":
//Detail Radius
processProperty(effect.property("ADBE Cartoonify-0002"), mulByUpscaleFactor);
//Edge->Width
processProperty(effect.property("ADBE Cartoonify-0010"), mulByUpscaleFactor);
break;
case "ADBE Camera Lens Blur":
//Blur Radius
processProperty(effect.property("ADBE Camera Lens Blur-0001"), mulByUpscaleFactor);
break;
case "CC Vector Blur":
//Amount
//60
processProperty(effect.property("CC Vector Blur-0002"), mulByUpscaleFactor);
break;
case "ADBE Bulge":
//Horizontal Radius
processProperty(effect.property("ADBE Bulge-0001"), mulByUpscaleFactor);
//Vertical Radius
processProperty(effect.property("ADBE Bulge-0002"), mulByUpscaleFactor);
//Bulge Center is automatic
break;
case "ADBE Median":
//Radius
processProperty(effect.property("ADBE Median-0001"), mulByUpscaleFactor);
break;
case "ADBE Box Blur2":
//Blur Radius
processProperty(effect.property("ADBE Box Blur2-0001"), mulByUpscaleFactor);
break;
case "ADBE Turbulent Displace":
//Size
processProperty(effect.property("ADBE Turbulent Displace-0003"), mulByUpscaleFactor);
break;
case "ADBE Lightning 2": //Random based, impossible to match 1:1
//Core Radius
processProperty(effect.property("ADBE Lightning 2-0006"), mulByUpscaleFactor);
//Glow Radius
processProperty(effect.property("ADBE Lightning 2-0011"), mulByUpscaleFactor);
//Forking
//TODO 3rd root is still too much
processProperty(effect.property("ADBE Lightning 2-0017"), function(v) {
return Math.pow(v * 100, 1 / (upscaleFactor + 1)) / 100;
});
break;
//Known effects which do not need upscaling property-wise.
case "ADBE Echo":
case "CC Light Burst 2.5": //Ray Length is independent from resolution?
case "CC Light Rays": //Apparently Radius property doesn't need upscaling
case "tc Sound Keys":
case "ADBE 4ColorGradient": //Check it
case "ADBE CHANNEL MIXER":
case "ADBE Change To Color":
case "ADBE Color Key":
case "ADBE Corner Pin":
case "ADBE Displacement Map":
case "ADBE Easy Levels2":
case "ADBE Find Edges":
case "ADBE Fractal Noise": //Random, impossible to match 1:1
case "ADBE Geometry2":
case "ADBE HUE SATURATION":
case "ADBE Noise":
case "ADBE Posterize":
case "ADBE Ramp":
case "ADBE Simple Choker":
case "ADBE Solid Composite":
case "ADBE Threshold2":
case "ADBE Tile":
case "ADBE Tint":
case "APC Colorama":
case "CC Toner":
case "Keylight 906":
case "VIDEOCOPILOT OpticalFlares": //It looks like it is pixel-agnostic but I'm not sure.
break;
default:
alertUnknownEffect(layer.containingComp.name, layer.name, effect);
}
}
//Simple Choker's values are locked to -100/100 so we can't just multiply them.
duplicateSimpleChokers(layer);
}
function alertUnknownEffect(compName, layerName, effect)
{
if (confirm(
"Composition: " + compName +
"\nLayer: " + layerName +
"\nUnknown effect: " + effect.name + " (" + effect.matchName + ")" +
"\n\nPlease check if this effect needs to be upscaled (aka contains any pixel values such as 'radius', 'width', etc).\nClick 'OK' if you want to see the effect properties."
))
{
for (var j = 1; j <= effect.numProperties; j += 20)
{
var propLines = new Array();
propLines.push("# Name | Match Name | Property Type | Value Type");
for (var k = j; k < j + 20 && k <= effect.numProperties; k++)
{
var prop = effect.property(k);
var propLine = "# "
+ prop.name + " | "
+ prop.matchName + " | "
+ enumName(PropertyType, prop.propertyType);
if (prop.propertyType == PropertyType.PROPERTY)
{
propLine += " | " + enumName(PropertyValueType, prop.propertyValueType);
}
propLines.push(propLine);
}
alert(propLines.join("\n"));
}
}
}
function enumName(enumType, value)
{
for (var k in enumType) if (enumType[k] == value) return k;
return null;
}
function processProperty(property, processFunc)
{
if (property.numKeys === 0)
{
property.setValue(processFunc(property.value));
}
else
{
if (property.numKeys > 500)
{
//Get property's containing layer
var layer = property;
while (layer.parentProperty !== null) layer = layer.parentProperty;
alert("Property " + property.name + " of layer " + layer.name + " contains " + property.numKeys + " keys.\nThis is a big amount which will take around " + Math.ceil(property.numKeys * 0.2 / 60) + " minutes to upscale.");
}
for (var i = 1; i <= property.numKeys; i++)
{
property.setValueAtKey(i, processFunc(property.keyValue(i)));
}
}
}
function duplicateSimpleChokers(layer)
{
function duplicateFirstNonDuplicated()
{
var effects = layer.property("ADBE Effect Parade");
for (var k = 1; k <= effects.numProperties; k++)
{
var property = effects.property(k);
if (property.matchName === "ADBE Simple Choker")
{
//Need to more or less save order, so no collecting.
if (property.name.indexOf("DUP_") === -1)
{
var ogName = property.name;
property.name = ogName + " DUP_OG";
var dup = property.duplicate();
dup.name = ogName + " DUP_COPY";
return true;
}
}
}
return false;
}
while (duplicateFirstNonDuplicated()) {}
}