Saturday, April 21, 2012

Project Phase Two - Altering Revit's API


For the second phase of the project, I altered Revit's API to simulate the LED display that has made this building famous.  I knew that I wanted to create a semi-random assortment of red, blue, yellow, and purple panels, with a much heavier emphasis placed on blue and red panels.  Using the provided "CurtainPanels" C# code, I applied an algorithm that would assign a weighted probability to a panel's color based on the previous panel's color.

The first step was to assign red panels to the bottom 6 floors, because the actual structure has nothing but red panels on the bottom.  Next, I assigned a "weighted red" panel family to the next 6 stories where the panel's probability of being red was about 70% and its probability of being blue was about 30%.  The top portion of the structure is solid blue, so I simply assigned a blue panel to the top third of the structure.  Finally, I applied my algorithm to randomly assign colors to the panels.  This algorithm used counters (M1, M2, M3, and M4) inside the "for" loop to recognize what the previous panel's color was, then applied a probability for the current panel.  The flowchart below demonstrates the algorithm's method of determining a panel's color.



In C# language, this process looked like the following:


                j = random.Next(1, 1000);
                Material myMaterial = material.Duplicate("My Material " + m + "-" + n);

                if (M1 > 2)
                {
                    if (j <= 800)  // 80% chance it stays blue
                    {
                        myMaterial.Color = new Color(red1, green1, blue1);
                        M1 = 3;
                        M2 = 2;
                        M3 = 2;
                        M4 = 2;
                    }
                    else if (j <= 875) // 7.5% chance it changes to red
                    {
                        myMaterial.Color = new Color(red2, green2, blue2);
                        M1 = 2;
                        M2 = 3;
                        M3 = 2;
                        M4 = 2;
                    }
                    else if (j <= 950) // 7.5% chance it changes to purple
                    {
                        myMaterial.Color = new Color(red3, green3, blue3);
                        M1 = 2;
                        M2 = 2;
                        M3 = 3;
                        M4 = 2;
                    }
                    else // 5% chance it changes to yellow
                    {
                        myMaterial.Color = new Color(red4, green4, blue4);
                        M1 = 2;
                        M2 = 2;
                        M3 = 2;
                        M4 = 3;
                    }
                }
                else if (M2 > 2)
                {
                    if (j <= 500) // 50% chance it stays red
                    {
                        myMaterial.Color = new Color(red2, green2, blue2);
                        M1 = 2;
                        M2 = 3;
                        M3 = 2;
                        M4 = 2;
                    }
                    else if (j <= 875) // 37.5% chance it changes to blue
                    {
                        myMaterial.Color = new Color(red1, green1, blue1);
                        M1 = 3;
                        M2 = 2;
                        M3 = 2;
                        M4 = 2;
                    }
                    else if (j <= 950) // 7.5% chance it changes to purple
                    {
                        myMaterial.Color = new Color(red3, green3, blue3);
                        M1 = 2;
                        M2 = 2;
                        M3 = 3;
                        M4 = 2;
                    }
                    else // 5% chance it changes to yellow
                    {
                        myMaterial.Color = new Color(red4, green4, blue4);
                        M1 = 2;
                        M2 = 2;
                        M3 = 2;
                        M4 = 3;
                    }
                }
                else if (M3 > 2)
                {
                    if (j <= 500) // 50% chance it stays purple
                    {
                        myMaterial.Color = new Color(red3, green3, blue3);
                        M1 = 2;
                        M2 = 2;
                        M3 = 3;
                        M4 = 2;
                    }
                    else if (j <= 575) // 7.5% chance it changes to red
                    {
                        myMaterial.Color = new Color(red2, green2, blue2);
                        M1 = 2;
                        M2 = 3;
                        M3 = 2;
                        M4 = 2;
                    }
                    else if (j <= 950) // 37.5% chance it changes to blue
                    {
                        myMaterial.Color = new Color(red1, green1, blue1);
                        M1 = 3;
                        M2 = 2;
                        M3 = 2;
                        M4 = 2;
                    }
                    else // 5% chance it changes to yellow
                    {
                        myMaterial.Color = new Color(red4, green4, blue4);
                        M1 = 2;
                        M2 = 2;
                        M3 = 2;
                        M4 = 3;
                    }
                }
                else if (M4 > 2)
                {
                    if (j <= 100) // 10% chance it stays yellow
                    {
                        myMaterial.Color = new Color(red4, green4, blue4);
                        M1 = 2;
                        M2 = 2;
                        M3 = 2;
                        M4 = 3;
                    }
                    else if (j <= 400) // 30% chance it changes to red
                    {
                        myMaterial.Color = new Color(red2, green2, blue2);
                        M1 = 2;
                        M2 = 3;
                        M3 = 2;
                        M4 = 2;
                    }
                    else if (j <= 700)  // 30% chance it changes to purple
                    {
                        myMaterial.Color = new Color(red3, green3, blue3);
                        M1 = 2;
                        M2 = 2;
                        M3 = 3;
                        M4 = 2;
                    }
                    else // 30% chance it changes to blue
                    {
                        myMaterial.Color = new Color(red1, green1, blue1);
                        M1 = 3;
                        M2 = 2;
                        M3 = 2;
                        M4 = 2;
                    }
                }
                else  // Defaults to blue
                {
                    myMaterial.Color = new Color(red1, green1, blue1);
                    M1 = 3;
                    M2 = 2;
                    M3 = 2;
                    M4 = 2;
                }

where the counter "j" is used to assign a probability to each color.

The final product was acceptable, but still does not exactly match the structure.  This is because of the order that Revit numbers its panels.  If you'll notice, there are large clusters of like colors that span multiple floors.  If I were to code C# to simulate this effect, I would need to somehow check the color of the panel exactly one floor beneath the current panel.  Since there are 30 panels per floor, the M1, M2, M3, and M4 counters would actual check the (n-30)th panel rather than the (n-1)th panel.  Since I am not fully capable in C#, I could not figure out how to do this.

Nevertheless, the following two screenshots show the final product.






Below is a video describing my process:



Wednesday, March 21, 2012

Project, Phase One


Building Information

Torre Agbar is located in Barcelona, Spain and was completed in 2005.  In addition to being a landmark in the area and a symbol for the growing technological industry in Barcelona, it stands as an architectural masterpiece.  Its stunning façade is made of many thousands of windows that are lit up in a spectacular display of red, blue, green, yellow, white, and purple LED lights at night time.  Figure 1 below shows Torre Agbar’s night time display.

 
Figure 1: Torre Agbar's Night Time LED Display

Conceptual Mass

The conceptual mass was originally going to be a series of floors that would be extruded between each other to create the shape of the building.  I felt that this allowed the most flexibility in that the user could modify the dimensions of each floor.  When extruded, however, there were problems with continuity of the mass, so I had to scrap that idea.  Instead, I had to revolve a series of lines.  From looking at pictures of the structure, I could see that roughly half of the structure was a cylinder with straight edges, which then changed into a cylinder with slanted edges, then to a cylinder with a parabolic type shape, and finally into a semi-spherical cap.  So, I created this combination of lines and revolved about a center line.  This created the shape that I wanted, but it had problems when I tried to change geometric parameters.  My solution to this problem was to revolve each line individually so that there were essentially 4 separate masses sitting on top of each other.  At the same time, I locked each set of lines to reference lines so that I could easily change geometric parameters and have the masses adapt correctly.  Figure 2 below shows the lines used to create the mass.

 
Figure 2: Revolved Lines

The independent parametric values governing the height of each part are the story heights (constant for every floor except the first floor and the top floor), and integers that correspond to the numbers of stories for the straight and slanted parts of the structure.  The number of stories for the curved part is governed by the number of stories of the straight and slanted parts and the total number of stories, set at 33.  With these parameters, the height of each part is just the number of stories times the story heights.  At the bottom of Figure 2, there is a value called “Bottom Radius”, this is the radius of the base of the structure, and is a user defined parametric value.  The bottom radius of the slanted part is the same as the bottom radius, and the top radius of the slanted part is calculated using a trigonometric relationship between the height of the slanted part and the angle at which it is slanted, which is also a user-defined parametric value.   The bottom radius of the curved part is the same as the top radius of the slanted part, and the top radius of the curved part is a user-defined parametric value because the curved line does not have an easily definable equation.  Figure 3 below shows the revolved mass.

 
Figure 3: Revolved Mass

The following screenshots show how the shape looks when the parametric values outlined above are changed.  The mass in Figure 4 is the result of a changed bottom radius and radius for the cap.  The mass in Figure 5 is the results of changing the number of floors for the straight and slanted parts, 33 and 1, respectively.

 
Figure 4: Model When Radii are Changed

 
Figure 5: Model When Number of Stories is Changed

Mass Envelope

Once the conceptual mass was made, the surfaces were divided to incorporate the rectangular windows that are the defining feature of Torre Agbar.  The number of divisions per floor, both horizontal and vertical, is tied to a parametric value.  With these defined, the U and V grid for each face are calculated using the number of stories for each face and the number of divisions per floor.  After these were defined, the surface was created using rectangular curtain wall panels.  The curtain panel mass is shown below, and was edited to have a different color and to have mullions.  The result is the façade below in Figure 7.  Because the top of the structure is a cap, there was a problem getting panels to work.  This will be discussed in more detail in the problems section of this report.  Figure 8 shows a changed number of curtain panels.

 
Figure 6: Curtain Panel Conceptual Mass

 
Figure 7: Exterior Façade

 
Figure 8: Changed Number of Curtain Panels

Project

Once these were completed, they were loaded into a project.  At elevation view, levels were added for each floor, in addition to levels for the roofs of each story.  Once these were correctly placed, mass floors were added, and roofs and ceilings were put into each mass floor.  Then, to cover up the plenum space, walls were placed that ran from the roof to the bottom of the floor. Figure 9 below shows the elevation view of the building.

 
Figure 9: Elevation View

Since there were not very precise floorplans, I had to use some artistic integrity when I laid out my floorplan.  Figure 10 below shows the 2nd level floorplan.


Figure 10: Level 2 Floorplan

The red arrow above in Figure 10 was the location for the interior rendering shown below.

 
Figure 11: Interior Rendering

In addition to interior features, the topography was modeled.  Torre Agbar is located in an urban area, but for ease of the project, I modeled the topography as if it was located in a wooded area.  Figure 12 below shows an exterior rendering of the building, complete with the topographical features.


 
Figure 12: Exterior Rendering

Problems

As I stated before, the curtain panels would not appear at the top of the structure.  I think this is because the grid lines all converge to a point at the very top, making the materials overlap.  This could possibly be solved by having the grid lines stop before reaching the top.
When I completed the project, I did not realize that we needed to create an envelope, so the curtain system loaded into the project is from the project itself, not from the envelope.
Finally, I can’t change parametric values in the actual project without having troubles with my floors, so the video will show changed parametric values in the conceptual mass only.