Skip to content

Commit

Permalink
Merged PR 1863: Switched Schema mapping to be dynamically generated e…
Browse files Browse the repository at this point in the history
….g. for AirTerminals in IFC2x3

Switched Schema mapping to be dynamically generated e.g. for AirTerminals in IFC2x3

Previously was an incomplete fixed mapping table

See bS IDS Issue [116](buildingSMART/IDS#116)
  • Loading branch information
andyward committed Oct 31, 2023
1 parent d826bc8 commit 861f584
Showing 1 changed file with 43 additions and 41 deletions.
84 changes: 43 additions & 41 deletions Xbim.IDS.Validator.Core/Helpers/SchemaTypeMap.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Xbim.Common;
using Xbim.Common.Metadata;
using Xbim.InformationSpecifications.Helpers;

namespace Xbim.IDS.Validator.Core.Helpers
Expand Down Expand Up @@ -41,51 +43,51 @@ internal class SchemaTypeMap
return null;
}


private static Lazy<IDictionary<string, SchemaInference>> lazySchemaMap = new Lazy<IDictionary<string, SchemaInference>>(() => BuildSchemaInferenceMappings());

static IDictionary<string, SchemaInference> _ifc2x3Inferences => lazySchemaMap.Value;

// Inferences: New types in later schemas that can be inferred in older schemas using Type information
static IDictionary<string, SchemaInference> BuildSchemaInferenceMappings()
{
var baseSchema = ExpressMetaData.GetMetadata(typeof(Ifc2x3.EntityFactoryIfc2x3).Module);
var targetSchema = ExpressMetaData.GetMetadata(typeof(Ifc4.EntityFactoryIfc4).Module);

var implicitlyMapped = GetMappings(baseSchema, targetSchema);

var dict = new Dictionary<string, SchemaInference>();

foreach( var mapping in implicitlyMapped )
{
var inference = new SchemaInference(SchemaInfo.SchemaIfc2x3[mapping.NewType.SuperType.ExpressName], SchemaInfo.SchemaIfc2x3[mapping.DefinedBy.ExpressName]);
dict.Add(mapping.NewType.ExpressNameUpper, inference);
}
return dict;

static IDictionary<string, SchemaInference> _ifc2x3Inferences = new Dictionary<string, SchemaInference>()
}



private static IEnumerable<(ExpressType NewType, ExpressType DefinedBy)> GetMappings(ExpressMetaData baseSchema, ExpressMetaData targetSchema)
{
//Terminals
["IFCAIRTERMINAL"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowTerminal"], SchemaInfo.SchemaIfc2x3["IfcAirTerminalType"]),
// AV - IFC4
// Comms Appliance - IFC4
["IFCELECTRICAPPLIANCE"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowTerminal"], SchemaInfo.SchemaIfc2x3["IfcElectricApplianceType"]),
["IFCFIRESUPPRESSIONTERMINAL"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowTerminal"], SchemaInfo.SchemaIfc2x3["IfcFireSuppressionTerminalType"]),
["IFCLAMP"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowTerminal"], SchemaInfo.SchemaIfc2x3["IfcLampType"]),
["IFCLIGHTFIXTURE"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowTerminal"], SchemaInfo.SchemaIfc2x3["IfcLightFixtureType"]),
// Medical
["IFCOUTLET"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowTerminal"], SchemaInfo.SchemaIfc2x3["IfcOutletType"]),
["IFCSANITARYTERMINAL"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowTerminal"], SchemaInfo.SchemaIfc2x3["IfcSanitaryTerminalType"]),
["IFCSPACEHEATER"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowTerminal"], SchemaInfo.SchemaIfc2x3["IfcSpaceHeaterType"]),
["IFCWASTETERMINAL"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowTerminal"], SchemaInfo.SchemaIfc2x3["IfcWasteTerminalType"]),

// Segments
["IFCPIPESEGMENT"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowSegment"], SchemaInfo.SchemaIfc2x3["IfcPipeSegmentType"]),
["IFCDUCTSEGMENT"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowSegment"], SchemaInfo.SchemaIfc2x3["IfcDuctSegmentType"]),
["IFCCABLECARRIERSEGMENT"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowSegment"], SchemaInfo.SchemaIfc2x3["IfcCableCarrierSegmentType"]),
["IFCCABLESEGMENT"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowSegment"], SchemaInfo.SchemaIfc2x3["IfcCableSegmentType"]),

// Energy Conversion
["IFCBOILER"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcEnergyConversionDevice"], SchemaInfo.SchemaIfc2x3["IfcBoilerType"]),
["IFCCHILLER"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcEnergyConversionDevice"], SchemaInfo.SchemaIfc2x3["IfcChillerType"]),
["IFCCOOLEDBEAM"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcEnergyConversionDevice"], SchemaInfo.SchemaIfc2x3["IfcCooledBeamType"]),
["IFCTRANSFORMER"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcEnergyConversionDevice"], SchemaInfo.SchemaIfc2x3["IfcTransformerType"]),
["IFCUNITARYEQUIPMENT"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcEnergyConversionDevice"], SchemaInfo.SchemaIfc2x3["IfcUnitaryEquipmentType"]),
// Storage
["IFCTANK"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowStorageDevice"], SchemaInfo.SchemaIfc2x3["IfcTankType"]),

// Flow Controllers
["IFCAIRTERMINALBOX"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowController"], SchemaInfo.SchemaIfc2x3["IfcAirTerminalBoxType"]),
["IFCDAMPER"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowController"], SchemaInfo.SchemaIfc2x3["IfcDamperType"]),
// Missing ElectricDistributionBoard is 4x only
["IFCELECTRICTIMECONTROL"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowController"], SchemaInfo.SchemaIfc2x3["IfcElectricTimeControlType"]),
["IFCFLOWMETER"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowController"], SchemaInfo.SchemaIfc2x3["IfcFlowMeterType"]),
["IFCPROTECTIVEDEVICE"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowController"], SchemaInfo.SchemaIfc2x3["IfcProtectiveDeviceType"]),
["IFCSWITCHINGDEVICE"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowController"], SchemaInfo.SchemaIfc2x3["IfcSwitchingDeviceType"]),
["IFCVALVE"] = new SchemaInference(SchemaInfo.SchemaIfc2x3["IfcFlowController"], SchemaInfo.SchemaIfc2x3["IfcValveType"]),
//
var products = targetSchema.ExpressType("IFCPRODUCT");

};
foreach (var type in products.AllSubTypes)
{
if (baseSchema.ExpressType(type.ExpressNameUpper) == null)
{
// New in the targer schema. Check if a Type exists by convention we can use
var baseSchemaType = baseSchema.ExpressType(type.ExpressNameUpper + "TYPE");
if (baseSchemaType != null)
{
// New but with Type we can use to discriminate in base schema
yield return (type, baseSchemaType);
}

}
}
}


// Substitutions: where a type is deprecated / removed and there's a forwarding type we can use
Expand Down

0 comments on commit 861f584

Please sign in to comment.