Populate geometry is not so simple because it looks at distance between points. There are some discussion on that on old Grasshopper forum
https://www.grasshopper3d.com/m/discussion?id=2985220%3ATopic%3A929095
You could go a lot faster with mesh and populating without looking at distance.
Here a script for mesh.
100 000 points in 1 s
I think I publiate it on a dendro topics.
fast mesh populate LEGACY.gh (32.6 KB)
/// <summary>
/// Fast populate on mesh using triangle populate, but gives more density on edges
///Laurent Delrieu 18/8/2019
/// </summary>
/// <param name="mesh"></param>
/// <param name="nPoints">number of point wanted</param>
/// <param name="seed">seed parameter for the random generator</param>
/// <returns>List of points</returns>
List<Point3d> MeshPopulate(Mesh mesh, int nPoints, int seed)
{
Mesh m = mesh.DuplicateMesh();
m.Faces.ConvertQuadsToTriangles();
Random rnd = new Random(seed);
// List<double> surfaceFaces = new List<double>();
List<double> sumSurfaceFaces = new List<double>();
List<Point3d> points = new List<Point3d>();
double totalArea = 0.0;
for (int i = 0; i < m.Faces.Count; i++)
{
double area = MeshFaceArea(i, m);
totalArea += area;
sumSurfaceFaces.Add(totalArea);
}
for (int i = 0; i < m.Faces.Count; i++)
{
double pointsOnAllFacesBefore = 0.0;
if (i > 0)
{
pointsOnAllFacesBefore = (double) nPoints * sumSurfaceFaces[i - 1] / totalArea;
}
double pointsOnAllFaces = (double) nPoints * sumSurfaceFaces[i] / totalArea;
int nPointOnFace = (int) Math.Max((int) pointsOnAllFaces - (int) pointsOnAllFacesBefore, 0);
points.AddRange(PointsOnMeshFace(i, m, nPointOnFace, rnd));
}
return points;
}
/// <summary>
/// Populate a TRIANGULAR FACE
/// </summary>
/// <param name="meshfaceindex"></param>
/// <param name="m"></param>
/// <param name="n"></param>
/// <param name="rnd"></param>
/// <returns></returns>
List<Point3d> PointsOnMeshFace(int meshfaceindex, Mesh m, int n, Random rnd)
{
List<Point3d> points = new List<Point3d>();
//get points into a nice, concise format
Point3d[] pts = new Point3d[4];
pts[0] = m.Vertices[m.Faces[meshfaceindex].A];
pts[1] = m.Vertices[m.Faces[meshfaceindex].B];
pts[2] = m.Vertices[m.Faces[meshfaceindex].C];
Vector3d v1 = m.Vertices[m.Faces[meshfaceindex].C] - m.Vertices[m.Faces[meshfaceindex].A];
Vector3d v2 = m.Vertices[m.Faces[meshfaceindex].B] - m.Vertices[m.Faces[meshfaceindex].A];
for (int i = 0; i < n; i++)
{
double b1 = rnd.NextDouble();
double b2 = rnd.NextDouble();
if ((b2 + b1) > 1.0)
{
b2 = 1.0 - b2;
b1 = 1.0 - b1;
}
points.Add((Point3d) m.Vertices[m.Faces[meshfaceindex].A] + v1 * b1 + v2 * b2);
}
return points;
}
//Algorithm
//http://james-ramsden.com/area-of-a-mesh-face-in-c-in-grasshopper/
double MeshFaceArea(int meshfaceindex, Mesh m)
{
//get points into a nice, concise format
Point3d[] pts = new Point3d[4];
pts[0] = m.Vertices[m.Faces[meshfaceindex].A];
pts[1] = m.Vertices[m.Faces[meshfaceindex].B];
pts[2] = m.Vertices[m.Faces[meshfaceindex].C];
if(m.Faces[meshfaceindex].IsQuad) pts[3] = m.Vertices[m.Faces[meshfaceindex].D];
//calculate areas of triangles
double a = pts[0].DistanceTo(pts[1]);
double b = pts[1].DistanceTo(pts[2]);
double c = pts[2].DistanceTo(pts[0]);
double p = 0.5 * (a + b + c);
//Added 18/08/2019 Math.Max to suppress less than 0 value and NaN on 0 area mesh
double area1 = Math.Sqrt(Math.Max(p * (p - a) * (p - b) * (p - c), 0.0));
//if quad, calc area of second triangle
double area2 = 0;
if(m.Faces[meshfaceindex].IsQuad)
{
a = pts[0].DistanceTo(pts[2]);
b = pts[2].DistanceTo(pts[3]);
c = pts[3].DistanceTo(pts[0]);
p = 0.5 * (a + b + c);
//Added 18/08/2019 Math.Max to suppress less than 0 value and NaN on 0 area mesh
area2 = Math.Sqrt(Math.Max(p * (p - a) * (p - b) * (p - c), 0.0));
}
return area1 + area2;
}
