Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Quick and Dirty Expression Baker

  • Quick and Dirty Expression Baker

    Posted by Bryan Woods on September 5, 2013 at 6:13 pm

    I’m struggling with expression baking. Its very stupid and incredibly time consuming. For my needs, I don’t need all the extra things the default baking does, and smartbaker from AE scripts doesn’t fix the issue either.

    I have a script that aligns/scales logos together, and another that dynamically adds text to a text layer. These things are static, no motion or anything like that. But the comps need to be long, like 10seconds long. Obviously baking these layers is a very long, time consuming process when really all I need is to bake the first frame, and then delete the keyframes generated. Typically, I’ve had to trim all my layers to 1 frame, highlight all the expressions of each layer, run the bake command, then delete the keyframes generated, and then re-extend all the layers back to what they were originally. It takes forever. And I want to see if I can find a better way to go about this.

    Ideally, I need to figure out a way to just give a general command that says “If there is an expression applied to this selected layer, bake it”, but I don’t know what the correct code would be for that (its really difficult to find the things I need from the CS6 scripting guide).
    So the process would be: 1. All layers selected, trim to 1 frame. 2. Identify expressions of each layer, and run AE’s bake command. 3. Delete created keyframes. 4. re-extend layers to the duration of the current comp.

    Below is a script Dan came up with a while back that does part of what I’m looking for, but I have to code for every possible expression in AE. For example, I would need to put in code to check for expression on source text. But I also don’t know how to trim a layer to 1 frame, then extend it back to the comp duration.


    {

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

    var myComp = app.project.activeItem;
    if (myComp && myComp instanceof CompItem){
    var myLayer;
    var myProperty;
    app.beginUndoGroup("convert expressions");
    for (var i = 1; i <= myComp.numLayers; i++){
    myLayer = myComp.layer(i);
    try{
    myProperty = myLayer.property("position");
    convertToKeyframes(myProperty);
    }catch(err){
    }
    try{
    myProperty = myLayer.property("anchorPoint");
    convertToKeyframes(myProperty);
    }catch(err){
    }
    try{
    myProperty = myLayer.property("rotation");
    convertToKeyframes(myProperty);
    }catch(err){
    }
    try{
    myProperty = myLayer.property("scale");
    convertToKeyframes(myProperty);
    }catch(err){
    }
    try{
    myProperty = myLayer.property("opacity");
    convertToKeyframes(myProperty);
    }catch(err){
    }
    }
    app.endUndoGroup();
    }

    }

    Really, I’m practically there with Dan’s code. I’m just not sure about layer trimming, or deleting keyframes. But I understand whats going on here, I just don’t have the vocabulary to express it!

    Bryan Woods replied 12 years, 10 months ago 2 Members · 6 Replies
  • 6 Replies
  • Xavier Gomez

    September 5, 2013 at 8:08 pm

    Why dont you use setValue instead of convert to keyframes?
    the code below converts the expression to its value if the expression is enabled and if there are no keys (otherwise the property is probably not constant and should not be converted to a constant value).
    function convertToValue(prop, evalTime)
    {
    if (prop.expressionEnabled && prop.numKeys<1)
    {
    prop.setValue(prop.valueAtTime(evalTime,false));
    prop.expressionEnabled = false;
    }
    return;
    }

    Xavier

  • Bryan Woods

    September 5, 2013 at 9:07 pm

    Ok, that could be an option. I wasn’t aware that this could be another way. If it removes the trimming/extending steps, that would be awesome. From your code you posted, would I use this for every check of each type of expression like in Dan’s code? Or would this be enough if we just applied this to a selected layer and it converts to setvalue for every expression in a layer?

    Thanks for your suggestion!

  • Xavier Gomez

    September 6, 2013 at 11:02 am

    The usage is the same as your “convertToKeyframes” function. You still need to loop over the layers/properties you want to apply it to.
    var myComp = app.project.activeItem;
    if (myComp instanceof CompItem)
    {
    var i, numLayers;
    var myLayer, evalTime;
    app.beginUndoGroup("convert expressions");
    for (i = 1; i <= numLayers; i++)
    {
    myLayer = myComp.layer(i);
    evalTime = myLayer.inPoint;
    try{ convertExpressionToValue(myLayer.property("position"), evalTime);} catch(err){ };
    try{ convertExpressionToValue(myLayer.property("anchorPoint"), evalTime);} catch(err){ };
    try{ convertExpressionToValue(myLayer.property("rotation"), evalTime);} catch(err){ };
    try{ convertExpressionToValue(myLayer.property("scale"), evalTime);} catch(err){ };
    try{ convertExpressionToValue(myLayer.property("opacity"), evalTime);} catch(err){ };
    }
    app.endUndoGroup();
    }

    If you know that you always want to convert expressions to keyframes inside the transform group only, you could make a function that does specifically that to a given layer. The principle is the same.

    Xavier.

  • Bryan Woods

    September 6, 2013 at 6:48 pm

    I’m not getting any life from your above code. Are you sure convertExpressionToValue is a valid function? Or do we need to define it? Because I run this at the moment on my selected layers, and nothing happens. Not even an error message pops up.

  • Xavier Gomez

    September 6, 2013 at 9:21 pm

    convertExpressionToValue is the function i had posted just before (by the way i realize i miscopied its name, it was convertToValue before… call it whatever you want). Just to make sure, here is the full text:

    function convertExpressionToValue(prop, evalTime)
    {
    if (prop.expressionEnabled && prop.numKeys<1)
    {
    prop.setValue(prop.valueAtTime(evalTime,false));
    prop.expressionEnabled = false; } return;
    }
    }
    var myComp = app.project.activeItem;
    if (myComp instanceof CompItem)
    {
    var i, numLayers=myComp.numLayers;
    var myLayer, evalTime;
    app.beginUndoGroup("convert expressions");
    for (i = 1; i <= numLayers; i++)
    {
    myLayer = myComp.layer(i);
    evalTime = myLayer.inPoint;
    try{ convertExpressionToValue(myLayer.property("position"), evalTime);} catch(err){ };
    try{ convertExpressionToValue(myLayer.property("anchorPoint"), evalTime);} catch(err){ };
    try{ convertExpressionToValue(myLayer.property("rotation"), evalTime);} catch(err){ };
    try{ convertExpressionToValue(myLayer.property("scale"), evalTime);} catch(err){ };
    try{ convertExpressionToValue(myLayer.property("opacity"), evalTime);} catch(err){ };
    }
    app.endUndoGroup();
    }

    Xavier.

  • Bryan Woods

    September 6, 2013 at 10:06 pm

    Aweseome, yeah I noticed the discrepency as well. Seems to be working properly. I added a check for source text. At this point I think i’ve covered every possible expression property, but do you know if there is a way to just create one statement that just accepts a value had an expression and converts its value? Instead of writing out planning for every possible expression attribute…

    Thanks for your help on this! Much easier than the steps I had in mind.

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