Hi,
Running a graph which I have previously run successfully, but now I get this message for most families… I’m running in 2023 with CPython3, I don’t believe this should fail?
object does not implement IFailuresPreprocessor
I’m trying to background open families and return any errors which are generated.
Any assistance gratefully received!
Mark
import clr
import sys
import System
from System.Collections.Generic import List, IList, Dictionary
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Events import *
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Events import ViewActivatedEventArgs, ViewActivatingEventArgs, DialogBoxShowingEventArgs
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
projDoc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = DocumentManager.Instance.CurrentUIApplication.Application
my_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)
pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
sys.path.append(pf_path + '\\IronPython 2.7\\Lib')
import logging
import traceback
## Start create logger Object ##
logger = logging.getLogger("DimissDialog")
# set to DEBUG
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s :: %(levelname)s :: %(funcName)s :: %(message)s')
# create handler
file_handler = logging.FileHandler(my_path + '\\' + projDoc.Title + 'DimissDialog.log', mode='w')
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.disabled = False
def ControlledApplication_FailuresProcessing(sender, e):
logger.info("ControlledApplication_FailuresProcessing Event")
global dict_corrupted
global currentFamilyName
global currentFamilyId
try:
fas = e.GetFailuresAccessor()
fas.DeleteAllWarnings()
fma = fas.GetFailureMessages()
for fa in fma:
logger.debug(("failure Description", fa.GetDescriptionText()))
if fa.GetSeverity() != FailureSeverity.Warning:
dict_corrupted.append([currentFamilyName, fa.GetDescriptionText()])
#if fa.GetDefaultResolutionCaption() == "Remove Constraints":
if fas.IsFailureResolutionPermitted(fa, FailureResolutionType.UnlockConstraints):
fa.SetCurrentResolutionType(FailureResolutionType.UnlockConstraints)
fas.ResolveFailure(fa)
e.SetProcessingResult(FailureProcessingResult.ProceedWithCommit)
else:
fa.SetCurrentResolutionType(FailureResolutionType.DeleteElements)
fas.ResolveFailure(fa)
e.SetProcessingResult(FailureProcessingResult.ProceedWithCommit)
except Exception as ex:
logger.exception(ex)
class FailureAdvancedHandler(IFailuresPreprocessor):
# create a dictionnary to store families with warnings
dict_Warning = Dictionary[System.String, List[System.String]]()
def __init__(self, famDoc):
self._famDoc = famDoc
def PreprocessFailures(self, failuresAccessor):
failMessages = failuresAccessor.GetFailureMessages()
if failMessages.Count == 0:
return FailureProcessingResult.Continue
transName = failuresAccessor.GetTransactionName()
try:
self.__class__.dict_Warning.Add(self._famDoc.Title + " " + str(currentFamilyId), List[System.String]([m.GetDescriptionText() for m in failMessages]))
# if alert is an warn remove it
if failuresAccessor.GetSeverity() == FailureSeverity.Warning:
for currentMessage in failMessages:
failuresAccessor.DeleteWarning(currentMessage)
return FailureProcessingResult.Continue
# if alert is an error resolve it (by delete elements or by split group etc...)
elif failuresAccessor.GetSeverity() != FailureSeverity.Warning:
for currentMessage in failMessages:
failuresAccessor.SetCurrentResolutionType(FailureResolutionType.DeleteElements)
failuresAccessor.ResolveFailures(currentMessage)
return FailureProcessingResult.ProceedWithCommit
else:
pass
except Exception as e:
logger.exception(ex)
return FailureProcessingResult.Continue
# Retrieve all families that are not system families in current doc
fam_types = FilteredElementCollector(projDoc).OfClass(Family)
errors = []
dict_warnings = None
dict_corrupted = []#Dictionary[System.String, System.String]()
delegate = System.EventHandler[FailuresProcessingEventArgs]( ControlledApplication_FailuresProcessing )
app.FailuresProcessing += delegate
for f in fam_types:
if (f.IsEditable):
currentFamilyName = f.Name + " : " + str(f.Id)
try:
TransactionManager.Instance.ForceCloseTransaction()
famDoc = projDoc.EditFamily(f)
t = Transaction(famDoc, 'Test')
t.Start()
failureOptions = t.GetFailureHandlingOptions()
handler = FailureAdvancedHandler(famDoc)
failureOptions.SetFailuresPreprocessor(handler)
t.SetFailureHandlingOptions(failureOptions)
if famDoc.IsFamilyDocument:
famManager = famDoc.FamilyManager
for familyType in famManager.Types:
famManager.CurrentType = familyType
famDoc.Regenerate()
except Exception as ex:
logger.exception(ex)
dict_corrupted.append([currentFamilyName, str(ex)])
else:
t.Commit()
t.Dispose()
famDoc.Close(False)
famDoc.Dispose()
dict_warnings = FailureAdvancedHandler.dict_Warning
app.FailuresProcessing -= delegate
OUT = dict_corrupted, dict_warnings