Building Coder(Revit 二次开发) - 缺少层(Level)属性的族实例

Building Coder 链接:http://thebuildingcoder.typepad.com/blog/2011/01/family-instance-missing-level-property.html

Revit二次开发论坛链接:http://revit.5d6d.com/viewthread.php?tid=1280&page=1&extra=#pid1782


这个主题由acadGraph CADstudio GmbH(http://www.acadgraph.de/)的Rudolf Honke提供。


有时候我们会需要取得位于指定层的所有元素,比方说窗族的所有实例。下面我使用的一个辅助函数:

List<Element> GetWindowsByLevel( 
  Document doc, 
  Level level )
{
  List<Element> elementList = new List<Element>();
 
  FilteredElementCollector collector 
    = new FilteredElementCollector( doc )
      .OfCategory( BuiltInCategory.OST_Windows );
 
  ParameterValueProvider provider 
    = new ParameterValueProvider( 
      new ElementId( 
        BuiltInParameter.FAMILY_LEVEL_PARAM ) );
 
  FilterNumericRuleEvaluator evaluator 
    = new FilterNumericEquals();
 
  ElementId idRuleValue = level.Id;
 
  FilterElementIdRule rule 
    = new FilterElementIdRule( 
      provider, evaluator, idRuleValue );
 
  ElementParameterFilter filter 
    = new ElementParameterFilter( rule );
 
  elementList.AddRange( 
    collector.WherePasses( filter ).ToElements() );
 
  return elementList;
}

但是很奇怪,这样做有时候会遗漏一些元素。问题出在这些元素的层属性没有被正确设置。这一点可以通过打开元素的属性视图来验证。对于那些没有设置层属性的元素,你无法在其属性窗口中找到“层”这一项。进一步使用 RevitLookup ”snoop built-in enums” 命令,你会发现原来是这些族实例的原生参数集合中不存在FAMILY_LEVEL_PARAM 参数,或是虽然存在但是值为null


有时候我们可以通过设置一个参数来影响一个属性。比方说通过移动或者旋转一个元素来改变它的位置和曲线。另外一些情况下,属性和那些“应该”与其相关的参数之间实际上没有关联。不过这是另外一个话题了。


回到我们讨论的问题上。由于层属性没有出现在属性视图中,所以我们无法手工设置它的值。这样一个罕见的情况出现了:我们只能通过调用Revit API 编程的方式解决这个问题。而无法通过Revit 操作的方式解决。(译者注:绝大多数情况下,通过Revit API 实现的功能是通过Revit 操作实现的功能的子集。但是显然,这个主题讨论的是一个特例)


现在让我们来看看利用Revit API 解决这个问题的具体步骤:
1. 首先获取当前文档中所有层;
2. 提供一个合适的GUI 方式让用户选择目标层;
3. 使用如下代码为缺少层属性的族实例设置层属性。

windowWithoutLevelParam.
    get_Parameter(BuiltInParameter.FAMILY_LEVEL_PARAM).
    Set(levels[levelDialogSelectedIndex].Id);

为所有缺少层属性的族实例执行以上操作。然后 GetWindowsByLevel() 方法就可以正常工作了。

你可能感兴趣的:(编程,windows,api,filter,文档,enums)