Seeking Help with Custom MeshShadow Component in RhinoCommon (C#)

Hi everyone,

I’m working on a custom C# component in Grasshopper, reproducing the existing MeshShadow component before further development. The goal of my component is to project a mesh onto a plane and then trace the shadow outline, returning it as a polyline.

Here’s a brief explanation of what the script does:

  1. It takes a mesh and a plane as input.
  2. It projects the mesh onto the plane to create a shadow.
  3. It computes the concave hull (also known as an alpha shape) around the vertices of the projected mesh to generate an outline.
  4. It returns the polyline outlining the shape of the shadow.

I’m currently facing an issue with the concave hull part of the script. The resulting polyline has self-intersecting lines, which I believe should not occur in a proper concave hull. I am not sure if there’s an issue with the script’s logic or if I’m missing something in the implementation.

I’d appreciate any help or insights you could provide to help me understand what’s going wrong and how I can fix it, or if there’s a better approach to achieve the desired functionality of the MeshShadow component. Maybe someone even knows how the mesh shadow component arrives at its polyline.

here’s the concavehull script i came up with, if anyone want’s to dig through.

// Compute the Delaunay mesh
public Polyline CreateConcaveHull(List<Point3d> points, double alpha)
  {
    // Create a Node2List from the points
    Node2List nodes = new Node2List();
    foreach (Point3d point in points)
    {
      nodes.Append(new Node2(point.X, point.Y));
    }

    // Initialize an empty list of Delaunay faces
    List<Grasshopper.Kernel.Geometry.Delaunay.Face> faces = new List<Grasshopper.Kernel.Geometry.Delaunay.Face>();

    // Compute the Delaunay mesh
    Mesh delaunayMesh = Grasshopper.Kernel.Geometry.Delaunay.Solver.Solve_Mesh(nodes, 0.0, ref faces);

    List<Line> alphaShapeEdges = new List<Line>();

    for (int i = 0; i < delaunayMesh.TopologyEdges.Count; i++)
    {
      Line edge = delaunayMesh.TopologyEdges.EdgeLine(i);
      if (edge.Length < alpha)
      {
        alphaShapeEdges.Add(edge);
      }
    }

    List<Curve> curveSegments = new List<Curve>();
    foreach (Line edge in alphaShapeEdges)
    {
      curveSegments.Add(new LineCurve(edge));
    }


    // Join the curve segments
    List<Curve> joinedCurves = Curve.JoinCurves(curveSegments).ToList();

    // Filter out the PolylineCurves from the joined curves
    List<PolylineCurve> polylines = new List<PolylineCurve>();
    foreach (Curve curve in joinedCurves)
    {
      PolylineCurve polyline = curve as PolylineCurve;
      if (polyline != null)
      {
        polylines.Add(polyline);
      }
    }

    PolylineCurve longestPolyline = null;
    double maxLength = 0.0;
    foreach (PolylineCurve polyline in polylines)
    {
      double length = polyline.GetLength();
      if (length > maxLength)
      {
        maxLength = length;
        longestPolyline = polyline;
      }
    }

    Polyline result;
    longestPolyline.TryGetPolyline(out result);
    return result;
  }

Thank you in advance for your assistance!