19. Revit API: Parameter(参数)

一、前言

我们在前面或多或少提到也用到参数了,这篇便细讲一下。

首先,我们知道好多信息都藏在参数里,或者说可以从参数中获取。我们还能够通过调整参数的值,改变模型的形态,即族的参变。

其次,有时族上没有我们想要的信息,但又需要在族上存与展示,这时我们可以为元素批量加上参数,对应着Revit管理面板上的记载“参数”功能。

这几个的功能是什么怎么用就不讲了,去看帮助文档噢。

在这里插入图片描述

所以,这篇就讲这些内容:

  • 参数&内置参数
  • 族参数
  • 共享参数
  • 项目参数

二、Parameter

Parameter就是用来表示和操控元素信息的一类东西,所有的Element都有参数,可以使用通用的方法获取。

// Element Class
public ParameterSet Parameters { get; }
public IList<Parameter> GetParameters(...);

Parameter可以表示的元素字段类型有:DoubleIntegerStringElementId四种。

2.1. 方法

MethodsDescription
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. 属性

再来看看属性,都是非常有用的。

PropertiesDescription
Definition参数的定义,包括参数名称、参数组、参数类型、单位类型
DisplayUnitType
HasValue
值显示的单位
是否有值
StorageType值的类型
UserModifiable值是否可以更改
IsShared是否为共享参数
  1. 值的类型可以让我们确定采用什么方法去获取值。
  2. 值的显示单位和参数定义上的单位类型,可以让我们计算出想要的值。

2.3. 参数名称 & 内置参数

我们知道Revit种有很多的参数,我们当然可以使用中文名称去获取,如上面的“面积”,但这样不好,Revit切换个语言代码就要炸了。

所以,对于Revit内置的参数,我们需要使用特定的代号去获取,它们都在BuiltInParameter(内置参数)枚举中。

可以通过RevitLookUp插件来获取,或者在文档中检索。

在这里插入图片描述


三、族参数

有时,一些族上没有我们需要的参数,但又需要用到,怎么办呢,那就加上呗。

  1. 编辑族,给这个族加个参数。
  2. 设置项目参数,让一批族都有这个参数。

这里,我们先讲第一种方式,第二种在后面项目参数那里讲。

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(族管理器)

好吧,这个破玩意儿,当初可是找了好些时间,才知道有这么个类,及其离谱,非常不爽,鬼知道我都看了些什么。

简单瞅瞅吧,重要的加粗了。

MehtodsDescription
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需要注意*】。
image.png

属性Types注意:
族类型可以在族编辑文档中添加,也可在项目文档中,通过“编辑类型”添加。

  • 族文档中添加:Types能获取到
  • 项目文档编辑类型添加:Types不能获取到

在这里插入图片描述

3.3. FamilyParameter(族参数)

FamilyParameter,就上面的GetParameters()方法获取。不同于Parameter,虽然部分属性相同,但两者间并不存在继承/派生关系。

  • Parameter:倾向于值的读写
  • FamilyParameter:倾向于参数的定义

方法嘛,没有。就是一些属性,用来定义参数。

PropertiesDescription
Definition
DisplayUnitType
StorageType
定义
显示单位
存储类型(double、int …)
IsInstance
IsShared
IsReporting
是否为实例参数
是否为共享参数
?
IsReadOnly是否只读
UserModifiable是否通过交互修改
Formula
CanAssignFormula
IsDeterminedByFormula
公式
AssociatedParameters关联

3.4. 参数与族参数获取比较

这个还是有必要提一下的。

  1. 参数获取,自基类Element的GetParameters方法获取。
  2. 族参数获取,自族管理类FamilyManager的GetParameters方法获取。

前者,获取到“实例”元素上所有参数。
后者,获取到“抽象”元素(族)上所有参数。
那么可以理解前者比后者多一些吧,毕竟Revit在生成模型时还是会偷偷做一些操作的。

问题呢,在于族参数获取上。
我们在自定义族时,可以塞很多参数,能获取到。

如何只获取用户添加的参数呢?即过滤掉Revit给加上的参数。

目前我还没有去做,但一个可能的操作是:遍历排除所有BuiltInParameter中的参数
当然我没有去尝试,有兴趣的小伙伴可以试试。有更好的方法也欢迎留言。


四、项目参数 & 共享参数

项目参数的创建过程中,用到了一个叫“共享参数文件”的东西。

从Revit项目参数的交互创建方式上,可以看到既可以由“项目参数”定义,也可以从“共享参数”创建。

但从API上看,我们只能采用“共享参数”的方式,并没有Definition直接运用的方法。

所以,共享参数和项目参数的创建,代码上是同步的,就多一步少一步而已。

前面提示:共享参数仅是提供了参数定义,与其它元素并无关联关系。

在这里插入图片描述

4.1. 项目参数的创建

先来看看创建项目参数的创建流程:

  1. 文件,创建一个txt文件,获取其路径filePath(已有则不创建)
  2. 引用,app.SharedParametersFilename = filePath
  3. 打开,app.OpenSharedParameterFile()
  4. 定义,此时创建共享参数:DefinitionFile -> DefinitionGroup -> Definition -> ExternalDefinitionCreationOptions
  5. 类型,CategorySet -> Category
  6. 绑定,Binding -> InstanceBinding / TypeBinding
  7. 应用,此时绑定项目参数。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.SharedFilePath
    FileStream 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
)
  1. 走创建共享参数那套流程,整个ExternalDefinition出来。
  2. 走族管理器那套流程,把这个外部参数定义给塞进去

删除嘛,通过族管理器删除咯。

emm…我直接把共享参数删掉(交互),通过共享参数添加的族参数还在,也就是说,这两着并无关联,创建仅仅是采用了共享参数中的参数定义 ㄟ( ▔, ▔ )ㄏ。上面补充提示了嗷。

吐槽:花里胡哨的,有个锤子用


五、总结

写完参数相关的内容了,

鼓掌👏👏👏

结束

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值