Planarize Quad MeshFaces in C#

Hi evereyone,

I am trying to planarize some QuadMeshFaces within a loop.
I found this thread here
and started to write what @Dani_Abalde proposed:

ErrorGlobal as new double
Count as new integer
A tree that stores, for each vertex, a list of vectors.
Per face:
Plane from point cloud.
For each point of the face:
Projecting the point to the plane and the distance is the factor error. You need to know if the value is positive or negative.
Add the vector (vertex - Project vertex) to the tree. the branch is the index of the vertice.
Per vertex:
Making the average of the vectors in the respective branch in the tree.
Move the vertex of the mesh with the average vector.
errorglobal += vector length
errorglobal / = vertices.count 'Average error or another way to see.
count + = 1
Loop while errorglobal> 0.01 or count <1000

My attempt so far:

private void RunScript(Mesh msh, ref object vertices, ref object planes, ref object distances, ref object averageVec, ref object moveVector, ref object Mesh, ref object cnt)
    int count = 0;
    for (int co = 0; count < 20 ; co++)

      var verticesTree = new DataTree<Point3d>();
      var distancesTree = new DataTree<double>();
      var moveVectorTree = new DataTree<Vector3d>();
      var planesTree = new DataTree<Plane>();
      var averageVectorTree = new DataTree<Vector3d>();

      //Per face_____________________________________________

      for (int i = 0; i < msh.Faces.Count; i++)
        //getting the vertices and putting them in a tree
        Point3f a; Point3f b; Point3f c;  Point3f d;
        msh.Faces.GetFaceVertices(i, out a, out b, out c, out d);
        verticesTree.Add(a, new GH_Path(i));
        verticesTree.Add(b, new GH_Path(i));
        verticesTree.Add(c, new GH_Path(i));
        verticesTree.Add(d, new GH_Path(i));

      for (int i = 0; i < verticesTree.BranchCount; i++)
        // projecting vertices to plane to get vectors and distances
        Plane plane;
        PlaneFitResult pFit = Plane.FitPlaneToPoints(verticesTree.Branch(i), out plane);
        planesTree.Add(plane, new GH_Path(i));

        for (int j = 0; j < verticesTree.Branch(i).Count; j++)
          Point3d copy = verticesTree.Branch(i)[j];

          Transform xForm = Transform.PlanarProjection(plane);

          double dis = copy.DistanceTo(verticesTree.Branch(i)[j]);
          distancesTree.Add(dis, new GH_Path(i));

          Vector3d move = (verticesTree.Branch(i)[j] - copy);
          moveVectorTree.Add(move, new GH_Path(i));

      //per vertex___________________________________________
      for (int i = 0; i < verticesTree.BranchCount; i++)
        for (int j = 0; j < verticesTree.Branch(i).Count; j++)
          Vector3d averageVector = average(moveVectorTree.Branch(i));
          averageVectorTree.Add(averageVector, new GH_Path(i));

          Transform xForm = Transform.Translation(averageVector);

      count += 1;

      vertices = verticesTree;
      planes = planesTree;
      distances = distancesTree;
      averageVec = averageVectorTree;
      moveVector = moveVectorTree;
      cnt = count;

  // <Custom additional code> 

  //_________Making an average Vector
  public Vector3d average (List<Vector3d> vectors)
    Vector3d avg = new Vector3d(0, 0, 0);

    for (int i = 0; i < vectors.Count; i++)
      avg += vectors[i];

    return avg / vectors.Count;

My issues:

  • the average vector that I get is always (0,0,0)
  • do I have to build the mesh afterwards or can I just move the vertices of the existing one

I hope it´s makes a little bit of sense and is not completly chaotic and far away from a working code.

Thanks in advace ! (6.9 KB)

That’s a classic task for a Physics Engine like K2 I’m afraid.