## Adaptive Pavilion

Adaptive Pavilion is an old school script that used to be taught in many workshops of the early days of Grasshopper (2010-2011). It consists of a Pavilion based on two free-form NURBS curves that delineate pavilion borders connected by arcs defining the pavilion surface. David Rutten, the creator of Grasshopper, has his version of this script from 2013, in which he teaches Grasshopper basics using this example. Back in those days, everyone had a version of this script. Some versions used triangulated panels, others used grid shell, and others voronoi…a lot of them used Voronoi.

In this tutorial, we explore a version that I used to teach in Grasshopper workshops. However, this version has a special Blender flavour. Instead of using a NURBS curve, we draw the curve using the power of Blender’s Grease Pencil, which allows us to make and animate 2D sketches in 3D Blender Environment. It is a powerful tool to be explored by architects and designers. This example is just a simple exploration of how this tool can be used.

### Grease Pencil

First, we create a `Blank`

`Grease Pencil`

object on Blender Viewport (`Shift+a -> Grease Pencil -> Blank`

).

Then, we turn on `Auto Keying`

to automatically save keyframes in the Blender timeline. This step is necessary because `Grease Pencil`

will use it to register drawings in the keyframes in the different drawing canvas. It is a feature of 2D animation, and the draws just can be saved in keyframes.

We draw the curve using the `Grease Pencil`

tool. On Blender Viewport, we digit `7`

from NumPad to change the view from `Perspective to `

Top View`. Then, change Blender Mode from `

Object Mode` to `

Draw` and draw a freehand curve following the `

Y` axis.

The next step is to pass this curve to Sverchok. We use `Object_ID Selector+`

(`BPY Data -> Object_ID Selector`

) for `data`

parameter we use `grease_pencils`

, for `name`

-> `GPencil`

, which will be this name by default it is the first object draw, for `layer`

-> `GP_layer`

, it follows the same logic of the `name`

parameter, but for the layer’s name. Finally, we click on the `active frame`

option to select active keyframes.

Then, we use `Path Length`

(`Analyzers -> Path Length`

) to measure the curve length.
`Object`

output from `Object_ID Selector`

node goes in `Vertices`

input from `Path Length`

, or in a short notation form:

`(Object_ID Selector[Object ->]) -> (Path Length[Vertices <-])`

I will use these notations from now to make less verbose input/output descriptions.

We connect a `Multiply`

(`Number -> Scalar Math`

) as a factor, because later we will divide this curve into vertices and use this factor to define the number of vertices.

`(Path Length[TotalLength ->]) -> (Multiply[x <-])`

Then, we connect the `Multiply`

node in a `Float to Int`

(`Number -> Float to Int`

) node.

`(Multiply [Out ->]) -> (Float to Int [float <-)`

We use a `Number Range`

(`Number -> Number Range`

) connected to the `Float to Int`

:

`(Float to Int[int]) -> (Number Range[step <-])`

To create an interval of numbers from `0`

to `1`

, using the method `Float`

, `Count`

, with `start`

as `0`

, `end`

as `1`

, or:

`Number Range {Float; Count; start:0; end:1}`

Then we connect the `Number Range`

and `Object_ID Selector`

to a `Vector Interpolation`

(`Vector -> Vector Interpolation`

). Also, we can use a `Viewer Draw`

(`Viz -> Viewer Draw`

) to visualise the vertices on the curve.

`Vector Interpolation {Linear}`

`(Number Range[Range ->]) -> (Vector Interpolation[Interval <-])`

`(Object_ID Selector[Object ->]) -> (Vector Interpolation[Vertices <-])`

`(Vector Interpolation[Vertices ->]) -> (Viewer Draw[vertices <-])`

We make a group with the curve nodes `Crtl+j`

.

We create a connection between the vertices using `UV Connection`

(`Modifiers-> Modifiers Make -> UV Connection`

). We use a `Viewer Draw (1)`

to visualise.

`UV Connection {Direct:U; Make:Edges}`

`(Vector Interpolation[Vertices ->]) -> (UV Connection[vertices <-])`

`(UV Connection[vertices ->]) -> (Viewer Draw (1)[vertices <-])`

`(UV Connection[data ->]) -> (Viewer Draw (1)[edges <-])`

### Creating a Pavilion Form

Now, we need to mirror the vertices to create other pavilion borders using `Mirror MK2`

(`Transformations -> Mirror`

). Here is a tip, if you click `T`

in the Sverchok canvas, you can access a menu with Sverchok components divided into categories. Through a search bar from this menu is possible to check in which category a specific node fits.

The parameters from the `Mirror MK2`

node will vary according to the curve drawn with the `Grease Pencil`

.

In my case the values used were:

`Mirror MK2 {Vertex; x:1.05; y:1.2; z:0}`

The `UV Connection`

node connects to `Mirror MK2`

.

`(UV Connection[vertices ->]) -> (Mirror MK2[vertices <-])`

The next step is to connect the list of vertices of both curves. We use `UV Connection (1)`

connecting `Mirror MK2`

and the previous `UV Connection`

. Also, we can use the shortcut `Alt + Space`

to search for nodes.

`UV Connection (1) {Direction: V; Make: Edges}`

`(UV Connection[vertices ->]) -> (UV Connection (1)[vertices 1 <-])`

`(Mirror [Vertices ->]) -> (UV Connection (1)[vertices 1.1 <-])`

But the second list of vertices is reversed. It makes the connection between vertices be reversed as well. We need to reverse the second list to make this connection work right. We use a `List Reverse`

(`List -> List Struct -> List Reverse`

) node between the `Mirror MK2`

and `UV Connection (1).

`List Reverse {Level: 2}`

`(Mirror MK2 [vertices ->]) -> (List Reverse[data <-])`

`(List Reverse[data -> ]) -> (UV Connection[vertices 1.1 <-])`

Now, we create vertices in the middle of each line created. This vertices will be used later to define the pavilion top. We use `Subdivide Lite`

(`Beta Nodes -> Subdivide Lite`

) connecting `UV Connection (1)`

. Also, we use a `Viewer Draw (2)`

to visualise the geometry.

`Subdivide Lite {Show Options; Show New}`

`(UV Connection (1)[vertices ->]) -> (Subdivide Lite[vertices <-])`

`(UV Connection (1)[data ->]) -> (Subdivide Lite[edg_pol <-])`

`(Subdivide Lite[New Vertices ->]) -> (Viewer Draw (2)[Vertices <-])`

We will create a cosine curve to control the pavilion top vertices. First, we use a `List Length`

(`List -> List Main -> List Length`

) to track how many vertices we have, connecting it to `Subdivide Lite`

with `New Vertices`

output.

`{List Length {Level : 1}}`

`(Subdivide Lite[New Vertices ->]) -> (List Length[Data <-])`

Then, we use a `Number Range (1)`

to control cosine frequency, a `Scalar Math (Multiply)`

(`Number -> Scalar Math`

) node to amplify the cosine frequency, and a `Scalar Math (Cosine)`

.

`Number Range (1) {Float: Step}`

`(List Length[Length ->]) -> (Number Range[Count <-])`

`(Number Range (1)[Range ->]) -> (Scalar Math (Multiply)[x <-])`

`(Scalar Math (Multiply)[Out ->]) -> (Scalar Math (Cosine)[x <-]))`

Now we use a `Scalar Math (Add)`

to control the position on the `Z`

axis of the cosine curve, then a `Vector In`

(`Vector -> Vector In`

) connecting the `Z`

input.

`(Scalar Math (Cosine)[Out ->]) -> (Scalar Math (Add)[x <-])`

`(Scalar Math (Add)[Out ->]) -> (Vector In[Z <-])`

Now everything is ready to generate the cosine curve. We use a `Move`

(`Transforms -> Move`

) node to move the vertices to the pavilion top. We connect it to `Vector In`

and `UV Connection (1)`

. Then, we use a `Viewer Draw (3)`

to visualise the output and change the values of `Scalar Math (Add)(Multiply)`

to modify the pavilion top vertices.

`(UV Connection (1)[New Vertices ->]) -> (Move[Vertices <-])`

`(Vector In[Vertices ->]) -> (Move[Movement Vertices <-])`

`(Move[Vertices ->]) -> (Viewer Draw (3)[Vertices <-])`

Now is the time to create a shell for the pavilion. We use `UV Connection (2)`

connecting following this sequence: the first vertices list `Vector Interpolation`

output, the cosine vertices `Move`

output, and the second vertices list `Reverse List`

output. We use a `Viewer Draw (4)`

to visualise the shell.

`UV Connection (2) {Direction: U; Make: Pols}`

`(Vector Interpolation[vertices ->]) -> (UV Connection (2)[vertices 1 <-])`

`(Move[Vertices ->]) -> (UV Connection (2)[vertices 1.1 <-])`

`(Reverse List[data ->]) -> (UV Connection (2) [vertices 2.1 <-])`

`(UV Connection (2) [Vertices ->]) -> (Viewer Draw (4)[Vertices <-])`

`(UV Connection (2) [data ->]) -> (Viewer Draw (4) [Poligons <-])`

Now we can make this pavilion less “sharp”, using a `Subdivide`

(`Modifiers -> Modifiers Make -> Subdivide`

) node, connecting `UV Connection (2)`

(vertices and polygon) and `UV Connection (1)`

(edges). Then, a `Viewer Draw (5)`

to visualise the geometry. We can control how smooth the shape will be by changing the value of the `Smooth`

parameter.

`Subdivide {Show Options; Falloff: Smooth; Grid Fill}`

`(UV Connection (2)[vertices ->]) -> (Subdivide[Vertices <-])`

`(UV Connection (1)[data ->]) -> (Subdivide[Edges <-])`

`(UV Connection (2)[data ->]) -> (Subdivide[Faces <-])`

`(Subdivide[Vertices ->]) -> (Viewer Draw (5)[Vertices <-])`

`(Subdivide[Edges ->]) -> (Viewer Draw (5)[Edges <-])`

`(Subdivide[Polygons ->]) -> (Viewer Draw (5)[Polygons <-])`

Then make a group with pavilion nodes `Ctrl +j`

.

### Adaptive Polygons

The final step is to adapt the panels with an external form. In this example, we use a Torus geometry. We use a `Adaptive Polygons`

(`Modifiers -> Modifiers Make -> Adaptive Polygons`

) and a `Torus`

(`Generator -> Torus`

). We have to connect Vertices and Polygons from a “recipient” `Subdivide`

output and vertices, edges, and polygons from a “donor” `Torus`

output. We can use a `Viewer Draw (6)`

to visualise the final result.

`(Subdivide[Vertices ->]) -> (Adaptive Polygons[Vertices Recipient <-])`

`(Subdivide[Polygons ->]) -> (Adaptive Polygons[Polygons Recipient <-])`

`(Torus [Vertices ->]) -> (Adaptive Polygons[Vertices Donor <-])`

`(Torus [Edges ->]) -> (Adaptive Polygons[Edges Donor <-])`

`(Torus [Polygons ->]) -> (Adaptive Polygons[Polygons Donor <-])`

`(Adaptive Polygons[Vertices ->]) -> (Viewer Draw (6)[Vertices <-)`

`(Adaptive Polygons[Edges ->]) -> (Viewer Draw (6)[Edges <-)`

`(Adaptive Polygons[Polygons ->]) -> (Viewer Draw (6)[Polygons <-)`

Then make a group of adaptive nodes `Ctrl+j`

.

Then you can play with the parameters.

…or change the Grease Pencil draw.

You can download the blender file here

Have fun.