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
1 Like
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