Why Populate Geometry so slow?

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;
  }
4 Likes