private void button_Go_Click(object sender, RoutedEventArgs e) { #if DEBUG string tempFolder = System.IO.Path.GetTempPath(); logF = new StreamWriter(Path.Combine(tempFolder, "GeneratePsetDefWin.log")); #endif textBox_OutputMsg.Clear(); string parFileNameOut = Path.Combine(Path.GetDirectoryName(SharedParFileName), Path.GetFileNameWithoutExtension(SharedParFileName) + "_out.txt"); stSharedPar = File.CreateText(parFileNameOut); ProcessPsetDefinition.processExistingParFile(SharedParFileName, false, ref stSharedPar); if (File.Exists(SharedParFileNameType)) { string typeParFileNameOut = Path.Combine(Path.GetDirectoryName(SharedParFileNameType), Path.GetFileNameWithoutExtension(SharedParFileNameType) + "_out.txt"); stSharedParType = File.CreateText(typeParFileNameOut); ProcessPsetDefinition.processExistingParFile(SharedParFileNameType, true, ref stSharedParType); } else { stSharedParType = File.CreateText(SharedParFileNameType); } ProcessPsetDefinition procPsetDef = new ProcessPsetDefinition(logF); if (string.IsNullOrEmpty(textBox_PSDSourceDir.Text) || string.IsNullOrEmpty(textBox_OutputFile.Text)) { return; } var psdFolders = new DirectoryInfo(textBox_PSDSourceDir.Text).GetDirectories("psd", SearchOption.AllDirectories); string dirName = Path.GetDirectoryName(textBox_OutputFile.Text); string penumFileName = Path.GetFileNameWithoutExtension(textBox_OutputFile.Text); if (File.Exists(textBox_OutputFile.Text)) { File.Delete(textBox_OutputFile.Text); } StreamWriter outF = new StreamWriter(textBox_OutputFile.Text); outF.WriteLine("/********************************************************************************************************************************"); outF.WriteLine("** NOTE: This code is generated from IFC psd files automatically by RevitIFCTools. **"); outF.WriteLine("** DO NOT change it manually as it will be overwritten the next time this file is re-generated!! **"); outF.WriteLine("********************************************************************************************************************************/"); outF.WriteLine(); outF.WriteLine("using System;"); outF.WriteLine("using System.Collections.Generic;"); outF.WriteLine("using System.Linq;"); outF.WriteLine("using System.Text;"); outF.WriteLine("using System.Threading.Tasks;"); outF.WriteLine("using Autodesk.Revit;"); outF.WriteLine("using Autodesk.Revit.DB;"); outF.WriteLine("using Autodesk.Revit.DB.IFC;"); outF.WriteLine("using Autodesk.Revit.ApplicationServices;"); outF.WriteLine("using Revit.IFC.Export.Exporter.PropertySet;"); outF.WriteLine("using Revit.IFC.Export.Exporter.PropertySet.Calculators;"); outF.WriteLine("using Revit.IFC.Export.Utility;"); outF.WriteLine("using Revit.IFC.Export.Toolkit;"); outF.WriteLine("using Revit.IFC.Common.Enums;"); outF.WriteLine(""); outF.WriteLine("namespace Revit.IFC.Export.Exporter"); outF.WriteLine("{"); outF.WriteLine("\tpartial class ExporterInitializer"); outF.WriteLine("\t{"); // Collect all Pset definition for psd folders foreach (DirectoryInfo psd in psdFolders) { string schemaFolder = psd.FullName.Remove(0, textBox_PSDSourceDir.Text.Length + 1).Split('\\')[0]; #if DEBUG logF.WriteLine("\n*** Processing " + schemaFolder); #endif foreach (DirectoryInfo subDir in psd.GetDirectories()) { procPsetDef.ProcessSchemaPsetDef(schemaFolder, subDir); } procPsetDef.ProcessSchemaPsetDef(schemaFolder, psd); } // For testing purpose: Dump all the propertyset definition in a text file if (checkBox_Dump.IsChecked.HasValue && checkBox_Dump.IsChecked.Value) { string pSetDump = ""; foreach (KeyValuePair <string, IList <VersionSpecificPropertyDef> > psetDefEntry in procPsetDef.allPDefDict) { pSetDump += "**** Property Set Name: " + psetDefEntry.Key; foreach (VersionSpecificPropertyDef vPdef in psetDefEntry.Value) { pSetDump += "\n ===> IfcVersion: " + vPdef.IfcVersion; pSetDump += "\n" + vPdef.PropertySetDef.ToString() + "\n"; } pSetDump += "\n\n"; } string dumpDir = Path.GetDirectoryName(textBox_OutputFile.Text); string dumpFile = Path.GetFileNameWithoutExtension(textBox_OutputFile.Text) + ".txt"; string dumpFilePath = Path.Combine(dumpDir, dumpFile); if (File.Exists(dumpFilePath)) { File.Delete(dumpFilePath); } StreamWriter tx = new StreamWriter(dumpFilePath); tx.Write(pSetDump); tx.Close(); } // Method to initialize all the propertysets outF.WriteLine("\t\tpublic static void InitCommonPropertySets(IList<IList<PropertySetDescription>> propertySets)"); outF.WriteLine("\t\t{"); outF.WriteLine("\t\t\tIList<PropertySetDescription> commonPropertySets = new List<PropertySetDescription>();"); foreach (KeyValuePair <string, IList <VersionSpecificPropertyDef> > psetDefEntry in procPsetDef.allPDefDict) { outF.WriteLine("\t\t\tInit" + psetDefEntry.Key + "(commonPropertySets);"); } outF.WriteLine("\n\t\t\tpropertySets.Add(commonPropertySets);"); outF.WriteLine("\t\t}"); outF.WriteLine(""); // For generated codes and shared parameters foreach (KeyValuePair <string, IList <VersionSpecificPropertyDef> > psetDefEntry in procPsetDef.allPDefDict) { string psetName = psetDefEntry.Key; outF.WriteLine("\t\tprivate static void Init" + psetName + "(IList<PropertySetDescription> commonPropertySets)"); outF.WriteLine("\t\t{"); string varName = psetDefEntry.Key.Replace("Pset_", "propertySet"); outF.WriteLine("\t\t\tPropertySetDescription {0} = new PropertySetDescription();", varName); string psetEnumStr = psetName.Replace("PSet_", "PSet"); try { Revit.IFC.Export.Toolkit.IFCCommonPSets psetEnum = (Revit.IFC.Export.Toolkit.IFCCommonPSets)Enum.Parse(typeof(Revit.IFC.Export.Toolkit.IFCCommonPSets), psetEnumStr); outF.WriteLine("\t\t\t{0}.SubElementIndex = (int)IFCCommonPSets.{1};", varName, psetName.Replace("PSet_", "PSet")); } catch (ArgumentException) { #if DEBUG logF.WriteLine("\t%Info: " + psetEnumStr + " is not defined in Revit.IFC.Export.Toolkit.IFCCommonPSets."); #endif } outF.WriteLine("\t\t\t{0}.Name = \"{1}\";", varName, psetName); outF.WriteLine("\t\t\tPropertySetEntry ifcPSE = null;"); outF.WriteLine("\t\t\tType calcType = null;"); foreach (VersionSpecificPropertyDef vspecPDef in psetDefEntry.Value) { PsetDefinition pDef = vspecPDef.PropertySetDef; if (vspecPDef.IfcVersion.Equals("IFC2X2", StringComparison.CurrentCultureIgnoreCase)) { outF.WriteLine("\t\t\tif (ExporterCacheManager.ExportOptionsCache.ExportAs2x2 && certifiedEntityAndPsetList.AllowPsetToBeCreated(ExporterCacheManager.ExportOptionsCache.FileVersion.ToString().ToUpper(), \"" + psetName + "\"))"); outF.WriteLine("\t\t\t{"); foreach (string applEnt in vspecPDef.PropertySetDef.ApplicableClasses) { string applEnt2 = applEnt; if (string.IsNullOrEmpty(applEnt)) { applEnt2 = "IfcBuildingElementProxy"; // Default if somehow the data is empty } outF.WriteLine("\t\t\t\t{0}.EntityTypes.Add(IFCEntityType.{1});", varName, applEnt2); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.ApplicableType)) { outF.WriteLine("\t\t\t\t{0}.ObjectType = \"{1}\";", varName, vspecPDef.PropertySetDef.ApplicableType); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.PredefinedType)) { outF.WriteLine("\t\t\t\t{0}.PredefinedType = \"{1}\";", varName, vspecPDef.PropertySetDef.PredefinedType); } } else if (vspecPDef.IfcVersion.Equals("IFC2X3TC1", StringComparison.CurrentCultureIgnoreCase) || vspecPDef.IfcVersion.Equals("IFC2X3_TC1", StringComparison.CurrentCultureIgnoreCase)) { outF.WriteLine("\t\t\tif (ExporterCacheManager.ExportOptionsCache.ExportAs2x3 && certifiedEntityAndPsetList.AllowPsetToBeCreated(ExporterCacheManager.ExportOptionsCache.FileVersion.ToString().ToUpper(), \"" + psetName + "\"))"); outF.WriteLine("\t\t\t{"); foreach (string applEnt in vspecPDef.PropertySetDef.ApplicableClasses) { string applEnt2 = applEnt; if (string.IsNullOrEmpty(applEnt)) { applEnt2 = "IfcBuildingElementProxy"; // Default if somehow the data is empty } outF.WriteLine("\t\t\t\t{0}.EntityTypes.Add(IFCEntityType.{1});", varName, applEnt2); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.ApplicableType)) { outF.WriteLine("\t\t\t\t{0}.ObjectType = \"{1}\";", varName, vspecPDef.PropertySetDef.ApplicableType); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.PredefinedType)) { outF.WriteLine("\t\t\t\t{0}.PredefinedType = \"{1}\";", varName, vspecPDef.PropertySetDef.PredefinedType); } } //else if (vspecPDef.IfcVersion.Equals("IFC4_ADD1")) //{ else if (vspecPDef.SchemaFileVersion.Equals("IFC4_ADD1", StringComparison.CurrentCultureIgnoreCase)) { outF.WriteLine("\t\t\tif (ExporterCacheManager.ExportOptionsCache.ExportAs4_ADD1 && certifiedEntityAndPsetList.AllowPsetToBeCreated(ExporterCacheManager.ExportOptionsCache.FileVersion.ToString().ToUpper(), \"" + psetName + "\"))"); outF.WriteLine("\t\t\t{"); foreach (string applEnt in vspecPDef.PropertySetDef.ApplicableClasses) { string applEnt2 = applEnt; if (string.IsNullOrEmpty(applEnt)) { applEnt2 = "IfcBuildingElementProxy"; // Default if somehow the data is empty } outF.WriteLine("\t\t\t\t{0}.EntityTypes.Add(IFCEntityType.{1});", varName, applEnt2); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.ApplicableType)) { outF.WriteLine("\t\t\t\t{0}.ObjectType = \"{1}\";", varName, vspecPDef.PropertySetDef.ApplicableType); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.PredefinedType)) { outF.WriteLine("\t\t\t\t{0}.PredefinedType = \"{1}\";", varName, vspecPDef.PropertySetDef.PredefinedType); } } else if (vspecPDef.SchemaFileVersion.Equals("IFC4_ADD2", StringComparison.CurrentCultureIgnoreCase)) { outF.WriteLine("\t\t\tif (ExporterCacheManager.ExportOptionsCache.ExportAs4_ADD2 && certifiedEntityAndPsetList.AllowPsetToBeCreated(ExporterCacheManager.ExportOptionsCache.FileVersion.ToString().ToUpper(), \"" + psetName + "\"))"); outF.WriteLine("\t\t\t{"); foreach (string applEnt in vspecPDef.PropertySetDef.ApplicableClasses) { string applEnt2 = applEnt; if (string.IsNullOrEmpty(applEnt)) { applEnt2 = "IfcBuildingElementProxy"; // Default if somehow the data is empty } outF.WriteLine("\t\t\t\t{0}.EntityTypes.Add(IFCEntityType.{1});", varName, applEnt2); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.ApplicableType)) { outF.WriteLine("\t\t\t\t{0}.ObjectType = \"{1}\";", varName, vspecPDef.PropertySetDef.ApplicableType); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.PredefinedType)) { outF.WriteLine("\t\t\t\t{0}.PredefinedType = \"{1}\";", varName, vspecPDef.PropertySetDef.PredefinedType); } } else if (vspecPDef.SchemaFileVersion.Equals("IFC4", StringComparison.CurrentCultureIgnoreCase)) { outF.WriteLine("\t\t\tif (ExporterCacheManager.ExportOptionsCache.ExportAs4 && certifiedEntityAndPsetList.AllowPsetToBeCreated(ExporterCacheManager.ExportOptionsCache.FileVersion.ToString().ToUpper(), \"" + psetName + "\"))"); outF.WriteLine("\t\t\t{"); foreach (string applEnt in vspecPDef.PropertySetDef.ApplicableClasses) { string applEnt2 = applEnt; if (string.IsNullOrEmpty(applEnt)) { applEnt2 = "IfcBuildingElementProxy"; // Default if somehow the data is empty } outF.WriteLine("\t\t\t\t{0}.EntityTypes.Add(IFCEntityType.{1});", varName, applEnt2); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.ApplicableType)) { outF.WriteLine("\t\t\t\t{0}.ObjectType = \"{1}\";", varName, vspecPDef.PropertySetDef.ApplicableType); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.PredefinedType)) { outF.WriteLine("\t\t\t\t{0}.PredefinedType = \"{1}\";", varName, vspecPDef.PropertySetDef.PredefinedType); } } else { #if DEBUG logF.WriteLine("%Error - Unrecognized schema version : " + vspecPDef.SchemaFileVersion); #endif } //} // Process each property foreach (PsetProperty prop in pDef.properties) { // Handle only one level deep of complex property !!!! if (prop.PropertyType is ComplexProperty) { ComplexProperty complexProp = prop.PropertyType as ComplexProperty; // For complex property the properties will be flattened by using <Pset>.<Property>.<SubProperty> foreach (PsetProperty propCx in complexProp.Properties) { string prefixName = pDef.Name + "." + prop.Name; procPsetDef.processSimpleProperty(outF, propCx, prefixName, pDef.IfcVersion, vspecPDef.SchemaFileVersion, varName, vspecPDef, penumFileName); } } else { procPsetDef.processSimpleProperty(outF, prop, pDef.Name, pDef.IfcVersion, vspecPDef.SchemaFileVersion, varName, vspecPDef, penumFileName); } } outF.WriteLine("\t\t\t}"); } outF.WriteLine("\t\t\tif (ifcPSE != null)"); outF.WriteLine("\t\t\t{"); //outF.WriteLine("\t\t\t\t{0}.Name = \"{1}\";", varName, psetName); outF.WriteLine("\t\t\t\tcommonPropertySets.Add({0});", varName); outF.WriteLine("\t\t\t}"); outF.WriteLine("\t\t}"); outF.WriteLine("\n"); } outF.WriteLine("\t}"); outF.WriteLine("}"); outF.Close(); procPsetDef.endWriteEnumFile(); // Now write shared parameter definitions from the Dict to destination file stSharedPar.WriteLine("# This is a Revit shared parameter file."); stSharedPar.WriteLine("# Do not edit manually."); stSharedPar.WriteLine("*META VERSION MINVERSION"); stSharedPar.WriteLine("META 2 1"); stSharedPar.WriteLine("*GROUP ID NAME"); stSharedPar.WriteLine("GROUP 2 IFC Properties"); stSharedPar.WriteLine("*PARAM GUID NAME DATATYPE DATACATEGORY GROUP VISIBLE DESCRIPTION USERMODIFIABLE"); stSharedPar.WriteLine("#"); foreach (KeyValuePair <string, SharedParameterDef> parDef in ProcessPsetDefinition.SharedParamFileDict) { SharedParameterDef newPar = parDef.Value; string vis = newPar.Visibility ? "1" : "0"; string usrMod = newPar.UserModifiable ? "1" : "0"; string parEntry = newPar.Param + "\t" + newPar.ParamGuid.ToString() + "\t" + newPar.Name + "\t" + newPar.ParamType + "\t" + newPar.DataCategory + "\t" + newPar.GroupId.ToString() + "\t" + vis + "\t" + newPar.Description + "\t" + usrMod; stSharedPar.WriteLine(parEntry); } stSharedParType.WriteLine("# This is a Revit shared parameter file."); stSharedParType.WriteLine("# Do not edit manually."); stSharedParType.WriteLine("*META VERSION MINVERSION"); stSharedParType.WriteLine("META 2 1"); stSharedParType.WriteLine("*GROUP ID NAME"); stSharedParType.WriteLine("GROUP 2 IFC Properties"); stSharedParType.WriteLine("*PARAM GUID NAME DATATYPE DATACATEGORY GROUP VISIBLE DESCRIPTION USERMODIFIABLE"); stSharedParType.WriteLine("#"); foreach (KeyValuePair <string, SharedParameterDef> parDef in ProcessPsetDefinition.SharedParamFileTypeDict) { SharedParameterDef newPar = parDef.Value; string parName4Type; if (newPar.Name.EndsWith("[Type]")) { parName4Type = newPar.Name; } else { parName4Type = newPar.Name + "[Type]"; } string vis = newPar.Visibility ? "1" : "0"; string usrMod = newPar.UserModifiable ? "1" : "0"; string parEntry = newPar.Param + "\t" + newPar.ParamGuid.ToString() + "\t" + parName4Type + "\t" + newPar.ParamType + "\t" + newPar.DataCategory + "\t" + newPar.GroupId.ToString() + "\t" + vis + "\t" + newPar.Description + "\t" + usrMod; stSharedParType.WriteLine(parEntry); } stSharedPar.Close(); stSharedParType.Close(); #if DEBUG logF.Close(); #endif }
private void button_Go_Click(object sender, RoutedEventArgs e) { if (listBox_schemaList.SelectedItems.Count == 0) { return; } DirectoryInfo dInfo = new DirectoryInfo(textBox_folderLocation.Text); if (dInfo == null) { return; } if (aggregateEntities == null) { aggregateEntities = new SortedSet <string>(); } aggregateEntities.Clear(); if (!Directory.Exists(textBox_outputFolder.Text)) { textBox_outputFolder.Text = ""; return; } logF = new StreamWriter(System.IO.Path.Combine(outputFolder, "entityList.log")); IList <IFCEntityAndPsetList> fxEntityNPsetList = new List <IFCEntityAndPsetList>(); string jsonFile = outputFolder + @"\IFCEntityAndPsetDefs.json"; if (File.Exists(jsonFile)) { File.Delete(jsonFile); } FileStream fs = File.Create(jsonFile); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List <IFCEntityAndPsetList>)); foreach (string fileName in listBox_schemaList.SelectedItems) { FileInfo f = dInfo.GetFiles(fileName).First(); processSchema(f); ProcessPsetDefinition procPdef = new ProcessPsetDefinition(logF); string schemaName = f.Name.Replace(".xsd", ""); IDictionary <string, IfcSchemaEntityNode> entDict = IfcSchemaEntityTree.GetEntityDictFor(f.Name); IFCEntityAndPsetList schemaEntities = new IFCEntityAndPsetList(); schemaEntities.Version = schemaName; schemaEntities.EntityList = new HashSet <IFCEntityInfo>(); schemaEntities.PsetDefList = new HashSet <IFCPropertySetDef>(); DirectoryInfo[] psdFolders = new DirectoryInfo(System.IO.Path.Combine(textBox_folderLocation.Text, schemaName)).GetDirectories("psd", SearchOption.AllDirectories); DirectoryInfo[] underpsdFolders = psdFolders[0].GetDirectories(); if (underpsdFolders.Count() > 0) { foreach (DirectoryInfo subDir in psdFolders[0].GetDirectories()) { procPdef.ProcessSchemaPsetDef(schemaName, subDir); } } else { procPdef.ProcessSchemaPsetDef(schemaName, psdFolders[0]); } //Collect information on applicable Psets for Entity IDictionary <string, HashSet <string> > entPsetDict = new Dictionary <string, HashSet <string> >(); foreach (KeyValuePair <string, IList <VersionSpecificPropertyDef> > pdefEntry in procPdef.allPDefDict) { foreach (VersionSpecificPropertyDef vPdef in pdefEntry.Value) { //if (vPdef.IfcVersion.Equals(schemaName, StringComparison.InvariantCultureIgnoreCase)) { IFCPropertySetDef psetDef = new IFCPropertySetDef(); psetDef.PsetName = vPdef.PropertySetDef.Name; IList <string> props = new List <string>(); foreach (PropertySet.PsetProperty property in vPdef.PropertySetDef.properties) { props.Add(property.Name); } psetDef.Properties = props; schemaEntities.PsetDefList.Add(psetDef); // TODO: to check the appl classes either a type or not and check whether the pair (type or without) exists in entDict, if there is add foreach (string applEntity in vPdef.PropertySetDef.ApplicableClasses) { if (entPsetDict.ContainsKey(applEntity)) { entPsetDict[applEntity].Add(vPdef.PropertySetDef.Name); } else { entPsetDict.Add(applEntity, new HashSet <string>() { vPdef.PropertySetDef.Name }); } // The Pset will be valid for both the Instance and the Type. Check for that here and add if found string entOrTypePair; if (applEntity.Length > 4 && applEntity.EndsWith("Type")) { entOrTypePair = applEntity.Substring(0, applEntity.Length - 4); } else { entOrTypePair = applEntity + "Type"; } if (aggregateEntities.Contains(entOrTypePair)) { if (entPsetDict.ContainsKey(entOrTypePair)) { entPsetDict[entOrTypePair].Add(vPdef.PropertySetDef.Name); } else { entPsetDict.Add(entOrTypePair, new HashSet <string>() { vPdef.PropertySetDef.Name }); } } } } } } // For every entity of the schema, collect the list of PredefinedType (obtained from the xsd), and collect all applicable // Pset Definitions collected above foreach (KeyValuePair <string, IfcSchemaEntityNode> ent in entDict) { IFCEntityInfo entInfo = new IFCEntityInfo(); // The abstract entity type is not going to be listed here as they can never be created if (ent.Value.isAbstract) { continue; } // Collect only the IfcProducts or IfcGroup if (!ent.Value.IsSubTypeOf("IfcProduct") && !ent.Value.IsSubTypeOf("IfcGroup") && !ent.Value.IsSubTypeOf("IfcTypeProduct")) { continue; } entInfo.Entity = ent.Key; if (!string.IsNullOrEmpty(ent.Value.PredefinedType)) { if (IfcSchemaEntityTree.PredefinedTypeEnumDict.ContainsKey(ent.Value.PredefinedType)) { entInfo.PredefinedType = IfcSchemaEntityTree.PredefinedTypeEnumDict[ent.Value.PredefinedType]; } } // Get Pset list that is applicable to this entity type if (entPsetDict.ContainsKey(entInfo.Entity)) { entInfo.PropertySets = entPsetDict[entInfo.Entity].ToList(); } // Collect Pset that is applicable to the supertype of this entity IList <IfcSchemaEntityNode> supertypeList = IfcSchemaEntityTree.FindAllSuperTypes(entInfo.Entity, "IfcProduct", "IfcTypeProduct", "IfcGroup"); if (supertypeList != null && supertypeList.Count > 0) { foreach (IfcSchemaEntityNode superType in supertypeList) { if (entPsetDict.ContainsKey(superType.Name)) { if (entInfo.PropertySets == null) { entInfo.PropertySets = new List <string>(); } foreach (string pset in entPsetDict[superType.Name]) { entInfo.PropertySets.Add(pset); } } } } schemaEntities.EntityList.Add(entInfo); } fxEntityNPsetList.Add(schemaEntities); } ser.WriteObject(fs, fxEntityNPsetList); fs.Close(); if (aggregateEntities.Count > 0) { string entityList; entityList = "using System;" + "\r\nusing System.Collections.Generic;" + "\r\nusing System.Linq;" + "\r\nusing System.Text;" + "\r\n" + "\r\nnamespace Revit.IFC.Common.Enums" + "\r\n{" + "\r\n /// <summary>" + "\r\n /// IFC entity types. Combining IFC2x3 and IFC4 (Add2) entities." + "\r\n /// List of Entities for IFC2x is found in IFC2xEntityType.cs" + "\r\n /// List of Entities for IFC4 is found in IFC4EntityType.cs" + "\r\n /// </summary>" + "\r\n public enum IFCEntityType" + "\r\n {"; foreach (string ent in aggregateEntities) { entityList += "\r\n /// <summary>" + "\r\n /// IFC Entity " + ent + " enumeration" + "\r\n /// </summary>" + "\r\n " + ent + ",\n"; } entityList += "\r\n Unknown," + "\r\n DontExport" + "\r\n }" + "\r\n}"; System.IO.File.WriteAllText(outputFolder + @"\IFCEntityType.cs", entityList); } foreach (IFCEntityAndPsetList fxEntityNPset in fxEntityNPsetList) { string entityList; entityList = "using System;" + "\r\nusing System.Collections.Generic;" + "\r\nusing System.Linq;" + "\r\nusing System.Text;" + "\r\n" + "\r\nnamespace Revit.IFC.Common.Enums." + fxEntityNPset.Version + "\r\n{" + "\r\n /// <summary>" + "\r\n /// List of Entities for " + fxEntityNPset.Version + "\r\n /// </summary>" + "\r\n public enum EntityType" + "\r\n {"; foreach (IFCEntityInfo entInfo in fxEntityNPset.EntityList) { entityList += "\r\n /// <summary>" + "\r\n /// IFC Entity " + entInfo.Entity + " enumeration" + "\r\n /// </summary>" + "\r\n " + entInfo.Entity + ",\r\n"; } entityList += "\r\n Unknown," + "\r\n DontExport" + "\r\n }" + "\r\n}"; System.IO.File.WriteAllText(outputFolder + @"\" + fxEntityNPset.Version + "EntityType.cs", entityList); } // Only allows test when only one schema is selected if (listBox_schemaList.SelectedItems.Count == 1) { button_subtypeTest.IsEnabled = true; button_supertypeTest.IsEnabled = true; button_ExportInfoPair.IsEnabled = true; } else { button_subtypeTest.IsEnabled = false; button_supertypeTest.IsEnabled = false; button_ExportInfoPair.IsEnabled = false; } if (logF != null) { logF.Close(); } }
int WriteGeneratedCode(StreamWriter outF, ProcessPsetDefinition procPsetDef, string penumFileName, string whichCat, IDictionary <string, int> paramGroupDict, int offset) { // Header section of the generated code outF.WriteLine("/********************************************************************************************************************************"); outF.WriteLine("** NOTE: This code is generated from IFC psd files automatically by RevitIFCTools. **"); outF.WriteLine("** DO NOT change it manually as it will be overwritten the next time this file is re-generated!! **"); outF.WriteLine("********************************************************************************************************************************/"); outF.WriteLine(); outF.WriteLine("using System;"); outF.WriteLine("using System.Collections.Generic;"); outF.WriteLine("using System.Linq;"); outF.WriteLine("using System.Text;"); outF.WriteLine("using System.Threading.Tasks;"); outF.WriteLine("using Autodesk.Revit;"); outF.WriteLine("using Autodesk.Revit.DB;"); outF.WriteLine("using Autodesk.Revit.DB.IFC;"); outF.WriteLine("using Autodesk.Revit.ApplicationServices;"); outF.WriteLine("using Revit.IFC.Export.Exporter.PropertySet;"); outF.WriteLine("using Revit.IFC.Export.Exporter.PropertySet.Calculators;"); outF.WriteLine("using Revit.IFC.Export.Utility;"); outF.WriteLine("using Revit.IFC.Export.Toolkit;"); outF.WriteLine("using Revit.IFC.Common.Enums;"); outF.WriteLine(""); outF.WriteLine("namespace Revit.IFC.Export.Exporter"); outF.WriteLine("{"); outF.WriteLine(" partial class ExporterInitializer"); outF.WriteLine(" {"); // Initialization section string allPsetOrQtoSetsName = "allPsetOrQtoSets"; string theSetName = "theSets"; string initPsetOrQsets = null; string setDescription = null; switch (whichCat) { case "Pset": initPsetOrQsets = "InitCommonPropertySets"; setDescription = "PropertySetDescription"; break; case "Ifc": initPsetOrQsets = "InitPredefinedPropertySets"; setDescription = "PropertySetDescription"; break; case "Qto": initPsetOrQsets = "InitQtoSets"; setDescription = "QuantityDescription"; break; default: logF.WriteLine("Category not supported {0}! Use only \"Pset\", \"Qto\", or \"Ifc\"", whichCat); break; } outF.WriteLine(" public static void {0}(IList<IList<{1}>> {2})", initPsetOrQsets, setDescription, allPsetOrQtoSetsName); outF.WriteLine(" {"); outF.WriteLine(" IList<{0}> {1} = new List<{0}>();", setDescription, theSetName); int groupId = offset; int defaultGroupId = 2; if (!paramGroupDict.ContainsKey("Revit IFCExporter Parameters")) { paramGroupDict.Add("Revit IFCExporter Parameters", defaultGroupId); } foreach (KeyValuePair <string, IList <VersionSpecificPropertyDef> > psetDefEntry in procPsetDef.allPDefDict) { // Skip key (name) that does not start with the requested type if (!psetDefEntry.Key.StartsWith(whichCat.ToString(), StringComparison.InvariantCultureIgnoreCase)) { continue; } outF.WriteLine(" Init" + psetDefEntry.Key + "({0});", theSetName); if (!paramGroupDict.ContainsKey(psetDefEntry.Key)) { paramGroupDict.Add(psetDefEntry.Key, groupId++); } } outF.WriteLine("\r\n allPsetOrQtoSets.Add({0});", theSetName); outF.WriteLine(" }"); outF.WriteLine(""); // For Pset or QtoSet definitions foreach (KeyValuePair <string, IList <VersionSpecificPropertyDef> > psetDefEntry in procPsetDef.allPDefDict) { // Skip key (name) that does not start with the requested type if (!psetDefEntry.Key.StartsWith(whichCat.ToString(), StringComparison.InvariantCultureIgnoreCase)) { continue; } string varName = null; string setsName = null; string psetName = psetDefEntry.Key; switch (whichCat) { case "Pset": setsName = "commonPropertySets"; outF.WriteLine(" private static void Init" + psetName + "(IList<{0}> {1})", setDescription, setsName); varName = psetDefEntry.Key.Replace("Pset_", "propertySet"); outF.WriteLine(" {"); outF.WriteLine(" {0} {1} = new {0}();", setDescription, varName); outF.WriteLine(" {0}.Name = \"{1}\";", varName, psetName); outF.WriteLine(" PropertySetEntry ifcPSE = null;"); break; case "Ifc": setsName = "commonPropertySets"; outF.WriteLine(" private static void Init" + psetName + "(IList<{0}> {1})", setDescription, setsName); varName = psetDefEntry.Key.Replace("Pset_", "propertySet"); outF.WriteLine(" {"); outF.WriteLine(" {0} {1} = new {0}();", setDescription, varName); outF.WriteLine(" {0}.Name = \"{1}\";", varName, psetName); outF.WriteLine(" PropertySetEntry ifcPSE = null;"); break; case "Qto": setsName = "quantitySets"; outF.WriteLine(" private static void Init" + psetName + "(IList<{0}> {1})", setDescription, setsName); varName = psetDefEntry.Key.Replace("Qto_", "qtoSet"); outF.WriteLine(" {"); outF.WriteLine(" {0} {1} = new {0}();", setDescription, varName); outF.WriteLine(" {0}.Name = \"{1}\";", varName, psetName); outF.WriteLine(" QuantityEntry ifcPSE = null;"); break; default: logF.WriteLine("Category not supported {0}! Use only \"Pset\", \"Qto\", or \"Ifc\"", whichCat); break; } outF.WriteLine(" Type calcType = null;"); foreach (VersionSpecificPropertyDef vspecPDef in psetDefEntry.Value) { PsetDefinition pDef = vspecPDef.PropertySetDef; if (vspecPDef.IfcVersion.StartsWith("IFC2X2", StringComparison.CurrentCultureIgnoreCase)) { outF.WriteLine(" if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2 && certifiedEntityAndPsetList.AllowPsetToBeCreated(ExporterCacheManager.ExportOptionsCache.FileVersion.ToString().ToUpper(), \"" + psetName + "\"))"); outF.WriteLine(" {"); foreach (string applEnt in vspecPDef.PropertySetDef.ApplicableClasses) { string applEnt2 = applEnt; if (string.IsNullOrEmpty(applEnt)) { applEnt2 = "IfcBuildingElementProxy"; // Default if somehow the data is empty } outF.WriteLine(" {0}.EntityTypes.Add(IFCEntityType.{1});", varName, applEnt2); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.ApplicableType)) { outF.WriteLine(" {0}.ObjectType = \"{1}\";", varName, vspecPDef.PropertySetDef.ApplicableType); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.PredefinedType)) { outF.WriteLine(" {0}.PredefinedType = \"{1}\";", varName, vspecPDef.PropertySetDef.PredefinedType); } } else if (vspecPDef.IfcVersion.StartsWith("IFC2X3", StringComparison.CurrentCultureIgnoreCase) || vspecPDef.IfcVersion.Equals("IFC2X3_TC1", StringComparison.CurrentCultureIgnoreCase)) { outF.WriteLine(" if (ExporterCacheManager.ExportOptionsCache.ExportAs2x3 && certifiedEntityAndPsetList.AllowPsetToBeCreated(ExporterCacheManager.ExportOptionsCache.FileVersion.ToString().ToUpper(), \"" + psetName + "\"))"); outF.WriteLine(" {"); foreach (string applEnt in vspecPDef.PropertySetDef.ApplicableClasses) { string applEnt2 = applEnt; if (string.IsNullOrEmpty(applEnt)) { applEnt2 = "IfcBuildingElementProxy"; // Default if somehow the data is empty } outF.WriteLine(" {0}.EntityTypes.Add(IFCEntityType.{1});", varName, applEnt2); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.ApplicableType)) { outF.WriteLine(" {0}.ObjectType = \"{1}\";", varName, vspecPDef.PropertySetDef.ApplicableType); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.PredefinedType)) { outF.WriteLine(" {0}.PredefinedType = \"{1}\";", varName, vspecPDef.PropertySetDef.PredefinedType); } } else if (vspecPDef.SchemaFileVersion.Equals("IFC4_ADD1", StringComparison.CurrentCultureIgnoreCase)) { outF.WriteLine(" if (ExporterCacheManager.ExportOptionsCache.ExportAs4_ADD1 && certifiedEntityAndPsetList.AllowPsetToBeCreated(ExporterCacheManager.ExportOptionsCache.FileVersion.ToString().ToUpper(), \"" + psetName + "\"))"); outF.WriteLine(" {"); foreach (string applEnt in vspecPDef.PropertySetDef.ApplicableClasses) { string applEnt2 = applEnt; if (string.IsNullOrEmpty(applEnt)) { applEnt2 = "IfcBuildingElementProxy"; // Default if somehow the data is empty } outF.WriteLine(" {0}.EntityTypes.Add(IFCEntityType.{1});", varName, applEnt2); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.ApplicableType)) { outF.WriteLine(" {0}.ObjectType = \"{1}\";", varName, vspecPDef.PropertySetDef.ApplicableType); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.PredefinedType)) { outF.WriteLine(" {0}.PredefinedType = \"{1}\";", varName, vspecPDef.PropertySetDef.PredefinedType); } } else if (vspecPDef.SchemaFileVersion.Equals("IFC4_ADD2", StringComparison.CurrentCultureIgnoreCase)) { outF.WriteLine(" if (ExporterCacheManager.ExportOptionsCache.ExportAs4 && certifiedEntityAndPsetList.AllowPsetToBeCreated(ExporterCacheManager.ExportOptionsCache.FileVersion.ToString().ToUpper(), \"" + psetName + "\"))"); outF.WriteLine(" {"); foreach (string applEnt in vspecPDef.PropertySetDef.ApplicableClasses) { string applEnt2 = applEnt; if (string.IsNullOrEmpty(applEnt)) { applEnt2 = "IfcBuildingElementProxy"; // Default if somehow the data is empty } outF.WriteLine(" {0}.EntityTypes.Add(IFCEntityType.{1});", varName, applEnt2); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.ApplicableType)) { outF.WriteLine(" {0}.ObjectType = \"{1}\";", varName, vspecPDef.PropertySetDef.ApplicableType); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.PredefinedType)) { outF.WriteLine(" {0}.PredefinedType = \"{1}\";", varName, vspecPDef.PropertySetDef.PredefinedType); } } else if (vspecPDef.SchemaFileVersion.Equals("IFC4", StringComparison.CurrentCultureIgnoreCase)) { outF.WriteLine(" if (ExporterCacheManager.ExportOptionsCache.ExportAs4 && certifiedEntityAndPsetList.AllowPsetToBeCreated(ExporterCacheManager.ExportOptionsCache.FileVersion.ToString().ToUpper(), \"" + psetName + "\"))"); outF.WriteLine(" {"); foreach (string applEnt in vspecPDef.PropertySetDef.ApplicableClasses) { string applEnt2 = applEnt; if (string.IsNullOrEmpty(applEnt)) { applEnt2 = "IfcBuildingElementProxy"; // Default if somehow the data is empty } outF.WriteLine(" {0}.EntityTypes.Add(IFCEntityType.{1});", varName, applEnt2); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.ApplicableType)) { outF.WriteLine(" {0}.ObjectType = \"{1}\";", varName, vspecPDef.PropertySetDef.ApplicableType); } if (!string.IsNullOrEmpty(vspecPDef.PropertySetDef.PredefinedType)) { outF.WriteLine(" {0}.PredefinedType = \"{1}\";", varName, vspecPDef.PropertySetDef.PredefinedType); } } else { logF.WriteLine("%Error - Unrecognized schema version : " + vspecPDef.SchemaFileVersion); } //} // Process each property foreach (PsetProperty prop in pDef.properties) { // Handle only one level deep of complex property !!!! if (prop.PropertyType is ComplexProperty) { ComplexProperty complexProp = prop.PropertyType as ComplexProperty; // For complex property the properties will be flattened by using <Pset>.<Property>.<SubProperty> foreach (PsetProperty propCx in complexProp.Properties) { string prefixName = prop.Name; procPsetDef.processSimpleProperty(outF, psetName, propCx, prefixName, pDef.IfcVersion, vspecPDef.SchemaFileVersion, varName, vspecPDef, penumFileName); } } else { procPsetDef.processSimpleProperty(outF, psetName, prop, null, pDef.IfcVersion, vspecPDef.SchemaFileVersion, varName, vspecPDef, penumFileName); } } outF.WriteLine(" }"); } outF.WriteLine(" if (ifcPSE != null)"); outF.WriteLine(" {"); outF.WriteLine(" {0}.Add({1});", setsName, varName); outF.WriteLine(" }"); outF.WriteLine(" }"); outF.WriteLine(""); outF.WriteLine(""); } outF.WriteLine(" }"); outF.WriteLine("}"); outF.Close(); return(groupId); }
private void button_Go_Click(object sender, RoutedEventArgs e) { string tempFolder = System.IO.Path.GetTempPath(); logF = new StreamWriter(Path.Combine(tempFolder, "GeneratePsetDefWin.log")); textBox_OutputMsg.Clear(); string parFileNameOut = Path.Combine(Path.GetDirectoryName(SharedParFileName), Path.GetFileNameWithoutExtension(SharedParFileName) + "_out.txt"); stSharedPar = File.CreateText(parFileNameOut); IDictionary <string, SharedParameterDef> existingParDict = ProcessPsetDefinition.processExistingParFile(SharedParFileName); IDictionary <string, SharedParameterDef> existingTypeParDict = new Dictionary <string, SharedParameterDef>(); if (File.Exists(SharedParFileNameType)) { string typeParFileNameOut = Path.Combine(Path.GetDirectoryName(SharedParFileNameType), Path.GetFileNameWithoutExtension(SharedParFileNameType) + "_out.txt"); stSharedParType = File.CreateText(typeParFileNameOut); existingTypeParDict = ProcessPsetDefinition.processExistingParFile(SharedParFileNameType); } else { stSharedParType = File.CreateText(SharedParFileNameType); } ProcessPsetDefinition procPsetDef = new ProcessPsetDefinition(logF); if (string.IsNullOrEmpty(textBox_PSDSourceDir.Text) || string.IsNullOrEmpty(textBox_OutputFile.Text)) { return; } var psdFolders = new DirectoryInfo(textBox_PSDSourceDir.Text).GetDirectories("psd", SearchOption.AllDirectories); var qtoFolders = new DirectoryInfo(textBox_PSDSourceDir.Text).GetDirectories("qto", SearchOption.AllDirectories); string dirName = Path.GetDirectoryName(textBox_OutputFile.Text); string outFileName = Path.GetFileNameWithoutExtension(textBox_OutputFile.Text); string penumFileName = Path.Combine(dirName, outFileName); // Collect all Pset definition for psd folders Dictionary <ItemsInPsetQtoDefs, string> keywordsToProcess = PsetOrQto.PsetOrQtoDefItems[PsetOrQtoSetEnum.PROPERTYSET]; HashSet <string> IfcSchemaProcessed = new HashSet <string>(); foreach (DirectoryInfo psd in psdFolders) { string schemaFolder = psd.FullName.Remove(0, textBox_PSDSourceDir.Text.Length + 1).Split('\\')[0]; logF.WriteLine("\r\n*** Processing " + schemaFolder); foreach (DirectoryInfo subDir in psd.GetDirectories()) { procPsetDef.ProcessSchemaPsetDef(schemaFolder, subDir, keywordsToProcess); } procPsetDef.ProcessSchemaPsetDef(schemaFolder, psd, keywordsToProcess); IfcSchemaProcessed.Add(schemaFolder); } // Collect all QtoSet definition for qto folders keywordsToProcess = PsetOrQto.PsetOrQtoDefItems[PsetOrQtoSetEnum.QTOSET]; foreach (DirectoryInfo qto in qtoFolders) { string schemaFolder = qto.FullName.Remove(0, textBox_PSDSourceDir.Text.Length + 1).Split('\\')[0]; logF.WriteLine("\r\n*** Processing " + schemaFolder); foreach (DirectoryInfo subDir in qto.GetDirectories()) { procPsetDef.ProcessSchemaPsetDef(schemaFolder, subDir, keywordsToProcess); } procPsetDef.ProcessSchemaPsetDef(schemaFolder, qto, keywordsToProcess); } // Process predefined properties foreach (string schemaName in IfcSchemaProcessed) { logF.WriteLine("\r\n*** Processing " + schemaName); procPsetDef.ProcessPredefinedPsets(schemaName); } // For testing purpose: Dump all the propertyset definition in a text file if (checkBox_Dump.IsChecked.HasValue && checkBox_Dump.IsChecked.Value) { string pSetDump = ""; foreach (KeyValuePair <string, IList <VersionSpecificPropertyDef> > psetDefEntry in procPsetDef.allPDefDict) { pSetDump += "**** Property Set Name: " + psetDefEntry.Key; foreach (VersionSpecificPropertyDef vPdef in psetDefEntry.Value) { pSetDump += "\r\n ===> IfcVersion: " + vPdef.IfcVersion; pSetDump += "\r\n" + vPdef.PropertySetDef.ToString() + "\r\n"; } pSetDump += "\r\n\n"; } string dumpDir = Path.GetDirectoryName(textBox_OutputFile.Text); string dumpFile = Path.GetFileNameWithoutExtension(textBox_OutputFile.Text) + ".txt"; string dumpFilePath = Path.Combine(dumpDir, dumpFile); if (File.Exists(dumpFilePath)) { File.Delete(dumpFilePath); } StreamWriter tx = new StreamWriter(dumpFilePath); tx.Write(pSetDump); tx.Close(); } IDictionary <string, int> groupParamDict = new Dictionary <string, int>(); string[] outFNameParts = outFileName.Split('_'); // Do it for the predefined propserty sets string fNameToProcess = Path.Combine(dirName, outFNameParts[0] + "_PredefPset.cs"); if (File.Exists(fNameToProcess)) { File.Delete(fNameToProcess); } StreamWriter outF = new StreamWriter(fNameToProcess); // Group ID 1 and 2 are reserved int offset = 3; offset = WriteGeneratedCode(outF, procPsetDef, penumFileName, "Ifc", groupParamDict, offset); // Do it for the predefined propserty sets fNameToProcess = Path.Combine(dirName, outFNameParts[0] + "_PsetDef.cs"); if (File.Exists(fNameToProcess)) { File.Delete(fNameToProcess); } outF = new StreamWriter(fNameToProcess); offset = WriteGeneratedCode(outF, procPsetDef, penumFileName, "Pset", groupParamDict, offset); // Do it for the predefined propserty sets fNameToProcess = Path.Combine(dirName, outFNameParts[0] + "_QsetDef.cs"); if (File.Exists(fNameToProcess)) { File.Delete(fNameToProcess); } outF = new StreamWriter(fNameToProcess); offset = WriteGeneratedCode(outF, procPsetDef, penumFileName, "Qto", groupParamDict, offset); // Close the Enum files procPsetDef.endWriteEnumFile(); WriteRevitSharedParam(stSharedPar, existingParDict, groupParamDict, false, out IList <string> deferredParList); AppendDeferredParamList(stSharedPar, deferredParList); stSharedPar.Close(); WriteRevitSharedParam(stSharedParType, existingTypeParDict, groupParamDict, true, out IList <string> deferredParTypeList); AppendDeferredParamList(stSharedParType, deferredParTypeList); stSharedParType.Close(); logF.Close(); }
PsetDefinition Process(string schemaVersion, FileInfo PSDfileName) { PsetDefinition pset = new PsetDefinition(); XDocument doc = XDocument.Load(PSDfileName.FullName); // Older versions of psd uses namespace! var nsInfo = doc.Root.Attributes("xmlns").FirstOrDefault(); XNamespace ns = ""; if (nsInfo != null) { ns = nsInfo.Value; } pset.Name = doc.Elements(ns + "PropertySetDef").Elements(ns + "Name").FirstOrDefault().Value; pset.IfcVersion = doc.Elements(ns + "PropertySetDef").Elements(ns + "IfcVersion").FirstOrDefault().Attribute("version").Value.Replace(" ", ""); if (pset.IfcVersion.StartsWith("2")) { if (pset.IfcVersion.Equals("2X", StringComparison.CurrentCultureIgnoreCase)) { pset.IfcVersion = "IFC" + pset.IfcVersion.ToUpper() + "2"; // BUG in the documentation. It ony contains "2x" instead of "2x2" } else { pset.IfcVersion = "IFC" + pset.IfcVersion.ToUpper(); // Namespace cannot start with a number. e.g. make sure 2x3 -> IFC2x3 } } else if (pset.IfcVersion.StartsWith("IFC4")) { pset.IfcVersion = schemaVersion.ToUpper(); } if (doc.Element(ns + "PropertySetDef").Attribute("ifdguid") != null) { pset.IfdGuid = doc.Element(ns + "PropertySetDef").Attribute("ifdguid").Value; } // Get applicable classes IEnumerable <XElement> applicableClasses = from el in doc.Descendants(ns + "ClassName") select el; IList <string> applClassesList = new List <string>(); foreach (XElement applClass in applicableClasses) { string className = ProcessPsetDefinition.removeInvalidNName(applClass.Value); if (!string.IsNullOrEmpty(className)) { applClassesList.Add(className); } } pset.ApplicableClasses = applClassesList; XElement applType = doc.Elements(ns + "PropertySetDef").Elements(ns + "ApplicableTypeValue").FirstOrDefault(); if (applType != null) { string applicableType = applType.Value; if (!string.IsNullOrEmpty(applicableType) && !applicableType.Equals("N/A", StringComparison.InvariantCultureIgnoreCase)) { // Remove "SELF\" in the applicable type if (applicableType.Contains("SELF\\")) { applicableType = applicableType.Replace("SELF\\", ""); } string[] applTypeStr = applicableType.Split('/', '.', '='); pset.ApplicableType = applTypeStr[0]; if (applTypeStr.Count() > 1) { pset.PredefinedType = applTypeStr[applTypeStr.Count() - 1].Replace("\"", ""); } // If the applicable type contains more than 1 entry, add them into the applicable classes string[] addClasses = pset.ApplicableType.Split(','); if (addClasses.Count() > 1) { foreach (string addClass in addClasses) { string addClassTr = addClass.TrimStart().TrimEnd(); if (!pset.ApplicableClasses.Contains(addClassTr)) { pset.ApplicableClasses.Add(addClassTr); } } } } } IList <PsetProperty> propList = new List <PsetProperty>(); var pDefs = from p in doc.Descendants(ns + "PropertyDef") select p; foreach (XElement pDef in pDefs) { PsetProperty prop = getPropertyDef(ns, pDef); SharedParameterDef shPar = new SharedParameterDef(); if (prop == null) { #if DEBUG logF.WriteLine("%Error: Mising PropertyType data for {0}.{1}", pset.Name, pDef.Element(ns + "Name").Value); #endif } else { propList.Add(prop); } } pset.properties = propList; return(pset); }