Hi evereyone,
I am trying to planarize some QuadMeshFaces within a loop.
I found this thread here
: https://www.grasshopper3d.com/forum/topics/vb-planar-mesh?page=1&commentId=2985220%3AComment%3A1434649&x=1#2985220Comment1434649
and started to write what @Dani_Abalde proposed:
ErrorGlobal as new double
Count as new integer
Do
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.
End
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
End
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);
copy.Transform(xForm);
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);
verticesTree.Branch(i)[j].Transform(xForm);
}
}
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 !
20191126_PQM.gh (6.9 KB)