Monday, December 6, 2010

FINAL PROJECT: Accessing BIM Data

BRIEF DESCRIPTION OF THE PROJECT 

This project, originally, is composed of 3 buildings with 6 different S-shaped roofs. These roofs are different from each other but share the same parameters. Parametric modeling is a very good tool to achieve that kind of complexity in design problems. Radius and of the arcs are changing from one roof to other.

First two building is modeled under the aim of Project; both buildings have also two different S-shaped roofs. For this purpose, roof structure is designed parametrically that allows me to easily create/design indefinite variety of buildings with this roof, no matter the dimensions of the floors. However, I was not able to make changes or adjustments on roof in the project file. This was the obstacle of my roof parametric family.

 

 Therefore, for the final project, I moved to the next step which was to write an API code to handle this obstacle. Through using this code, I will be able to change the length of the roof according to the length of the floor beneath. The challenging part of this project is that the length of roof is calculated within the parametric family itself under the parameter name, "ARC1_LENGTH" OR “ARC2_LENGTH”, with the formula as in the Picture 01. Therefore, they are both the curved length not the projection on X axis. Consequently, changing the length of roof according to the change in length of floor will not give the right result for this project. 
 
 
 



To solve this problem, I do experiments on the length of projected roof on X axis and prepared a database. Each S-shaped roof consists of two arcs, and for each roof, the radius and length of these two arcs are changing.  This database includes angles of each arc, and shows the length increase or decrease according to the selected angle for each arc. Since angle value more than 45° seems not appropriate as a roof for this project, I put constraints for the value between 0° and 45°. 

 
Hence, I passed the parameters of roof family through the use of an excel sheet (database). Basically, this process dwells five steps:

(1)   Reading the Floor in project and getting its AREA parameter.
(2)   Converting the AREA to LENGTH through using the width of the floor.
(3)   Through using the LENGTH of floor, referring to the database and finding the appropriate length of Roof accordingly. To find the appropriate length of Roof, all the length values on excel sheet is tried by the program by loop function.
(4)   After deciding on the length of Roof, then picking the ANGLE of the roof.
(5)   Transferring this ANGLE of the roof to project and write it in the ANGLE parameter of Roof and adjusting roof.


 The important point before using this program is that since there are two codes for modifying one roof structure, one needed to be careful on the direction of the dragged floors and selecting the code. For instance, in the picture 2, if the floor is dragged to the right, code ARC2 should be run whereas if the floor is dragged to the left, code ARC1 should be run.






CODE FOR ROOF_ARC1


STEP1: Reading the Floor in project and getting its AREA parameter

            In the project Revit file, through using edit boundary option, you can basically dragging ground floors in order to either decrease or increase the length of the floors, and the value of their areas will be changed accordingly. If you know the modified floor length, we could calculate the appropriate change in the roof length. If we know the area of floor, we could divide the value into the width of the floor to get the length. 
 
ElementId idtemp1;//FOR FLOOR1
ElementId idtemp2;//FOR FLOOR2
                   
idtemp1 = new ElementId(446016);
idtemp2 = new ElementId(446244);
           
Floor Floors1 = doc.get_Element(idtemp1) as Floor;
Floor Floors2 = doc.get_Element(idtemp2) as Floor;



 

Therefore, all we need is to define the floors in the Visual C# program code by referring to their IDs and get their Area parameter to the code. 
 STEP2: Converting the AREA to LENGTH through using the width of the floor


 
I assumed that we only need to make changes on the roof length, not on the roof width. Thus, I fixed the width of floor width to 66 ft. Then, through the formula, we can get the value of modified floor lengths. However, it is easy to change the width of the floor through making the similar change on the code.
           
double newRoofLength1 = (Floors1.get_Parameter("Area").AsDouble()) / 66;
double newRoofLength2 = (Floors2.get_Parameter("Area").AsDouble()) / 66;

Therefore, windows that shows the value of the already existing curvic length of Roof 1 and 2 pop up. Then, their  expected/modified linear lengths are shown.





 

STEP3: Referring to the database and finding the appropriate length of Roof accordingly

            After calculating the length of the floor, code sets this length value as the new length of roof’s projection on X axis.  The important point is with each of the codes, we could only control/change either ARC1or ARC2 in each roof. In other words, could only control one arch of the each roof through fixing the angle of the second one. 
 
Then, it starts to read the data about length from Excel sheet to find the appropriate angle. I used the loop function which makes program to try all the related lengths and looping.
double lastCell = 0.0;
            double newAngle1 = 45.0/180.0*Math.PI;
            double newAngle2 = 45.0 / 180.0 * Math.PI;
double maximumDegree = 50.0 / 180.0 * Math.PI;
            double intervalDegree = 5.0 / 180.0 * Math.PI;
            int count = 0;


For the Roof 1, ARC2_ANGLE_B is fixed to 10°.
MessageBox.Show("searching for angle1....");//FOR ROOF1
      for (int i = 0; i < 50; i+=5)
            {
double cellValue = Double.Parse(ExcelDB("A10", "A" + i.ToString()));
            MessageBox.Show("cellValue : " + cellValue.ToString());
            MessageBox.Show("new Length of Modified Roof1: " + newRoofLength1.ToString());
            if (cellValue > newRoofLength1)
                {
                                        MessageBox.Show("count: " + count);
                    newAngle1 = count * 5.0 / 180.0 * Math.PI;
                    break;
                }
               count++;
            }
       MessageBox.Show("new angle1: " + newAngle1.ToString());
       roofAngle21.Set(newAngle1);
       roofAngle11.Set(10.0 / 180.0 * Math.PI);






  For Roof 2, repeats the same process:



int count2 = 0;

            MessageBox.Show("searching for angle2....");//FOR ROOF2
            for (int j = 0; j < 50; j += 5)
            {
                double cellValue2 = Double.Parse(ExcelDB("A15", "A" + j.ToString()));
                MessageBox.Show("cellValue : " + cellValue2.ToString());
                MessageBox.Show("new Length of Modified Roof2: " + newRoofLength2.ToString());
                if (cellValue2 > newRoofLength2)
                {
                   
                    MessageBox.Show("count: " + count2);
                    newAngle2 = count2 * 5.0 / 180.0 * Math.PI;
                    break;
                }

                count2++;
            }
           
            MessageBox.Show("new angle2: " + newAngle2.ToString());
            roofAngle22.Set(newAngle2);
            roofAngle12.Set(10.0 / 180.0 * Math.PI);
            //#endregion

            transaction.Commit();

            retRes = Result.Succeeded;
            return retRes;
        }




STEP4: Setting the ANGLE of the roof

            In order to apply the changes on the values of roof parametric family, we needed to define roofs and pass the parameters of roofs that we will use to modify the roofs.

                        ElementId id1;//FOR ROOF1
            ElementId id2;//FOR ROOF2
          
            id1 = new ElementId(441493);
            id2 = new ElementId(443937);
          
            FamilyInstance Roof1 = doc.get_Element(id1) as FamilyInstance;
            FamilyInstance Roof2 = doc.get_Element(id2) as FamilyInstance;
Parameter roofLength1 = Roof1.get_Parameter("TOTAL_LENGHT");
            Parameter roofLength2 = Roof2.get_Parameter("TOTAL_LENGHT");
            Parameter roofAngle11 = Roof1.get_Parameter("ARC1_ANGLE_A");
            Parameter roofAngle12 = Roof2.get_Parameter("ARC1_ANGLE_A");
            Parameter roofAngle21 = Roof1.get_Parameter("ARC2_ANGLE_B");
            Parameter roofAngle22 = Roof2.get_Parameter("ARC2_ANGLE_B");

            ElementId typeId1 = Roof1.GetTypeId();
            ElementId typeId2 = Roof2.GetTypeId();

            ElementType Roof1Type = doc.get_Element(typeId1) as ElementType;
            ElementType Roof2Type = doc.get_Element(typeId2) as ElementType;







STEP5: Transferring this ANGLE of the roof to project and write it in the ANGLE parameter of Roof and adjusting roof.

 Finally, according to the changing angle of the roof 1 and 2, in the project, roofs are modified.





CODE FOR ROOF_ARC2


This is the process for Code 1, now let's look at how Code 2 works. It is basically same as the Code 1. The main difference is their way of using Data sheet. Code 1 refers to the column whereas Code 2 refers to the row:



 Therefore, when we drag the floors and run the Code 2, it works as such


 


 
MessageBox.Show("searching for angle1....");//FOR ROOF1
            for (int i = 0; i < 50; i+=5)
                  {
                      double cellValue = Double.Parse(ExcelDB("A10", "A" + i.ToString()));
                MessageBox.Show("cellValue : " + cellValue.ToString());
                MessageBox.Show("new Length of Modified Roof1: " + newRoofLength1.ToString());
                if (cellValue > newRoofLength1)
                {
                   
                    MessageBox.Show("count: " + count);
                    newAngle1 = count * 5.0 / 180.0 * Math.PI;
                    break;
                }
               count++;
                  }
            MessageBox.Show("new angle1: " + newAngle1.ToString());
            roofAngle21.Set(newAngle1);
            roofAngle11.Set(10.0 / 180.0 * Math.PI);

            int count2 = 0;

 
CONCLUSION
I put constraints to the roof, no matter what the value of roof, if it is smaller or larger than the values on the Excel sheet, the roof is going to be either 0° or 45°.


FUTURE POSSIBLE APPLICATIONS

This kind of BIM applications provides us to create endless variety in buildings. Especially in residential design, most of the challenge that architects come across is to design houses that are varied from each other; unique for user. Through using  BIM, this project proves that through families and codes, we could end up with an endless variety in design.