Skip to content
C#
参数与过滤

参数与过滤

Revit 元素的信息几乎全部存储为 Parameter(参数)。掌握参数的读写和基于参数的元素过滤是数据处理的核心能力。


Parameter(参数)

每个 Revit 元素的属性——尺寸、材质、注释等——都通过 Parameter 访问:

Element element = doc.GetElement(elementId);

// 通过内置参数获取
Parameter param = element.get_Parameter(BuiltInParameter.DOOR_WIDTH);
if (param != null && param.HasValue)
{
    double width = param.AsDouble();   // 英尺(默认的内部单位)
    double widthMm = UnitUtils.ConvertFromInternalUnits(width, UnitTypeId.Millimeters);
}

// 通过名称获取(共享参数或项目参数)
Parameter customParam = element.LookupParameter("自定义参数名");
Parameter commentParam = element.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS);

参数数据类型与读取

Parameter param = element.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET);

// 检查是否有值
if (param == null || !param.HasValue)
    return;

// 数据类型
StorageType storageType = param.StorageType;
// Integer, Double, String, ElementId, None

switch (storageType)
{
    case StorageType.Integer:
        int intVal = param.AsInteger();
        break;

    case StorageType.Double:
        double dblVal = param.AsDouble();               // 始终为英尺
        double mmVal = UnitUtils.ConvertFromInternalUnits(dblVal, UnitTypeId.Millimeters);
        // 或使用 AsValueString 获取带格式的显示字符串
        string display = param.AsValueString();          // "2000.0", "200mm" 等
        break;

    case StorageType.String:
        string strVal = param.AsString();
        break;

    case StorageType.ElementId:
        ElementId elemId = param.AsElementId();
        Element referencedElem = doc.GetElement(elemId);
        break;

    case StorageType.None:
        // 无值存储(通常为分组参数)
        break;
}

参数定义信息

// 获取参数的定义(元数据)
Definition def = param.Definition;
string paramName = def.Name;                           // 参数名
ParameterType paramType = def.ParameterType;           // 参数类型(长度、面积、体积...)
BuiltInParameterGroup paramGroup = def.ParameterGroup; // 参数分组
bool isReadOnly = def.IsReadOnly;                      // 是否只读
bool isInstance = def.IsInstance;                      // 实例参数 vs 类型参数

💡 IsInstance = true → 实例参数(每个实例独立值)。IsInstance = false → 类型参数(同类共享值)。


修改参数值

// 修改参数值(必须在事务中)
using (Transaction tx = new Transaction(doc, "修改参数"))
{
    tx.Start();

    Parameter param = element.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS);
    if (param != null && !param.IsReadOnly)
    {
        param.Set("新备注");
    }

    // 修改长度参数
    Parameter lengthParam = element.get_Parameter(BuiltInParameter.DOOR_WIDTH);
    if (lengthParam != null && !lengthParam.IsReadOnly)
    {
        double newWidthMm = 1000.0;
        lengthParam.Set(UnitUtils.ConvertToInternalUnits(newWidthMm, UnitTypeId.Millimeters));
    }

    tx.Commit();
}

常用 BuiltInParameter

BuiltInParameter 含义 适用元素
ALL_MODEL_INSTANCE_COMMENTS 注释(通用) 所有模型元素
ALL_MODEL_MARK 标记 所有模型元素
DOOR_WIDTH 门宽度
DOOR_HEIGHT 门高度
WINDOW_WIDTH 窗宽度
WALL_BASE_OFFSET 底部偏移
WALL_TOP_OFFSET 顶部偏移
WALL_STRUCTURAL_USAGE_PARAM 结构用途
CURVE_ELEM_LENGTH 曲线元素长度 墙、梁、管道
INSTANCE_ELEVATION_PARAM 实例标高偏移 族实例
LEVEL_PARAM 关联标高 族实例
FLOOR_ATTR_THICKNESS_PARAM 楼板厚度 楼板
MATERIAL_PARAM 材质 墙、楼板等
FAMILY_BASE_LEVEL_PARAM 基准标高 族实例

💡 要探索一个元素有哪些参数,最快捷的方式是使用 RevitLookup(官方开源工具),可以在元素上右键查看所有参数。


ElementFilter —— 过滤器系统

Revit 提供了一套完善的 ElementFilter 体系来做高效的数据库级别过滤:

逻辑组合过滤器

// AND 过滤:墙 且 有注释
ElementFilter wallFilter = new ElementCategoryFilter(BuiltInCategory.OST_Walls);
ElementFilter commentFilter = new ElementParameterFilter(
    ParameterFilterRuleFactory.CreateHasValueRule(
        new ElementId(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS)));

ElementFilter andFilter = new LogicalAndFilter(wallFilter, commentFilter);

var filteredWalls = new FilteredElementCollector(doc)
    .WherePasses(andFilter)
    .WhereElementIsNotElementType()
    .ToElements();

// OR 过滤:墙 或 门
ElementFilter doorFilter = new ElementCategoryFilter(BuiltInCategory.OST_Doors);
ElementFilter orFilter = new LogicalOrFilter(wallFilter, doorFilter);

参数过滤

// 创建参数值规则
// 数值规则
FilterRule lengthRule = ParameterFilterRuleFactory.CreateGreaterRule(
    new ElementId(BuiltInParameter.CURVE_ELEM_LENGTH),
    UnitUtils.ConvertToInternalUnits(5000, UnitTypeId.Millimeters),   // > 5m
    1e-6                                                              // 容差
);

// 字符串规则
FilterRule commentRule = ParameterFilterRuleFactory.CreateContainsRule(
    new ElementId(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS),
    "重要",
    caseSensitive: false
);

// 有值规则
FilterRule hasValueRule = ParameterFilterRuleFactory.CreateHasValueRule(
    new ElementId(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS));

// 组合成 ElementParameterFilter
ElementFilter paramFilter = new ElementParameterFilter(commentRule);

var result = new FilteredElementCollector(doc)
    .WherePasses(paramFilter)
    .ToElements();

参数规则类型

// 创建规则的各种方式
ParameterFilterRuleFactory.CreateEqualsRule(paramId, value, epsilon);
ParameterFilterRuleFactory.CreateGreaterRule(paramId, value, epsilon);
ParameterFilterRuleFactory.CreateGreaterOrEqualRule(paramId, value, epsilon);
ParameterFilterRuleFactory.CreateLessRule(paramId, value, epsilon);
ParameterFilterRuleFactory.CreateLessOrEqualRule(paramId, value, epsilon);
ParameterFilterRuleFactory.CreateNotEqualsRule(paramId, value, epsilon);

// 字符串规则
ParameterFilterRuleFactory.CreateBeginsWithRule(paramId, prefix);
ParameterFilterRuleFactory.CreateContainsRule(paramId, substring, caseSensitive);
ParameterFilterRuleFactory.CreateEndsWithRule(paramId, suffix);
ParameterFilterRuleFactory.CreateEqualsRule(paramId, exactString, caseSensitive);
ParameterFilterRuleFactory.CreateNotEqualsRule(paramId, exactString, caseSensitive);

// 特殊规则
ParameterFilterRuleFactory.CreateHasValueRule(paramId);
ParameterFilterRuleFactory.CreateNotHasValueRule(paramId);
ParameterFilterRuleFactory.CreateSharedParameterApplicableRule("共享参数名");

其他常用过滤器

// 按类别过滤
ElementFilter categoryFilter = new ElementCategoryFilter(BuiltInCategory.OST_Walls);

// 按类过滤(.NET 类型)
ElementFilter classFilter = new ElementClassFilter(typeof(Wall));

// 按元素是否为类型过滤
ElementFilter isTypeFilter = new ElementIsElementTypeFilter(inverted: false);
ElementFilter isNotTypeFilter = new ElementIsElementTypeFilter(inverted: true);

// 按族名称过滤
ElementFilter familyNameFilter = new FamilyInstanceFilter(
    doc, new ElementId(BuiltInCategory.OST_Doors));

// 按标高过滤
ElementFilter levelFilter = new ElementLevelFilter(levelId);

// 按房间过滤
ElementFilter roomFilter = new RoomFilter();

// 按结构用途过滤
ElementFilter structuralFilter = new StructuralInstanceUsageFilter(
    StructuralInstanceUsage.Column);

// 按设计选项过滤
ElementFilter designOptionFilter = new ElementDesignOptionFilter(designOptionId);

// 反转过滤器
ElementFilter inverseFilter = new LogicalNotFilter(classFilter);

使用 QuickFilter vs SlowFilter

// 自定义过滤器:实现 IQuickFilter(快)或 ISlowFilter(慢)
public class MyWallQuickFilter : IQuickFilter    // 快速(数据库层)
{
    public bool PassesFilter(Element element)
    {
        // 只能使用 ElementRecord 中的基本字段(Category, Class, Type 等)
        return element.Category?.Id.IntegerValue == (int)BuiltInCategory.OST_Walls;
    }
}

public class MyWallSlowFilter : ISlowFilter      // 慢速(内存层)
{
    public bool PassesFilter(Element element)
    {
        // 可以访问元素的所有属性和参数
        Parameter param = element.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS);
        return param?.AsString()?.Contains("重要") == true;
    }
}

ElementQuickFilter 在数据库层运行,性能远优于 ElementSlowFilter。能用 QuickFilter 时避免用 SlowFilter,能用 API 内置过滤器时避免用 Lambda Where()


遍历共享参数

// 获取文档中所有共享参数定义
public List<SharedParameterElement> GetSharedParameters(Document doc)
{
    return new FilteredElementCollector(doc)
        .OfClass(typeof(SharedParameterElement))
        .Cast<SharedParameterElement>()
        .ToList();
}

// 根据 GUID 查找共享参数
public SharedParameterElement? FindSharedParameter(Document doc, Guid guid)
{
    return GetSharedParameters(doc)
        .FirstOrDefault(sp => sp.GuidValue == guid);
}

获取元素的全部参数

public void DumpElementParameters(Element element)
{
    StringBuilder sb = new StringBuilder();
    sb.AppendLine($"元素:{element.Name} ({element.Id})");

    foreach (Parameter param in element.Parameters)
    {
        string value = param.HasValue ? GetParameterDisplayValue(param) : "(无值)";
        string type = param.IsInstance ? "实例" : "类型";
        string readonly_ = param.IsReadOnly ? "[只读]" : "";

        sb.AppendLine($"  [{type}] {param.Definition.Name} = {value} {readonly_}");
    }

    TaskDialog.Show("参数列表", sb.ToString());
}

private string GetParameterDisplayValue(Parameter param)
{
    switch (param.StorageType)
    {
        case StorageType.Integer: return param.AsInteger().ToString();
        case StorageType.Double:
            return param.AsValueString() ?? param.AsDouble().ToString("F4");
        case StorageType.String: return param.AsString() ?? "";
        case StorageType.ElementId: return param.AsElementId().ToString();
        default: return "?";
    }
}