Free Function Friday Ep.38 – getMaskPaths

June 17th 2016 08:00:31am

Welcome to Free Function Friday. This week’s function is designed to gather mask path data. You can pass a layer object to this function and it loops through the parent mask property group seeing if there are any mask paths. If at least one mask exists, the function then retrieves the path data for that mask.

Available attributes are listed below and explained in more detail in the Adobe After Effects CS6 Scripting Guide AENhancers After Effects Scripting Guide. One thing to note too, is that the CS6 scripting guide is the most recent guide Adobe has put out. For each new After Effects release since CS6, there has been blog post updates noting the changes to ExtendScript over the years.

Due to the age of this post, I recommend AENhancers online guide as it is more current, but you can grab the original guide via the green button on the right.

The information is a bit spread out at the moment, but most links can be located through the Adobe I/O page. ExtendScript allows access to read and right the following attributes of a mask path.

Shape object attributes:

  • closed: When true, the first and last vertices are connected to form a closed curve. When false, the closing segment is not drawn.
  • vertices: The anchor points of the shape. Specify each point as an array of two floating-point values, and collect the point pairs into an array for the complete set of points.
  • inTangents: The incoming tangent vectors, or direction handles, associated with the vertices of the shape.
  • outTangents: The outgoing tangent vectors, or direction handles, associated with the vertices of the shape.
  • featherSegLocs: An array containing each feather point’s mask path segment number (section of the mask path between vertices, numbered starting at 0).
  • featherRelSegLocs: An array containing each feather point’s relative position, from 0 to 1, on its mask path segment (section of the mask path between vertices, numbered starting at 0).
  • featherRadii: An array containing each feather point’s radius (feather amount); inner feather points have negative values.
  • featherInterps: An array containing each feather point’s radius interpolation type (0 for non-Hold feather points, 1 for Hold feather points).
  • featherTensions: An array containing each feather point’s tension amount, from 0 (0% tension) to 1 (100% tension).
  • featherTypes: An array containing each feather point’s direction, either 0 (outer feather point) or 1 (inner feather point).
  • featherRelCornerAngles: An array containing each feather point’s relative angle percentage between the two normals on either side of a curved outer feather boundary at a corner on a mask path. The angle value is 0% for feather points not at corners.

Source Code:

var mask = app.project.item(1).layer(1); //Assumes first project item is comp, and first layer has a mask

var r = getMaskPaths(mask);

alert("Path Data:\rClosed: " + r[0].closed.toString() + "\n" + 
"FeatherInterps: " + r[0].featherInterps.toString() + "\n" + 
"FeatherRadii: " + r[0].featherRadii.toString() + "\n" + 
"featherRelCornerAngles: " + r[0].featherRelCornerAngles.toString() + "\n" + 
"featherRelSegLocs: " + r[0].featherRelSegLocs.toString() + "\n" + 
"featherSegLocs: " + r[0].featherSegLocs.toString() + "\n" + 
"featherTensions: " + r[0].featherTensions.toString() + "\n" + 
"featherTypes: " + r[0].featherTypes.toString() + "\n" + 
"inTangents: " + r[0].inTangents.toString() + "\n" + 
"outTangents: " + r[0].outTangents.toString() + "\n" + 
"vertices: " + r[0].vertices.toString()
);

function getMaskPaths(layObj){
		var paths, pathNames, masksGrp, masksGrpLen, curMask;
		paths = new Array();
		pathNames = new Array();
		if(layObj instanceof AVLayer){
			masksGrp = layObj.property("ADBE Mask Parade");
			masksGrpLen = masksGrp.numProperties;
			if(masksGrpLen > 0){
				for(var m=1; m<=masksGrpLen; m++){
					curMask = masksGrp.property(m).property("ADBE Mask Shape").value;
					pathNames.push(masksGrp.property(m).name);
					paths.push(curMask);
				}
			}
		}
		
		if(paths.length === pathNames.length && paths.length > 0){
			return [pathNames, paths];
		}else{
			return null;
		}
}
Checkout more:
Houdini | Loops
After Effects ExtendScript Training: Ep. 4
Houdini Mardini Medieval
Free Function Friday Ep.38 – getMaskPaths
After Effects ExtendScript Training: Ep. 12 Part 1