I want to do a laplacian smoothing on a surface moving the control points towards the average of its neighbors, but something I’m doing wrong because the following failures arise:
How should I update the edges?
How do I keep the seams fixed when it’s closed?
private void RunScript(Brep Brp, double S, int I, bool N, ref object A)
{
if(Brp == null || !Brp.IsValid)return;
if(I <= 0 || S <= 0){ A = Brp; return;}
S = Math.Min(1.0, S);
double S1 = 1.0 - S;
BrepFace bf = Brp.Faces[0];
NurbsSurface nurbs = bf.ToNurbsSurface();
Brep newBrep = Brp.DuplicateBrep();
int UC = nurbs.Points.CountU;
int VC = nurbs.Points.CountV;
bool cu = nurbs.IsClosed(0);
bool cv = nurbs.IsClosed(1);
while(I-- > 0){
NurbsSurface newSrf = new NurbsSurface(nurbs);
for(int i = 0; i < UC ; i++){
for(int j = 0; j < VC; j++){
if(N){
PointFaceRelation pfr = bf.IsPointOnFace(i, j);
if(pfr == PointFaceRelation.Boundary || pfr == PointFaceRelation.Exterior )continue;
}
Rhino.Geometry.ControlPoint cp = nurbs.Points.GetControlPoint(i, j);
Point3d avePt = new Point3d();
double aveW = 0;
int cnt = 0;
int id = -1;
if(GetID(i - 1, cu, UC, out id)){
Rhino.Geometry.ControlPoint cpa = nurbs.Points.GetControlPoint(id, j);
avePt += cpa.Location;
aveW += cpa.Weight;
cnt++;
}
if(GetID(i + 1, cu, UC, out id)){
Rhino.Geometry.ControlPoint cpa = nurbs.Points.GetControlPoint(id, j);
avePt += cpa.Location;
aveW += cpa.Weight;
cnt++;
}
if(GetID(j - 1, cv, VC, out id)){
Rhino.Geometry.ControlPoint cpa = nurbs.Points.GetControlPoint(i, id);
avePt += cpa.Location;
aveW += cpa.Weight;
cnt++;
}
if(GetID(j + 1, cv, VC, out id)){
Rhino.Geometry.ControlPoint cpa = nurbs.Points.GetControlPoint(i, id);
avePt += cpa.Location;
aveW += cpa.Weight;
cnt++;
}
avePt /= cnt;
aveW /= cnt;
newSrf.Points.SetControlPoint(i, j, new ControlPoint(
avePt * S + cp.Location * S1,
aveW * S + cp.Weight * S1));
}
}
nurbs = newSrf;
}
newBrep.Faces[0].ChangeSurface(newBrep.AddSurface(nurbs));
newBrep.Compact();
string log;
if(!newBrep.IsValidWithLog(out log)) Print(log);
A = newBrep;
}
public static bool GetID(int i, bool cu, int U, out int ri){
ri = -1;
if(!cu && (i < 0 || i >= U))return false;
ri = (i + U) % U;
return true;
}
SurfaceSmooth.gh (33.7 KB)