Files
SzmediTools/Szmedi.RvKits/InfoManager/Delivery/ParameterHelpers.cs
2025-09-16 16:06:41 +08:00

757 lines
36 KiB
C#

using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
namespace Szmedi.RvKits.InfoManager.Delivery
{
internal class ParameterHelpers
{
/// <summary>
/// 添加族参数,需要编辑族
/// </summary>
/// <param name="uidoc"></param>
/// <param name="parametersToAdded">数据库中分类的参数</param>
/// <param name="sharedParameters">数据库中唯一的共享参数</param>
/// <param name="isFamilyParam">true常规族参数或false共享参数族参数</param>
/// <param name="filePath">共享参数路径</param>
public static void AddFamilyParameters(
UIDocument uidoc,
List<ParamData> parametersToAdded,
List<SharedParameterData> sharedParameters,
bool isFamilyParam,
string filePath)
{
StringBuilder sb = new();
Document doc = uidoc.Document;
Autodesk.Revit.ApplicationServices.Application app = doc.Application;
//var references = uidoc.Selection.PickObjects(ObjectType.Element,
// new TypesSelectionFilter(doc, typeof(FamilyInstance)), "请选择需要添加添加共享参数作为族参数的族实例");
var instancesSelected = uidoc.Selection
.PickElementsByRectangle(new FuncFilter(e => e is FamilyInstance instance && instance.Symbol.Family.IsEditable), "请框选需要添加参数的族实例")
.Cast<FamilyInstance>()
.ToList();
//var instancesSelected = from reference in references
// select doc.GetElement(reference) as FamilyInstance;
if (!instancesSelected.Any())
{
return;
}
//得到族
var families = instancesSelected
.GroupBy(ins => ins.Symbol.Family.Id.IntegerValue)
.Select(g => g.FirstOrDefault()?.Symbol.Family)
.ToList();
using (TransactionGroup group = new(doc, "添加族参数"))
{
group.Start();
var originSharedParametersFile = app.SharedParametersFilename.Clone();
DefinitionFile tempFile = SharedParameterAssists.CreateSharedParameterFile(app, filePath);
var g = tempFile.Groups.Create("TempGroup");
foreach (var family in families)
{
if (!family.IsEditable)
{
sb.AppendLine($"族:{family.Name},不可编辑,需采用其他方式添加参数。");
continue;
}
var famdoc = doc.EditFamily(family);
using (Transaction ts = new(famdoc, "添加族参数"))
{
ts.Start();
foreach (var paramData in parametersToAdded)
{
var familyParam = famdoc.FamilyManager.get_Parameter(paramData.FullProperty);
//族参数存在时,不处理
if (familyParam != null)
{
continue;
}
//常规族参数
if (isFamilyParam)
{
try
{
famdoc.FamilyManager.AddParameter(
paramData.FullProperty,
BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES,
paramData.Unit == "/" ? ParameterType.Text : ParameterType.Number,
true
);
}
catch (Exception e)
{
LogAssists.WriteLog(e.Message);
}
}
//共享参数族参数
else
{
SharedParameterData sharedParam = sharedParameters.Find(p => p.FullParamName == paramData.FullProperty);
try
{
if (sharedParam != null)
{
ExternalDefinitionCreationOptions options =
new(
sharedParam.FullParamName,
paramData.Unit == "/" ? ParameterType.Text : ParameterType.Number)
{
GUID = new Guid(sharedParam.GUID)
};
var definition =
g.Definitions.get_Item(sharedParam.FullParamName) ?? g.Definitions.Create(options);
famdoc.FamilyManager
.AddParameter(
(ExternalDefinition)definition,
BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES,
true);
}
}
catch (Exception ex)
{
sb.AppendLine(ex.Message);
LogAssists.WriteLog(ex.Message);
}
}
}
ts.Commit();
}
famdoc.LoadFamily(doc, new FamilyLoadOption());
famdoc.Close(false);
}
File.Delete(tempFile.Filename);
app.SharedParametersFilename = originSharedParametersFile.ToString();
group.Assimilate();
}
}
/// <summary>
/// 添加项目信息
/// </summary>
/// <param name="doc"></param>
/// <param name="ParametersToAdded">数据库中分类的参数</param>
/// <param name="SharedParameters">数据库中唯一的共享参数</param>
/// <param name="filePath">共享参数路径</param>
public static void AddProjectParameters(Document doc, List<ParamData> ParametersToAdded, List<SharedParameterData> SharedParameters, string filePath)
{
StringBuilder sb = new();
Autodesk.Revit.ApplicationServices.Application app = doc.Application;
using Transaction trans = new(doc, "添加项目信息(共享参数)");
trans.Start();
//原有的共享参数文件
var originSharedParametersFile = app.SharedParametersFilename.Clone().ToString();
DefinitionFile tempFile = SharedParameterAssists.CreateSharedParameterFile(app, filePath);
var g = tempFile.Groups.Create("tempGroup");
//数据库读取的参数
foreach (var paramData in ParametersToAdded)
{
var isExist = SharedParameterAssists.IsExistProjectParam(doc, paramData.FullProperty, out var def, out var binding);
//存在则使用现有项目参数
if (isExist)
{
//存在但未关联到项目信息
if (!binding.Categories.Contains(Category.GetCategory(doc, BuiltInCategory.OST_ProjectInformation)))
{
binding.Categories.Insert(Category.GetCategory(doc, BuiltInCategory.OST_ProjectInformation));
doc.ParameterBindings.ReInsert(def, binding, BuiltInParameterGroup.PG_IDENTITY_DATA);
}
}
else
{
try
{
foreach (var sharedParameter in SharedParameters)
{
if (sharedParameter.FullParamName != paramData.FullProperty)
{
continue;
}
var categories = app.Create.NewCategorySet();
categories.Insert(Category.GetCategory(doc, BuiltInCategory.OST_ProjectInformation));
var newInstanceBinding = app.Create.NewInstanceBinding(categories);
ExternalDefinitionCreationOptions options =
new(
sharedParameter.FullParamName,
paramData.Unit == "/" ? ParameterType.Text : ParameterType.Number)
{
GUID = new Guid(sharedParameter.GUID)
};
var definition = g.Definitions.get_Item(sharedParameter.FullParamName);
definition ??= g.Definitions.Create(options);
doc.ParameterBindings.Insert(
definition,
newInstanceBinding,
BuiltInParameterGroup.PG_IDENTITY_DATA
);
break;
}
}
catch (Exception ex)
{
sb.AppendLine(ex.Message);
File.Delete(tempFile.Filename);
app.SharedParametersFilename = originSharedParametersFile;
trans.Commit();
return;
}
}
}
trans.Commit();
File.Delete(tempFile.Filename);
app.SharedParametersFilename = originSharedParametersFile;
}
/// <summary>
/// 添加自定义族参数
/// </summary>
/// <param name="uidoc"></param>
/// <param name="custom"></param>
/// <param name="isFamilyParam"></param>
/// <param name="filePath"></param>
public static void AddFamilyParam(UIDocument uidoc, CustomParamData custom, bool isFamilyParam, string filePath)
{
var doc = uidoc.Document;
var app = doc.Application;
var instancesSelected = uidoc.Selection
.PickElementsByRectangle(new FuncFilter(e => e is FamilyInstance instance && instance.Symbol.Family.IsEditable), "请框选需要添加参数的族实例")
.Cast<FamilyInstance>()
.ToList();
//var instancesSelected = from reference in references
// select doc.GetElement(reference) as FamilyInstance;
if (!instancesSelected.Any())
{
return;
}
StringBuilder sb = new();
//得到族的唯一族实例
var families = instancesSelected
.GroupBy(ins => ins.Symbol.Family.Id.IntegerValue)
.Select(g => g.FirstOrDefault()?.Symbol.Family)
.ToList();
using (TransactionGroup group = new(doc, "添加族参数"))
{
group.Start();
var originSharedParametersFile = app.SharedParametersFilename.Clone().ToString();
DefinitionFile tempFile = SharedParameterAssists.CreateSharedParameterFile(app, filePath);
var g = tempFile.Groups.Create("TempGroup");
foreach (var family in families)
{
if (!family.IsEditable && !family.IsInPlace)
{
sb.AppendLine($"族:{family.Name},不可编辑,需采用其他方式添加参数。");
continue;
}
var famdoc = doc.EditFamily(family);
using (Transaction ts = new(famdoc, "添加族参数"))
{
ts.Start();
//常规族参数
if (isFamilyParam)
{
try
{
famdoc.FamilyManager.AddParameter(
custom.FullProperty,
BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES,
custom.Unit == "/" ? ParameterType.Text : ParameterType.Number,
true
);
}
catch (Exception e)
{
LogAssists.WriteLog(e.Message);
}
}
else
{
try
{
ExternalDefinitionCreationOptions options =
new(custom.FullProperty, ParameterType.Text)
{
GUID = new Guid(custom.Guid)
};
var definition =
g.Definitions.get_Item(custom.FullProperty) ?? g.Definitions.Create(options);
famdoc.FamilyManager.AddParameter(
(ExternalDefinition)definition,
BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES,
true
);
}
catch (Exception e)
{
LogAssists.WriteLog(e.Message);
}
}
ts.Commit();
}
famdoc.LoadFamily(doc, new FamilyLoadOption());
famdoc.Close(false);
}
File.Delete(tempFile.Filename);
app.SharedParametersFilename = originSharedParametersFile;
group.Assimilate();
}
}
/// <summary>
/// 参数绑定
/// </summary>
/// <param name="uidoc"></param>
/// <param name="custom"></param>
/// <param name="filePath"></param>
public static void AddParamBinding(UIDocument uidoc, CustomParamData custom, string filePath)
{
var doc = uidoc.Document;
var app = doc.Application;
var references = uidoc.Selection
.PickObjects(
ObjectType.Element,
new FuncFilter(
e => e is HostObject or Railing or Stairs ||
e.Category.Id.IntegerValue == -2000180 ||
(e is FamilyInstance instance && instance.Symbol.Family.IsEditable),//坡道
(_, _) => true),
"请选择需要添加参数的元素,并完成选择")
.ToList();
var familyInstancesSelected = references.Select(doc.GetElement);
var categoryList = familyInstancesSelected.GroupBy(ins => ins.Category.Id.IntegerValue)
.Select(g => g.FirstOrDefault()?.Category)
.ToList();
doc.Invoke(
ts =>
{
var originSharedParametersFile = app.SharedParametersFilename.Clone().ToString();
DefinitionFile tempFile = SharedParameterAssists.CreateSharedParameterFile(app, filePath);
var g = tempFile.Groups.Create("TempGroup");
var categories = app.Create.NewCategorySet();
foreach (var category in categoryList)
{
categories.Insert(category);
}
var newInstanceBinding = app.Create.NewInstanceBinding(categories);
ExternalDefinitionCreationOptions options =
new(custom.FullProperty, ParameterType.Text) { GUID = new Guid(custom.Guid) };
try
{
var definition = g.Definitions.Create(options);
doc.ParameterBindings
.Insert(definition, newInstanceBinding, BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES);
}
finally
{
app.SharedParametersFilename = originSharedParametersFile.ToString();
File.Delete(tempFile.Filename);
}
}, "添加共享参数");
}
/// <summary>
/// 添加自定义共享参数
/// </summary>
/// <param name="doc"></param>
/// <param name="paramName"></param>
/// <param name="categorySet"></param>
public static void AddSharedParam(Document doc, string paramName, CategorySet categorySet, BuiltInParameterGroup group)
{
doc.Invoke(
ts =>
{
var filePath = Path.Combine(GlobalVariables.DirAssembly, $"TempSharedParameters.txt");
var app = doc.Application;
var originSharedParametersFile = app.SharedParametersFilename.Clone().ToString();
DefinitionFile tempFile = SharedParameterAssists.CreateSharedParameterFile(app, filePath);
var g = tempFile.Groups.Create("TempGroup");
var newInstanceBinding = app.Create.NewInstanceBinding(categorySet);
ExternalDefinitionCreationOptions options =
new(paramName, ParameterType.Text);
try
{
var definition = g.Definitions.Create(options);
doc.ParameterBindings.Insert(definition, newInstanceBinding, group);
}
finally
{
app.SharedParametersFilename = originSharedParametersFile.ToString();
File.Delete(tempFile.Filename);
}
}, $"<{paramName}>共享参数");
}
/// <summary>
/// 构件参数共享参数的绑定(一般用于系统构件)
/// </summary>
/// <param name="uidoc"></param>
/// <param name="parametersToAdded">数据库中分类的参数</param>
/// <param name="sharedParameters">数据库中唯一的共享参数</param>
/// <param name="filePath">共享参数路径</param>
/// <param name="sb">错误信息</param>
public static void AddParameterElementsBinding(UIDocument uidoc, List<ParamData> parametersToAdded, List<SharedParameterData> sharedParameters, string filePath)
{
StringBuilder sb = new StringBuilder();
Document doc = uidoc.Document;
var app = doc.Application;
var references = uidoc.Selection
.PickObjects(
ObjectType.Element,
new FuncFilter(
e => e is HostObject or Railing or Stairs || e.Category.Id.IntegerValue == -2000180 || (e is FamilyInstance instance && instance.Symbol.Family.IsEditable),//坡道
(_, _) => true
),
"请选择需要添加参数的元素,并完成选择"
)
.ToList();
var familyInstancesSelected = references.Select(doc.GetElement);
var categoryList = familyInstancesSelected
.GroupBy(ins => ins.Category.Id.IntegerValue)
.Select(g => g.FirstOrDefault()?.Category)
.ToList();
if (!familyInstancesSelected.Any())
{
return;
}
using (Transaction trans = new(doc, "添加项目参数(共享参数)"))
{
trans.Start();
var originSharedParametersFile = app.SharedParametersFilename.Clone().ToString();
DefinitionFile tempFile = SharedParameterAssists.CreateSharedParameterFile(app, filePath);
var g = tempFile.Groups.Create("TempGroup");
foreach (var paramData in parametersToAdded)
{
var isExist = SharedParameterAssists.IsExistProjectParam(doc, paramData.FullProperty, out var def, out var binding);
//存在则直接绑定到类别
if (isExist)
{
foreach (var category in categoryList)
{
if (!binding.Categories.Contains(category))
{
binding.Categories.Insert(category);
doc.ParameterBindings.ReInsert(def, binding, BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES);
}
}
}
else
{
foreach (var sharedParameter in sharedParameters)
{
try
{
if (sharedParameter.FullParamName != paramData.FullProperty)
{
continue;
}
var categories = app.Create.NewCategorySet();
foreach (var category in categoryList)
{
categories.Insert(category);
}
var newInstanceBinding = app.Create.NewInstanceBinding(categories);
var definition = g.Definitions.get_Item(sharedParameter.FullParamName);
if (definition == null)
{
ExternalDefinitionCreationOptions options =
new(
sharedParameter.FullParamName,
paramData.Unit == "/" ? ParameterType.Text : ParameterType.Number
)
{
GUID = new Guid(sharedParameter.GUID)
};
definition = g.Definitions.Create(options);
}
doc.ParameterBindings.Insert(
definition,
newInstanceBinding,
BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES
);
break;
}
catch (Exception ex)
{
sb.AppendLine(ex.Message);
LogAssists.WriteLog(ex.Message);
}
}
}
}
app.SharedParametersFilename = originSharedParametersFile.ToString();
trans.Commit();
File.Delete(tempFile.Filename);
}
}
/// <summary>
/// 移除轨道交通的所有参数
/// </summary>
/// <param name="doc"></param>
public static void RemoveMetroParameters(Document doc)
{
var elements = doc.OfAllModelCollector()?.GroupBy(e => e.GetTypeId()).Select(e => e.FirstOrDefault());
if (elements == null)
{
MessageBox.Show("没有找到模型元素", "错误");
return;
}
var parameterElements = doc.OfClass<ParameterElement>().Cast<ParameterElement>();
StringBuilder sb = new();
var dict = SharedParameterAssists.GetParameterElementBindings(doc);
var bindings = doc.ParameterBindings;
doc.InvokeGroup(
tg =>
{
var map = doc.ParameterBindings;
foreach (var element in elements)
{
Element type = null;
var hasTypeId = element.GetTypeId() != ElementId.InvalidElementId;
if (hasTypeId)
{
type = doc.GetElement(element.GetTypeId());
}
List<Parameter> parameters = new();
var paramMap = element.ParametersMap;
using (Transaction trans = new(doc, "清理项目或共享参数"))
{
trans.Start();
foreach (Parameter param in paramMap)
{
if (Regex.IsMatch(param.Definition.Name, @"^[A-Z][A-Z](-)\d(00-)"))
{
var ds = dict.Where(
e => e.Key.GetDefinition().Id == (param.Definition as InternalDefinition)?.Id);
try
{
if (ds.Any())//说明是项目参数
{
var d = ds.FirstOrDefault();
var parameter = d.Key;
var binding = d.Value;
if (parameter is SharedParameterElement)//共享参数
{
bindings.Remove(param.Definition);
}
else//项目参数
{
dict.Remove(parameter);
doc.Delete(parameter.Id);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
LogAssists.WriteLog($"{param.Definition.Name}:" + ex.Message);
}
#region
//if (param.IsShared)
//{
// //删除定义
// uidoc.Document.ParameterBindings.Remove(param.Definition);
//}
////删除项目参数创建的项目参数
//else if (map.Contains(param.Definition))
//{
// var paramElement = parameterElements.Where(p => p.Name == param.Definition.Name).FirstOrDefault();
// uidoc.Document.Delete(paramElement.Id);
//}
//if (param.IsShared)
//{
// var binding = doc.ParameterBindings.get_Item(param.Definition);
// if (binding is TypeBinding)
// {
// var typeBinding = (TypeBinding)binding;
// try
// {
// if (typeBinding.Categories.Size == 1)
// {
// uidoc.doc.ParameterBindings.Remove(param.Definition);
// }
// typeBinding.Categories.Erase(element.Category);
// }
// catch (Exception e)
// {
// sb.AppendLine(e.Message);
// }
// }
// if (binding is InstanceBinding)
// {
// var instanceBinding = (InstanceBinding)binding;
// try
// {
// if (instanceBinding.Categories.Size == 1)
// {
// uidoc.doc.ParameterBindings.Remove(param.Definition);
// }
// instanceBinding.Categories.Erase(element.Category);
// }
// catch (Exception e)
// {
// sb.AppendLine(e.Message);
// }
// }
//}
#endregion
}
}
doc.Regenerate();
//类型参数
if (hasTypeId)
{
foreach (Parameter param in type.ParametersMap)
{
if (Regex.IsMatch(param.Definition.Name, @"^[A-Z][A-Z](-)\d(00-)"))
{
//var name = param.Definition.Name;
//var defs = dict.Keys.Select(e => e.GetDefinition());
var ds = dict.Where(
e => e.Key.GetDefinition().Id ==
(param.Definition as InternalDefinition)?.Id);
try
{
if (ds.Any())//说明是项目参数
{
var d = ds.FirstOrDefault();
var parameter = d.Key;
var binding = d.Value;
if (parameter is SharedParameterElement)//共享参数
{
bindings.Remove(param.Definition);
}
else//项目参数
{
dict.Remove(parameter);
doc.Delete(parameter.Id);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
LogAssists.WriteLog($"{param.Definition.Name}:" + ex.Message);
}
}
}
}
trans.Commit();
}
var instaneFlag = element.ParametersMap
.OfType<Parameter>()
.Any(param => Regex.IsMatch(param.Definition.Name, @"^[A-Z][A-Z](-)\d(00-)"));
var typeFlag = false;
if (hasTypeId)
{
typeFlag = type.ParametersMap
.OfType<Parameter>()
.Any(param => Regex.IsMatch(param.Definition.Name, @"^[A-Z][A-Z](-)\d(00-)"));
}
var NeedToEditFamily = instaneFlag || typeFlag;
//bool IsNeedEditFamily = false;
//foreach (Parameter param in paramMap)
//{
// if (Regex.IsMatch(param.Definition.Name, @"^[A-Z][A-Z](-)\d(00-)"))
// {
// IsNeedEditFamily = true;
// break;
// }
//}
if (NeedToEditFamily && element is FamilyInstance instance)
{
Document famdoc = null;
try
{
var family = instance.Symbol.Family;
if (family.IsEditable)
{
famdoc = doc.EditFamily(family);
}
Debug.WriteLineIf(famdoc == null, $"{family.Name} 不可编辑。");
if (famdoc != null)
{
using (Transaction ts = new(famdoc, "删除参数"))
{
ts.Start();
var familyParameters = famdoc.FamilyManager
.GetParameters()
.Where(fp => Regex.IsMatch(fp.Definition.Name, @"^[A-Z][A-Z](-)\d(00-)"));
foreach (var fp in familyParameters)
{
famdoc.FamilyManager.RemoveParameter(fp);
}
ts.Commit();
}
famdoc.LoadFamily(doc, new FamilyLoadOption());
famdoc.Close(false);
}
}
catch (Exception)
{
sb.AppendLine($"{famdoc.Title} 发生错误!");
}
}
}
}, "清理轨交标准参数");
if (sb.Length > 0)
{
MessageBox.Show(sb.ToString(), "错误", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
}
}