Building Coder(Revit 二次开发)- 图形化显示区域边界

原文链接: Graphically Display Area Boundary Loops

我最近研究了一个关于检测区域边界是否闭合的问题,方法是在 RevitLookup 中查看相关的坐标值。但是我想人脑很难分析这么多的数据,所以靠谱的方式你懂的,还是创建一个外部命令(DisplayBoundary)来自动化地完成。该命令遍历选中区域(或是模型中的所有区域)的边界片段,然后创建一个曲线来代表每个片段。

命令运行之后,新创建的曲线就可以独立地图形化显示了。

区域边界片段获取设置

Area.GetBoundarySegments() 方法需要一个 SpatialElementBoundaryOptions 对象作为参数,SpatialElementBoundaryOptions 对象提供两个属性来定义如何获取边界片段:

1. StoreFreeBoundaryFaces (bool)

    在结果中是否包含自由边界面(空间元素表面的与其轮廓表面不重合的部分)

2. SpatialElementBoundaryLocation (enum)

    Finish - 空间元素的轮廓面

    Center - 空间元素中心线面

因为 Revit 墙体的 Location 属性是定义于其中心线的,所以应该使用 SpatialElementBoundaryLocation 属性来从边界片段结果中获取闭合线。

例子

下图是我用来测试的 Revit 文件。

Area element



它的锯齿状边界来源于位于该区域的房间的门窗洞。

Area boundary rooms, walls and openings


选中这个区域并运行 DisplayBoundary 命令,并在视图中分离模型曲线之后,结果如下图所示:

Model curves displaying area boundary


代码

public Result Execute(
  ExternalCommandData commandData,
  ref string message,
  ElementSet elements )
{
  UIApplication uiapp = commandData.Application;
  UIDocument uidoc = uiapp.ActiveUIDocument;
  Application app = uiapp.Application;
  Document doc = uidoc.Document;
 
  FilteredElementCollector col = null;
 
  ElementSet set = uidoc.Selection.Elements;
 
  int n = set.Size;
 
  if( 0 < n )
  {
    List<ElementId> ids = new List<ElementId>( set.OfType<Area>().Select<Area,ElementId>( e => e.Id ) );
  
    if( 0 == ids.Count )
    {
      message = "Please select some area alements "
        + " before running his command, or nothing "
        + "at all to process all of them.";
 
      return Result.Failed;
    }
 
    // 注意从逻辑上讲是不需要调用 WhereElementIsNotElementType() 方法的。
    // 但是 Revit API 有个小缺陷,如果不调用则在对 col 进行过滤操作时会抛出一个异常。
    col = new FilteredElementCollector( doc, ids ).WhereElementIsNotElementType();
  }
  else
  {
    // 注意我们不能使用 Area 作为 OfClass() 方法的参数,因为 Area 不是 Revit 的本地对象。
    // 应该先使用 Area 的基类 SpatialElement 作为 OfClass() 方法的参数,然后在结果中将类型转换成 Area。
    col = new FilteredElementCollector( doc ).OfClass( typeof( SpatialElement ) );
  }
 
  // 定义边界设置
  SpatialElementBoundaryOptions opt = new SpatialElementBoundaryOptions();
  opt.StoreFreeBoundaryFaces = true;
  opt.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Center; // 闭合线
  //opt.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish; // 非闭合线
 
  using( Transaction tx = new Transaction( doc ) )
  {
    tx.Start( "Convert Area Loops To Model Curves" );
 
    foreach( SpatialElement e in col )
    {
      Area area = e as Area;
      Debug.Print( area.Name ); 

      double z = area.Level.Elevation; 
      Plane levelPlane = app.Create.NewPlane( XYZ.BasisZ, new XYZ( 0, 0, z ) ); 
      SketchPlane sketchPlane = doc.Create.NewSketchPlane( levelPlane ); 
      IList<IList<BoundarySegment>> 
      loops = area.GetBoundarySegments( opt ); 
      foreach( IList<BoundarySegment> loop in loops ) 
      { 
        foreach( BoundarySegment seg in loop ) 
        { 
          doc.Create.NewModelCurve( seg.Curve, sketchPlane ); 
        } 
      } 
    } 

    tx.Commit(); 
  } 
  return Result.Succeeded;
}
完整的代码可以在这里下载: DisplayBoundary.zip
  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值