Ungrouping & Purging All Families in a Model

revit
#1

Hello. New to Dynamo here so go easy please.
I am hoping that I can use Dynamo to achieve the following - opening each family loaded into a model, ungrouping all elements, purging, and loading them back into the model. Am I being too optimistic?

This is because a job we’re working on has got 2300+ families loaded - it is a historic building with a lot of bespoke content. The company who produced the point cloud based 3D survey grouped all elements in each family before saving it. I have worked out that this has caused each family to have a file size increase of anything from 20% to sometimes 70%, had the elements not been grouped! Considering the amount of content loaded, I figure this is having a pretty big impact on the model size and workflow on the whole team, who will be using this model daily for years to come.

I am hoping Dynamo will be our way out of this… any help would be much appreciated!

0 Likes

#2

Hello, please take a look at this discussion:

0 Likes

#3

Any updates to the post? How to batch processing families inside a model (purge them particularly)?

0 Likes

#4

Unfortunately no!
The thread suggested above does not cover this particular issue of purging families.

0 Likes

#5

This thread could help to to get the answers you need:

0 Likes

#6

Fair enough!
Long story short, this is what I need Dynamo to do:

  • open each family loaded into a model,
  • ungroup all elements within that family,
  • purge family,
  • load back into the model

Possibly a big ask.

0 Likes

#7

Usually, proceeding step by step leads to results. You can surely ask for help on the particular issues you encounter when building your graph. The forum guidelines are clearly explaining how to do this (point 7 is quite explicit, I think)

0 Likes

#8

They are, and I didn’t really expect to have work done for me, was quite genuinely wondering whether it’s the type of thing it would do or not. Thanks for your help though!

0 Likes

#9

OK, this topic could possibly go further, so here is a way to get started:


Group.UngroupElements is from Rhythm or Clockwork.
Please use with caution and do some preliminary tests (don’t run in automatic or several times and use Undo in Revit if needed)

0 Likes

#10

Oooo. Thank you for this, will see how I get on and report back!

1 Like

#11

"Usually, proceeding step by step leads to results"
Usually not. Thus, your next post about ungrouping is a good example - it works only with elements in the model.
The original topic is much trickier - how to process families and work inside them as we do in models. Look fwd to gurus.

0 Likes

#12

@Nikolay_Gerasimov1
https://forum.dynamobim.com/faq

1 Like

#13

Here is a start on how to open, ungroup and save the families. I 'm not sure if it’s possible to reload the documentes with Dynamo.

WIP-open family and ungroup.dyn (6.3 KB)

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 *

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
elements = UnwrapElement(IN[0])
path = IN[1]

for e in elements:
	famdoc = doc.EditFamily(e)
	fec = FilteredElementCollector(famdoc).OfCategory(BuiltInCategory.OST_IOSModelGroups).WhereElementIsNotElementType()
	if fec.FirstElement() is not None:
		groups = fec.ToElements()
		TransactionManager.Instance.EnsureInTransaction(famdoc)
		[g.UngroupMembers() for g in groups]
		TransactionManager.Instance.ForceCloseTransaction()
		
		famdoc.SaveAs(path +"\\" + e.Name + ".rfa")
		
OUT = 0
2 Likes

#14

You can use IFamilyLoadOptions Interface in Revit API http://www.revitapidocs.com/2017/d447ed92-74e1-2125-dd0a-38a5ae85ce53.htm

1 Like

#15

Yes, you have to use that as an argument in one of the overloads of the LoadFamily Method. It requires that you create a custom class and maybe utilize StrongBox type to handle the out attributes in that class’ methods. That shouldn’t be any problem, but I had some doubt about the transactions, but it can probably be handled with ForceCloseTransaction() in the Transaction manager.

Here is a C# example:

0 Likes

#16

I found some time to take a look at the reloading:

The IFamilyLoadOptions implemented in python:

class FamilyOption(IFamilyLoadOptions):
	def OnFamilyFound(self,familyInUse,overwriteParameterValues):
		overwriteParameterValues = True
		return True
		
	def OnSharedFamilyFound(self, sharedFamily, familyInUse, FamilySource, overwriteParameterValues):
		return True

Here is the call of the LoadFamily method call on the familydocument:

famdoc.LoadFamily(doc, FamilyOption())

@luisa Do you want to test the script? It doesn’t purge anything, because that has to be done manually. There is no API call to the purge command in Revit.

OpenAndUngroupFamilies.dyn (6.1 KB)

For anyone that might be interested,.the complete python script:

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 *

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

class FamilyOption(IFamilyLoadOptions):
	def OnFamilyFound(self,familyInUse,overwriteParameterValues):
		overwriteParameterValues = True
		return True
		
	def OnSharedFamilyFound(self, sharedFamily, familyInUse, FamilySource, overwriteParameterValues):
		return True
		
#Preparing input from dynamo to revit
families = UnwrapElement(IN[0])

for f in families:
	famdoc = doc.EditFamily(f)
	fec = FilteredElementCollector(famdoc).OfCategory(BuiltInCategory.OST_IOSModelGroups).WhereElementIsNotElementType()
	if fec.FirstElement() is not None:
		groups = fec.ToElements()

		TransactionManager.Instance.EnsureInTransaction(famdoc)
		[g.UngroupMembers() for g in groups]
		TransactionManager.Instance.TransactionTaskDone()
		TransactionManager.Instance.ForceCloseTransaction()
		
		TransactionManager.Instance.EnsureInTransaction(doc)
		famdoc.LoadFamily(doc, FamilyOption())
		TransactionManager.Instance.TransactionTaskDone()
		TransactionManager.Instance.ForceCloseTransaction()
		
		#famdoc.SaveAs(path +"\\" + e.Name + ".rfa")
OUT = 0
2 Likes

Setting the builtin parameter accessible thru the family editor?
#17

@Einar_Raknes definitely but am snowed under with other work at the moment! I will report back once I find the time to dedicate to this. Many thanks!

0 Likes

#18

There was a similar question on how to edit multiple families quite a while ago, that was answered here:

It might give you some more examples to work with, but you might need to dig the old forum for the full-rez images.

1 Like

#19

This is what I wanted to know. Thx.

0 Likes

#20

You can still purge e.g. unused families with dynamo: http://whatrevitwants.blogspot.no/2015/11/purge-component-families-using.html

0 Likes