Get all parameters associated with element using python

Hi all,

I want to get all the parameters like builtinparameters(instanceparameter) and project parameters associated with the element. Please let me know how to proceed with that ?

The following code will only give the project parameters. But I want to have all (BuiltInparameters+Project Parameters) associate with the element.

For Ex: If I take columns, it should give me all the instance parameters(which are builtin) and project parameters assigned to the columns).

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument

res = []
iterador = doc.ParameterBindings.ForwardIterator()
while iterador.MoveNext():
	res.append(iterador.Key.Name)
	
OUT = res

Please let me know how to do that ? Thanks in advance

1 Like

@shashank.baganeACM ,

can you not just Access via Element.Parameters at least you get the instance parameters

a = UnwrapElement(IN[0])
b = dir(IN[0])
c = dir(a)
OUT = a,c,b

KR

Andreas
2022-05-18_14h57_28

Taking a look at what you have, it looks like you’re getting parameters from the document, which would be why you only see BuiltInParameters and project parameters.

If you want to get all parameters from an element, you have to first identify what element you’re trying to retrieve parameters from. There’s a number of ways to do this, which one is best really depends on you situation.
From there, if we look at the API docs, you can see that Elements have a Parameter property. This will retrieve a set of all parameters associated with that element. You can iterate through this how you wish. If you’re looking to return the names of each parameter we can take a look at the Parameter Class, but you’ll see there is no “Name” property. Instead, we have to get the Definition first. The definition has a Name property we can use.

# Get your element however you want, just for this example I'm retrieving an element using the integer value of it's Id.
elem = doc.GetElement(ElementId(1234567))
params = elem.Parameters
# Get all the names and append them to the param_names list.
param_names = []
for p in params:
    param_names.append(p.Definition.Name)
# Alternatively to the for loop, in Python we can use list comprehension.
param_names = [p.Definition.Name for p params]
4 Likes

Hi @stewart.skyler @Draxl_Andreas Thanks for your support and responsr. I really appriciate that. I got the solution where in I get all the parameters like project parameters, Built In Parameters(type parameters and instance parameters).

# Get project parameters
res = []
iterador = doc.ParameterBindings.ForwardIterator()
while iterador.MoveNext():
	res.append(iterador.Key.Name)

# Get Builtin parameters
typefilter = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns).ToElements()

typecol = typefilter[0]

typeparams = typecol.Parameters

typeparamnames = []

for p in typeparams:
	typeparamnames.append(p.Definition.Name)
2 Likes
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('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

doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

#Preparing input from dynamo to revit

# Get project parameters
res = []
iterador = doc.ParameterBindings.ForwardIterator()
while iterador.MoveNext():
	res.append(iterador.Key.Name)

# Get Builtin parameters
typefilter = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns).ToElements()

typecol = typefilter[0]

typeparams = typecol.Parameters

typeparamnames = []

for p in typeparams:
	typeparamnames.append(p.Definition.Name)

i tested like this… i got an error, do you select your elements? @shashank.baganeACM
do have an OUTput?

3

Do you have any structural columns in your model?.
Worked fine for me after I changed BuiltInCategory.OST_StructuralColumns to BuiltInCategory.OST_Conduit since I have plenty of conduit in my model.

1 Like

Yes @stewart.skyler I have structural columns. I was trying to get parameters for structural columns
That’s great to hear that it got worked for you.

Sorry, I meant to reply to @Draxl_Andreas since theirs was encountering an error. lol

But yeah, the code looks good. One small tip if you’re not already aware - If you just want the first element from the collection you can use .FirstElement() instead of .ToElements(), which removes the need for this line typecol = typefilter[0].

Edit:
I also have a tendency, if I’m going to be using BuiltInCategory or BuiltInParameter a couple times, to shorten the name.
If you put something like bic = BuiltInCategory at the top of your code, you can then shorten BuiltInCategory.OST_StructuralColumns
to
bic.OST_StructuralColumns
Purely personal preference, just thought I’d mention it. :slight_smile:

2 Likes

@Draxl_Andreas The same thing that are trying the code I am trying.

I am not getting any errors

1 Like

Yeah @stewart.skyler That would be better and would be clean. Thanks for the suggestions man. I really appreciate that. From now onwards I’ll also try to follow like this. Cheers :beers:

1 Like

Hay @stewart.skyler I was just wondering like for this code can we modify if I want to get instance parameters then ?

Actually now I only get all the project parameters and type parameters ( BuiltIn). But I want to add instance parameters too.

what I have done is like

#Get all the instance parameters.
eleid = UnwrapElement(IN[0]).Id
elem = doc.GetElement(eleid)
params = elem.Parameters
# Get all the names and append them to the param_names list.
param_names = []
for p in params:
    param_names.append(p.Definition.Name)

TransactionManager.Instance.TransactionTaskDone()

I want to collect collect all the instance elements in active view and then pick only one element to apply my above pasted code to get all the instance parameters. So can we do it python ? Please let me know how do I do it in python itselft to avoid input IN[0]

So the .Parameters property will retrieve all parameters associated with that element, including project parameters. So long as the project parameter is assigned to that category (In your case I’m assuming Structural Columns). If you want to also retrieve the type parameters, you have to first retrieve the type. In the API, types are generally referred to as “symbols”.

To put this into action, let’s assume your elem variable is a FamilyInstance. When you call the .Parameters method, you will get all the parameters like I already mentioned, but not the parameters of the family type, as you have noticed.
To get the type parameters, we have to first get the FamilySymbol, and then use the .Parameters property on that.
So, how do you get the FamilySymbol from the FamilyInstance? It’s actually pretty easy. If we look through the various properties of the FamilyInstance class, you will see one labeled symbol.
Putting this all together:
elem.Symbol.Parameters
Will return the type parameters for that element.

I want to collect collect all the instance elements in active view and then pick only one element to apply my above pasted code to get all the instance parameters. So can we do it python ? Please let me know how do I do it in python itselft to avoid input IN[0]

This depends on what exactly you’re looking for. If you want to prompt the user to select something, you can use the selection method of uidoc.Selection.PickObject().

If you just want to do what you were already doing with the FilteredElementCollector, and then just grabbing whatever the first item is, but narrowed down to your ActiveView. the FilteredElementCollector Class actually has a couple of different constructors.


Take a look at the second one on that list. The description says “Constructs a new FilteredElementCollector that will search and filter the visible elements in a view.”
Sounds a lot like what we’re looking for right? If we open it up, we’ll see that if you input the ElementId of a view, it’ll only look at elements in that view.
Similarly, the third constructor does the same thing but with a list of ElementIds instead.
So, once again, putting that all together:

active_view = doc.ActiveView
FilteredElementCollector(doc, active_view.Id)

Will create a collector that only looks through the elements in your active view.


We’re starting to get deep into API territory. If you haven’t already seen this, I’d read through the Dynamo Python Primer.

The primer will touch on this as well, but you’re also going to want to get familiar with navigating the website I’ve been linking to.

Finally, Jeremy Tammik’s blog is invaluable. There are a great many explanations and examples for just about everything in the API.
That said, everything here is written in C# so far as I’m aware, so you’ll have to get used to reading that and converting it to Python, but it’s doable with some practice.
https://thebuildingcoder.typepad.com/blog/about-the-author.html#2

4 Likes

Hi @stewart.skyler Thanks for the details and information. Finally I got all the parameters such as project parameters, instance parameters and type parameters.

I really appreciate that.

The final code will be:

import clr

import sys
sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')

import System
from System.Collections.Generic import *

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

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager 
from RevitServices.Transactions import TransactionManager 

clr.AddReference("RevitAPI")
clr.AddReference("RevitAPIUI")

import Autodesk 
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication 
app = uiapp.Application 
uidoc = uiapp.ActiveUIDocument

def tolist(obj1):
	if hasattr(obj1,"__iter__"): return obj1
	else: return [obj1]

TransactionManager.Instance.EnsureInTransaction(doc)

# Get project parameters
res = []
iterador = doc.ParameterBindings.ForwardIterator()
while iterador.MoveNext():
	res.append(iterador.Key.Name)

# Get Builtin parameters
col = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns).FirstElement()

typeparams = col.Parameters

typeparamnames = []

for p in typeparams:
	typeparamnames.append(p.Definition.Name)

#Get all the instance parameters.

elem = FilteredElementCollector(doc).OfClass(FamilyInstance).FirstElement()
params = elem.Parameters

param_names = []
for p in params:
    param_names.append(p.Definition.Name)

TransactionManager.Instance.TransactionTaskDone()

OUT = res, param_names, typeparamnames

If it’s working that’s good, but I noticed a couple things.
First
Your first variable typeparams is not storing type parameters. It’s storing the instance parameters of whatever the first Structural Column instance the collector found. If you want the type parameters we have to get the symbol of that element first.

Second
elem = FilteredElementCollector(doc).OfClass(FamilyInstance).FirstElement()
This line will grab the first FamilyInstance it finds. Which could be any family. Say you’re trying to get the parameters from a StructualColumn family. That line might select the a StructuralColumn family, it might also select, say, a Generic Model, or an Annotation, etc.
I bet if you set your out to OUT = elem.Category.Name it will probably not be what you were looking for.

So, the FamilyInstance class is very generic. Any element in your model, that you can find in this list:


Is a FamilyInstance. (Or at least, most of the time. There might be some edge cases here I’m not thinking of)

So, solutions.
For the first one, like I said, we need the symbol.
col.Symbol.Parameters will get you the type parameters of the element stored in col.
That said, this will get the type parameters for the first Structural Column the collector finds.
This stands to cause a couple of potential issues.

  1. The first element it finds could end up being a family type, instead of an instance of that family.

  2. If you have more than one type for your structural columns you’re going to have to figure out how to get the correct type before calling the parameters method.

For the second one, you can use your original collector to get the instance parameters.
col = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns).FirstElement()
but again, this is grabbing whatever that first structural column element that it finds is.

There are, of course, solutions to all of this, but me writing your code for you only does so much to help you.

1 Like

Thanks @stewart.skyler for the corrections for letting me know. I appreciate that.

1 Like