How to 3D Print Complex, Semi-Random Lattice Structures, Easily
We show how to use Grasshopper and Rhino to automatically generate complex Voronoi structures ready for 3D printing.
Step 1: A Warning
At the very start, I want to let you know: this is going to be one of the hardest, most esoteric 3D printing tutorials I've written yet.
You'll have to download a few random pieces of software, do visual coding of computer algorithms, and there's even some Maths.
So I'm marking this tutorial:
You've been warned.
Things are going to get weird from here on out.
Step 2: Why are we doing this?
Objects reflect how they were built.
If you picked up an object and the outside looked like this, you would immediately know where it came from:
And if you picked up something that looked like this:
So recently I was at a trade show and I saw a LOT of things that looked like this in a competitor's booth:
And if you've been in the industry a while, you know that's sort of the 3D printing 'look', right?
Semi-random, sort-of-repeating structures that could NEVER be machined, inside a larger controlled shape, is how we let you know something is 3D printed.
As an industry, it's sort of become our 'aesthetic':
Let's take those two pink bunnies as an example. I realized I could figure out how to make the faceted one on the right, by just reducing the poly count in my design software:
But I realized I had NO IDEA how to create that complex bunny on the left!
Or that crazy white gyroid shape above!
I work in 3D printing but had no idea how to automatically generate the complex '3D Printed look' that most of the industry uses as our standard! That's like a leather worker having no idea how to make a cow.
So that's why I started this journey: to learn how to take any CAD shape I can design and fill it with complex '3D Print looking' semi-repeating structures, and then print it.
To do that, we're going to have to download two new pieces of software.
Step 3: Downloading Rhino and Grasshopper
There are obviously many ways to get this effect (since a lot of people do it) but I'm going to show you the one most accessible to me. (If you have better ideas, don't be afraid to mention them in the comments!)
First, get a copy of the 3D CAD package Rhino.
(I'm using Rhino version 5 because that's the license my company has, but Rhino version 6 is the most recent.)
If you don't want to buy a $995 license of Rhino just for this tutorial, you can download an official
You should be able to go through this tutorial in MUCH less than 90 days, and hey, then you'll know a little Rhino for your next job!
But Rhino is just a CAD system. Unless we want to sketch and cut all those complex shapes out of our model BY HAND, we'll need a flexible, editable program to automatically do the grunt work for us.
In this case, that's Grasshopper, an open-ended visual coding language plug-in for Rhino:
Luckily, there is no license or cost associated with Grasshopper, so you can just download and run it if you have Rhino! (Rhino 6 automatically includes Grasshopper, Rhino 5 requires a download here.)
There are many other plug-ins for Rhino, and they all seem to have fun animal names (Weaverbird, Flamingo, Penguin) but these are the only two we're using. (FOR NOW.)
You can tell you've done this step correctly when you can open Rhino and type in the command 'Grasshopper' to get a separate window:
Now, let's prepare a file for Rhino use.
Step 4: Preparing your model for Rhino
This step is something you can do in any CAD software you have, but I'm going to do it in SOLIDWORKS, because I know that system much better than Rhino.
What we're trying to get is a model that has, at a minimum, three bodies inside it:
The reason we're doing this is because, if you don't, after you use Grasshopper to make your middle body all complex and lattice-like, it will have hundreds of jagged little lattice beams sticking out all along its edges, which make it a pain to hold, to use in an assembly, to attach to other models, etc.
By having three bodies, after we lattice the middle one, we will be able to merge it back with the inner and outer bodies to control what our part borders look like.
If you don't have a hole in the middle of your model, I suppose you could get by with not having the inner ring body. But the above three body rule prepares you for most any type of shape.
Here's how I do it:
Using a Split feature, there is no overlap between your bodies, they are line-to-line perfect. But having gone through this process a few times, I'm mostly convinced that a little bit of volume overlap will make things easier to merge at the end.
But this is the way I first did it, and if you get to the end and your specific bodies don't merge well in Rhino, consider coming back here and adding more overlap between your three bodies.
Once you've got your model as a 3 body STL, STEP, or Rhino file, we can move on to some quick preparation in Rhino.
Step 5: Preparing your model for Grasshopper
Now that we've brought our three body model into Rhino, there are three quick things we need to do to prepare the model for Grasshopper:
- Put each body on a different layer
- Make a copy of the middle body
- Explode the middle body into surfaces
Putting each body on a different layer makes it easy to hide/show/color/merge them after we're all done:
Making a copy of the center body gives you one to keep as the original (which you will need for a boolean later), and one to explode into surfaces (which Grasshopper needs as a starting point).
Finally, take the copy of the middle body you just made and "Explode" it into surfaces:
Step 6: Using Grasshopper to Create Voronoi Structures
Most of what's in this section I learned by watching YouTube tutorials on how to program Grasshopper.
So after reading my steps below, if you want to go to the source and watch someone create a similar Grasshopper program in real time, here's an excellent starting point, from user "Parametric House".
(In essence, I'm giving you a text based version of the useful parts of 2-4 videos, with additional commentary and lessons learned specific to 3D printing. It's useful to watch those videos too, if you really want to get good at this.)
Grasshopper is a visual coding language, so instead of writing text like:
10: Print "Hi World!"
20: GOTO 10
we're going to connect boxes with little arrows on a big canvas.
Here's how Grasshopper looks when you first open it:
And if I wanted to create a program that scaled a Rhino surface by 2x, I would write:
And right away, the power of Grasshopper is apparent.
I can put ANY Rhino surface I want into that first orange box, meaning this simple program is infinitely reusable.
With just a move of that slider, I can change from a 2x, to 3x, to 4x scale, even 0.5x or 0.1x.
And the output of the program is geometry that can go into OTHER Grasshopper functions, meaning I can easily chain many, many little modules like this together to get complex, repeatable results!
So right now, you're asking yourself: "How would I know that the number command is called 'Number Slider' and not 'Input', or 'Variable'? And how would I know scale is called 'Scale' and not 'Enlarge'?"
And that's the biggest challenge of Grasshopper, I've found. It's got SO MANY options, to handle every type of geometry Rhino might have (points, curves, surfaces, meshes, solids), every sort of math you could do, every sort of transform and situation, that just FINDING the right command is the hardest part.
(This is why videos like the one from Parametric House are so valuable to watch, to build your Grasshopper vocabulary. Recommend you check them out!)
Three quick notes here:
- To add a command to your Grasshopper program, double click on the sheet and start typing in the first few letters, it will auto-complete pretty quickly.
- To input geometry from your Rhino screen, select that geometry, then right click on the Grasshopper command and choose "Set One Surface" or something equivalent.
- To link one command to another, just drag the end nub of one command (on its right) to the start nub of another (on its left). It will snap in place easily!
So let's start walking through that video and putting in the commands. I'm going to do a split screen from here on out, to show you the Grasshopper command and the temporary result in Rhino.
First, we want to choose our top exploded surface and make a rectangular plane which has the same dimensions, to act as a 'limiting boundary' for our complex lattice:
(If you left click on a Grasshopper command it should give you a green preview of that selected command. Don't worry- the temporary green geometry is not 'baked' into Rhino yet.)
Notice how our green rectangular surface seems a LOT bigger than the curved, exploded surface we started with, even laid flat? We'll see why that's happening a lot later.
Next, we want to Populate that new flat Geometry with around 200 random points:
(You guys are doing these steps along with me, right? Because you won't learn anything if you're not doing them with me.)
Next, we want to take those 200 random points and draw a "Voronoi" diagram around them.
Get used to typing the word "Voronoi" because it's a huge step in creating these complex, semi-random lattice structures we're looking for. Essentially, a Voronoi diagram is a line that's equally distant from the two points on either side of it. Read this Wikipedia article to learn more.
Luckily, Grasshopper has a simple command for Voronoi diagrams:
I think we need to appreciate this for a second. On my computer, that Voronoi command made that complex, controllable, repeatable green Voronoi pattern from 200 points in less time that it takes me to type these bold words.
(Grasshopper is an immensely powerful add-on for CAD, and I think I'm going to be using it for a lot more projects from here on out!)
The video does a neat trick here (5:20), and uses our flat plane surface to make a curve, which acts as an outer boundary for our Voronoi diagram:
But we've still got just a theoretical, infinitely-thin lattice on our plane. We need to make it thick enough for our printers to actually print!
So now we're going to use a 'Scale' feature to give it some width, making a real lattice:
(One fun thing about Grasshopper is that you can adjust those sliders, like that 0.85, and your graphics will update in real time! It will stress your graphics card if you do it too much, but if you want to see different thicknesses of your lattice, play around with it now!)
Now we're going to take that collection of scaled curves (still just separate curves) and knit them together, using a 'Boundary Surface' command.
We are going to feed that boundary surface two things: the curves we just offset with the Scale, and the original rectangular curve from our original bounding plane (command #4).
To make two inputs feed into the same command, simply SHIFT+drag the second input arrow into the Curve feature:
Note: SHIFT+dragging a second input into our new Curve feature makes a matrix of inputs inside that curve command, like there's a (0,1) list of the original rectangular bounding plane curve added to a (0,200) list of all these offset Voronoi curves, resulting in a 4x4 matrix like (0,1; 0,200).
We just want one, 'flat' matrix going forward, so we have to right click on the Curve feature and 'Flatten' it (#13 above).
If this seems confusing, it was at first for me too. To recap, for this step, you are going to:
- Make a new Curve command (#12)
- Drag the output of our Scale feature into it
- SHIFT+ Drag the output of our bounding plane (#4) into it
- Right click on the Curve feature and Flatten it into one matrix (#13)
- Add a Boundary Surface command (#14)
If you're still confused, this happens in the Parametric House video at 7:00.
We're almost there.
By now, you should have a boundary Vornoi surface that looks like this:
All we have to do is extrude it, map it back onto our original shape, and then do some booleans!
Let's Extrude it in the Z direction, with a little slider that lets us control how high it goes:
And now we're going to 'Surface Morph' it back onto our original curved surface, with a few sliders that let us control where exactly how far it goes:
That looks like a lot, but it's just using the output of our extrude, setting one surface like we did at the beginning, and making 3 sets of domain sliders.
Here's where you should be after that surface morph:
If you're having trouble getting there, right click on the Surface Morph command and 'Reparameterize' it:
It's interesting to see how the U domain sliders affect where our shape morphs to. Here's a comparison:
So by changing those sliders, we can have the Morph cover as much or as little of our original body that we want! (Good if you only want to Voronoi a certain section.)
And now we've finally solved the mystery of why our original bounding plane (#4) was SO BIG compared to our exploded curved surface. It seems like, in Rhino, a curved surface goes all the way around in a circle , and we're only seeing a trimmed section of it on screen.
This is why, the 0->1 morph goes all the way around that same circle, since we're telling it to use ALL of that domain.
Okay, pretty close to done.
To get the Voronoi section to overlap with my model for a boolean, I'm going to Move it down in the Z direction (the direction and amount you move it will change depending on your specific geometry, which is why I used a slider):
And we're done!
Right click on your final Move command and "Bake" that Geometry into any Rhino layer to make it real, permanent Rhino object!
(It will ask you which layer to 'Bake' your geometry onto, I usually have a layer created specifically for that. You can delete bad bakes more easily that way.)
Step 7: Merging Bodies in Rhino
The final Voronoi structure from my last Grasshopper step was a little too spread out for my artistic tastes, so I went back and increased our number of points from 200 and made the offset a little more dense to make it look nicer:
That's the great thing about Grasshopper- it's generating all the geometry every time you change a slider, so feel free to edit any sliders right now and re-bake your result before continuing on!
(You can also use your saved Grasshopper script on a totally DIFFERENT CAD file, just by opening a new file in Rhino, saving hours of time!)
Now that we have REAL geometry, the first thing I'm going to do is a Solid Intersection of our Voronoi shape with our original middle body (not the surfaces, but the real middle body solid) to get:
This is getting really cool.
And remember how I made you have an inner and outer ring, way back in SOLIDWORKS? Look at that intersection we just made, with all those jagged outer edges. This is when the 3 body method pays off, because now we do a Solid Union with those other two bodies:
(One more important note here: DELETE ALL YOUR SURFACE BODIES before printing. Otherwise they'll fill in all the gaps we just made!)
And if you export that result to your full color, high resolution Stratasys J750 printer you get...
Step 8: Printing!
That is exactly what I was looking for, when I started this project.
I started with a precise, curved CAD shape, used Grasshopper to 'Voronoi' my insides, and still have my smooth, defined outer borders, to make sure it fits into whatever assembly I want!
And with the script written I can do it again immediately, to any other CAD body I have!
I used Rhino to throw on a 'desert texture' and:
That's pretty satisfying, knowing I can control the texture AND the Voronoi pattern on nearly ANY model I want to print.
But we can go even further.
Step 9: Going Further
There is another good YouTube tutorial from Parametric House about "Voronoi Attractors", which let you cluster your Voronoi points in a certain circle, to make your grid more dense in any area you wish.
I'm not going to go through that video step by step, but the general gist is you are adding to your Grasshopper program:
- A) a Graphical interface to move the center of your circle around,
- B-C) Sliders which say how big the circle is and how many new points are in it
- D) a second Populate Geometry command, the output of which you will SHIFT+drag into your existing Voronoi command, to add to your original points.
Here's how it looks added to your existing code:
(Watch that video if you want to see that added, step-by-step.)
With that done, you can now add a 'cluster' of Voronoi points like this (and notice how much lag there is between my input and the result, showing how hard my graphics card is straining!):
Texturing that result and printing that file on a full-color J750 results in:
That smaller clustered area can be ANYWHERE in my model I want, at any density, and this is repeatable, for many different models- THAT'S the power of Grasshopper + Stratasys 3D printing!
There is even ANOTHER plug-in for Grasshopper called "Weaverbird" and if you want to make 3 dimensional lattices (instead of the extruded and morphed 2D grids we're essentially making). There's another Parametric House tutorial showing how to use Weaverbird as well (I'm going to have to meet these guys sometime!) and if you get Weaverbird + Grasshopper going, you can do things like THIS:
(A notice to employers: those two last Weaverbird examples were created by our Spring intern Anthony Valle, a senior at Suffolk University. If you're looking for someone to hire who eagerly jumps into 3D printing complex shapes, let Anthony know!)
So some of you are probably asking, "But none of these are useful prints. What can we actually DO with all of this?"
Well, if you play around with Voronoi programs, texturing, and multi-material 3D printing for about a week, you can make something like this:
That's a Voronoi + galaxy textured top, printed on a prototype video game controller, and lit internally. If you want to learn how to do something like THAT, I've got a tutorial on that as well.
The point is, there is a LOT more do to, once you've got the basics of this workflow humming!
To help you get started, if you want to download any of the SOLIDWORKS, Rhino or Grasshopper files I've used in this tutorial, go to this GrabCAD Library.
And if you have any questions on how Stratasys software and printers can get you similar results as those seen above, you can always email me at firstname.lastname@example.org.
Hope this helped!