参数与过滤
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 内置过滤器时避免用 LambdaWhere()。
遍历共享参数
// 获取文档中所有共享参数定义
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 "?";
}
}