556 lines
19 KiB
C#
556 lines
19 KiB
C#
using Autodesk.Revit.DB;
|
|
using Autodesk.Revit.UI;
|
|
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
|
using Nice3point.Revit.Toolkit.External.Handlers;
|
|
|
|
using ShrlAlgoToolkit.Core.Assists;
|
|
|
|
using System.Collections;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Windows;
|
|
|
|
|
|
namespace ShrlAlgoToolkit.RevitAddins.RvFamily;
|
|
|
|
public partial class FamilyProcessorViewModel : ObservableObject
|
|
{
|
|
[ObservableProperty]
|
|
public partial bool AddCategoryPrefix { get; set; }
|
|
|
|
[ObservableProperty]
|
|
public partial bool CreateCategoryFolder { get; set; }
|
|
|
|
[ObservableProperty]
|
|
public partial IList<ElementType> FamilyEditCollection { get; set; }
|
|
|
|
//private readonly List<TreeModel> 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(RevitAddins.RvFamily.FamilyProcessorViewModel.SaveFamiliesCommand))]
|
|
public partial string PathToSaveFamily { get; set; }
|
|
|
|
[ObservableProperty]
|
|
public partial string Prefix { get; set; }
|
|
|
|
[ObservableProperty]
|
|
public partial string ReplaceStr { get; set; }
|
|
|
|
[ObservableProperty]
|
|
[NotifyCanExecuteChangedFor(nameof(RevitAddins.RvFamily.FamilyProcessorViewModel.TransmitFamilyCommand), nameof(RevitAddins.RvFamily.FamilyProcessorViewModel.SaveFamiliesCommand))]
|
|
public partial Document SourceDoc { get; set; }
|
|
|
|
[ObservableProperty]
|
|
public partial string Suffix { get; set; }
|
|
|
|
[ObservableProperty]
|
|
[NotifyCanExecuteChangedFor(nameof(RevitAddins.RvFamily.FamilyProcessorViewModel.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<Family> FamilyCollection { get; set; } = new();
|
|
|
|
[ObservableProperty]
|
|
public List<Document> sourceDocsList;
|
|
|
|
[ObservableProperty]
|
|
public List<Document> targetDocsList;
|
|
|
|
public FamilyProcessorViewModel(UIApplication uiapp)
|
|
{
|
|
this.uiapp = uiapp;
|
|
handler = new ActionEventHandler();
|
|
FamilyEditCollection = uiapp.ActiveUIDocument.Document
|
|
.OfClasses(typeof(HostObjAttributes), typeof(FamilySymbol))
|
|
.Cast<ElementType>()
|
|
.ToList();
|
|
SourceDocsList = AllDocuments;
|
|
//FamilyEditCollection = uiApplication.ActiveUIDocument.Document.QueryElementTypeByType<ElementType>().Cast<ElementType>().ToList();
|
|
}
|
|
|
|
//private List<TreeModel> AddFamilyToTreeView()
|
|
//{
|
|
// List<TreeModel> familiesTree = new();
|
|
|
|
// #region 族
|
|
|
|
// if (SourceDoc == null)
|
|
// {
|
|
// return null;
|
|
// }
|
|
|
|
// var categories = SourceDoc.Settings.Categories;
|
|
|
|
// var familyCollector = SourceDoc.OfClass<Family>().Cast<Family>().ToList();
|
|
|
|
// var familySymbolCollector = SourceDoc.OfClass<FamilySymbol>().Cast<FamilySymbol>().ToList();
|
|
|
|
// //ErrorModels<ElementId> 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<HostObjAttributes>()
|
|
// .ToList();
|
|
// //IList<string> categoryNames = (from HostObjAttributes ele in hostObjectCollector
|
|
// // select ele.Category.Name).ToList();
|
|
|
|
// //var elementTypes = new FilteredElementCollector(sourceDoc).OfClass(typeof(ElementType));
|
|
// //ErrorModels<string> 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 System.Windows.Window window)
|
|
{
|
|
window.DialogResult = false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取当前所有文档
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private List<Document> ListOfOpenedDocument()
|
|
{
|
|
var documents = new List<Document>();
|
|
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<Family>().OfType<Family>().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 = (System.Collections.IList)obj;
|
|
var collection = items.Cast<Family>();
|
|
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<View>()
|
|
.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<View>()
|
|
.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<Family>();
|
|
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<Document> 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;
|
|
// }
|
|
//}
|