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;
}
}
}
}
}