Looking for node to modify Parameter in *.rfa file


#1

Does anyone have a node to modify a family parameter from “instance” to “type” ?

I have used the DanEdu nodes to delete de parameters and re-apply them as instance or type. This is a succes but of course the parameters lose their link to the reference planes. Because of this I am looking for a node that modifies the parameter so the link to the ref planes stays intact.

Can anyone help ?

Verdi


#2

it looks like there is a misconcept of these parameters purpose. May you show a graph, a drawings for what you want to obtain? Probably there is better solution.


#3

Pretty sure Element.SetParameterByName can work if the input is a familytype instead of element.

Also, try searching this forum for change familytype parameters. This thread solves it with the above mentioned method: Set Type Parameter


#4

@Uaifestival @kennyb6 Thanx for the reply guys.

I want to keep a existing parameter and just change it from instance to type. @kennyb6 the thread you mentioned is one that changes the parameter value. I do not need to change the value or formula.

I have a lot of existing families where the parameter is a instance. Because of the change of workflow we decided to change the families into type families. The image below explains what i want to do with multiple families in Dynamo.


#5

Ah okay I understand now. I don’t know if there is a node that does that but it appears possible through API, meaning either zero touch or python node could do it using the method MakeInstance or MakeType.

Hopefully someone who is good with this stuff can make a simple script.


#6

So I have a script that is working right now and can switch back and forth between instance and type but it depends on the input. Are you trying to input a list of model elements or a list of families?


#7

Python script:

import clr

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

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

# class for overwriting loaded families in the project
class FamOpt1(IFamilyLoadOptions):
    def __init__(self): pass
    def OnFamilyFound(self,familyInUse, overwriteParameterValues): return True
    def OnSharedFamilyFound(self,familyInUse, source, overwriteParameterValues): return True

def changeParam(f1,name,make,result):
	famdoc = doc.EditFamily(f1)
	try: # this might fail if the parameter exists or for some other reason
	    trans1.EnsureInTransaction(famdoc)
	    par_name = [a for a in famdoc.FamilyManager.Parameters if a.Definition.Name==name][0]
	    if make == True:
	    	famdoc.FamilyManager.MakeType(par_name)
	    else:
	    	famdoc.FamilyManager.MakeInstance(par_name)
	    trans1.ForceCloseTransaction()
	    famdoc.LoadFamily(doc, FamOpt1())
	    result.append(True)
	except Exception, e:
	    result.append([False,e])
	    trans1.ForceCloseTransaction()  
	famdoc.Close(False)

def unwrapping(ele):
	try:
		f1 = UnwrapElement(ele.Type.Family)
	except:
		f1 = UnwrapElement(ele)
	return f1

trans1 = TransactionManager.Instance
trans1.ForceCloseTransaction() #just to make sure everything is closed down
# Dynamo's transaction handling is pretty poor for
# multiple documents, so we'll need to force close
# every single transaction we open
result = []
if hasattr(IN[0], "__iter__") == True and hasattr(IN[1], "__iter__") == True:
	for i in range(len(IN[0])):
		f1 = unwrapping(IN[0][i])
		changeParam(f1,IN[1][i],IN[2],result)
elif hasattr(IN[0], "__iter__") == True and hasattr(IN[1], "__iter__") == False:
	for i in IN[0]:
		f1 = unwrapping(i)
		changeParam(f1,IN[1],IN[2],result)
elif hasattr(IN[0], "__iter__") == False and hasattr(IN[1], "__iter__") == False:
	f1 = unwrapping(IN[0])
	changeParam(f1,IN[1],IN[2],result)

OUT = result

Shout out to @Dimitar_Venkov for this thread and Nathan Miller’s theprovingground.org for API help.

I haven’t been able to fully test it so let me know of any problems, but it should be able to handle:

  • Single or list of families, elements, or a combination as input 0
  • Single parameter as string in input 1
  • Single or list of booleans for input 2; True = make parameter into Type, false into Instance

PS. I am still a novice for python and working with api, so please excuse any horrible coding standard. Those with more experience, I would love some feedback

PPS. Forgot to mention, this script works in the project space, not family editor. I misread the title. If you need specifically for family editor, I can make another version but thought project space would be more useful.


#8

Wow Thank you for the help @kennyb6

I will try it out today! I want to change it in * .rfa files without opening the files in Revit. That way I can change multiple families at once.

Thanx again guys and I will keep u updated !


#9

You can very much change several .rfa files with Revit open.


#10

You want to open it inside the family editor or the project that has all of the families loaded? I don’t understand when you want to change it in the .rfa but also want to do multiple families at once.

My script can do all the families you want at once as long as the families are already loaded in the project and the script is ran in the project.

For more info, my script will actually open up each family file you want and change the parameters, then close the family file, all inside the .rvt while without having to manually open any .rfa


#11

I’ve tried the script with no luck seeing i have minimal python experience. The person i can ask for help is not available today :frowning:

This is what happens when I try it.

And this is the script:

I do not understand the explination in line 19 because the parameter always exists. It is an existing parameter that we want to change/modify.

I have tried using both a list (also flattened) and a single family from project as IN[0].
The name of the parameter i want to modify as IN[1]
A true/false boolean as IN[2]

This nodes opens and saves files automatically right ? Or should i use the Rythm nodes to open and close after? I will try to find the mistake, or if I can spot something i didn’t copy correctly from your node.

Thanx again for putting time into this ! :+1:


#12

Sorry, the script was made to only work with an element or a family, you entered a family type. I can remake it real quick to allow family type but in the mean time, convert it to the family first and it should work.


#13

Nice ! It works with families. Dont mind remaking it for family-types. Can you do it for rfa-files maybe or is that a lot of work ? If you can , I can even save the rfa file after the change I think.

Now the change is for a family in the project, not in the family file (rfa) itself.

This has already helped me a lot !! So if the rest is too much work, I’ll find another way or try to learn some python and modify your script :stuck_out_tongue: Not sure how long that will take … :x


#14

Can you try this new script and feed it a familytype? I can’t test it at the moment but curious if it will work.
Are you sure it doesn’t save it in the .rfa? Try running the script then go to edit family and check. I don’t know if it will update the .rfa file on your system but the one attached inside the .rvt should be. If you want one for use inside .rfa that is easy as it is just a section of this python script. I can attach it in another comment in a bit.

New script:

import clr

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

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

# class for overwriting loaded families in the project
class FamOpt1(IFamilyLoadOptions):
    def __init__(self): pass
    def OnFamilyFound(self,familyInUse, overwriteParameterValues): return True
    def OnSharedFamilyFound(self,familyInUse, source, overwriteParameterValues): return True

def changeParam(f1,name,make,result):
	famdoc = doc.EditFamily(f1)
	try: # this might fail if the parameter exists or for some other reason
	    trans1.EnsureInTransaction(famdoc)
	    par_name = [a for a in famdoc.FamilyManager.Parameters if a.Definition.Name==name][0]
	    if make == True:
	    	famdoc.FamilyManager.MakeType(par_name)
	    else:
	    	famdoc.FamilyManager.MakeInstance(par_name)
	    trans1.ForceCloseTransaction()
	    famdoc.LoadFamily(doc, FamOpt1())
	    result.append(True)
	except Exception, e:
	    result.append([False,e])
	    trans1.ForceCloseTransaction()  
	famdoc.Close(False)

def unwrapping(ele):
	if type(ele).__name__ == "Family":
		f1 = UnwrapElement(ele)
	elif type(ele).__name__ == "FamilyType":
		f1 = UnwrapElement(ele.Family)
	else:
		f1 = UnwrapElement(ele.Type.Family)
	return f1

trans1 = TransactionManager.Instance
trans1.ForceCloseTransaction() #just to make sure everything is closed down
# Dynamo's transaction handling is pretty poor for
# multiple documents, so we'll need to force close
# every single transaction we open
result = []
if hasattr(IN[0], "__iter__") == True and hasattr(IN[1], "__iter__") == True:
	for i in range(len(IN[0])):
		f1 = unwrapping(IN[0][i])
		changeParam(f1,IN[1][i],IN[2],result)
elif hasattr(IN[0], "__iter__") == True and hasattr(IN[1], "__iter__") == False:
	for i in IN[0]:
		f1 = unwrapping(i)
		changeParam(f1,IN[1],IN[2],result)
elif hasattr(IN[0], "__iter__") == False and hasattr(IN[1], "__iter__") == False:
	f1 = unwrapping(IN[0])
	changeParam(f1,IN[1],IN[2],result)

OUT = result

#15

For use in .rfa files:

makeinstance2

import clr

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

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

def changeParam(name,make):
	famdoc = doc
	try: # this might fail if the parameter exists or for some other reason
	    trans1.EnsureInTransaction(famdoc)
	    par_name = [a for a in famdoc.FamilyManager.Parameters if a.Definition.Name==name][0]
	    if make == True:
	    	famdoc.FamilyManager.MakeType(par_name)
	    else:
	    	famdoc.FamilyManager.MakeInstance(par_name)
	    out = True
	    trans1.ForceCloseTransaction()
	except Exception, e:
	    out = [False,e] 
	    trans1.ForceCloseTransaction()
	return out

trans1 = TransactionManager.Instance

result = changeParam(IN[0],IN[1])

OUT = result

Forgot to close the transaction, it is updated now.


#16

You are right. The family has changed in the project but not in the rfa file on the system. It would be perfect if it changed on the system. That way i can change the database or make a copy of the folder with families and change it etc.

The new script does not work with familytypes, still works with families.

I want to use multiple rfa files as input, so i will try to do that in Dynamo or find a way to create a family-list or something.


#17

I am not sure on how to save the file on the system, though I do know it is possible. As for opening a directory of .rfa’s and performing this script automatically, I wouldn’t even know where to begin for that. I am still pretty novice with python and converting from C# to python is already the extent of my ability. Sorry I can’t help any further, though I am sure there are plenty of experts here who might be able to help.


#18

Also strange that it doesn’t work with familytypes because it works for me. At least when I feed it a single family type.


#19

No problem Kenny. You have already helped me a lot. It works in the project for multiple families!
I will ask someone to modify the script so it does the same thing for rfa files or I will try to look for a script that saves the rfa files from a certain project. The result would be the same.

Thanx for your help again !! :+1::+1:


#20

Just as an information, I have made several nodes for working with families… if you want to work with them as family documents (fra files).

There are several posts showing how to work with bulk work on families. I made that series of nodes for purposes like yours and many others in addition.

Here is an overview.