Circle Packing Perforations

I’ve read just about every circle packing post on here and the original Grasshopper forum. So many ways to skin that cat. The method I’ve latched onto uses a C# script from god knows where/when. It’s just a little buggy compared to newer methods and I’m not sure how to update it or find a post-Kangaroo 2 alternative.

This is my simple perforation definition.

circle pack (21.4 KB)

This Circle Packing definition below by @DanielPiker isn’t as tight around the boundaries as I’d like, it’s also built around Sphere Collider so I don’t know how to adapt it to multiple size circles with offset spacing, like I did with the perforation script but it works so smoothly, when I push boundary the circles just overlap a little instead of popping out like the one above. It’s far more forgiving and you can add pull.

I’d love to find a middle ground, or at the very least understand what that C# script in my perforation def is doing and how to modify it.

What are the properties of the circle packing you want?
You mention different radii - do you want to set a small number of specific radii? or a general range?
Do you care about the exact number of circles?
Are you looking for something topologically regular, or more random looking?

The script in the first definition above is a custom goal for collision between spheres of any radius and a curve. It can be used to get the circles tangent to the boundary, instead of their centres ending up on the boundary. As you found though, they can sometimes end up off the surface and outside the boundary altogether. Adding an OnMesh goal can be one way to avoid this.
Here’s that definition with a few small modifications: (15.2 KB)

For some examples of more regular distributions (mesh based instead of collision based), have a look at this recent thread:


R6 only? Or is there a way to make it work in R5? I have Kangaroo 2 in GH and tried to resolve the path but had no luck.


I think this one should work in R5. The assembly location would then be something like

Thank you, I got very close but missed that folder. A screen shot of the GH canvas would help me fix the Multiplication problem? (after Random?)



Thanks. Took me awhile to realize that there is a second Multiplication component in the model, but the value of its ‘B’ input isn’t visible? So I improvised with a slider: (25.2 KB)

@Joseph_Oster Just checked Daniel’s file, the B input you are missing is 2.

Thanks for that, oh patron saint of circle packing! It was the collisions I was really struggling with, how they would break the boundary under pressure. Which you solved.

I’ve been using this for a variety of projects, as an aesthetically pleasing way to remove some weight without loosing structure. I’ve got the adding and removing circles part down, it was just loosing circles that kills me, I’ll often include in a number of fixed radii within the randos for installation points, hidden plug welds or spacers. Just defeats the purpose when they would pop out and I’d have to re-arrange them in manually. Using the grab tool would usually break the boundary as well.

Is the need to constantly reset an unfortunate necessity for collision based packing? Like how changing the offset value or removing circles without resetting after muddles it up with duplicates?


@Joseph_Oster Sorry about that, figures my definition would have eccentricities. I’m still in the “Frankenstein shit together and see if it works” stage of learning Grasshopper.

Another aspect I’m working on is a Circle-to-Boundary offset, for all around equal spacing. The challenge there has been offset direction, when I’m setting up parts to cut in CAM software, it recognizes closed curves as parts and closed curves nested within as holes. So there is no confusion when I ask it to cut inside or outside the line or add an offset.

I like the Boundary component because it seems to understand that, figure there’s got to be some way to use that to offset flat surface edges toward or away each-other. (11.3 KB)

Another quite different approach is to remesh, then optimise for a true compact circle packing.


hello guys.
thanks for sharing this great work!
i am trying to implement a min/max radius element to perforate but am failing so far…
any input?

You must provide more information in order to get help (49.8 KB) sure, sorry!

basically what i am trying to achieve, with a limited knowledge of grasshopper, is to get a perforation pattern that would make this wing (see attached) as light as possible (i.e. maximising the area of the perforated surface).


  • while doing so i must also keep control of the radius of the perforations and the gap/offset between the circles and the boundary (manufacturing issues)
  • i must keep the perforations on a grid (so the weight is evenly distributed along the span (i.e. X axis) (and not necessarily along the Y axis))

Here is where I got to so far, I was intending to use galapagos as a solver.
In other words, as I see it, I need to pack circles on a grid, in the boundary of my 2D shape.

It is probably a bit naive sorry (32.6 KB)

Resurrecting this old topic!

Daniel, I’m finally having fun with the remesh but running into trouble with different curves. Trying to get the same boundary adherence as this, but with the square shape below.

I couldn’t get it to work at all with SimpleRemesh, when I switched to a regular Remesh, it works but hangs out of the boundary.

Would appreciate any pointers

cp remesh (25.3 KB)