364 lines
14 KiB
C#
364 lines
14 KiB
C#
|
||
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
|
||
{
|
||
/// <summary>
|
||
/// 添加或附加绑定自定义共享参数
|
||
/// </summary>
|
||
/// <param name="doc"></param>
|
||
/// <param name="paramName"></param>
|
||
/// <param name="categories"></param>
|
||
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);
|
||
}
|
||
}
|
||
|
||
}
|
||
/// <summary>
|
||
/// 获取项目参数的参数实体和元素绑定
|
||
/// </summary>
|
||
/// <param name="doc"></param>
|
||
/// <returns></returns>
|
||
public static Dictionary<ParameterElement, ElementBinding> GetParameterElementBindings(Document doc)
|
||
{
|
||
var parameterElements = new FilteredElementCollector(doc).OfClass(typeof(ParameterElement)).Cast<ParameterElement>().ToList();
|
||
|
||
Dictionary<ParameterElement, ElementBinding> 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();
|
||
/// <summary>
|
||
/// 是否存在该项目参数
|
||
/// </summary>
|
||
/// <param name="doc"></param>
|
||
/// <param name="paramName"></param>
|
||
/// <param name="definition"></param>
|
||
/// <param name="binding"></param>
|
||
/// <returns></returns>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建共享参数文件
|
||
/// </summary>
|
||
/// <param name="revitApp"></param>
|
||
/// <param name="shareFile">共享文件路径</param>
|
||
/// <returns></returns>
|
||
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;
|
||
// 对参数定义的其他操作
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取类别和参数的绑定
|
||
/// </summary>
|
||
/// <param name="doc">激活的文档</param>
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|