
Grow Mask Generator
01 | Growth solver for surface mask
The first step is to make an attribute that can guide the subsequent effects. The range of this attribute is 0-1, and it appears as a state of spreading on the surface of the object. Therefore, a custom solver was used in the first step.
In this solver, Input1 is the base Geo and the some initialized attributes. Input2 is the start point of the spreading mask. The start point and the base Geo is not required to be in a same geometry.
The most important part of the solver is the red wrangles, the right one will use point cloud use the start points to sample the base geometry in a customize radius and find weather these nearby points are in the “in” group. The left one will receive these information from the right one. Then, if the points near these strart points do not belong to the "in group", they will have a certain chance to enter this group. At the same time, in order to ensure that they will not be missed, this point will be directly put into the "in group" if they are still not selected for 4 times.
//Info Node
float radius = chf("radius");
int maxpoints = chi("maxpoints");
int pnum = 0;
int in = 2;
i[]@in;
i[]@num;
//for the input points from input0, search their neighbour points and get their ptnum
int handle = pcopen(1,"P",@P,radius,maxpoints);
while(pciterate(handle))
{
pcimport(handle,"point.number",pnum);
pcimport(handle,"in",in);
append(@in,in);
append(@num,pnum);
}
@point_num = @numpt;
int number = point("op:../info","point_num",0);
int ppnumber = point(1,"ppnum",0);
i[]@point;
i[]@ifin;
//extrude selected point number
for(int i = 0; i < number; i++)
{
i[]@temp = point("op:../info","num",i);
i[]@temp2 = point("op:../info","in",i);
int k_lim = len(@temp);
for(int k = 0; k < k_lim; k++)
{
append(@point,@temp[k]);
append(@ifin,@temp2[k]);
i@length += 1;
}
}
//for each selected point they have chf("in_chance") chance to be choosen to process group
for(int m = 0; m < @length; m++)
{
float judge = random(@point[m]*@Frame);
float temp_process = point(0,"group_process",@point[m]);
if(judge < chf("in_chance") && @ifin[m] == 0 && temp_process ==0)
{
setpointattrib(0,"group_process",@point[m],1,"set");
setpointattrib(0,"in_Frame",@point[m],@Frame,"set");
setpointattrib(0,"in",@point[m],1,"set");
setpointgroup(0,"process",@point[m],1,"set");
}
//if a point are not choosen for chi("skip_tolerence") times,then choose it
if(judge >= chf("in_chance") && @ifin[m] == 0 && temp_process ==0)
{
int count_temp = point(0,"count",@point[m])+1;
setpointattrib(0,"count",@point[m],count_temp,"set");
}
if(point(0,"count",@point[m])>chi("skip_tolerence") && @ifin[m] == 0 && temp_process ==0)
{
setpointattrib(0,"group_process",@point[m],1,"set");
setpointattrib(0,"in_Frame",@point[m],@Frame,"set");
setpointattrib(0,"in",@point[m],1,"set");
setpointgroup(0,"process",@point[m],1,"set");
}
}
After passing through the solver, each point will be given an "in" attribute of 0 or 1, and therefore a mask with sharp edges will be obtained. In order to make the existing mask to obtain a smooth edge, point wrangle is used in this project to post-process the output ”in” attribute
This node compares the number of frames at which each point is selected into the "in group" with the current frame number, and specifies that after a point is selected, the in attribute will not directly change from 0 to 1, and the in_blur attribute will be set Slowly change from floating 0 to floating 1 within time. So that the mask edge will become pretty soft.