示例#1
0
        /// <summary>
        /// Get the file to roles information
        /// </summary>
        /// <returns>Dictionary or FileInfo to RoleFilter</returns>
        private Dictionary <XbimModel, RoleFilter> GetFileRoles()
        {
            Dictionary <XbimModel, RoleFilter> modelRoles = new Dictionary <XbimModel, RoleFilter>();

            foreach (var refModel in _fedModel.ReferencedModels)
            {
                IfcDocumentInformation doc   = refModel.DocumentInformation;
                IfcOrganization        owner = doc.DocumentOwner as IfcOrganization;
                if ((owner != null) && (owner.Roles != null))
                {
                    RoleFilter docRoles = GetRoleFilters(owner.Roles.ToList());
                    try
                    {
                        FileInfo file = new FileInfo(refModel.Model.DatabaseName);
                        if (file.Exists)
                        {
                            modelRoles[refModel.Model] = docRoles;
                        }
                        else
                        {
                            MessageBox.Show("File path does not exist: {0}", doc.Name);
                        }
                    }
                    catch (System.ArgumentException)
                    {
                        MessageBox.Show("File path is incorrect: {0}", doc.Name);
                    }
                }
            }
            return(modelRoles);
        }
示例#2
0
        public override void Parse(int propIndex, IPropertyValue value, int[] nestedIndex)
        {
            switch (propIndex)
            {
            case 0:
            case 1:
                base.Parse(propIndex, value, nestedIndex);
                return;

            case 2:
                _relatingDocument = (IfcDocumentInformation)(value.EntityVal);
                return;

            case 3:
                _relatedDocuments.InternalAdd((IfcDocumentInformation)value.EntityVal);
                return;

            case 4:
                _relationshipType = value.StringVal;
                return;

            default:
                throw new XbimParserException(string.Format("Attribute index {0} is out of range for {1}", propIndex + 1, GetType().Name.ToUpper()));
            }
        }
示例#3
0
        /// <summary>
        /// Add the refrence models
        /// </summary>
        /// <param name="file">FileInfo for the xbimf file</param>
        /// <param name="organizationName">Organisation Name</param>
        /// <param name="role">RoleFilter</param>
        /// <param name="displayName"></param>
        public void AddRefModel(FileInfo file, string organizationName, RoleFilter roles = RoleFilter.Unknown, string displayName = null)
        {
            if (!file.Exists)
            {
                throw new FileNotFoundException("Cannot find reference model file", file.FullName);
            }

            //add model to list of referenced models
            IfcIdentifier docId = _fedModel.AddModelReference(file.FullName, organizationName, IfcRole.UserDefined).Identifier;

            using (var txn = _fedModel.BeginTransaction())
            {
                IfcDocumentInformation addDocId = _fedModel.ReferencedModels.Where(item => item.DocumentInformation.DocumentId == docId).Select(item => item.DocumentInformation).FirstOrDefault();
                IfcOrganization        org      = addDocId.DocumentOwner as IfcOrganization;
                if (org != null)
                {
                    org.Roles.Clear();
                    //Add Roles
                    foreach (var item in GetActorRoles(roles))
                    {
                        org.AddRole(item);
                    }
                }
                //add display name if required
                if (displayName != null)
                {
                    addDocId.Description = displayName;
                }
                txn.Commit();
            }
        }
示例#4
0
        /// <summary>
        /// Get merge roles for federated models, used to work out Model Merge Precedence Rules
        /// </summary>
        private Dictionary <XbimModel, COBieMergeRoles> LinkRoleToModel()
        {
            Dictionary <IfcRole, COBieMergeRoles>   mapMergeRoles        = MapRolesForMerge();//assign merge role to a IfcRoleEnum value
            Dictionary <XbimModel, COBieMergeRoles> mapModelToMergeRoles = new Dictionary <XbimModel, COBieMergeRoles>();

            //mapModelToMergeRoles.Add(Model, COBieMergeRoles.Unknown); //assume that it is just the holder model(xBIMf) (as xbim is creating holding file .xbimf) for and all the models are in the Model.RefencedModels property

            //now get the referenced models
            foreach (var refModel in Model.ReferencedModels)
            {
                IfcDocumentInformation doc   = refModel.DocumentInformation;
                IfcOrganization        owner = doc.DocumentOwner as IfcOrganization;
                if ((owner != null) && (owner.Roles != null))
                {
                    COBieMergeRoles mergeRoles = COBieMergeRoles.Unknown;

                    foreach (var role in owner.Roles)
                    {
                        IfcRole roleitem = role.Role;

                        if (mapMergeRoles[roleitem] != COBieMergeRoles.Unknown)
                        {
                            mergeRoles = mergeRoles | mapMergeRoles[roleitem]; //use in if's ((mergeRoles & COBieMergeRoles.Architectural) == COBieMergeRoles.Architectural)
                            //remove the unknown as we now have at least one value
                            if ((mergeRoles & COBieMergeRoles.Unknown) == COBieMergeRoles.Unknown)
                            {
                                mergeRoles = mergeRoles ^ COBieMergeRoles.Unknown;
                            }
                        }
                    }
                    mapModelToMergeRoles.Add(refModel.Model, mergeRoles);
                }
            }
            return(mapModelToMergeRoles);
        }
示例#5
0
 /// <summary>
 /// Add the document references to the IfcDocumentInformation object
 /// </summary>
 /// <param name="row">COBieDocumentRow holding row data</param>
 /// <param name="ifcDocumentInformation">IfcDocumentInformation object to add references too</param>
 private void AddDocumentReference(COBieDocumentRow row, IfcDocumentInformation ifcDocumentInformation)
 {
     if (ValidateString(row.File))
     {
         //get locations, assume we have the same number of locations and document names
         List <string> strLocationValues = null;
         if (ValidateString(row.Directory))
         {
             strLocationValues = SplitString(row.Directory, ':');
         }
         List <string> strNameValues = SplitString(row.File, ':');
         //see if we have a location match to every document name
         if ((strLocationValues != null) && (strNameValues.Count != strLocationValues.Count))
         {
             strLocationValues = null; //cannot match locations to document so just supply document names
         }
         //create the Document References
         if (strNameValues.Count > 0)
         {
             int i = 0;
             foreach (var name in strNameValues)
             {
                 var docref = Model.Instances.New <IfcDocumentReference>();
                 docref.Name = new IfcLabel(name);
                 if (strLocationValues != null)
                 {
                     docref.Location = strLocationValues[i];
                 }
                 ifcDocumentInformation.DocumentReferences.Add(docref);
                 i++;
             }
         }
     }
 }
示例#6
0
 /// <summary>
 /// Add the document references to the IfcDocumentInformation object
 /// </summary>
 /// <param name="row">COBieDocumentRow holding row data</param>
 /// <param name="ifcDocumentInformation">IfcDocumentInformation object to add references too</param>
 private void AddDocumentReference(COBieDocumentRow row, IfcDocumentInformation ifcDocumentInformation)
 {
     if (ValidateString(row.File))
     {
         //get locations, assume we have the same number of locations and document names
         List <string> strLocationValues = null;
         if (ValidateString(row.Directory))
         {
             strLocationValues = SplitString(row.Directory, ':');
         }
         List <string> strNameValues = SplitString(row.File, ':');
         //see if we have a location match to every document name
         if ((strLocationValues != null) && (strNameValues.Count != strLocationValues.Count))
         {
             strLocationValues = null; //cannot match locations to document so just supply document names
         }
         //create the Document References
         if (strNameValues.Count > 0)
         {
             IfcDocumentReference[] ifcDocumentReferences = new IfcDocumentReference[strNameValues.Count];
             int i = 0;
             foreach (string name in strNameValues)
             {
                 ifcDocumentReferences[i] = Model.Instances.New <IfcDocumentReference>(dr => { dr.Name = name; });
                 if (strLocationValues != null)
                 {
                     ifcDocumentReferences[i].Location = strLocationValues[i];
                 }
                 i++;
             }
             ifcDocumentInformation.SetDocumentReferences(true, ifcDocumentReferences);
         }
     }
 }
 /// <summary>
 /// Missing Inverse method on  IfcDocumentInformation, need to be implemented on IfcDocumentInformation class
 /// </summary>
 /// <param name="ifcDocumentInformation">IfcDocumentInformation object</param>
 /// <returns>IEnumerable of IfcRelAssociatesDocument objects</returns>
 public IEnumerable <IfcRelAssociatesDocument> DocumentInformationForObjects(IfcDocumentInformation ifcDocumentInformation)
 {
     if (ifcRelAssociatesDocuments == null)
     {
         ifcRelAssociatesDocuments = Model.FederatedInstances.OfType <IfcRelAssociatesDocument>().ToList();
     }
     return(ifcRelAssociatesDocuments.Where <IfcRelAssociatesDocument>(irad => (irad.RelatingDocument as IfcDocumentInformation) == ifcDocumentInformation));
 }
 public XbimReferencedModel(IfcDocumentInformation documentInformation)
 {
     DocumentInformation = documentInformation;
     if (!File.Exists(documentInformation.Name))
     {
         throw new XbimException("Reference model not found:" + documentInformation.Name);
     }
     Model = new XbimModel();
     if (!Model.Open(documentInformation.Name, XbimDBAccess.Read))
     {
         throw new XbimException("Unable to open reference model: " + documentInformation.Name);
     }
 }
示例#9
0
        /// <summary>
        /// Get Name from IfcDocumentInformation
        /// </summary>
        /// <param name="ifcDocumentInformation">Document Information Object</param>
        /// <returns>string or null</returns>
        private string GetName(IfcDocumentInformation ifcDocumentInformation)
        {
            if (ifcDocumentInformation == null)
            {
                return(null);
            }

            if (!string.IsNullOrEmpty(ifcDocumentInformation.Name))
            {
                return(ifcDocumentInformation.Name);
            }

            return(null);
        }
示例#10
0
        /// <summary>
        /// Get created by
        /// </summary>
        /// <param name="ifcDocumentInformation"></param>
        /// <returns></returns>
        private ContactKey GetCreatedBy(IfcDocumentInformation ifcDocumentInformation)
        {
            if (ifcDocumentInformation.DocumentOwner != null)
            {
                return(Helper.GetCreatedBy(ifcDocumentInformation.DocumentOwner));
            }

            //get owner from the IfcRelAssociatesDocument object
            if (Helper.DocumentOwnerLookup.ContainsKey(ifcDocumentInformation))
            {
                return(Helper.GetCreatedBy(Helper.DocumentOwnerLookup[ifcDocumentInformation]));
            }
            return(null);
        }
示例#11
0
        /// <summary>
        /// Get createdOn
        /// </summary>
        /// <param name="ifcDocumentInformation"></param>
        /// <returns></returns>
        private DateTime?GetCreatedOn(IfcDocumentInformation ifcDocumentInformation)
        {
            if (ifcDocumentInformation.CreationTime != null)
            {
                var created = ifcDocumentInformation.CreationTime ?? ifcDocumentInformation.LastRevisionTime;
                if (created != null)
                {
                    return(new DateTime(created.DateComponent.YearComponent, created.DateComponent.MonthComponent, created.DateComponent.DayComponent));
                }
            }

            if (Helper.DocumentOwnerLookup.ContainsKey(ifcDocumentInformation))
            {
                return(Helper.GetCreatedOn(Helper.DocumentOwnerLookup[ifcDocumentInformation]));
            }

            return(DateTime.Now);
        }
示例#12
0
        /// <summary>
        /// Get the child documents with drill down into children of child....
        /// </summary>
        /// <param name="ifcDocumentInformation">IfcDocumentInformation</param>
        /// <returns>List of Document</returns>
        private List <Document> GetChildDocs(IfcDocumentInformation ifcDocumentInformation)
        {
            List <Document> childDocList = new List <Document>();
            var             ChildRels    = ifcDocumentInformation.IsPointer.FirstOrDefault();//SET[0:1] gets the relationship when ifcDocumentInformation is the RelatingDocument (parent) document

            if (ChildRels != null && ChildRels.RelatedDocuments != null)
            {
                foreach (IfcDocumentInformation item in ChildRels.RelatedDocuments)
                {
                    if (ChainInstMap == null) //set ChainInstMap, used to avoid infinite loop
                    {
                        ChainInstMap = new HashSet <IfcDocumentInformation>();
                    }

                    if (!ChainInstMap.Contains(item))              //check we have not already evaluated this IfcDocumentInformation
                    {
                        childDocList.AddRange(MappingMulti(item)); //drill down
                    }
                }
            }
            return(childDocList);
        }
示例#13
0
        /// <summary>
        /// Get the file information for the document attached to the ifcRelAssociatesDocument
        /// </summary>
        /// <param name="ifcRelAssociatesDocument">IfcRelAssociatesDocument object</param>
        /// <returns>FileInformation structure </returns>
        private FileInformation GetFileInformation(IfcRelAssociatesDocument ifcRelAssociatesDocument)
        {
            FileInformation DocInfo = new FileInformation()
            {
                Name = DEFAULT_STRING, Location = DEFAULT_STRING
            };
            string value = "";

            if (ifcRelAssociatesDocument != null)
            {
                //test for single document
                IfcDocumentReference ifcDocumentReference = ifcRelAssociatesDocument.RelatingDocument as IfcDocumentReference;
                if (ifcDocumentReference != null)
                {
                    //this is possibly incorrect, think it references information within a document
                    value = ifcDocumentReference.ItemReference.ToString();
                    if (!string.IsNullOrEmpty(value))
                    {
                        DocInfo.Name = value;
                    }
                    value = ifcDocumentReference.Location.ToString();
                    if (!string.IsNullOrEmpty(value))
                    {
                        DocInfo.Location = value;
                    }
                }
                else //test for a document list
                {
                    IfcDocumentInformation ifcDocumentInformation = ifcRelAssociatesDocument.RelatingDocument as IfcDocumentInformation;
                    if (ifcDocumentInformation != null)
                    {
                        IEnumerable <IfcDocumentReference> ifcDocumentReferences = ifcDocumentInformation.DocumentReferences;
                        if (ifcDocumentReferences != null)
                        {
                            List <string> strNameValues     = new List <string>();
                            List <string> strLocationValues = new List <string>();
                            foreach (IfcDocumentReference docRef in ifcDocumentReferences)
                            {
                                //get file name
                                value = docRef.ItemReference.ToString();
                                if (!string.IsNullOrEmpty(value))
                                {
                                    strNameValues.Add(value);
                                }
                                else
                                {
                                    value = docRef.Name.ToString();
                                    if (!string.IsNullOrEmpty(value))
                                    {
                                        strNameValues.Add(value);
                                    }
                                }
                                //get file location
                                value = docRef.Location.ToString();
                                if ((!string.IsNullOrEmpty(value)) && (!strNameValues.Contains(value)))
                                {
                                    strLocationValues.Add(value);
                                }
                            }
                            //set values to return
                            if (strNameValues.Count > 0)
                            {
                                DocInfo.Name = COBieXBim.JoinStrings(':', strNameValues);
                            }
                            if (strLocationValues.Count > 0)
                            {
                                DocInfo.Location = COBieXBim.JoinStrings(':', strLocationValues);
                            }
                        }
                    }
                }
            }
            return(DocInfo);
        }
示例#14
0
        /// <summary>
        /// Convert a IfcDocumentReference to Document
        /// </summary>
        /// <param name="ifcDocumentReference">Document Reference Object</param>
        /// <param name="document">Document Object</param>
        /// <returns>Document</returns>
        private Document ConvertToDocument(IfcDocumentReference ifcDocumentReference, IfcDocumentInformation ifcDocumentInformation)
        {
            string name = GetName(ifcDocumentInformation) ?? GetName(ifcDocumentReference);

            //fail to get from IfcDocumentReference, so try assign a default
            if (string.IsNullOrEmpty(name))
            {
                name = "Document";
            }
            //check for duplicates, if found add a (#) => "DocName(1)", if none return name unchanged
            name = GetNextName(name);

            var document = new Document();

            document.Name      = name;
            document.CreatedBy = ifcDocumentInformation != null?GetCreatedBy(ifcDocumentInformation) : null;

            document.CreatedOn = ifcDocumentInformation != null?GetCreatedOn(ifcDocumentInformation) : null;

            document.Categories = (ifcDocumentInformation != null) && (!string.IsNullOrEmpty(ifcDocumentInformation.Purpose)) ? new List <Category>(new[] { new Category {
                                                                                                                                                                Code = ifcDocumentInformation.Purpose
                                                                                                                                                            } }) : null;

            //ApprovalBy will be reset to a string field as ContactKey field is incorrect but for now fill ContactKey.email
            //document.ApprovalBy = (ifcDocumentInformation != null) && (!string.IsNullOrEmpty(ifcDocumentInformation.IntendedUse)) ? new ContactKey() { Email = ifcDocumentInformation.IntendedUse } : null;
            document.ApprovalBy = (ifcDocumentInformation != null) && (!string.IsNullOrEmpty(ifcDocumentInformation.IntendedUse)) ? ifcDocumentInformation.IntendedUse : null; //once fixed

            document.Stage = (ifcDocumentInformation != null) && (!string.IsNullOrEmpty(ifcDocumentInformation.Scope)) ? ifcDocumentInformation.Scope : null;

            document.Directory = GetFileDirectory(ifcDocumentReference);
            document.File      = GetFileName(ifcDocumentReference);

            document.ExternalSystem = null;
            document.ExternalEntity = ifcDocumentReference.GetType().Name;
            document.ExternalId     = null;

            document.Description = (ifcDocumentInformation != null) && (!string.IsNullOrEmpty(ifcDocumentInformation.Description)) ? ifcDocumentInformation.Description.ToString() : null;
            document.Reference   = (ifcDocumentInformation != null) &&
                                   (ifcDocumentInformation.DocumentId != null) &&
                                   (ifcDocumentInformation.DocumentId.Value != null) &&
                                   (!string.IsNullOrEmpty(ifcDocumentInformation.DocumentId.Value.ToString())) ? ifcDocumentInformation.DocumentId.Value.ToString() : null;
            Helper.DocumentProgress.Add(document);
            return(document);
        }
示例#15
0
        /// <summary>
        /// Add the data to the Document Information object
        /// </summary>
        /// <param name="row">COBieDocumentRow holding the data</param>
        private void AddDocument(COBieDocumentRow row)
        {
            if (CheckIfExistOnMerge(row))
            {
                return; //already in document
            }
            IfcDocumentInformation   ifcDocumentInformation   = Model.Instances.New <IfcDocumentInformation>();
            IfcRelAssociatesDocument ifcRelAssociatesDocument = Model.Instances.New <IfcRelAssociatesDocument>();

            //Add Created By, Created On and ExtSystem to Owner History.
            SetUserHistory(ifcRelAssociatesDocument, row.ExtSystem, row.CreatedBy, row.CreatedOn);

            if (Contacts.ContainsKey(row.CreatedBy))
            {
                ifcDocumentInformation.DocumentOwner = (IfcPersonAndOrganization)Contacts[row.CreatedBy];
            }

            //using statement will set the Model.OwnerHistoryAddObject to IfcConstructionProductResource.OwnerHistory as OwnerHistoryAddObject is used upon any property changes,
            //then swaps the original OwnerHistoryAddObject back in the dispose, so set any properties within the using statement
            using (COBieXBimEditScope context = new COBieXBimEditScope(Model, ifcRelAssociatesDocument.OwnerHistory))
            {
                //create relationship between Document and ifcObjects it relates too
                ifcRelAssociatesDocument.RelatingDocument = ifcDocumentInformation;
                //Add Name
                if (ValidateString(row.Name))
                {
                    ifcDocumentInformation.Name = row.Name;
                }

                //Add Category
                if (ValidateString(row.Category))
                {
                    ifcDocumentInformation.Purpose = row.Category;
                }

                //Add approved By
                if (ValidateString(row.ApprovalBy))
                {
                    ifcDocumentInformation.IntendedUse = row.ApprovalBy;
                }

                //Add Stage
                if (ValidateString(row.Stage))
                {
                    ifcDocumentInformation.Scope = row.Stage;
                }

                //Add GlobalId
                AddGlobalId(row.ExtIdentifier, ifcRelAssociatesDocument);

                //Add Object Relationship
                IfcRoot ifcRoot = GetObjectRelationship(row);
                //add to the document relationship object
                if (ifcRoot != null)
                {
                    ifcRelAssociatesDocument.RelatedObjects.Add(ifcRoot);
                }


                //Add Document reference
                AddDocumentReference(row, ifcDocumentInformation);

                //add Description
                if (ValidateString(row.Description))
                {
                    ifcDocumentInformation.Description = row.Description;
                }

                //Add Reference
                if (ValidateString(row.Reference))
                {
                    ifcDocumentInformation.DocumentId = row.Reference;
                }
                else
                {
                    ifcDocumentInformation.DocumentId = ""; //required field so add blank string
                }
            }
        }
        public override void Run()
        {
            using (var txn = model.BeginTransaction("Example creation"))
            {
                IfcProject        project           = model.Instances.New <IfcProject>(p => p.Name = "TriluxLightingProducts");
                IfcUnitAssignment ifcUnitAssignment = model.Instances.New <IfcUnitAssignment>(ua =>
                {
                    ua.Units.Add(model.Instances.New <IfcSIUnit>(u =>
                    {
                        u.UnitType = Xbim.Ifc4.Interfaces.IfcUnitEnum.LENGTHUNIT;
                        u.Name     = Xbim.Ifc4.Interfaces.IfcSIUnitName.METRE;
                        u.Prefix   = Xbim.Ifc4.Interfaces.IfcSIPrefix.MILLI;
                    }));
                    ua.Units.Add(model.Instances.New <IfcSIUnit>(u =>
                    {
                        u.UnitType = Xbim.Ifc4.Interfaces.IfcUnitEnum.MASSUNIT;
                        u.Name     = Xbim.Ifc4.Interfaces.IfcSIUnitName.GRAM;
                        u.Prefix   = Xbim.Ifc4.Interfaces.IfcSIPrefix.KILO;
                    }));
                });

                var ifcClassificationSystemOmniClass = model.Instances.New <IfcClassification>();
                ifcClassificationSystemOmniClass.Name        = "Omniclass";
                ifcClassificationSystemOmniClass.Edition     = "1.0";
                ifcClassificationSystemOmniClass.EditionDate = "2018-12-27T00:00:00.0000000";
                ifcClassificationSystemOmniClass.Description = "The OmniClass Construction Classification System (known as OmniClass™ or OCCS) is a classification system for the construction industry. OmniClass is useful for many applications, from organizing library materials, product literature, and project information, to providing a classification structure for electronic databases. It incorporates other extant systems currently in use as the basis of many of its Tables – MasterFormat™ for work results, UniFormat for elements, and EPIC (Electronic Product Information Cooperation) for structuring products.";
                ifcClassificationSystemOmniClass.Location    = "http://www.omniclass.org/";

                var ifcClassificationReferenceOmniClass = model.Instances.New <IfcClassificationReference>();
                ifcClassificationReferenceOmniClass.Identification   = "23-35-47";
                ifcClassificationReferenceOmniClass.Name             = "Electrical Lighting";
                ifcClassificationReferenceOmniClass.Description      = "NOT PROVIDED";
                ifcClassificationReferenceOmniClass.ReferencedSource = ifcClassificationSystemOmniClass;

                var ifcRelAssociatesClassificationOmniClass = model.Instances.New <IfcRelAssociatesClassification>();
                ifcRelAssociatesClassificationOmniClass.RelatingClassification = ifcClassificationReferenceOmniClass;

                var ifcClassificationSystemUniClass = model.Instances.New <IfcClassification>();
                ifcClassificationSystemUniClass.Name        = "Uniclass";
                ifcClassificationSystemUniClass.Edition     = "2015";
                ifcClassificationSystemUniClass.EditionDate = "";
                ifcClassificationSystemUniClass.Description = "";
                ifcClassificationSystemUniClass.Location    = "https://www.thenbs.com/our-tools/introducing-uniclass-2015";

                var ifcClassificationReferenceUniClass = model.Instances.New <IfcClassificationReference>();
                ifcClassificationReferenceUniClass.Identification   = "CA-70-10-30";
                ifcClassificationReferenceUniClass.Name             = "Site lighting equipment";
                ifcClassificationReferenceUniClass.Description      = "NOT PROVIDED";
                ifcClassificationReferenceUniClass.ReferencedSource = ifcClassificationSystemUniClass;

                var ifcRelAssociatesClassificationUniClass = model.Instances.New <IfcRelAssociatesClassification>();
                ifcRelAssociatesClassificationUniClass.RelatingClassification = ifcClassificationReferenceUniClass;

                //Insert a project library to store the product data templates and type products
                IfcProjectLibrary ifcProductDataLibrary = New <IfcProjectLibrary>(l => {
                    l.Name        = "TriluxLightingProductsLibrary";
                    l.GlobalId    = "1DbshdzGD71ejurQqQcxbw";
                    l.Description = "Library for Trilux light fixtures product data templates based on the ZVEI European core properties";
                    l.Phase       = "Design,Build,Operate";
                });
                Comment(ifcProductDataLibrary, @"Root element of this file. Because this doesn't define a specific instance in the building it is a library. It can be used to declare elements, properties, property templates and other library objects which can be later used in the actual design.");
                Comment(ifcProductDataLibrary.OwnerHistory, @"Owner history is used to define ownership of the information.");

                var ifcProductDataLibraryDeclarations = New <IfcRelDeclares>(rel =>
                {
                    rel.RelatingContext = ifcProductDataLibrary;
                }).RelatedDefinitions;
                Comment(ifcProductDataLibraryDeclarations.OwningEntity, @"This relation points to all definitions declared within the scope of the library. These can be elements, element types, properties or property templates");


                //Creating an IfcPropertySetTemplate manually
                //This is not optimal
                //Instead of creating the IfcPropertySetTemplates manually,
                //they should be loaded from the publishing dictionary

                //Read templates from excel sheet
                var          workbook = new XLWorkbook(Path.Combine(sourceFolder, sourceFile));
                IXLWorksheet worksheetTemplates;
                IXLRange     rangeTemplates;
                worksheetTemplates = workbook.Worksheet("Templates");
                rangeTemplates     = worksheetTemplates.Range("A1:H27");
                IXLTable  rawDataTemplates = rangeTemplates.AsTable();
                DataTable dtTemplates      = ReadDataTable(worksheetTemplates);


                IfcPropertySetTemplate ifcPropertySetTemplate = model.Instances.New <IfcPropertySetTemplate>(pset =>
                {
                    pset.GlobalId         = "1DbshTzGD71ejurQqQcxbw";
                    pset.Name             = "IfcPropertySetTemplate";
                    pset.Description      = "Group of properties for " + ifcProductDataLibrary.Name;
                    pset.ApplicableEntity = "IfcLightFixture/USERDEFINED";
                    pset.TemplateType     = Xbim.Ifc4.Interfaces.IfcPropertySetTemplateTypeEnum.PSET_TYPEDRIVENONLY;
                });
                Comment(ifcPropertySetTemplate, @"Declaration of 'IfcPropertySetTemplate' within the library for lighting product data templates.");
                Comment(ifcPropertySetTemplate, @"Insert property templates; they should be loaded from the publishing dictionary");

                foreach (DataRow row in dtTemplates.Rows)
                {
                    //Publisher SystemName  GlobalId PrimaryMeasureType  DataColumn

                    ifcPropertySetTemplate.HasPropertyTemplates.AddRange(new[]
                    {
                        model.Instances.New <IfcSimplePropertyTemplate>(pt =>
                        {
                            pt.Name               = row["SystemName"].ToString();
                            pt.Description        = "";
                            pt.GlobalId           = row["GlobalId"].ToString();
                            pt.TemplateType       = Xbim.Ifc4.Interfaces.IfcSimplePropertyTemplateTypeEnum.P_SINGLEVALUE;
                            pt.AccessState        = Xbim.Ifc4.Interfaces.IfcStateEnum.LOCKED;
                            pt.PrimaryMeasureType = row["PrimaryMeasureType"].ToString();

                            string primaryMeasureType = row["PrimaryMeasureType"].ToString();

                            if (primaryMeasureType == typeof(IfcLengthMeasure).Name)
                            {
                                pt.PrimaryUnit = model.Instances.New <IfcSIUnit>(u =>
                                {
                                    u.UnitType = Xbim.Ifc4.Interfaces.IfcUnitEnum.LENGTHUNIT;
                                    u.Name     = Xbim.Ifc4.Interfaces.IfcSIUnitName.METRE;
                                    u.Prefix   = Xbim.Ifc4.Interfaces.IfcSIPrefix.MILLI;
                                });
                            }
                            else if (primaryMeasureType == typeof(IfcMassMeasure).Name)
                            {
                                pt.PrimaryUnit = model.Instances.New <IfcSIUnit>(u =>
                                {
                                    u.UnitType = Xbim.Ifc4.Interfaces.IfcUnitEnum.MASSUNIT;
                                    u.Name     = Xbim.Ifc4.Interfaces.IfcSIUnitName.GRAM;
                                });
                            }
                            else if (primaryMeasureType == typeof(IfcPlaneAngleMeasure).Name)
                            {
                                pt.PrimaryUnit = model.Instances.New <IfcConversionBasedUnit>(punit =>
                                {
                                    //Convert the angel measure from the unit grad to the SI Unit radian
                                    //rad=grad*(PI/180)
                                    punit.Name             = "Grad";
                                    punit.UnitType         = Xbim.Ifc4.Interfaces.IfcUnitEnum.PLANEANGLEUNIT;
                                    punit.ConversionFactor = model.Instances.New <IfcMeasureWithUnit>(mwu =>
                                    {
                                        mwu.UnitComponent = model.Instances.New <IfcSIUnit>(siUnit =>
                                        {
                                            siUnit.UnitType = Xbim.Ifc4.Interfaces.IfcUnitEnum.PLANEANGLEUNIT;
                                            siUnit.Name     = Xbim.Ifc4.Interfaces.IfcSIUnitName.RADIAN;
                                        });
                                        mwu.ValueComponent = new IfcReal(Math.PI / 180);
                                    });
                                    punit.Dimensions = model.Instances.New <IfcDimensionalExponents>(dim =>
                                    {
                                        dim.LengthExponent                   = 0;
                                        dim.MassExponent                     = 0;
                                        dim.TimeExponent                     = 0;
                                        dim.ElectricCurrentExponent          = 0;
                                        dim.ThermodynamicTemperatureExponent = 0;
                                        dim.AmountOfSubstanceExponent        = 0;
                                        dim.LuminousIntensityExponent        = 0;
                                    });
                                });
                            }
                        })
                    });
                }
                ;


                ifcProductDataLibraryDeclarations.Add(ifcPropertySetTemplate);

                //Read source data from excel sheet
                var          workbookData = new XLWorkbook(Path.Combine(sourceFolder, sourceFile));
                IXLWorksheet worksheetData;
                IXLRange     rangeData;
                worksheetData = workbookData.Worksheet("Sheets");
                rangeData     = worksheetData.Range("A1:Z690");
                IXLTable  rawData = rangeData.AsTable();
                DataTable dtData  = ReadDataTable(worksheetData);

                var ifcRelDefinesByTemplate = New <IfcRelDefinesByTemplate>(dbt =>
                {
                    dbt.RelatingTemplate = ifcPropertySetTemplate;
                });

                int n = 0;
                do
                {
                    foreach (DataRow row in dtData.Rows)
                    {
                        var ifcTypeProduct = model.Instances.New <IfcTypeProduct>();
                        ifcTypeProduct.GlobalId             = "1DbshTzGD71ejurQqQcxbw"; //How to generate a fresh IFC GlobalId with XBim?
                        ifcTypeProduct.Name                 = row["Name"].ToString();
                        ifcTypeProduct.Description          = "Description of " + ifcTypeProduct.Name;
                        ifcTypeProduct.ApplicableOccurrence = "IfcLightFixture";

                        ifcRelAssociatesClassificationOmniClass.RelatedObjects.Add(ifcTypeProduct);
                        ifcRelAssociatesClassificationUniClass.RelatedObjects.Add(ifcTypeProduct);

                        IfcPropertySet ifcPropertySet = model.Instances.New <IfcPropertySet>(pset =>
                        {
                            pset.Name = "Properties of " + ifcTypeProduct.Name;
                        });

                        foreach (DataRow template in dtTemplates.Rows)
                        {
                            if (template["PropertyWithDocumentLink"].ToString() == "Yes")
                            {
                                //Insert the product information into documents
                                string folderName = template["SystemName"].ToString();
                                string docName    = row[template["SystemName"].ToString()].ToString();

                                IfcDocumentInformation ifcDocumentInformation = model.Instances.New <IfcDocumentInformation>(doc =>
                                {
                                    doc.Identification   = docName;
                                    doc.Name             = docName;
                                    doc.Location         = $@"{folderName}/{docName}";
                                    doc.Confidentiality  = Xbim.Ifc4.Interfaces.IfcDocumentConfidentialityEnum.PUBLIC;
                                    doc.ElectronicFormat = MimeTypes.GetMimeType(docName);
                                    doc.IntendedUse      = "Product information";
                                    doc.Purpose          = "Product information";
                                });

                                IfcRelAssociatesDocument ifcRelAssociatesDocument = model.Instances.New <IfcRelAssociatesDocument>(docref =>
                                {
                                    docref.RelatedObjects.Add(ifcTypeProduct);
                                    docref.RelatingDocument = ifcDocumentInformation;
                                });

                                //<IfcRelAssociatesDocument GlobalId="3vBcwkKGf1cxmQZUtNnL0g">
                                //   < RelatedObjects >
                                //      < IfcTransportElement xsi: nil = "true" ref= "i143" />
                                //   </ RelatedObjects >
                                //   < RelatingDocument >
                                //      < IfcDocumentInformation xsi: nil = "true" ref= "i150" />
                                //   </ RelatingDocument >
                                //</ IfcRelAssociatesDocument >
                            }
                            else
                            {
                                //Insert the product information into Properties
                                ifcPropertySet.HasProperties.AddRange(new[]
                                {
                                    model.Instances.New <IfcPropertySingleValue>(p =>
                                    {
                                        string propertyName = template["SystemName"].ToString();
                                        var dataValue       = row[propertyName];

                                        p.Name        = propertyName;
                                        p.Description = "";

                                        string primaryMeasureType = template["PrimaryMeasureType"].ToString();
                                        if (primaryMeasureType == typeof(IfcLengthMeasure).Name)
                                        {
                                            p.NominalValue = new IfcMassMeasure(Double.Parse(dataValue.ToString()));
                                        }
                                        else if (primaryMeasureType == typeof(IfcMassMeasure).Name)
                                        {
                                            p.NominalValue = new IfcMassMeasure(Double.Parse(dataValue.ToString()));
                                        }
                                        else if (primaryMeasureType == typeof(IfcPlaneAngleMeasure).Name)
                                        {
                                            p.NominalValue = new IfcPlaneAngleMeasure(Double.Parse(dataValue.ToString()));
                                        }
                                        else
                                        {
                                            p.NominalValue = new IfcLabel(dataValue.ToString());
                                        }
                                    })
                                });
                            }
                        }
                        ;

                        ifcTypeProduct.HasPropertySets.Add(ifcPropertySet);

                        ifcProductDataLibraryDeclarations.Add(ifcTypeProduct);
                        Comment(ifcTypeProduct, @"Declaration of 'IfcTypeProduct' within the library for a ligthing product.");

                        ifcRelDefinesByTemplate.RelatedPropertySets.Add(ifcPropertySet);
                    }
                    n++;
                }while (n < 1);

                txn.Commit();
            }

            string targetFileName = Path.Combine(targetFolder, targetFile);

            SaveAs(targetFileName, true, typeof(IfcProjectLibrary));

            //Create ifcZip file
            File.Delete(zipFile);
            ZipFile.CreateFromDirectory(sourceFolder, zipFile);
            using (ZipArchive zipArchive = ZipFile.Open(zipFile, ZipArchiveMode.Update))
            {
                zipArchive.GetEntry(sourceFile).Delete();
                zipArchive.CreateEntryFromFile($"{targetFolder}/{targetFile}.ifcXML", $"{targetFile}.ifcXML");
                zipArchive.CreateEntryFromFile($"{targetFolder}/{targetFile}.ifc", $"{targetFile}.ifc");
            }
        }