xBIM 插入复制功能
目录
插入复制功能
在IFC 模型中合并和删除实体是一项不重要的任务,因为IFC不是一个分层结构。而是具有潜在循环关系的复杂结构,是一个双向导向。在单个实体上执行这些任务不是问题(STEP21文件中。可以想象成单行)
#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);
正如对所有参数的简要描述一样:
- toCopy: 要复制的实体
- mappings: 以前插入的映射。对于两个模型之间的所有插入, 应该始终只有一个实例。
- propTransform: 可选的委托, 您可以使用它来筛选将在复制之前获得 coppied 或转换它的内容。这是非常棒的一个功能。
- includeInverses: 选项引入所有反转实体。这是潜在的危险, 因为如果不受 propTransform 委托的限制, 它可能会轻易地带来几乎整个模型。
- keepLabels: 选项以使实体标签保持不变。有时保持标签相同可能会很有用。如果目标模型不是新模型或从多个模型中插入对象, 则永远不要使用此选项。
从所有这些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 反向关系 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); };
PropertyTranformDelegate 采用两个参数, 其中第一个是 ExpressMetaProperty, 另一个是表示 IPersistEntity 的对象。ExpressMetaProperty 是一个缓存的对象, 这是我们自己的反射元模型的一部分, 我们用于某些数据操作。该委托在使用 c# 反射的其他代码中用于检查数据和复制值。如果未指定委托 InsertCopy (), 将使用实体中的所有属性并将其复制过来。
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; 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); } } } } }