Hi All,
I created a script which generate rebars for a manhole as shown in the image below
I am currently seeking a more efficient logic and approach to reduce the length of my code. I attempted to iterate over the four walls using a main "for loop
" and create curve loops (curveloop1
, curveloop2
, H_Loop
) as described in my code, but it has proven challenging. Therefore, I request your assistance in achieving this.
Here my code:
Manhole_rebars
import math
import clr
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *
from System.Collections.Generic import IList, List, Dictionary
from System import Array
uidoc = __revit__.ActiveUIDocument
results = clr.Reference[IntersectionResultArray]()
doc = uidoc.Document
units = doc.GetUnits().GetFormatOptions(SpecTypeId.Length).GetUnitTypeId()
# select all walls within the project
walls = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToElements()
width = walls[0].Width
# select all floors within the project
floors = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Floors).WhereElementIsNotElementType().ToElements()
# get floor width for the first floor
floor_width = floors[0].get_Parameter(BuiltInParameter.FLOOR_ATTR_THICKNESS_PARAM).AsDouble()
# select all rebars types within the project
rebar_Types = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rebar).WhereElementIsElementType().ToElements()
# get the rebar type "HA12 (Fe400)" and it's diameter
rebar_Type = [r for r in rebar_Types if Element.Name.GetValue(r) == "HA12 (Fe400)"][0]
rebar_diameter = rebar_Type.BarModelDiameter
# covers parameters
c1 = width/2 + UnitUtils.ConvertToInternalUnits(0.05, units)
c2 = (floor_width - UnitUtils.ConvertToInternalUnits(0.05, units))
d2 = c2 + rebar_diameter
c3 = UnitUtils.ConvertToInternalUnits(0.05, units)
# spacing parameter
space = UnitUtils.ConvertToInternalUnits(0.15, units)
# create a curveloop from the first wall with the shape "|__|"
wall1 = walls[0]
bbx1 = wall1.get_BoundingBox(None)
h1 = bbx1.Max.Z - bbx1.Min.Z
temp_line1 = wall1.Location.Curve
param1 = rebar_diameter/temp_line1.Length
param2 = 1 - param1
lineB = Line.CreateBound(temp_line1.Evaluate(param1, True), temp_line1.Evaluate(param2, True))
paramA = c1/temp_line1.Length
paramB = 1 - paramA
# create path for repartition of the second CurveLoop "curveloop2"
path1 = Line.CreateBound(temp_line1.Evaluate(paramA, True), temp_line1.Evaluate(paramB, True))
vectB = XYZ(0,0, 1)
lineB = lineB.CreateTransformed(Transform.CreateTranslation(vectB.Multiply(-c2)))
vectZ = XYZ(0,0, h1 + c2)
lineA = Line.CreateBound(lineB.GetEndPoint(0).Add(vectZ), lineB.GetEndPoint(0))
lineC = Line.CreateBound(lineB.GetEndPoint(1), lineB.GetEndPoint(1).Add(vectZ))
# curveloop1 obtained
curveloop1 = CurveLoop.Create(List[Curve]([lineA, lineB, lineC]))
# Translate the curveloop1 to the start position before doing a multiple offset
plane1 = curveloop1.GetPlane()
trans1 = Transform.CreateTranslation(plane1.Normal.Negate().Multiply(c1))
curveloop1.Transform(trans1)
# create a curveloop from the second wall with the shape "|__|"
wall2 = walls[1]
bbx2 = wall2.get_BoundingBox(None)
h2 = bbx1.Max.Z - bbx1.Min.Z
temp_line2 = wall2.Location.Curve
param3 = rebar_diameter/temp_line2.Length
param4 = 1 - param1
lineE = Line.CreateBound(temp_line2.Evaluate(param3, True), temp_line2.Evaluate(param4, True))
paramC = c1/temp_line2.Length
paramD = 1 - paramC
path2 = Line.CreateBound(temp_line2.Evaluate(paramC, True), temp_line2.Evaluate(paramD, True))
vectE = XYZ(0,0, 1)
lineE = lineE.CreateTransformed(Transform.CreateTranslation(vectE.Multiply(-d2)))
vectZ = XYZ(0,0, h2 + c2)
lineD = Line.CreateBound(lineE.GetEndPoint(0).Add(vectZ), lineE.GetEndPoint(0))
lineF = Line.CreateBound(lineE.GetEndPoint(1), lineE.GetEndPoint(1).Add(vectZ))
# curveloop1 obtained
curveloop2 = CurveLoop.Create(List[Curve]([lineD, lineE, lineF]))
# Translate the curveloop2 to the start position before doing a multiple offset
plane2 = curveloop2.GetPlane()
trans2 = Transform.CreateTranslation(plane2.Normal.Negate().Multiply(c1))
curveloop2.Transform(trans2)
# __
#Create an horizontal CurveLoop as a rectangle "|__|"
line1 = temp_line1
end_pt1 = line1.GetEndPoint(1)
L = line1.Length
norm1 = line1.Direction.Normalize()
vect1 = (XYZ(end_pt1.X, end_pt1.Y, end_pt1.Z + L)).Subtract(end_pt1)
line2 = Line.CreateBound(end_pt1, end_pt1.Add((vect1).CrossProduct(norm1)))
end_pt2 = line2.GetEndPoint(1)
norm2 = line2.Direction.Normalize()
vect2 = (XYZ(end_pt2.X, end_pt2.Y, end_pt2.Z + L)).Subtract(end_pt2)
line3 = Line.CreateBound(end_pt2, end_pt2.Add((vect2).CrossProduct(norm2)))
end_pt3 = line3.GetEndPoint(1)
norm3 = line3.Direction.Normalize()
vect3 = (XYZ(end_pt3.X, end_pt3.Y, end_pt3.Z + L)).Subtract(end_pt3)
line4 = Line.CreateBound(end_pt3, end_pt3.Add((vect3).CrossProduct(norm3)))
# Horizontal curveloop "H_Loop" obtained
H_Loop = CurveLoop.Create(List[Curve]([line1, line2, line3, line4]))
# Translate the curveloop2 to the start position before doing a multiple offset
H_plane = H_Loop.GetPlane()
H_trans = Transform.CreateTranslation(H_plane.Normal.Multiply(c3))
H_Loop.Transform(H_trans)
# create path for repartition of the horizontal CurveLoop
temp_pt = temp_line1.GetEndPoint(0)
path3 = Line.CreateBound(XYZ(temp_pt.X, temp_pt.Y, temp_pt.Z + c3), XYZ(temp_pt.X, temp_pt.Y, temp_pt.Z + h1 - c3))
# define a function to create a multiple translation of a curveloop
def curveloop_Transform(curveloop, path, space):
n = path.Length // space
loop = [curveloop]
if curveloop.GetPlane().Normal.IsAlmostEqualTo(XYZ.BasisZ):
offset = loop[0].GetPlane().Normal.Multiply(space)
xform = Transform.CreateTranslation(offset)
else:
offset = loop[0].GetPlane().Normal.Negate().Multiply(space)
xform = Transform.CreateTranslation(offset)
count = 0
while count < n:
loop.append(loop[-1].CreateViaTransform(loop[-1], xform))
count += 1
return(loop)
# Multiple translation of the the curveloop1
loop1 = curveloop_Transform(curveloop1, path2, space)
# Multiple translation of the the curveloop2
loop2 = curveloop_Transform(curveloop2, path1, space)
# Multiple translation of the the curveloop3
loop3 = curveloop_Transform(H_Loop, path3, space)
# create Array Lists from Lists Curveloop
H_arrayIlist = List[CurveLoop]()
V_arrayIlist1 = List[CurveLoop]()
V_arrayIlist2 = List[CurveLoop]()
for i in loop3:
H_arrayIlist.Add(CurveLoop.Create([j for j in i]))
for i in loop1:
V_arrayIlist1.Add(CurveLoop.Create([j for j in i]))
for i in loop2:
V_arrayIlist2.Add(CurveLoop.Create([j for j in i]))
# create rebars
with Transaction(doc, 'create rebars') as t :
t.Start()
validationResult = clr.Reference[RebarFreeFormValidationResult]()
rebar1 = Rebar.CreateFreeForm(doc, rebar_Type, floors[0], H_arrayIlist, validationResult)
rebar2 = Rebar.CreateFreeForm(doc, rebar_Type, floors[0], V_arrayIlist1, validationResult)
rebar3 = Rebar.CreateFreeForm(doc, rebar_Type, floors[0], V_arrayIlist2, validationResult)
t.Commit()
Thanks.