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

Building Coder(Revit 二次开发) - 在一个倾斜的面上创建墙

问题
我想在一个倾斜的面上创建一面墙。是否有例子代码可以参考?
 
Jeremy
这里有一段简单的代码,对象文档是包含一个概念块(Conceptual Mass)族实例的项目。代码首先检索概念块上法向方向为 (-1, 0, 1) 的面,然后在这个面上创建墙。
[csharp]  
void CreateFaceWall( Document doc )  
{  
  FilteredElementCollector collector = new FilteredElementCollector( doc );  
  
  FamilyInstance fi = collector.OfClass( typeof( FamilyInstance ) ).FirstElement() as FamilyInstance;  
  
  XYZ nnorm = new XYZ( -1, 0, 1 ).Normalize();  
  
  if( fi != null )  
  {  
    Options op = new Options();  
    op.IncludeNonVisibleObjects = true;  
    //op.DetailLevel = DetailLevels.Undefined;  
    op.ComputeReferences = true;  
   
    // 译者注:个人认为这个类名起得不好,不太像一个集合类。如果叫 GeometryObjectSet 会更符合 Revit API 的类命名习惯。  
    GeometryElement ge = fi.get_Geometry( op );  
   
    if( ge != null )  
    {  
      foreach( GeometryObject obj in ge )  
      {  
        Solid solid = obj as Solid;  
  
  
        // 译者注:类型转换之后判断是否为 NULL 是一个很好的习惯。因为 Revit API 往往会将不同类型的对象放在同一个集合中。  
        // 下面的 PlanarFace pf = f as PlanarFace; 也是相同的道理。  
        if( solid != null && solid.Faces.Size > 0 )  
        {  
          foreach( Face f in solid.Faces )  
          {  
            PlanarFace pf = f as PlanarFace;  
            if( pf != null )  
            {  
              XYZ fnorm = pf.Normal.Normalize();  
   
              // 译者注:经常被问到如何进行向量计算。其实 Revit API 已经为绝大多数向量计算提供了直接的方法。不用再费劲地翻线性代数书了 :)  
              if( fnorm.IsAlmostEqualTo( nnorm ) )  
              {  
                string log = "";  
                bool done = false;  
                foreach( WallType t in doc.WallTypes )  
                {  
                  if( t != null )  
                  {  
                    ElementId id = t.Id;  
                    using( Transaction trans = new Transaction( doc ) )  
                    {  
                      trans.Start( "Add wall" );  
                      try  
                      {  
                        // 译者注:这里是亮点。注意创建非垂直的墙体应该使用 FaceWall,而不是 Wall。  
                        // 从 API 文档可以发现,与 Wall 一样,FaceWall 直接派生于 HostObject。  
                        FaceWall fw = FaceWall.Create( doc, id, WallLocationLine.CoreExterior, f.Reference );  
   
                        if( fw != null )  
                        {  
                          TaskDialog.Show("Succeeded", "Succeeded" );  
                          done = true;  
                        }  
                      }  
                      catch( Exception ex )  
                      {  
                        log += t.Name + ": " + ex.Message + "\r\n";  
                      }  
                      trans.Commit();  
                    }  
                    if( done )  
                      break;  
                  }  
                }  
                TaskDialog.Show( "Failed", log );  
              }  
            }  
          }  
        }  
      }  
    }  
  }  
}  
 
无法访问的位置(Location)属性
 
问题
我试图访问一个 FaceWall 对象的位置属性。不过返回的无论是 LocationCurve 还是 LocationPoint,值都是 NULL。
[csharp]  
Reference r1 = doc.Selection.PickObject( ObjectType.Element, "Please pick a wall: " );  
Element e1 = doc.GetElement( r1 );  
FaceWall faceWall = e1 as FaceWall;  
LocationCurve theCurve = faceWall.Location as LocationCurve;  
LocationPoint thePoint = faceWall.Location as LocationPoint;  
 
Jeremy
这是 Revit 目前的一个限制。如果元素的位置信息比较复杂,无法用一个点或者线段来表示,那么 Location 属性的内容可能是一个复杂的无法用 Revit API 访问的对象,或者干脆就是 NULL。显然 FaceWall 的位置信息就属于这种情况。所以你应该通过分析它的 GeometryElement 属性来获取位置信息。
补充:软件开发 , C# ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,