Create rebar shape from wall face

Hi All,

In the code below, I am trying to create a ‘U’ shape (as a model line for now) from a selected wall face, which I intend to use later for creating shape-driven rebar using the CreateFromCurves method. Is there a better approach or code logic for this, or can you suggest an alternative?

Rebar Shape U
import math
from Autodesk.Revit.DB import *
from System.Collections.Generic import IList, List
uidoc = __revit__.ActiveUIDocument

doc = uidoc.Document

# select all walls within the project
Walls = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToElements()

# get walls faces 
Faces = []
for w in Walls:
    face_Ref = list(HostObjectUtils.GetSideFaces(w, ShellLayerType.Interior))[0]
    wall_face = w.GetGeometryObjectFromReference(face_Ref)
    Faces.append(wall_face)
    
# choose one face end get its edges serving as the base of creating the searched rebar shape

face = Faces[0]

boundary = face.EdgeLoops[0]

edges = []

for edge in boundary:
    edges.append(edge.AsCurve())

# iterate over the edges list and choose the first vertical edge as a begening curve for the rebar shape
for idx, edge in enumerate(edges):
    if idx == 3:
        edges = edges[idx:] + edges[:idx]

# obtaining the searched rebar shape " U "
edges = edges[:-1]

curves = []

#Creating a temporary 2D plane to visualize the rebar shape

Points = [i.GetEndPoint(0) for i in edges]

plan = Plane.CreateByThreePoints(Points[0], Points[1], Points[2])

# get the Normal of the plane for calculation purposes
Ref_vect = plan.Normal.Normalize()

# Differentiate the horizontal curve from the two vertical ones for calculation purposes.
horiz_vect = [e.Direction for e in edges if e.GetEndPoint(0).Z == e.GetEndPoint(1).Z][0]

# Create a transformation function to obtain the final rebar shape from the offset face edges  
def trans(vector, cover):
    t = Transform.CreateTranslation(vector.Normalize().Multiply(cover))
    return(t)

curves = []

# offset distance c1 for the vertical edge 
c1 = 0.1/0.3048

# offset distance c2 for the horizontal edge 
c2 = 0.1/0.3048

# create the final rebar shape " U " 
for e in edges:
    st_pt = e.GetEndPoint(0)
    End_pt = e.GetEndPoint(1)
    direct = e.Direction
    vect = direct.CrossProduct(Ref_vect)
    # select the horizontal edge and offset it with the desired parameters
    if direct.IsAlmostEqualTo(horiz_vect):
        e = e.CreateTransformed(trans(vect, c2))
        param1 = c1/e.Length
        param2 = 1 - param1
        st_pt = e.Evaluate(param1, True)
        End_pt = e.Evaluate(param2, True)
        e = Line.CreateBound(st_pt, End_pt)
        curves.append(e)
    # select the vertical edges and offset them with the desired parameters    
    else:
        # check if the two vertical edge have the same orientation 
        if direct.IsAlmostEqualTo(XYZ.BasisZ) :
            if vect.IsAlmostEqualTo(horiz_vect):
                vect = vect.Negate()
                e = e.CreateTransformed(trans(vect, c1))
                # new start point for the offseted curve
                p = XYZ(e.GetEndPoint(0).X, e.GetEndPoint(0).Y, e.GetEndPoint(0).Z - c2)
                e = Line.CreateBound(p, e.GetEndPoint(1)) 
                curves.append(e)
        else: 
            e= Line.CreateBound(End_pt, st_pt)
            vect = vect.Negate()
            e = e.CreateTransformed(trans(vect, c1))
            # new start point for the offseted curve
            p = XYZ(e.GetEndPoint(0).X, e.GetEndPoint(0).Y, e.GetEndPoint(0).Z - c2)
            e = Line.CreateBound(p, e.GetEndPoint(1)) 
            curves.append(e)
            
# create a sketch plan to temporary visualize the rebar shape         
with Transaction(doc, 'create Sketch plan') as t:
    t.Start()
    skp = SketchPlane.Create(doc, plan)
    t.Commit()
print(skp)

# create a tomporary model lines to visualize the rebar shape
Lines = []
with Transaction(doc, 'create Model Lines') as t:
    t.Start()
    for l in curves:
        Ml = doc.Create.NewModelCurve(l, skp)
        Lines.append(Ml)
    t.Commit()

PS: I can’t attach the Revit Model for testng the code/?

Thanks.

If it can help, here the code I used to create my model

import math
from Autodesk.Revit.DB import *
from System.Collections.Generic import IList, List
uidoc = __revit__.ActiveUIDocument

doc = uidoc.Document

wall_Type_Id = doc.GetDefaultElementTypeId(ElementTypeGroup.WallType)

def_wall_Type = doc.GetElement(wall_Type_Id)

floor_Type_Id = doc.GetDefaultElementTypeId(ElementTypeGroup.FloorType)

def_floor_Type = doc.GetElement(floor_Type_Id)

levels = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).WhereElementIsNotElementType().ToElements()

materials = FilteredElementCollector(doc).WherePasses(ElementCategoryFilter(BuiltInCategory.OST_Materials))

material = [i for i in materials if i.Name == "Béton - Coulé sur place - Béton20"]

if len(material) > 0:
    mat = material[0]
    m_Id = mat.Id
else:
    with Transaction(doc, 'Get/create concrete material') as t:
        t.Start()
        m_Id = Material.Create(doc, "Béton - Coulé sur place - Béton20")
        mat = doc.GetElement(m_Id)
        mat.MaterialClass = "Béton"
        mat.MaterialCategory = "Béton"
        mat.Color = Color(192,192,192)
        mat.Shininess = 128
        mat.Smoothness = 50
        asset = StructuralAsset("ConcreteStructuralAsset", StructuralAssetClass.Concrete)
        asset.ConcreteCompression = UnitUtils.ConvertToInternalUnits(20, UnitTypeId.Megapascals)
        asset.Density = UnitUtils.ConvertToInternalUnits(2500, UnitTypeId.KilogramsPerCubicMeter)
        asset.SetPoissonRatio(0.2)
        asset.SetYoungModulus(UnitUtils.ConvertToInternalUnits(11000*20**(1/3), UnitTypeId.Megapascals))
        struc = PropertySetElement.Create(doc, asset)
        mat.SetMaterialAspectByPropertySet(MaterialAspect.Structural, struc.Id)
        appar_Id = ElementId(177984)
        mat.AppearanceAssetId = appar_Id
        t.Commit()
    
level = [l for l in levels if l.LookupParameter('Elévation').AsValueString() == '0.00' or l.LookupParameter('Elévation').AsDouble() == 0]

if len(level) > 0:
    lvl = level[0]
    lvl_Id = lvl.Id
# Create Points and Lines:

c = 1/0.3048
Thick_wall = 0.20

Pt0 = XYZ(-(0.60 + Thick_wall/2)*c,-(0.60 + Thick_wall/2)*c,0)

c0 = XYZ(-(0.60 + Thick_wall)*c,-(0.60 + Thick_wall)*c,0)

Pt1 = XYZ((0.60 + Thick_wall/2)*c,-(0.60 + Thick_wall/2)*c,0)

c1 = XYZ((0.60 + Thick_wall)*c,-(0.60 + Thick_wall)*c,0)

Pt2 = XYZ((0.60 + Thick_wall/2)*c, (0.60 + Thick_wall/2)*c,0)

c2 = XYZ((0.60 + Thick_wall)*c, (0.60 + Thick_wall)*c,0)

Pt3 = XYZ(-(0.60 + Thick_wall/2)*c,(0.60 + Thick_wall/2)*c,0)

c3 = XYZ(-(0.60 + Thick_wall)*c,(0.60 + Thick_wall)*c,0)


Lines = []

crvs = []
Line1 = Line.CreateBound(Pt0, Pt1)
Lines.append(Line1)

crv1 = Line.CreateBound(c0, c1)
crvs.append(crv1)

Line2 = Line.CreateBound(Pt1, Pt2)
Lines.append(Line2)

crv2 = Line.CreateBound(c1, c2)
crvs.append(crv2)

Line3 = Line.CreateBound(Pt2, Pt3)
Lines.append(Line3)

crv3 = Line.CreateBound(c2, c3)
crvs.append(crv3)

Line4 = Line.CreateBound(Pt3, Pt0)
Lines.append(Line4)

crv4 = Line.CreateBound(c3, c0)
crvs.append(crv4)

sloop = Line.CreateBound(XYZ(0,0,0), XYZ(c*1,0,0))

loop = CurveLoop()

for crv in crvs:
    loop.Append(crv)
    
curves = [loop]

# Create Plane and Sketch_plan:
normal = XYZ.BasisZ

origin = XYZ.Zero
geomPlane = Plane.CreateByNormalAndOrigin(normal, origin)

with Transaction(doc, 'create Manhole') as t:
    t.Start()
    voile_BA_20 = def_wall_Type.Duplicate('voile-BA_20')
    Dalle_BA_20 = def_floor_Type.Duplicate('Dalle_BA_20')
    cs1 = voile_BA_20.GetCompoundStructure()
    cs2 = Dalle_BA_20.GetCompoundStructure()

    for structLayer1, structLayer2 in zip(cs1.GetLayers(), cs2.GetLayers()):
        cs1.SetLayerFunction(structLayer1.LayerId, MaterialFunctionAssignment.Structure)
        cs1.SetMaterialId(structLayer1.LayerId, m_Id)
        cs1.SetLayerWidth(0, Thick_wall*c)
        cs2.SetLayerFunction(structLayer2.LayerId, MaterialFunctionAssignment.Structure)
        cs2.SetMaterialId(structLayer2.LayerId, m_Id)
        cs2.SetLayerWidth(0, Thick_wall*c)
        
    voile_BA_20.SetCompoundStructure(cs1)
    Dalle_BA_20.SetCompoundStructure(cs2)
#SKP = SketchPlane.Create(doc, geomPlane)

# Create Model Lines:

#Mod_lines = [doc.Create.NewModelCurve(i, SKP) for i in Lines]

    for l in Lines:
        Wall = Wall.Create(doc, l, voile_BA_20.Id, lvl_Id, c*2.00,0.00, False, True)
    bot_floor = Floor.Create(doc, curves, Dalle_BA_20.Id, lvl_Id, True, sloop, 0)    
# Create walls:
    t.Commit()

Thanks.