need help with my script - imports mask from text file

Find out why the . goes before the /

Moderator: Paul Tuersley

Post Reply
evesira
Posts: 4
Joined: July 30th, 2009, 10:52 am

Hello there,

I'm trying to write two scripts:
-one that imports a mask from a text file containing a series floating point values
-one that imports a motion path (position keyframes) from the same type of text file



Here's what I have so far for importing a mask:

Code: Select all

// After Effects script - import mask/path from text file
// By Vincent Rubinetti
// 08 -  12 - 2009

var pointSeparator = "\n";
var xySeparator = " ";

var project = app.project;

if (project)
{
	var myComp = app.project.activeItem;
     if (myComp != null && (myComp instanceof CompItem))
	{
         var selectedLayers = myComp.selectedLayers;
         if(selectedLayers.length == 1)
         {         
			var myLayer = selectedLayers[0];
			var selectedProps = myLayer.selectedProperties;
			if(selectedProps.length >= 1)
			{
				var selectedProp = selectedProps[0];
				alert("Select a text file with data points");
				var myFile = File.openDialog ("Select text file with data points");  
				var fileOK = myFile.open("r","TEXT","????");
				if (fileOK)
				{
					var undoStr = "Import Mask";
					app.beginUndoGroup(undoStr);
					
					var myText = myFile.read();
					var points = myText.split(pointSeparator);
					
					var myMask = selectedProp.property("maskShape").value;
					var myShape = new Shape();
					
					var shapeArray = new Array();
					var xyArray = new Array();
					
					for(var i = 0; i < points.length; i++)
					{
						xyArray = points[i].split(xySeparator);
						if (xyArray.length == 2 && !isNaN(parseFloat(xyArray[0])) && !isNaN(parseFloat(xyArray[1])))
						{
							xyArray[0] = parseFloat(xyArray[0]);
							xyArray[1] = parseFloat(xyArray[1]);
							shapeArray[i] = xyArray;
						}
                                                else
                                                {break;}
					}
				
					myShape.vertices = shapeArray;
					myShape.closed = true;
					myMask = myShape;
					
					app.endUndoGroup();
				}
				else
				{alert("Error opening text file");}
			}
			else
			{alert("Exactly one property must be selected");}
		}
		else
		{alert("Exactly one layer must be selected");} 
	}
	else 
	{alert("No comp");}
}
else
{alert("No project");}
I give it a text file like this:

Code: Select all

1380.10 839.15
1386.04 849.01
1389.26 859.19
1389.78 869.42
1387.66 879.43
1383.00 888.97
1375.93 897.80
1366.60 905.69
1355.20 912.46
1341.94 917.93
1327.06 921.97
1310.81 924.45
1293.45 925.29
1275.25 924.47
1256.50 921.96
1237.46 917.79
1218.41 912.01
1199.62 904.72
1181.33 896.04
1163.79 886.13
1147.19 875.15
1131.73 863.32
1117.58 850.85
1104.86 837.98
1093.66 824.97
1084.07 812.07
1076.12 799.55
1069.79 787.66
1065.07 776.67
1061.87 766.82
1060.11 758.35
1059.65 751.46
1060.34 746.36
1061.99 743.21
1064.41 742.16
1067.37 743.31
1070.64 746.74
1073.98 752.49
1077.14 760.58
1079.86 770.98
1081.91 783.61
1083.04 798.39
1083.03 815.18
1081.68 833.81
1078.78 854.09
1074.18 875.81
1067.74 898.71
1059.36 922.53
1048.94 946.99
1036.47 971.80
1021.92 996.66
1005.32 1021.26
986.75 1045.30
966.29 1068.48
944.10 1090.53
920.33 1111.16
895.19 1130.14
868.90 1147.22
841.71 1162.22
813.90 1174.96
785.77 1185.29
757.61 1193.13
729.74 1198.39

It doesn't work. No errors are thrown, and the app doesn't crash, so it did something. I'm quite sure the logic is correct (splitting up the text file appropriately and setting the shape vertices). But admittedly, I don't understand the AE object model. The script is doing something to some property somewhere, but not the one i want. I want the user to be able to select: layer -> Masks -> someMask -> mask path -> shape.

Also, for the script that will import a motion path, I want the user to be able to import it to any property that has x and y values. Is this possible?
bradshaw1965
Posts: 98
Joined: March 14th, 2006, 2:16 pm
Location: Atlanta, GA
Contact:

Take a look at:
http://omino.com/pixelblog/2008/12/25/a ... endscript/

at first glance without going through your logic, you might be missing myMask.setValue(shapeArray);

also
...that you must assign the vertices before assigning closed to true or false
http://www.chris-g.net/2008/12/08/after ... scripting/

hope that helps.

Dale
Dale Bradshaw
Technology Director | Primal Screen
creative-workflow-hacks.com
Atlanta, GA
evesira
Posts: 4
Joined: July 30th, 2009, 10:52 am

Hurray! I solved it! Now I need insight.

What else could importing a text file with xy data points be useful for? So far I've written import as mask, and import as position keyframe data. Would it be useful to import the data as an actual shape on a shape layer, and if so, how would I do this? Would it be useful to use the data as some other keyframe data besides position?




For anyone looking at this in the future, here it is:

Code: Select all

// After Effects script - import mask from text file
// By Vincent Rubinetti
// 08 -  12 - 2009

var pointSeparator = "\n";
var xySeparator = " ";

var project = app.project;

if (project)
{
	var myComp = app.project.activeItem;
     if (myComp != null && (myComp instanceof CompItem))
	{
         var selectedLayers = myComp.selectedLayers;
         if (selectedLayers.length == 1)
         {         
			alert("Select a text file with data points");
			var myFile = File.openDialog ("Select text file with data points");  
			var fileOK = myFile.open("r","TEXT","????");
			if (fileOK)
			{
				var undoStr = "Import Mask";
				app.beginUndoGroup(undoStr);
				
				var myLayer = selectedLayers[0];
				newMask = myLayer.Masks.addProperty("Mask");
				myMaskShape = newMask.property("Mask Path");
				myShape = myMaskShape.value;
					
				var myText = myFile.read();
				var points = myText.split(pointSeparator);
					
				var xyArray = new Array();
				var vertexArray = new Array();
				
				var xmin, ymin, xmax, ymax;

				for(var i = 0; i < points.length; i++)
				{
					xyArray = points[i].split(xySeparator);
					if (xyArray.length == 2 && !isNaN(parseFloat(xyArray[0])) && !isNaN(parseFloat(xyArray[1])))
					{
						xyArray[0] = parseFloat(xyArray[0]);
						xyArray[1] = parseFloat(xyArray[1]);
						if (i == 0)
						{
							xmin = xyArray[0];
							ymin = xyArray[1];
							xmax = xyArray[0];
							ymax = xyArray[1];
						}
						else
						{
							if (xyArray[0] > xmax)
							{xmax = xyArray[0];}
							if (xyArray[0] < xmin)
							{xmin = xyArray[0];}
							if (xyArray[1] > ymax)
							{ymax = xyArray[1];}
							if (xyArray[1] < ymin)
							{ymin = xyArray[1];}
						}
						vertexArray[i] = xyArray;
					}
					else
					{break;}
				}
				var xoffset = (xmin+xmax)/2;
				var yoffset = (ymin+ymax)/2;
				var scale = 1;
				scale = parseFloat(prompt("Scale factor (1 for original size, 2 for twice original size, etc; -1 to fit comp size):", 1));
				if (scale < 0)
				{
					var xscale = myComp.width/(xmax-xmin);
					var yscale = myComp.height/(ymax-ymin);
					if (xscale < yscale)
					{scale = xscale;}
					else
					{scale = yscale;}
				}
				for (i = 0; i < vertexArray.length; i++)
				{
					var p = vertexArray[i];
					p[0] -= xoffset;
					p[1] -= yoffset;
					p[0] *= scale;
					p[1] *= scale;
				}
				myShape.vertices = vertexArray;
				myShape.closed = false;
				myMaskShape.setValue(myShape);
		
				myFile.close();
				app.endUndoGroup();
			}
			else
			{alert("Error opening text file");}
		}
		else
		{alert("Exactly one layer must be selected");} 
	}
	else 
	{alert("No comp");}
}
else
{alert("No project");}
Post Reply