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 { /// /// 添加族参数,需要编辑族 /// /// /// 数据库中分类的参数 /// 数据库中唯一的共享参数 /// true常规族参数或false共享参数族参数 /// 共享参数路径 public static void AddFamilyParameters( UIDocument uidoc, List parametersToAdded, List 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() .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(); } } /// /// 添加项目信息 /// /// /// 数据库中分类的参数 /// 数据库中唯一的共享参数 /// 共享参数路径 public static void AddProjectParameters(Document doc, List ParametersToAdded, List 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; } /// /// 添加自定义族参数 /// /// /// /// /// 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() .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(); } } /// /// 参数绑定 /// /// /// /// 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); } }, "添加共享参数"); } /// /// 添加自定义共享参数 /// /// /// /// 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}>共享参数"); } /// /// 构件参数共享参数的绑定(一般用于系统构件) /// /// /// 数据库中分类的参数 /// 数据库中唯一的共享参数 /// 共享参数路径 /// 错误信息 public static void AddParameterElementsBinding(UIDocument uidoc, List parametersToAdded, List 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); } } /// /// 移除轨道交通的所有参数 /// /// 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().Cast(); 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 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() .Any(param => Regex.IsMatch(param.Definition.Name, @"^[A-Z][A-Z](-)\d(00-)")); var typeFlag = false; if (hasTypeId) { typeFlag = type.ParametersMap .OfType() .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); } } } }