In order to enable the use of rebar shapes in Architectural Template projects (as opposed to Structural Template projects), I’m using the code snippet below to either use an existing or load the 0-00 rebar shape from a local path (Rebar_path), as shown in the image below:
import clr
import os
import System
from System.Windows.Forms import MessageBox
# Import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
from Autodesk.Revit.DB import *
Rebar_path = r"C:\ProgramData\Autodesk\RVT 2023\Libraries\French\Structure\Formes d'armature\NF-P-02-016-1993\0-00.rfa"
def get_rebars_shapes():
try:
# get existing rebar shapes if a new "Structural Template" project is started
collector = FilteredElementCollector(doc) \
.OfCategory(BuiltInCategory.OST_RebarShape) \
.WhereElementIsElementType() \
.ToElements()
rebar_shapes = [s.Name for s in collector]
if rebar_shapes:
return rebar_shapes
# If no shapes exist "Architectural Template" project is started, try loading shape "0-00"
if not os.path.exists(Rebar_path):
MessageBox.Show("Rebar shape family file not found:\n{}".format(Rebar_path))
return None
with Transaction(doc, "Load Rebar Shape 0-00") as t:
t.Start()
if not os.path.exists(Rebar_path):
MessageBox.Show("Failed to load rebar shape family.")
return None
doc.Regenerate()
t.Commit()
# Collect rebar shapes again after loading
collector = FilteredElementCollector(doc) \
.OfCategory(BuiltInCategory.OST_RebarShape) \
.WhereElementIsElementType() \
.ToElements()
rebar_shapes = [s for s in rebar_shapes if s.Name == "0-00"]
if not rebar_shapes:
MessageBox.Show("Shape '0-00' not found even after loading.")
return None
return rebar_shapes
except Exception as ex:
MessageBox.Show("Error occurred:\n{}".format(str(ex)), title="Critical Error")
return None
shapes = get_rebars_shapes()
OUT = shapes
I switched to IronPython 2.7 engine and used this updated code, where I can this time get rebar shape Name property if I start a Structural Template project, however I still unable to load the shape I want if I start an Architectural Template project?
import clr
import os
import System
import traceback
clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import MessageBox
# Import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
from Autodesk.Revit.DB import *
Rebar_path = r"C:\ProgramData\Autodesk\RVT 2023\Libraries\French\Structure\Formes d'armature\NF-P-02-016-1993\0-00.rfa"
def get_rebars_shapes():
try:
# get existing rebar shapes if a new "Structural Template" project is started
collector = FilteredElementCollector(doc)\
.OfCategory(BuiltInCategory.OST_RebarShape)\
.WhereElementIsElementType().ToElements()
rebar_shapes = [Element.Name.GetValue(s) for s in collector]
if rebar_shapes:
return rebar_shapes
# If no shapes exist "Architectural Template" project is started, try loading shape "0-00"
if not os.path.exists(Rebar_path):
MessageBox.Show("Rebar shape family file not found:\n{}".format(Rebar_path))
return None
with Transaction(doc, "Load Rebar Shape 0-00") as t:
t.Start()
if not os.path.exists(Rebar_path):
MessageBox.Show("Failed to load rebar shape family.")
return None
doc.Regenerate()
t.Commit()
# Collect rebar shapes again after loading
collector = FilteredElementCollector(doc)\
.OfCategory(BuiltInCategory.OST_RebarShape)\
.WhereElementIsElementType().ToElements()
rebar_shapes = [s for s in rebar_shapes if Element.Name.GetValue(s) == "0-00"]
if not rebar_shapes:
MessageBox.Show("Shape '0-00' not found even after loading.")
return None
return rebar_shapes
except Exception as ex:
print(traceback.format_exc())
return None
shapes = get_rebars_shapes()
OUT = shapes
You’re absolutely right!.. thank you for pointing out the mistake I overlooked!
Instead of writing if not doc.LoadFamily(Rebar_path): , I mistakenly repeated if not os.path.exists(Rebar_path): twice.
I’ve corrected the error in the updated code below, and it now works as expected.
import clr
import os
import System
import traceback
clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import MessageBox
# Import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
def get_rebars_shapes():
try:
# Get existing rebar shapes
collector = FilteredElementCollector(doc)\
.OfCategory(BuiltInCategory.OST_RebarShape)\
.WhereElementIsElementType().ToElements()
rebar_shapes = [Element.Name.GetValue(s) for s in collector]
if rebar_shapes:
return rebar_shapes
# If no shapes exist, try loading "0-00"
if not os.path.exists(Rebar_path):
MessageBox.Show("Rebar shape family file not found:\n{}".format(Rebar_path))
return None
with Transaction(doc, "Load Rebar Shape 0-00") as t:
t.Start()
if not doc.LoadFamily(Rebar_path):
MessageBox.Show("Failed to load rebar shape family.")
t.Commit()
return None
t.Commit()
doc.Regenerate()
# Collect rebar shapes again after loading
collector = FilteredElementCollector(doc)\
.OfCategory(BuiltInCategory.OST_RebarShape)\
.WhereElementIsElementType().ToElements()
rebar_shapes = [s for s in collector if Element.Name.GetValue(s) == "0-00"]
if not rebar_shapes:
MessageBox.Show("Shape '0-00' not found even after loading.")
return None
return rebar_shapes
except Exception as ex:
print(traceback.format_exc())
return None
shapes = get_rebars_shapes()
OUT = shapes