Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Bake expressions of a specific property for all layers inside selected comps

  • Bake expressions of a specific property for all layers inside selected comps

    Posted by Gabriele Bartoli on December 3, 2015 at 5:01 pm

    Hi,

    I have been trying to modify a script made by Dan, which I found here on the forum. The original would check a defined number of properties and bake expressions, if any were found. It would cycle through all layers of an active comp. What I am trying to do is to have a script do the same thing, but for multiple comps. The property I am interested in is the Source Text property.

    I’ll paste the edited code below: I had to do some reverse engineering and I added a lot of comments. It is my first try with a script and I had to wrap my head around the code. As of now, it works with only the active comp, but it targets the proper property.

    I was thinking of storing the selection, begin a for loop through such selection (which should be an array) and use the exact same code for each item of the array.

    Any suggestion on how to store such selection? I tried to do:

    var selection = app.project.selection
    but I can’t seem to make it work.

    Here is the code:

    // Define function
    function convertToKeyframes(theProperty){
    if (theProperty.canSetExpression && theProperty.expressionEnabled){
    theProperty.selected = true;
    app.executeCommand(app.findMenuCommandId("Convert Expression to Keyframes"));
    theProperty.selected = false;
    }
    }

    // Store the selected comp:
    // It can either be selected in the "Project" tab or in the timeline
    // If a layer is selected, the method returns the comp to which the layer belongs
    var myComp = app.project.activeItem;

    // ----- debug print
    //$.write();
    //$.write(myComp instanceof CompItem);

    // Check if something is selected and if selection it is a Composition
    if (myComp && myComp instanceof CompItem){
    var myLayer;
    var myProperty;

    // Wraps everything that follows in a single Undo step
    app.beginUndoGroup("convert expressions");

    // The for loop is used to access every layer in the comp using its index
    for (var i = 1; i <= myComp.numLayers; i++){
    myLayer = myComp.layer(i);

    // If the layer has the property, invoke the function with the property as input
    try{
    myProperty = myLayer.property("sourceText");
    convertToKeyframes(myProperty);
    }catch(err){
    }

    }
    app.endUndoGroup();
    }

    Thanks!

    Gabriele Bartoli replied 10 years, 5 months ago 2 Members · 3 Replies
  • 3 Replies
  • Miguel De mendoza

    December 3, 2015 at 8:02 pm

    There are some erros on your code.
    First of all,using a try/catch statement to check if a layer have a property is not the best way:
    // If the layer has the property, invoke the function with the property as input
    try{//wrong
    myProperty = myLayer.property("sourceText");
    convertToKeyframes(myProperty);
    }catch(err){
    }

    You must do it by a if/else statement, and in your case, what you need to check is if the current layer is a TextLayer object, because all text layers must have a sourceText property.

    Second you are trying to access sourceText property on a wrong way. You must access it using full property spec, and it’s better to use the matchName instead of the name:

    if(myLayer instanceof TextLayer){
    myProperty = myLayer.property(" ADBE Text Properties").property("ADBE Text Document");
    //Do stuff
    }

    Other thing I can see is if you want to do this for multiple comps you must encapsulate your code on a function with the current comp as parameter, and then iterate throug the comps:

    function bakeExpressions(curComp){
    // Check if something is selected and if selection it is a Composition...
    //...
    }
    selection = app.project.selection;

    for(var curComp in selection){
    bakeExpressions(curComp);
    }

  • Gabriele Bartoli

    December 3, 2015 at 8:24 pm

    Thanks for taking the time to look at the code. Hope you don’t mind, but I’m going to focus on the third point, which is the most important to me. I’m on a deadline and I’d like to focus on that for now. The rest of the code is exactly what Dan Ebberts wrote and it works, so I’ll leave it as is for the time being.

    I’ll let you know how it goes!

    Thanks again.

  • Gabriele Bartoli

    December 9, 2015 at 2:11 am

    Hi.

    I finally got the code to do what I needed it to be (which was slightly different from baking the expression for the whole length of the layer), and I thought I’d share it. Let me know what you think!

    /*
    Freeze expression at inPoint

    This script goes through the layers of the comps selected in the project panel and identifies all Text Layers.
    If the Source Text property is being evaluated via expression, a keyframe is created at inPoint for the expression-driven value.
    After creating such keyframe, the expression is disabled.

    This can be useful to save a lot of rendertime if the expression is not used to change the value across time but only to get
    it from another source (.txt file, comp name, another text layer).
    */

    {
    function manipulateTextLayers(comp){
    var totLayers = comp.numLayers; // Store the length of the input argument 'comp'

    for (j = 1; j &lt;= totLayers; j++){
    var myLayer = comp.layer(j); // Store the layer object in a var

    // Check if the layer is a Text layer, then proceed
    if(myLayer instanceof TextLayer){
    var myProperty = myLayer.property("sourceText"); // Store property of interest in var

    // Check an expression is currently applied
    if (myProperty.expressionEnabled){
    var inPoint = myLayer.inPoint; // Store the inPoint time for the layer in var
    var valAtInPoint = myProperty.valueAtTime(inPoint, false); // Store the value of the property at inPoint
    // NOTE: Using 'false' as the second argument, any applied expression is NOT ignored

    myProperty.setValueAtTime(inPoint, valAtInPoint); // Create a keyframe inPoint with the expression-driven value
    myProperty.expressionEnabled = false; // Disable the expression
    }
    }
    }
    }

    app.beginUndoGroup("Freeze expressions at inPoint"); // Set the undo group

    // $.write("\n=============\n"); // Debug line of text

    // Store the selection. The selection attribute returns an array
    var selection = app.project.selection;

    // Run through the selected items and invoke function only for comps
    for (i = 0;i &lt; selection.length; i++){
    if ( selection[i] instanceof CompItem){
    $.write(selection[i].name + "\n"); // Debug

    // Invoke function
    manipulateTextLayers(selection[i]);
    }else{
    $.write(selection[i].name + " is selected but not a comp!\n");
    }
    }

    }

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy