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.

Adaptive Pavilion

Grease Pencil

First, we create a Blank Grease Pencil object on Blender Viewport (Shift+a -> Grease Pencil -> Blank).

Blank Grease Pencil

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.

Drawing the Curve

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.

Object_ID Selector

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.

Path Length

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}

Number Range

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 <-])

Vector Interpolation

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

Group Curve

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 <-])

UV Connection Curve

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 <-])

UV Connection 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 <-])

List Reverse

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 <-])

Subdivide Lite

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 <-])

List Length

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 <-]))

Number Range Cosine

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 <-])

Vector In

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 <-])

UV Connection Shell

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.

Pavilion Group

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 <-)

Adaptive Polygons

Then make a group of adaptive nodes Ctrl+j.

Adaptive Polygons Group

Then you can play with the parameters.

Pavilion changing parameters

…or change the Grease Pencil draw.

Pavilion changing draw

You can download the blender file here

Have fun. Monkey working