問題 我想在一個傾斜的面上創建一面牆。是否有例子代碼可以參考? 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 屬性來獲取位置信息。