Export from multiple Revit files to IFC + python

Hi everyone,
I’m trying to create a script where I export from 4 Revit files into separate IFC files.
I’ve ventured into creating a Python script, strongly inspired by Arpit Verma (LinkedIn).

In short, this is what I’m trying to do:
For each .rvt file in a folder, I want to export an IFC from a specific view that contains “IFC” in its name.
It should export the IFC to another folder, saved with the same name as the Revit file.

the code:

import os
import clr
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# imput from Dynamo (expecting string patgs for folder)
source_folder = IN[0]
destination_folder = IN[1]

#define the IFC export option with your custom configuration
def get_ifc_export_options():
    ifc_options = IFCExportOptions()
    ifc_options.ExportBaseQuantities = True
    ifc_options.ExportAnnotations = False
    ifc_options.SpaceBoundaryLevel = 1
    ifc_options.WallAndColumnSplitting = False
    ifc_options.Export2DElements = False
    ifc_options.VisibleElementsOfCurrentView = True #Export only visible elements
    ifc_options.ExportLinkedFiles = True
    ifc_options.ExportPartsAsBuildingElements = False
    ifc_options.ExportSpecificSchedules = False
    return ifc_options

def find_ifc_view(doc):
    """Finds the first view with 'IFC' in the name (case-insensitive)."""
    views = filteredElementCollector(doc).OfClass(View3D).ToElements()
    for view in views:
        if "ifc" in view.Name.lower():
            return view
    return None

# Get the Revit application
app = DocumentManager.Instance.CurrentUIApplication.Application

def export_ifc(doc, ifc_options, destination_folder, view_id):
    """Export the Revit model to IFC format using a specific view."""
    # Get the file name without extension
    file_name = os.path.splitext(os.path.basename(doc.PathName))[0]
    
    # Create the full path for the IFC file
    ifc_file_path = os.path.join(destination_folder, file_name + ".ifc")
    
    try:
        # Start a dummy transaction to allow export
        t = Transaction(doc, "IFC Export")
        t.Start()

        # set the view for export
        ifc_options.ActiveViewId = view_id
        
        # Export the model to IFC format with the custom options
        doc.Export(destination_folder, file_name + ".ifc", ifc_options)
        print(f"Exported: {ifc_file_path}")
        
        # Commit the dummy transaction
        t.Commit()
        
    except Exception as e:
        print(f"Faild to export {file_name}: {str(e)}")
        
    finally:
        if t.HasStarted() and not t.HasEnded():
            t.RollBack()
    
def close_document(doc):
    """Safely closes the document."""
    try:
        if doc and doc.IsValidObject:
            doc.Close(False)
    except Exception as e:
        print(f"Error closing document: {str(e)}")

# Ensure the source and destination folders are valid
if not os.path.exists(source_folder):
    OUT = "Error: The source folder does not exist."
elif not os.path.exists(destination_folder):
    OUT = "Error: The destination folder does not exist."
else:
    exported_files = []
    error_files = []
        
    # Loop through all the files in the source folder
    for file_name in os.listdir(source_folder):
        if file_name.endswith(".rvt"):
            full_file_path = os.path.join(source_folder, file_name)
            print(f"Processing file: {full_file_path}")
            
            # Open the Revit model
            model_path = ModelPathUtils.ConvertUserVisiblePathToModelPath(full_file_path)
            open_options = OpenOptions()
            open_options.DetachFromCentralOption = DetachFromCentralOption.DetachAndPreserveWorksets # Preserving worksets for BIM3600 files
            open_options.Audit = False # Set audit to False
            
            doc = None
            
            try:
                doc = app.OpenDocumentFile(model_path, open_options)
                
                # Get the custom IFC export option
                ifc_options = get_ifc_export_options()
                
                # Finde the "IFC" 3D view
                ifc_view = find_ifc_view(doc)
                
                if ifc_view:
                    print(f"IFC view found: {ifc_view.Name}")
                    # Export the opened model to IFC using the found view
                    export_ifc(doc, ifc_options, destination_folder, ifc_view.Id)
                    exported_files.append(file_name)
                else:
                    print(f"No IFC view found in {file_name}. Skipping export.")
                    error_files.append(file_name)
            
            except Exception as e:
                print(f"Error processing {file_name}: {str(e)}")
                error_files.append(file_name)
                
            finally:
                # Close the document af exporting
                close_document(doc)
                    
    # Output for Dynamo
    if exported_files:
        OUT = f"Export Complete: {len(exported_files)} files exported."
    else:
        OUT = "No Files were exported."
        
    if error_files:
       OUT = f" Errors occurred in {len(error_files)} files."

Mod note: I edited your original post to use preformatted text for the whole code portion (please make sure to always use preformatted text for code in the future). Check and confirm that everything looks correct.

What happens with your code so far? Are you getting any errors? Is anything happening? It probably would have been easier to start with one file and work through the export logic until it all worked. Then you’d just have to add looping for the list.

1 Like

Or better yet, try Dynamo Multiplayer from Bird Tools and worry not about background opening issues!

1 Like