public void CopyAllEntitiesTest() { using (var source = new XbimModel()) { PropertyTranformDelegate propTransform = delegate(IfcMetaProperty prop, object toCopy) { var value = prop.PropertyInfo.GetValue(toCopy, null); return(value); }; source.Open("BIM Logo-LetterM.xBIM"); source.SaveAs("WithGeometry.ifc"); using (var target = XbimModel.CreateTemporaryModel()) { target.AutoAddOwnerHistory = false; using (var txn = target.BeginTransaction()) { var copied = new XbimInstanceHandleMap(source, target); foreach (var item in source.Instances) { target.InsertCopy(item, copied, txn, propTransform); } txn.Commit(); } target.SaveAs("WithoutGeometry.ifc"); } source.Close(); //the two files should be the same } }
/// <summary> /// Inserts deep copy of an object into this model. The entity must originate from the same schema (the same EntityFactory). /// This operation happens within a transaction which you have to handle yourself unless you set the parameter "noTransaction" to true. /// Insert will happen outside of transactional behaviour in that case. Resulting model is not guaranteed to be valid according to any /// model view definition. However, it is granted to be consistent. You can optionally bring in all inverse relationships. Be careful as it /// might easily bring in almost full model. /// /// </summary> /// <typeparam name="T">Type of the copied entity</typeparam> /// <param name="toCopy">Entity to be copied</param> /// <param name="mappings">Mappings of previous inserts</param> /// <param name="includeInverses">Option if to bring in all inverse entities (enumerations in original entity)</param> /// <param name="keepLabels">Option if to keep entity labels the same</param> /// <param name="propTransform">Optional delegate which you can use to filter the content which will get copied over.</param> /// <param name="noTransaction">If TRUE all operations inside this function will happen out of transaction. /// Also no notifications will be fired from objects.</param> /// <returns>Copy from this model</returns> public T InsertCopy <T>(T toCopy, XbimInstanceHandleMap mappings, PropertyTranformDelegate propTransform, bool includeInverses, bool keepLabels, bool noTransaction) where T : IPersistEntity { if (noTransaction) { IsTransactional = false; } T result; try { result = ModelHelper.InsertCopy(this, toCopy, mappings, propTransform, includeInverses, keepLabels, (type, i) => _instances.New(type, i)); } catch { throw; } finally { //make sure model is transactional at the end again IsTransactional = true; } return(result); }
public void CopyWallsOver() { const string original = "SampleHouse.ifc"; const string inserted = "SampleHouseWalls.ifc"; PropertyTranformDelegate semanticFilter = (property, parentObject) => { //leave out geometry and placement if (parentObject is IIfcProduct && (property.PropertyInfo.Name == "Representation" || // nameof() removed to allow for VS2013 compatibility property.PropertyInfo.Name == "ObjectPlacement")) // nameof() removed to allow for VS2013 compatibility { return(null); } //leave out mapped geometry if (parentObject is IIfcTypeProduct && property.PropertyInfo.Name == "RepresentationMaps") // nameof() removed to allow for VS2013 compatibility { return(null); } //only bring over IsDefinedBy and IsTypedBy inverse relationships which will take over all properties and types if (property.EntityAttribute.Order < 0 && !( property.PropertyInfo.Name == "IsDefinedBy" || // nameof() removed to allow for VS2013 compatibility property.PropertyInfo.Name == "IsTypedBy" // nameof() removed to allow for VS2013 compatibility )) { 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(((IModel)model).SchemaVersion, XbimStoreType.InMemoryModel)) { using (var txn = iModel.BeginTransaction("Insert copy")) { //single map should be used for all insertions between two models var map = new XbimInstanceHandleMap(model, iModel); foreach (var wall in walls) { iModel.InsertCopy(wall, map, semanticFilter, true, false); } txn.Commit(); } iModel.SaveAs(inserted); } } }
public void CopyWallsOver() { const string original = "4walls1floorSite.ifc"; const string inserted = "..\\..\\Inserted.ifc"; PropertyTranformDelegate semanticFilter = (property, parentObject) => { //leave out geometry and placement if ((property.PropertyInfo.Name == "Representation" || property.PropertyInfo.Name == "ObjectPlacement") && parentObject is IfcProduct) { return(null); } //only bring over IsDefinedBy and IsTypedBy inverse relationships if (property.EntityAttribute.Order < 0 && !( property.PropertyInfo.Name == "IsDefinedBy" || property.PropertyInfo.Name == "IsTypedBy" )) { return(null); } return(property.PropertyInfo.GetValue(parentObject, null)); }; using (var model = new IO.Memory.MemoryModel(new EntityFactory())) { var errs = model.LoadStep21(original); Assert.AreEqual(0, errs); var wall = model.Instances.FirstOrDefault <IfcWall>(); using (var iModel = new IO.Memory.MemoryModel(new EntityFactory())) { using (var txn = iModel.BeginTransaction("Insert copy")) { var w = new Stopwatch(); w.Start(); iModel.InsertCopy(wall, new XbimInstanceHandleMap(model, iModel), null, true, true); txn.Commit(); w.Stop(); var iWalls = iModel.Instances.OfType <IfcWall>().ToList(); Debug.WriteLine("Time to insert {0} walls (Overall {1} entities): {2}ms", iWalls.Count, iModel.Instances.Count, w.ElapsedMilliseconds); Assert.IsTrue(iWalls.Count >= 1); using (var fileStream = new StreamWriter(inserted)) { iModel.SaveAsStep21(fileStream); } } } } CompareEntityLines(inserted, original); }
public void ExtractIfcGeometryEntitiesTest() { using (var source = new XbimModel()) { PropertyTranformDelegate propTransform = delegate(IfcMetaProperty prop, object toCopy) { if (typeof(IfcProduct).IsAssignableFrom(toCopy.GetType())) { if (prop.PropertyInfo.Name == "ObjectPlacement" || prop.PropertyInfo.Name == "Representation") { return(null); } } if (typeof(IfcTypeProduct).IsAssignableFrom(toCopy.GetType())) { if (prop.PropertyInfo.Name == "RepresentationMaps") { return(null); } } return(prop.PropertyInfo.GetValue(toCopy, null));//just pass through the value }; //source.Open("BIM Logo-LetterM.xBIM"); //source.SaveAs("WithGeometry.ifc"); string modelName = @"4walls1floorSite"; string xbimModelName = Path.ChangeExtension(modelName, "xbim"); source.CreateFrom(Path.ChangeExtension(modelName, "ifc"), null, null, true); using (var target = XbimModel.CreateModel(Path.ChangeExtension(modelName + "_NoGeom", "xbim"))) { target.AutoAddOwnerHistory = false; using (var txn = target.BeginTransaction()) { var copied = new XbimInstanceHandleMap(source, target); foreach (var item in source.Instances.OfType <IfcRoot>()) { target.InsertCopy(item, copied, txn, propTransform, false); } txn.Commit(); } target.SaveAs(Path.ChangeExtension(modelName + "_NoGeom", "ifc")); target.Close(); } source.Close(); // XbimModel.Compact(Path.ChangeExtension(modelName + "_NoGeom", "xbim"), Path.ChangeExtension(modelName + "_NoGeom_Compacted", "xbim")); //the two files should be the same } }
public void MergeProductsTest() { const string model1File = "TestSourceFiles\\4walls1floorSite.ifc"; const string copyFile = "copy.ifc"; const string model2File = "TestSourceFiles\\House.ifc"; var newModel = new MemoryModel(new Ifc2x3.EntityFactoryIfc2x3()); using (var model1 = MemoryModel.OpenRead(model1File)) { PropertyTranformDelegate propTransform = delegate(ExpressMetaProperty prop, object toCopy) { var value = prop.PropertyInfo.GetValue(toCopy, null); return(value); }; using (var model2 = MemoryModel.OpenRead(model2File)) { var rencontre = false; using (var txn = newModel.BeginTransaction("test")) { var copied = new XbimInstanceHandleMap(model1, newModel); foreach (var item in model1.Instances.OfType <IfcProduct>()) { newModel.InsertCopy(item, copied, propTransform, false, false); } copied = new XbimInstanceHandleMap(model2, newModel); foreach (var item in model2.Instances.OfType <IfcProduct>()) { var buildingElement = item as IfcBuildingElement; if (model1.Instances.OfType <IfcBuildingElement>() .Any(item1 => buildingElement != null && buildingElement.GlobalId == item1.GlobalId)) { rencontre = true; } if (!rencontre) { newModel.InsertCopy(item, copied, propTransform, false, false); } } txn.Commit(); } using (var file = File.Create(copyFile)) { newModel.SaveAsStep21(file); file.Close(); } } } }
public void MergeProductsTest() { const string model1File = "4walls1floorSite.ifc"; const string copyFile = "copy.ifc"; const string model2File = "House.ifc"; var newModel = IfcStore.Create(IfcSchemaVersion.Ifc2X3, XbimStoreType.InMemoryModel); using (var model1 = IfcStore.Open(model1File)) { PropertyTranformDelegate propTransform = delegate(ExpressMetaProperty prop, object toCopy) { var value = prop.PropertyInfo.GetValue(toCopy, null); return(value); }; using (var model2 = IfcStore.Open(model2File)) { var rencontre = false; using (var txn = newModel.BeginTransaction()) { var copied = new XbimInstanceHandleMap(model1, newModel); foreach (var item in model1.Instances.OfType <IfcProduct>()) { newModel.InsertCopy(item, copied, propTransform, false, false); } copied = new XbimInstanceHandleMap(model2, newModel); foreach (var item in model2.Instances.OfType <IfcProduct>()) { var buildingElement = item as IfcBuildingElement; if (model1.Instances.OfType <IfcBuildingElement>() .Any(item1 => buildingElement != null && buildingElement.GlobalId == item1.GlobalId)) { rencontre = true; } if (!rencontre) { newModel.InsertCopy(item, copied, propTransform, false, false); } } txn.Commit(); } newModel.SaveAs(copyFile); } newModel.Close(); } }
public void CopyAllEntitiesTest() { const string sourceFile = "TestSourceFiles\\4walls1floorSite.ifc"; var copyFile = "copy.ifc"; using (var source = MemoryModel.OpenRead(sourceFile)) { PropertyTranformDelegate propTransform = delegate(ExpressMetaProperty prop, object toCopy) { var value = prop.PropertyInfo.GetValue(toCopy, null); return(value); }; using (var target = new MemoryModel(new Ifc2x3.EntityFactoryIfc2x3())) { using (var txn = target.BeginTransaction("Inserting copies")) { target.Header.FileDescription = source.Header.FileDescription; target.Header.FileName = source.Header.FileName; target.Header.FileSchema = source.Header.FileSchema; var map = new XbimInstanceHandleMap(source, target); foreach (var item in source.Instances) { target.InsertCopy(item, map, propTransform, true, true); } txn.Commit(); } using (var outFile = File.Create(copyFile)) { target.SaveAsStep21(outFile); outFile.Close(); } } //the two files should be the same FileCompare(sourceFile, copyFile); } }
public void CopyAllEntitiesTest() { var sourceFile = "source.ifc"; var copyFile = "copy.ifc"; using (var source = new Ifc2x3.IO.XbimModel()) { PropertyTranformDelegate propTransform = delegate(ExpressMetaProperty prop, object toCopy) { var value = prop.PropertyInfo.GetValue(toCopy, null); return(value); }; //source.CreateFrom(@"C:\Users\Steve\Downloads\Test Models\crash\NBS_LakesideRestaurant_EcoBuild2015_Revit2014_.ifc","source.xbim",null,true); //source.CreateFrom(@"C:\Users\Steve\Downloads\Test Models\Wall with complex openings.ifc", "source.xbim",null,true); source.Open("BIM Logo-LetterM.xBIM"); source.SaveAs(sourceFile); using (var target = Ifc2x3.IO.XbimModel.CreateTemporaryModel()) { target.AutoAddOwnerHistory = false; using (var txn = target.BeginTransaction()) { target.Header = source.Header; var copied = new XbimInstanceHandleMap(source, target); foreach (var item in source.Instances) { target.InsertCopy(item, copied, txn, propTransform, true); } txn.Commit(); } target.SaveAs(copyFile); } source.Close(); //the two files should be the same FileCompare(sourceFile, copyFile); } }
/// <summary> /// Inserts deep copy of an object into this model. The entity must originate from the same schema (the same EntityFactory). /// This operation happens within a transaction which you have to handle yourself unless you set the parameter "noTransaction" to true. /// Insert will happen outside of transactional behaviour in that case. Resulting model is not guaranteed to be valid according to any /// model view definition. However, it is granted to be consistent. You can optionaly bring in all inverse relationships. Be carefull as it /// might easily bring in almost full model. /// /// </summary> /// <typeparam name="T">Type of the copied entity</typeparam> /// <param name="model">Model to be used as a target</param> /// <param name="toCopy">Entity to be copied</param> /// <param name="mappings">Mappings of previous inserts</param> /// <param name="includeInverses">Option if to bring in all inverse entities (enumerations in original entity)</param> /// <param name="keepLabels">Option if to keep entity labels the same</param> /// <param name="propTransform">Optional delegate which you can use to filter the content which will get coppied over.</param> /// <param name="getLabeledEntity">Functor to be used to create entity with specified label</param> /// <returns>Copy from this model</returns> public static T InsertCopy <T>(IModel model, T toCopy, XbimInstanceHandleMap mappings, PropertyTranformDelegate propTransform, bool includeInverses, bool keepLabels, Func <Type, int, IPersistEntity> getLabeledEntity) where T : IPersistEntity { try { var toCopyLabel = toCopy.EntityLabel; XbimInstanceHandle copyHandle; var toCopyHandle = new XbimInstanceHandle(toCopy); //try to get the value if it was created before if (mappings.TryGetValue(toCopyHandle, out copyHandle)) { return((T)copyHandle.GetEntity()); } var expressType = model.Metadata.ExpressType(toCopy); var copy = keepLabels ? getLabeledEntity(toCopy.GetType(), toCopyLabel) : model.Instances.New(toCopy.GetType()); copyHandle = new XbimInstanceHandle(copy); //key is the label in original model mappings.Add(toCopyHandle, copyHandle); var props = expressType.Properties.Values.Where(p => !p.EntityAttribute.IsDerived); if (includeInverses) { props = props.Union(expressType.Inverses); } foreach (var prop in props) { var value = propTransform != null ? propTransform(prop, toCopy) : prop.PropertyInfo.GetValue(toCopy, null); if (value == null) { continue; } var isInverse = (prop.EntityAttribute.Order == -1); //don't try and set the values for inverses var theType = value.GetType(); //if it is an express type or a value type, set the value if (theType.GetTypeInfo().IsValueType || typeof(ExpressType).GetTypeInfo().IsAssignableFrom(theType) || theType == typeof(string)) { prop.PropertyInfo.SetValue(copy, value, null); } else if (!isInverse && typeof(IPersistEntity).GetTypeInfo().IsAssignableFrom(theType)) { prop.PropertyInfo.SetValue(copy, InsertCopy(model, (IPersistEntity)value, mappings, propTransform, includeInverses, keepLabels, getLabeledEntity), null); } else if (!isInverse && typeof(IList).GetTypeInfo().IsAssignableFrom(theType)) { var itemType = theType.GetItemTypeFromGenericType(); var copyColl = prop.PropertyInfo.GetValue(copy, null) as IList; if (copyColl == null) { throw new Exception(string.Format("Unexpected collection type ({0}) found", itemType.Name)); } foreach (var item in (IList)value) { var actualItemType = item.GetType(); if (actualItemType.GetTypeInfo().IsValueType || typeof(ExpressType).GetTypeInfo().IsAssignableFrom(actualItemType)) { copyColl.Add(item); } else if (typeof(IPersistEntity).GetTypeInfo().IsAssignableFrom(actualItemType)) { var cpy = InsertCopy(model, (IPersistEntity)item, mappings, propTransform, includeInverses, keepLabels, getLabeledEntity); copyColl.Add(cpy); } else if (typeof(IList).GetTypeInfo().IsAssignableFrom(actualItemType)) //list of lists { var listColl = (IList)item; var getAt = copyColl.GetType().GetTypeInfo().GetMethod("GetAt"); if (getAt == null) { throw new Exception(string.Format("GetAt Method not found on ({0}) found", copyColl.GetType().Name)); } var copyListColl = getAt.Invoke(copyColl, new object[] { copyColl.Count }) as IList; if (copyListColl == null) { throw new XbimException("Collection can't be used as IList"); } foreach (var listItem in listColl) { var actualListItemType = listItem.GetType(); if (actualListItemType.GetTypeInfo().IsValueType || typeof(ExpressType).GetTypeInfo().IsAssignableFrom(actualListItemType)) { copyListColl.Add(listItem); } else if (typeof(IPersistEntity).GetTypeInfo().IsAssignableFrom(actualListItemType)) { var cpy = InsertCopy(model, (IPersistEntity)listItem, mappings, propTransform, includeInverses, keepLabels, getLabeledEntity); copyListColl.Add(cpy); } else { throw new Exception(string.Format("Unexpected collection item type ({0}) found", itemType.Name)); } } } else { throw new Exception(string.Format("Unexpected collection item type ({0}) found", itemType.Name)); } } } else if (isInverse && value is IEnumerable <IPersistEntity> ) //just an enumeration of IPersistEntity { foreach (var ent in (IEnumerable <IPersistEntity>)value) { InsertCopy(model, ent, mappings, propTransform, includeInverses, keepLabels, getLabeledEntity); } } else if (isInverse && value is IPersistEntity) //it is an inverse and has a single value { InsertCopy(model, (IPersistEntity)value, mappings, propTransform, includeInverses, keepLabels, getLabeledEntity); } else { throw new Exception(string.Format("Unexpected item type ({0}) found", theType.Name)); } } return((T)copy); } catch (Exception e) { throw new XbimException(string.Format("General failure in InsertCopy ({0})", e.Message), e); } }
public T InsertCopy <T>(T toCopy, XbimInstanceHandleMap mappings, PropertyTranformDelegate propTransform, bool includeInverses, bool keepLabels) where T : IPersistEntity { return(_model.InsertCopy(toCopy, mappings, propTransform, includeInverses, keepLabels)); }
/// <summary> /// Implementation of IModel variant of InsertCopy() function /// </summary> /// <typeparam name="T">Type of the object to be inserted. This must be a type supported by this model</typeparam> /// <param name="toCopy">Object to copy</param> /// <param name="mappings">Mappings make sure object is only inserted once. You should use one instance of mappings for all InsertCopy() calls between two models</param> /// <param name="propTransform">Delegate which can be used to transform properties. You can use this to filter out certain properties or referenced objects</param> /// <param name="includeInverses">If TRUE interse relations are also copied over. This may potentially bring over almost entire model if not controlled by propTransform delegate</param> /// <param name="keepLabels">If TRUE entity labels of inserted objects will be the same as the labels of original objects. This should be FALSE if you are inserting objects to existing model /// or if you are inserting objects from multiple source models into a single target model where entity labels may potentially clash.</param> /// <returns>New created object in this model which is a deep copy of original object</returns> public T InsertCopy <T>(T toCopy, XbimInstanceHandleMap mappings, PropertyTranformDelegate propTransform, bool includeInverses, bool keepLabels) where T : IPersistEntity { var txn = CurrentTransaction as XbimReadWriteTransaction; return(Cache.InsertCopy(toCopy, mappings, txn, includeInverses, propTransform, keepLabels)); }
public T InsertCopy <T>(T toCopy, XbimInstanceHandleMap mappings, XbimReadWriteTransaction txn, PropertyTranformDelegate propTransform, bool includeInverses = false) where T : IPersistEntity { return(Cache.InsertCopy(toCopy, mappings, txn, includeInverses, propTransform)); }
/// <summary> /// Writes the Input to an IFC file /// /// The Input can be one model /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button_Click(object sender, RoutedEventArgs e) { if (InputPorts[0].Data != null) { PropertyTranformDelegate semanticFilterIFC2x3 = (property, parentObject) => { return(property.PropertyInfo.GetValue(parentObject, null)); }; PropertyTranformDelegate semanticFilterIFC4 = (property, parentObject) => { return(property.PropertyInfo.GetValue(parentObject, null)); }; var newModelIfc2x3 = IfcStore.Create(IfcSchemaVersion.Ifc2X3, XbimStoreType.InMemoryModel); var newModelIfc4 = IfcStore.Create(IfcSchemaVersion.Ifc4, XbimStoreType.InMemoryModel); IfcSchemaVersion ifcVersion = IfcSchemaVersion.Unsupported; // Check the IFC Version IfcVersionType = InputPorts[0].Data.GetType(); if (IfcVersionType.Name == "ModelInfoIFC2x3") { var modelid = ((ModelInfoIFC2x3)(InputPorts[0].Data)).ModelId; var elementIdsList = ((ModelInfoIFC2x3)(InputPorts[0].Data)).ElementIds; var res = new HashSet <Xbim.Ifc2x3.UtilityResource.IfcGloballyUniqueId>(elementIdsList); xModel = DataController.Instance.GetModel(modelid); ifcVersion = xModel.IfcSchemaVersion; List <Xbim.Ifc2x3.Kernel.IfcProduct> elements = xModel.Instances.OfType <Xbim.Ifc2x3.Kernel.IfcProduct>().ToList(); using (var txn = newModelIfc2x3.BeginTransaction()) { var copied = new XbimInstanceHandleMap(xModel, newModelIfc2x3); foreach (var element in elements) { if (res.Contains(element.GlobalId)) { newModelIfc2x3.InsertCopy(element, copied, semanticFilterIFC2x3, false, false); } } txn.Commit(); } } else if (IfcVersionType.Name == "ModelInfoIFC4") { var modelid = ((ModelInfoIFC4)(InputPorts[0].Data)).ModelId; var elementIdsList = ((ModelInfoIFC4)(InputPorts[0].Data)).ElementIds; var res = new HashSet <Xbim.Ifc4.UtilityResource.IfcGloballyUniqueId>(elementIdsList); xModel = DataController.Instance.GetModel(modelid); ifcVersion = xModel.IfcSchemaVersion; List <Xbim.Ifc4.Kernel.IfcProduct> elements = xModel.Instances.OfType <Xbim.Ifc4.Kernel.IfcProduct>().ToList(); using (var txn = newModelIfc4.BeginTransaction()) { var copied = new XbimInstanceHandleMap(xModel, newModelIfc4); foreach (var element in elements) { if (res.Contains(element.GlobalId)) { newModelIfc4.InsertCopy(element, copied, semanticFilterIFC4, false, false); } } txn.Commit(); } } // Write the new IFC file to the selected Path SaveFileDialog saveFileDialog1 = new SaveFileDialog(); saveFileDialog1.Filter = "IfcFile |*.ifc"; saveFileDialog1.Title = "Save an IFC File"; saveFileDialog1.ShowDialog(); if (saveFileDialog1.FileName != "") { if (ifcVersion == IfcSchemaVersion.Ifc2X3) { newModelIfc2x3.SaveAs(saveFileDialog1.FileName); newModelIfc2x3.Close(); if (File.Exists(saveFileDialog1.FileName)) { MessageBox.Show("File saved", "My Application", MessageBoxButton.OK); } else { MessageBox.Show("There was an Error \n Please Try again", "My Application", MessageBoxButton.OK); } } else if (ifcVersion == IfcSchemaVersion.Ifc4) { newModelIfc4.SaveAs(saveFileDialog1.FileName); newModelIfc4.Close(); if (File.Exists(saveFileDialog1.FileName)) { MessageBox.Show("File saved", "My Application", MessageBoxButton.OK); } else { MessageBox.Show("There was an Error \n Please Try again", "My Application", MessageBoxButton.OK); } } } } else { MessageBox.Show("Please Connect a Model", "My Application", MessageBoxButton.OK); } }
/// <summary> /// Merge two IFC files with the same IFC Version to a new IFC File. /// </summary> public override void Calculate() { if (InputPorts[0].Data == null) { return; } if (InputPorts[1].Data == null) { return; } // Check for same IFC Version IfcVersionTypeModel1 = InputPorts[0].Data.GetType(); IfcVersionTypeModel2 = InputPorts[1].Data.GetType(); if (IfcVersionTypeModel1 != IfcVersionTypeModel2) { MessageBox.Show("The IFC Versions are not the same!", "My Application", MessageBoxButton.OK); return; } PropertyTranformDelegate propTransform = delegate(ExpressMetaProperty prop, object toCopy) { var value = prop.PropertyInfo.GetValue(toCopy, null); return(value); }; // Important for new IFC File var newModelIfc2x3 = IfcStore.Create(IfcSchemaVersion.Ifc2X3, XbimStoreType.InMemoryModel); var newModelIfc4 = IfcStore.Create(IfcSchemaVersion.Ifc4, XbimStoreType.InMemoryModel); var txnIfc2x3 = newModelIfc2x3.BeginTransaction(); var txnIfc4 = newModelIfc4.BeginTransaction(); // List of elements - Important, that no element exist twice in the new file HashSet <Xbim.Ifc2x3.UtilityResource.IfcGloballyUniqueId> buildingElementsIFC2x3 = new HashSet <Xbim.Ifc2x3.UtilityResource.IfcGloballyUniqueId>(); HashSet <Xbim.Ifc4.UtilityResource.IfcGloballyUniqueId> buildingElementsIFC4 = new HashSet <Xbim.Ifc4.UtilityResource.IfcGloballyUniqueId>(); IfcSchemaVersion ifcVersion = IfcSchemaVersion.Unsupported; XbimInstanceHandleMap copied = null; var label1 = ControlElements[1] as Label; label1.Content = ""; // Loop over both IFC files for (var i = 0; i < 2; i++) { if (IfcVersionTypeModel1.Name == "ModelInfoIFC2x3") { var modelid = ((ModelInfoIFC2x3)(InputPorts[i].Data)).ModelId; var res = new HashSet <Xbim.Ifc2x3.UtilityResource.IfcGloballyUniqueId>(); var elementIdsList = ((ModelInfoIFC2x3)(InputPorts[i].Data)).ElementIds; foreach (var elementID in elementIdsList) { res.Add(elementID); } var xModel = DataController.Instance.GetModel(modelid); ifcVersion = xModel.IfcSchemaVersion; List <Xbim.Ifc2x3.Kernel.IfcProduct> elements = xModel.Instances.OfType <Xbim.Ifc2x3.Kernel.IfcProduct>().ToList(); copied = new XbimInstanceHandleMap(xModel, newModelIfc2x3); foreach (var element in elements) { if (res.Contains(element.GlobalId) && !buildingElementsIFC2x3.Contains(element.GlobalId)) { newModelIfc2x3.InsertCopy(element, copied, propTransform, false, false); buildingElementsIFC2x3.Add(element.GlobalId); } } } else if (IfcVersionTypeModel1.Name == "ModelInfoIFC4") { var modelid = ((ModelInfoIFC4)(InputPorts[i].Data)).ModelId; var elementIdsList = ((ModelInfoIFC4)(InputPorts[i].Data)).ElementIds; var res = new HashSet <Xbim.Ifc4.UtilityResource.IfcGloballyUniqueId>(elementIdsList); var xModel = DataController.Instance.GetModel(modelid); ifcVersion = xModel.IfcSchemaVersion; List <Xbim.Ifc4.Kernel.IfcProduct> elements = xModel.Instances.OfType <Xbim.Ifc4.Kernel.IfcProduct>().ToList(); copied = new XbimInstanceHandleMap(xModel, newModelIfc4); foreach (var element in elements) { if (res.Contains(element.GlobalId) && !buildingElementsIFC4.Contains(element.GlobalId)) { newModelIfc4.InsertCopy(element, copied, propTransform, false, false); buildingElementsIFC4.Add(element.GlobalId); } } } } // Safe new IFC File Random zufall = new Random(); int number = zufall.Next(1, 1000); string result = Path.GetTempPath(); string copyFile = result + "copy" + number + ".ifc"; while (File.Exists(copyFile)) { number = zufall.Next(1, 1000); copyFile = result + "copy" + number + ".ifc"; } if (ifcVersion == IfcSchemaVersion.Ifc2X3) { txnIfc2x3.Commit(); newModelIfc2x3.SaveAs(copyFile); newModelIfc2x3.Close(); ModelInfoIFC2x3 modelInfo = new ModelInfoIFC2x3(copyFile); foreach (var id in buildingElementsIFC2x3) { modelInfo.AddElementIds(id); } OutputIfc2x3 = modelInfo; var xModel = IfcStore.Open(copyFile); DataController.Instance.AddModel(copyFile, xModel); xModel.Close(); } else if (ifcVersion == IfcSchemaVersion.Ifc4) { txnIfc4.Commit(); newModelIfc4.SaveAs(copyFile); newModelIfc4.Close(); ModelInfoIFC4 modelInfo = new ModelInfoIFC4(copyFile); foreach (var id in buildingElementsIFC4) { modelInfo.AddElementIds(id); } OutputIfc4 = modelInfo; var xModel = IfcStore.Open(copyFile); DataController.Instance.AddModel(copyFile, xModel); xModel.Close(); } if (IfcVersionTypeModel1.Name == "ModelInfoIFC2x3") { label1.Content = "Merge Complete!"; OutputPorts[0].Data = OutputIfc2x3; } else if (IfcVersionTypeModel1.Name == "ModelInfoIFC4") { label1.Content = "Merge Complete!"; OutputPorts[0].Data = OutputIfc4; } }