Revit二次开发示例:ErrorHandling

本示例介绍了Revit的错误处理。

 

#region Namespaces
using System;
using System.Collections.Generic;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;

#endregion

namespace ErrorHandling
{
    [Autodesk.Revit.Attributes.Transaction(TransactionMode.Manual)]
    [Autodesk.Revit.Attributes.Regeneration(RegenerationOption.Manual)]
    [Autodesk.Revit.Attributes.Journaling(JournalingMode.NoCommandData)]
    public class Command : IExternalCommand, IExternalApplication
    {
        public static FailureDefinitionId m_idWarning;
        public static FailureDefinitionId m_idError;
        private FailureDefinition m_fdWarning;
        private FailureDefinition m_fdError;
        private Application m_revitApp;
        private Document m_doc;

        public Result OnShutdown(UIControlledApplication application)
        {
            return Result.Succeeded;
        }

        public Result OnStartup(UIControlledApplication application)
        {
            try
            {
                // Create failure definition Ids
                Guid guid1 = new Guid("0C3F66B5-3E26-4d24-A228-7A8358C76D39");
                Guid guid2 = new Guid("93382A45-89A9-4cfe-8B94-E0B0D9542D34");
                Guid guid3 = new Guid("A16D08E2-7D06-4bca-96B0-C4E4CC0512F8");
                m_idWarning = new FailureDefinitionId(guid1);
                m_idError = new FailureDefinitionId(guid2);

                m_fdWarning = FailureDefinition.CreateFailureDefinition(m_idWarning, FailureSeverity.Warning, "I am the warning.");
                m_fdError = FailureDefinition.CreateFailureDefinition(m_idError, FailureSeverity.Error, "I am the error");

                m_fdWarning.AddResolutionType(FailureResolutionType.MoveElements, "MoveElements", typeof(DeleteElements));
                m_fdWarning.AddResolutionType(FailureResolutionType.DeleteElements, "DeleteElements", typeof(DeleteElements));
                m_fdWarning.SetDefaultResolutionType(FailureResolutionType.DeleteElements);

                m_fdError.AddResolutionType(FailureResolutionType.DetachElements, "DetachElements", typeof(DeleteElements));
                m_fdError.AddResolutionType(FailureResolutionType.DeleteElements, "DeleteElements", typeof(DeleteElements));
                m_fdError.SetDefaultResolutionType(FailureResolutionType.DeleteElements);


            }
            catch (Exception)
            {
                return Result.Failed;
            }

            return Result.Succeeded;
        }


        public Result Execute(
          ExternalCommandData commandData,
          ref string message,
          ElementSet elements)
        {
            m_revitApp = commandData.Application.Application;
            m_doc = commandData.Application.ActiveUIDocument.Document;

            Level level1 = GetLevel();
            if (level1 == null)
            {
                throw new Exception("[ERROR] Failed to get level 1");
            }

            try
            {
                try
                {
                    Transaction transaction = new Transaction(m_doc, "Warning_FailurePreproccessor");
                    FailureHandlingOptions options = transaction.GetFailureHandlingOptions();
                    FailurePreproccessor preprocessor = new FailurePreproccessor();
                    options.SetFailuresPreprocessor(preprocessor);
                    transaction.SetFailureHandlingOptions(options);
                    transaction.Start();
                    FailureMessage fm = new FailureMessage(m_idWarning);
                    m_doc.PostFailure(fm);
                    transaction.Commit();
                }
                catch (Exception)
                {
                    message = "Failed to commit transaction Warning_FailurePreprocessor";
                    return Result.Failed;
                }

                try
                {
                    Transaction transacton = new Transaction(m_doc, "Warning_FailurePreprocessor_OverlappedWall");
                    FailureHandlingOptions options = transacton.GetFailureHandlingOptions();
                    FailurePreproccessor preproccessor = new FailurePreproccessor();
                    options.SetFailuresPreprocessor(preproccessor);
                    transacton.SetFailureHandlingOptions(options);
                    transacton.Start();

                    Line line = Line.CreateBound(new XYZ(-10, 0, 0), new XYZ(-20, 0, 0));
                    Wall wall1 = Wall.Create(m_doc, line, level1.Id, false);
                    Wall wall2 = Wall.Create(m_doc, line, level1.Id, false);
                    m_doc.Regenerate();

                    transacton.Commit();
                }
                catch (Exception)
                {
                    message = "Failed to commit transaction Warning_FailurePreproccessor_OverlappedWall";
                    return Result.Failed;
                }

                try
                {
                    m_revitApp.FailuresProcessing += FailuresProcessing;
                    Transaction transactoin = new Transaction(m_doc, "Error_FailuresProcessingEvent");
                    transactoin.Start();

                    Line line = Line.CreateBound(new XYZ(0, 10, 0), new XYZ(20, 10, 0));
                    Wall wall = Wall.Create(m_doc, line, level1.Id, false);
                    m_doc.Regenerate();

                    FailureMessage fm = new FailureMessage(m_idError);
                    FailureResolution fr = DeleteElements.Create(m_doc, wall.Id);
                    fm.AddResolution(FailureResolutionType.DeleteElements, fr);
                    m_doc.PostFailure(fm);
                    transactoin.Commit();
                }
                catch (Exception)
                {
                    message = "Failed to commit transaction Error_FailuresProcessingEvent";
                    return Result.Failed;
                }

                try
                {
                    FailuresProcessor processor = new FailuresProcessor();
                    Application.RegisterFailuresProcessor(processor);
                    Transaction transaction = new Transaction(m_doc, "Error_FailuresProcessor");
                    transaction.Start();

                    Line line = Line.CreateBound(new XYZ(0, 20, 0), new XYZ(20, 20, 0));
                    Wall wall = Wall.Create(m_doc, line, level1.Id, false);
                    m_doc.Regenerate();

                    FailureMessage fm = new FailureMessage(m_idError);
                    FailureResolution fr = DeleteElements.Create(m_doc, wall.Id);
                    fm.AddResolution(FailureResolutionType.DeleteElements, fr);
                    m_doc.PostFailure(fm);
                    transaction.Commit();
                }
                catch (Exception)
                {
                    message = "Failed to commit transaction Error_FailuresProcessor";
                    return Result.Failed;
                }


            }
            catch (Exception ex)
            {
                message = ex.Message;
                return Result.Failed;
            }

            return Result.Succeeded;
        }

        void FailuresProcessing(object sender, Autodesk.Revit.DB.Events.FailuresProcessingEventArgs e)
        {
            FailuresAccessor failuresAccessor = e.GetFailuresAccessor();
            string transactionName = failuresAccessor.GetTransactionName();

            IList<FailureMessageAccessor> fams = failuresAccessor.GetFailureMessages();
            if (fams.Count == 0)
            {
                e.SetProcessingResult(FailureProcessingResult.Continue);
                return;
            }

            if (transactionName.Equals("Error_FailuresProcessingEvent"))
            {
                foreach (FailureMessageAccessor fma in fams)
                {
                    FailureDefinitionId id = fma.GetFailureDefinitionId();
                    if (id == Command.m_idError)
                    {
                        failuresAccessor.ResolveFailure(fma);
                    }
                }

                e.SetProcessingResult(FailureProcessingResult.ProceedWithCommit);
                return;
            }

            e.SetProcessingResult(FailureProcessingResult.Continue);
        }

        private Level GetLevel()
        {
            Level level1 = null;

            FilteredElementCollector collector = new FilteredElementCollector(m_doc);
            ElementClassFilter filter = new ElementClassFilter(typeof(Level));
            IList<Element> levels = collector.WherePasses(filter).ToElements();

            foreach (Level level in levels)
            {
                if (level.Name.Equals("Level 1"))
                {
                    level1 = level;
                    break;
                }
            }

            return level1;
        }
    }

    public class FailurePreproccessor : IFailuresPreprocessor
    {
        public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
        {
            IList<FailureMessageAccessor> fmas = failuresAccessor.GetFailureMessages();
            if (fmas.Count == 0)
            {
                return FailureProcessingResult.Continue;
            }

            string transactionName = failuresAccessor.GetTransactionName();
            if (transactionName.Equals("Warning_FailurePreprocessor"))
            {
                foreach (FailureMessageAccessor fma in fmas)
                {
                    FailureDefinitionId id = fma.GetFailureDefinitionId();
                    if (id == Command.m_idError)
                    {
                        failuresAccessor.ResolveFailure(fma);
                    }
                }
                return FailureProcessingResult.ProceedWithCommit;
            }
            else
            {
                return FailureProcessingResult.Continue;
            }
        }
    }


    public class FailuresProcessor : IFailuresProcessor
    {
        public void Dismiss(Document document)
        {

        }

        public FailureProcessingResult ProcessFailures(FailuresAccessor failuresAccessor)
        {
            IList<FailureMessageAccessor> fmas = failuresAccessor.GetFailureMessages();
            if (fmas.Count == 0)
            {
                return FailureProcessingResult.Continue;
            }

            string transactionName = failuresAccessor.GetTransactionName();
            if (transactionName.Equals("Error_FailuresProcessor"))
            {
                foreach (FailureMessageAccessor fma in fmas)
                {
                    FailureDefinitionId id = fma.GetFailureDefinitionId();
                    if (id == Command.m_idError)
                    {
                        failuresAccessor.ResolveFailure(fma);
                    }
                }

                return FailureProcessingResult.ProceedWithCommit;
            }
            else
            {
                return FailureProcessingResult.Continue;
            }

        }
    }


    
}
原文地址:https://www.cnblogs.com/xpvincent/p/3610823.html