Revit + Python

Revit – Automatic Model Upgrade

R

With Revit’s yearly release schedule, it’s not uncommon to upgrade models from one release year to the newest version.  This can be a time consuming process if there are a lot of models in a project – opening….waiting….saving….waiting….closing….repeat.  However, with pyRevit and a bit of Python coding, you can automate this process to cycle through an entire directory of files and ‘save-as’ over themselves to your current version.

Let’s look at an example of how we can do this, and I’ll go through each line and explain what is happening.  There are probably more efficient ways of doing this, but it gets the job done and was fairly quick to write. Here’s the code:

"""Open and save all Revit models in a folder (including subdirectories) 
from the model's current version to the open version of Revit."""

import os

from pyrevit import forms
from Autodesk.Revit.DB import (OpenOptions, ModelPathUtils, SaveAsOptions)

# sets button title, tool author, and ability to run with no open documents
__title__ = 'Update\nModel Version'
__author__ = 'Andrew Urban, Revision.Cloud'
__context__ = 'zero-doc'

# select folder of files to be updated
directory_contents = []
file_folder = forms.pick_folder(title = 'File Folder')
for root, dirs, files in os.walk(file_folder):
    for revit_file in files:
        if '.rvt' in revit_file:
            directory_contents.append(os.path.join(root, revit_file))

for revit_model in directory_contents:
    revit_model_path = ModelPathUtils.ConvertUserVisiblePathToModelPath(revit_model)
    open_options = OpenOptions()
    revit_document = __revit__.Application.OpenDocumentFile(revit_model_path, open_options)
    save_as_options = SaveAsOptions()
    save_as_options.MaximumBackups = 1
    save_as_options.OverwriteExistingFile = True
    revit_document.SaveAs(revit_model, save_as_options)
    revit_document.Close(False)

# delete backup files
delete_backups = []
for root, dirs, files in os.walk(file_folder):
    for revit_model in files:
        if '.0001.rvt' in revit_model:
            delete_backups.append(os.path.join(root, revit_model))

for remove_it in delete_backups:
    os.remove(remove_it)
  • Lines 1 and 2 ("""Open and save all Revit models in a folder (including subdirectories) from the model's current version to the open version of Revit."""):
    • These lines (in triple quotes) explain what the tool does. This will be the tooltip that displays when a user hovers over this tool button within Revit.
  • Line 4 (import os):
    • Imports the ‘os’ module. This allows easy interaction with folders and files within Windows.
  • Line 6 (from pyrevit import forms):
    • Imports ‘forms’ from pyRevit. This module contains various forms and dialog boxes.
  • Line 7 (from Autodesk.Revit.DB import (OpenOptions, ModelPathUtils, SaveAsOptions)):
    • From the Revit database, imports the classes necessary for this tool to run properly.
  • Line 10 (__title__ = 'Update\nModel Version'):
    • Using pyRevit’s syntax, ‘__title__ ‘ is the tool name that will be displayed on the Revit button. If no title is specified in the file, the button name will be equal to the python file name.
    • the ‘\n’ in the name will push the text that follows to the next line.
  • Line 11 (__author__ = 'Andrew Urban, Revision.Cloud'):
    • This line also follows some pyRevit syntax. The author of the tool will also be displayed in the tooltips that are shown when a user hovers over the button in Revit.
    • This line is optional within the code.
  • Line 12 (__context__ = 'zero-doc'):
    • A final bit of pyRevit syntax. If ‘__context__’ is set to ‘zero-doc’, the button will display correctly and be usable within Revit even if no files are open. If ‘__context__’ is not specified, the button will be greyed out when no files are open.
  • Line 15 (directory_contents = []):
    • Creates an empty list called ‘directory_contents’. This list will be filled with files once a directory is selected.
  • Line 16 (file_folder = forms.pick_folder(title = 'File Folder')):
    • ‘forms.pick_folder()’ is a pyRevit form that prompts the user to select a specific folder and returns a string containing the path to that folder. Once selected the variable ‘file_folder’ will equal that string.
  • Line 17 (for root, dirs, files in os.walk(file_folder):):
    • ‘os.walk()’ will iterate through the root, directories, and files within the specified folder.
  • Line 18 (for revit_file in files:):
    • Iteration through all of the files within a specified directory.
  • Line 19 (if '.rvt' in revit_file:):
    • Filtering files to isolate Revit files (.rvt)
  • Line 20 (directory_contents.append(os.path.join(root, revit_file)):
    • ‘os.path.join’ creates a string combining the file path and the file name.
    • combined path/file name is added to the directory_contents list.
  • Line 22 (for revit_model in directory_contents:):
    • Once the directory_contents library is complete, this line iterates through all of the files in the dictionary.
  • Line 23 (revit_model_path = ModelPathUtils.ConvertUserVisiblePathToModelPath(revit_model)):
    • ModelPathUtils.ConvertUserVisiblePathToModelPath() converts the file path string into a Model Path that Revit can read to open the individual Revit file.
  • Line 24 (open_options = OpenOptions()):
    • Creates an empty OpenOptions object that is used when Revit opens a model.
  • Line 25 (revit_document = __revit__.Application.OpenDocumentFile(revit_model_path, open_options)):
    • ‘__revit__.Application.OpenDocumentFile()’ uses the revit_model_path and the open_options to open the revit model in the directory_contents library.
  • Line 26 (save_as_options = SaveAsOptions()):
    • Creates an empty SaveAsOptions object that is used when Revit saves a model.
  • Line 27 (save_as_options.MaximumBackups = 1):
    • Sets the maximum number of file backups to 1 within the save_as_options.
  • Line 28 (save_as_options.OverwriteExistingFile = True):
    • Sets ‘OverwriteExistingFile’ to True, which allows the file to save over itself.
  • Line 29 (revit_document.SaveAs(revit_model, save_as_options)):
    • Saves the file over itself per the current, open version of Revit.
  • Line 30 (revit_document.Close(False)):
    • Closes the Revit file without saving it. (It was saved on the previous line of code).
  • Line 33 (delete_backups = []):
    • Creates an empty list called ‘delete_backups’. This list will be filled with Revit backup files to delete.
  • Line 34 (for root, dirs, files in os.walk(file_folder):):
    • ‘os.walk()’ will iterate through the root, directories, and files within the specified folder.
  • Line 35 (for revit_model in files:):
    • Iteration through all of the files within a specified directory.
  • Line 36 (if '.0001.rvt' in revit_model:):
    • Filtering files to isolate Revit backup files (.0001.rvt)
  • Line 37 (delete_backups.append(os.path.join(root, revit_model))):
    • ‘os.path.join’ creates a string combining the file path and the file name.
    • combined path/file name is added to the delete_backups list.
  • Line 39 (for remove_it in delete_backups:):
    • Once the delete_backups library is complete, this line iterates through all of the files in the dictionary.
  • Line 40 (os.remove(remove_it)):
    • ‘os.remove()’ deletes the specified file.

With the new version of Revit running, when this tool is run the dialog box will come up prompting the user to select a directory containing files to upgrade. Once selected, the files will be opened in the background and go through the version upgrade process. Once fully opened, the file will be saved over itself and closed. Then, the process will repeat for the next file in the list, until all of the files have been upgraded.

So, what do you think? Useful? Please let me know in the comments if there are improvements that can be made to the code, or if there is some addition to make the tool even more useful. Thanks!

About the author

Andrew Urban

With almost 15 years as a registered architect, and nearly as much experience using Revit, I have recently taught myself Python and have begun to create productivity increasing addons for Revit. I'm am always interested in learning new and innovative ways to use Revit and all other tools of our profession.

By Andrew Urban
Revit + Python

Andrew Urban

With almost 15 years as a registered architect, and nearly as much experience using Revit, I have recently taught myself Python and have begun to create productivity increasing addons for Revit. I'm am always interested in learning new and innovative ways to use Revit and all other tools of our profession.