查看: 7295|回复: 12

[revit二次开发讲座]Revit的参数

    [复制链接]

发表于 2010-11-16 20:17:50 | 显示全部楼层 |阅读模式
本帖最后由 kratos 于 2010-11-16 20:17 编辑

大家好,男的们,女的们好。注册论坛很长时间了,作为版主我很愧疚(对不起你啊。。。站长大人),一直没有对这个插件板块作出自己应有的贡献。每次点开这个版面,都是共享Revit插件的,我强烈建议再开一个Revit AddIns Store板块,提供大家专门下载插件。
回到我没有贡献的话题,主要是忙。。。太忙了,不过忙是有代价的,领导没有拖欠工资(站长。。。你懂的)。

ok,废话不说了,回到revit二次开发的技术讲座,我是这样想的,先开两个:参数和族。为什么呢,因为Revit首先是一个参数化建模软件,然后是一个以构件为集合的建模软件,这里的构件在revit里的专业名称是族(e文是family,下文皆称family,因为作为二次开发,我们一般使用e文编程。。。)。当然,这是我个人的理解,有异议,请拍砖。

我们先看看Revit的参数吧,从界面上看revit有两种参数类型-project/family parameter和shared parameter。
parametertypes.png
进入点:Manage(Tab)->Project Parameters(button)->Project Parameters(Dailog)->Add(button)->Paramter Properties(dialog).
这两种参数的区别:
project parameter:其定义仅存在于项目文件中,但不能在tags里。
shared parameter:其定义存在于一个文本文件,可以在不同的项目和族文件间共享。这个共享的名字可不是白给的,在定制tag族时起到了关联tag中的label和project中模型的参数的作用。

我的观点是尽量使用shared parameter,因为它包含了project parameter所有的内容而且可以使用一个guid来唯一标识,这是project parameter所不及的。我们通常只能通过名字来获取一个element的parameter,如下面代码所示(一般的代码都用c#,除非特别声明),但是我们的目标是国际化的族库和国际化的插件,这就意味着参数名字可能不太稳定,被翻译成其他国家的语言,下面的代码仅能对英语国家起作用,于是我们的插件必须对每个国家做一套代码。
<code>
Parameter param = element.get_Parameter("projectParamName");
</code>
这个现实对插件的开发人员是痛苦的。。。所以我推荐使用shared parameter(相信我,没错的),你可以使用guid来得到parameter,快,很准。
<code>
GUID guid = new GUID("{E5E0AE36-D962-43F7-B1B6-2E590D58A1CF}");
Parameter param = element.get_Parameter(guid);
</code>
而且Revit API仅提供shared parameter的创建接口。

我们先来看看如何从Revit 模型中获得parameter信息,没有parameter的对象,一切都是浮云。。。

1. 查看当前项目文件的parameters。
界面的入口点:Revit->manage(tab)->Settings(Panel)->Project Parameters(button)
ProjectParameters.png
API的访问方法:Document.ParameterBindings 属性
通过这个属性,我们可以访问到如上图所示的3个参数。有人可能要问,我的模型里有那么多的参数,这里怎么只有3个。这个问题会引出另一种类型的参数-BuiltInParameter,我们后面再具体说明。这里列出的3个是用户自行添加的参数。
<code>
BindingMap bindingMap = _dbdocument.ParameterBindings;
// iterate the binding map via iterator.
DefinitionBindingMapIterator itor = bindingMap.ForwardIterator();
while (itor.MoveNext())
{
Definition definition = itor.Key;
Binding binding = bindingMap.get_Item(definition);
}
</code>
我们可以通过Definition的到Parameter的名字,类型(长度,坡度,。。。),参数组等信息,通过Binding可以知道这个parameter 和那些category绑定,即那些category的对象会包含这个参数。
备注:有童鞋可能喜欢通过foreach来访问容器对象,但是对于map来说,我们只能foreach它的内容,即Binding。这样我们就缺少了definition的信息。
<code>
// iterate the binding map via foreach.
foreach (Binding binding in bindingMap)
{
...
}
</code>

2. 从模型对象里获得parameters。
界面入口点:选择一个对象,Revit->Modify|...(Tab)->Properties(Panel)->Properties(button)。
DoorParameters.png
API的访问方法:Element.Parameters 属性
通过这个属性,我们可以获得模型对象的所有属性。
<code>
void GetElementParameterInformation(Document document, Element element)
{
// Format the prompt information string
String prompt = "Show parameters in selected Element:";
StringBuilder st = new StringBuilder();
// iterate element's parameters
foreach (Parameter para in element.Parameters)
{

...
}
// Give the user some information
TaskDialog.Show("Revit", prompt);
}
</code>
如果希望访问element的某个parameter,怎么办呢。
API提供了4个重载方法。
Element.get_Parameter(BuiltInParameter builtInparameter)
BuiltInParameter是一个枚举类型,列举了所有的内建参数,Revit并不是所有的族都是可加载的,有些族是内建的系统族,如墙,楼板等,Revit需要为他们定义一些内建的参数。当然对于可加载的族也会有一些内建参数,这个跟创建族的模板有关。遗憾的是我们并没有一个官方文档来描述,哪些element有哪些内建参数,对于这个只能凭经验,因为内建参数是不能被删除的,所以经验是可靠的。
Element.get_Parameter(Definition definition)
Definition可以通过前面介绍的BindingMap得到。说实话这个方法用起来比较麻烦,不如下面介绍的直接通过参数名字获得参数。
Element.get_Parameter(Guid guid)
这个方法很重要,但只对共享参数起作用。所以我常说自定义参数用共享参数。
Element.get_Parameter(String paramName)
不多说,通过参数名获得参数。

得到了Parameter,下面我们看一下如何对Parameter进行操作-读,写。这部分比较简单,直接查看帮助文档中Parameter类型的接口即可,这里只强调以下几点:
1. 通过Parameter.AsDouble得到的参数值的单位都是国际标准单位,除了长度单位,在Revit里长度单位是feet。
2. 通过Parameter.AsValueString可以得到带单位的字符串,例如长度为12米,的到的值是"12m",这个单位关联到模板的单位设置。
3. Parameter.IsShared可以判断一个parameter是共享参数还是其它类型的参数。Parameter.GUID可以的到其guid。
4. (Parameter.Definition as InternalDefintion).BuiltInParameter可以判断一个参数是内建参数还是其他参数。

终于到最后一部分了,如何创建parameter。这里只介绍共享参数的创建。
我们看看如何在界面上创建shared parameter,并介绍相应的API方法。
1. 设置/创建shared parameter文件。
创建shared parameter时,我们需要一个保存shared parameter定义(参数名称,guid等信息)的文本文件。
UI入口点:Revit->Manage(tab)->Settings(panel)->Shared Parameters(button)->Edit Shared Parameters(Dialog)。
editsharedparameters.png
如果本地硬盘已经有一个shared parameter的定义文件,可以直接指定。
<code>
Autodesk.Revit.ApplicationServices.Application applicaton = ...;  //获得application对象
application.SharedParametersFilename = ...;   //设置定义文件路径。
DefinitionFile sharedDefintionFile = application.OpenSharedParameterFile(); //打开文件,获得定义文件。
</code>
如果当查询的文件不存在时,希望新建一个shared parameter的定义文件,可以使用如下代码。
<code>
try{
definitionFile = application.OpenSharedParameterFile();
}catch(Exception)  //查询的文件不存在。
{
//新建一个shared parameter的定义文件。
IO.StreamWriter fs = new StreamWriter(application.SharedParametersFilename);
fs.Close();
definitionFile = application.OpenSharedParameterFile();
}
</code>

2. 获得/新建一个parameter group。
<code>
DefinitionGroup sharedGroup = null;
//查找一个名叫parameter group的参数组。
sharedGroup = sharedDefinitionFile.Groups.get_Item("parameter group");
//没找到,就新建一个。
if(sharedGroup == null)
{
sharedGroup = definitionFile.Groups.Create("parameter group");}
</code>

3. 访问组里的parameter。
<code>
DefinitionsBaseIterator itor = sharedGroup.Defintions.ForwardIterator();
while(itor.MoveNext())
{
ExternalDefinition externalDefinition = itor.Current as ExternalDefinition;
...
}
</code>

4. 创建shared parameter定义。
paramdef.png
API提供两个重载函数来创建shared parameter的定义。
Definitions.Create(string name, ParameterType paramType)
Definitions.Create(string name, ParameterType paramType, bool isVisible)
带bool参数的函数是创建一个界面不可见的参数定义,也就是说这个参数如果加到project里去了,用户从界面上是访问不到的。这个功能也是界面上没有的,API独家奉送。如果你需要保存一些自己的数据,可以创建不可见的参数,然后保存起来。
<code>
Definition definition = sharedGroup.Definitions.Create("parameter name", ParameterType.Text, true);
</code>

5. 将参数绑定到project里去吧。
parameterbinding.png
绑定一个参数到project里需要注意几点:
project parameter还是shared parameter。对于API来说,只有shared parameter一个选项。
parameter group,这个跟上面定义文件里的group不一样,上面的是用户自己的分组,这个是Revit内建的分组。
Type还是Instance,是类型参数还是实例参数。
Categories,这个参数绑定到哪些category上。
<code>
// 获得需要绑定的category,并插入到一个新的set里。
Category doorsCategory = document.Settings.Categories.get_Item(BuiltInCategory.OST_Doors)
...
CategorySet categories = application.Create.NewCategorySet();
categories.Insert(doorsCategory);
...
// 确定好是Type还是Instance
Binding instanceBinding = application.Create.NewInstanceBinding(categories);
//Binding typeBinding = application.Create.NewTypeBinding(categories);
// 绑定到project里去。
document.ParameterBindings.Insert(definition, instanceBinding, BuiltInParameterGroup.PG_DATA);
</code>


<基本上完>

评分

3

查看全部评分

回复

使用道具 举报

发表于 2010-11-16 21:30:18 | 显示全部楼层
大师就是大师,这资料别的地方可找不到!
回复 支持 反对

使用道具 举报

发表于 2010-11-16 23:51:15 | 显示全部楼层
怎么是英文板面啊……汗……
回复 支持 反对

使用道具 举报

发表于 2010-11-17 09:01:31 | 显示全部楼层
值得慢慢细看研究学习.收藏先
回复 支持 反对

使用道具 举报

发表于 2010-11-17 16:04:00 | 显示全部楼层
真给力,老大。
回复 支持 反对

使用道具 举报

发表于 2010-11-18 10:14:29 | 显示全部楼层
太强了,学习了!!
回复 支持 反对

使用道具 举报

发表于 2010-11-27 11:34:16 | 显示全部楼层

Thank you very much , This is very nice ...
回复 支持 反对

使用道具 举报

发表于 2010-11-28 13:06:23 | 显示全部楼层
这个我得顶的。
回复 支持 反对

使用道具 举报

发表于 2010-12-21 15:18:45 | 显示全部楼层
楼主的境界只能仰止
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-12-21 17:44:16 | 显示全部楼层
songduoshao 发表于 2010-12-21 15:18
楼主的境界只能仰止

呵呵,谢谢捧场。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则