Revit-API-07

/

/

/

revit-api/07-revit-api-parameters

Understand Parameters in Revit API

Revit is all about parameters, and it's very crucial that you understand how to work with them using Revit API.

Revit-API-07

/

/

/

revit-api/07-revit-api-parameters

Understand Parameters in Revit API

Revit is all about parameters, and it's very crucial that you understand how to work with them using Revit API.

Summary

Time to learn about parameters

By now you should all know how to select and read your elements with Revit API. And that's already a huge step towards becoming a pyRevit developer.

And now we are going to learn how to work with parameters using Revit API. And it's a very important concept, because you will often need to Get Read and Set parameter values of your elements in Revit.

So let's look into that.

Exploring Parameters in Revit

Before I show you how to code, let's explore parameters with Revit Lookup.

Select a few elements like a Wall and a Door and then go to Add-Ins -> Revit Lookup -> Snoop Selection. You will often start with Revit Lookup before opening code-editor and that's a good habit to develop.

Then look for a property called - Parameters. It will return you a ParameterSet, which is a list of instance parameters.

This will open up another window with a list of instance parameters on the left, and their properties and methods on the right.

And keep in mind that each parameter is based on Parameter class in Revit API.

Instance vs Type Parameters

Now, pay attention.

Because many misunderstand the difference between Instance and Type parameters in Revit API. It's very simple, but many overlook it.

💡You can only get instance parameters from an instance, and you can only get type parameters from a type.

For example:

Wall.Parameter -> List of Instance Parameters
Wall.WallType.Parameters -> List of Type Parameters

So to read type parameters of your wall, you need to get its WallType and then look into parameters.

It's a simple step, but many overlook it in Revit API because we don't even pay attention that we open WallType menu to read type parameters. Our brain kind of associated everything with the wall in Revit.

💡Tip: I prefer to use GetTypeId() method to get a type, because its more universal across all categories and better for beginners. But you can also use WallType properties for walls too.

Explore Parameters

Since all instance and type parameters follow the same structure, let me list the most important properties that you might need to use.

I will use variable p refering to a Parameter.

p.Definition.Name - Name of a Parameter
p.Definition.BuiltInParamter - Internal Name of a Built-in Parameter
p.Definition.VariesAcrossGroups- Is the value controlled inside of group or not
p.Definition.StorageType- Parameter's StorageType
It can be String, Integer, Double, ElementId.
p.Definition.IsShared- True/False if it's shared parameter

You can even iterate through all parameters and print all this information about each of them. Here is the code:

from Autodesk.Revit.UI.Selection import ObjectType

# 👉 Pick an Object
ref_pick_object = uidoc.Selection.PickObject(ObjectType.Element)
elem            = doc.GetElement(ref_pick_object)
elem_type       = doc.GetElement(elem.GetTypeId())

for p in elem.Parameters:
    print(p)
    print('Parameter Name: {}'.format(p.Definition.Name))
    print('BuiltInParameter: {}'.format(p.Definition.BuiltInParameter))
    print('VariesAcrossGroups: {}'.format(p.Definition.VariesAcrossGroups))
    print('StorageType: {}'.format(p.StorageType))
    print('Value: {}'.format(p.AsValueString()))
    print('IsShared: {}'.format(p.IsShared))
    print('-'*50)

Also, if you want to read the value from a parameter there are 5 different methods depending on parameter's storage type.

Usually you can logically think what is the right one based on the data parameter can store or by looking in the StorageType property.

Here are the methods:

p.AsString() - Read value of a String parameter (Text)
p.AsDouble() - Read value of a Double parameter (Float number)
p.AsInteger() - Read value of Integer Parameter (Integers and Yes/No)
p.AsElementId() - Read value of ElementId Parameter (Refers to other elements like Level, Material…)

p.AsValueString()- Read value as a String. This one will convert whatever value is stored into a string. It's not as commonly used, but it's best to check what kind of value you will get with Revit Lookup.


⚠️NB! You can find StorageType Property and StorageType Enumeration.

Enumeration contains all possible options (String, Double, Integer, ElementId)
Property, refers to other classes, so you can read its StorageType value.

For example, we can create an if-statement,
[if StorageType of a parameter is equal to StorageType.String] then do something.


Here is a code sample:

from Autodesk.Revit.UI.Selection import ObjectType

# 👉 Pick an Object
ref_pick_object = uidoc.Selection.PickObject(ObjectType.Element)
elem            = doc.GetElement(ref_pick_object)
elem_type       = doc.GetElement(elem.GetTypeId())

# Get Parameter Value
for p in elem.Parameters:    
    # Text Parameters
    if p.StorageType == StorageType.String:
        value = p.AsString() #String

    # Integer or Yes/No Parameters
    if p.StorageType == StorageType.Integer:
        value = p.AsInteger() #Integer

    # Numeric Parameters (Double = Float)
    if p.StorageType == StorageType.Double:
        value = p.AsDouble() #Float

    # Reference to other Elements (Level, Material, Host Element, etc.)
    if p.StorageType == StorageType.ElementId:
        value = p.AsElementId() #ElementId

    # Print Results
    print('Parameter StorageType: {}'.format(p.StorageType))
    print('Parameter Value: {}'.format(value))
    print('Parameter Type: {}'.format(type(value)))
    print('Parameter AsValueString: {}'.format(p.AsValueString()))
    print('-'*50)

⚠️ This code is just an example!

The code above explains you the difference between these methods and StorageType. But when you need to read parameter value, you would only use one of these methods since you will know what parameter type it holds.

Let's look more into reading Built-In and Shared Parameters.

Getting Specific Parameters (Built-In and Shared)

In practice, you don't always want to list all parameters. Often, you'll want to grab specific ones. Built-in parameters are accessed via their enumerations, while shared or project parameters are accessed by name.

Built-In Parameters

Here’s a short snippet that shows how you get, say, the Comments parameter and the Area parameter from a wall:

Getting Specific Parameter

In practice, you don't want to list all parameters.

Instead, you want to grab a specific one that you need in your script. And there are different ways to get your parameters depending if you work with:

  • Built-In Parameter

  • Shared Parameter

  • Project Parameter


Let's begin with built-in parameters.

Getting Built-In Parameters

There are many methods in Revit API to get a built-in parameter. The most common one is - element.get_Parameter(BuiltInParameter).

Notice that we need an argument - BuiltInParameter Enumeration. It's like a pulldown menu with hundreds of available parameters to choose from. You just need to know the right name.

To find the right name, you would normally look it up with Revit Lookup. Let's say that you want to find internal name for Comments.

  • Snoop Element with Revit Lookup

  • Open parameters and find 'Comments'

  • Go to Definition

  • Check the value in BuiltInParameter

This is what you get in case of Comments Parameter:

In case of Area you will see this:

As you can see sometimes it can be easy to find it logically, but other times it doesn't make as much sense. So therefore, always double-check with Revit Lookup.

Now once you know internal BuiltInParameter names, you can use the following code to get these parameters:

p_comments = elem.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS)
p_area = elem.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED)

And to get their parameter values you need to choose the right method. If it's a text parameter like 'Comments' then you will use AsString(), and in case of area it's a numeric value, so we use AsDouble().

You can always double-check the values you get or StorageType with Revit Lookup.

p_comments = elem.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS)
p_area = elem.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED)

# Reading those values:
comment_value = p_comments.AsString()  # It's a text parameter
area_value = p_area.AsDouble()         # It's a double parameter in feet

💡Tip: This method is not documented in Revit API Docs, because it comes from .NET Framework.

Convert Internal Units to Metric

⚠️NB: Revit API uses feet as internal units.

Since all units in Revit API are in feet, you might need to convert them to metric. Luckily there are 2 methods in UnitUtils we can use:

Here is a code example:

p_area   = elem.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED)
area_ft  = p_area.AsDouble()         # ⚠️ Revit API usese FEET!
area_m2  = UnitUtils.ConvertFromInternalUnits(area_value, UnitTypeId.SquareMeters)
area_cm2 = UnitUtils.ConvertFromInternalUnits(area_value, UnitTypeId.SquareCentimeters)
Summary: Getting Built-In Parameters

Let's put it all together so you can test it in your scripts.

#🔎 Read Built-in Parameter Values
p_com_value     = p_comments.AsString()
p_com_typ_value = p_typ_comments.AsString()
p_area_ft       = p_area.AsDouble()
p_area_m2       = UnitUtils.ConvertFromInternalUnits(p_area_ft, UnitTypeId.SquareMeters)
p_area_cm2      = UnitUtils.ConvertFromInternalUnits(p_area_ft, UnitTypeId.SquareCentimeters)


print('Comments: {}'.format(p_com_value))
print('Type Comments: {}'.format(p_com_typ_value))
print('{}ft'.format(p_area_ft))
print('{}m2'.format(p_area_m2))
print('{}cm2'.format(p_area_cm2))
print('---')

💡I highly encourage you to try getting other parameters. That's how you will learn x10 time more by actually experimenting.

Shared or Project Parameters

For shared or project parameters, which are not built-in, you need to retrieve them by name.

So instead of using p.get_Parameter(BuiltInParameter), we are going to use p.LookupParameter('ParameterName'. You can check it here in Docs.

Here is how to do it:

p_shared = elem.LookupParameter('EF_Param')  # Shared Parameter

⚠️NB! You might not find you parameter.

Since shared parameters are custom and have to be loaded in the project, it might be missing in the project, and you can get an error saying that you are trying to do something with a NoneType.

So, you have to check if you actually found the parameter before you try to read its values. Here is an example:

p_shared = elem.LookupParameter('EF_Param')  # Example name
if p_shared:
    shared_value = p_shared.AsString()
    print('EF_Param:', shared_value)
else:
    print('Parameter Missing...')

💡If LookupParameter returns None, that means the parameter doesn’t exist on that element (perhaps the element’s category doesn’t support it, or it’s not loaded in the project).

Instance vs Type Parameters with Python

Alright, how about Instance vs Type parameters?

As you remember they come from different elements.

Wall.Parameter -> List of Instance parameters
Wall.WallType.Parameters -> List of Type Parameters.

So we have to use the same logic with code.

# 👉 Pick an Object
ref_pick_object = uidoc.Selection.PickObject(ObjectType.Element)
elem            = doc.GetElement(ref_pick_object)  # Pick Wall Instance 
elem_type       = doc.GetElement(elem.GetTypeId()) # Get  Wall Type

# Get Instance Parameter
p_comments     = elem.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS)

# Get Type Parameter
p_typ_comments = elem_type.get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_COMMENTS)

# Display values:
print('Comments: {}'.format(p_comments.AsString()))
print('Type Comments: {}'.format(p_typ_comments.AsString()))
  • Pick a Wall

  • Get WallType

  • Get Instance parameter from Wall

  • Get Type parameter from Wall Type

  • Read their values

Spoiler: How to Change Parameter Values?

You will learn more about changing parameter values in the next lesson, because you will need to learn another Revit API concepts called Transactions.

It's like a guardian of your Revit projects that doesn't allow any accidental changes. It's great, especially for beginners, because you won't be able to break anything while you explore Revit API.

Here is a little spoiler of how to change wall offset, but I will explain it in more depth in the next lesson.

t = Transaction(doc, "Change Name")
t.Start()  # 🔓

p_base_offset = elem.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET)
new_value_in_feet = UnitUtils.ConvertToInternalUnits(1.69, UnitTypeId.Centimeters)
p_base_offset.Set(new_value_in_feet)

t.Commit() # 🔒

💡You can ignore this, as I will explain it in more depth in the next lesson.

HomeWork

Before we continue with setting parameter values I want you to practice.

Practice getting and reading parameter values. Choose another element with another category and read some values.

  • Get/Read Instance Built-In Parameter

  • Get/Read Type Built-In Parmaeter

  • Get/Read Instance Shared Parameter

  • Get/Read Type Shared Parameter

It really makes the difference when you try to do it yourself.

Pick some elements, explore it with Revit Lookup and choose a few parameters. And then Get and Read them with python so you can understand all the steps by doing it yourself.

Practice is the best way to learn it.

⌨️ Happy Coding!

Discuss the lesson :

P.S. Sometimes this chat might experience connection issues.

Use Discord App for best experience.

Discuss the lesson :

P.S. Sometimes this chat might experience connection issues.

Use Discord App for best experience.

Discuss the lesson :

P.S. Sometimes this chat might experience connection issues.

Use Discord App for best experience.

Unlock Community

The pyRevit Hackers Community is only available with pyRevit Hackers Bundle.
Upgrade Here to Get Access to the community and all pyRevit Courses.

Use coupon code "upgrade" to get 150EUR Discount as a member.

⌨️ Happy Coding!

Unlock Community

The pyRevit Hackers Community is only available with pyRevit Hackers Bundle.
Upgrade Here to Get Access to the community and all pyRevit Courses.

Use coupon code "upgrade" to get 150EUR Discount as a member.

⌨️ Happy Coding!

Unlock Community

The pyRevit Hackers Community is only available with pyRevit Hackers Bundle.
Upgrade Here to Get Access to the community and all pyRevit Courses.

Use coupon code "upgrade" to get 150EUR Discount as a member.

⌨️ Happy Coding!

© 2023-2024 EF Learn Revit API

© 2023-2024 EF Learn Revit API

© 2023-2024 EF Learn Revit API