using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
namespace Szmedi.Toolkit.RvAssists
{
public class SharedParameterAssists
{
///
/// 添加或附加绑定自定义共享参数
///
///
///
///
public static void AddOrAttachSharedParameter(Document doc, string paramName, BuiltInParameterGroup group = BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES, ParameterType parameterType = ParameterType.Text, params Category[] categories)
{
if (IsExistProjectParam(doc, paramName, out var def, out var binding))
{
foreach (var cate in categories)
{
binding.Categories.Insert(cate);
}
doc.ParameterBindings.ReInsert(def, binding, group);
}
else
{
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 categorySet = app.Create.NewCategorySet();
foreach (Category item in categorySet)
{
categorySet.Insert(item);
}
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 DefinitionFile CreateSharedParameterFile(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(
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(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(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;
}
}
}
}
}