using System.Reflection; using System.Text; using System.Windows; using Autodesk.Revit.DB; using Szmedi.RevitToolkit.Approval.Models; using Szmedi.Toolkit.Revit.Approval; namespace Szmedi.RevitToolkit.Approval.Assists { public class SharedParameterAssists { /// /// 添加自定义共享参数 /// /// /// /// public static void AddSharedParameter(Document doc, string paramName, CategorySet categorySet, BuiltInParameterGroup group = BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES, ParameterType parameterType = ParameterType.Text) { string addInPath = Assembly.GetExecutingAssembly().Location; string dirAssembly = Path.GetDirectoryName(addInPath); var filePath = Path.Combine(Path.GetTempPath(), $"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); try { var definition = g.Definitions.Create(options); doc.ParameterBindings.Insert(definition, newInstanceBinding, group); } finally { app.SharedParametersFilename = originSharedParametersFile.ToString(); //File.Delete(tempFile.Filename); } } /// /// 获取项目参数的参数实体和元素绑定 /// /// /// public static Dictionary GetParameterElementBindings(Document doc) { var parameterElements = new FilteredElementCollector(doc).OfClass(typeof(ParameterElement)).Cast().ToList(); Dictionary dict = []; var dep = doc.ParameterBindings.ForwardIterator(); while (dep.MoveNext()) { if (dep.Key is InternalDefinition definition) { var binding = dep.Current as ElementBinding; foreach (var param in parameterElements) { var def = param.GetDefinition(); if (def.Id == definition.Id) { dict.Add(param, binding); } } } } return dict; } //private string tempFolder = Path.GetTempPath(); /// /// 是否存在该项目参数 /// /// /// /// /// /// public static bool IsExistProjectParam(Document doc, string paramName, out Definition definition, out ElementBinding binding) { DefinitionBindingMap map = doc.ParameterBindings; var dep = map.ForwardIterator(); var isExist = false; binding = null; definition = null; while (dep.MoveNext()) { definition = dep.Key; var definitionName = definition.Name; binding = dep.Current as ElementBinding; if (definitionName == paramName) { isExist = true; break; } } return isExist; } /// /// 建筑构件参数共享参数的绑定 /// /// 最好使用类型,可以减少遍历次数,提升整个模型添加参数的效率 /// 数据库中分类的参数 /// 数据库中唯一的共享参数 public static void AddArchiParameters(Element element, List parametersToAdded, List sharedParameters) { string filePath = Path.Combine(Path.GetTempPath(), "tempSharedParams.txt"); var doc = element.Document; var app = doc.Application; StringBuilder sb = new StringBuilder(); List needToAdd = []; foreach (var item in parametersToAdded) { if (element.GetParameters(item.PropName).Count == 0) { needToAdd.Add(item); } } if (needToAdd.Count == 0) { return; } var originSharedParametersFile = app.SharedParametersFilename.Clone().ToString(); DefinitionFile tempFile = SharedParameterAssists.CreateSharedParameterFile(app, filePath); var g = tempFile.Groups.Create("TempGroup"); var category = element.Category; var b = GetParameterElementBindings(doc); foreach (var paramData in parametersToAdded) { var isExist = IsExistProjectParam(doc, paramData.PropName, out var def, out var binding); if (isExist && binding is TypeBinding) { var ids = b.Where(d => d.Key.IsValidObject && d.Key.Name == def.Name).Select(e => e.Key.Id); doc.Delete([.. ids]); isExist = false; } //存在则直接绑定到类别 if (isExist) { if (!binding.Categories.Contains(category)) { binding.Categories.Insert(category); } doc.ParameterBindings.ReInsert(def, binding, BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES); } else { try { var sharedParameter = sharedParameters.FirstOrDefault( p => p.ParamName == paramData.PropName); if (sharedParameter == null) { sb.AppendLine($"找不到与'{paramData.PropName}'同名的共享参数"); continue; } var categories = app.Create.NewCategorySet(); categories.Insert(category); var newInstanceBinding = app.Create.NewInstanceBinding(categories); var definition = g.Definitions.get_Item(sharedParameter.ParamName); if (definition == null) { ExternalDefinitionCreationOptions options = new( sharedParameter.ParamName, paramData.ParameterType == "Number" ? ParameterType.Number : ParameterType.Text ) { GUID = new Guid(sharedParameter.GUID) }; definition = g.Definitions.Create(options); } doc.ParameterBindings.Insert( definition, newInstanceBinding, BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES ); //foreach (var sharedParameter in sharedParameters) //{ // if (sharedParameter.ParamName != paramData.ParamName) // { // continue; // } // break; //} } catch (Exception ex) { MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } } app.SharedParametersFilename = originSharedParametersFile.ToString(); File.Delete(tempFile.Filename); //if (sb.Length > 0) //{ // MessageBox.Show(sb.ToString()); //} //else //{ // MessageBox.Show("完成添加"); //} } /// /// 轨道交通参数共享参数的绑定 /// /// 最好使用类型,可以减少遍历次数,提升整个模型添加参数的效率 /// 数据库中分类的参数 /// 数据库中唯一的共享参数 /// 共享参数路径 public static void AddMetroParameters(Element element, List parametersToAdded, List sharedParameters) { string filePath = Path.Combine(Path.GetTempPath(), "tempSharedParams.txt"); Document doc = element.Document; var app = doc.Application; List needToAdd = []; foreach (var item in parametersToAdded) { if (element.GetParameters(item.ParamFullName).Count == 0) { needToAdd.Add(item); } } if (needToAdd.Count == 0) { return; } var originSharedParametersFile = app.SharedParametersFilename.Clone().ToString(); DefinitionFile tempFile = SharedParameterAssists.CreateSharedParameterFile(app, filePath); var g = tempFile.Groups.Create("TempGroup"); var category = element.Category; var b = GetParameterElementBindings(doc); StringBuilder sb = new StringBuilder(); foreach (var paramData in needToAdd) { //如果存在 var isExist = IsExistProjectParam(doc, paramData.ParamFullName, out var def, out var binding); if (isExist && binding is TypeBinding) { var ids = b.Where(d => d.Key.IsValidObject && d.Key.Name == def.Name).Select(e => e.Key.Id); doc.Delete([.. ids]); isExist = false; } //存在则直接绑定到类别 if (isExist) { if (!binding.Categories.Contains(category)) { binding.Categories.Insert(category); } doc.ParameterBindings.ReInsert(def, binding, BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES); } else { try { var sharedParameter = sharedParameters.FirstOrDefault( p => p.ParamFullName == paramData.ParamFullName); if (sharedParameter == null) { sb.AppendLine($"找不到与'{paramData.ParamFullName}'同名的共享参数"); continue; } var categories = app.Create.NewCategorySet(); categories.Insert(category); var newInstanceBinding = app.Create.NewInstanceBinding(categories); var definition = g.Definitions.get_Item(sharedParameter.ParamName); if (definition == null) { ExternalDefinitionCreationOptions options = new( sharedParameter.ParamFullName, 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 ); //foreach (var sharedParameter in sharedParameters) //{ // if (sharedParameter.ParamFullName != paramData.ParamFullName) // { // continue; // } // break; //} } catch (Exception ex) { MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } } app.SharedParametersFilename = originSharedParametersFile.ToString(); File.Delete(tempFile.Filename); if (sb.Length > 0) { MessageBox.Show(sb.ToString()); } //else //{ // MessageBox.Show("完成添加"); //} } /// /// 创建共享参数文件 /// /// /// 共享文件路径 /// public static DefinitionFile CreateSharedParameterFile(Autodesk.Revit.ApplicationServices.Application revitApp, string shareFile) { System.Text.StringBuilder contents = new(); contents.AppendLine("# This is a Revit shared parameter file."); contents.AppendLine("# Do not edit manually."); contents.AppendLine("*META VERSION MINVERSION"); contents.AppendLine("META 2 1"); contents.AppendLine("*GROUP ID NAME"); contents.AppendLine("*PARAM GUID NAME DATATYPE DATACATEGORY GROUP VISIBLE"); File.WriteAllText(shareFile, contents.ToString()); revitApp.SharedParametersFilename = shareFile; return revitApp.OpenSharedParameterFile(); } public static DefinitionGroup GetGroup(DefinitionFile myDefinitionFile, string groupName, string log) { var groups = myDefinitionFile.Groups; DefinitionGroup definitionGroup; foreach (var definitionGroup2 in groups) { if (definitionGroup2.Name == groupName) { using (StreamWriter streamWriter = new(log, true)) { streamWriter.WriteLine($"参数组 {groupName} 已存在"); } definitionGroup = definitionGroup2; return definitionGroup; } } using (StreamWriter streamWriter2 = new(log, true)) { streamWriter2.WriteLine($"参数组 {groupName} 未发现"); } definitionGroup = groups.Create(groupName); using (StreamWriter streamWriter3 = new(log, true)) { streamWriter3.WriteLine($"参数组 {definitionGroup.Name} 已创建"); } return definitionGroup; } public static ExternalDefinition GetDefinition( DefinitionFile sharedParamFile, string definitionName, ParameterType paramType, DefinitionGroup group ) { foreach (var definitionGroup in sharedParamFile.Groups) { foreach (var definition in definitionGroup.Definitions) { var externalDefinition = (ExternalDefinition)definition; if (externalDefinition.Name == definitionName) { return externalDefinition; } } } ExternalDefinitionCreationOptions externalDefinitionCreationOptions = new(definitionName, paramType); return group.Definitions.Create(externalDefinitionCreationOptions) as ExternalDefinition; } private void CreateSharedParam( Autodesk.Revit.ApplicationServices.Application app, Document doc, string sharedParametersFilePath, string groupName, string definitionName ) { var parameterType = ParameterType.Text; CategorySet categorySet = new(); var wallCategory = doc.Settings.Categories.get_Item(BuiltInCategory.OST_Walls); categorySet.Insert(wallCategory); var instanceParameter = true; var parameterGroup = BuiltInParameterGroup.PG_DATA; if (!File.Exists(sharedParametersFilePath)) { try { var sw = File.CreateText(sharedParametersFilePath); sw.Close(); } catch (Exception) { throw new Exception("无法创建共享参数文件: " + sharedParametersFilePath); } } // 设置共享参数文件 app.SharedParametersFilename = sharedParametersFilePath; // 打开共享参数文件 var definitionFile = app.OpenSharedParameterFile(); if (definitionFile == null) { throw new Exception("无法打开共享参数文件"); } // 获取参数组的集合 var groups = definitionFile.Groups; // 获取参数组 var group = groups.get_Item(groupName); if (null == group) { // 如果参数组不存在,则创建一个 group = groups.Create(groupName); } if (null == group) { throw new Exception("获取参数组失败: " + groupName); } // 获取参数定义 var definition = group.Definitions.get_Item(definitionName); // 如果参数定义不存在,则创建一个 definition ??= group.Definitions.Create(new ExternalDefinitionCreationOptions(definitionName, parameterType)); // 调用不同的函数创建类型参数或者实例参数 ElementBinding binding = instanceParameter ? app.Create.NewInstanceBinding(categorySet) : app.Create.NewTypeBinding(categorySet); // 把参数定义和类别绑定起来(下面的小节会提到“绑定”),元素的新的参数就创建成功了。 var insertSuccess = doc.ParameterBindings.Insert(definition, binding, parameterGroup); if (!insertSuccess) { throw new Exception("绑定类别失败"); } } private void CreateSharedParam(Autodesk.Revit.ApplicationServices.Application app, Document doc) { // 获取创建共享参数的txt路径 var txtFile = app.SharedParametersFilename; // 判断 路径是否有效,如果为空,读者可以创建一txt文件 //将路径赋值给app.SharedParametersFilename if (!string.IsNullOrEmpty(txtFile)) { // 判断 路径是否有效,如果为空,读者可以创建一txt文件 //将路径赋值给app.SharedParametersFilename if (File.Exists(txtFile)) { var dfile = app.OpenSharedParameterFile(); // 创建一个共享参数分组 var dg = dfile.Groups.Create("MyGroup"); // 参数创建的选项,包括参数名字,参数类型,用户是不是可以修改。。 ExternalDefinitionCreationOptions edco = new("特别注释", ParameterType.Text); // 创建参数 var df = dg.Definitions.Create(edco); // 上面就创建了 一个名为“MyGroup” 的分组,并在这个分组下创建了一个名为“特别注释”的参数 // 创建一个Category集合 var cateSet = app.Create.NewCategorySet(); // 获取墙的category var wallCate = Category.GetCategory(doc, BuiltInCategory.OST_Walls); // 在Category集合中加入 墙的category var flag = cateSet.Insert(wallCate); // 给 这个Category集合中的Category 创建一个实例绑定 var wallInsBd = app.Create.NewInstanceBinding(cateSet); // 获取当前Document的BindingMap var bmap = doc.ParameterBindings; //创建共享参数和Category之间的Binding bmap.Insert(df, wallInsBd); } } } public void GetSharedPara(Autodesk.Revit.ApplicationServices.Application RevitApp) { // 打开共享参数文件 var definitionFile = RevitApp.OpenSharedParameterFile(); // 获取参数组的集合 var groups = definitionFile.Groups; foreach (var group in groups) { // 获取参数组内的参数定义 foreach (var definition in group.Definitions) { var name = definition.Name; var type = definition.ParameterType; // 对参数定义的其他操作 } } } /// /// 获取类别和参数的绑定 /// /// 激活的文档 public void ShareParameterBinging(Document doc) { var map = doc.ParameterBindings; var dep = map.ForwardIterator(); while (dep.MoveNext()) { var definition = dep.Key; // 获取参数定义的基本信息 var definitionName = definition.Name; var parameterType = definition.ParameterType; // 几乎都可以转型为InstanceBinding,笔者没有碰到过其他情况,如有例外,请联系我们。 if (dep.Current is InstanceBinding instanceBinding) { // 获取绑定的类别列表 var categorySet = instanceBinding.Categories; } } } } }