Changes not applied gbXML export via Python script

Hi,

I found a Python script on the web which allows to automatically export gbXML file from Revit using Dynamo and added some custom feature which include call to a webservice for gbXML parsing.
It works great unless some changes are not applied to the export file.

I have a Revit model with some spaces (arround 100).
I did a first export then I noticed that a few spaces had a wrong space type.
Went back to Revit, applied the modifications needed and relaunched the dynamo script.
The result is the same as before, the space types are not modified in the gbXML feed.

I have also tried to delete the space and recreate it => result is the same
Add more spaces => the new one are not in the gbXML feed.

If I do the process manually: R / Export / gbXML / choose spaces : it works.

Any ideas on how to fix that?

Thanks a lot.
Clement

I’m no expert on this, but I think people will want to see your Python script.

3 Likes

Exactly.
#Import Lib externes à Revit
import sys
sys.path.append(r’C:\Program Files (x86)\IronPython 2.7\DLLs’)
sys.path.append(r’C:\Program Files (x86)\IronPython 2.7\Lib’)

#Lib qui permet d'ouvrir le navigateur web et donc charger le webservice pour parser le fichier gbXML
import webbrowser

#Libs Revit
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import clr

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *

#Récupère les variables passée en arguemnts 
folder = IN[0]
filename = IN[1]
complete = folder+'\\'+filename+'.xml'

optionsenergy = Analysis.EnergyAnalysisDetailModelOptions()

#Choose between final or secondlevel boundaries for export
#optionsenergy.Tier = Analysis.EnergyAnalysisDetailModelTier.Final
optionsenergy.Tier = Analysis.EnergyAnalysisDetailModelTier.SecondLevelBoundaries

TransactionManager.Instance.EnsureInTransaction(doc)
model = Analysis.EnergyAnalysisDetailModel.Create(doc,optionsenergy)
TransactionManager.Instance.TransactionTaskDone()

options = GBXMLExportOptions()
#buildingelement supposedly only works with massExport
#options.ExportEnergyModelType = ExportEnergyModelType.BuildingElement

options.ExportEnergyModelType = ExportEnergyModelType.SpatialElement

TransactionManager.Instance.EnsureInTransaction(doc)
doc.Export(folder,filename,options)
TransactionManager.Instance.TransactionTaskDone()

#Appel le script de parsing gbXML
webbrowser.open('http://localhost/tfe/backend/gbxml_parser.php?file=' + complete, new=2)

#Variable de sortie
OUT = 0
1 Like

Any ideas on this?
Thanks.

I’m having trouble with this as well. The way it looks, Revit stores every EnergyAnalysisDetailModel that is created. But it doesn’t advance export to the last Model in the store by default. Not yet sure how to set export to the last model created.

The code below will make a list of all the EnergyAnalysisDetailModel in the document.

    all_eadm = FilteredElementCollector(doc).OfClass(EnergyAnalysisDetailModel).WhereElementIsNotElementType().ToElements()

From the docs:

It is recommended that applications call Document.Delete() on the EnergyAnalysisDetailModel elements
 that they create when finished accessing the data, but any energy models created after the main energy
 model will be deleted automatically before document saving or synchronization.

-Jake

Finally found the applicable remarks in the API docs:

This export operation will operate on the main EnergyAnalysisDetailModel in the document, if it exists (see EnergyAnalysisDetailModel.GetMainEnergyAnalysisDetailModel()). If it does not exist, or if the requested ExportEnergyModelType does not match the type of the main EnergyAnalysisDetailModel, this function will fail. If you need to export a model with different settings or type than the current main energy model in the document, you should delete the current main energy model, update the EnergyAnalysisSettings, and regenerate the energy model.

So, the gbXML will be exported against the first (Main) EnergyAnalysisDetailModel in the document. Surest course of action is to delete all EnergyAnalysisDetailModel then create a fresh Main model for export. Please see the Python code below as working example.

# Exports EnergyAnalysisDetailModel gbXML
# https://help.autodesk.com/view/RVT/2021/ENU/?guid=Revit_API_Revit_API_Developers_Guide_Advanced_Topics_Analysis_Conceptual_Energy_Analysis_html
# Export method basis: https://forum.dynamobim.com/t/export-gbxml-file-from-revit/77348

import clr #This is .NET's Common Language Runtime. It's an execution environment
#that is able to execute code from several different languages.
import sys #sys is a fundamental Python library - here, we're using it to load in
#the standard IronPython libraries
sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib') #Imports the
#standard IronPython libraries, which cover everything from servers and
#encryption through to regular expressions.
import System #The System namespace at the root of .NET
from System import Array #.NET class for handling array information
from System.Collections.Generic import * #Lets you handle generics. Revit's API
#sometimes wants hard-typed 'generic' lists, called ILists. If you don't need
#these you can delete this line.
clr.AddReference('ProtoGeometry')  #A Dynamo library for its proxy geometry
#classes. You'll only need this if you're interacting with geometry.
from Autodesk.DesignScript.Geometry import * #Loads everything in Dynamo's
#geometry library
clr.AddReference("RevitNodes") #Dynamo's nodes for Revit
import Revit #Loads in the Revit namespace in RevitNodes
clr.ImportExtensions(Revit.Elements) #More loading of Dynamo's Revit libraries
clr.ImportExtensions(Revit.GeometryConversion) #More loading of Dynamo's
#Revit libraries. You'll only need this if you're interacting with geometry.
clr.AddReference("RevitServices") #Dynamo's classes for handling Revit documents
import RevitServices 
from RevitServices.Persistence import DocumentManager #An internal Dynamo class
#that keeps track of the document that Dynamo is currently attached to
from RevitServices.Transactions import TransactionManager #A Dynamo class for
#opening and closing transactions to change the Revit document's database

clr.AddReference("RevitAPI") #Adding reference to Revit's API DLLs
clr.AddReference("RevitAPIUI") #Adding reference to Revit's API DLLs

import Autodesk #Loads the Autodesk namespace
from Autodesk.Revit.DB import * #Loading Revit's API classes
from Autodesk.Revit.DB.Analysis import * #Loading Revit's API Analysis classes
from Autodesk.Revit.UI import * #Loading Revit's API UI classes  

doc = DocumentManager.Instance.CurrentDBDocument #Finally, setting up handles to the active Revit document
uiapp = DocumentManager.Instance.CurrentUIApplication #Setting a handle to the active Revit UI document
app = uiapp.Application  #Setting a handle to the currently-open instance of the Revit application
uidoc = uiapp.ActiveUIDocument #Setting a handle to the currently-open instance of the Revit UI application

# The inputs to this node will be stored as a list in the IN variable.
outputDirectory = IN[0]
outputFileName = IN[1]

# To open a new transaction, we need to use the TransactionManager class
# Which takes the current document's handle as an argument
TransactionManager.Instance.EnsureInTransaction(doc)

# Energy Analysis Detail Model Options
# https://apidocs.co/apps/revit/2021.1/49b0be90-7d7f-ab4b-ce6a-c5aa81a8cc71.htm
energyOpts = EnergyAnalysisDetailModelOptions()

## Default Tier is 'Final'
#energyOpts.Tier = EnergyAnalysisDetailModelTier.NotComputed
#energyOpts.Tier = EnergyAnalysisDetailModelTier.FirstLevelBoundaries
#energyOpts.Tier = EnergyAnalysisDetailModelTier.SecondLevelBoundaries
#energyOpts.Tier = EnergyAnalysisDetailModelTier.Final

## Default EnergyModelType is 'SpatialElement'
#energyOpts.EnergyModelType = EnergyModelType.SpatialElement
#energyOpts.EnergyModelType = EnergyModelType.BuildingElement

## Delete all EnergyAnalysisDetailModel so that MainEnergyAnalysisDetailModel is created for export
# https://apidocs.co/apps/revit/2021.1/adf1b78e-dcab-7b46-80fa-a470f0fd848b.htm
all_eadm = FilteredElementCollector(doc).OfClass(EnergyAnalysisDetailModel).WhereElementIsNotElementType().ToElements()
for a in all_eadm:
	Document.Delete(doc, a.Id)

eadm = EnergyAnalysisDetailModel
model = eadm.Create(doc,energyOpts)

# GBXMLExport method
# https://apidocs.co/apps/revit/2021.1/abb350ef-a773-7b70-6881-166e6f3c0a56.htm

# GBXMLExport options
# https://apidocs.co/apps/revit/2021.1/3e31ec67-5a6e-993e-40d9-6e43285e5888.htm
gbxmlOpts = GBXMLExportOptions()

# Default ExportEnergyModelType is 'SpatialElement'
#gbxmlOpts.ExportEnergyModelType = ExportEnergyModelType.SpatialElement
#gbxmlOpts.ExportEnergyModelType = ExportEnergyModelType.BuildingElement

doc.Export(outputDirectory, outputFileName, gbxmlOpts)

# Delete created EnergyAnalysisDetailModel as recommended by docs
Document.Delete(doc, model.Id)

#The following method will close the transaction and confirm any changes
#made to the Revit document's database.
TransactionManager.Instance.TransactionTaskDone()

all_eadm = FilteredElementCollector(doc).OfClass(EnergyAnalysisDetailModel).WhereElementIsNotElementType().ToElements()

#Assign your output to the OUT variable
path = outputDirectory + '\\' + outputFileName
OUT = 'Exported gbXML to: ' + path, all_eadm
1 Like

I would like to ask
Now I’m working on a python script to export gbXML files for different windows variations
But it export the same file with different names only
How to solve this issue
Do you it’s the same problem about exporting the same energy model file

This code does not work on Revit 2023

The gbXML will be exported against the first (Main) EnergyAnalysisDetailModel in the document. Surest course of action is to delete all EnergyAnalysisDetailModel then create a fresh Main model for export.

Hello,

The Python code working example that was posted was developed in the Revit 2021 environment.

The Revit 2023 API deprecated some Energy Model functionality of previous versions. Unfortunately, I do not have access to Revit 2023.

Depending on your needs you may be able to sidestep Revit entirely for gbXML iteration by using the xgbxml Python library.

-Jake

Thank you