# Turning Tower

Turning tower is a recurrent Grasshopper algorithm in workshops and courses that I have participated in or watched. I like this algorithm because it pushes learners to new concepts, such as range, series, lists, logic operators, remapping numbers, euclidean transformations. All these concepts are relevant to the development of other Grasshopper algorithms. I decided to start from this algorithm and see how the same logic works in Sverchok building a complete exercise with all elements of my version of Turning Tower that I use to teach Grasshopper to students. If you are starting with Sverchok, I suggest you first look at the previous tutorial that I made Hello Sverchok that gives you some foundations to get started.

## Modelling the Tower

First, we need to define the building ground floor based on a polygon. I used the node `NGon`

(`Generator -> Ngon`

) to build my ground floor. You can change the parameters of `N of sides`

and `Radius`

as you wish to adapt the form of your tower. Next, we define the levels number and ceiling height for the building using the `Number Range`

(`Number -> Number Range`

) node with `Float`

as `Step`

. Then, we set to start as `0`

(which is where our ground floor will start), `step`

as `3.0`

for our ceiling height, and `count`

to define the number of building levels, using `A Number`

node(`Number -> A Number`

). We can use a `Viewer Draw`

node (`Viz -> Viewer Draw`

) to keep tracking of the process.

In Sverchok, unlike Grasshopper, to apply serial transformations to a mesh, we use **Matrix** operations. A matrix can be applied to a mesh to scale, rotate, or translate. We are going to use some transformations in this algorithm. First, we need to connect the `Number Range`

output to the input `Z`

of a `Vector In`

(`Vector -> Vector In`

) node, creating the vectors that will place our building levels. Then, we use `Matrix in`

(`Matrix -> Matrix in`

) to set the matrix transformation to the location of the original polygon. We connect the output of `Matrix in`

into the `Matrix`

input of the `Viewer Draw`

node to visualise this transformation.

A nice aspect of the Turning Tower algorithm is the combination of several transformations.
First, we need to create the effect of “turning” the tower. We can use a node to deform the matrix, `Matrix Deform`

(`Matrix -. Matrix Deform`

). Then, we use a new `Number Range`

with the method `count`

, which will connect with the previous `A number`

node that determines the number of building levels. Also, we define a start and stop for the rotation angle, using `start`

and `stop`

in the `Number Range`

node. Finally, we need to define the rotation axis using a `Vector in`

node in the `Z`

direction with the value of `1`

as vector amplitude. The outputs from `Matrix in`

, `Vector in `

and `Number Range`

go into `Matrix Deform`

input, `Matrix in`

output goes into `Original`

input, `Vector in`

output goes into the `Rotation`

input, and `Number Range`

output goes into `Angle`

input.

We can make it more interesting by applying a scale transformation. We use another `Number Range`

node, but we connect the existing `Matrix in`

node input `Scale`

. We use the method `count`

starting as `1`

, which means a multiplication factor of `1`

maintaining the original size for the first element of the list and a `stop`

value of `0.5`

, representing that the last element will have the half of the size of the first one. All the other elements will be in an interpolated factor between `1`

and `0.5`

. A shortcut tip to visualise the nodes nicer and tidy we can use the `Shift + Right/Mouse button`

to connect one or more wires.

The `Viewer Draw`

node is for visualising those steps, but to apply the transformations for the next steps, we replace `Viewer Draw`

with the `Matrix Apply`

node.

A good practice is to make groups of elements that compound a set of nodes or design steps. We can group nodes in Sverchok, selecting the nodes and then using the shortcut `Crtl + J`

.

## Facade Panels - Part 1

Now is the time to create the facade panels. First, we need to interpolate the vertices from the `Ngon`

base with the vertices of the `Matrix Apply`

node. We use the `UV Connection`

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

) node, determining `Direction`

( for the direction of the interpolation), `Cycle`

(to determine the direction of the wrapping), `Cap`

(to determine if the shape will be capped or not), `Make`

(for choose between Polygons or Edges), and `Slice`

(to choose if the connection will be sliced in different objects for each vertex from the base vertices).

Then, we can use `Poke Faces`

(`Modifiers -> Modifiers Change -> Poke Faces`

) to triangulate the panels. A new tip is that you can use numbers to access specific categories of nodes: `1`

basic data types, `2`

mesh, `3`

advanced objects, `4`

connection, and `5`

SV interface. We connect `UV Connection`

outputs into `Poke Faces`

inputs, `vertices`

goes into `Vertices`

and `data`

goes into `Faces`

. Also, we use the `Poke Offset`

parameter to determine the offset of the centre vertex following the normal axis of the faces.

### Attractor Point

We are going to hold the panels for a moment because we need to start to prepare the attractor point that will influence the size of the openings of the panels. The Attractor points well-explored technique in parametric design used to create variations according to a specific goal. For instance, in this exercise, we explore a single attractor defined as an `Empty Object`

in Blender, measuring its distance concerning the centre of each panel, determining a scale factor based on that distance.

First, we need to find the centre point of each point. We use the node `Origins`

( `Analyzers -> Origins`

), connecting `vertices`

output from `Poke Faces`

into `vertices input, and `

Faces` output into `

Faces` input. Then, choosing the method `

Faces` of the `

Origins` node.

Then, we need to create the `Empty Object`

in Blender Viewport.` Shift+A`

then `Empty -> Plain Axis`

. Then, get the node `Get Objects Data`

(`Scenes -> Get Objects Data`

) and link it to the `Empty Object`

.

The next step is to get the matrix of the object that records its location. We use `Matrix Out`

connecting the `matrix`

output from `Get Objects Data`

into `matrix`

input.

Now, we use the node `Distance`

(`Analyzers -> Distance`

) to measure the distance from the location of the `Empty Object`

to each panel centre point `Origins`

. We hold this for a moment because the attractor and panels will be finalised in the next step.

## Facade Panels - Part 2

We almost have the attractor point set up, but first, we go back to the panels. We use the `Inset Faces`

node (`CAD -> Inset Faces`

) to create the frame for the panels, connecting `Poke Faces`

outputs into `Inset Faces`

, `Vertices`

into `Verts`

, `Faces`

into `Faces`

, and `FaceData`

into `Face data`

.

We have large distance values, and we can not use it as a scale factor because it will mess up the frames creating disproportional elements. We need to remap the mathematical domain of this list of numbers into another domain that makes sense to scale the panels. For instance, if the distances vary from `20`

to `50`

, we can remap it from `0.07`

to `0.9`

, maintaining the ratio among the numbers. We use the node `Map Range`

( `Number -> Map Range`

), using `List Limits`

checkbox choosing the `New min`

and `New Max`

value. Then we connect the `Map Range`

output into the `Thickness`

input of `Inset Faces`

… and now we have opening changing according to the distance of the attractors.

The next step is to create the panels’ visualisation. First, we use `List Mask (out)`

(`List -> List Mask (out)`

) to divide the list into two lists: frames and panels, connecting `Inset Faces`

outputs into `List Mask (out)`

inputs,` Faces`

into `data`

and `Mask`

into `mask`

with level list equal `2`

. After that, we can visualise the panels and frames using two `Mesh Viewer`

nodes, one with the `dataTrue`

and the other with `dataFalse`

, both from `List Mask (out)`

faces outputs. It will filter the elements for us.

Now we have the face panels done. We can create a group for it `Crlt + j`

.

## Orienting floors plans in the XY plane

To add more value to this exercise, we can orient all the floors plans into the XY plane to compare the sizes of each floor plan and check how it was affected by the scale transformation.

First, we create a plane using the `Plane`

(`Generator -> Plane`

) node. We choose the method `Num`

, then set values for `Step X`

and `Step Y`

that can fit the size of the floor plans, for instance, `30`

. Clicking on the `Matrix`

option will automatically connect a `Matrix In`

component. Then, we can slide the `X`

axis in the `Location`

parameter for better visualisation. Finally, we increase the numbers of `Num X`

and `Num Y`

to ensure that the number of divisions can include all generated floor plans. For instance, in this example, the numbers used are `8`

and `6`

. Also, we use `Viewer Draw`

to visualise all modifications.

Then, we use the node `Origins`

with the method `Faces`

to get the centre of each division. Then, `Matrix In`

to get its location.

Next, we use the node `List Match`

(`List -> List Main -> List Match`

), which combines the list together. This is a very important node to control the structure of our lists. We are going to use the method `Short`

which given two lists of different sizes, it will give outputs for both lists based on the shortest list. For example:

**Input lists**

`list 1 = [a,b,c,d,e,f,g]`

`list 2 = [1,2,3,4]`

**Output lists with the method Short**

`list 1 output= [a,b,c,d]`

`list 2 output= [1,2,3,4]`

There are other methods for combination, but we can explore them in another opportunity. So, we combine the `matrix`

output from `Matrix In`

and the `vertices`

from the floors plan `Matrix Apply`

. Also, we use `Viewer Draw`

to visualise the floor plans oriented into the centre of the plane faces.

Then, we use `Matrix Apply`

to make the changes permanent.

After applying the transformations, we use `Vector Out`

(`Vector -> Vector Out`

) to deconstruct the vector into its values `X`

, `Y`

, `Z`

, because we need to make the `Z`

value equal `0`

for all vertices to put all floor plans into the `XY`

plane. We connect `X`

and `Y`

values into a `Vector In`

node, leaving the `Z`

value as `0`

.

Then we create a group with these nodes `Ctrl + j`

.

## Logic Operator to check floors plans

Now, we can test the size of the floors plans based on a given area and give a visual output when it passes the threshold. For instance, we can say to make the floor plans red when the area is smaller than `100`

m2 and make it green when it is greater than `100`

m2.

In this exercise, we explore an example of how we can give a visual output based on logic operators. First, we need to get the area for the floor plans we use the `Area`

(`Analyzers -> Area`

) node. We can use a `Stethoscope MK2`

(`Text -> Stethoscope MK2`

) node to check its values. We connect the output from `vertices`

from `Vector In`

into input `Vertices`

and the output `Faces`

from `Matrix Apply`

into input `Polygons`

.

Now, to check if the area of the floor plans is smaller than `100`

m2. We use `Logic Functions`

(`Logic -> Logic Functions`

) node with the `<`

operator. We connect the output from `Area`

into `X`

, and we define `100`

for the `Y`

value. It will return a list with `True`

or `False`

according to the results. We can use it later to mask the list that contains the floor plans according to these boolean values.

To use it as a mask for the floor plans, we need to make this list of boolean values flat, which means put all the values into its level `0`

. To do that we use `List Levels`

(`List -> List Struct -> List Levels`

) node. We click in the check box `Flatten`

to make this list flat and `Wrap`

to add a level (an additional bracket) wrapping the list.

Now, we use `List Mask (out)`

to mask the values of the vertices from the floor plans according to the boolean list. We connect the `Vector In`

vertices into the input `data`

and output `data`

from `List Levels`

into `mask`

input. Then, we use two `Viewer Draw`

nodes, one to visualise the red when it is smaller than `100`

m2 and the other one to visualise green when it is greater than `100`

m2.

It is time to group the logic operators `Ctrl + j`

.

## Save a SVG drawing

This step is specific to the Sverchok algorithm. in Sverchok, we have native nodes that make it possible to create drawings from our design and save them as a svg file, which is an open format to store vectors. So, we can save a file the floor plans as SVG and then open in an external favourite Free Software CAD/BIM (FreeCAD, LibreCAD), Vector (Inkscape), or Image manipulator (Gimp, Krita), depending on the purpose that we want to give to this drawings.

Here we are going to create the floors plans with its area as a text. First, we need to convert the `Area`

output that are floating numbers into integers. We use `Float to Int`

(`Numbers -> Float to Int`

), then we need to convert this int number into a string containing the symbol `m2`

. We use a `Formula`

node to do that containing: `str(x) + " m2"`

.We can visualise the results with a `Stethoscope`

node.

Now, we create the structure of the SVG text using `Text SVG`

(`SVG -> Text SVG`

). As the text input, we use the output from the `Formula`

node, and we create an `Origins`

node to get the centre of the floor plans to define the origin of the text connecting its output into the input `Location`

.

Now we can create the floor plans using `Path SVG`

(`SVG -> Path SVG`

), connecting the vertices from the floor plans into the input `vertices`

and then click on the `Fill/Stroke`

button to create a `Fill/Stroke`

(SVG -> Fill/Stroke) node already connected to it. Then, we define `Fill`

as `None`

and `Stroke`

as `Flat`

, defining `Stroke Width`

as `0.3`

. It will create the silhouette of the floor plans.

Now we need to combine the SVG lists `Path SVG`

and `Text SVG`

into a single list. We use `List Join`

(`List -> List Main -> List Join`

) with the method `Mix`

to interpolate the values of the lists.

Now, we are going to create the SVG. We use `SVG Document`

(`SVG -> SVG Document`

), defining `Width`

as `297`

and `Height`

as `210`

to make it an A4 landscape standard. We can keep the `Unit`

as `mm`

, then change `Scale`

to `1`

. We click on `Folder Path`

to create a `File Path`

(`Network -> File Path`

) node, defining the location to save the SVG file. Then, we connect `data`

output from `List Join`

into `SVG Objects`

. Also, we can define a name for the SVG file, and then we can click into `Open Server`

, which will open a web browser tab showing in real-time the SVG file.

Now we can fix the text size.

We need to centralise the text into the floor plans. We can deconstruct from `Origins`

subtracting from `X`

values. We use `Vector Out`

, `Scalar Math`

(`Number -> Scalar Math`

) with the `Sub`

operator, and `Vector In`

.

Now we can create a group with this last step `Ctrl + j`

.

We can change the position of `Empty Object`

to explore the changes in the facade panels.

We can also change the parameter to see how it affects the form and floors plans.

We can change the facade materials in Blender to better visualise them into a rendered view, but we can keep it for a future tutorial about Blender.

You can download the blend file here

Have fun.