Translation curves issue in Revit API

Hi All, @Mike.Buttery , @c.poupin

I am attempting, in the example below, to translate circular curves vertically while simultaneously checking the following condition to maintain a minimum spacing between the last curve and the bottom edge of the slab

#checking the minimum spacing between the last curve and the bottom edge of the slab
    if v_path - e < H_s/2:
        out_cir_rebar = out_cir_rebar[-1]

I tested various inputs for the desired spacing, referred to as (H_s ), in my code, and it works as shown in the image below. However, I only obtained the last curves when (H_s ) is set to 0.20 m. I don’t know why I’m encountering this issue specifically for this value?

Here my code:

Curves_translation
import clr
from math import pi, ceil
from System.Collections.Generic import IList, List

clr.AddReference("ProtoGeometry")
from Autodesk.DesignScript.Geometry import *

clr.AddReference("RevitNodes")
import Revit
from Revit.GeometryConversion import *
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument
# Helper functions
metres = lambda iu: UnitUtils.ConvertFromInternalUnits(iu, UnitTypeId.Meters)
degrees = lambda rad: UnitUtils.Convert(rad, UnitTypeId.Radians, UnitTypeId.Degrees)

# Inputs
all_Shafts = FilteredElementCollector(doc).OfCategory(BuiltInCategory. OST_StructuralFraming).WhereElementIsNotElementType().ToElements()

Start_shaft = all_Shafts[0]

cir_rebar_type = UnwrapElement(IN[1])
V_rebar_type = UnwrapElement(IN[2])
#spacing for circular rebars
H_s = IN[3]
#spacing for vertical rebars
V_s = IN[4]
start_hook = UnwrapElement(IN[5])
end_hook = UnwrapElement(IN[6])


# Get geometry (Largest circle at lowest point)
Start_geom = Start_shaft.get_Geometry(Options())


solids = list(Start_geom.GetTransformed(Transform.Identity))[1]
curves = [e.AsCurve() for e in solids.Edges]
arcs = [c for c in curves if "Arc" in c.ToString()]
out_arc_radius = max(arcs, key=lambda c: c.get_Radius()).get_Radius()
()
out_arc = min(
    [arc for arc in arcs if arc.get_Radius() == out_arc_radius],
    key=lambda c: c.get_Center().Z,
)

inner_arc_radius = max(arcs, key=lambda c: c.get_Radius()!= out_arc_radius).get_Radius()
inner_arc = min(
    [arc for arc in arcs if arc.get_Radius() == inner_arc_radius ],
    key=lambda c: c.get_Center().Z,
)
# Parameters
l = 12
cover = 0.05
cir_diameter = metres(cir_rebar_type.BarModelDiameter)
V_diameter = metres(V_rebar_type.BarModelDiameter)
hook_bend = metres(V_rebar_type.StandardHookBendDiameter)
V_cover = cover + (cir_diameter + V_diameter) /2 
# overlap lengths
circ_overlap_length = 50 * cir_diameter
V_overlap_length = 50 * V_diameter
out_rebar_radius = metres(out_arc.Radius) - cover

center1 = out_arc.Center
center1 = XYZ(center1.X, center1.Y, center1.Z + cover + 1.5 * V_diameter + hook_bend/2)

# Calculations
# getting Out vertical curves for outer vertical rebars:
bbox = Start_geom.GetBoundingBox()
H1 = (bbox.Max.Subtract(bbox.Min).Z)
out_vert_bar = Line.CreateBound(XYZ(out_arc_radius, 0, cover * 3.28084), XYZ(out_arc_radius, 0, H1  + V_overlap_length * 3.28084))

inner_vert_bar = Line.CreateBound(XYZ(inner_arc_radius, 0, cover * 3.28084), XYZ(inner_arc_radius, 0, H1 + V_overlap_length * 3.28084))

h_line = Line.CreateBound(out_vert_bar.GetEndPoint(0), inner_vert_bar.GetEndPoint(0))

H_offset1 = Transform.CreateTranslation(h_line.Direction.Normalize().Multiply(V_cover*3.28084))

out_vert_bar = out_vert_bar.CreateTransformed(H_offset1)

# getting out circular curves for outer circular rebars:
number_out_bars = int((2 * pi * out_rebar_radius) // (l - 50 * cir_diameter))
remainder_out_bar = round((2 * pi * out_rebar_radius) - (l - 50 * cir_diameter) * number_out_bars + 50 * cir_diameter, 3)
out_circ_bars = [12] * number_out_bars + [remainder_out_bar]
start_angles = [(l - 50 * cir_diameter) / out_rebar_radius * n for n in range(number_out_bars + 1)]
end_angles = map(sum, zip([bar / out_rebar_radius for bar in out_circ_bars], start_angles))

out_cir_Arc = []
end_out_cir_Arc = []
for i,j in zip(start_angles, end_angles):
    out_arc = Arc.Create(center1.Multiply(3.28084), out_rebar_radius*3.28084, i, j, XYZ(1, 0, 0), XYZ(0, 1, 0))
    out_cir_Arc.append(out_arc)
        
v_path = Line.CreateBound(XYZ(out_rebar_radius * 3.28084 , 0, (cover + 1.5 * V_diameter + hook_bend/2) * 3.28084), XYZ(out_rebar_radius * 3.28084 , 0, H1 )).Length/3.28084


cir_rebar_count = int(ceil(v_path /H_s))


out_cir_rebar = []
out_cir_Vect = []
for i in range(cir_rebar_count):
    temp1 = []
    for c in out_cir_Arc:
        e = 0
        e = i * H_s
        print(e)
        circ_offset = Transform.CreateTranslation(out_vert_bar.Direction.Normalize().Multiply(e * 3.28084))
        c = c.CreateTransformed(circ_offset)
        temp1.append(c.ToProtoType())
    out_cir_rebar.append(temp1)
    if v_path - e < H_s/2:
        out_cir_rebar = out_cir_rebar[-1]
        

OUT = out_cir_rebar

Be kind to check my rvt and dyn file below:

circular_rebar.dyn (20.1 KB)
Shaft_test.rvt (7.4 MB)

Thanks in advance for your help.

Wow, how to possibly debug such compex Python inside Dynamo? Might it help to break it down into smaller chunks and nodes? Also maybe debugging the math & logic in Python outside of Revit could help.

Also:

This line is your problem - it replaces the full list with only the last element
Review this Stack Overflow answer for examples of how to slice

The code is also doing multiples of operations which are unnecessary:

  • Not required e = 0, print(e)
  • Can move line into the loop above e = i * H_s,
  • Create the translation with circ_offset = Transfrom.CreateTranslation(XYZ(0, 0, e * 3.28084)) and locate in the loop above
1 Like

Refactored, assuming the translation is always vertical

for i in range(cir_rebar_count):
    temp1 = []
    e = i * H_s
    if v_path - e >= H_s/2:
        circ_offset = Transform.CreateTranslation(XYZ(0, 0, e * 3.28084))
        for c in out_cir_Arc:
            bar = c.CreateTransformed(circ_offset)
            temp1.append(bar.ToProtoType())
        out_cir_rebar.append(temp1)
2 Likes

Effectively, the syntax I have written logically takes only the last item!!..I forgot to put " : " and wrote the correct syntax: " out_cir_rebar = out_cir_rebar[:-1] ", which also solves the problem in addition to your solution.

Thanks.