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); } } } } }