Advertisement
Guest User

Untitled

a guest
Mar 30th, 2017
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.13 KB | None | 0 0
  1. # Copyright(c) 2016, Team Awesome
  2.  
  3. import clr
  4. import sys
  5. import System
  6. from System import Array
  7. from System.Collections.Generic import *
  8. from math import ceil, floor
  9. import time
  10.  
  11. clr.AddReference("RevitAPI")
  12. import Autodesk
  13. from Autodesk.Revit.DB import *
  14.  
  15. # Import DocumentManager and TransactionManager
  16. clr.AddReference("RevitServices")
  17. import RevitServices
  18. from RevitServices.Persistence import DocumentManager
  19. from RevitServices.Transactions import TransactionManager
  20.  
  21. # Import ToDSType(bool) extension method
  22. clr.AddReference("RevitNodes")
  23. import Revit
  24. clr.ImportExtensions(Revit.Elements)
  25.  
  26. # Start Transaction
  27. doc = DocumentManager.Instance.CurrentDBDocument
  28. TransactionManager.Instance.EnsureInTransaction(doc)
  29.  
  30. clr.AddReferenceByName('Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c')
  31. from Microsoft.Office.Interop import Excel
  32. System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo("en-US")
  33. from System.Runtime.InteropServices import Marshal
  34.  
  35. pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
  36. sys.path.append(pyt_path)
  37.  
  38. #Declare variables
  39. start_time = time.clock()
  40. output=[]
  41. RunIt = IN[0]
  42. familyTypes=IN[1]
  43. elements=IN[2]
  44. templateFile=IN[3]
  45. sheetName=IN[4]
  46. outFile=IN[5]
  47. if outFile[-5:] != ".xlsx":
  48.     outFile+=".xlsx"
  49. roomList=IN[6]
  50. rooms=roomList[1]
  51. roomParam = roomList[0]
  52. elementParams=IN[7]
  53. headers=IN[8]
  54. sheetLimiter=IN[9]
  55. roomOutputNr=IN[10]
  56. columnPrint=IN[11]
  57. rowPrint=IN[12]
  58.  
  59. #always add new stuff at the bottom so you dont need to change the indexes around
  60.  
  61. #sets up excel file
  62. def SetUp(xlApp):
  63.     # supress updates and warning pop ups
  64.     xlApp.Visible = False
  65.     xlApp.DisplayAlerts = False
  66.     xlApp.ScreenUpdating = False
  67.     return xlApp
  68.  
  69. def ExitExcel(filePath, xlApp, wb, ws):
  70.     # clean up before exiting excel, if any COM object remains
  71.     # unreleased then excel crashes on open following time
  72.     def CleanUp(_list):
  73.         if isinstance(_list, list):
  74.             for i in _list:
  75.                 Marshal.ReleaseComObject(i)
  76.         else:
  77.             Marshal.ReleaseComObject(_list)
  78.         return None
  79.    
  80.     wb.SaveAs(unicode(filePath))
  81.     xlApp.ActiveWorkbook.Close(False)
  82.     xlApp.ScreenUpdating = True
  83.     xlApp.Quit()
  84.     CleanUp([ws,wb,xlApp])
  85.     return None
  86.  
  87. #searches worksheet for a value and returns that value's position in the worksheet
  88. def searchVal(ws, key):
  89.     originX = ws.UsedRange.Row
  90.     originY = ws.UsedRange.Column
  91.     boundX = ws.UsedRange.Rows(ws.UsedRange.Rows.Count).Row
  92.     boundY = ws.UsedRange.Columns(ws.UsedRange.Columns.Count).Column
  93.     xlAfter = ws.Cells(originY, originX)
  94.     xlLookIn = -4163
  95.     xlLookAt = "&H2"
  96.     xlSearchOrder = "&H1"
  97.     xlSearchDirection = 1
  98.     xlMatchCase = False
  99.     xlMatchByte = False
  100.     xlSearchFormat = False
  101.     cell = ws.Cells.Find(key, xlAfter, xlLookIn, xlLookAt, xlSearchOrder, xlSearchDirection, xlMatchCase, xlMatchByte, xlSearchFormat)
  102.     if cell != None:
  103.         cellAddress = cell.Address(False, False)
  104.         addressX = xlApp.Range(cellAddress).Row
  105.         addressY = xlApp.Range(cellAddress).Column
  106.         result=[]
  107.         result.append(addressX)
  108.         result.append(addressY)
  109.         return result
  110.     return False
  111.  
  112.  
  113. #gets room information based on the parameter we sent in
  114. def roomInfo(elem):
  115.     info = {}
  116.     uElement = UnwrapElement(elem)
  117.     try:
  118.         for room in rooms:
  119.             info[room]=0
  120.         for j in uElement:
  121.             for phase in doc.Phases:
  122.                 if j.CreatedPhaseId == phase.Id:
  123.                     try:
  124.                         room = j.Room[phase]
  125.                         for p in room.Parameters:
  126.                             if p.Definition.Name == roomParam:              
  127.                                 geonum = p.AsString()
  128.                                 info[geonum]+=1
  129.                     except:
  130.                         continue
  131.     except:
  132.         pass
  133.     return info
  134.    
  135. #checks design option, and returns only those elements in Main Model or primary
  136. def desOpts(elem):
  137.     if elem.GetParameterValueByName("Design Option") == "-1":
  138.         return True
  139.     try:
  140.         if "primary" in elem.GetParameterValueByName("Design Option").InternalElement.Name:
  141.             return True
  142.     except:
  143.         return False
  144.     return False
  145.  
  146. def elDictionary():
  147.     elDict = {}
  148.     for elem in elements:
  149.         if desOpts(elem):
  150.             type = elem.GetParameterValueByName("Type Id")
  151.             if type not in elDict:
  152.                 elDict[type] = []
  153.             elDict[type].append(elem)
  154.     return elDict
  155.  
  156. #resizes the images
  157. def scaleImg(maxWidth, maxHeight, imgWidth, imgHeight):
  158.     ratio = min(maxWidth/imgWidth, maxHeight/imgHeight)
  159.     return imgWidth*ratio, imgHeight*ratio
  160.  
  161. #replaces placeholder values in cells with actual values and adjusts row height
  162. def fixValues(ws, name, val):
  163.     char_width=1.55
  164.     position = searchVal(ws, name)
  165.     if position:
  166.         tc =  ns[counter].Cells(position[0], position[1])
  167.         lineBreaks = tc.Value.ToString().count('\n')
  168.         try:
  169.             num_chars = len(val)
  170.             chars_per_row = floor(tc.Width / char_width)
  171.             if num_chars * char_width > tc.Width:
  172.                 num_rows = ceil((num_chars*char_width) / tc.Width)
  173.                 tc.Value = val
  174.                 """tc.RowHeight = num_rows * tc.Height + (3 * num_rows)
  175.                tc.Style.WrapText = True
  176.                actualRows = tc.Rows.Count
  177.                lineBreaks = tc.Value.ToString().count(str(unichr(10)))
  178.                #lineBreaks2 = tc.Value.ToString().count(char(10))
  179.                output.append("Height is " +str(tc.Height))
  180.                output.append("Width is " + str(tc.Width))
  181.                output.append("Chars per row is " + str(chars_per_row))
  182.                output.append("Num rows is " + str(num_rows))
  183.                output.append("Width is " +str(tc.Width))
  184.                output.append("num chars is " + str(num_chars))
  185.                output.append("actual rows is " + str(actualRows))
  186.                output.append("linebreaks is " +str(lineBreaks))
  187.                #output.append("linebreaks2 is " +str(lineBreaks2))
  188.                output.append(repr(val))
  189.                output.append("*"*20)"""
  190.             else:
  191.                 tc.Value = val
  192.         except:
  193.             tc.Value = val
  194.  
  195. def getRoomPos(ws, name):
  196.     return searchVal(ws, name)
  197.  
  198. #replaces placeholder values in cells with actual values    
  199. def fixHeader(ws, name, val):
  200.     position = searchVal(ws, name)
  201.     if position:
  202.         tc = ws.Cells(position[0],position[1])
  203.         tc.Value = val
  204.  
  205. def fixHeaders(ws):
  206.     numHeaders = len(headers)
  207.     for index,key in enumerate(headers):
  208.         if index < numHeaders/2:
  209.             valIndex = index + numHeaders/2
  210.             fixHeader(ws, "#"+key+"#", headers[valIndex])
  211.  
  212. #gets rooms elements are in and counts totals
  213. def fixRooms(ws, elems):
  214.     roomData = roomInfo(elems)
  215.     roomString = []
  216.     row = 0
  217.     col = 0
  218.     roomPos = getRoomPos(ws, "#ROOMNR#")
  219.     try:
  220.         startRow = roomPos[0]
  221.         startCol = roomPos[1]
  222.     except TypeError:
  223.         pass
  224.         #output.append("Could not find #ROOMNR# in the template")
  225.     lastRow = None
  226.     try:
  227.         for index, room in enumerate(sorted(rooms)):
  228.             if roomData[room]>0:
  229.                 if roomOutputNr:
  230.                     s = "%s (%s)" % (room, str(roomData[room]))
  231.                 else:
  232.                     s = "%s" % (room)
  233.                 if s not in roomString:
  234.                     insertRow = startRow + row
  235.                     insertCol = startCol + col
  236.                     tc =  ns[counter].Cells(insertRow, insertCol)
  237.                     tc.Value =s
  238.                     lastRow = insertRow
  239.                     col +=1
  240.                     if len(rooms) < index+2 and sorted(rooms)[index+1][0] != room[0]:
  241.                         col = 0
  242.                         row +=2
  243.                     if col == 4:
  244.                         col = 0
  245.                         row +=1
  246.                     roomString.append(s)
  247.     except:
  248.         output.append("I found no rooms. Check input parameter for Room Element Collector!")
  249.     return lastRow
  250.  
  251. #this runs the boolean
  252. if RunIt:  
  253.     xlApp = Excel.ApplicationClass()
  254.     SetUp(xlApp)
  255.     xlApp.Workbooks.Open(unicode(templateFile))
  256.     wb = xlApp.ActiveWorkbook
  257.     ws = xlApp.Sheets(sheetName)
  258.     originalSheet = wb.Sheets(1)
  259.     ns = {}
  260.     counter = 0
  261.     fixHeaders(ws)  
  262.    
  263.     #Build an element dictionary we can use later:
  264.     elDict = elDictionary()
  265.  
  266.     #Let's iterate over all our family types we got in
  267.     for index, familyType in enumerate(familyTypes):
  268.         #Find all elements that belong to this family type
  269.         if familyType in elDict:
  270.             elems = elDict[familyType]
  271.             if len(elems) > 0 :
  272.                 originalSheet.Copy(after=wb.Sheets(wb.Sheets.Count))
  273.                 ns[counter] = wb.Sheets(wb.Sheets.Count)
  274.                 ns[counter].Activate
  275.  
  276.                 if familyType.GetParameterValueByName("Type Mark") != "":
  277.                     try:
  278.                         ns[counter].Name = familyType.GetParameterValueByName("Type Mark")
  279.                     except:
  280.                         output.append("Was unable to create sheet due to duplicate type marks\nThe type mark in question is: "+familyType.GetParameterValueByName("Type Mark")+"\nPlease check and correct the model.")
  281.                 else:
  282.                     ns[counter].Name = "FAIL"+str(counter)
  283.                     output.append("Type marks missing, correct your in data")
  284.            
  285.                 fixValues(ws, "#TOTAL#", str(len(elems)))
  286.  
  287.                 #Room counter
  288.                 lastRow = fixRooms(ws, elems)
  289.                 if lastRow == None:
  290.                     lastRow = 30                
  291.                 #Fix print area and set print area and header rows
  292.                 print_vals = columnPrint.split(":")
  293.                 print_start=print_vals[0]
  294.                 print_end=print_vals[1]
  295.                 ns[counter].PageSetup.PrintArea = print_start+"1:"+print_end + str(lastRow)
  296.                 ns[counter].PageSetup.PrintTitleRows = rowPrint
  297.                
  298.                 #Iterate over all the elementParams and replace the template placeholder values one by one
  299.                 for ep in elementParams:
  300.                     if ep == "Type Image":
  301.                         position = searchVal(ws, "#"+str(ep)+"#")
  302.                         if position:
  303.                             tc =  ns[counter].Cells(position[0], position[1])
  304.                             maxWidth=0
  305.                             for i in xrange(1,6):
  306.                                 tcc = ns[counter].Cells(position[0], position[1]+i)
  307.                                 maxWidth+=tcc.Width
  308.                             val = familyType.GetParameterValueByName(ep)
  309.                             fixValues(ws, "#"+str(ep)+"#","")
  310.                             try:
  311.                                 fp = val.GetParameterValueByName("Loaded from file")
  312.                                 w,h = scaleImg(maxWidth, tc.Height, val.GetParameterValueByName("Width"), val.GetParameterValueByName("Height"))
  313.                                 ns[counter].Shapes.AddPicture(FileName = fp, LinkToFile=False, SaveWithDocument=True, Left=tc.Left, Top=tc.Top, Width=w, Height=h)
  314.                             except:
  315.                                 pass
  316.                     else:
  317.                         val = familyType.GetParameterValueByName(ep) or elems[0].GetParameterValueByName(ep)
  318.                         fixValues(ws, "#"+str(ep)+"#", val)
  319.                 counter +=1
  320.             #This limits the number of sheets created if boolean is true            
  321.             if sheetLimiter == True and index>=9:
  322.                 break      
  323.     originalSheet.Delete()
  324.     output.append("success")
  325.     ExitExcel(str(outFile), xlApp, xlApp.ActiveWorkbook, ws)
  326.  
  327. else:
  328.     output.append("Run is disabled")
  329. exec_time = "Execution time was " + str(time.clock() - start_time) + "seconds"
  330. output.append(exec_time)
  331. OUT = output
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement