574 lines
23 KiB
C#
574 lines
23 KiB
C#
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
|
||
{
|
||
/// <summary>
|
||
/// 添加自定义共享参数
|
||
/// </summary>
|
||
/// <param name="doc"></param>
|
||
/// <param name="paramName"></param>
|
||
/// <param name="categorySet"></param>
|
||
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);
|
||
}
|
||
}
|
||
/// <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="element">最好使用类型,可以减少遍历次数,提升整个模型添加参数的效率</param>
|
||
/// <param name="parametersToAdded">数据库中分类的参数</param>
|
||
/// <param name="sharedParameters">数据库中唯一的共享参数</param>
|
||
public static void AddArchiParameters(Element element, List<Constraint> parametersToAdded, List<ArchiSharedParameter> sharedParameters)
|
||
{
|
||
string filePath = Path.Combine(Path.GetTempPath(), "tempSharedParams.txt");
|
||
var doc = element.Document;
|
||
var app = doc.Application;
|
||
StringBuilder sb = new StringBuilder();
|
||
List<Constraint> 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("完成添加");
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 轨道交通参数共享参数的绑定
|
||
/// </summary>
|
||
/// <param name="element">最好使用类型,可以减少遍历次数,提升整个模型添加参数的效率</param>
|
||
/// <param name="parametersToAdded">数据库中分类的参数</param>
|
||
/// <param name="sharedParameters">数据库中唯一的共享参数</param>
|
||
/// <param name="filePath">共享参数路径</param>
|
||
public static void AddMetroParameters(Element element, List<AfcaMetroBaseParameter> parametersToAdded, List<MetroSharedParameter> sharedParameters)
|
||
{
|
||
string filePath = Path.Combine(Path.GetTempPath(), "tempSharedParams.txt");
|
||
Document doc = element.Document;
|
||
var app = doc.Application;
|
||
List<AfcaMetroBaseParameter> 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("完成添加");
|
||
//}
|
||
}
|
||
/// <summary>
|
||
/// 创建共享参数文件
|
||
/// </summary>
|
||
/// <param name="revitApp"></param>
|
||
/// <param name="shareFile">共享文件路径</param>
|
||
/// <returns></returns>
|
||
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;
|
||
// 对参数定义的其他操作
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|