Placing Lights from Excel using Python having issues with multiple family types

Following on from @Kulkul python code in the following thread;

[FamilyInstance.ByPoint overwrites]

I had been previously using the FamilyInstance.ByPointAndLevel OOTB node, but found the behavior is not consistent and will sometimes run really slow despite very similar inputs.

The Python Kulkil posted is significantly faster but the node only runs when the input is a single family type, when multiple family types are input it throws up an error “ExpectedFamilySymbol, got list”.

Does there need to be another loop within the Python code for the Family Types to simulate running the python lacing as longest, or should the inputs be grouped by key for each kind of family type to create?

It all depends. If all your fixtures use the same type you can supply a single FamilySymbol and just loop through the points. If your fixtures vary in type then you’ll need to include a FamilySymbol for each instance and loop through each pair of symbols and points. Same thing would go for levels.

There’s around 200 lights per floor, but only 3 types.

The python code from @Kulkul is below, would I have to write a loop for each type of family in the list of families to be created?

import clr

clr.AddReference("RevitServices")
clr.AddReference("RevitNodes")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc =  DocumentManager.Instance.CurrentDBDocument

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

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


def ptslist(obj1):
	if hasattr(obj1,"__iter__"): return obj1
	else: return [obj1]

famType = UnwrapElement(IN[0])
pts = ptslist(IN[1])
lvl = UnwrapElement(IN[2])

elems = []

for pt in pts:
	TransactionManager.Instance.EnsureInTransaction(doc)
	elems.append(doc.Create.NewFamilyInstance(pt.ToRevitType(True), famType, lvl, Structure.StructuralType.NonStructural))
	TransactionManager.Instance.TransactionTaskDone()
	
OUT = elems

So the loop becomes something like the code below, forgive my use of python as I’ve barely used it before.

for pt in pts:
	for fam in famType:
		TransactionManager.Instance.EnsureInTransaction(doc)
		elems.append(doc.Create.NewFamilyInstance(pt.ToRevitType(True), famType, lvl, Structure.StructuralType.NonStructural))
		TransactionManager.Instance.TransactionTaskDone()

I’ve set the input up to only run one one level at a time to make it simpler for the user.

You would have to loop for each instance (like you already do for pts) but you would need to include the type. It would look more like:

for pt,type in zip(pts,types):

This ensures that each new instances is created with the correct pairing of family type and location.

2 Likes