Create Structural Framing with Python Got Error TypeError: expected XYZ, got Line

Hello

I am trying to create a Structural Framing with Python
But got error : TypeError: expected XYZ, got Line
I tried several thing to change a line to XYZ

Python code:

# Enable Python support and load DesignScript library
import clr  #Imports Ironpython's Common Language Runtime module
import sys
sys.path.append(r"C:\Program Files (x86)\IronPython 2.7\Lib")

# Import Autodesk DesingScript.Geometry deze 3 regels zijn nodig om alle functies/nodes van DesignScript in te laden  ook import Autodesk
clr.AddReference('ProtoGeometry')    # Imports DesignScript Dll Assembly
import Autodesk
from Autodesk.DesignScript.Geometry import *	# Import the classes bijv: Vector, Circle of * als je alles in laad 

# Import RevitAPI Classes :  
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *		# (from Autodesk.Revit import DB  zou ook kunnen = het zelfde)	

clr.AddReference('RevitAPIUI') 
from Autodesk.Revit.UI import *

# Import DocumentManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
# Import RevitNodes :
clr.AddReference("RevitNodes")
import Revit
from Revit import *
# Adds ToDSType (bool) extention method to Wrapped elements
clr.ImportExtensions(Revit.Elements)
# Import ToProtoType, ToRevitType geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)
# Import ???
clr.ImportExtensions(Revit.GeometryReferences)
# Import DSCoreNodes :
clr.AddReference("DSCoreNodes")
import DSCore
from DSCore import *
# important vars, dynamo version
#-------------------------------
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument
app = uiapp.Application
view = uidoc.ActiveView 

ADG = Autodesk.DesignScript.Geometry
PByC = Autodesk.DesignScript.Geometry.Point.ByCoordinates
LBySE = Autodesk.DesignScript.Geometry.Line.ByStartPointEndPoint

# output unit
unit = DisplayUnitType.DUT_MILLIMETERS

# The inputs to this node will be stored as a list in the IN variables.
StrFrType2eVerd = UnwrapElement(IN[0])
			#					SELECT LEVELS IN DOCUMENT
outputLevels = []
levels = []
LevelNames = []
areas = []
elevations = []
elementids = []

collector = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Levels).OfClass(Level)

famtypeitr = collector.GetElementIdIterator()
famtypeitr.Reset()
	# unit / IniUtils is om van revit internal units naar mm te converteren 
unit = DisplayUnitType.DUT_MILLIMETERS
for item in famtypeitr:
	famtypeID = item
	faminst = doc.GetElement(famtypeID)
 	level = faminst
	levelname = faminst.Name
	elevation = faminst.Elevation
	elementid = faminst.Id  	
	levels.append(level)
	LevelNames.append(levelname)
	elevations.append(UnitUtils.ConvertFromInternalUnits(elevation, unit))
	elementids.append(elementid)
outputLevels.append(levels)
outputLevels.append(LevelNames)
outputLevels.append(elevations)
outputLevels.append(elementids)
# SELECT LEVEL:
for Elem, Name, Elev in zip(outputLevels[0], outputLevels[1], outputLevels[2]):
	if Name == "02 bk. ruwe vloer":
		Level02bkRuweVloerElem = Elem
		Level02bkRuweVloerName = Name
		Level02bkRuweVloerElev = Elev	

startPoint = XYZ(0, 0, 0)
endPoint = XYZ(10000, 10, 10)

line = Autodesk.Revit.DB.Line.CreateBound(startPoint, endPoint)
#line.ToXyz()
line2 = LBySE(PByC(0, 0, 0), PByC(1000, 0, 0))
line2.ToRevitType()

fsymbol = FilteredElementCollector(doc).OfClass(FamilySymbol).OfCategory(BuiltInCategory.OST_StructuralFraming).ToElements()[0]

#transaction start
TransactionManager.Instance.EnsureInTransaction(doc);
	#create beam
#beam = doc.Create.NewFamilyInstance(line2.ToXyz(), IN[0], Level02bkRuweVloerElem, Structure.StructuralType.Beam)
beam = doc.Create.NewFamilyInstance(line2, IN[0], Level02bkRuweVloerElem, Structure.StructuralType.Beam)
#transaction end
TransactionManager.Instance.TransactionTaskDone();

OUT = fsymbol, beam

Hi nico,

I think this will help you. I beleive the correct workflow is the following:
1: place (invisible because pointhas no length) beam on XYZ point.
2: then assinging a curve/line to the framing element.

https://forums.autodesk.com/t5/revit-api-forum/create-new-instance-of-structural-framing/td-p/7172793

Hello @walraven.timo i tried youre workflow. But i still can not get it to work.
But according to th guide to placing family instances with the api . The workflow i first tried is the recommended method to create Beams and Braces.

Strange behavior

I could not manage to get it to work.
So i tried to create a beam with a node from archilab from @Konrad_K_Sobon
that node does not work either. But when i first run the OOTB node StructuralFraming.BeamByCurve (that node is creating a beam) and then delete the ootb node and after that i run the StructuralFraming.BeamByCurve from Archilab then the archilab node is creating a beam.

Why is this happening?

Code from Archilab:

# Copyright(c) 2015, Konrad K Sobon
# @arch_laboratory, http://archi-lab.net

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

# Import Element wrapper extension methods
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

# Import geometry conversion extension methods
clr.ImportExtensions(Revit.GeometryConversion)

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *

import System
from System import Array
from System.Collections.Generic import *

import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)

#The inputs to this node will be stored as a list in the IN variable.
dataEnteringNode = IN
dsObjects = IN[0]
_symbol = UnwrapElement(IN[1])
_level = UnwrapElement(IN[2])

def toRvtPoint(point):
	unitsFactor = 3.28084 #Revit works in Feet while Dynamo in Meters
	x = point.X * unitsFactor
	y = point.Y * unitsFactor
	z = point.Z * unitsFactor
	return XYZ(x,y,z)

def toRvtType(dsObject):
	if type(dsObject) == NurbsCurve:
		points = dsObject.ControlPoints()
		rvtPoints = List[XYZ]()
		for i in points:
			rvtPoints.Add(toRvtPoint(i))
		weights = dsObject.Weights()
		rvtWeights = List[float](weights)
		knots = dsObject.Knots()
		rvtKnots = List[float](knots)
		degree = int(dsObject.Degree)
		cClosed = dsObject.IsClosed
		rational = dsObject.IsRational
		return Autodesk.Revit.DB.NurbSpline.Create(rvtPoints, rvtWeights, rvtKnots, degree, cClosed, rational)
	elif type(dsObject) == Arc:
		#convert DS Arc to Revit Arc
		startPt = toRvtPoint(dsObject.StartPoint)
		endPt = toRvtPoint(dsObject.EndPoint)
		midPt = toRvtPoint(dsObject.PointAtParameter(0.5))
		return Autodesk.Revit.DB.Arc.Create(startPt, endPt, midPt)
	elif type(dsObject) == Line:
		#convert DS Line to Revit Line
		startPt = toRvtPoint(dsObject.StartPoint)
		endPt = toRvtPoint(dsObject.EndPoint)
		return Autodesk.Revit.DB.Line.CreateBound(startPt, endPt)
	elif type(dsObject) == Circle:
		#convert DS Circle to Revit Arc (for arcs with 2pi range will be automatically converted to circle)
		center = toRvtPoint(dsObject.CenterPoint)
		radius = dsObject.Radius * 3.28084 #converted to FT from M
		startAngle = 0
		endAngle = 2 * math.pi
		xAxis = XYZ(1,0,0) #has to be normalized
		yAxis = XYZ(0,1,0) #has to be normalized
		return Autodesk.Revit.DB.Arc.Create(center, radius, startAngle, endAngle, xAxis, yAxis)
	elif type(dsObject) == NurbsCurve and dsObject.Degree < 3:
		points = []
		subCurves = dsObject.DivideEqually(26)
		for i in subCurves:
			points.append(i.StartPoint)
		points.insert(len(points), subCurves[(len(subCurves)-1)].EndPoint)
		controlPoints = List[XYZ]()
		for i in points:
			controlPoints.Add(toRvtPoint(i))
		tangents = Autodesk.Revit.DB.HermiteSplineTangents()
		endTangent = toRvtPoint(dsObject.TangentAtParameter(1))
		startTangent = toRvtPoint(dsObject.TangentAtParameter(0))
		tangents.EndTangent = endTangent.Normalize()
		tangents.StartTangent = startTangent.Normalize()
		return Autodesk.Revit.DB.HermiteSpline.Create(controlPoints, False, tangents)
	elif type(dsObject) == PolyCurve:
		subCurves = dsObject.Curves()
		points = []
		for i in subCurves:
			points.append(i.PointAtParameter(0))
			points.append(i.PointAtParameter(1))
		points = Autodesk.DesignScript.Geometry.Point.PruneDuplicates(points,0.01)
		points = process_list(toRvtPoint, points)
		rvtPoints = List[XYZ](points)
		return Autodesk.Revit.DB.PolyLine.Create(rvtPoints)	
	else:
		return dsObject.ToRevitType()

def process_list(_func, _list):
	return map( lambda x: process_list(_func, x) if type(x)==list else _func(x), _list )

try:
	errorReport = None
	TransactionManager.Instance.EnsureInTransaction(doc)
	
	rvtLines = process_list(toRvtType, dsObjects)
	
	elementsOut = []
	for i in rvtLines:
		try:
			instance = doc.Create.NewFamilyInstance(i, _symbol, _level, StructuralType.Beam)
			if instance != None:
				elementsOut.append(instance)
		except:
			pass
	TransactionManager.Instance.TransactionTaskDone()
except:
	# if error accurs anywhere in the process catch it
	import traceback
	errorReport = traceback.format_exc()

#Assign your output to the OUT variable
if errorReport == None:
	OUT = elementsOut
else:
	OUT = errorReport

Got it.

one of the problem was that the familysymbol was not active
Thanks @Kulkul for: New to Python: "Exception: The symbol is not active" error

if _symbol.IsActive == False:
	_symbol.Activate()
	doc.Regenerate()

Nico

2 Likes