IFC 模型中的合併和刪除實體是一個很是重要的任務,由於 IFC 不是一個分層結構。它是一個複雜的結構,具備潛在的循環關係,是一個雙向導航。在單個實體上執行這些任務並非問題(您能夠將其想象爲STEP21文件中的一行)。html
#144= IFCBUILDINGSTOREY('026ajlHVj1HBm_osQm7IDT',#47,'Lower Roof - Slab Level',$,$,#143,$,
'Lower Roof - Slab Level',.ELEMENT.,3199.99999999704);
若是您但願隔離定義實體的完整數據孤島,而且但願刪除該實體而不對數據孤島以外的其餘實體產生反作用,或者但願合併該實體以使其與現有數據混合而不產生重複性和不一致性,則會變得愈來愈困難。出於這些緣由,咱們更喜歡第三種選擇,即選擇您想要的,並將其複製到一個空模型中。這顯然是一項潛在的複雜任務,但至少在你的控制之下更容易。IModel
接口中的核心函數是 InsertCopy()
:緩存
T InsertCopy<T>(T toCopy, XbimInstanceHandleMap mappings, PropertyTranformDelegate propTransform,
bool includeInverses, bool keepLabels);
正如對全部參數的簡要描述同樣:app
從全部這些 PropertyTranformDelegate 委託中看起來彷佛有點神祕。但它是上述方法的基本部分,由於它容許控制複製數據的範圍。若是您容許反向,而且不提供任何額外的過濾,那麼您最終可能會獲得包含98%的原始模型,即便您只是嘗試在單個牆上覆制。要正確使用它,你須要很是好地理解IFC的結構。下面是一個強大的轉換的簡單示例,它將忽略全部的幾何圖形和位置,只容許描述產品類型及其屬性的逆關係。幾何圖形一般佔文件的90%左右,所以若是您對基於幾何圖形的圖形或分析不感興趣,可使用它建立僅包含描述性數據的很是小的IFC文件。函數
PropertyTranformDelegate semanticFilter = (property, parentObject) => { // 省略幾何圖形和位置 if (parentObject is IIfcProduct && (property.PropertyInfo.Name == nameof(IIfcProduct.Representation) || property.PropertyInfo.Name == nameof(IIfcProduct.ObjectPlacement))) return null; // 省略映射的幾何圖形 if (parentObject is IIfcTypeProduct && property.PropertyInfo.Name == nameof(IIfcTypeProduct.RepresentationMaps)) return null; // 僅經過反向關係(它將接管全部屬性和類型)實現 isDefinedby 和 istypedby property.PropertyInfo.Name == nameof(IIfcProduct.IsDefinedBy) || property.PropertyInfo.Name == nameof(IIfcProduct.IsTypedBy) )) return null; return property.PropertyInfo.GetValue(parentObject, null); };
PropertyTranformDelegate 採用兩個參數, 其中第一個是 ExpressMetaProperty, 另外一個是 IPersistEntity 的對象。ExpressMetaProperty 是一個緩存對象,它是咱們本身反射元模型的一部分,咱們用於某些數據操做。該委託在其餘代碼中使用,這些代碼使用C#反射來檢查數據並複製值。若是不指定委託insertcopy(),則將使用實體中的全部屬性並複製它們。spa
using Xbim.Common; using Xbim.Ifc; using Xbim.Ifc4.Interfaces; namespace BasicExamples { class InsertCopy { public void CopyWallsOver() { const string original = "SampleHouse.ifc"; const string inserted = "SampleHouseWalls.ifc"; PropertyTranformDelegate semanticFilter = (property, parentObject) => { // 省略幾何圖形和位置 if (parentObject is IIfcProduct && (property.PropertyInfo.Name == nameof(IIfcProduct.Representation) || property.PropertyInfo.Name == nameof(IIfcProduct.ObjectPlacement))) return null; // 省略映射的幾何圖形 if (parentObject is IIfcTypeProduct && property.PropertyInfo.Name == nameof(IIfcTypeProduct.RepresentationMaps)) return null; // 僅經過反向關係(它將接管全部屬性和類型)實現 isDefinedby 和 istypedby if (property.EntityAttribute.Order < 0 && !( property.PropertyInfo.Name == nameof(IIfcProduct.IsDefinedBy) || property.PropertyInfo.Name == nameof(IIfcProduct.IsTypedBy) )) return null; return property.PropertyInfo.GetValue(parentObject, null); }; using (var model = IfcStore.Open(original)) { var walls = model.Instances.OfType<IIfcWall>(); using (var iModel = IfcStore.Create(model.IfcSchemaVersion, XbimStoreType.InMemoryModel)) { using (var txn = iModel.BeginTransaction("Insert copy")) { //兩個模型之間的全部插入都應使用單一圖 var map = new XbimInstanceHandleMap(model, iModel); foreach (var wall in walls) { iModel.InsertCopy(wall, map, semanticFilter, true, false); } txn.Commit(); } iModel.SaveAs(inserted); } } } } }