i have some 500 layers or more of 3d, for a 60 shot piece. each of these layers needs to be precomped once (so that any rotos i do on the matte will trickle down to the multiple times the matte will be used), and then once more (the matte is set to STENCIL LUMA as the topmost layer in another comp).
i thought i could write a script to do all this for me, but my script won't loop, and i don't understand why. i've used for loops before, but perhaps not this complex.
is anyone able to clear this up for me?
code below:
(rd - i've used some of your utilities, thankyou).
Code: Select all
{ // opening brace
// create undo group
app.beginUndoGroup("Foo");
// rd_selectedLayers(comp, inOrder)
//
// Description:
// This function retrieves an array of the selected layers in a
// composition, with the option of retrieving them in top-to-bottom order.
//
// Parameters:
// comp - The composition containing the selected layers.
// inOrder - Controls if layers will be returned in selected (true, or
// not specified) or top-to-bottom (false) order.
//
// Returns:
// Array of Layer objects. Array is empty if no layers are currently
// selected. Array indices start at 0.
//
function rd_selectedLayers(comp, inOrder)
{
if ((comp != null) && (comp instanceof CompItem))
{
if ((inOrder == undefined) || (inOrder == true))
{
// Selected order (if explicit, or no inOrder parameter)
return comp.selectedLayers;
}
else
{
var selectedLayers = comp.selectedLayers;
selectedLayers.sort(rd_sortLayersByIndex);
return selectedLayers;
}
}
else
return new Array();
}
var myComp = app.project.activeItem;
if(myComp instanceof CompItem)
{
rd_selectedLayers(myComp, true);
function preCompAllLayers()
{
for (var i = 1; i <= myComp.selectedLayers.length; i++)
{
item = myComp.selectedLayers[i];
var chosenLayer = item;
// put all attributes of the topmost layer into variables that i can use later to create comps of the same dimesions/frame rate/etc
//when precomping multiple layers, i should check to see if the first layer is an AV Item, as a text/camera/light/audioonly will not have these attributes!
//if the layer is text/camera/light/audioonly, go to the next layer in the stack
//if all layers are text/camera/light/audioonly, then apply a set of defaults, or addComp() will fail.
var layerHeight = chosenLayer.height;
var layerWidth = chosenLayer.width;
var layerPixelAspect = chosenLayer.source.pixelAspect;
var layerFrameRate = chosenLayer.source.frameRate;
var backgroundColour = [1,1,1];
//var layerName = chosenLayer.name;
// Are we at the top level (root folder)?
var currItem = chosenLayer.source;
while (currItem.parentFolder != app.project.rootFolder)
{
// Select the current item's parent folder also retrieve the name of the folder
var subFolder = currItem.parentFolder;
subFolder.selected = true;
var subFolderName = subFolder.name;
break;
}
//These assume a layer stretch > 0. These need to be revised for negatively stretched layers.
//ins and outs of chosenLayer. only used to get the in/out of earliest and latest layer
var newInPoint = chosenLayer.inPoint;
var newOutPoint = chosenLayer.outPoint;
var layerDuration = newOutPoint - newInPoint;
// get the name of first layer and chop to 31 chars
var layerName = chosenLayer.name;
if(layerName.length > 31)
{
layerName = layerName.substring(0, 31);
}
// create the new comp
layerComp = subFolder.items.addComp("Matte :: " + layerName, layerWidth, layerHeight, layerPixelAspect, layerDuration, layerFrameRate);
//#####################################
//add the layers to the new comp
//iterate through from the bottom up, so the layers appear in the new comp in the same order as they are in the current comp
//so i have an array of the indices of the selected layers. fine.
//now what?
myComp.selectedLayers[i].copyToComp(layerComp);
//slip the layer so it's inPoint is at the beginning of the comp:
//rdshifter will help me here
//refer to layer within newComp by name, should still be layerName
//var Layers = layerComp.layers;
//var origLayer = layerCompLayers.byName(layerName);
//var offset = origLayer.inPoint - origLayer.startTime;
//origLayer.startTime = offset*-1;
//add newComp to the original comp, thus achieving precomposition. move to index of topmost orginal layer.
myCompLayers = myComp.layers;
var preCompAdded = myCompLayers.add(layerComp);
var theNumber = i - 1;
preCompAdded.moveAfter(myComp.selectedLayers[theNumber]);
// move it to the inpoint of the original layer, newInPoint
preCompAdded.startTime = newInPoint;
//remove the original AV layers from myComp
chosenLayer.remove();
/*var layerIndices = new Array();
layerIndices[0] = i
var newComp = myComp.layers.precompose(layerIndices, "newCompName", true );
var theNumber = i - 1;
newComp.moveAfter(myComp.selectedLayers[theNumber]);
*/
//item.blendingMode = BlendingMode.STENCIL_LUMA;
clear;
//end function
}
}
preCompAllLayers();
}
//finish undoGroup
app.endUndoGroup();
} //closing brace
one thing to note is that the footage needs to be in a folder in the project for the script to work (i like neatness, and with 60 shots things are going to get messy real quick).