Extracting levels from multiple categories via python

Hi all,

I’ve managed to write a python script to extract level information for a couple of categories (Structural Framing, Structural Columns). However I’m wondering if this is the right/lean way to do it using multiple try/except statements as these categories are based on different built-in parameters. Please can you give me some pointer? Thanks, much appreciated in advance!

import clr

clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *

clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *

clr.AddReference('System')
from System.Collections.Generic import List

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

#Assign Document
doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

		
#Preparing input
elements = UnwrapElement(IN[0])

output = [ ]

#Transaction
TransactionManager.Instance.EnsureInTransaction(doc)

for e in elements:
	elem = []
	
	#Levels
	try:
		Level = e.get_Parameter(BuiltInParameter.LEVEL_PARAM).AsValueString()
	except:
		try:
			Level = e.get_Parameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM).AsValueString()
		except:
			try:
				Level = e.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).AsValueString()
			except:
				try:
					Level = e.get_Parameter(BuiltInParameter.FAMILY_LEVEL_PARAM).AsValueString()
				except:
					Level = "n/a"

	#Output
	elem.append(Level)
	
	output.append(elem)

TransactionManager.Instance.TransactionTaskDone()

OUT = output

Well - first - from what I see, you don’t need a transaction. A transaction is only needed when you are modifying the Revit data. You are just collecting information.

A better outline for the code would be to know what you are looking for based on the item type (Probably a particular built-in category.)
for e in elements:
if e is widgetA:
do stuff
elif e is widgetB:
do other stuff
elif e is widgetC:
etc.

Try except may get you what you want, but it can be difficult to debug and is a bit heavy handed.

1 Like

you can study element.level from clockwork :slight_smile:

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

def GetLevel(item):
	val = None
	if hasattr(item, "LevelId"): 
		val = item.Document.GetElement(item.LevelId)
		if val: return val
	if hasattr(item, "Level"):
		val = item.Level
		if val: return val
	if hasattr(item, "GenLevel"):
		val = item.GenLevel
		if val: return val
	if (item.GetType().ToString() in ("Autodesk.Revit.DB.Architecture.StairsRun", "Autodesk.Revit.DB.Architecture.StairsLanding")):
		item = item.GetStairs()
	if (item.GetType().ToString() == "Autodesk.Revit.DB.Architecture.Stairs"):
		try: return item.Document.GetElement(item.get_Parameter(BuiltInParameter.STAIRS_BASE_LEVEL_PARAM).AsElementId())
		except: pass
	if (item.GetType().ToString() == "Autodesk.Revit.DB.ExtrusionRoof"):
		try: return item.Document.GetElement(item.get_Parameter(BuiltInParameter.ROOF_CONSTRAINT_LEVEL_PARAM).AsElementId())
		except: pass
	if not val:
		try: return item.Document.GetElement(item.get_Parameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM).AsElementId())
		except: 
			try: return item.Document.GetElement(item.get_Parameter(BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM).AsElementId())
			except: 
				try: return item.Document.GetElement(item.get_Parameter(BuiltInParameter.SCHEDULE_LEVEL_PARAM).AsElementId())
				except: return None

items = UnwrapElement(IN[0])

if isinstance(IN[0], list): OUT = [GetLevel(x) for x in items]
else: OUT = GetLevel(items)
1 Like

Great, this is the exact example that i need! Thanks for the reminder :man_facepalming:

1 Like

Hi,

FYI, there is an Element Level node in the Genius Loci package that works with all the categories.

3 Likes

Many thanks for your response. I’m trying to learn python so just try to write some simple scripts. :grinning: