Roof with Holes
Expected Time: 30 min
In this tutorial you will learn how to create holes in a roof. We assume that you have already created a roof in Rhino. This can be a rectangular shape, or a more organic form. However, it is important that you are using a surface and not a solid. Before we start, let’s think about the design aspects that are important.
- The holes must be randomly distributed over the roof
- The size of the holes may be varying
- The Grasshopper script must run smoothly, it may not take more than 1 second to calculate
Before we start building however, let’s take a look at the intersection modules of Grasshopper.
The Grasshopper Intersect tab has four categories: mathematical, physical, region and shape. The mathematical modules mainly focus on intersections between curves and planes or surfaces. Physical intersections are mostly 2-Dimensional. Regions include the trim and split tools of Grasshopper. Shape intersections focus on 3-Dimensional geometry, like solids and 3D meshes.
So why is this important? When you will start working with intersections of geometry, it will be hard finding the right method. Sometimes a script may work, but it is very slow and hard to work with. Therefore we advise you to practice with the different tools, watch tutorials and before solving, think about the best method!
Generally speaking, the lower amount of dimensions geometry has, the easier the calculation. For example: a curve and a curve is a faster calculation than a solid with a solid. This is the reason why it was asked to use a surface, and not a solid as roof to work with.
Creating the Script
First, create your roof in Rhino or Grasshopper. This should be a surface. In the picture on the left, you see an example how it can look like. Of course you can also just make a rectangular surface. After that, connect it to a surface parameter in Grasshopper.
- Create a roof in Rhino
- Set the roof to a surface parameter
Now we want to project the surface on the ground plane. This will be the blueprint where we make the holes for our script.
- Project the surface on the ground
There are several project functions in Grasshopper. Make sure you use the right one as visible in the image! The project function also asks for a Plane. If we hold our mouse on the Plane input, you see it already has set a World XY Plane, so this is fine.
Now populate the projection with points using the Populate Geometry module. Please take a look at Random Points on Surface if you are not familiar with this function. Connect a Number Slider to the Count and Seed and check your Rhino viewport.
- Connect a Populate Geometry function to the projection
- Add two number sliders to the Count and Seed
As you can see, some of the points are very close to the boundary of the blueprint. This is a problem. When you will create a circle around these points, the holes will cut the boundaries of your roof. This problem will be solved in a later stage. Let’s go back to where we were.
The next step is to create the circles around the points we just made.
- Add a Circle CNR to every point
Now we want to generate the radius of the circles randomly. Add a random node to the radius and connect a construct domain to it as we have done in several earlier tutorials. The Number input of the random node is equal to the count of the Populate Geometry function.
- Connect a random node to the Radius of the circles
- Add a construct domain to the range with Number Sliders as input
- Connect the Numbers Slider of the Populate Geometry Count to the Number input of the Random node
- If you want, you can add a seed input
The next step is to fix the problem that some circles are cutting the edges of the blueprint. There are multiple methods to solve this problem. First, you could remove al the circles that intersect. However, that would mean that the amount of openings is not equal anymore to your preferred input. Second, you can change the boundary. In our case, we will choose for the second option.
Add a deconstruct Brep to the projection. This will divide the original surface in Faces, Edges and Vertices.
- Connect a Deconstruct Brep to the Geometry output of the projection
When you connect a panel to the Edges output, you see that the output gives 4 different edges. Of course, if we want to offset them, they need to be joined. So add a join curves node.
- Connect a panel to the Edges output of the Deconstruct Brep
- Connect a join curves to the Edges output of the Deconstruct Brep
After joining the curves, the overall edge should get an offset inwards. For this, Offset Curve can be used. Note that the Plane Input already has an XY Plane, so that is fine. You can leave the Corners input as it is.
- Add an Offset Curve to the joined edges
The question is, how far should the curve be offsetted? Considering that the radius of the circles is based on a domain. We can use the maximum possible value (Domain End) as Distance.
- Connect the Number Slider of the Domain End to the Distance input of the Offset Curve
Now the curve should be changed to a surface. This can be done by adding the Boundary Surfaces component
- Connect a Boundary Surface component to the curve output
Now we should replace the Populate Geometry Geometry input with the new surface just created.
- Replace the Populate Geometry Geometry input with the created surface, as can be seen in the left picture
- Reorder you Grasshopper script
- Rename your Number Sliders
Let's check our Rhino viewport. We now have a blueprint with curves. The last step is to project these curves on the roof and make an intersection.
Project the created blueprint curves on the roof. Use the original surface as input for the Brep. Make sure you use the correct version of the project nodes! As you see, the direction of the project function we use is Z (up), so it can be left empty.
- Project the holes on the roof
- Connect the original surface to the Brep input of the Project node
Connect a panel to the Curve output. As you see, we have a structure of lists in lists. This is not was we need, flatten the list. Tree editing is a complex but essential aspect of Grasshopper. In this stage in the tutorials, it is still hard to explain. Just remember that flattening will give you one single list with information.
- Flatten the Curve list
The final question is what intersection module to use. Note that we use a surface and curves. Looking at the intersection tab, a Surface Split can be found. Set off the preview of all functions we used before to see the result.
- Add a Surface Split
- Set off the preview of previously used nodes
As you see in the Rhino viewport, not only the intersected roof is visible, but also the smaller hole parts. You can fix this by adding a List Item node. Standard, the List Item node takes the first item of the list (index 0). Luckily, the overall surface is already the first item. If not for some reason, just add a Number Slider to the Index of the list item and find the right surface.
- Connect a list item to the Fragments output of the Surface Split
By adding an Extrude to you script, you can give your roof thickness.
- Add thickness to your roof with
- Add a Unit Z to the direction of the extrusion
- Connect a Number Slider to the Unit Z vector
Your script is now completed! For good practice, add a Geometry Parameter at the end. Don't forget to turn off the preview of nodes that are not important.
- Add thickness to your roof with
Calculation Speed of Grasshopper
During your learning process of Grasshopper, you will find out that calculation time is important. As stated in the beginning of this tutorial, it is important to use the right modules, because some of them take more time to calculate than others. If you want to see which functions in your script are the bottleneck, turn on the profiler to see the problem.