Voroni cell pattern on 3d model surface into ExoWireframe for 3d printing

Hello everyone,

I need help with with Grasshopper! I’m trying get a voroni cell pattern on a 3d model surface into ExoWireframe for cell thickening and 3d printing. I’ve attached both my rhino file and grasshopper file, there is also a screenshot showing my rhino model and grasshopper design.

I’ve successfully managed to create a voroni cell pattern on my model using the voroni 3d component with points populated from my 3d model as input. I’ve used the boundary of my 3d model as input into the voroni 3d component so that it treated my entire 3d model as reference for voroni 3d pattern creation. I used a brep I brep intersection between my 3d model and the brep cell output from the voroni 3d component. That produces the voroni 3d pattern I want on the 3d model surface. I would like to take the output curves from this intersection and thicken them using the ExoWireframe component so that I can ultimately 3d print this.

The problem is that the output of the intersection are polyline curves and the input for ExoWireframe needs to be lines. I’ve trying exploding the output curves from the brep intersection component, I’ve tried removing duplicate lines in Rhino and Grasshopper, I’ve tried converting the curves in Rhino to lines using the Convert command, I’ve used multipipe successfully but there are too many overlaps in the cells and I’d prefer the control of ExoWireframe. I’ve tried using Topologizer to clean up and organize the input in preparation for ExoWirefram - I’ve tried a lot of different tools in intersection, Lunchbox, Curves and within Rhino to convert them so they can be accepted into ExoWireframe but nothing has worked. I’d appreciate any insights you might have into this!

13c play.gh (5.8 KB)
013c play.3dm (5.6 MB)

Have you tried Multipipe?

Here’s a way to clean up your input for MultiPipe.
If you get rid of duplicate faces first before intersecting, it is easier than trying to remove duplicate curves later.
It can also help to use a remesh to distribute the points better before the Voronoi step, to avoid very short edges.

voronoi_clean.gh (11.4 KB)

The alternative is to go with an implicit isosurface approach for the pipes, and sometimes with very messy/overlapping curves that can’t be cleaned up, that will be the only option, but that gives a dense mesh, and here with a little clean up it is possible to get an actual pipe surface.

Thanks Daniel - your result looks a lot better than mine. It sure helps when you know what you’re doing.

Daniel, thank you so much for presenting this very elegant solution to this problem, beautifully done! I’ve learned so much from your post and examining your grasshopper design. I did not realize how important it is to prepare 3d geometry for input into voroni 3d component by using triangulate mesh and demesh to define mesh points while using volume and scale components to define the boundary limit for the voroni 3d cells. I have a few questions about your method below, I’d kindly appreciate if you would review them and help me understand…

I see why you are deconstructing the brep output from voroni 3d, I think I see why you are outputting the deconstructed faces into the area component : to find the centroids of the voroni 3d faces. What I don’t understand here is why you are using an area component for a point cloud that is 3d from DeBrep. Is that why you are using the Flatten attribute in the output from DeBrep component ? so that the point data is flattened for input into the area component ?

I see that the cull duplicates component removes any duplicate points. I don’t understand what closest point component is doing, why is this necessary ? Why is the output from closest point component use with the flattened Brep output from Deconstruct Brep component ?

I kind of understand this organizing and processing of the original 3d model input that you’ve achieved in each of these steps (apart from the above) where it’s ultimately intersected against the original 3d model to produce that lovely curve output from Brep Brep intersection. I noticed that when I bake the rebuild curve component, I get a curve network in Rhino in which each of the curves have 10 points. Is that a default setting of using the rebuild curve that it produces curves with 10 points ? Lastly, why is the output of rebuild curve component flattened before going into the final multipipe component ?

Thank you so much for your patience and understanding here, sorry about all of the questions, I’m quite new at this and I’m very excited to learn, I love this now that you have showed me the possibilities !

if you bake the Cells output of the 3D Voronoi component, you will see that you get perfect closed solid cells like these, which perfectly split the box volume:

this also means that for each pair of adjacent cells AB you have each shared surface S from the deconstruction of cell A, and another identical copy of S from the deconstruction of cell B


so the green group in the following image has the role of “make in such a way when we explode the single cells into a list of surfaces, we don’t end up with double surfaces anywhere anymore”

and the way it “filters” the data -to understand if a given surface has duplicated- is by checking the area centroid point of each surface (two identical overlapping surfaces will have two identical area centroid points)

this is evident here, where the Area Centroid points output shows 585 points, and after culling the duplicated ones you end up with just 342 of them

because the definition has culled points, and we are interested in surfaces, the last two components Closest Point and List Item are used to retrieve for each remaining unique point its corresponding initial surface

Grasshopper does its best to preserve the data structure through the various components
for instance: Voronoi 3D outputs 57 different cells, and if you DeBrep them you will get 57 separate data-branches, each branch containing all the surfaces that form that particular cell

in this particular case you just want to understand which surfaces are duplicated among neighbor cells, and you are not interested in keeping the data structure that identifies the single cells, so it’s just easy to make a single basket with all the surfaces (Flatten makes a single basket of everything)

you can input a slider or a text panel indicating how many points you want the Curve to be rebuilt with


the reason is the very same of the Flattened applied to DeconstructBrep earlier:
the output of the Brep | Brep intersection component generates one new data-branch for each surface that is present (note that data branches are generated also if a given surface does not produce an intersection curve with your original shape, so you get some branches with 0 items inside)

that very same data structure is preserved through the Rebuild Curve component, but if you plug it into the MultiPipe component without Flattening it first you’ll notice each curve is piped by itself, and is not connected with any other: belonging to different branches means they are treated independently, so you flatten the data tree in such a way they all belong to the same data branch (and are treated as a whole)

at this link you can download the Grasshopper Primer: if you like this stuff this is the first thing I’d study :heart_eyes: About | The Grasshopper Primer (EN)


Hi @Arthur_Paul_O_Keeffe

No problem. Some parts of that definition probably do need a bit of explanation.
I think @inno’s reply already covers most of it - thanks!.

As for the reason I included the remeshing step near the start-
Grasshopper’s populate geometry doesn’t place points completely randomly, it distributes them a bit to stop any of them being too close together. This helps prevent short edges in the triangulation of these points.
The Voronoi is the circumcircular dual of the Delaunay triangulation, meaning for each pair of adjacent triangles the corresponding Voronoi edge is formed by connecting the centers of the circles through each of their 3 points. Sometimes this can result in very short edges in the Voronoi like the red edge here, even if none of the original points in the point distribution are close together.

These tiny edges can be messy to deal with later for piping.

TriRemesh actually does some optimisation so that not just the edge lengths of the triangulation, but also those of the dual are reasonably even without any very short ones.