一、前言
我们在前面或多或少提到也用到参数了,这篇便细讲一下。
首先,我们知道好多信息都藏在参数里,或者说可以从参数中获取。我们还能够通过调整参数的值,改变模型的形态,即族的参变。
其次,有时族上没有我们想要的信息,但又需要在族上存与展示,这时我们可以为元素批量加上参数,对应着Revit管理面板上的记载“参数”功能。
这几个的功能是什么怎么用就不讲了,去看帮助文档噢。
所以,这篇就讲这些内容:
- 参数&内置参数
- 族参数
- 共享参数
- 项目参数
二、Parameter
Parameter
就是用来表示和操控元素信息的一类东西,所有的Element
都有参数,可以使用通用的方法获取。
// Element Class
public ParameterSet Parameters { get; }
public IList<Parameter> GetParameters(...);
Parameter可以表示的元素字段类型有:Double
、Integer
、String
、ElementId
四种。
2.1. 方法
Methods | Description |
---|---|
AsDouble AsInteger AsString AsElementId AsStringValue | 获取double类型值,默认0 获取Intl类型值,默认0,常用作bool 获取string类型值,默认empty,用于文本描述 获取Id类型值,默认null,一般是关联作用 将值按照【显示格式】输出 |
Set(…) x4 SetValueString | 设置参数值 |
CanBeAssociatedWithGlobalParameter(s) DissociateFromGlobalParameter GetAssociatedGlobalParameter | 参数与全局参数的关联 |
很简单吧,主要就是获取与设置方法。
需要注意的是,一个参数只有
1
个值,我们需要使用对应的As方法获取。
所以这要求我们事先知道一个参数表示的是什么,以及用什么值类型表示的。
比如下面的面积,就需要使用AsDouble方法获取。
为什么是283.95呢?因为Revit计算,采用的是英尺
作为单位。283.95平方英尺约等于26.38平方米。
2.2. 属性
再来看看属性,都是非常有用的。
Properties | Description |
---|---|
Definition | 参数的定义,包括参数名称、参数组、参数类型、单位类型 |
DisplayUnitType HasValue | 值显示的单位 是否有值 |
StorageType | 值的类型 |
UserModifiable | 值是否可以更改 |
IsShared | 是否为共享参数 |
- 值的类型可以让我们确定采用什么方法去获取值。
- 值的显示单位和参数定义上的单位类型,可以让我们计算出想要的值。
2.3. 参数名称 & 内置参数
我们知道Revit种有很多的参数,我们当然可以使用中文名称去获取,如上面的“面积”,但这样不好,Revit切换个语言代码就要炸了。
所以,对于Revit内置的参数,我们需要使用特定的代号去获取,它们都在BuiltInParameter
(内置参数)枚举中。
可以通过RevitLookUp插件来获取,或者在文档中检索。
三、族参数
有时,一些族上没有我们需要的参数,但又需要用到,怎么办呢,那就加上呗。
- 编辑族,给这个族加个参数。
- 设置项目参数,让一批族都有这个参数。
这里,我们先讲第一种方式,第二种在后面项目参数那里讲。
3.1. 为族添加参数
来看流程:
- 获取族、进入族编辑态
- 获取族管理器
- 开启事务,为族添加参数,提交事务
- 将族载入到项目中
- 关闭族文档
/// <summary>
/// 通过族实例为族添加参数
/// </summary>
/// <param name="familyInstance">族实例</param>
/// <param name="parameterName">参数名称</param>
/// <param name="builtInParameterGroup">参数组</param>
/// <param name="parameterType">参数类型</param>
/// <param name="isInstance">是否为族参数</param>
public static void CreateFamilyParameter(FamilyInstance familyInstance, string parameterName,BuiltInParameterGroup builtInParameterGroup,ParameterType parameterType,bool isInstance = true)
{Document Document = familyInstance.Document;Document familyDocument = Document.EditFamily(familyInstance.Symbol.Family);FamilyManager familyManager = familyDocument.FamilyManager;using (Transaction ts = new Transaction(familyDocument, "创建参数")){ts.Start();familyManager.AddParameter(parameterName, builtInParameterGroup, parameterType, isInstance);ts.Commit();}familyDocument.LoadFamily(Document, new ProjectFamLoadOption());familyDocument.Close(false);
}
3.2. FamilyManager(族管理器)
好吧,这个破玩意儿,当初可是找了好些时间,才知道有这么个类,及其离谱,非常不爽,鬼知道我都看了些什么。
简单瞅瞅吧,重要的加粗了。
Mehtods | Description |
---|---|
AddParameter(…) x3 RemoveParameter RenameParameter | 添加参数,3个重载,有一个可以添加共享参数 移除参数 修改参数名称 |
GetParameters GetAssociatedFamilyParameter | 获取参数 |
Set(…) x4 SetValueString SetFormula SetDescription | 设置参数值 设置参数公式 设置参数描述 |
ReplaceParameter x2 | 族参数和共享参数间的替换 |
MakeInstance MakeType MakeNonReporting MakeReporting | 设置参数为实例参数(各族实例可为不同值) 设置参数为类型参数(各族实例为相同值) ?? ?? |
IsParameterLockable IsParameterLocked SetParameterLocked | 参数锁定 |
DeleteCurrentType RenameCurrentType 属性:Types 属性:CurrentType{ get; } | 族类型,就下面这个。【Types需要注意*】。 |
属性Types注意:
族类型可以在族编辑文档中添加,也可在项目文档中,通过“编辑类型”添加。
- 族文档中添加:Types能获取到
- 项目文档编辑类型添加:Types不能获取到
3.3. FamilyParameter(族参数)
FamilyParameter
,就上面的GetParameters()
方法获取。不同于Parameter
,虽然部分属性相同,但两者间并不存在继承/派生关系。
- Parameter:倾向于值的读写
- FamilyParameter:倾向于参数的定义
方法嘛,没有。就是一些属性,用来定义参数。
Properties | Description |
---|---|
Definition DisplayUnitType StorageType | 定义 显示单位 存储类型(double、int …) |
IsInstance IsShared IsReporting | 是否为实例参数 是否为共享参数 ? |
IsReadOnly | 是否只读 |
UserModifiable | 是否通过交互修改 |
Formula CanAssignFormula IsDeterminedByFormula | 公式 |
AssociatedParameters | 关联 |
3.4. 参数与族参数获取比较
这个还是有必要提一下的。
- 参数获取,自基类
Element
的GetParameters方法获取。 - 族参数获取,自族管理类
FamilyManager
的GetParameters方法获取。
前者,获取到“实例”元素上所有参数。
后者,获取到“抽象”元素(族)上所有参数。
那么可以理解前者比后者多一些吧,毕竟Revit在生成模型时还是会偷偷做一些操作的。
问题呢,在于族参数获取上。
我们在自定义族时,可以塞很多参数,能获取到。
如何只获取用户添加的参数呢?即过滤掉Revit给加上的参数。
目前我还没有去做,但一个可能的操作是:遍历排除所有BuiltInParameter
中的参数。
当然我没有去尝试,有兴趣的小伙伴可以试试。有更好的方法也欢迎留言。
四、项目参数 & 共享参数
项目参数的创建过程中,用到了一个叫“共享参数文件”的东西。
从Revit项目参数的交互创建方式上,可以看到既可以由“项目参数”定义,也可以从“共享参数”创建。
但从API上看,我们只能采用“共享参数”的方式,并没有Definition
直接运用的方法。
所以,共享参数和项目参数的创建,代码上是同步的,就多一步少一步而已。
前面提示:共享参数仅是提供了参数定义,与其它元素并无关联关系。
4.1. 项目参数的创建
先来看看创建项目参数的创建流程:
- 文件,创建一个txt文件,获取其路径filePath(已有则不创建)
- 引用,app.SharedParametersFilename = filePath
- 打开,app.OpenSharedParameterFile()
- 定义,此时创建共享参数:DefinitionFile -> DefinitionGroup -> Definition -> ExternalDefinitionCreationOptions
- 类型,CategorySet -> Category
- 绑定,Binding -> InstanceBinding / TypeBinding
- 应用,此时绑定项目参数。BindingMap:doc.ParameterBindings.Insert(…)
流程有了,那就来看看代码示例吧。名称,
/// <summary>
/// 为指定类型的元素创建项目参数
/// </summary>
/// <param name="uidoc">文档</param>
/// <param name="parameterName">参数名称</param>
/// <param name="builtInCategory">指定元素的类别</param>
/// <param name="parameterType">参数类型</param>
public void CreateProjectParameter(UIDocument uidoc,string parameterName,BuiltInCategory builtInCategory,ParameterType parameterType)
{Document doc = uidoc.Document;Autodesk.Revit.ApplicationServices.Application app = uidoc.Application.Application;// 1.string filePath = Path.Combine(Config.SharedFilePath, "MySharedParameterFile.txt"); // Config.SharedFilePathFileStream fs = File.Create(filePath);fs.Close();// 2.app.SharedParametersFilename = filePath;// 3.DefinitionFile definitionFile = app.OpenSharedParameterFile();// 4. 共享参数创建DefinitionGroup group = definitionFile.Groups.get_Item("Group");group ??= definitionFile.Groups.Create("Group");Definition definition = group.Definitions.get_Item(parameterName);if (definition == null){ExternalDefinitionCreationOptions edco = new ExternalDefinitionCreationOptions(parameterName, parameterType);definition = group.Definitions.Create(edco);}// 5.CategorySet categories = app.Create.NewCategorySet();Category category = doc.Settings.Categories.get_Item(builtInCategory);categories.Insert(category);// 6. ElementBinding binding = app.Create.NewInstanceBinding(categories); // new InstanceBinding(categories);//ElementBinding binding = app.Create.NewTypeBinding(categories);// 7. 项目参数绑定BindingMap bingingMap = doc.ParameterBindings;bingingMap.Insert(definition, binding);doc.Regenerate();//definitionFile.Dispose();//File.Delete(filePath);
}// 使用
this.CreateProjectParameter( uiDoc, "MySharedParameter", BuiltInCategory.OST_Walls,ParameterType.Text);
使用效果如下:
4.2. 项目参数的删除
项目参数删除,需要从BindingMap
中找到要删除的参数Definition
。
// 删除项目参数
public void DeleteProjectParameter(UIDocument uiDoc, string parameterName, BuiltInCategory builtInCategory = BuiltInCategory.INVALID)
{Document doc = uiDoc.Document;BindingMap bindingMap = doc.ParameterBindings;DefinitionBindingMapIterator iterator = bindingMap.ForwardIterator();List<Definition> removeds = new List<Definition>();while (iterator.MoveNext()){Definition definition = iterator.Key;if (definition.Name == parameterName){if (builtInCategory != BuiltInCategory.INVALID){ElementBinding binding = iterator.Current as ElementBinding;CategorySet categories = binding.Categories;Category category = doc.Settings.Categories.get_Item(builtInCategory); // Category.GetCategory(doc, builtInCategory);if (categories.Contains(category))removeds.Add(definition);}else{removeds.Add(definition);}}}foreach (Definition definition in removeds){bindingMap.Remove(definition);}doc.Regenerate();
}
4.3. 共享参数的删除
哎~项目参数是删除了,共享参数可咋办嘞。
咋办,凉拌。: |
不知道通过代码删,没见提供删除方法哇。
4.4. 族共享参数
是“族共享参数”,不是“共享参数”嗷。
共享参数是可以塞给族的,这样就能够单个族拥有该参数了,而不会像项目参数那样,给整个类型的族。
怎么做到的呢?
结合上面的“族管理器”和“项目参数创建”连部分内容。
// FamilyManager 添加共享参数
public FamilyParameter AddParameter(ExternalDefinition familyDefinition,BuiltInParameterGroup parameterGroup,bool isInstance
)
- 走创建共享参数那套流程,整个
ExternalDefinition
出来。 - 走族管理器那套流程,把这个外部参数定义给塞进去
删除嘛,通过族管理器删除咯。
emm…我直接把共享参数删掉(交互),通过共享参数添加的族参数还在,也就是说,这两着并无关联,创建仅仅是采用了共享参数中的参数定义 ㄟ( ▔, ▔ )ㄏ。上面补充提示了嗷。
吐槽:花里胡哨的,有个锤子用
五、总结
写完参数相关的内容了,
鼓掌👏👏👏
结束