Creating column on a point using NewFamilyInstance

Hi everyone,

I’m trying to create columns on a bunch of points such that the columns are associated with a level which is created in the same graph. I’m doing this in a python node inside Dynamo but am getting the error shown in the image. I’ve tried running the script in architectural, structural and construction templates with the families available (just to check if it was not working for specific families) but it doesn’t seem to work.
In the attached script, I’m trying to do this for a single point for now.

What I’m using: Revit 2023 with US English Content for Revit 2023 installed (adds extra families), OOTB nodes only.

Could anybody tell me what could be the problem?

Attached graph:
create column - revit api.dyn (29.7 KB)

Hi @Aradhya_Singh ,

Is there a specific reason you are doing this through a Python script instead of the OOTB node?

Also, the error message states that you need to also supply a reference level because the family is a reference level-based family, have you tried adding the level?

PS: If you create levels in the same script you might have to add an Transaction.End node after that aswell.

1 Like

Hello @Aradhya_Singh

CPython3/PythonNet 2.5.x engine has issues with overload methods, try with IronPython2 engine instead

1 Like

Thank you for your suggestions, @Daan.

I’m using a Python node to do this because I want to create a framed structure based on the number of levels input by the user, as the end product. So, I thought to create the columns in a script and do a for loop for repeating it in the other levels. I’m not sure if there’s an OOTB node that can act in place of a for loop.

Now, if supplying a reference level means passing a level in the arguments for the Create.NewFamilyInstance command, then yes I’m doing it.

import clr 
import sys  
import System 

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

clr.AddReference("RevitNodes") 

import Revit 
clr.ImportExtensions(Revit.Elements) 
clr.ImportExtensions(Revit.GeometryConversion) 

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

clr.AddReference("RevitAPI") 

import Autodesk 
from Autodesk.Revit.DB import * 
from Autodesk.Revit.DB.Structure import *
  

doc = DocumentManager.Instance.CurrentDBDocument 

#Inputs to node

#famtype=UnwrapElement(IN[0])
points =UnwrapElement(IN[1])

columns=FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns).WhereElementIsElementType().ToElements()#get all column types

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

TransactionManager.Instance.EnsureInTransaction(doc)

for column in columns: 
	column_name=column.get_Parameter(BuiltInParameter.ALL_MODEL_FAMILY_NAME).AsString()
	#if column_name=="UC-Universal Columns-Column":
	column_type=column
	
if column_type.IsActive == False:
    column_type.Activate()
    doc.Regenerate()

point = points[0]
    
mycolumn=doc.Create.NewFamilyInstance(XYZ(point.X, point.Y, point.Z), column_type, levels[0], Structure.StructuralType.Column)

TransactionManager.Instance.TransactionTaskDone()

OUT = mycolumn

I should’ve pasted the code in the question also to make it easier to see I guess.

I also added a Transaction.End node after creating the levels but I still get the error.
Another thread suggested connecting the output of the Transaction.End to a dummy input in the python node, so that it’s computed only after the levels are created. That didn’t work too.

Please let me know if I can try something else too.

Thank you for your reply @c.poupin .

I’ve tried running the same script with IronPython2 this time but the error remains.

More suggestions are welcome.

Its necessary to click ‘save’ to apply the new selected engine

Have you tried adding this aswell?

Also, you probably don’t need a for loop, when you use the OOTB node you could add multiple objects on multiple (revit) levels using list levels/ lacing.

It works now !!
Thanks a lot, @c.poupin .

1 Like

Yes, I did try supplying the level along with adding a Transaction.End node. Now that the python script works with IronPython2, I think I’ll try going with it but I’ll look into using the OOTB nodes too after this.
Thanks a ton for your time @Daan .

Glad to hear that! Weird that the error message says that it needs a level-input while that is not the case though.

1 Like

Hi all, I’m having a very very similar problem. I tried the solution above but still cannot make the column in Revit 2023.

Any Suggestion? @c.poupin? or anybody?

@c.poupin Is there any solution for this yet with Cpython? or is this just going to be an ongoing problem where Cpython works when it works, but just randomly it decides not to work in some cases. What i mean by random is that creation of a column using

doc.Create.NewFamilyInstance(XYZ, familytype, Level, Structure.StructuralType.Column)

exhibits a problem with the Level, but creation of a Beam using:

doc.Create.NewFamilyInstance(Line, familytype, Level, Structure.StructuralType.Beam)

works just fine and has the exact same Level as an input. Seems like the beam should have also failed with the same reference level input error as the column did.

Hi, @Ben_Osborne1
Assuming the arguments are correct type, apart from building your own Overload resolution (via Reflection), I don’t see another solution with PythonNet 2.x

To date, with .NetCore on the way I’d suggest the following

  • IronPython or C# for
    - working with the .Net environment
  • CPython/PythonNet for
    - data analysis, creation
    - geometry analysis, creation
    - to use some algorithm python packages

this is just my opinion, I may change if PythonNet3.0 is ever implemented in Dynamo

2 Likes