Let’s look at how Revit generates and stores building information. Having a firm understanding of Revit’s data model is very important when working with the data that is generated and managed by Revit. In this guide we will take a look at Revit’s data model and discuss it in detail. Other chapters will guide you in working with this data model using the Revit-aware Grasshopper components.

The Element DNA

The graphic below, shows the DNA of a single Revit Element . It works like a small machine that takes inputs, processes them, and generates geometry and data as outputs. Keep in mind that not every element has geometry. Some of these elements might only carry information.

So practically, we feed type and instance information into the family function, to generate the element metadata (including calculated properties) and geometry. Always keep in mind that the data we provide in Revit Family definition, and Type or Instance parameters, are used alongside the family logic to generate BIM data structure.

The generated elements are then stored in a Revit Document. They are also organized by a series of Containers, each with a specific purpose.

This is also a good place to mention Subcategories. They sound like an organization level right under the Category, but in practice, it is easier to think of them as a property of geometry rather than an organization level. When a Family function generates geometry, it can group them into subcategories of the main category. Their main purpose it to allow finer control over the graphical representation of each part of the geometry.

Elements & Instances

An often-asked question is What is an Element? Elements are the basic building blocks in Revit data model. Elements are organized into Categories. The list of categories is built into each Revit version and can not be changed. Elements have Parameters that hold data associated with the Element. Depending on their category, Elements will get a series of built-in parameters and can also accept custom parameters defined by user. Elements might have geometry e.g. Walls (3D) or Detail Components (2D), or might not include any geometry at all e.g. Project Information (Yes even that is an Element in Revit data model, although it is not selectable since Revit views are designed around geometric elements, therefore Revit provides a custom window to edit the project information). Elements have Types that define how the element behaves in the Revit model.

In Revit API, Elements are represented by the DB.Element and each element parameter is represented by DB.Parameter. The DB.Element has multiple methods to provide access to its collection of properties

 

Each element has an Id (DB.Element.Id) that is an integer value. However this Id is not stable across upgrades and workset operations such as Save To Central, and might change. It is generally safer to access elements by their Unique Id (DB.Element.UniqueId) especially if you intend to save a reference to an element outside the Revit model e.g. an external database. Note that although the DB.Element.UniqueId looks like a UUID number, it is not. Keep that in mind if you are sending this information to your external databases.

See Revit: Elements & Instances guide on how to work with Revit Elements and Instances using Grasshopper in Revit.

Parameters

Elements contain parameters so they can carry metadata. For example, height is a property of a Wall element and its value is carried by the Height Parameter. Let’s take a look at various parameter types that we encounter when working with Revit elements.

Built-in Parameters

These are the most obvious set of parameters that are built into Revit based on the element type. For example, a Wall, or Room element has a parameter called Volume. This parameter does not make sense for a 2D Filled Region element and thus is not associated with that element type.

Revit shows the list of built-in parameters in the Element Properties panel.

In Revit API, all the built-in parameters are represented by the DB.BuiltInParameter enumeration

Project/Shared Parameters

Revit allows a user to create a series of custom parameters and apply them globally to selected categories. The Element Properties panel displays the project parameters attached to the selected element as well.

Global Parameters

Global parameters are category-agnostic parameters that could be applied to a range of instance or type parameters across many different Revit categories.

 

See Revit: Parameters guide on how to inspect, read, and write Revit element instance and type parameters using Grasshopper in Revit.

Categories, Families, & Types

As the above graphic shows, Revit organizes the building components into Categories, Families, and Types. Let’s discuss each in more detail.

Categories

Categories are the highest-level groups. These categories are built into Revit and loosely organize the components by their function. There are also multiple category types in a Revit model:

  • Model categories e.g. Walls, Doors, Floors, Roofs, etc.
  • Analytical categories e.g. Analytical Surfaces, Structural Loads, etc.
  • Annotation categories e.g. Tags, Dimensions, etc.

There are many categories in each category type. Some argue that the Category Type is actually a higher-level organization but in practice, following the Categories, Families, and Types organization system is easier to understand and remember.

In Revit API, all the built-in categories are represented by the DB.BuiltInCategory enumeration and all the built-in category types are represented by the DB.CategoryType enumeration

Types

Before discussing Families, we need to discuss Types in Revit. There can be multiple types of elements under each of the Revit categories discussed above. For example a 3ft x 7ft single-panel door, is a door Type under the Doors category, or a 2x4 wood post is a column Type under the Structural Columns category.

Each type, can have a series of Type Parameters that modify the behavior or other aspect of that specific Type. When working with Revit, we tend to define or modify various Types and place instances of these types into the model. For example we can define a 3ft x 7ft single-panel door Type and place many instances of this type in the model. All these instances will follow the logic that is enforced by that specific type. However, Type definitions can also allow certain Instance Parameters to be modified to change the behavior or graphics of a specific instance.

Families

Now that we know what Types are we can discuss Families. There is big challenge with the Category and Type structure that we discussed above. There can be many many various types in a Revit model and they can be radically different from each other. For example we can have hundreds of door types with various designs and sizes. A garage door is vastly different from a single-panel interior door. So we need a way to organize these types into related groups:

  • System Families are named groups e.g. Duct System or Basic Wall

  • Custom Families (or Loadable Families) are far more complex. They are a way to create custom types with custom design, and behavior. For example you can create a new table family that looks like a spaceship, is hovering over the floor, and can show 6 to 12 chairs depending on the desired configuration. Revit Family Editor can be used to define new custom families based on a family template file (*.rft). Custom families can be stored in external family files (*.rfa) and be shared with other Revit users. In-Place Families are a simplified variation of the custom families, specifically created for geometry that has limited use in a model.

The name, System Families, has led to a lot of confusion among Revit users. Remember, System Families are just a name given to a related group of types. They are vastly different from Custom Families and can NOT be stored in external family files. As Revit users or Revit programmers we generally do not deal with System Families and Revit API does not support creating or modifying the System Families as of yet either. Hence when discussing Revit, it is quite common to refer to Custom Families simply as Families

In Revit API, Custom Families are represented by the DB.Family, their various types are represented by DB.FamilySymbol, and each instance is represented by a DB.FamilyInstance

Defining new custom families is not a trivial task especially if they need to be smart and flexible to adapt to multiple model conditions, and is arguably one of the most important automation topics in Revit. Most companies create their own set of custom families for various components that are often used in their models. There are also third-party companies that create custom families, or create family organization solutions.

To get you started, Revit installation provides a default set of these custom families based on the measurement system e.g. Imperial vs Metric and also provides many templates to help with creating new custom families from scratch.

See Revit: Types & Families guide on how to work with Revit Types, and Families using Grasshopper in Revit. To create more advanced families, see Revit: Custom Families will guide you through automating creation of such families using Grasshopper in Revit.

Containers

Revit Containers (e.g. Worksets, Design Options, etc.) are a mechanism to logically group a series of elements, and they each have a very specific usage. For example Worksets allow loading parts of the buildings only so collaboration and conflict resolution becomes easier. When loading a specific workset, the elements that are not part of that workset are not loaded.

See Groups, Worksets, Design Options, and Phases guides on how to work with each container type using Grasshopper in Revit.

In simplest terms, Revit Documents are collections of Revit Elements. A Revit Document can represent a building model (Revit Projects) or can represent an Custom Family definition (Revit Families).

See Revit: Documents guide on how to work with Revit documents, linked documents, and querying elements inside them using Grasshopper in Revit.