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 removeIds) { foreach (var id in removeIds) { GlobalResource.RevitModels.Remove(id.IntegerValue.ToString()); } 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.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 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.IsValidObject) { return; } if (!GlobalResource.CurrentDocument.IsValidObject || doc.GetHashCode() != GlobalResource.CurrentDocument.GetHashCode()) { GlobalResource.CurrentDocument = doc; //GlobalResource.RevitModels = new List>>>(); } AddUnhandledElements(); } } }