C# Custom Grasshopper Plugin: Get Brep Boundary Curve & Centroids

Hey guys,

I have just started building my very first Grasshopper component and have no experience C#. To start slowly, I want to replace my visual GH script with a custom C# component, step by step replacing GH components on my canvas until I finally only have one custom component instead of a cluster.
Obviously I stumbled across my first error:

  1. I can’t manage to generate the boundary polyline curves from the breps I input
  2. I do not retrieve the same Centroids like the GH components

Do you guys know why this might be the case?

Best
Max

Here is the Code:

protected override void SolveInstance(IGH_DataAccess DA)
{
List inputBreps = new List();

    if (!DA.GetDataList(0, inputBreps)) return;

    List<PolylineCurve> boundaries = new List<PolylineCurve>();
    List<Point3d> centroids = new List<Point3d>();

    foreach (Brep brep in inputBreps)
    {

        if (brep != null)
        {
            // Retrieve the boundary curves and concatenate them into a single polyline curve
            Curve[] edgeCurves = brep.DuplicateEdgeCurves();
            PolylineCurve boundary = new PolylineCurve();

            boundary.MakeClosed(0.001); // Close the polyline to ensure it's a closed boundary
            boundaries.Add(boundary);

            // Calculate the centroid
            Point3d centroid = brep.GetBoundingBox(true).Center;
            centroids.Add(centroid);
        }
    }

        DA.SetDataList(0, boundaries);
        DA.SetDataList(1, centroids);
    }

GH has access to most of RhinoCommon, right?

This doesn’t get the centroid of the brep. It puts a bounding box around the brep, and then gets the centroid of the box.

What you probably want is:
VolumeMassProperties foo = VolumeMassProperties.Compute(brep);
and then foo.Centroid.X is the center in the x axis, etc.

Do you need to duplicate them? Can you just loop over .Edges for whatever calculation you want?

The story is much bigger, but I thought I should go step by step. The cluster that I have created takes two surfaces (The “Ceiling” of a lower floor & the “Floor” of the upper floor (I am taking about a building)) and than checks where they overlap ->cuts them and stores the surfaces on the respective layers (“Roof”, “Exposed Floor”, “Internal Floor”)
FloorCheck_Visuell.gh (25.9 KB)
I have attached the file.

Technically I also want to repeat this checking for as many floors that I have in the file, currently I just multiplied the component and connected the intersecting surfaces manually.

I jsut didn’t want to overload my request and start with little questions.

Then hopefully you got what you wanted, because I don’t understand exactly what you’re doing (not that I need to).

Connected on and off, just checking in when the access is good.

No worries. The centroid no works exactly like the other GH components. I used the AreaMassProperties as my beeps are planar surfaces all the time. So thank you!
For the polyline curve I am still not sure what to do. I need them as a geometry. What do you mean with Looping?

Best
Max

Looping is also in the workshop videos, I think it’s part 2 or so. Generally it just describes an looping operation that is done until a certain condition is met.

You are not actually connecting the brep.edges (edgeCurves) you copied anywhere in your code to a polyline (I recommend working with polycurves btw). Working with arrays (Curve[ ]) is kinda finicky, I usually just make a new list and add them through list.addrange() to work with them.

I didn’t really know what you were doing with this:

and whether you really needed to create a set of copies, or whether you were looking at curve properties and could just

Foreach

over the existing edges to look at them.

Given your additional explanation, I think I understand that you do want a unified curve around the floor of the building as a separate object.

Yes my current task is super simple, which is why I am confused the writing it in C# makes it so complicated. I have two surfaces, and for each surface I need to retrieve the boundary curve. So I get two closed polylines. For now thats just my task. Obviously I will use that in many different ways, but I want to implement my bug cluster “component by component” to keep track of what I am doing.

Glad to hear you’ve moving on, I think how you’d want to get your previous code working is this:

Note I haven’t tested this code, but it should get you going in the right direction. I included comments where I made changes.

protected override void SolveInstance(IGH_DataAccess DA)
{
    List inputBreps = new List();

    if (!DA.GetDataList(0, inputBreps)) return;

    // Use a Curve List Here
    List<Curve> boundaries = new List<Curve>();
    List<Point3d> centroids = new List<Point3d>();

    foreach (Brep brep in inputBreps)
    {

        if (brep != null)
        {
            // Retrieve the boundary curves and join them into curves
            Curve[] edgeCurves = brep.DuplicateEdgeCurves();
            // Notice that this is another array.
            // If a brep has inner cut outs, it will have multiple loops
            Curve[] joinedEdgeCurves = new Curve.Join(edgeCurves);
            // By definition, edges from a valid brep must be closed, 
            // so it's probably safe to just assume that they're closed here

            boundaries.AddRange(joinedEdgeCurves);

            // Calculate the centroid
            Point3d centroid = brep.GetBoundingBox(true).Center;
            centroids.Add(centroid);
        }
    }

    // If you needed your centroids and boundaries to be in a one-one structure,
    // you'd need to either filter out any inner loop when we're joining edge curves
    // or you'd want to set up a datatree.
    DA.SetDataList(0, boundaries);
    DA.SetDataList(1, centroids);
}

See https://developer.rhino3d.com/api/rhinocommon/rhino.geometry.curve/joincurves for additional info on JoinCurves. Your code wasn’t using the edge curves you’d gotten from the brep for anything, it was instead just initializing a new PolylineCurve without adding any curves to it. @Tuyen_Nguyen got it right when he pointed out that you weren’t joining the curves together.