Expected Time: 30 min
A strong feature of Grasshopper is it's ability to populate surfaces. In this tutorial we will populate a double curved surface with structural triangles. At first we will start making the component, which we will then use to populate the surface.
Before we start building the grasshopper model we should determine some of its basic properties. In the introduction we already stated that we want to populate a double curved surface with structural triangles. But to study different results we need to have different input. Therefor we need to determine some variables/parameters that will influence the different results.
These variables/parameters could include:
- number of triangles in both directions
- specific shape variations (round corners, etc.)
In this tutorial we will try to keep it simple, so we skip the complicating variables (for now).
Step 1 - Starting the grasshopper model
First of all we need to define the triangles. We do this by creating two triangles on a base surface. So first of all we need this surface. We could use a surface created within Grasshopper, but as this surface is just temporary we use a surface created in Rhino instead. Make sure you create this surface in the top right quadrant of the top viewport.
- Create a surface in Rhino
The size of the surface does not matter that much, but it is easiest to make it more or less the estimated size of the final triangles that will make the surface.
Now we start using Grasshopper. In Grasshopper we add a Surface parameter to be able to link to the surface we created in Rhino.
- Create a surface parameter in Grasshopper
- Set a Rhino surface on the Grasshopper Surface parameter
We want to create triangles between the corners of the surface. Therefore we need the data of the corners. We get this data by deconstructing the surface.
- Deconstruct the surface
By connecting the Surface with the BRep Components we get to see the preview of the surface with its corner points.
Hovering over the V of the BRep Components shows us the list containing the coordinates of the four corner points. If you want to see the order of the vertices, use a Point List node.
- Visualize the order of the vertices in Rhino
We need to split the data of the corner points so we can use them individually. To do this we need a List Item.
- Retrieve a specific vertex
Connect the data of the BRep Components with the L input of the List Item. By clicking on the small + icon when zoomed in on the List Item function, we can get all four vertices of the surface.
- Zoom in on the List Item node and click three times on the + icon
Now we will create two opposite triangles from the surfaces using two polylines. To specify which vertices to use, we add a Merge node. The points should be picked clockwise. For the first polyline connect List Item index 1, 2 and 3 to the Merge node. For the second polyline respectively, select items i, 2 and 3.
- Add two Merge nodes to the canvas ;
- For the first Merge node, connect item i, 3 and 2;
- For the second Merge node, connect item 2, 1 and i
Create two polylines from the Merge outputs and close them.
- Create two polylines from the Merge nodes
- Set the the Closed input to True
Our Grasshopper model should now look something like this. If you do not see two opposite triangles, you probably didn't connect the points in the correct order to the merge node.
Step 2 - Shaping up the triangles
The triangles are only curves so far, so we want to give them some thickness. First of all we are going to offset the curves.
- Offset the polylines
The Offset will need a distance, so it would be nice to be able to change this distance easily. Especially because we don't know exactly how big everything will be in the end. To change the Offset distance we use a Number Slider.
- Give the curve offsets a distance
The triangles are going to populate a double curved surface. Thus the plane on which the triangles are positioned should be different for every triangle. To achieve this we have to determine the positioning of the plane.
Create a plane through three points. Use the right hand rule. Your thumb is the Z-axis, make sure it points upwards, your index finger the X-axis and your other fingers is the Y-axis.
- Create a plane for each triangle
For each triangle we use a Plane 3Pt and an Offset. The distance for the offset is the same for both triangles so we use one Number slider that connects to both Offsets. For the Plane 3Pt we use the three corner points of the triangle and use its output to determine the direction of the Offset. With the Plane 3Pt we need to take care with the order of the input, because it influences the direction of the offset.
As you remember you made the triangles with a closed polyline in clockwise (negative) direction on a global coordinate system with Z-axis up. With Plane 3Pt you created a local coordinate system with Z-axis up.
With this knowledge a positive offset on a postive closed lines would be in outer direction. And a positive offset on a negative closed lines would be in inner direction.
- For the first plane, connect List Item output 3, i, 2;
- For the second plane, connect List Item output 1, 2, i
- Connect the planes outputs to the polyline offsets plane inputs
We will use a planar surface to actually create the face of the triangle. We want to make a planar surface between the original triangle curve and the offset curve, therefore we connect both to the Planar Srf.
- Create a face between the polyline and offset
There is only one problem. Instead of making one surface between the two curves, it makes two surfaces. This has to do with the data streams (more on data streams later). Grasshopper data works in a very hierarchical way and if components are not in the same hierarchy-layer they will not work together.
By flattening the data we more or less flatten the hierarchy. This makes sure the components are in the same hierarchy-layer and therefore they can work together.
- Flatten the Edges input
Now the triangles are how we want them. The geometry to populate the surface with is now ready.
Step 3 - Populating the surface
Now all we need is a Surface to populate the triangles onto. We can do this in many different ways, but in this example we start with drawing two curves in Rhino.
- Create two curves above each other
In Grasshopper we create a Curve component and loft the two curves
- Add a curve parameter to the surface
- Link the curves to the curve parameter
- Loft the two curves
If the lofted surface is not in the correct direction, make sure you flip one of the curves in Rhino using the flip command.
Next step is to divide the surface we created by doing an Isotrim.
- Trim the surface in small parts
Isotrim needs input values with the actual number of divisions. An easy way to achieve that is to use Divide Domain.
- Create a domain for the surface
- Define the U and V input with two Number Sliders
The surface now looks more or less like this.
The interesting part is the output of the Isotrim component. If we look closely we see that its a list of surfaces.
Our original triangles had a surface as input, so all we have to do is connect the output of the Isotrim with the input of the triangle and it will populate the surface with the triangles. The sliders give us the opportunity to adjust some variables and therefore study several design alternatives. Changing the input curves of the surface also gives us this opportunity.
Combine the Boundary Surfaces nodes in one Geometry Parameter. Turn off the preview off all other nodes.
- Create a Geometry Parameter and connect the Boundary Surfaces
Step 4 - Give a thickness to the model
As final step, Extrude the model in the perpendicular direction of the surface. This may be different in your model, but in our case, we should be using the Y-direction. Connect a Number Slider to define the thickness.
- Extrude the Geometry
- Define the direction (in our case the Y-direction)
- Add a Number Slider to the unit vector for the thickness
Now we need to make the extrusions closed.
- Cap the holes of the Extrusion
If you want, you can add a final Geometry parameter.
- Finalize with a Geometry Parameter, holding the result