loop not working to sort out repetitive task, help?

Find out why the . goes before the /

Moderator: Paul Tuersley

Post Reply
ScottG
Posts: 38
Joined: March 19th, 2006, 2:45 am

hey guys,

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).
ScottG
Posts: 38
Joined: March 19th, 2006, 2:45 am

it works better now, but it only processes every 2nd item of my selected layers?
why every 2nd item??? i don't get it.

new code:

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, false);
				
				function preCompAllLayers()
				{
				for (var i = 0; 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
							myComp.selectedLayers[i].copyToComp(layerComp);
							
							//add newComp to the original comp, thus achieving precomposition. move to index of topmost orginal layer.
							myCompLayers = myComp.layers;
							var preCompAdded = myCompLayers.add(layerComp);
							
							preCompAdded.moveToEnd();
							
							// move it to the inpoint of the original layer, newInPoint
							preCompAdded.startTime = newInPoint;
							
							//remove the original AV layers from myComp
							chosenLayer.remove();
							
							//item.blendingMode = BlendingMode.STENCIL_LUMA;
						
						chosenLayer = null;
						layerHeight = null;
						layerWidth = null;
						layerPixelAspect = null;
						layerFrameRate = null;
						backgroundColour = null;
						currItem = null;
						subFolder = null;
						subFolderName = null;
						layerName = null;
						layerComp = null;
						myCompLayers = null;
						preCompAdded = null;
						theNumber = null;
						theNumberTwo = null;
						
						//end function
						
						}
							
				}
				preCompAllLayers();
				
			}
	
		
	
//finish undoGroup
app.endUndoGroup();

} //closing brace

[/code]
ScottG
Posts: 38
Joined: March 19th, 2006, 2:45 am

i can get it to run on all layers, but i want it to run only on those layers i select.
the problem seems to be when i add the new comp in, it shuffles the layer indexes around momentarily, even though after i move the added comp and delete the original layer the indexes are all identical.

since after each loop, the indexes are identical to the state they were in before i ran the loop, i don't understand how this momentary shuffle could be the problem. the array of selected layers shouldn't have changed?

hmmm. perhaps i need an array of selected layers INDEXES and not an array of layers??
ScottG
Posts: 38
Joined: March 19th, 2006, 2:45 am

the indices idea turned out to be pure gold. not much experience with arrays, so once i figured it out it made things a lot easier. i can now precompose rather than create a comp, copy the layer, place the comp in the original comp and delete the layer (the longhand way of precomposing).

less code!

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, false);
				var selectedLayerIndices = new Array();
				var layer, state, layerIndex;
					for (var y=1; y<=myComp.numLayers; y++)
					{
					layer = myComp.layer(y);
						if (layer.selected)
						{
							selectedLayerIndices[selectedLayerIndices.length] = layer.index;
						}
					}
				
				
				function preCompAllLayers()
				{
				for (var i = 0; i < selectedLayerIndices.length; i++)
						{
							item = selectedLayerIndices[i];
							var foobar = new Array();
							foobar[0] = item;
							//alert(item);

						var chosenLayer = myComp.layer(item);
						var chosenLayerName = myComp.layer(item).name;
						var newComp = myComp.layers.precompose(cock, "Matte :: " + chosenLayerName, true);
						myComp.layer(item).blendingMode = BlendingMode.STENCIL_LUMA;
						var newComp2 = myComp.layers.precompose(cock, "sc_01 :: " + chosenLayerName, true);
						
						
						//end function
						
						}
							
				}
				preCompAllLayers();
				
			}
	
		
	
//finish undoGroup
app.endUndoGroup();

} //closing brace
Post Reply