using System.Collections; using System.IO; using System.Text; using System.Windows; using Autodesk.Revit.DB; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Nice3point.Revit.Toolkit.External.Handlers; using ShrlAlgoToolkit.RevitAddins.Common.Assists; namespace ShrlAlgoToolkit.RevitAddins.FamMaster; public partial class FamilyProcessorViewModel : ObservableObject { [ObservableProperty] public partial bool AddCategoryPrefix { get; set; } [ObservableProperty] public partial bool CreateCategoryFolder { get; set; } [ObservableProperty] public partial IList FamilyEditCollection { get; set; } //private readonly List familyNodes = new(); [ObservableProperty] public partial string FindStr { get; set; } private readonly ActionEventHandler handler; [ObservableProperty] public partial bool IsOverride { get; set; } = true; [ObservableProperty] public partial int ModifyNameIndex { get; set; } [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(SaveFamiliesCommand))] public partial string PathToSaveFamily { get; set; } [ObservableProperty] public partial string Prefix { get; set; } [ObservableProperty] public partial string ReplaceStr { get; set; } [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(TransmitFamilyCommand), nameof(SaveFamiliesCommand))] public partial Document SourceDoc { get; set; } [ObservableProperty] public partial string Suffix { get; set; } [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(TransmitFamilyCommand))] public partial Document TargetDoc { get; set; } //private readonly ExternalEvent saveEvent; //private readonly SaveFamilyHandler handler; //便于类中各处进行调用,故在此处添加字段 private readonly UIApplication uiapp; [ObservableProperty] public partial bool View3dAsDefault { get; set; } [ObservableProperty] public partial List FamilyCollection { get; set; } = new(); [ObservableProperty] public List sourceDocsList; [ObservableProperty] public List targetDocsList; public FamilyProcessorViewModel(UIApplication uiapp) { this.uiapp = uiapp; handler = new ActionEventHandler(); FamilyEditCollection = uiapp.ActiveUIDocument.Document .OfClasses(typeof(HostObjAttributes), typeof(FamilySymbol)) .Cast() .ToList(); SourceDocsList = AllDocuments; //FamilyEditCollection = uiApplication.ActiveUIDocument.Document.QueryElementTypeByType().Cast().ToList(); } //private List AddFamilyToTreeView() //{ // List familiesTree = new(); // #region 族 // if (SourceDoc == null) // { // return null; // } // var categories = SourceDoc.Settings.Categories; // var familyCollector = SourceDoc.OfClass().Cast().ToList(); // var familySymbolCollector = SourceDoc.OfClass().Cast().ToList(); // //ErrorModels dimensionTypeId = (from ElementToMove i in new FilteredElementCollector(sourceDoc).OfClass(typeof(DimensionType)) select i.ViewId).ToList(); // //var elementTypes = new FilteredElementCollector(sourceDoc).OfClass(typeof(ElementType)); // //ElementClassFilter familysymbolfilter = new ElementClassFilter(typeof(FamilySymbol)); // //ElementClassFilter hostsymbolFilter = new ElementClassFilter(typeof(HostObjAttributes)); // //LogicalOrFilter andfilter = new LogicalOrFilter(familysymbolfilter, hostsymbolFilter); // //var familiesSymbolCollector = new FilteredElementCollector(sourceDoc).WherePasses(andfilter); // foreach (Category category in categories) // { // TreeModel familyCategoryNode = // new() // { // //familyCategory.ViewId = category.Name; // Name = category.Name, // IsExpanded = false // }; // foreach (var family in familyCollector) // { // if (family.FamilyCategory.Name == category.Name) // { // TreeModel familyNode = // new() // { // //familyNode.ViewId = family.Name; // Name = family.Name, // IsExpanded = false, // Parent = familyCategoryNode // }; // familyCategoryNode.Children.Add(familyNode); // //获取族及其族类型,作为加载对象合集 // familyNodes.Add(familyNode); // foreach (var familySymbol in familySymbolCollector) // { // if (familySymbol.FamilyName == family.Name) // { // TreeModel familySymbolNode = // new() // { // //familiesSymbolNode.ViewId = familySymbol.Name; // Name = familySymbol.Name, // Parent = familyNode // }; // familyNode.Children.Add(familySymbolNode); // } // } // } // } // if (familyCategoryNode.Children.Count != 0) // { // FamilyNodesList.Add(familyCategoryNode); // } // } // #endregion 族 // var hostObjectCollector = new FilteredElementCollector(SourceDoc) // .OfClass(typeof(HostObjAttributes)) // .Cast() // .ToList(); // //IList categoryNames = (from HostObjAttributes ele in hostObjectCollector // // select ele.Category.Name).ToList(); // //var elementTypes = new FilteredElementCollector(sourceDoc).OfClass(typeof(ElementType)); // //ErrorModels ss1 = categoryNames.Distinct().ToList(); // foreach (var obj in hostObjectCollector) // { // var categoryName = obj.Category.Name; // var familyName = obj.FamilyName; // var familySymbolName = obj.Name; // #region categoryRegion // TreeModel familyCategoryNode = null; // foreach (var t in familiesTree) // { // if (t.ToolTip.Equals(categoryName)) //遍历是否找到相同的节点 // { // familyCategoryNode = t; //有则传递给当前类别节点 // break; // } // } // if (familyCategoryNode == null) // { // TreeModel t = new() { Name = categoryName, IsExpanded = false }; // familyCategoryNode = t; // familiesTree.Add(familyCategoryNode); // } // #endregion categoryRegion // #region familyRegion // TreeModel familyNode = null; // foreach (var t in familyCategoryNode.Children) // { // if (t.ToolTip.Equals(categoryName + "-" + familyName)) // { // familyNode = t; // break; // } // } // if (familyNode == null) // { // TreeModel t = // new() // { // Name = familyName, // IsExpanded = false, // Parent = familyCategoryNode // }; // familyCategoryNode.Children.Add(t); // familyNode = t; // familyNodes.Add(familyNode); // } // #endregion familyRegion // #region familySymbol // TreeModel familySymbolNode = null; // foreach (var t in familyNode.Children) // { // if (t.ToolTip.Equals(familyName + "-" + familySymbolName)) // { // familySymbolNode = t; // break; // } // } // if (familySymbolNode == null) // { // TreeModel t = // new() // { // Name = familySymbolName, // IsExpanded = false, // Parent = familyNode // }; // familyNode.Children.Add(t); // } // #endregion familySymbol // //TreeModel familyNode = new TreeModel(); // //familyNode.Name = obj.FamilyName; // ////familyNode.Name = obj.FamilyName; // //familyNode.IsExpanded = false; // //familyNode.Parent = categoryNode; // //categoryNode.Children.Add(familyNode); // //familyNodes.Add(familyNode); // ////if (obj.Name == familyNode.Name) // ////{ // //TreeModel familiesSymbolNode = new TreeModel(); // ////familiesSymbolNode.ViewId = familySymbol.Name; // //familiesSymbolNode.Name = obj.Name; // //familiesSymbolNode.Parent = familyNode; // //familyNode.Children.Add(familiesSymbolNode); // //} // } // familiesTree.Sort(); // return familiesTree; // //FamilyTreeView.UpdateLayout(); //} [RelayCommand] private static void Cancel(object obj) { if (obj is Window window) { window.DialogResult = false; } } /// /// 获取当前所有文档 /// /// private List ListOfOpenedDocument() { var documents = new List(); foreach (Document document in uiapp.Application.Documents) { if (!document.IsLinked && !document.IsFamilyDocument) { documents.Add(document); } } return documents; } partial void OnSourceDocChanged(Document value) { FamilyCollection = SourceDoc.OfClass().OfType().Where(f => f.IsEditable).ToList(); TargetDocsList = new( AllDocuments.Where( d => (d.PathName != null && SourceDoc?.PathName != null && d.PathName != SourceDoc.PathName) || (SourceDoc != null && d.Title != SourceDoc.Title) || SourceDoc == null ) ); } [RelayCommand(CanExecute = nameof(CanSaveFamilies))] private void SaveFamilies(object obj) { var items = (IList)obj; var collection = items.Cast(); var selectedItems = collection.ToList(); if (!selectedItems.Any()) { return; } handler.Raise(_ => { StringBuilder sb = new(); if (!Directory.Exists(PathToSaveFamily)) { var dr = MessageBox.Show("路径不存在,是否创建该路径", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Information); if (dr == MessageBoxResult.OK) { try { Directory.CreateDirectory(PathToSaveFamily); } catch (Exception ex) { ex.Message.ToLog(); MessageBox.Show("无法创建保存路径", "错误", MessageBoxButton.YesNo, MessageBoxImage.Error); } } } else { //FileInfo fileInfo = new FileInfo(text3); foreach (var family in selectedItems) { var familyFileInfo = family.Name; //string categoryInfo = family.Category.Name; var directory = PathToSaveFamily + "\\"; var categoryInfo = family.FamilyCategory.Name; if (CreateCategoryFolder) { directory += $"{categoryInfo}\\"; DirectoryInfo directoryInfo = new(directory); if (!directoryInfo.Exists) { directoryInfo.Create(); } } if (AddCategoryPrefix) { familyFileInfo = $"({categoryInfo}){familyFileInfo}"; } var completeDir = directory + familyFileInfo + ".rfa"; try { FileInfo fileInfo = new(completeDir); if (fileInfo.Exists) { if (IsOverride) { fileInfo.Delete(); } } if (family.IsEditable) { var editFamily = SourceDoc.EditFamily(family); if (View3dAsDefault) { Set3DView(editFamily); } editFamily.SaveAs(completeDir); editFamily.Close(false); } else { sb.AppendLine($"{categoryInfo}-{family.Name}"); } } catch (Exception ex) { MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } } if (!string.IsNullOrEmpty($"{sb}")) { MessageBox.Show($"以下族无法导出:\n{sb}", "导出错误", MessageBoxButton.OK, MessageBoxImage.Error); } }); //saveEvent.Raise(); } [RelayCommand] private void SelectDirectory() { Melskin.Controls.VistaFolderBrowserDialog dialog = new(); //dialog.Description = "请选择文件路径"; //dialog.SeletcedPath = @"C:\Users\ZGG\Documents"; if (dialog.ShowDialog() == true) { var savePath = dialog.SelectedPath; PathToSaveFamily = savePath; } } private static void Set3DView(Document doc) { try { Transaction transaction = new(doc); transaction.Start(); doc.GetDocumentPreviewSettings(); SaveAsOptions saveAsOptions = new(); if (doc.GetDocumentPreviewSettings().PreviewViewId.Equals(ElementId.InvalidElementId)) { var startingViewSettings = StartingViewSettings.GetStartingViewSettings(doc); if (!startingViewSettings.ViewId.Equals(ElementId.InvalidElementId)) { saveAsOptions.PreviewViewId = startingViewSettings.ViewId; } else { var viewCollector = new FilteredElementCollector(doc).OfClass(typeof(View)); var viewEnum = viewCollector .Cast() .Where(view => view.ViewType == ViewType.ThreeD && !view.IsTemplate); var flag = true; foreach (View view in (IEnumerable)viewEnum) { if (view.IsTemplate) { continue; } saveAsOptions.PreviewViewId = view.Id; flag = false; break; } if (flag) { foreach ( View view in (IEnumerable) viewCollector .Cast() .Where(viewNot3D => { return viewNot3D.ViewType is ViewType.FloorPlan or ViewType.EngineeringPlan or ViewType.Elevation || (viewNot3D.ViewType == ViewType.Section && !viewNot3D.IsTemplate); }) ) { if (view.IsTemplate) { continue; } saveAsOptions.PreviewViewId = view.Id; break; } } } } transaction.Commit(); } catch { // ignored } } [RelayCommand(CanExecute = nameof(CanTransmitFamilies))] private void TransmitFamily(object obj) { var items = (IList)obj; var collection = items.Cast(); var selectedItems = collection.ToList(); if (!selectedItems.Any()) { return; } handler.Raise(_ => { TargetDoc.Invoke(_ => { CopyPasteOptions copyPasteOptions = new(); //copyPasteOptions.SetDuplicateTypeNamesHandler(copyPasteOptions.GetDuplicateTypeNamesHandler()); var ids = selectedItems.ConvertAll(f => f.Id); ElementTransformUtils.CopyElements(SourceDoc, ids, TargetDoc, null, copyPasteOptions); }, "传递族" ); }); } private List AllDocuments => ListOfOpenedDocument(); private bool CanSaveFamilies => PathToSaveFamily != null && SourceDoc != null; private bool CanTransmitFamilies => SourceDoc != null && TargetDoc != null; } //public class CopyHandlerOk : IDuplicateTypeNamesHandler //{ // public DuplicateTypeAction OnDuplicateTypeNamesFound(DuplicateTypeNamesHandlerArgs args) // { // return DuplicateTypeAction.UseDestinationTypes; // } //} //public class CopyHandlerAbort : IDuplicateTypeNamesHandler //{ // public DuplicateTypeAction OnDuplicateTypeNamesFound(DuplicateTypeNamesHandlerArgs args) // { // return DuplicateTypeAction.Abort; // } //}