Opening & closing of multiple models in background while completing a set of tasks

try changing from this:

if isinstance(IN[0], list):
    file = IN[0]
    filename = IN[2]
else:
    file = [IN[0]]
    filename = [IN[2]]

to this:

if isinstance(IN[0], list):
    file = IN[0]
else:
    file = [IN[0]]
if isinstance(IN[2],list): 
    filename = IN[2]
else:
    filename = [IN[2]]

Unfortunately, same message: unsupported operand type(s) for +: ‘list’ and ‘str’

Thanks for the feedback. I do not know how to do that yet, I am now trying to learn python as I have never learned any coding language. Guess will need some time to get it going :slight_smile:

I did some changes and it is working now!

I set the line:

	newfilepath = newpath + "\\" + filenames

To:

	newfilepath = newpath + "\\" + str(filenames)

And removed two flatten nodes, leaving as this:

However, it seems that the files are not being closed, even with the line

	newdoc.Close(True)

As I can see them in the worksharing monitor and the memory is still in use.

The current script is now:

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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

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

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

from System.Collections.Generic import *

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

# Import python library
import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)
import os

tOptions = TransactWithCentralOptions()

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

def flatten(*args):
for x in args:
    if hasattr(x, '__iter__'):
        for y in flatten(*x): yield y
    else: yield x


#Credits Archi-lab
def checkParameter(param):
for p in param:
	internal = p.Definition
	if internal.BuiltInParameter != BuiltInParameter.INVALID:
		return p
return param[0]

def GetParaValue(params):
paravalue = []
p = checkParameter(params)
if p.StorageType == StorageType.String:
	paravalue.append(p.AsString())
elif p.StorageType == StorageType.ElementId:
	paravalue.append(p.AsValueString())
elif p.StorageType == StorageType.Integer:
	paravalue.append(p.AsValueString())
else:
	paravalue.append(None)
return paravalue

if isinstance(IN[0], list):
file = IN[0]
filename = IN[2]
else:
file = [IN[0]]
filename = [IN[2]]

newpath = IN[1]
LinkNames, newdocpath, results, unloadstatus, linkParas = [], [], [], [], []

openConfig = WorksetConfiguration(WorksetConfigurationOption.CloseAllWorksets)
oOptions = OpenOptions()
oOptions.DetachFromCentralOption = DetachFromCentralOption.DetachAndPreserveWorksets
oOptions.Audit = True
oOptions.SetOpenWorksetsConfiguration(openConfig)

worksharingOptions = WorksharingSaveAsOptions()
worksharingOptions.SaveAsCentral = True

SaveOptions = SaveAsOptions()
SaveOptions.MaximumBackups = 50
SaveOptions.SetWorksharingOptions(worksharingOptions)
SaveOptions.OverwriteExistingFile = True

rOptions = RelinquishOptions(False)
rOptions.StandardWorksets = True
rOptions.ViewWorksets = True
rOptions.FamilyWorksets = True
rOptions.UserWorksets = True
rOptions.CheckedOutElements = True

sOptions = SynchronizeWithCentralOptions()
sOptions.SetRelinquishOptions(rOptions)
sOptions.Compact = True
sOptions.SaveLocalBefore = True
sOptions.SaveLocalAfter = True

TransactionManager.Instance.ForceCloseTransaction()

try:
for files,filenames in zip(file,filename):
	modelpath = FilePath(files)
	newdoc = app.OpenDocumentFile(modelpath,oOptions)
	collector = Autodesk.Revit.DB.FilteredElementCollector(newdoc)
	linkTypes = UnwrapElement(collector.OfClass(Autodesk.Revit.DB.RevitLinkType))
	for linkType in flatten(linkTypes):
		linkPara = linkType.GetParameters("Type Name")
		linkParavalue = GetParaValue(linkPara)
		try:
			linkType.Unload(None)
			unloadstatus.append(True)
		except:
			unloadstatus.append(False)
		results = [unloadstatus]		
	newfilepath = newpath + "\\" + str(filenames)
	newdoc.SaveAs(newfilepath,SaveOptions)			
	newdoc.SynchronizeWithCentral(tOptions,sOptions)
	newdoc.Close(True)
	newdocpath.append(newfilepath) 
	OUT = newdocpath 	
except Exception,e:
OUT = str(e)

well i dont know whats wrong with your code, maybe can upload your sample files? and show me the inputs?? here is what i have now:

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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

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

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

from System.Collections.Generic import *

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

# Import python library
import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)
import os

tOptions = TransactWithCentralOptions()

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

def flatten(*args):
    for x in args:
        if hasattr(x, '__iter__'):
            for y in flatten(*x): yield y
        else: yield x
	

#Credits Archi-lab
def checkParameter(param):
	for p in param:
		internal = p.Definition
		if internal.BuiltInParameter != BuiltInParameter.INVALID:
			return p
	return param[0]

def GetParaValue(params):
	paravalue = []
	p = checkParameter(params)
	if p.StorageType == StorageType.String:
		paravalue.append(p.AsString())
	elif p.StorageType == StorageType.ElementId:
		paravalue.append(p.AsValueString())
	elif p.StorageType == StorageType.Integer:
		paravalue.append(p.AsValueString())
	else:
		paravalue.append(None)
	return paravalue
	
if isinstance(IN[0], list):
	file = IN[0]
	filename = IN[2]
else:
	file = [IN[0]]
	filename = [IN[2]]

newpath = IN[1]
LinkNames, newdocpath, results, unloadstatus, linkParas = [], [], [], [], []

openConfig = WorksetConfiguration(WorksetConfigurationOption.CloseAllWorksets)
oOptions = OpenOptions()
oOptions.DetachFromCentralOption = DetachFromCentralOption.DetachAndPreserveWorksets
oOptions.Audit = True
oOptions.SetOpenWorksetsConfiguration(openConfig)

worksharingOptions = WorksharingSaveAsOptions()
worksharingOptions.SaveAsCentral = True

SaveOptions = SaveAsOptions()
SaveOptions.MaximumBackups = 50
SaveOptions.SetWorksharingOptions(worksharingOptions)
SaveOptions.OverwriteExistingFile = True

rOptions = RelinquishOptions(False)
rOptions.StandardWorksets = True
rOptions.ViewWorksets = True
rOptions.FamilyWorksets = True
rOptions.UserWorksets = True
rOptions.CheckedOutElements = True

sOptions = SynchronizeWithCentralOptions()
sOptions.SetRelinquishOptions(rOptions)
sOptions.Compact = True
sOptions.SaveLocalBefore = True
sOptions.SaveLocalAfter = True

TransactionManager.Instance.ForceCloseTransaction()

if IN[3]:
	try:
		for files,filenames in zip(file,filename):
			modelpath = FilePath(files)
			newdoc = app.OpenDocumentFile(modelpath,oOptions)
			collector = Autodesk.Revit.DB.FilteredElementCollector(newdoc)
			linkTypes = UnwrapElement(collector.OfClass(Autodesk.Revit.DB.RevitLinkType))
			for linkType in flatten(linkTypes):
				linkPara = linkType.GetParameters("Type Name")
				linkParavalue = GetParaValue(linkPara)
				try:
					linkType.Unload(None)
					unloadstatus.append(True)
				except:
					unloadstatus.append(False)
				results = [unloadstatus]		
			newfilepath = newpath + "\\" + filenames
			newdoc.SaveAs(newfilepath,SaveOptions)			
			newdoc.SynchronizeWithCentral(tOptions,sOptions)
			newdoc.Close(True)
			newdocpath.append(newfilepath) 
			OUT = newdocpath 	
	except Exception,e:
		OUT = str(e)
else: OUT = "Please set IN[3] to true"

with IN[3] being a boolean input

EDIT: it works fine for all cases i used.

1 Like

Thanks, it is working as well, however it does not close the files, and keep consuming memory. They will only go if I close Revit. Which is not a big deal, I am messing with this because I am willing to batch run this on 300 rvt files within a average of 300mb each.

The files I am using to test it are just blank ones.

I realized that because I had worksharing monitor open and I could still see them there.
123%20s

ah i know what is your issue. you will need to open a blank project for this application. Do not use it at a current project.

EDIT: by blank i mean a new empty project

I believe I was in a blank file, will check and try again, thanks!

Can the working dyn be posted? I’m trying to get this work but having trouble.

Thanks!

here is the latest one, RevitModel_DetachUnloadSave_v1.3.dyn (48.1 KB)

1 Like

Hi guys,
I’m looking for an automatization to detach and save as new central the files come in BIM360 in a server’s folder… This amazing script can help me?

Hi there, BIM360 documents might be alittle bit more tricky, but the script should do the trick as well. Maybe you could test it out and let us know?

Hi @stillgotme,
of course, I’m trying it right these days and I’ll let you know soon

It seems doesn’t work… Maybe in the dicrectory folder there must to be only rvt file and no other folders?
The script run and complete but the lists are empty

If I run it between two folder on the desktop it works well, but it doesn’ t work if I run it between BIM360 and a server’s folder. Maybe the code of python node needs to a modify?

its empty list cause the directory.content node couldnt find any files within it. Did you download the files from bim360?

no, I did not. I just copy/paste the file path on the pc to BIM360… is it a wrong way?

After several tests, is possible to open, detach and save as multiple file in batch with Revit Batch Processor… It works perfectly, you need the model Guide ID as text

colleagues, I’m sorry if I’m interfering with what you don’t need…

in order not to load links when opening a model, you can use transmissiondata, which allows you to configure the unloading of links without opening models.

it will look something like this:
t_data=TransmissionData.ReadTransmissionData(path)
t_data_links_id = t_data.GetAllExternalFileReferenceIds()

for u in t_data_links_id:

refdata = t_data.GetLastSavedReferenceData(u)
if refdata.ExternalFileReferenceType == ExternalFileReferenceType.RevitLink:

	refdata_mas.append(refdata)
	link_ref = refdata.GetPath()
	linktype_ref = refdata.PathType
	t_data.SetDesiredReferenceData(u,link_ref,linktype_ref,False)

t_data.IsTransmitted = True
TransmissionData.WriteTransmissionData(path, t_data)

2 Likes

Hi. Can i have a script for this task?
i will appreciate. Thank you