Files
SzmediTools/Szmedi.RevitToolkit.Approval/ViewModels/ManualFillSignViewModel.cs
2025-09-16 16:06:41 +08:00

517 lines
24 KiB
C#

using System.Collections.Specialized;
using System.ComponentModel;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Xml.Linq;
using Autodesk.Internal.Windows;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Plumbing;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
using Szmedi.RevitToolkit.Approval.Models;
namespace Szmedi.RevitToolkit.Approval.ViewModels
{
public partial class ManualFillSignViewModel : ObservableObject
{
public ManualFillSignViewModel()
{
ArchiCollection = CollectionViewSource.GetDefaultView(ArchiSigns);
ArchiSpaceCollection = CollectionViewSource.GetDefaultView(ArchiSpaceSigns);
MasterPlanSpaceCollection = CollectionViewSource.GetDefaultView(MasterPlanSpaceSigns);
}
public List<string> ArchiSigns => MvdLiteAssist.GetSigns(Major.Architecture, "建筑", "IfcBuilding");
public List<string> ArchiSpaceSigns => MvdLiteAssist.GetSigns(Major.Architecture, "空间", "IfcSpatialElement");
public List<string> MasterPlanSpaceSigns => MvdLiteAssist.GetSigns(Major.MasterPlan, "空间", "IfcSpatialElement");
public ICollectionView ArchiCollection { get; set; }
public ICollectionView ArchiSpaceCollection { get; set; }
public ICollectionView MasterPlanSpaceCollection { get; set; }
[ObservableProperty]
public partial string ArchiFilterText { get; set; }
partial void OnArchiFilterTextChanged(string value)
{
if (ArchiCollection != null)
{
ArchiCollection.Filter = item =>
{
if (item is string sign)
{
return string.IsNullOrEmpty(value) || sign.Contains(value);
}
return false;
};
ArchiCollection.Refresh();
}
}
[RelayCommand]
private void WriteSystemSign(object obj)
{
if (obj is ComboBoxItem item)
{
var majorName = item.Content.ToString();
//var content = IOAssists.GetMvdLiteContent(majorName);
//var data = MvdLiteAssist.Parse(content);
//var definition = MvdLiteAssist.GetDefinitionByName(data, "系统", "IfcSystem");
//var systemSigns = definition.TypeLabels;
var systemSigns = MvdLiteAssist.GetSigns(majorName, "系统", "IfcSystem");
RvApp.Handler
.Raise(
uiapp =>
{
StringBuilder sb = new StringBuilder();
var uidoc = uiapp.ActiveUIDocument;
var doc = uidoc.Document;
doc.InvokeGroup(
_ =>
{
var pipeSystem = Category.GetCategory(doc, BuiltInCategory.OST_PipingSystem);
var ductSystem = Category.GetCategory(doc, BuiltInCategory.OST_DuctSystem);
var electricalSystem = Category.GetCategory(
doc,
BuiltInCategory.OST_ElectricalCircuit);
var set = uiapp.Application.Create.NewCategorySet();
set.Insert(pipeSystem);
set.Insert(ductSystem);
set.Insert(electricalSystem);
if (doc.IsExistProjectParam("深圳系统标识", out var def, out var b))
{
InstanceBinding ib = new InstanceBinding(set);
doc.Invoke(
_ =>
{
doc.ParameterBindings.ReInsert(def, ib, BuiltInParameterGroup.PG_IFC);
});
}
else
{
doc.AddSharedParameter("深圳系统标识", set, BuiltInParameterGroup.PG_IFC);
}
doc.Invoke(
_ =>
{
var systemGroups = new FilteredElementCollector(doc).OfClass(
typeof(MEPSystem))
.WhereElementIsNotElementType()
.GroupBy(s => s.GetTypeId());
foreach (var systemGroup in systemGroups)
{
var systemTypeName = doc.GetElement(systemGroup.Key).Name
.Replace("系统", "");
int minRatio = 30;
string resultSign = string.Empty;
foreach (var sign in systemSigns)
{
var signClean = sign.Replace("系统", "").Replace(" ", "");
var temp = FuzzySharp.Fuzz.PartialRatio(signClean, systemTypeName);
if (temp >= minRatio)
{
minRatio = temp;
resultSign = sign;
}
}
foreach (var system in systemGroup)
{
var sign = system.LookupParameter("深圳系统标识");
if (sign == null)
{
sb.AppendLine($"{system.Id} {system.Name}未定义参数:深圳系统标识");
continue;
}
if (sign != null && !sign.IsReadOnly)
{
sign.Set(resultSign);
}
}
}
},
"填写系统标识");
if (sb.Length > 0)
{
MessageBox.Show(sb.ToString(), "部分元素处理失败", MessageBoxButton.OK, MessageBoxImage.Warning);
}
else
{
MessageBox.Show("处理完成", "完成");
}
}, "填写深圳系统标识");
});
}
}
[ObservableProperty]
public partial string ArchiSpaceFilterText { get; set; }
partial void OnArchiSpaceFilterTextChanged(string value)
{
if (ArchiSpaceCollection != null)
{
ArchiSpaceCollection.Filter = item =>
{
if (item is string sign)
{
return string.IsNullOrEmpty(value) || sign.Contains(value);
}
return false;
};
ArchiSpaceCollection.Refresh();
}
}
[ObservableProperty]
public partial string MasterPlanSpaceFilterText { get; set; }
partial void OnMasterPlanSpaceFilterTextChanged(string value)
{
if (MasterPlanSpaceCollection != null)
{
MasterPlanSpaceCollection.Filter = item =>
{
if (item is string sign)
{
return string.IsNullOrEmpty(value) || sign.Contains(value);
}
return false;
};
MasterPlanSpaceCollection.Refresh();
}
}
[RelayCommand]
private void RoomNameToSign()
{
RvApp.Handler
.Raise(
uiapp =>
{
StringBuilder sb = new StringBuilder();
var uidoc = uiapp.ActiveUIDocument;
var doc = uidoc.Document;
var rooms = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).WhereElementIsNotElementType();
doc.Invoke(
_ =>
{
foreach (var room in rooms)
{
var name = room.get_Parameter(BuiltInParameter.ROOM_NAME)?.AsString();
var sign = room.GetParameters("深圳空间标识").FirstOrDefault();
if (sign == null)
{
sb.AppendLine($"{room.Id} {room.Name}未定义参数:深圳空间标识");
continue;
}
if (sign != null && !sign.IsReadOnly)
sign.Set(name);
}
},
"房间名转标识");
if (sb.Length > 0)
{
MessageBox.Show(sb.ToString(), "部分元素处理失败", MessageBoxButton.OK, MessageBoxImage.Warning);
}
else
{
MessageBox.Show("处理完成", "完成");
}
});
}
[RelayCommand]
private void WriteLevelSign(object obj)
{
if (obj == null)
{
MessageBox.Show("请选择标识", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
if (obj is ComboBoxItem item)
{
var levelSign = item.Content.ToString();
RvApp.Handler
.Raise(
uiapp =>
{
var uidoc = uiapp.ActiveUIDocument;
var doc = uidoc.Document;
if (uidoc.ActiveView.ViewType != ViewType.Elevation)
{
var view = doc.OfClass<ViewSection>()
.Cast<View>()
.FirstOrDefault(v => v.ViewType == ViewType.Elevation && !v.IsTemplate);
uidoc.ActiveView = view;
}
//var uidoc = uiapp.ActiveUIDocument;
//var doc = uidoc.Document;
doc.InvokeGroup(
_ =>
{
var area = Category.GetCategory(doc, BuiltInCategory.OST_Areas);
var room = Category.GetCategory(doc, BuiltInCategory.OST_Rooms);
var level = Category.GetCategory(doc, BuiltInCategory.OST_Levels);
var set = uiapp.Application.Create.NewCategorySet();
set.Insert(area);
set.Insert(room);
set.Insert(level);
var sign = "深圳空间标识";
if (doc.IsExistProjectParam(sign, out var def, out var b))
{
InstanceBinding ib = new InstanceBinding(set);
doc.Invoke(
_ =>
{
doc.ParameterBindings.ReInsert(def, ib, BuiltInParameterGroup.PG_IFC);
});
}
else
{
doc.AddSharedParameter(sign, set, BuiltInParameterGroup.PG_IFC);
}
var levels = uidoc.Selection
.PickElementsByRectangle(new GenericFilter<Level>(), "请框选标高");
doc.Invoke(
_ =>
{
foreach (var level in levels)
{
level.LookupParameter("深圳空间标识")?.SetValue(levelSign);
}
});
},
"填写楼层标识");
});
}
}
/// <summary>
/// 需要移除现有的标识参数
/// </summary>
/// <param name="paramName"></param>
/// <returns></returns>
private bool NeedRemoveParameter(Document doc, string paramName)
{
var dict = SharedParameterAssists.GetParameterElementBindings(doc)
.Where(d => d.Key.Name == paramName);
if (dict.Any())
{
var result = MessageBox.Show(
$"已存在一个或多个{paramName}的参数定义,将全部进行删除,并重新添加,是否继续?",
"警告",
MessageBoxButton.YesNo,
MessageBoxImage.Warning);
if (result == MessageBoxResult.Yes)
{
doc.Invoke(
_ =>
{
doc.Delete(dict.Select(d => d.Key).Select(p => p.Id).ToList());
},
$"删除现有{paramName}参数");
}
else
{
return false;
}
}
return true;
}
//[RelayCommand]
//private void PreviewTextInput(TextCompositionEventArgs args)
//{
// if (args != null && args.Source is ComboBox cb)
// {
// if (cb.Text == cb.SelectedItem?.ToString())
// {
// args.Handled = true;
// }
// }
//}
[RelayCommand(CanExecute = nameof(CanWriteArchiSign))]
private void WriteArchiSign()
{
RvApp.Handler
.Raise(
uiapp =>
{
var doc = uiapp.ActiveUIDocument.Document;
doc.InvokeGroup(
tg =>
{
var sign = "深圳建筑标识";
//if (!NeedRemoveParameter(doc, SignParamName))
//{
// return;
//}
var projectInfo = doc.ProjectInformation;
var param = projectInfo.LookupParameter(sign);
if (param != null)
{
doc.Invoke(
ts =>
{
var projectInfo = doc.ProjectInformation;
projectInfo.LookupParameter(sign).Set(SelectedArchiSign);
});
}
else
{
var set = uiapp.Application.Create.NewCategorySet();
var cate = Category.GetCategory(doc, BuiltInCategory.OST_ProjectInformation);
set.Insert(cate);
if (SelectedArchiSign.Contains("景观") || SelectedArchiSign.Contains("景点"))
{
doc.AddSharedParameter("材质", set, BuiltInParameterGroup.PG_IFC);
}
//SharedParameterAssists.IsExistProjectParam(doc, "深圳建筑标识", out var);
doc.AddSharedParameter(sign, set, BuiltInParameterGroup.PG_IFC);
doc.Invoke(
ts =>
{
var projectInfo = doc.ProjectInformation;
projectInfo.LookupParameter(sign).Set(SelectedArchiSign);
});
}
},
"深圳建筑标识");
});
}
[RelayCommand(CanExecute = nameof(CanWriteArchiSpaceSign))]
private void WriteArchiSpaceSign()
{
RvApp.Handler
.Raise(
uiapp =>
{
var uidoc = uiapp.ActiveUIDocument;
var doc = uidoc.Document;
doc.InvokeGroup(
tg =>
{
var area = Category.GetCategory(doc, BuiltInCategory.OST_Areas);
var room = Category.GetCategory(doc, BuiltInCategory.OST_Rooms);
var level = Category.GetCategory(doc, BuiltInCategory.OST_Levels);
var set = uiapp.Application.Create.NewCategorySet();
set.Insert(area);
set.Insert(room);
set.Insert(level);
var sign = "深圳空间标识";
if (doc.IsExistProjectParam(sign, out var def, out var b))
{
InstanceBinding ib = new InstanceBinding(set);
doc.Invoke(
_ =>
{
doc.ParameterBindings.ReInsert(def, ib, BuiltInParameterGroup.PG_IFC);
});
}
else
{
doc.AddSharedParameter(sign, set, BuiltInParameterGroup.PG_IFC);
}
var references = uidoc.Selection
.PickObjects(
Autodesk.Revit.UI.Selection.ObjectType.Element,
new FuncFilter(e => e is Room || e is Area),
"请选择空间");
doc.Invoke(
ts =>
{
foreach (var reference in references)
{
var elem = doc.GetElement(reference);
elem.LookupParameter(sign).Set(SelectedArchiSpaceSign);
}
});
},
"深圳建筑空间标识");
});
}
[RelayCommand(CanExecute = nameof(CanWriteMasterPlanSpaceSign))]
private void WriteMasterPlanSpaceSign()
{
RvApp.Handler
.Raise(
uiapp =>
{
var doc = uiapp.ActiveUIDocument.Document;
doc.InvokeGroup(
tg =>
{
var sign = "深圳空间标识";
//if (!NeedRemoveParameter(doc, SignParamName))
//{
// return;
//}
var set = uiapp.Application.Create.NewCategorySet();
var cate = Category.GetCategory(doc, BuiltInCategory.OST_ProjectInformation);
set.Insert(cate);
if (doc.IsExistProjectParam(sign, out var def, out var b))
{
InstanceBinding ib = new InstanceBinding(set);
doc.Invoke(
_ =>
{
doc.ParameterBindings.ReInsert(def, ib, BuiltInParameterGroup.PG_IFC);
});
}
else
{
doc.AddSharedParameter(sign, set, BuiltInParameterGroup.PG_IFC);
}
//SharedParameterAssists.IsExistProjectParam(doc, "深圳建筑标识", out var);
doc.Invoke(
ts =>
{
var projectInfo = doc.ProjectInformation;
projectInfo.LookupParameter(sign).Set(SelectedArchiSpaceSign);
});
},
"深圳总图空间标识");
});
}
private bool CanWriteArchiSign => !string.IsNullOrEmpty(SelectedArchiSign);
private bool CanWriteArchiSpaceSign => !string.IsNullOrEmpty(SelectedArchiSpaceSign);
private bool CanWriteMasterPlanSpaceSign => !string.IsNullOrEmpty(SelectedMasterPlanSpaceSign);
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(WriteArchiSignCommand))]
public partial string SelectedArchiSign { get; set; }
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(WriteArchiSpaceSignCommand))]
public partial string SelectedArchiSpaceSign { get; set; }
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(WriteMasterPlanSpaceSignCommand))]
public partial string SelectedMasterPlanSpaceSign { get; set; }
}
}