Place Family Instance through the API

Hi, everyone!

I am trying to place family instances on a face, using the NewFamilyInstance Method (Reference, XYZ, XYZ, FamilySymbol) method.

Here’s the code:

familySymbol = UnwrapElement(IN[2])
refVector = XYZ(1, 0, 0)

for i, plFace in enumerate(IN[0]):
	#faceIfb = ItemFactoryBase(plFace)
	for surface in UnwrapElement(IN[1][i]):
		pt = UnwrapElement(IN[3][i])
		ItemFactoryBase.NewFamilyInstance(plFace, pt, refVector,  familySymbol)
		#ItemFactoryBase.NewFamilyInstance(faceIfb, pt, refVector,  familySymbol)

and I get the following error:

however, if I try to get an ItemFactoryBase object from the PlanarFace, here’s what happens:

familySymbol = UnwrapElement(IN[2])
refVector = XYZ(1, 0, 0)

for i, plFace in enumerate(IN[0]):
	faceIfb = ItemFactoryBase(plFace)
	for surface in UnwrapElement(IN[1][i]):
		pt = UnwrapElement(IN[3][i])
		#ItemFactoryBase.NewFamilyInstance(plFace, pt, refVector,  familySymbol)
		ItemFactoryBase.NewFamilyInstance(faceIfb, pt, refVector,  familySymbol)

It says it has no public constructor :tipping_hand_man:
is it then possible to do that through the API?

edit: forgot to mention what my inputs are

so they are PlanarFaces I already got through the API and didn’t wrap , the family type and centerpoints of surfaces for the location

Cheers

@danail.momchilov ,

for placing them you will also need Transactions

KR

Andreas

OMG ofcourse I do… !

I don’t think it would solve it anyway, as I would’ve gotten a warning about that. But let me give it a try :slight_smile:

nope, it’s the same:

@danail.momchilov ,

what your input?

import clr

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

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

clr.AddReference('System')
from System.Collections.Generic import List

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)

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

doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

#Preparing input from dynamo to revit
familySymbol = UnwrapElement(IN[0])
refVector = XYZ(1,0,0)

TransactionManager.Instance.EnsureInTransaction(doc)
#Do some action in a Transaction
for i, plFace in enumurate(IN[0]):
	for s in UnwrapElement(IN[0][i]):
		pt = UnwrapElement(IN[3][i])
		ItemFactoryBase.NewFamiliyInstance(pFace, pt, revVector, familySymbol)
		
TransactionManager.Instance.TransactionTaskDone()

OUT = "Placed FamilyInstance"

it looks you have too many

1 Like

Thx, Andreas, sure the points list is enough, but that doesn’t solve the issue:

t.Start()

for i, plFace in enumerate(IN[0]):
	for pt in UnwrapElement(IN[2][i]):
		ItemFactoryBase.NewFamilyInstance(plFace, pt, refVector,  familySymbol)
		
t.Commit()

Hi,
according to the API doc ItemFactoryBase.NewFamilyInstance() is not a Static method

you need an Revit Document instance to use it with doc.Create

see the example in API Doc

related topic

2 Likes

Thank you so much! I’m not sure I am doing the right thing, but I tried to follow these instructions:

Prior to that I am getting the faces as a reference with Options.ComputeReference = True

I might have progressed a bit :smiley: …but it now seems that the code thinks I am trying to use a method, taking an XYZ as a first argument, while I’m trying to use the reference one:

is there something else I am doing wrong?

You need to convert your Dynamo points to Revit XYZs.

2 Likes

I think that actually worked! just need to tweak it a little bit and convert units for the coordinates

@danail.momchilov ,

:wink:

1 Like

thx, I was just sharing my thoughts :slight_smile: I am usually just multiplying or dividing by 30.48

Here’s the final code:

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

import System
from System import Array

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")
clr.AddReference("RevitAPIUI")

import Autodesk
from Autodesk.Revit.DB import XYZ, Point, FamilySymbol
from Autodesk.Revit.Creation import Document

def cm(a):
	return a/30.48

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument

familySymbol = UnwrapElement(IN[1])
refVector = XYZ(1, 0, 0)
outlist = []

TransactionManager.Instance.EnsureInTransaction(doc)

for i, plFace in enumerate(IN[0]):
	for pt in UnwrapElement(IN[2][i]):
		ptXYZ = XYZ(cm(pt.X), cm(pt.Y), cm(pt.Z))
		instance = uidoc.Document.Create.NewFamilyInstance(plFace, ptXYZ, refVector,  familySymbol)
		outlist.append(instance)
		
TransactionManager.Instance.TransactionTaskDone()

OUT = outlist

thank you all for the support, I am actually not sure who to thank first as I had pretty much everything messed up :smiley: it’s just the first time I was interacting with the Creation namespace

2 Likes

you can use the ToXyz() extension method (conversion)
see here

2 Likes