Error creating rebars from curves in python

Hello,
I am trying to copy existing RebarContainers to new elements and after “exploding” the RebarContainer into Rebars, but I am getting an internal error if I try to get the RebarContainerItem hook types and use them to create the new Rebars. If I give hookTypes a value of None all works well.
Please take a look at my code and let me know if you have any ideas what I am doing wrong.

1 Like

Please post the code as preformatted text as well :slight_smile:

And you should at least add a on ‘‘else’’ statement to the end of your ‘‘if’’ :slight_smile:

1 Like

Hope this is better.

rebars = []
# Start transaction
TransactionManager.Instance.EnsureInTransaction(doc)
for containerItem in container:
    rebarStyle = doc.GetElement(containerItem.RebarShapeId).RebarStyle
    barType = doc.GetElement(containerItem.BarTypeId)
    hookTypeStart = doc.GetElement(containerItem.GetHookTypeId(0))
    hookTypeEnd = None #doc.GetElement(containerItem.GetHookTypeId(1))
    element = doc.GetElement(container.GetHostId())
    origin = doc.GetElement(container.GetHostId()).Location.Point
    curves = containerItem.GetCenterlineCurves(True, True, True)
    hookOrientationStart = containerItem.GetHookOrientation(0)
    hookOrientationEnd = containerItem.GetHookOrientation(1)

    rebar = Rebar.CreateFromCurves(doc, rebarStyle, barType, hookTypeStart, hookTypeEnd, element, origin, curves, hookOrientationStart, hookOrientationEnd, True, True)

    if containerItem.LayoutRule == RebarLayoutRule.FixedNumber:
        rebar.GetShapeDrivenAccessor().SetLayoutAsFixedNumber(containerItem.NumberOfBarPositions, containerItem.ArrayLength, containerItem.BarsOnNormalSide, containerItem.IncludeFirstBar, containerItem.IncludeLastBar)
    elif containerItem.LayoutRule == RebarLayoutRule.MaximumSpacing:
        rebar.GetShapeDrivenAccessor().SetLayoutAsFixedNumber(containerItem.MaxSpacing, containerItem.ArrayLength, containerItem.BarsOnNormalSide, containerItem.IncludeFirstBar, containerItem.IncludeLastBar)
    elif containerItem.LayoutRule == RebarLayoutRule.NumberWithSpacing:
        rebar.GetShapeDrivenAccessor().SetLayoutAsMinimumClearSpacing(containerItem.MaxSpacing, containerItem.ArrayLength, containerItem.BarsOnNormalSide, containerItem.IncludeFirstBar, containerItem.IncludeLastBar)
    elif containerItem.LayoutRule == RebarLayoutRule.MinimumClearSpacing:
  rebar.GetShapeDrivenAccessor().SetLayoutAsNumberWithSpacing(containerItem.NumberOfBarPositions, containerItem.MaxSpacing, containerItem.BarsOnNormalSide, containerItem.IncludeFirstBar, containerItem.IncludeLastBar)
    else:
        pass

   rebars.append(rebar)
  
# container.ClearItems()
# End transaction
TransactionManager.Instance.TransactionTaskDone()
# Assign your output to the OUT variable.
OUT = rebars",
2 Likes

I tried a new approach and now it works fine. I used the CreateFromCurvesAndShape() method instead of CreateFromCurves() to create the rebar, and ComputeDrivingCurves() method to get the curve of each Rebar.
Still if someone figures out why the first version did not work or if you have suggestions how to improve this script I am open to any advice.

# Enable Python support and load DesignScript library
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import ToDSType(bool) extension method
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)

# Import DocumentManager and TransactionManager
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Import RevitAPI
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB.Structure import Rebar, RebarContainerType, RebarContainer, RebarShape, RebarBarType, RebarHookType, RebarLayoutRule
from Autodesk.Revit.DB import LocationPoint, XYZ, FilteredElementCollector, ElementFilter

# The inputs to this node will be stored as a list in the IN variables.
container = UnwrapElement(IN[0])

# Place your code below this line
doc = DocumentManager.Instance.CurrentDBDocument

# List of Rebars
rebars = []

# List of errors
errors = []

# Start transaction
TransactionManager.Instance.EnsureInTransaction(doc)

for containerItem in container:
	# Get the RebarShape of the current containerItem
	rebarShape = doc.GetElement(containerItem.RebarShapeId)
	# Get the RebarBarType of the current containerItem
	barType = doc.GetElement(containerItem.BarTypeId)
	# Get the RebarHookType at the start of the current containerItem
	hookTypeStart = None;
	if containerItem.GetHookTypeId(0).IntegerValue > 0:
		hookTypeStart = doc.GetElement(containerItem.GetHookTypeId(0))
	# Get the RebarHookType at the end of the current containerItem
	hookTypeEnd = None;
	if containerItem.GetHookTypeId(0).IntegerValue > 0:
		hookTypeEnd = doc.GetElement(containerItem.GetHookTypeId(1))
	# Get the host of the RebarContainer
	element = doc.GetElement(container.GetHostId())
	# Get the Normal of the containerItem
	norm = containerItem.Normal
	# Get the curves of the current 
	curves = containerItem.ComputeDrivingCurves()
	# Get the HookOrientation at the start of the containerItem
	hookOrientationStart = containerItem.GetHookOrientation(0)
	# Get the HookOrientation at the end of the containerItem
	hookOrientationEnd = containerItem.GetHookOrientation(1)
	
	# Try to create the Rebar
	try:
		# Create Rebar using CreateFromCurvesAndShape method
		rebar = Rebar.CreateFromCurvesAndShape(doc, rebarShape, barType, hookTypeStart, hookTypeEnd, element, norm, curves, hookOrientationStart, hookOrientationEnd)
		
		# Check what is the LayoutRule of the current containerItem
		if containerItem.LayoutRule == RebarLayoutRule.FixedNumber:
			# Set the layout of the Rebar as fixed number
			rebar.GetShapeDrivenAccessor().SetLayoutAsFixedNumber(containerItem.NumberOfBarPositions, containerItem.ArrayLength, containerItem.BarsOnNormalSide, containerItem.IncludeFirstBar, containerItem.IncludeLastBar)
		elif containerItem.LayoutRule == RebarLayoutRule.MaximumSpacing:
			# Set the layout of the Rebar as maximum spacing
			rebar.GetShapeDrivenAccessor().SetLayoutAsMaximumSpacing(containerItem.MaxSpacing, containerItem.ArrayLength, containerItem.BarsOnNormalSide, containerItem.IncludeFirstBar, containerItem.IncludeLastBar)
		elif containerItem.LayoutRule == RebarLayoutRule.NumberWithSpacing:
			# Set the layout of the Rebar as number with spacing
			rebar.GetShapeDrivenAccessor().SetLayoutAsNumberWithSpacing(containerItem.NumberOfBarPositions, containerItem.MaxSpacing, containerItem.BarsOnNormalSide, containerItem.IncludeFirstBar, containerItem.IncludeLastBar)	
		elif containerItem.LayoutRule == RebarLayoutRule.MinimumClearSpacing:
			# Set the layout of the Rebar as minimum clear spacing
			rebar.GetShapeDrivenAccessor().SetLayoutAsMinimumClearSpacing(containerItem.MaxSpacing, containerItem.ArrayLength, containerItem.BarsOnNormalSide, containerItem.IncludeFirstBar, containerItem.IncludeLastBar)
		else:
			# If no LayoutRule do nothing
			pass
		# Add the new Rebar to the rebars list
		rebars.append(rebar)
	# Catch error if unable to create the Rebar
	except Exception as inst:
		# Add error to the errors list
		errors.append(inst)	

# End transaction
TransactionManager.Instance.TransactionTaskDone()

# Output list containing a sublist of Rebars and a sublist of errors
output = []
output.append(rebars)
output.append(errors)

# Assign your output to the OUT variable.
OUT = output
2 Likes