Thank you, this indeed turns rotobezier ON.
However rotobezier gives poor result unless one inputs some already good enough values for the tangents.
In case someone faces the same problem in the future, I post below a short script based on some doc on Bezier interpolation found there: https://people.sc.fsu.edu/~jburkardt/html/bezier_interpolation.html. (sorry, can’t figure out how the link tool is working !)
This script assumes that what AE calls Bezier interpolation is really a Bezier interpolation (there are many other types of interpolations similar to Bézier). But it works very well so it should be the case, and the algorythm will vectorize properly most curves (smooth enough, curves with sharp variation like sin with very high frenquency require more vertices).
It creates 3 times more points than the number of vertices of the path (2/3 of these points are here to make sure that the path will walk through them). The funny numbers have their explanation in the doc linked above.
Note: this is just the bit of code needed to get the Vertex and Tangents arrays. The script won’t run as it is. To run it, one has to complete the input and add lines like:
var myLayer = app.project.activeItem.layer(1);
var myMask = myLayer.Masks.addProperty(“ADBE Mask Atom”);
myProperty = myMask.property(“ADBE Mask Shape”);
myPath = myProperty.value;
myPath.vertices = V_Array; myPath.inTangents = IT_Array; myPath.outTangents = OT_Array;
myPath.closed = CloseBoolean;
myProperty.setValue(myPath);
myMask.rotoBezier = rotoBezierBoolean;
(etc.)
function CurvePoint(u) { // the curve function
var x; var y;
x = ; // input function there
y = ; // input function there
return([x,y]);
}
function VectorNorm(X){ // optionnal, for more smoothing
return(Math.sqrt(X[0]*X[0]+X[1]*X[1]))
}
function Average(X,weightX,Y,weightY){ // optionnal, for more smoothing
var pX=weightX /(weightX+weightY);
var pY=weightY /(weightX+weightY);
return ( pX * X + pY * Y );
}
var Nvertex =....; // the number of vertex you want in your path
var u_min = ... ; // the min value for the curve parameter
var u_max = ... ; // the max value for the curve parameter
// some other parameters for the curve
var CloseBoolean = false; // true for a closed path, false for open
var SmoothBoolean = false;
var rotoBezierBoolean = false;
//
var P_Array=new Array();
var V_Array=new Array(); // the array of vertices
var iT_Array=new Array(); // the array of inTangents
var oT_Array=new Array(); // the array of outTangents
var newP=new Array();
for (i=0; i <= 3*Nvertex; i++) { // creates the array of ALL POINTS (the actual vertices + intermediary hidden control points)
u = u_min + i * (u_max-u_min)/(3*(Nvertex)); // for uniform parameter set. This should be adapted to the need.
P_Array[i] = CurvePoint(u);
}
for (i=0; i < Nvertex ; i++) { // builds the Vertex, inTangents and OutTangents arrays
// builds the Vertex Array
V_Array[i] = P_Array[3*i];
// builds the IN Tangents Array
if (i < 0) iT_Array[i] = ( 2*P_Array[3*i-3] - 9* P_Array[3*i-2] + 18*P_Array[3*i-1] - 11*P_Array[3*i] ) /6;
else{
if (CloseBoolean == false) iT_Array[0] = [0,0];
else iT_Array[0] = (2*P_Array[3*(Nvertex)-3] - 9* P_Array[3*(Nvertex)-2] + 18*P_Array[3*(Nvertex)-1] - 11*P_Array[0])/6;
}
// builds the OUT Tangents Array
if (i < Nvertex-1) oT_Array[i] = (-11* P_Array[3*i] + 18*P_Array[3*i+1] - 9*P_Array[3*i+2] + 2*P_Array[3*i+3])/6;
else{
if (CloseBoolean == false) oT_Array[Nvertex-1]=[0,0];
else oT_Array[Nvertex-1] = ( -11* P_Array[3*(Nvertex-1)] + 18*P_Array[3*(Nvertex-1)+1] - 9*P_Array[3*(Nvertex-1)+2] + 2*P_Array[0] ) /6;
}
}
//some optionnal smoothing
if (SmoothBoolean == true){
Temp= new Array();
var o_norm;
var i_norm;
for (i=0; i < Nvertex ; i++) {
o_norm=VectorNorm(oT_Array[i]);
i_norm=VectorNorm(iT_Array[i]);
if (o_norm+i_norm > 0){
Temp= Average(oT_Array[i],o_norm,-iT_Array[i],i_norm)
oT_Array[i]=(1+(o_norm-i_norm)/(o_norm+i_norm)) * Temp;
iT_Array[i]= -(1-(o_norm-i_norm)/(o_norm+i_norm)) * Temp;
}
}
}