Dynamo python change familysymbol(type) name

Hi all,

I’m currently working on a script that changes the familysymbol name. but some way i can’t get this one to work.

Objective/workflow: in our company we are using a base parametric family(called: Betonplint - parametrisch), which is loaded in to a adaptive family, which is loaded in to a secondary adaptive main family. so we have a dynamo script that generates and saves these families with dimensions from an excel sheet. and later on this generated families will be loaded in to a project and with an other dynamo script we place these adaptive families in ‘the world’ with coordinates. when that model i generated we are using ‘Navisworks Manage’ to share our model with our client. but due the fact we are using 1 base family, all families wil return with there base name in Navisworks manage. See screenshot below:
Selection tree navisworks manage

But see this picture how we want to present the navisworks tree:
Selection tree navisworks manage we want

i achieved this by renaming the family with this method and by renaming it’s type with this method.

But as we have already a python script that generates these families i wan’t to integrate this. Renaming the family works(green marked) but renaming it’s type(red marked) not. see the pictures below from the script/ input-output and the result in the projectbrowser in revit.


this is the python script i use for generating, renaming and saving the families.

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

clr.AddReference("RevitServices")
import RevitServices
from Autodesk.Revit.DB import FilteredElementCollector, Family
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

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

doc = DocumentManager.Instance.CurrentDBDocument
name = IN[0]
compact = IN[1]
newcentral = IN[2]
isworkshared = IN[3]
elmts = IN[4]
parmNam = IN[5]
val = IN[6]
searcha = IN[7]
renamea = IN[8]

for i in range(len(name)):
	for j in range(len(val[i])):
		Revit.Elements.Element.SetParameterByName(elmts[0], parmNam[i][j], val[i][j])
	
	
	#TransactionManager.Instance.ForceCloseTransaction()
	search=searcha[i]
	rename=renamea[0][i]#[i]
	type_name = []
	collector = FilteredElementCollector(doc).OfClass(Family)
	TransactionManager.Instance.EnsureInTransaction(doc)
	for element in collector.ToElements():
	    for idx, searched in enumerate(search):
	        if searched == element.Name:
	            element.Name = rename[idx]
	            type_name.append(element.Name)
	TransactionManager.Instance.ForceCloseTransaction()
	
	searchb=searcha[i]
	renameb=renamea[0][i]#[i]
	type_namea = []
	type_namecheck = []
	familytypes = FilteredElementCollector(doc).OfClass(FamilySymbol).ToElements()
	
	TransactionManager.Instance.EnsureInTransaction(doc)
	for typ in familytypes:
		typename = typ.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM).AsString()
		typename_object = typ.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM)
		type_namea.append(typename)
		if searchb[0] == typename:
			type_namecheck.append("gevonden")
			#typeName = typename_object.LookupParameter(searchb[0]).Set(renameb[0])
			#typeName = typename.Name(BuiltInParameter.SYMBOL_NAME_PARAM).Set(renameb)
	TransactionManager.Instance.ForceCloseTransaction()
	
	if doc.IsFamilyDocument:
		name[i] += '.rfa'
	else:
		name[i] += '.rvt'
	opt = SaveAsOptions()
	opt.OverwriteExistingFile = True
	opt.Compact = compact
	if isworkshared and newcentral:
		wsopt = WorksharingSaveAsOptions()
		wsopt.ClearTransmitted = True
		wsopt.SaveAsCentral = True
		opt.SetWorksharingOptions(wsopt)
	try:
		doc.SaveAs(name[i], opt)
		OUT = 'ALLE ELEMENTEN ZIJN GEGENEREERD',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck
	except:
		try:
			wsopt.ClearTransmitted = False
			opt.SetWorksharingOptions(wsopt)
			doc.SaveAs(name[i], opt)
			OUT = 'not done',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck
		except:
			OUT = 'not done',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck

The question:
what line of code do i need after the “if searchb[0] == typename:” to set the name ?
as you can see i tried two different options but both are giving error’s.

PS: i’m working with revit 2021.

Gr Edward

1 Like

To rename family types you should use the ALL_MODEL_TYPE_NAME builtin parameter.

@Daniel_Woodcock1 thanks for your reply.

See the script below where i used youre suggestion. but i’m now getting an error

Script with mentioned “ALL_MODEL_TYPE_NAME”

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

clr.AddReference("RevitServices")
import RevitServices
from Autodesk.Revit.DB import FilteredElementCollector, Family
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

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

doc = DocumentManager.Instance.CurrentDBDocument
name = IN[0]
compact = IN[1]
newcentral = IN[2]
isworkshared = IN[3]
elmts = IN[4]
parmNam = IN[5]
val = IN[6]
searcha = IN[7]
renamea = IN[8]

for i in range(len(name)):
	for j in range(len(val[i])):
		Revit.Elements.Element.SetParameterByName(elmts[0], parmNam[i][j], val[i][j])
	
	
	#TransactionManager.Instance.ForceCloseTransaction()
	search=searcha[i]
	rename=renamea[0][i]#[i]
	type_name = []
	collector = FilteredElementCollector(doc).OfClass(Family)
	TransactionManager.Instance.EnsureInTransaction(doc)
	for element in collector.ToElements():
	    for idx, searched in enumerate(search):
	        if searched == element.Name:
	            element.Name = rename[idx]
	            type_name.append(element.Name)
	TransactionManager.Instance.ForceCloseTransaction()
	
	searchb=searcha[i]
	renameb=renamea[0][i]#[i]
	type_namea = []
	type_namecheck = []
	familytypes = FilteredElementCollector(doc).OfClass(FamilySymbol).ToElements()
	
	TransactionManager.Instance.EnsureInTransaction(doc)
	for typ in familytypes:
		typename = typ.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM).AsString()
		typename_object = typ.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM)
		type_namea.append(typename)
		if searchb[0] == typename:
			type_namecheck.append("gevonden")
			#typeName = typename_object.LookupParameter(searchb[0]).Set(renameb[0])
			typeName = typ.Name(BuiltInParameter.ALL_MODEL_TYPE_NAME_).Set(renameb)
			#typeName = typename.Name(BuiltInParameter.SYMBOL_NAME_PARAM).Set(renameb)
	TransactionManager.Instance.ForceCloseTransaction()
	
	if doc.IsFamilyDocument:
		name[i] += '.rfa'
	else:
		name[i] += '.rvt'
	opt = SaveAsOptions()
	opt.OverwriteExistingFile = True
	opt.Compact = compact
	if isworkshared and newcentral:
		wsopt = WorksharingSaveAsOptions()
		wsopt.ClearTransmitted = True
		wsopt.SaveAsCentral = True
		opt.SetWorksharingOptions(wsopt)
	try:
		doc.SaveAs(name[i], opt)
		OUT = 'ALLE ELEMENTEN ZIJN GEGENEREERD',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck
	except:
		try:
			wsopt.ClearTransmitted = False
			opt.SetWorksharingOptions(wsopt)
			doc.SaveAs(name[i], opt)
			OUT = 'not done',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck
		except:
			OUT = 'not done',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck

thanks in advance

Try this instead…

TransactionManager.Instance.EnsureInTransaction(doc)
for typ in familytypes:
	typename = typ.get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_NAME)
	type_namea.append(typename.AsString())
	if searchb[0] == typename:
		type_namecheck.append("gevonden")
		typename.Set(renameb)
TransactionManager.Instance.ForceCloseTransaction()

@Daniel_Woodcock1
i’m sorry, but i made a small mistake in my code so the if statement did not do anything at all.

i fixed my if statement. and tried 2 different ways of renaming the parameter.
1- when using typename.Set (as suggested i get this error). Quite logic in my opinion

2- when using typ.Name(BuiltInParameter.ALL_MODEL_TYPE_NAME).Set(renameb[0])
i get this error.

This is the script with the both tested lines:

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

clr.AddReference("RevitServices")
import RevitServices
from Autodesk.Revit.DB import FilteredElementCollector, Family
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

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

doc = DocumentManager.Instance.CurrentDBDocument
name = IN[0]
compact = IN[1]
newcentral = IN[2]
isworkshared = IN[3]
elmts = IN[4]
parmNam = IN[5]
val = IN[6]
searcha = IN[7]
renamea = IN[8]

for i in range(len(name)):
	for j in range(len(val[i])):
		Revit.Elements.Element.SetParameterByName(elmts[0], parmNam[i][j], val[i][j])
	
	
	#TransactionManager.Instance.ForceCloseTransaction()
	search=searcha[i]
	rename=renamea[0][i]#[i]
	type_name = []
	collector = FilteredElementCollector(doc).OfClass(Family)
	TransactionManager.Instance.EnsureInTransaction(doc)
	for element in collector.ToElements():
	    for idx, searched in enumerate(search):
	        if searched == element.Name:
	            element.Name = rename[idx]
	            type_name.append(element.Name)
	TransactionManager.Instance.ForceCloseTransaction()
	
	searchb=searcha[i]
	renameb=renamea[0][i]#[i]
	type_namea = []
	type_namecheck = []
	familytypes = FilteredElementCollector(doc).OfClass(FamilySymbol).ToElements()
	
	TransactionManager.Instance.EnsureInTransaction(doc)
	for typ in familytypes:
		
		typename = typ.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM)
		typenamestr = str(typename)
		typnaam = typename.AsString()
		type_namea.append(typename.AsString())
		if searchb[0] == typnaam:
			type_namecheck.append("gevonden")
			#typename.Set(renameb[0])
			typ.Name(BuiltInParameter.ALL_MODEL_TYPE_NAME).Set(renameb[0])
	TransactionManager.Instance.ForceCloseTransaction()
	
	if doc.IsFamilyDocument:
		name[i] += '.rfa'
	else:
		name[i] += '.rvt'
	opt = SaveAsOptions()
	opt.OverwriteExistingFile = True
	opt.Compact = compact
	if isworkshared and newcentral:
		wsopt = WorksharingSaveAsOptions()
		wsopt.ClearTransmitted = True
		wsopt.SaveAsCentral = True
		opt.SetWorksharingOptions(wsopt)
	try:
		doc.SaveAs(name[i], opt)
		OUT = 'ALLE ELEMENTEN ZIJN GEGENEREERD',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck,typenamestr,typ,typnaam
	except:
		try:
			wsopt.ClearTransmitted = False
			opt.SetWorksharingOptions(wsopt)
			doc.SaveAs(name[i], opt)
			OUT = 'not done',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck,typenamestr,typ,typnaam
		except:
			OUT = 'not done',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck,typenamestr,typ,typnaam

I hope someone can help me with this?

Thanks in advance

Gr Edward

You are still doing this wrong. Can you replace the part I quoted with the code I provided as your code is still pretty much as it was when you originally posted.

To break this down a little further…

For the first error, you are using the readonly BIP SYMBOL_NAME_PARAM and not the editable BIP. This needs to be ALL_MODEL_TYPE_NAME if you wish to set it.

For the second error, you are doing typ.Name(Builtin… ). This simply is not a thing, FamilySymbol.Name is a readonly property and should always be without brackets and never assigned to. Instead, you need to get the parameter object (ALL_MODEL_TYPE_NAME) first, you can get and set this. Again, see my last post, I am not setting the name property on the type, instead I am setting the parameter objects value on that type which in turn updates rhe readonly FamilySymbol.Name property.

I hope that makes sense.

2 Likes

I partially getting what you mean.(already many thanks for your time)

So i tried to set it the way you described. then i still get this error:

this is the script

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

clr.AddReference("RevitServices")
import RevitServices
from Autodesk.Revit.DB import FilteredElementCollector, Family
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

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

doc = DocumentManager.Instance.CurrentDBDocument
name = IN[0]
compact = IN[1]
newcentral = IN[2]
isworkshared = IN[3]
elmts = IN[4]
parmNam = IN[5]
val = IN[6]
searcha = IN[7]
renamea = IN[8]

for i in range(len(name)):
	for j in range(len(val[i])):
		Revit.Elements.Element.SetParameterByName(elmts[0], parmNam[i][j], val[i][j])
	
	
	#TransactionManager.Instance.ForceCloseTransaction()
	search=searcha[i]
	rename=renamea[0][i]#[i]
	type_name = []
	collector = FilteredElementCollector(doc).OfClass(Family)
	TransactionManager.Instance.EnsureInTransaction(doc)
	for element in collector.ToElements():
	    for idx, searched in enumerate(search):
	        if searched == element.Name:
	            element.Name = rename[idx]
	            type_name.append(element.Name)
	TransactionManager.Instance.ForceCloseTransaction()
	
	searchb=searcha[i]
	renameb=renamea[0][i]#[i]
	type_namea = []
	type_namecheck = []
	familytypes = FilteredElementCollector(doc).OfClass(FamilySymbol).ToElements()
	
	TransactionManager.Instance.EnsureInTransaction(doc)
	for typ in familytypes:
		
		typename = typ.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM)
		typenameget = typ.get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_NAME)
		typenamestr = str(typename)
		typnaam = typename.AsString()
		type_namea.append(typename.AsString())
		if searchb[0] == typnaam:
			type_namecheck.append("gevonden")
			typenameget.Set(renameb[0])
			#typ.Name(BuiltInParameter.ALL_MODEL_TYPE_NAME).Set(renameb[0])
	TransactionManager.Instance.ForceCloseTransaction()
	
	if doc.IsFamilyDocument:
		name[i] += '.rfa'
	else:
		name[i] += '.rvt'
	opt = SaveAsOptions()
	opt.OverwriteExistingFile = True
	opt.Compact = compact
	if isworkshared and newcentral:
		wsopt = WorksharingSaveAsOptions()
		wsopt.ClearTransmitted = True
		wsopt.SaveAsCentral = True
		opt.SetWorksharingOptions(wsopt)
	try:
		doc.SaveAs(name[i], opt)
		OUT = 'ALLE ELEMENTEN ZIJN GEGENEREERD',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck,typenamestr,typ,typnaam
	except:
		try:
			wsopt.ClearTransmitted = False
			opt.SetWorksharingOptions(wsopt)
			doc.SaveAs(name[i], opt)
			OUT = 'not done',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck,typenamestr,typ,typnaam
		except:
			OUT = 'not done',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck,typenamestr,typ,typnaam

Hmm, seems to be that one or more of your family types cannot be renamed. You might want to add to your if condition a check if the family type can actually be renamed or parameter is readonly. Use one of the following…

typ.CanBeRenamed

Or…

typenameget.IsReadOnly

So your if statement would be along the lines of…

if seachb[0] == typnaam and typ.CanBeRenamed:

Or…

if seachb[0] == typnaam and not typenameget.IsReadOnly:

It is always good to add validation where you can to catch conditions like this. If I were you I would do some tests in another node isolating the type renaming so you can see better what is happening, or in the same node, if it is read only parameter or type cannot be renamed then add type to an array you can output in the graph so you can see on what elements this is happening to. This is the best and only way to debug in dynamo python.

Hello
you can try to use directly the Name property (setter)

import clr
import sys
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS

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

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

familytypes = FilteredElementCollector(doc).OfClass(FamilySymbol).ToElements()

TransactionManager.Instance.EnsureInTransaction(doc)
for typ in familytypes:
	currentName = Element.Name.GetValue(typ)
	typ.Name = "MyPrefix_" + currentName

TransactionManager.Instance.TransactionTaskDone()

OUT = familytypes
3 Likes

@c.poupin thanks for your reply. it works now.
@Daniel_Woodcock1 also many thanks for your patience with me.

2 Likes

Hi @c.poupin and @Daniel_Woodcock1

after some testing in real projects, the script needs some addition’s.
The problem i have now is that in the top family still ‘type 1’ is. and i wand tot change is. but cant really figure out what i need to add to find this ‘type 1’.
See the picture below, the type 1 is changed in all lower family’s but not in the top one.

this is my script i use.

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

clr.AddReference("RevitServices")
import RevitServices
from Autodesk.Revit.DB import FilteredElementCollector, Family
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

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

doc = DocumentManager.Instance.CurrentDBDocument
name = IN[0]
compact = IN[1]
newcentral = IN[2]
isworkshared = IN[3]
elmts = IN[4]
parmNam = IN[5]
val = IN[6]
searcha = IN[7]
renamea = IN[8]

for i in range(len(name)):
	for j in range(len(val[i])):
		Revit.Elements.Element.SetParameterByName(elmts[0], parmNam[i][j], val[i][j])
	
	
	#TransactionManager.Instance.ForceCloseTransaction()
	search=searcha[i]
	rename=renamea[0][i]#[i]
	type_name = []
	collector = FilteredElementCollector(doc).OfClass(Family)
	TransactionManager.Instance.EnsureInTransaction(doc)
	for element in collector.ToElements():
	    for idx, searched in enumerate(search):
	        if searched == element.Name:
	        	element.Name = rename[idx]
	        	type_name.append(element.Name)
	TransactionManager.Instance.ForceCloseTransaction()
	
	searchb=searcha[i]
	renameb=renamea[0][i]#[i]
	type_namea = []
	type_namecheck = []
	familytypes = FilteredElementCollector(doc).OfClass(FamilySymbol).ToElements()
	
	TransactionManager.Instance.EnsureInTransaction(doc)
	for typ in familytypes:
		currentName = Element.Name.GetValue(typ)
		
		typename = typ.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM)
		typenameget = typ.get_Parameter(BuiltInParameter.ALL_MODEL_TYPE_NAME)
		typenamestr = str(typename)
		typnaam = typename.AsString()
		type_namea.append(typename.AsString())
		#if searchb[0] == typnaam:
		type_namecheck.append("gevonden")
			#typ.Name = "test_" +currentName
		typ.Name = renameb[0]
			#typenameget.Set(renameb[0])
			#typ.Name(BuiltInParameter.ALL_MODEL_TYPE_NAME).Set(renameb[0])
	TransactionManager.Instance.ForceCloseTransaction()
	
	if doc.IsFamilyDocument:
		name[i] += '.rfa'
	else:
		name[i] += '.rvt'
	opt = SaveAsOptions()
	opt.OverwriteExistingFile = True
	opt.Compact = compact
	if isworkshared and newcentral:
		wsopt = WorksharingSaveAsOptions()
		wsopt.ClearTransmitted = True
		wsopt.SaveAsCentral = True
		opt.SetWorksharingOptions(wsopt)
	try:
		doc.SaveAs(name[i], opt)
		OUT = 'ALLE ELEMENTEN ZIJN GEGENEREERD',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck,typenamestr,typ,typnaam
	except:
		try:
			wsopt.ClearTransmitted = False
			opt.SetWorksharingOptions(wsopt)
			doc.SaveAs(name[i], opt)
			OUT = 'not done',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck,typenamestr,typ,typnaam
		except:
			OUT = 'not done',type_name,searcha,search,renamea,rename,type_namea,familytypes,searchb,renameb,type_namecheck,typenamestr,typ,typnaam

hope someone of you know how to get this last parameter?

thanks in advance

To rename types in the family editor, the method is as follows
https://www.revitapidocs.com/2021.1/ddd98706-5a07-feac-4b1f-49d52471a8c8.htm
Note
it might be better to do one script per environment (project and family editor)