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.
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
.
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.
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
Facesoutput into
Facesinput. Then, choosing the method
Facesof 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.
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
.
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
.
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
.
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.