qin
2024-09-24 43bd8ee779a4cca7483bdf73c176b9fb8ebed5e2
HStation.RevitDev/RevitDataExport/Utility/DocumentUtil.cs
@@ -1,67 +1,265 @@
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using DevExpress.Utils.Extensions;
using HStation.RevitDev.RevitDataExport.Common;
using System.Linq;
namespace HStation.RevitDev.RevitDataExport.Utility
{
    public class DocumentUtil
    {
        public static void RegistDocumentEvent(Application app)
        {
            app.DocumentChanged -= App_DocumentChanged;
            app.DocumentChanged += App_DocumentChanged;
        }
        private static void App_DocumentChanged(object sender, DocumentChangedEventArgs e)
        {
            var doc = e.GetDocument();
            var addedIds = e.GetAddedElementIds();
            var removeIds = e.GetDeletedElementIds();
            var modifiedIds = e.GetModifiedElementIds();
            bool instancePlacing = GlobalResource.InstancePlacing;
            bool pipePlacing = GlobalResource.PipePlacing;
            if (pipePlacing || instancePlacing)
            {
                foreach (var id in addedIds)
                {
                    var elem = doc.GetElement(id);
                    if (elem is FamilyInstance fi)
                    {
                        GlobalResource.FamilyInstanceIds.Add(id.IntegerValue.ToString());
                        TaskDialog.Show("提示", "增加族示例:" + id.IntegerValue.ToString());
                    }
                    if (elem is Pipe pipe)
                    {
                        GlobalResource.FamilyInstanceIds.Add(id.IntegerValue.ToString());
                        TaskDialog.Show("提示", "增加管道:" + id.IntegerValue.ToString());
                    }
                }
            }
            foreach (var id in removeIds)
            {
                if (GlobalResource.FamilyInstanceIds.Contains(id.IntegerValue.ToString()))
                {
                    GlobalResource.FamilyInstanceIds.Remove(id.IntegerValue.ToString());
                    TaskDialog.Show("提示", "删除元素:" + id.IntegerValue.ToString());
                }
            }
            foreach (var id in modifiedIds)
            {
                if (GlobalResource.FamilyInstanceIds.Contains(id.IntegerValue.ToString()))
                {
                }
            }
        }
    }
}
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using DevExpress.Utils.Extensions;
using HStation.RevitDev.Model.ModelEnum;
using HStation.RevitDev.RevitDataExport.Common;
using HStation.RevitDev.RevitDataExport.Service;
using System;
using System.Collections.Generic;
using System.Linq;
namespace HStation.RevitDev.RevitDataExport.Utility
{
    public static class DocumentUtil
    {
        public static void RegistDocumentEvent(ExternalCommandData commandData)
        {
            commandData.Application.Application.DocumentChanged -= App_DocumentChanged;
            commandData.Application.Application.DocumentChanged += App_DocumentChanged;
            GlobalResource.CurrentUIDocument = commandData.Application.ActiveUIDocument;
            RegistViewEvent(commandData);
        }
        private static void App_DocumentChanged(object sender, DocumentChangedEventArgs e)
        {
            //当创建一个新文档时,先执行documentChanged事件,在执行documentCreated事件
            var doc = e.GetDocument();
            GlobalResource.CurrentDocument = doc;
            try
            {
                var addedIds = e.GetAddedElementIds();
                var removeIds = e.GetDeletedElementIds();
                AddElements(doc, addedIds);
                RemoveElements(removeIds);
                AddUnhandledElements();
                GlobalResource.InstancePanel.UpdateForm();
            }
            catch (Exception ex)
            {
                TaskDialog.Show("错误", ex.Message);
            }
        }
        //private static void UpdateLinkerInfo(Document doc)
        //{
        //    if (!doc.IsValidObject) { return; }
        //    foreach (var pair in GlobalResource.RevitModels)
        //    {
        //        foreach (var id in pair.Value)
        //        {
        //            if (id == null) { continue; }
        //            var element = doc.GetElement(new ElementId(int.Parse(id)));
        //            var linkedElems = element.GetConnectElements();
        //            var linkedIds = linkedElems.Select(x => x.Id.IntegerValue.ToString());
        //            model.LinkIds = string.Join(",", linkedIds);
        //        }
        //    }
        //}
        private static void RemoveElements(ICollection<ElementId> removeIds)
        {
            foreach (var id in removeIds)
            {
                GlobalResource.RevitModels.Remove(id.IntegerValue.ToString());
            }
            return;
        }
        private static void AddElements(Document doc, ICollection<ElementId> addedIds)
        {
            if (GlobalResource.PlacingType == RevitType.RFT_Pipe)
            {
                foreach (var id in addedIds)
                {
                    var elem = doc.GetElement(id);
                    if (elem is FamilyInstance fi)
                    {
                        AddAutoCreated(fi);
                    }
                    if (elem is Pipe)
                    {
                        GlobalResource.RevitModels.Add(elem, RevitType.RFT_Pipe);
                    }
                }
            }
            else if (GlobalResource.PlacingType != RevitType.RFT_Unknown)
            {
                foreach (var id in addedIds)
                {
                    var elem = doc.GetElement(id);
                    if (elem is FamilyInstance)
                    {
                        GlobalResource.RevitModels.Add(elem, GlobalResource.PlacingType);
                    }
                }
            }
            else
            {
                bool isPumpSystemElement = false;
                foreach (var id in addedIds)
                {
                    //手动布置的构件如消火栓、热换器等基本不能自动加入到系统中,能自动布置并连接
                    //系统的基本都是三通、四通、弯头、过渡件、管帽这些
                    if (IsConnectedWithPumpSystem(doc, id))
                    {
                        isPumpSystemElement = true;
                        break;
                    }
                }
                if (isPumpSystemElement)
                {
                    foreach (var id in addedIds)
                    {
                        AddToPumpSystem(doc, id);
                    }
                }
            }
            return;
        }
        private static bool IsConnectedWithPumpSystem(Document doc, ElementId id)
        {
            var elem = doc.GetElement(id);
            if (elem is Pipe pipe) //直接点击水泵的连接件创建管道
            {
                if (pipe.ConnectWithPumpSystem())
                {
                    return true;
                }
            }
            else if (elem is FamilyInstance fi)
            {
                if (fi.ConnectWithPumpSystem()) //直接点击管道连接点创建管道时,Revit会自动创建弯头,都需要加入到缓存
                {
                    return true;
                }
            }
            return false;
        }
        private static void AddToPumpSystem(Document doc, ElementId id)
        {
            var elem = doc.GetElement(id);
            if (elem is Pipe)
            {
                GlobalResource.RevitModels.Add(elem, RevitType.RFT_Pipe);
            }
            else if (elem is FamilyInstance fi)
            {
                AddAutoCreated(fi);
            }
            return;
        }
        private static void AddAutoCreated(FamilyInstance fi)
        {
            if (fi.IsPipeHat())
            {
                GlobalResource.RevitModels.Add(fi, RevitType.RFT_Blocker);
            }
            else if (fi.IsWanTou())
            {
                GlobalResource.RevitModels.Add(fi, RevitType.RFT_Elbow);
            }
            else if (fi.IsConverter())
            {
                GlobalResource.RevitModels.Add(fi, RevitType.RFT_Converter);
            }
            else if (fi.IsSanTong())
            {
                GlobalResource.RevitModels.Add(fi, RevitType.RFT_ThreeJoint);
            }
            else if (fi.IsSiTong())
            {
                GlobalResource.RevitModels.Add(fi, RevitType.RFT_FourJoint);
            }
            else
            {
                TaskDialog.Show("警告", $"未知类型被添加!id:{fi.Id.IntegerValue}");
                //报错
            }
        }
        public static void RegistViewEvent(ExternalCommandData commandData)
        {
            commandData.Application.ViewActivated -= Application_ViewActivated;
            commandData.Application.ViewActivated += Application_ViewActivated;
        }
        private static void Application_ViewActivated(object sender, ViewActivatedEventArgs e)
        {
            //切换文档时
            if (GlobalResource.CurrentDocument == null ||
                GlobalResource.CurrentDocument.GetHashCode() != e.CurrentActiveView.Document.GetHashCode())
            {
                GlobalResource.CurrentDocument = e.CurrentActiveView.Document;
                GlobalResource.InstancePanel.UpdateForm();
            }
        }
        public static List<Element> GetModelElements(this Document doc)
        {
            if (!doc.IsValidObject)
            {
                return new List<Element>();
            }
            var collector1 = new FilteredElementCollector(doc).
                OfCategory(BuiltInCategory.OST_PipeCurves).
                WhereElementIsNotElementType();
            var collector2 = new FilteredElementCollector(doc).
                OfClass(typeof(FamilyInstance)).
                WhereElementIsNotElementType();
            var elements1 = collector1.ToElements()?.ToList();
            var elements2 = collector2.ToElements()?.ToList();
            elements1.AddRange(elements2);
            elements1 = elements1.Where(x => x.Category.CategoryType == CategoryType.Model).ToList();
            elements1 = elements1.Where(x => x.get_BoundingBox(null) != null).ToList();
            return elements1;
        }
        public static void AddUnhandledElements()
        {
            var elements = GlobalResource.CurrentDocument.GetModelElements();
            foreach (var element in elements)
            {
                var id = element.Id.IntegerValue.ToString();
                if (GlobalResource.RevitModels.Contains(id))
                {
                    continue;
                }
                RevitMepCategoryService.AddToCache(element);
            }
            //UpdateLinkerInfo(GlobalResource.CurrentDocument);
        }
        public static void UpdataDocumentCache(this Document doc)
        {
            if (!doc.IsValidObject)
            {
                return;
            }
            if (!GlobalResource.CurrentDocument.IsValidObject || doc.GetHashCode() != GlobalResource.CurrentDocument.GetHashCode())
            {
                GlobalResource.CurrentDocument = doc;
                //GlobalResource.RevitModels = new List<Tuple<string, Dictionary<RevitType, List<string>>>>();
            }
            AddUnhandledElements();
        }
    }
}