Revit-API-07

/

/

/

revit-api/07-revit-api-parameters

Understand Parameters in Revit API

...

Revit-API-07

/

/

/

revit-api/07-revit-api-parameters

Understand Parameters in Revit API

...

Summary

By Now You Should All Know How to Select Your Elements

By now you should all know how to select your elements and how to read their properties and methods with REIT API. And that's already a huge step towards becoming a Power Revit hacker.

In this article, we're going to explore the next concept: how to work with parameters using the Revit API. This is a really, really important one, so I want you to pay really good attention during this lesson. You'll need to know how to get, how to read, and how to set parameter values in almost every single script that you're going to write.

It's not that complicated, and don't worry—I'm going to take you through all the steps. But first of all, let's start with an overview inside of Revit Lookup, and I want to show you what's going on inside parameters. Then we'll jump to code and try to do the same but with code, right?

Exploring Parameters with Revit Lookup

I'm already in the Revit project, it's the same file, and I'm just going to select maybe one wall, maybe also a door. Then we're gonna go to Add-Ins > Revit Lookup and click Snoop Selection.

In here, you can see I have two elements. One has the class of FamilyInstance, the other is a Wall. FamilyInstance is made for all loadable families (doors, windows, generic models, etc.). If I select the door, you can see the category is Doors.

Inside any of these elements, you’ll notice there's a property called Parameters. When I click on it, it opens a list of all instance parameters (e.g., area, comments, category, etc.). You can read properties and see what kind of values they return.

Instance vs Type Parameters

Keep in mind that when you work with an instance (a wall, a door, etc.) and go to Parameters, you're getting instance parameters only. However, if you want to get the type parameter, you need to:

  1. Find the type of that instance.

  2. Get that type’s parameters.

For example, you can search for GetTypeId on an element, which leads you to the WallType or Family Symbol (which basically stands for Family Type). Once you have the type, you can see all type parameters there.

This is a simple concept but can be confusing. When you get an instance, you get instance parameters. To get type parameters, you need the instance, then you get its type, and then you get type parameters. They’re two different objects in Revit API.

The Most Important Properties Inside Revit Lookup

When you open a parameter—let's say Comments—and look in Revit Lookup, you'll see several properties:

  • IsShared: tells you if the parameter is a shared parameter or not.

  • StorageType: parameters can have four storage types:

    1. String (just text)

    2. Integer (integer numbers)

    3. Double (numbers with decimals)

    4. ElementId (references to other elements, like a wall’s base level)

  • Value: how you read the parameter’s actual value depends on its StorageType. You might use:

    • AsString() for string-based parameters

    • AsInteger() for integers

    • AsDouble() for doubles (like areas and lengths, usually in internal Revit units—feet)

    • AsElementId() for parameters that store references to other Revit elements

  • AsValueString(): a common method to retrieve a text-based representation of the value (useful for quick checks).

Definition vs Parameter Values

Each parameter can have a Definition, which acts like a blueprint (storing name, built-in parameter enum, etc.). Then every individual element has its own values for these parameters.

If you see something like BuiltInParameter in the definition, that means it’s a built-in parameter (like ALL_MODEL_INSTANCE_COMMENTS). But if it says Invalid, it’s not built-in—it could be a shared or a project parameter.

Reading Parameter Values in Code

How do we apply all this in our Revit API code? Let’s jump right in. Below is a small snippet showing how we typically pick an element and list its parameters:

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

# For example, listing all parameters
for p in elem.Parameters:
    print('-' * 50)
    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))

When you run something like the snippet above, you’ll see the parameter name, the built-in parameter enum if there is one, and the parameter values in your console.

You’ll notice that if you have a length or area parameter, the internal value is in feet. That’s because Revit API uses feet for its internal units. But you already know how to convert them using UnitUtils.ConvertFromInternalUnits().

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:

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

If you want to convert the area to another unit (e.g., meters or centimeters), you can do something like this:

from Autodesk.Revit.DB import UnitUtils, UnitTypeId

area_m2 = UnitUtils.ConvertFromInternalUnits(area_value, UnitTypeId.SquareMeters)
area_cm2 = UnitUtils.ConvertFromInternalUnits(area_value, UnitTypeId.SquareCentimeters)

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 get_Parameter(BuiltInParameter.XYZ), you do:

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 simply not assigned).

Instance vs Type Parameters in Code

Instance parameters are read directly from the element (elem). Type parameters, on the other hand, are read from the element type. First, you get the type via:

elem_type = doc.GetElement(elem.GetTypeId())

Then, you read the parameters from elem_type. For example:

p_type_comments = elem_type.get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_COMMENTS)
type_comments_value = p_type_comments.AsString()

Be sure to check if a parameter exists before reading it. If you want type parameters, don’t forget you have to jump from the instance to the type.

Practice Makes Perfect

And that’s the basics about Revit API parameters on how to get and read their values. But to set parameter values, there’s one more concept you need to understand, called transactions. That’s exactly what we’ll talk about in the next lesson.

Practice Tip: I recommend you to go and actually practice this new skill on different elements (walls, doors, windows, etc.) and experiment with both built-in and shared parameters. Try instance and type parameters, because don’t forget—they’re related yet different objects in the Revit API. Practicing is where you will learn the most. You can watch me do it all day, but if you do it once yourself, you’ll learn far more.

Sneak Peek: Writing/Setting Values (Transactions)

Just a quick tease of what’s to come—setting parameter values requires you to wrap the action in a Transaction block, like so:

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() # 🔒

We’ll go into more detail in the next lesson about how transactions work and how to properly set parameter values. So, once you’re ready, I’m waiting for you in the next lesson where we’re going to talk a little bit more about transactions, how to make changes in Revit, and lastly, how to set values to your parameters. See you very soon!

HomeWork

⌨️ Happy Coding!

Questions:

What should I write in __init__.py file?

What should I write in __init__.py file?

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