Building Coder(Revit 二次开发)- 创建球体用于AVF和过滤

原文链接: Sphere Creation for AVF and Filtering

Revit 2012 API 新引入了 GeometryCreationUtilities 类来帮助创建实体。然而它没有提供直接的球体创建方法,而是提供了以下五个根据输入曲线创建几何实体的辅助方法:
  • CreateBlendGeometry 融合
  • CreateExtrusionGeometry 拉伸
  • CreateRevolvedGeometry 旋转
  • CreateSweptGeometry 放样
  • CreateSweptBlendGeometry 放样融合
创建之后的几何结果并不会作为元素添加到文档中。不过你可以使用创建的实体、实体的面和边做如下操作:
- 作为Analysis Visualization Framework(AVF)方法的面输入参数
  例如:SpatialFieldManager.AddSpatialFieldPrimitive
- 作为确定三维元素空间相交情况的实体输入参数
- 作为布尔操作的输入参数
- 作为几何计算的输入参数
  例如:面投影(Face.Project)、面相交(Face.Intersect)、和其它有关面、实体、边的几何方法

既然这种方式创建的实体只存在于内存中,无法添加到 Revit 文件数据库与文件一起保存,那它们有什么作用呢?

正如我们上面提到的,你可以使用这些实体通过AVF来可视化地显示一些结果;或者在搜索相交元素时(ElementIntersectsFilter)将范围限定在一个空间区域。

创建球体
我们可以使用 CreateRevolvedGeometry() 方法:首先创建一个表示半圆的闭合曲线,包括180度的圆弧和连接圆弧两个端点的直线(即经过圆心的直径线)。然后将半圆面以直径线为轴旋转360度就可以了。


这里我们首先需要创建一个 Revit 称之为 Frame 的对象。为了使我的代码能允许在任意位置创建球体,我还需要将球心和球半径作为输入参数。我可以使用球心来定义 Frame 的位置。起初我以为既然半圆面的闭合曲线是针对全局坐标系的,那么 Frame 应该会自动将半圆面的其它几何数据转换为全局坐标系。但是当我使用以球心为原点的局部坐标系定义圆弧和直径线时,CreateRevolvedGeometry() 方法会抛出异常: 闭合曲线必须位于Z轴的右侧(X坐标 >= 0)


所以我们必须在创建圆弧和直径线时,就使用已经转换到全局坐标系的坐标值。

  /// <summary>
  /// 使用指定的球心和半径创建球体
  /// </summary>
  static public Solid CreateSphereAt(
    CreationApp creapp,
    XYZ centre,
    double radius )
  {
    // 使用标准的全局坐标系创建 Frame
 
    Frame frame = new Frame( centre,
      XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ );
 
    // 创建一个Z轴方向的半圆闭合曲线(注意所有的坐标都是相对全局坐标系的)
 
    Arc arc = creapp.NewArc( 
      centre - radius * XYZ.BasisZ,
      centre + radius * XYZ.BasisZ,
      centre + radius * XYZ.BasisX );
 
    Line line = creapp.NewLineBound(
      arc.get_EndPoint( 1 ),
      arc.get_EndPoint( 0 ) );
 
    CurveLoop halfCircle = new CurveLoop();
    halfCircle.Append( arc );
    halfCircle.Append( line );
 
    List<CurveLoop> loops = new List<CurveLoop>( 1 );
    loops.Add( halfCircle );
 
    return GeometryCreationUtilities
      .CreateRevolvedGeometry(
        frame, loops, 0, 2 * Math.PI );
  }

使用AVF显示实体

使用几何创建工具类创建的临时实体的一个重要用途就是用于根据几何特征过滤元素,我会在最近另外讨论这个问题。现在先让我们使用AVF显示这些几何实体。

  void PaintSolids(
    Document doc,
    Solid solid,
    int level )
  {
    Application app = doc.Application;
 
    View view = doc.ActiveView;
 
    if( view.AnalysisDisplayStyleId == ElementId.InvalidElementId )
    {
      CreateAvfDisplayStyle( doc, view );
    }
 
    SpatialFieldManager sfm = SpatialFieldManager.GetSpatialFieldManager( view );
 
    if( null == sfm )
    {
      sfm = SpatialFieldManager.CreateSpatialFieldManager( view, 1 );
    }
 
    if( _schemaId != -1 )
    {
      IList<int> results = sfm.GetRegisteredResults();
 
      if( !results.Contains( _schemaId ) )
      {
        _schemaId = -1;
      }
    }
 
    if( _schemaId == -1 )
    {
      AnalysisResultSchema resultSchema = new AnalysisResultSchema( "PaintedSolids", "Description" );
      _schemaId = sfm.RegisterResult( resultSchema );
    }
 
		FaceArray faces = solid.Faces;
		Transform trf = Transform.Identity;

		foreach( Face face in faces )
		{
			int idx = sfm.AddSpatialFieldPrimitive( face, trf );

			IList<UV> uvPts = new List<UV>( 1 );

			uvPts.Add( face.GetBoundingBox().Min );

			FieldDomainPointsByUV pnts = new FieldDomainPointsByUV( uvPts );

			List<double> doubleList = new List<double>( 1 );

			doubleList.Add( level );

			IList<ValueAtPoint> valList = new List<ValueAtPoint>( 1 );

			valList.Add( new ValueAtPoint( doubleList ) );

			FieldValues vals = new FieldValues( valList );

			sfm.UpdateSpatialFieldPrimitive( idx, pnts, vals, _schemaId );
		}
  }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值