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
            }
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        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);
                }
            }
        }
Beispiel #4
0
        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();
                    }
                }
            }
        }
Beispiel #7
0
        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);
            }
        }
Beispiel #9
0
        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);
            }
        }
Beispiel #11
0
 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));
 }
Beispiel #12
0
        /// <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));
        }
Beispiel #13
0
 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;
            }
        }