using Autodesk.Revit.ApplicationServices; 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.Entity; using HStation.RevitDev.RevitDataExport.Service; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using static DevExpress.Data.Mask.Internal.RegExMaskMath.CloudOfInts; 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) { var doc = e.GetDocument(); try { var addedIds = e.GetAddedElementIds(); var removeIds = e.GetDeletedElementIds(); var modifiedIds = e.GetModifiedElementIds(); AddElements(doc, addedIds); RemoveElements(removeIds); ModifyElements(modifiedIds); 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 model in pair.Value) { var id = model.Id; 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 ModifyElements(ICollection modifiedIds) { foreach (var id in modifiedIds) { } } private static void RemoveElements(ICollection removeIds) { foreach (var id in removeIds) { var strId = id.IntegerValue.ToString(); if (GlobalResource.RevitModels.Contains(strId)) { GlobalResource.RevitModels.Remove(id.IntegerValue.ToString()); foreach (var pair in GlobalResource.RevitModels) { var values = pair.Value; var model = values.Where(x => x.Id == strId)?.ToList(); if (model == null || model.Count() == 0) { continue; } else { values.Remove(model[0]); } } } } return; } private static void AddElements(Document doc, ICollection 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.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) { GlobalResource.CurrentDocument = e.CurrentActiveView.Document; } public static List GetModelElements(this Document doc) { if (!doc.IsValidObject) { return new List(); } 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.GetHashCode() != GlobalResource.CurrentDocument.GetHashCode()) { GlobalResource.CurrentDocument = doc; GlobalResource.RevitModels = new Dictionary>(); } AddUnhandledElements(); } } }