Skip to main content
Participating Frequently
July 3, 2015
Answered

Is it possible to call a script file from an expression?

  • July 3, 2015
  • 1 reply
  • 1012 views

Hello everyone,

tl;dr Accessing path vertices via expression doesn't seem possible, but scripts can, so is it possible to do it by calling a script file inside the expression?

My goal is to access the number of vertices in various path objects and use this value in an expression. The expression is driving a trim path's offset property and the expression use relative naming so that I can copy the trim path to 500 other shape layers groups and have a different effect (speed of the offset) for each group depending on the number of vertices of each path.

I've been looking for a solution to this problem for quite some time now and my conclusion is that you simply cannot access path vertices via expression, whether the path is in a mask or a shape layer.

Is this correct?

With a mask on a solid layer and according to the After Effects Scripting Guide I should be able to do:

thisComp.layer("Black Solid 1").mask("Mask 1").maskPath.value

or

thisComp.layer("Black Solid 1").mask("Mask 1").maskPath.value.vertices

or

thisComp.layer("Black Solid 1").mask("Mask 1").maskPath.value.vertices.length

I also tried:

thisComp.layer("Black Solid 1").mask("Mask 1").maskPath.vertices.length

and so on...

But when debugging this with the source text of a text layer I only get "undefined" for the value and errors for the other expressions ("property named 'vertices' in Class 'Property' is missing or does not exist").

I'm pretty sure these are the correct methods since a lot of scripts are using those, including:

http://omino.com/pixelblog/2008/12/25/ae-mask-vertices-from-extendscript/

http://www.crgreen.com/aescripts/actual_scripts/Connect_Point_to_Mask_Vertex.jsx

http://aescripts.com/maskvertexexpression/

So if directly accessing the path arrays via expression is not possible, I was thinking about calling, in each expression, an external script which would then return the number of vertices there is in each arrays. It would look like something like this (pseudo-code):

arrayLength = content(thisProperty.propertyGroup(2).name).content("Path 1").value.vertices.length

return arrayLength

And then use the value I get from the script to adjust the speeds in my expressions:

time*arrayLength*thisComp.layer("Controller").effect("Speed")("Slider")

So is it possible to call a script file inside an expression? How?

If not, do you have any other suggestion?

Thanks.

Reference: After Effects CS6 Scripting Guide, page 172.

This topic has been closed for replies.
Correct answer Dan Ebberts

You can use $.evalFile() to execute an external file, but it will be executed by the expression engine, not scripting, so I don't think it helps you. I don't think there is an automatic solution. I think you're stuck with manually running a script any time you change the project, to update a slider somewhere with the number of vertexes.

Dan

1 reply

Dan Ebberts
Community Expert
Dan EbbertsCommunity ExpertCorrect answer
Community Expert
July 3, 2015

You can use $.evalFile() to execute an external file, but it will be executed by the expression engine, not scripting, so I don't think it helps you. I don't think there is an automatic solution. I think you're stuck with manually running a script any time you change the project, to update a slider somewhere with the number of vertexes.

Dan

kltsAuthor
Participating Frequently
July 4, 2015

Hello Dan,

Hadn't thought of that, but manually running a script that would generate a null layer with 500 sliders is an option yes, definitely not my favorite one but I guess it would work.

I first tried $.evalFile with this script:

(timeToFrames()%2) ? "test_A" : "test_B";

The expression was on a "source text" property and the text updated every frame so I think it's good news? Or was it only executed by the expression engine like you said?

In any case I had never heard of evalFile before so thanks a lot for that!

Then when I tried to access layers, properties, objects and so on via evalFile I only got errors. I've tried doing this two ways:

1.

app.project.item(1).layer(1).mask(1).property("maskShape").value.vertices.length;

Error message: "property or method named 'app' in Class 'global' is missing or does not exist."

Launching the script "alert(String(app.project.item(1).layer(1).mask(1).property("maskShape").value.vertices.length)+"vertices")" with the play button of the ExtendScript Toolkit application works fine though and I get the correct number of vertices so it seems the syntax is correct.

2.

mask("Mask 1").maskPath.value.vertices.length;

Error message: "property or method named 'vertices' in Class 'Object' is missing or does not exist."

So it looks like it didn't go through the script engine (?) and I'm back at square one when I wasn't even using a script file at all.

So to make option 1 work I think I need to define the current project the expression is called from as the "app.project".

Any idea on how I could do that? Is it even possible?

Also Dan, -sorry, fanboy moment- but you're an absolute legend to most of us and I have to admit I was thrilled when I saw your answer here Thanks for MotionScript and everything else.

Dan Ebberts
Community Expert
Community Expert
July 4, 2015

I guess your results don't surprise me because your first test file contained a valid expression, and the others didn't.

Depending on what you're doing exactly, it might be possible to set up a script that runs periodically, keeping an eye on changes you're making, and updating properties as you go, but that's a different (somewhat-complicated) can of worms.

Dan