Sorry. The definition below should be easier to follow.
If the surface is built in Dynamo, Surface.PointAtParameter should mostly provide you with a proper points grid as in the example below.
Also extended the definition to enable multiple projections of varying heights (calculated normal to the surface)
surfaceGrid.dyn (14.2 KB)
//Sample Surface
n1 = NurbsCurve.ByPoints(Point.ByCoordinates([0,10,20,50],[55,60,52,48],[5,12,-3,6]));
n2 = NurbsCurve.ByPoints(Point.ByCoordinates([-5,15,40,50],[5,10,2,8],[15,10,-3,0]));
sr = Surface.ByLoft([n1,n2]);
//[[u index, v index, elevation]]
sr =[[5,7,-5],[9,4,-25],[2,8,-5]];
//Point Translation
s3 = trnz (sr,10,10,uvw);
//Surface paneling
t1 = List.Sublists(s3<1>,0..1,1);
t2 = List.DropItems(t1<1>,-1);
u1 = List.DropItems(s3,-1);
u2 = List.DropItems(u1<1>,-1);
u3 = List.DropItems(t2,1);
u4 = List.AddItemToFront(u2<1><2>,u3<1><2>);
v1 = List.DropItems(s3,1);
v2 = List.DropItems(v1<1>,1);
v3 = List.DropItems(t2,-1);
v4 = List.AddItemToFront(v2<1><2>,v3<1><2>);
w1 = Surface.ByPerimeterPoints([u4,v4]);
//Function: Surface Grid - Multiple Point Translation
//sr : Surface
//uc : Surface divisions (U)
//vc : Surface divisions (V)
//u in uvw : Index of point to be translated (U)
//v in uvw : Index of point to be translated (V)
//w in uvw : Normal distance to be translated
def trnz (sr,u,v,uvw:var[]..[])
{
p = Surface.PointAtParameter(sr<1>,
(0..1..#u)<2>,(0..1..#v)<3>);
a = [Imperative]
{
ct = List.Count(p[0]);
pt = p;
for (i in uvw)
{
q1 = ((i[0]-1)*ct)+i[1];
r1 = List.Flatten(pt,-1);
r2 = List.GetItemAtIndex(r1,q1);
r3 = sr.NormalAtPoint(r2);
r4 = r2.Translate(r3,i[2]);
r5 = List.Flatten(pt,-1);
s1 = List.RemoveItemAtIndex(r5,q1);
s2 = List.Insert(s1,r4,q1);
pt = List.Chop(s2,ct);
}
return = pt;
}
return = a;
};