当前位置:编程学习 > C#/ASP.NET >>

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

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)。


所以我们必须在创建圆弧和直径线时,就使用已经转换到全局坐标系的坐标值。
[csharp
<span style="font-size:12px;">  /// <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 ); 
  }</span> 

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

[csharp] 
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 ); 

补充:软件开发 , C# ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,