Hi All,
I’m working on a way to automate the creation of a new “Scenario” in Revit.
It goes like this:
- Create new area scheme
- Create area plans and copy over boundaries to new scheme
- Copy areas from Existing (also known as Rentable) to new scheme
So far, I have been able to do the first two tasks, but get an error copying over the Areas:
As far as I can tell my arguments are correct, according to the API the <class ‘list’> is a list of Element Ids, of course.
Looking at previous posts here and here, it appears my syntax is correct and it has all the references.
I tried both the Spring and RIE nodes, but after various attempts at different list configurations either got nothing or duplicate areas on the source view. Since they have not been updated to CPython/Revit 2022, maybe that’s why? If there are any up-to-date packages out there, I am open to that, but if not, it’s Python or bust.
Except for copying areas, you should be able to create an areascheme (called “Whatever”), create areaviewplans for the new scheme and copy over area boundaries from a model (if your Rentable area scheme is named “Existing”).
Here is the code. Props to @jacob.small and @c.poupin for their snippets!
#Python CopyAreasToNewScenario
import sys
import clr
clr.AddReference("System")
from System.Collections.Generic import List
from itertools import compress, repeat, groupby
from operator import itemgetter
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
import Revit.Elements as RE
#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 *
clr.AddReference("RevitAPIUI")
from Autodesk.Revit.UI import *
import System
from System.Collections.Generic import *
#get the current document in Revit.
doc = DocumentManager.Instance.CurrentDBDocument
run = IN[0] #input for the run control
if not run: sys.exit("\r\r\t\tSet Run to True\r\r") #a toggle to run the code or not
levels = []
all_Levels = FilteredElementCollector(doc) \
.OfCategory(BuiltInCategory.OST_Levels) \
.WhereElementIsNotElementType() \
.ToElements()
level_names = [l.Name for l in all_Levels]
#Create existing Areaplan view dictionary
all_views = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()
views = []
for v in all_views:
if not v.IsTemplate:
if (doc.GetElement(v.GetTypeId())).get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_NAME).AsString() == "Existing":
if not v.Name == "R001":
if not v.Name == "S001":
views.append(v)
viewNames = []
for view in views:
viewNames.append(view.Name)
viewDict = {viewNames[i]: views[i] for i in range(len(viewNames))}
#create new areascheme dictionary
newViews = []
for v in all_views:
if not v.IsTemplate:
if (doc.GetElement(v.GetTypeId())).get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_NAME).AsString() == "Whatever":
if not v.Name == "R001":
if not v.Name == "S001":
newViews.append(v)
newViewDict = {viewNames[j]: newViews[j] for j in range(len(viewNames))}
#collect all Area Schemes in the project
schemes = FilteredElementCollector(doc).OfClass(AreaScheme).WhereElementIsNotElementType().ToElements()
schemelst = []
#Get Existing areascheme
for s in schemes:
if s.Name == 'Existing':
exScheme = s
exSchemeNm = exScheme.Name
exSchemeId = exScheme.Id
pvp = ParameterValueProvider(ElementId(BuiltInParameter.AREA_SCHEME_ID))
fne = FilterNumericEquals()
ruleValue = exSchemeId
fRule = FilterElementIdRule(pvp, fne, ruleValue)
filter = ElementParameterFilter(fRule)
#Filter Areas based on Existing scheme
exstAreas = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Areas) \
.WherePasses(filter).WhereElementIsNotElementType().ToElements()
areaLvlNames = []
areaIds = List[ElementId]()
areaLevelsIds = []
for area in exstAreas:
areaId = area.Id
areaLvlName = area.Level.Name
areaLvlNames.append(areaLvlName)
areaIds.Add(area.Id)
gpLevelNames = [list(i) for j, i in groupby(areaLvlNames)]
areaLevelsNms = zip(areaIds, areaLvlNames)
areaGroups = groupby(areaLevelsNms, itemgetter(1))
areasByLvl = [[item[0] for item in data] for (key, data) in areaGroups]
#This zipped list is used for the CopyElements() arguments
levIds = zip(gpLevelNames, areasByLvl)
TransactionManager.Instance.EnsureInTransaction(doc)
newElems = []
for lnm, a in levIds:
l = lnm[0]
newElem = ElementTransformUtils.CopyElements(viewDict[l], a, newViewDict[l], None, None)
newElems.append(newElem)
TransactionManager.Instance.TransactionTaskDone()
OUT = newElems
ScenarioSetup_test.dyn (18.8 KB)
Any insight is appreciated!
Thanks,
@lorhal