Copy link to clipboard
Copied
I work in animation and a huge part of my day is comping SWF assets in AE. Under certain conditions, such as a camera move, the lines in SWF artwork will shimmer due to continuous rasterization of the SWF layers. There's a way around this by precomping the SWF assets and scaling them to 200%, then turning off continuous rasterization of the precomp (not the SWF layers) and scaling the precomp by 50% (thereby arriving back at 100% overall but without the shimmer).
I have a script which does the upscale part, which must be run inside of the SWF precomp. It changes the comp size to 3840x2160, and upscales all the SWFs 200%.
This works great, but it's only automates part of the operation. One level up, I have to manually set the precomp to 50% and turn off continuous rasterization. This gets tedious if a scene has dozens of characters, each with their own SWF precomp.
What I'd like to do is simply select the SWF precomp and run the script, and it perform the upscaling operation inside the precomp, then sets the scale of the precomp to 50% and turns off continuous rasterization. Ideally, I'd love this to be able to work on multiple selected precomps, looping through each of the (but this is wish list stuff – so bonus points if anyone can figure that out!).
I'll be honest, I'm still learning AE scripting. The script is cobbled together from a few places, albeit with a few modifications from me, so any help is greatly appreciated. Thank you!
myPanel.grp.group3.swf_fix.onClick = function() {
app.beginUndoGroup("Scale to 4K")
var activeComp = app.project.activeItem;
// Scale the comp to 4K
activeComp.width = 3840;
activeComp.height = 2160;
// Add null
var nullLayer = activeComp.layers.addNull();
// Scale null to 1/4 size of comp
nullLayer.position.setValue([activeComp.width/4,activeComp.height/4]);
// Parent layers to null
ParentUnparented(activeComp, nullLayer);
// Scale null 200%
nullLayer.transform.scale.setValue([200,200]);
// Delete null
nullLayer.remove();
// Go through layers, parent if not already parented. This is temporary and required.
function ParentUnparented(theComp, newParent)
{
for (var i = 1; i <= theComp.numLayers; i++) {
var curLayer = theComp.layer(i);
var wasLocked = curLayer.locked;
curLayer.locked = false;
if (curLayer != newParent && curLayer.parent == null) {
curLayer.parent = newParent;
}
curLayer.locked = wasLocked
}
}
app.endUndoGroup();
}
Sorry, I didn't read part 2 of your post. You could define variable s in your var declaration section, and then do this:
// do stuff to the precomp layer
s = precompLayer.transform.scale.value;
precompLayer.transform.scale.setValue([s[0]/2,s[1]/2]);
precompLayer.collapseTransformation = true;
Copy link to clipboard
Copied
I think I would change the workflow a little so that the script expects that you have precomp layers selected in the main comp. It could then do the down scaling and turning off the collapseTransformation atrribute on the precomp layers, and use layer.source to get to the corresponding precomps to do the part you already have coded.
Copy link to clipboard
Copied
Thanks Dan, that definitely points me in the right direction as to the theory. It's been over a year since I dabbled in AE scripting so I'm a little rusty as to how to implement it into the code I already have. I'll need to think about it and research how to do it.
Would this also work for multiple selected precomps?
Copy link to clipboard
Copied
Yes, sure. I'd structure like this (I'd also add a bunch of checks to make sure the activeItem is a comp and that each selected layer has a source and that the source is a CompItem--especially if other people would use the script):
var mainComp = app.project.activeItem;
var precompLayers = mainComp.selectedLayers;
var precompLayer;
var precomp;
for (var i = 0; i < precompLayers.length; i++){
precompLayer = precompLayers[i];
// do stuff to the precomp layer
precomp = precompLayer.source;
// do stuff inside the precomp
}
Copy link to clipboard
Copied
Thank you Dan! I'm so close. 99% there. The stuff inside of the precomp is working great with your additions.
However, I know that my "do stuff to the precomp layer" code is incorrect…
(1) The code works, but it's affecting layer number 1, when I actually need it to affect selected layers. I know that this is due it referencing Layer(1), but I'm unsure how to change that to make it affect selected layers only. I tried "precompLayers.transform.scale.setValue([50,50]);" but I get an error that "undefined is not an object".
(2) I've realized that setting the scale to 50,50 is not actually what I need. What I need instead is to divide the current scale by 2. Eg, the original layer might be 180%, so I would want it to know be 90%. I'm unsure how to do that. I thought I might be on the right track with "mainComp.layer(1).setValue([mainComp.width/2,mainComp.height/2]);" but I get an error "mainComp.layer(1).setValue is undefined"
app.beginUndoGroup("Upscale SWF")
var mainComp = app.project.activeItem;
var precompLayers = mainComp.selectedLayers;
var precompLayer;
var precomp;
for (var i = 0; i < precompLayers.length; i++){
precompLayer = precompLayers[i];
// do stuff to the precomp layer
mainComp.layer(1).transform.scale.setValue([50,50]);
mainComp.layer(1).collapseTransformation = true;
precomp = precompLayer.source;
// do stuff inside the precomp
// Scale the comp to 4K
precomp.width = 3840;
precomp.height = 2160;
// Add null
var nullLayer = precomp.layers.addNull();
// Scale null to 1/4 size of comp
nullLayer.position.setValue([precomp.width/4,precomp.height/4]);
// Parent layers to null
ParentUnparented(precomp, nullLayer);
// Scale null 200%
nullLayer.transform.scale.setValue([200,200]);
// Delete null
nullLayer.remove();
// Go through layers, parent if not already parented. This is temporary and required.
function ParentUnparented(theComp, newParent)
{
for (var i = 1; i <= theComp.numLayers; i++) {
var curLayer = theComp.layer(i);
var wasLocked = curLayer.locked;
curLayer.locked = false;
if (curLayer != newParent && curLayer.parent == null) {
curLayer.parent = newParent;
}
curLayer.locked = wasLocked
}
}
}
app.endUndoGroup();
Copy link to clipboard
Copied
I think it would be like this:
// do stuff to the precomp layer
precompLayer.transform.scale.setValue([50,50]);
precompLayer.collapseTransformation = true;
Copy link to clipboard
Copied
Sorry, I didn't read part 2 of your post. You could define variable s in your var declaration section, and then do this:
// do stuff to the precomp layer
s = precompLayer.transform.scale.value;
precompLayer.transform.scale.setValue([s[0]/2,s[1]/2]);
precompLayer.collapseTransformation = true;
Copy link to clipboard
Copied
Thanks Dan, that did it! I truly appreciate your patience on this.
Copy link to clipboard
Copied
Again, thank you. Is there a way to set the scale to 50% of the current value, rather than entering 50 as the value? Eg, the original layer might be 180%, so I would want it to know be 90%. I'm unsure how to do that. In the GUI I would just go into the scale value and type "/2" after the number, so I'm looking for a way to do that with the script.
I also realized a couple of errors in my code. I needed the collapse transform to be 'false' not 'true', and I needed the null to be a 3D layer in the precomp (due to the SWFs having 3D enabled). Here's where I'm currently at…
app.beginUndoGroup("Upscale SWF")
var mainComp = app.project.activeItem;
var precompLayers = mainComp.selectedLayers;
var precompLayer;
var precomp;
for (var i = 0; i < precompLayers.length; i++){
precompLayer = precompLayers[i];
// do stuff to the precomp layer
precompLayer.transform.scale.setValue([50,50]);
precompLayer.collapseTransformation = false;
precomp = precompLayer.source;
// do stuff inside the precomp
// Scale the comp to 4K
precomp.width = 3840;
precomp.height = 2160;
// Add null
var nullLayer = precomp.layers.addNull();
// Make null 3D
nullLayer.threeDLayer = true;
// Center null to comp
nullLayer.position.setValue([960,540,0]);
// Parent layers to null
ParentUnparented(precomp, nullLayer);
// Scale null 200%
nullLayer.transform.scale.setValue([200,200]);
// Delete null
nullLayer.remove();
// Go through layers, parent if not already parented. This is temporary and required.
function ParentUnparented(theComp, newParent)
{
for (var i = 1; i <= theComp.numLayers; i++) {
var curLayer = theComp.layer(i);
var wasLocked = curLayer.locked;
curLayer.locked = false;
if (curLayer != newParent && curLayer.parent == null) {
curLayer.parent = newParent;
}
curLayer.locked = wasLocked
}
}
}
app.endUndoGroup();
Find more inspiration, events, and resources on the new Adobe Community
Explore Now