Hi All,
I have found a solution that I am happy with.
Using a Transaction Group to process groups of 100 Creation data elements as ‘SubTransactions’ then Assimilating them for a single commit.
Each SubTransaction takes 1.1 seconds to process based on what the Revit Journal File is telling me.
This timing scales fine for my application, as I have fixed the duplicate element errors that were occurring at this stage in my process.
Doc.Regeneration takes a little while after my process has been run, but I cannot see a way of reducing that time.
(Not that its too long, only takes a couple of minutes after the process ‘says’ it has been completed in my log file.)
Here is the code for reference, thanks all for your input.
## Import Reference Examples
import clr
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Events import DialogBoxShowingEventArgs
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('System')
from System.Collections.Generic import List as sList
clr.AddReference('DSCoreNodes')
import DSCore
from DSCore import *
def flat(lst):
return DSCore.List.Flatten(lst,2)
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc = uiapp.ActiveUIDocument
location_list = flat(IN[0])
family_list = flat(IN[1])
rotation_list = flat(IN[2])
lev_list = flat(IN[3])
counts = IN[4]
## Split list into chuncks
def chunks(data,sizes):
it = iter(data)
return [[next(it) for _ in range(size)] for size in sizes]
chopLen = IN[5]
# Yield successive n-sized chunks from L.
def chop(L, n):
for i in range(0, len(L), n):
yield L[i:i+n]
# # Chop Inputs
chopLocation = chop(location_list,chopLen)
chopFamily = chop(family_list,chopLen)
chopRotation = chop(rotation_list,chopLen)
chopLevel = chop(lev_list,chopLen)
# Failure Info
class CreateFailureAdvancedHandler(IFailuresPreprocessor):
def PreprocessFailures(self, failuresAccessor):
failMessages = failuresAccessor.GetFailureMessages()
if failMessages.Count == 0:
return FailureProcessingResult.Continue
if failuresAccessor.GetSeverity() == FailureSeverity.Warning:
for currentMessage in failMessages:
failuresAccessor.DeleteWarning(currentMessage)
return FailureProcessingResult.Continue
# Outputs
result = []
testing = []
# Family Instance Creation Data
collect = sList[Autodesk.Revit.Creation.FamilyInstanceCreationData]()
TransactionManager.Instance.ForceCloseTransaction()
tg = TransactionGroup(doc,"Multiple Family Creation")
tg.Start()
for cLocation, cFamily, cRotation, cLev in zip(chopLocation,chopFamily,chopRotation,chopLevel):
collect.Clear()
# Start the sub-transaction
t = Transaction(doc, "SubTransaction")
t.Start()
# Set how Failures will be handled fore the Transaction
failureOptions = t.GetFailureHandlingOptions()
failureOptions.SetFailuresPreprocessor(CreateFailureAdvancedHandler())
t.SetFailureHandlingOptions(failureOptions)
for location, family, rotation, lev in zip(cLocation, cFamily, cRotation, cLev):
location1 = location.ToXyz()
family1 = UnwrapElement(family)
rotation1 = Math.DegreesToRadians(rotation)
lev1 = UnwrapElement(lev)
create = Autodesk.Revit.Creation.FamilyInstanceCreationData(location1,family1,lev1,StructuralType.NonStructural)
create.RotateAngle = rotation1
create.Axis = Line.ByStartPointDirectionLength(location,Vector.ZAxis(),1).ToRevitType()
collect.Add(create)
# Place DB FamilyInstances
items = doc.Create.NewFamilyInstances2(collect)
# Commit Transaction
t.Commit()
# Get Revit Families
pack = []
for i in items:
pack.append(doc.GetElement(i))
result.append(pack)
# Combine all the SubTransactions into one Undo Stack item
tg.Assimilate()
## Post Process Flattened Lists to match input structure
resultF = flat(result)
output = chunks(resultF,counts)
OUT = output