How can Create StructuralFaming elements with startspoints and endpoints

I used StructuralFaming.BeamByCurve Nodes in Dynamo (Revit 2024) to Create the structuralFramingType that is line based. But now I wanna create it by Pyhon Codes(using Python Script Nodes in Dynamo) with Coordinates xyz. So First, I create Lines with Start Points and End Points and so the follow Steps corresponding to Codes Below. But when I run it. The Output Result is ‘EmptyList’. Plz help me. In StructuralFraming.BeamByCurve, there are Three inputs that are curve, level, structuralFramingType. However what I want is ‘curve’ input is replaced by Coords xyz that I said before. Level is fixed that named ‘1F’ and structuralFramingType is variable thing so I wanna find the correct familyInstance and use it that already loaded in Revit Project.

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

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

doc = DocumentManager.Instance.CurrentDBDocument

# 입력값 가져오기
StartPoints = IN[0]
EndPoints = IN[1]

# Level 가져오기 (1F로 고정)
level = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).WhereElementIsElementType().FirstElement()

# Enable to Get Information about Loaded Family Data in the Revit Project
collector = FilteredElementCollector(doc)
collector.OfCategory(BuiltInCategory.OST_StructuralFraming)
familyTypes = collector.OfClass(FamilySymbol).ToElements()

# Transaction 시작
TransactionManager.Instance.EnsureInTransaction(doc)

# Beam 생성
# Create foundationInstances of Pillar Foundation

# FamilySymbol 가져오기 (원하는 FamilyName 및 FamilyType으로 필터링)
Framing_Name = "PSC_거더_표준패밀리_NonRadius"
Framing_Type = "PSC_거더_표준패밀리_NonRadius"

beams = []
for typ in familyTypes:
    typeName = typ.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM).AsString()

    # Check if family matches with the given Name and Type.
    if typ.Family.Name == Framing_Name and typeName == Framing_Type:
        if typ.IsActive == False:
            typ.Activate()
            doc.Regenerate()

            for i in range(len(StartPoints)):
                # Dynamo 점을 XYZ 형식으로 변환
                start_point_xyz = XYZ(StartPoints[i].X, StartPoints[i].Y, StartPoints[i].Z)
                end_point_xyz = XYZ(EndPoints[i].X, EndPoints[i].Y, EndPoints[i].Z)

                # Line 요소 생성
                line = Line.CreateBound(start_point_xyz, end_point_xyz)

                structuralType = Structure.StructuralType.Structural

                # StructuralFraming.BeamByCurve 메서드를 사용하여 Beam 생성
                beam = StructuralFraming.BeamByCurve(doc, line, familyTypes, level)
                beams.append(beam)

# Transaction 종료
TransactionManager.Instance.TransactionTaskDone()

# 결과 출력 (선택 사항)
OUT = beams
1 Like

The code you provided has a potential issue with how it’s using the StructuralFraming.BeamByCurve method. This method expects a curve as input, not a list of family types. Here’s how you can fix the code to create beams using coordinates:

`Pythonimport clr
clr.AddReference(‘RevitAPI’)
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *

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

doc = DocumentManager.Instance.CurrentDBDocument

입력값 가져오기

StartPoints = IN[0]
EndPoints = IN[1]

Level 가져오기 (1F로 고정)

level = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).WhereElementIsElementType().FirstElement()

Enable to Get Information about Loaded Family Data in the Revit Project

collector = FilteredElementCollector(doc)
collector.OfCategory(BuiltInCategory.OST_StructuralFraming)
familyTypes = collector.OfClass(FamilySymbol).ToElements()

Transaction 시작

TransactionManager.Instance.EnsureInTransaction(doc)

Beam 생성

beams =
for i in range(len(StartPoints)):

Dynamo 점을 XYZ 형식으로 변환

start_point_xyz = XYZ(StartPoints[i].X, StartPoints[i].Y, StartPoints[i].Z)
end_point_xyz = XYZ(EndPoints[i].X, EndPoints[i].Y, EndPoints[i].Z)

Line 요소 생성

line = Line.CreateBound(start_point_xyz, end_point_xyz)

Find the desired FamilySymbol based on name and type

desired_family = None
for typ in familyTypes:
typeName = typ.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM).AsString()
if typ.Family.Name == Framing_Name and typeName == Framing_Type:
desired_family = typ
break

Check if desired family is found

if desired_family:
# StructuralFraming.BeamByCurve 메서드를 사용하여 Beam 생성
beam = StructuralFraming.BeamByCurve(doc, line, level, desired_family)
beams.append(beam)
else:
print(“Warning: Could not find family”, Framing_Name, Framing_Type)

Transaction 종료

TransactionManager.Instance.TransactionTaskDone()

결과 출력 (선택 사항)

OUT = beams`

Use code with caution.

content_copy

Changes made:

  • The code iterates through each pair of start and end points.
  • It creates a Line element using Line.CreateBound.
  • It searches for the desired family type based on Framing_Name and Framing_Type.
  • If the family is found, it uses StructuralFraming.BeamByCurve with the line, level, and the desired familySymbol.
  • It adds the created beam to the beams list.
  • If the family is not found, it prints a warning message.

This code should create beams using the provided coordinates and the desired family type (if found) within a transaction.

Thanks for trying to help out @steinryan28 - but your code is suffering from a lack of formatting due to how you’re providing the code. You might want to consider using the preformatted text option as it will make it easier for the people you’re helping out. This animation shows how to do so on the forum (note that many other forums, messaging services and the like have similar options in their UIs as well):

preformatted Text

This is particularly important with code as indentation matters, and in the samples above there is no indentation.

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

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

doc = DocumentManager.Instance.CurrentDBDocument

# 입력값 가져오기
StartPoints = IN[0]
EndPoints = IN[1]

# Level 가져오기 (1F로 고정)
level = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).WhereElementIsElementType().FirstElement()

# Enable to Get Information about Loaded Family Data in the Revit Project
collector = FilteredElementCollector(doc)
collector.OfCategory(BuiltInCategory.OST_StructuralFraming)
familyTypes = collector.OfClass(FamilySymbol).ToElements()

# Transaction 시작
TransactionManager.Instance.EnsureInTransaction(doc)

# Beam 생성
beams = []
for i in range(len(StartPoints)):
  # Dynamo 점을 XYZ 형식으로 변환
  start_point_xyz = XYZ(StartPoints[i].X, StartPoints[i].Y, StartPoints[i].Z)
  end_point_xyz = XYZ(EndPoints[i].X, EndPoints[i].Y, EndPoints[i].Z)

  # Line 요소 생성
  line = Line.CreateBound(start_point_xyz, end_point_xyz)

  # Find the desired FamilySymbol based on name and type
  desired_family = None
  for typ in familyTypes:
    typeName = typ.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM).AsString()
    if typ.Family.Name == Framing_Name and typeName == Framing_Type:
      desired_family = typ
      break

  # Check if desired family is found
  if desired_family:
    # StructuralFraming.BeamByCurve 메서드를 사용하여 Beam 생성
    beam = StructuralFraming.BeamByCurve(doc, line, level, desired_family)
    beams.append(beam)
  else:
    print("Warning: Could not find family", Framing_Name, Framing_Type)

# Transaction 종료
TransactionManager.Instance.TransactionTaskDone()

# 결과 출력 (선택 사항)
OUT = beams

Looks like you have some errors around line 41 - have you confirmed this works?

1 Like

It still doesn’t work.I fixed the Codes like

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

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

doc = DocumentManager.Instance.CurrentDBDocument

# 입력값 가져오기
StartPoints = IN[0]
EndPoints = IN[1]

# Level 가져오기 (1F로 고정)
level = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).WhereElementIsElementType().FirstElement()


# Enable to Get Information about Loaded Family Data in the Revit Project
collector = FilteredElementCollector(doc)
collector.OfCategory(BuiltInCategory.OST_StructuralFraming)
familyTypes = collector.OfClass(FamilySymbol).ToElements()

# Transaction 시작
TransactionManager.Instance.EnsureInTransaction(doc)

Framing_Name = "PSC_거더_표준패밀리_NonRadius"
Framing_Type = "PSC_거더_표준패밀리_NonRadius"
level_Name = "1F"

# Beam 생성
beams = []
for i in range(len(StartPoints)):
    # Dynamo 점을 XYZ 형식으로 변환
    start_point_xyz = XYZ(StartPoints[i].X, StartPoints[i].Y, StartPoints[i].Z)
    end_point_xyz = XYZ(EndPoints[i].X, EndPoints[i].Y, EndPoints[i].Z)

    # Line 요소 생성
    line = Line.CreateBound(start_point_xyz, end_point_xyz)

    # Find the desired FamilySymbol based on name and type
    desired_family = None
    for typ in familyTypes:
        typeName = typ.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM).AsString()
        if typ.Family.Name == Framing_Name and typeName == Framing_Type:
            desired_family = typ
            break

  # Check if desired family is found
    if desired_family:
        # StructuralFraming.BeamByCurve 메서드를 사용하여 Beam 생성
        beam = StructuralFraming.BeamByCurve(doc, line, level_Name, desired_family)
        beams.append(beam)
    else:
        print("Warning: Could not find family", Framing_Name, Framing_Type)

# Transaction 종료
TransactionManager.Instance.TransactionTaskDone()

# 결과 출력 (선택 사항)
OUT = beams

In my guess, There’s no name of level…So, Doesn’t it work? I’ve no idea. Maybe I’m supposed to pass and move to next work.