2014-02-21 56 views
0

在一個項目中,我需要將牆的原始幾何圖形導出爲IFC文件。所謂的原始幾何形狀是牆體的幾何形狀,不需要通過牆壁上的門窗來切割,而與屋頂,地板,橫樑,立柱等沒有關係。我想要的原始幾何體通常應該是一個形狀喜歡的框。如何使用Revit API檢索牆的原始幾何圖形?

不幸的是,沒有直接的Revit API給了我一面牆的原始幾何圖形。 element.get_Geometry方法返回由門,窗戶和連接的樓層,屋頂等切割的最終幾何體。

獲取牆的原始幾何體的一種可能方式是根據牆的參數自己重建幾何體,但我的懶惰方法是讓Revit來完成這項工作。我的方法有五個步驟如下:

第1步:啓動Revit事務。

第2步:致電element.get_Geometry之前,暫時刪除的門和牆託管窗,以及與牆體連接屋頂和地板,從Revit中的文檔。

第3步:調用document.Regenerate方法更新文檔中的元素。當然牆的幾何圖形也應該更新。

第4步:調用element.get_Geometry來獲得我想要的原始幾何。

步驟5:回滾事務,以便Revit文檔保持不變。

問題在步驟2中出現。即使我刪除了門窗,返回的幾何中仍有開口。

我的問題是,如何刪除與牆相關的所有元素?

我的Revit版本是2013.我使用的.rvt文件是Revit隨附的rac_basic_sample_project.rvt。我想出口的牆是117698或117654.

我的項目的ID牆上是基於基於Revit IFC出口srouce代碼。

以下是代碼段I用於獲取原始幾何:

private GeometryElement GetOriginalWallGeometry2(Element element) 
{ 
    Document doc = element.Document; 
    GeometryElement geomElem = null; 
    //Step 1 
    using (Transaction t = new Transaction(doc)) 
    { 
     //Step 2: 

     //delete wall joins 
     Autodesk.Revit.DB.Wall wall = element as Autodesk.Revit.DB.Wall; 

     //assert element is a wall 
     //the joined floors or roofs can be deleted as expected. 
     if (null != wall) 
     { 
      while (Autodesk.Revit.DB.WallUtils.IsWallJoinAllowedAtEnd(wall, 0)) 
      { 
       Autodesk.Revit.DB.WallUtils.DisallowWallJoinAtEnd(wall, 0); 
      } 
      while (Autodesk.Revit.DB.WallUtils.IsWallJoinAllowedAtEnd(wall, 1)) 
      { 
       Autodesk.Revit.DB.WallUtils.DisallowWallJoinAtEnd(wall, 1); 
      } 
     } 

     //The following code of deleting doors doesn't work as expected. 
     { 
      FilteredElementCollector collector = new FilteredElementCollector(doc); 
      ICollection<Element> elementsList = collector.OfCategory(BuiltInCategory.OST_Doors).ToElements(); //here should be OST_Doors or others? 

      foreach (Element elem in elementsList) 
      { 
       try 
       { 
        doc.Delete(elem); 
       } 
       catch (System.Exception ex) 
       { 
       } 
      } 
     } 

     //The following code of deleting windows doesn't work as expected. 
     { 
      FilteredElementCollector collector = new FilteredElementCollector(doc); 
      ICollection<Element> elementsList = collector.OfCategory(BuiltInCategory.OST_Windows).ToElements();//here should be OST_Windows or others? 

      foreach (Element elem in elementsList) 
      { 
       try 
       { 
        doc.Delete(elem); 
       } 
       catch (System.Exception ex) 
       { 
       } 
      } 
     } 


     //The following code also doesn't work as expected. 
     Autodesk.Revit.DB.HostObject hostObj = element as Autodesk.Revit.DB.HostObject; 
     if (hostObj != null) 
     { 
      IList<ElementId> idlist = hostObj.FindInserts(true, true, true, true); 
      foreach (ElementId id in idlist) 
      { 
       try 
       { 
        doc.Delete(id); 
       } 
       catch (System.Exception ex) 
       { 
       } 
      } 
     } 

     //Floors can be deteled as expected. 
     { 
      FilteredElementCollector collector = new FilteredElementCollector(doc); 
      ICollection<Element> linkList = collector.OfCategory(BuiltInCategory.OST_Floors).ToElements(); 

      foreach (Element elelink in linkList) 
      { 
       try 
       { 
        doc.Delete(elelink); 
       } 
       catch (System.Exception ex) 
       { 

       } 
      } 
     } 

     //Roofs can be deteled as expected. 
     { 
      FilteredElementCollector collector = new FilteredElementCollector(doc); 
      ICollection<Element> linkList = collector.OfCategory(BuiltInCategory.OST_Roofs).ToElements(); 

      foreach (Element elelink in linkList) 
      { 
       try 
       { 
        doc.Delete(elelink); 
       } 
       catch (System.Exception ex) 
       { 

       } 
      } 
     } 

     //Step 3 
     doc.Regenerate(); 

     //Step 4 
     Options options; 
     View ownerView = element.Document.GetElement(element.OwnerViewId) as View; 
     if (ownerView == null) 
     { 
      options = GeometryUtil.GetIFCExportGeometryOptions(); 
     } 
     else 
     { 
      options = new Options(); 
      options.View = ownerView; 
     } 
     geomElem = element.get_Geometry(options); 

     //Step 5 
     FailureHandlingOptions failureOptions = t.GetFailureHandlingOptions(); 
     failureOptions.SetClearAfterRollback(true); 
     failureOptions.SetDelayedMiniWarnings(true); 
     t.SetFailureHandlingOptions(failureOptions); 
     try 
     { 
      t.RollBack(); 
     } 
     catch (System.Exception ex) 
     { 
     } 
    } 

    return geomElem; 
} 
+0

你能給我們多一點細節嗎? – Shevliaskovic

+0

你改變了整個問題的含義? –

回答

0

我使用下面的方法來檢索特定類別的元件。

/// <summary> 
    /// Get all elements of the specified type that fall into the specified category 
    /// <para>The specified type must derive from Element, or you can use Element but you get everything :)</para> 
    /// </summary> 
    /// <typeparam name="T">The type of element to get</typeparam> 
    /// <param name="builtInCategory">The BuiltinCategory to discriminate the element set</param> 
    /// <returns>The collection of elements that match the type and specified categry</returns> 
    public IEnumerable<T> GetElements<T>(BuiltInCategory builtInCategory) where T : Element 
    { 
     FilteredElementCollector collector = new FilteredElementCollector(Document); 
     // Seems you must be a subclass of element to use the OfClass method 
     if (typeof(T) != typeof(Element)) 
      collector.OfClass(typeof(T)); 
     collector.OfCategory(builtInCategory); 
     return collector.Cast<T>(); 
    } 

如果你試圖讓門窗那就這樣使用

var doors = GetElements<FamilyInstance>(BuiltInCategory.OST_DOORS); 
var windows = GetElements<FamilyInstance>(BuiltInCategory.OST_WINDOWS); 

這假設您正在尋找的開口是門或窗。

如果您在牆壁或其他類型的開口內尋找空洞擠壓等,那麼您需要在您的問題中更具體。

作爲上面顯示的函數的一個更復雜的版本,當我希望對檢索的元素應用一個過濾器時,我使用下面的方法。

 /// <summary> 
    /// Get the collection of elements of the specified type that are within the provided category that also pass the filter. 
    /// <para>The specified type must derive from Element, or you can use Element but you get everything :)</para> 
    /// </summary> 
    /// <typeparam name="T">The type of element to get</typeparam> 
    /// <param name="builtInCategory">The BuiltinCategory to discriminate the element set</param> 
    /// <param name="filter">The filter to check the element against</param> 
    /// <returns>The collection of elements of the specified type and specified category that pass the filter</returns> 
    public IEnumerable<T> GetElements<T>(BuiltInCategory builtInCategory, ElementFilter filter) where T : Element 
    { 
     FilteredElementCollector collector = new FilteredElementCollector(Document); 
     // Seems you must be a subclass of element to use the OfClass method 
     if (typeof(T) != typeof(Element)) 
      collector.OfClass(typeof(T)); 
     collector.OfCategory(builtInCategory); 
     collector.WherePasses(filter); 
     return collector.Cast<T>(); 
    } 

使用上面所定義的方法方法的優點是,它會從隔離在未來的Revit API的變化的代碼,而不是使用整個反覆代碼庫相同的代碼塊。

0

如果你想要檢索的門窗和牆壁上的任何其他開放,這是正確的代碼:

var ids = (yourCurrentWallElement as Wall).FindInserts(true, true, true, true); 
foreach (ElementId id in ids) 
{ 
    var el = doc.GetElement(id); 

    Debug.WriteLine(" Id: " + el.Id); 
    Debug.WriteLine(" Type: " + el.GetType().Name); 
    Debug.WriteLine(" Category: " + el.Category.Name); 
    Debug.WriteLine(" Type: " + el.GetType().Name); 

    if (el is FamilyInstance) 
    { 
     var fi = el as FamilyInstance; 
     if (fi != null) 
      Debug.WriteLine(" Symbol Name: " + fi.Symbol.Name); 
    } 
} 

在FindInserts更多信息 - >http://revitapisearch.com/html/58990230-38cb-3af7-fd25-96ed3215a43d.htm

其他例子 - >http://spiderinnet.typepad.com/blog/2012/04/get-wall-inserts-using-the-revit-wallfindinserts-net-api.html

相關問題