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.