I think my family creation time using the FamilyInstances2 method will work overall, I am confident that batch execution using it will work. Just having a head scratcher with the below. Ideally it would run a Transaction for each chunk ignoring any warnings thrown.
Bit of a long one⌠but here goes.
So Code 1 will process everything as chunks but commit 1 transaction (Iâm looking for a transaction per chunk) with no warnings, creates elements as expected. Some DuplicateInstances warnings are created for multiple elements, which is ok as Iâm looking on how to ignore this programmatically.
Code 1
## 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 *
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)
#OUT = chopLocation
class DuplicateInstancesWarningSwallower(IFailuresPreprocessor):
def PreprocessFailures(self, failuresAccessor):
fail_list = List[FailureMessageAccessor]()
fail_acc_list = failuresAccessor.GetFailureMessages().GetEnumerator()
for failure in fail_acc_list:
failuresAccessor.ResolveFailure(failure)
failure_id = failure.GetFailureDefinitionId()
failure_severity = failure.GetSeverity()
failure_type = BuiltInFailures.InaccurateFailures.DuplicateInstances
if failure_id == failure_type:
failuresAccessor.DeleteWarning(failure)
return FailureProcessingResult.Continue
output = []
result = []
testing = []
collect = sList[Autodesk.Revit.Creation.FamilyInstanceCreationData]()
for cLocation, cFamily, cRotation, cLev in zip(chopLocation,chopFamily,chopRotation,chopLevel):
collect.Clear()
TransactionManager.Instance.EnsureInTransaction(doc)
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)
items = doc.Create.NewFamilyInstances2(collect)
pack = []
for i in items:
pack.append(doc.GetElement(i))
result.append(pack)
TransactionManager.Instance.TransactionTaskDone()
OUT = result
Code 2 will process chunks as separate Transactions but throws the DuplicateInstances warnings when run, so not ideal for a âhands-freeâ user execution.
Code 2
## 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 *
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)
#OUT = chopLocation
class DuplicateInstancesWarningSwallower(IFailuresPreprocessor):
def PreprocessFailures(self, failuresAccessor):
fail_list = List[FailureMessageAccessor]()
fail_acc_list = failuresAccessor.GetFailureMessages().GetEnumerator()
for failure in fail_acc_list:
failuresAccessor.ResolveFailure(failure)
failure_id = failure.GetFailureDefinitionId()
failure_severity = failure.GetSeverity()
failure_type = BuiltInFailures.InaccurateFailures.DuplicateInstances
if failure_id == failure_type:
failuresAccessor.DeleteWarning(failure)
return FailureProcessingResult.Continue
output = []
result = []
testing = []
collect = sList[Autodesk.Revit.Creation.FamilyInstanceCreationData]()
for cLocation, cFamily, cRotation, cLev in zip(chopLocation,chopFamily,chopRotation,chopLevel):
collect.Clear()
TransactionManager.Instance.ForceCloseTransaction()
t = Transaction(doc, "Batch Create Families")
# Start
t.Start()
#tOpt = t.GetFailureHandlingOptions()
#tOpt.SetFailuresPreprocessor(DuplicateInstancesWarningSwallower())
#t.SetFailureHandlingOptions(tOpt)
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)
items = doc.Create.NewFamilyInstances2(collect)
pack = []
for i in items:
pack.append(doc.GetElement(i))
result.append(pack)
t.Commit()
OUT = result
And Code 3 enables FailurePreProcessor methods, shows no warning but creates nothingâŚ
Code 3
## 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 *
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)
#OUT = chopLocation
class DuplicateInstancesWarningSwallower(IFailuresPreprocessor):
def PreprocessFailures(self, failuresAccessor):
fail_list = List[FailureMessageAccessor]()
fail_acc_list = failuresAccessor.GetFailureMessages().GetEnumerator()
for failure in fail_acc_list:
failuresAccessor.ResolveFailure(failure)
failure_id = failure.GetFailureDefinitionId()
failure_severity = failure.GetSeverity()
failure_type = BuiltInFailures.InaccurateFailures.DuplicateInstances
if failure_id == failure_type:
failuresAccessor.DeleteWarning(failure)
return FailureProcessingResult.Continue
output = []
result = []
testing = []
collect = sList[Autodesk.Revit.Creation.FamilyInstanceCreationData]()
for cLocation, cFamily, cRotation, cLev in zip(chopLocation,chopFamily,chopRotation,chopLevel):
collect.Clear()
TransactionManager.Instance.ForceCloseTransaction()
t = Transaction(doc, "Batch Create Families")
# Start
t.Start()
tOpt = t.GetFailureHandlingOptions()
tOpt.SetFailuresPreprocessor(DuplicateInstancesWarningSwallower())
t.SetFailureHandlingOptions(tOpt)
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)
items = doc.Create.NewFamilyInstances2(collect)
pack = []
for i in items:
pack.append(doc.GetElement(i))
result.append(pack)
t.Commit()
OUT = result
At least I am making progress