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: