I am trying to process data from Excel into Room Boundary Lines, per level, into an existing model.
The spreadsheet has Column A: Level Name, Column B: DesignScript String. I am using regex to convert the strings to model lines. The lines are then grouped by level.
Everything seemed to be going ok until dealing with the CurveArray(). The closest I got was to use a nested for loop into curvearray, but that produces a flat list. Since I want to put many curves on multiple levels, I need to separate them. I’ve tried dict, enumerate, various indents, but no dice.
Looking at the Clockwork node, it should be easy, as it only uses one for loop to create the CurveArray. Since the NewRoomBoundaryLine method requires a singular SketchPlane and View per CurveArray, is there some kind of list wrangling I’m missing?
import sys
import re
import clr
from itertools import groupby
#Import module for Revit
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
#import module for the Document and transactions
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
#import Revit API
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
#get the current document in Revit.
doc = DocumentManager.Instance.CurrentDBDocument
#get levels and level names
allLevels = FilteredElementCollector(doc) \
.OfCategory(BuiltInCategory.OST_Levels) \
.WhereElementIsNotElementType() \
.ToElements()
level_names = [l.Name for l in allLevels]
#Create Plane dictionary
planes = []
for level in allLevels:
elev=level.Elevation
point=XYZ(0,0,elev)
planes.append(Plane.CreateByNormalAndOrigin(XYZ.BasisZ,point))
planeDict = {level_names[i]: planes[i] for i in range(len(level_names))}
#Create view dictionary
all_views = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).ToElements()
views = []
for v in all_views:
if not v.IsTemplate:
if (doc.GetElement(v.GetTypeId())).get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_NAME).AsString() == "Floor Plan":
views.Add(v)
viewNames = []
for view in views:
viewNames.append(view.Name)
viewDict = {viewNames[i]: views[i] for i in range(len(viewNames))}
data = IN[0]
lines = []
lvlNames = []
levelsNlines = []
sPlanes = []
#regex code to map coordinates
regx = re.compile(r'((?:-)?\d+\.\d+)').findall
#convert strings to model lines
for lvl, str in data:
lvlNames.append(lvl)
if "Line" in str:
line = Line.CreateBound(XYZ(float(regx(str)[0])/12,float(regx(str)[1])/12,float(regx(str)[2])/12),XYZ(float(regx(str)[3])/12,float(regx(str)[4])/12,float(regx(str)[5])/12))
lines.append(line)
elif "Arc" in str:
arc = Arc.Create(XYZ(float(regx(str)[4])/12,float(regx(str)[5])/12,float(regx(str)[6])/12),float(regx(str)[7])/12,float(regx(str)[8])*0.0174533,float(regx(str)[9])*0.0174533, XYZ(1.0, 0.0, 0.0), XYZ(0.0, 1.0, 0.0))
lines.append(arc)
levelsNlines = zip(lvlNames,lines)
gline = []
group = []
gzip = []
groups = []
uniquekeys = []
glines = []
#group lines per level
for k,g in groupby(levelsNlines, lambda x: x[0]):
groups.append(list(g))
uniquekeys.append(k)
for group in groups:
gzip = zip(*group)
glines.append(gzip[1])
TransactionManager.Instance.EnsureInTransaction(doc)
#Create SketchPlane dictionary
sPlanes = []
for plane in planes:
sPlane = SketchPlane.Create(doc, plane)
sPlanes.append(sPlane)
sPlaneDict = {level_names[i]: sPlanes[i] for i in range(len(level_names))}
docCreation = doc.Create
#create curvearrays per level
curvearray = CurveArray()
for gline in glines:
for curve in gline:
curvearray.Append(curve)
for key in uniquekeys:
rLine = docCreation.NewRoomBoundaryLines(sPlaneDict[key], curvearray, viewDict[key])
TransactionManager.Instance.TransactionTaskDone()
elementList = []
for r in rLine:
elementList.append(rLine)
OUT = elementlist
Any insight is appreciated!