Kinetic Facade design, with the ability to responds to solar exposure.

with the latest technological advancements in the field of smart building and kinetic architecture, today we’re able to design and document and erect buildings that are not only aware of their surrounding climactic and geographical context, but are in fact able to analyze and intelligently respond to those factors by a variety of ways, including physical modification of their individual architectural components for higher levels of optimization.

one such example of a kinetic building is the Kiefer Technic showroom located in Bad Gleichenberg, Austria. apart from the aesthetically interesting and visually pleasing collective form of the external parametric shading devices, the building’s smart facade also play a tremendous role in regulating the amount of solar radiation that the building is exposed to throughout the day, and all year long. this kind of design allows for higher flexibility during the building’s design phase, as well as providing well studied and deeply optimized solutions to the natural lighting and thermal comfort design problems. another extremely well known example of kinetic architecture is Al-Bahar Towers in Abu dhabi, UAE. in this blog post we’re going to explore the idea of kinetic architectural elements inside of Revit by creating a solar responsive facade that takes Geo-location, time and date information from our Revit model and adjusts itself in accordance to these parameters. so without further ado, let’s get started.

Kiefer Technic Showroom located in Bad Gleichenberg, Austria. it’s dynamic facade can be changed and altered in accordance with the external weather conditions, as well as individual user preference.

Required steps:

  1. Modeling the kinetic facade units as an adaptive component inside of Revit.
  2. Applying the facade elements to the building mass using Dynamo and Lunchbox.
  3. Collecting Geo-Location , date and time data from Revit and importing it into Dynamo.
  4. Using the ladybug package to calculate the sun path and sun’s angle of incidence on our building.
  5. Extracting orientation data from each instance of our panels family.
  6. Adjusting the adaptive component’s “openness” value based on it’s orientation and it’s angle with the sun.
ordinary adaptive components not corresponding to the sun…
Result: Smart panels that adjust according to sun’s position…

Step 1: modeling the adaptive component

We’ll start by creating the adaptive component family. the reason for choosing an adaptive family as opposed to a curtain panel family is that generally, adaptive families allow for more advanced and complex geometry, since they’re not dependent on a planar curtain wall to be deployed, the user can deploy them however they want with four clicks (once for every adaptive point). but in our case we’ll use Dynamo to programmatically place our components so it’s even easier. creating families in Revit is a rather wide topic on it’s own and well outside of the scope of this tutorial, so the reader is expected to have a basic knowledge of how adaptive families are created and how they’re controlled parametrically . with that being said, let’s get started. once we’re in the adaptive component modeling environment, proceed with creating the skeleton using a collection of points and reference lines as demonstrated in the figure bellow.

skeleton model for the adaptive component.

Now is a good time to introduce parameters, and the way they’re involved in the behavior of this family:

the parameters which drive this adaptive component and their formulae.

So we have about 7 vital parameters ( apart from aesthetic ones such as thickness and glass material). now we’ll understand each parameter’s purpose as well as their formula.

  1. Direction line Length: this line exists for data inquiry purposes only (we’ll get the panels’ orientation data from this). the length is irrelevant we’re only interested in the line’s direction, thus a value of 10mm is sufficient in our case.
  2. Offset: this parameter controls the height of the joint. it’s directly related to how “opened” the panel is. it’s calculated using the following formula: (length of the panel / 4) * openedRaw.
  3. Report (Length of the panel): this is a reporting parameter, meaning that it does not directly affect the family. rather, it provides us with important dimension information that will be used to calculate the other parameters. this particular reporting parameter provides the total length of the panels.
  4. Fold Parameter: this controls the position of the folding edge along the reference lines. it has the following formula: 0.5 * (1 – openedRaw)
  5. fold half: this is the position of the elbow along the reference curves, it’s always half the amount of Fold Parameter. it has the following formula: Fold parameter / 2.
  6. opened: this is a parameter between 0 and 100 that governs how “open” the panels is. it has no formula since this is the user input.
  7. openedRaw: this is the raw data that will be used in the other formulae, in other words this is the mapped version of Opened. it’s calculated using this formula: (opened – 0) / (100 – 0) * (0.75 – 0) +0 (the zeros are for demonstration purposes, but please do keep in mind that (0 to 100) is the range of user input and (0 to 0.75) is the allowed input range of the panels. I have mapped it in order to further streamline the process)

Now that we have all the parameters set correctly, the panel should be able to respond to user input ( Opened parameter):

Step 2: programmatically applying the panels to face

In this step, we’ll be using a custom Dynamo package called Lunchbox that mostly deals with surface tesselation. dividing a face into quads is still doable without this tool but it would take a considerable amount of time and effort. so I really recommend that you use this workflow instead:

Programmatically subdividing our surface into quads and applying our panels
  1. Selecting the desired faces.
  2. Creating a list out of them.
  3. Using Panel.PanelQuad from Lunchbox to tessellate the faces with the desired U and V values.
  4. Flattening the list with an amount of 2.
  1. feeding that list into AdaptiveComponent.ByPoints node in order to place our panels.
  2. Sometimes we need to shift the indices (to rotate the panels) or revers the list (to mirror the panels) based on the context.

Step 3: Collecting date, time and Geo-location data from Revit

In this stage and the next one, we’ll heavily rely on a custom set of Dynamo tools Called Ladybug. we’ll be using it to generate a sun path diagram within dynamo. this will enable us to conduct complex solar studies for our project. but before that could happen, we’ll have to extract some vital information from the model first:

Generating the location is relatively easy, all we have to do is to use a Construct Location node from Ladybug and feed the required information into it using built-in Dynamo for Revit nodes. the only problem here is that there is no readily available node to acquire the time zone. so we’ll have to resort to using some python code to do that. this is the required python script:

# Enable Python support and load DesignScript library
import clr
#not needed in this case
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

#extracting time zone information from sunSettings
sunSettings = IN[0]
timezone = sunSettings.InternalElement.TimeZone

OUT = timezone

Now that we have our location information, it’s time start working on our date and time data. for that we’ll be using a SunSettings.CurrentDateTime node. once we a have DateTime object, the rest is just a matter of extracting the right kinds of information using some more python:

# Enable Python support and load DesignScript library
import clr
#extracting the month
dateTime = IN[0]
month = dateTime.Month
OUT = month
#extracting the day
dateTime = IN[0]
day = dateTime.Day
OUT = day
#extracting the hour
dateTime = IN[0]
hour = dateTime.Hour
OUT = hour
#extracting the minute
dateTime = IN[0]
min = dateTime.Minute
OUT = min

Now we’re able to feed all of that newly acquired information into a Calculate HOY node from Ladybug and we’re ready to conduct our solar studies.

Step 4: Generating sun path and calculating sun’s angle of incident

  1. Here we use our Location and HOY information to generate a sun path diagram using Ladybug’s Sunpath node.
  2. We normalize the sun’s directional vector by dissolving it into it’s X and Y components and regenerating another vector with zero as it’s Z component.
Generated sun path diagram within Dynamo, we also acquired sun’s directional vector.

Step 5: Acquiring orientation data for every instance of our panel

Everything we’ve done up until now is useless if we don’t know which way our panels are facing, there are many ways to tackle this problem, finding the panel’s centroid and then extracting the normal of the original face at that point is a perfectly viable option, but I wanted something more universal, I didn’t want to deal with the surface on which our panels are hosted since that can get really laborious really fast. a better alternative is to store every panel’s orientation information in it’s geometry. remember we created a tiny 10mm geometrical line when modeling our panels? were you wondering what it’s purpose was? well, this is exactly why we created that line in the first place, to find out the panel’s orientation later on. now you might be asking why couldn’t we just process the whole geometry for every instance of the panels and use a normal vector on one of it’s forward oriented faces? well technically we could do that, but as you can imagine that would take a really long time to run, since we’d have to process a whole bunch of geometry, even those that we don’t really need. obviously this is not a very efficient way of solving this problem. therefore we’ll dive a little deeper into the Revit API in order to extract the line geometry only.

Orientation information of every panel
  1. Prompting the user to select a single instance of the panel.
  2. Finding the right family type for the selected element.
  3. Acquiring every instance belonging to the selected family type.
  4. flattening the list.
  1. Pyhton Code: looping through every element and acquiring it’s Curve based geometry only.
  2. Getting the start and end point of every line.
  3. generating vectors representing the orientation of every panel using Vector.ByTwoPoints.

Here is the Python code used to extract Curve based geometry from the panels:

# Enable Python support and load DesignScript library
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

elements = IN[0]
lines = []

for element in elements:
	element = UnwrapElement(element)
	opt = Options()
	geo1 = element.get_Geometry(opt)
	enum1 = geo1.GetEnumerator() ; enum1.MoveNext()
	geo2 = enum1.Current.GetInstanceGeometry()

	for obj in geo2:	
		if isinstance(obj, Curve):
			lines.append(obj.ToProtoType())

OUT = lines

Step 6: Adjusting the “openness” parameter of every panel based on their angle of incidence with the rays of the sun

Now that we have the sun’s direction as well as the direction of every shading device, we can easily calculate the angle that they have with one another. we’ll later map this angle to the minimum and maximum values that the Opened parameter can accept (0 and 100). this way we can adjust every panel based on how much of an angle it has with the normalized vector of the sun.

  1. calculate the angle between the sun’s directional vector and the orientation of the panels using Vector.AngleWithVector.
  2. get the minimum and maximum angles and map the remaining values to somewhere between 0 and 100 using Math.MapTo.
  3. edit the Opened parameter of the elements based on the values that our solar studies have generated.

Every time the user changes one of these parameters in the Revit model: location of the project, date and/or time of the day, the facade updates itself to better correspond to those changes.

Selecting Erbil, Iraq as our Project location inside of Reivt

We selected Erbil, Iraq as our project location for this example and generated results for the following hours of the day on July 22nd 2020:

  • 7:00 am
  • 9:30 am
  • 12:00 pm
  • 2:30 pm
  • 5:00 pm
  • 7:30 pm

As you can see It’s now extremely easy and efficient to generate different results with a few simple clicks. with this we come to the end of this blog post, I really hope that you gained something useful from this long read and that this will serve as an inspiration for you to keep on creating!