Wrong rebar Hook direction for angle 90°

Hi everyone,

I’m once again getting the same error linked here for rebar hook direction only when angle 90° is choosen (this issue has upset me and I don’t know it is due to what and how to find a solution!!??)
for more details, check my references below:

1st script: rebars curves
import sys
import clr
import math
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference('RevitNodes')
import Revit
from Revit.Elements import Element

element = IN[0]
cover = IN[1]
rebar_type = IN[2]
spacing = IN[3]

geo = element.Geometry()
surfaces = geo[0].Explode()

s_area = []

for i in surfaces:
    s_area.append(i.Area)
    
S_area = ["%0.2f"%(round(i,2)) for i in s_area]
    
surf = []
surf_area = set()

for s, a in zip(surfaces, S_area):
    if a not in surf_area and S_area.count(a) == 2:
        surf.append(s)
        surf_area.add(a)
        

out_V_crv = surf[1].GetIsoline(0, 1).Explode()[0]
out_direct = out_V_crv.Direction

iner_V_crv = surf[0].GetIsoline(0, 1).Explode()[0]
iner_direct = iner_V_crv.Direction

if out_direct.Z > 0 :
    out_V_crv = out_V_crv
else:
    out_V_crv = out_V_crv.reverse()
    
if iner_direct.Z > 0 :
    iner_V_crv = iner_V_crv
else:
    iner_V_crv = iner_V_crv.reverse()    
    
vect = out_direct.Cross(Vector.ByCoordinates(0,1,0))  
out_V_rebar = out_V_crv.Translate(vect, cover)

iner_V_rebar = iner_V_crv.Translate(vect.Reverse(), cover)

overlap_length = rebar_type.GetParameterValueByName("Diamètre de barre")*50/1000
out_path = surf[1].GetIsoline(1, 0).Explode()[0]
out_path = out_path.Offset(-cover)
rebar_count = math.ceil(out_path.Length/spacing)

out_V_rebar = out_V_rebar.ExtendEnd(overlap_length)

def rebar_rotation(circle, space):
    sweepAngle = (space * 360) / (circle.Radius *  2 * math.pi)
    return sweepAngle
angle = rebar_rotation(out_path, spacing)
count = int(math.ceil(360/angle))

out_rebar = []
out_vect = []
for i in range(0, count):   
    a= i*angle
    rebar = out_V_rebar.Rotate(out_path.CenterPoint, Vector.ByCoordinates(0,0,1), a)
    vect = rebar.Normal
    vect = vect.Rotate(Vector.ByCoordinates(0,0,1), a)
    out_rebar.append(rebar)
    out_vect.append(vect)
iner_V_rebar = iner_V_rebar.ExtendEnd(overlap_length)
OUT = out_rebar, out_vect
2nd script: rebars
import sys
import clr
import math
import System
from System.Collections.Generic import IList, List 

clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
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

out_V_rebar = IN[0][0]
out_vect = IN[0][1]
cover = IN[1]/0.3048
rebar_type = UnwrapElement(IN[2])
Hook_type = UnwrapElement(IN[3])
host= UnwrapElement(IN[4])
spacing = IN[5]/0.3048

rebars = []

TransactionManager.Instance.EnsureInTransaction(doc)
for c, v in zip(out_V_rebar, out_vect):
    crvs = List[Curve]()
    crvs.Add(c.ToRevitType())    
    out_V_rebar = Rebar.CreateFromCurves(doc, RebarStyle.Standard, rebar_type, Hook_type, Hook_type, host, v.ToRevitType(), crvs, RebarHookOrientation.Left, RebarHookOrientation.Right, True, True)
    rebars.append(out_V_rebar)
TransactionManager.Instance.TransactionTaskDone()

OUT = out_V_rebar

Shaft_rebar.dyn (15.8 KB)
Shaft_rebar.rvt (3.4 MB)

Thanks in advance for your help.

Weird. I ran straight from the download without changing any settings and got this.

I did have to change one line of code for language translation.

image

1 Like

As you said it’s Weird… for others it’s works fine and for me it wont work!! :crazy_face:
According to your opinion what’s the cause of this issue ?

Thanks

Million dollar question for sure!
It would have to be a local setting and right off, I cannot think of any that would do that. Especially on just one of the rotation settings and not all of them.

Sorry, I’m not really helping solve your issue.

1 Like

@Thomas_Mahon , @Organon

To find a solution to this issue that only occurs in my case, I posted another thread Normal vector Revit API trying to understand vectors class in Revit API and how I can create them directly using API instead of Protogeometry to avoid any conflict, thus seeing how things go…by the way, this issue keeps recurring only when Hook orientation is set to 90°, so what’s the exact explanation to this matter and what is its solution (PS: this has also happend here)

please chek my updated references below:

st script: rebar_curve
import sys
import clr
import math
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference('RevitNodes')
import Revit
from Revit.Elements import Element

element = IN[0]
cover = IN[1]
rebar_type = IN[2]
spacing = IN[3]

geo = element.Geometry()
surfaces = geo[0].Explode()

s_area = []

for i in surfaces:
    s_area.append(i.Area)
    
S_area = ["%0.2f"%(round(i,2)) for i in s_area]
    
surf = []
surf_area = set()

for s, a in zip(surfaces, S_area):
    if a not in surf_area and S_area.count(a) == 2:
        surf.append(s)
        surf_area.add(a)
        

out_V_crv = surf[1].GetIsoline(0, 1).Explode()[0]
out_direct = out_V_crv.Direction

if out_direct.Z > 0 :
    out_V_crv = out_V_crv
else:
    out_V_crv = out_V_crv.reverse()
    
vect = out_direct.Cross(Vector.ByCoordinates(0,1,0))  
out_V_rebar = out_V_crv.Translate(vect, cover)

overlap_length = rebar_type.GetParameterValueByName("Diamètre de barre")*50/1000
out_V_rebar = out_V_rebar.ExtendEnd(overlap_length)

out_path = surf[1].GetIsoline(1, 0).Explode()[0]
out_path = out_path.Offset(-cover)
    
OUT = out_V_rebar, out_path
2nd script: rebars
import sys
import clr
import math
import System

from System.Collections.Generic import IList, List 

clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
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

curv = IN[0][0].ToRevitType()
out_path = IN[0][1].ToRevitType()
cover = IN[1]/0.3048
rebar_type = UnwrapElement(IN[2])
Hook_type = UnwrapElement(IN[3])
host= UnwrapElement(IN[4])
spacing = IN[5]/0.3048


# compute the rotation angle
def rebar_rotation(circle, space):
    sweepAngle = (space * 360) / (circle.Radius *  2 * math.pi)
    return sweepAngle

angle = rebar_rotation(out_path, spacing)

# rotated rebars count
count = int(math.ceil(360/angle))

# get rotated curves
rot_curvs = []
for i in range(0, count):   
    a= i*angle
    rot_curv = Transform.CreateRotation(XYZ.BasisZ, a*2*math.pi/360)
    rebar_curve = curv.CreateTransformed(rot_curv)
    rot_curvs.append(rebar_curve)
    
#create horizontal line needed to create normal vector
curv1 = curv.CreateOffset(spacing, XYZ(0,1,0))
line =Line.CreateBound(curv.GetEndPoint(0), curv1.GetEndPoint(0))
rot_90 = Transform.CreateRotation(XYZ.BasisZ, math.pi/2)
line = line.CreateTransformed(rot_90)

#get rotated lines
Vect = []
for i in range(0, count):   
    a= i*angle
    rot_vect = Transform.CreateRotation(XYZ.BasisZ, a*2*math.pi/360)
    vect = line.CreateTransformed(rot_vect)
    Vect.append(vect)
    
#create normal vectors
Vect = [(i.GetEndPoint(0) - i.GetEndPoint(1)).Normalize() for i in Vect]

# create rebars
rebars = []
TransactionManager.Instance.EnsureInTransaction(doc)
for c, v in zip(rot_curvs, Vect):
    out_V_crv = List[Curve]()
    out_V_crv.Add(c)
    out_V_rebar = Rebar.CreateFromCurves(doc, RebarStyle.Standard, rebar_type, Hook_type, Hook_type, host, v, out_V_crv, RebarHookOrientation.Left, RebarHookOrientation.Right, True, True)
    rebars.append(out_V_rebar)
TransactionManager.Instance.TransactionTaskDone()

OUT = rebars

updated_rebars.dyn (16.0 KB)

Thanks.

Ran your updated script and it ran perfectly. Set at 90 degrees, the hooks were turned inward and not outward as shown in your pic. So I really can’t explain what would be causing the problem just within your session of Revit. Not sure if this will help, here are the results from the first python script.

Startpoint
image

Endpoint
image

Direction
image

2 Likes

@staylor
Can you please confirm if the same rebar shape is generated in your case “Shape N°23” to understand the origin of this issue ?

Thanks.

@christian.stan
Can you please confirm if the same rebar shape “Shape N°23 ” is generated in your case
@c.poupin I know you are not a structure engineer but what you think about my reflection?

Thanks.

1 Like

Looks like you found a solution to your problem.

before with the shapes


after removing shapes

edit: here is a rebar shape family taken from the standard since rvt 2020
2-00.rfa (332 KB)

which should work without deleting all affected shapes

Cordially
christian.stan

3 Likes

@christian.stan

I found the 1st half of the solution and you the 2nd :face_with_monocle: :grin:

Now it’s works perfectly after deleting shape 23 as shown below

here the final script for creating rebars (2nd updated script):

updated_rebar
import sys
import clr
import math
import System

from System.Collections.Generic import IList, List 

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

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

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

doc = DocumentManager.Instance.CurrentDBDocument

out_curv = IN[0][0].ToRevitType()
out_path = IN[0][1].ToRevitType()
iner_curv = IN[0][2].ToRevitType()
iner_path = IN[0][3].ToRevitType()

cover = IN[1]/0.3048
rebar_type = UnwrapElement(IN[2])
Hook_type = UnwrapElement(IN[3])
host= UnwrapElement(IN[4])
spacing = IN[5]/0.3048
container_name = rebar_type.ToDSType(False).Name

# compute the rotation angle
def rebar_rotation(circle, space):
    sweepAngle = (space * 360) / (circle.Radius *  2 * math.pi)
    return sweepAngle

out_angle = rebar_rotation(out_path, spacing)
iner_angle = rebar_rotation(iner_path, spacing)
# rotated rebars count
out_count = int(math.ceil(360/out_angle))
iner_count = int(math.ceil(360/iner_angle))
# get rotated curves
out_rot_curvs = []
for i in range(0, out_count):   
    a= i*out_angle
    rot_curv = Transform.CreateRotation(XYZ.BasisZ, a*2*math.pi/360)
    out_curvs = out_curv.CreateTransformed(rot_curv)
    out_rot_curvs.append(out_curvs)
    
iner_rot_curvs = []
for i in range(0, iner_count):   
    a= i*iner_angle
    rot_curv = Transform.CreateRotation(XYZ.BasisZ, a*2*math.pi/360)
    iner_curvs = iner_curv.CreateTransformed(rot_curv)
    iner_rot_curvs.append(iner_curvs)
    
curvs = [out_rot_curvs, iner_rot_curvs]

#create horizontal line needed to create normal vector

out_line =Line.CreateBound(out_curv.GetEndPoint(0), iner_curv.GetEndPoint(0))
iner_line =Line.CreateBound(iner_curv.GetEndPoint(0), out_curv.GetEndPoint(0))
rot_90 = Transform.CreateRotation(XYZ.BasisZ, math.pi/2)
out_line = out_line.CreateTransformed(rot_90)
iner_line = iner_line.CreateTransformed(rot_90)
#get rotated lines
out_Vect = []
for i in range(0, out_count):   
    a= i*out_angle
    rot_vect = Transform.CreateRotation(XYZ.BasisZ, a*2*math.pi/360)
    out_vect = out_line.CreateTransformed(rot_vect)
    out_Vect.append(out_vect)

iner_Vect = []
for i in range(0, iner_count):   
    a= i*iner_angle
    rot_vect = Transform.CreateRotation(XYZ.BasisZ, a*2*math.pi/360)
    iner_vect = iner_line.CreateTransformed(rot_vect)
    iner_Vect.append(iner_vect)
    
#create normal vectors
out_Vect = [(i.GetEndPoint(0) - i.GetEndPoint(1)).Normalize() for i in out_Vect]
iner_Vect = [(i.GetEndPoint(0) - i.GetEndPoint(1)).Normalize() for i in iner_Vect]

Vect = [out_Vect, iner_Vect]

# create rebars
rebars = []


TransactionManager.Instance.EnsureInTransaction(doc)

for i, j in zip(range(0, len(curvs)), range(0, len(Vect))):
    containerTypeId = RebarContainerType.GetOrCreateRebarContainerType(doc, container_name )
    rebarContainer = RebarContainer.Create(doc, host, containerTypeId)
    totalLength = []
    rebar_curv = List[Curve]()
    for c, v in zip(curvs[i], Vect[j]):
        totalLength.Add(c.Length)
        rebar_curv.Add(c)
        V_rebar = Rebar.CreateFromCurves(doc, RebarStyle.Standard, rebar_type, Hook_type, Hook_type, host, v, rebar_curv, RebarHookOrientation.Left, RebarHookOrientation.Right, True, True)
        doc.Regenerate()
        rebarContainer.AppendItemFromRebar(V_rebar)
        doc.Delete(V_rebar.Id)
        rebar_curv.Clear()
    quantityParameter = rebarContainer.get_Parameter(BuiltInParameter.REBAR_ELEM_QUANTITY_OF_BARS)
    totalLengthParameter = rebarContainer.LookupParameter("Longueur de barre totale")
    containerParameters = rebarContainer.GetParametersManager()
    containerParameters.AddOverride(quantityParameter.Id, len(curvs[i]))
    containerParameters.AddOverride(totalLengthParameter.Id, sum(totalLength))
    rebars.append(rebarContainer)
    
TransactionManager.Instance.TransactionTaskDone()

OUT = rebars

before that, in your previous tests, had you the “shape 23” in your rebar family ? …if yes I still not figure out why in my case this shape is choosen instead of “shape 00” or others shapes??

Thanks.

2 Likes

Hello, from what I understand if your form is not present it performs a second scan ignoring the hookStart and hookEnd



Cordially
christian.stan

2 Likes

@christian.stan

It’s clair for me now, and the origin of this ssue is known…sometimes it’s easier then read and well understand each function in the method’s document as you have done it :wink:

Thanks so much.

1 Like