/// <summary> /// Processes IfcRepresentationContext attributes. /// </summary> /// <param name="ifcRepresentationContext">The IfcRepresentationContext handle.</param> override protected void Process(IFCAnyHandle ifcRepresentationContext) { base.Process(ifcRepresentationContext); Identifier = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentationContext, "ContextIdentifier", null); Type = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentationContext, "ContextType", null); if (IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationContext, IFCEntityType.IfcGeometricRepresentationContext)) { bool found = false; CoordinateSpaceDimension = IFCImportHandleUtil.GetRequiredIntegerAttribute(ifcRepresentationContext, "CoordinateSpaceDimension", out found); if (!found) { CoordinateSpaceDimension = 3; // Don't throw, just set to default 3D. } Precision = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(ifcRepresentationContext, "Precision", IFCImportFile.TheFile.Document.Application.VertexTolerance); IFCAnyHandle worldCoordinateSystem = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcRepresentationContext, "WorldCoordinateSystem", false); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(worldCoordinateSystem)) { WorldCoordinateSystem = IFCLocation.ProcessIFCAxis2Placement(worldCoordinateSystem); } else { WorldCoordinateSystem = Transform.Identity; } // For IfcGeometricRepresentationSubContext, it seems as if try { IFCAnyHandle trueNorth = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcRepresentationContext, "TrueNorth"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(trueNorth)) { TrueNorth = IFCPoint.ProcessNormalizedIFCDirection(trueNorth); } else { TrueNorth = XYZ.BasisZ; } } catch { TrueNorth = XYZ.BasisZ; } if (IFCImportFile.TheFile.SchemaVersion >= IFCSchemaVersion.IFC2x2 && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationContext, IFCEntityType.IfcGeometricRepresentationSubContext)) { IFCAnyHandle parentContext = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcRepresentationContext, "ParentContext", true); ParentContext = IFCRepresentationContext.ProcessIFCRepresentationContext(parentContext); TargetScale = IFCImportHandleUtil.GetOptionalPositiveRatioAttribute(ifcRepresentationContext, "TargetScale", 1.0); TargetView = IFCEnums.GetSafeEnumerationAttribute <IFCGeometricProjection>(ifcRepresentationContext, "TargetView", IFCGeometricProjection.NotDefined); UserDefinedTargetView = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentationContext, "UserDefinedTargetView", null); } } }
protected override void Process(IFCAnyHandle ifcSurface) { base.Process(ifcSurface); bool foundUDegree = false; UDegree = IFCImportHandleUtil.GetRequiredIntegerAttribute(ifcSurface, "UDegree", out foundUDegree); if (!foundUDegree) { Importer.TheLog.LogError(ifcSurface.StepId, "Cannot find the UDegree attribute of this surface", true); } bool foundVDegree = false; VDegree = IFCImportHandleUtil.GetRequiredIntegerAttribute(ifcSurface, "VDegree", out foundVDegree); if (!foundVDegree) { Importer.TheLog.LogError(ifcSurface.StepId, "Cannot find the VDegree attribute of this surface", true); } IList <IList <IFCAnyHandle> > controlPoints = IFCImportHandleUtil.GetListOfListOfInstanceAttribute(ifcSurface, "ControlPointsList"); if (controlPoints == null || controlPoints.Count == 0) { Importer.TheLog.LogError(ifcSurface.StepId, "This surface has invalid number of control points", true); } List <IFCAnyHandle> controlPointsTmp = new List <IFCAnyHandle>(); foreach (List <IFCAnyHandle> list in controlPoints) { controlPointsTmp.AddRange(list); } ControlPointsList = IFCPoint.ProcessScaledLengthIFCCartesianPoints(controlPointsTmp); bool foundUClosed = false; UClosed = IFCImportHandleUtil.GetOptionalLogicalAttribute(ifcSurface, "UClosed", out foundUClosed); if (!foundUClosed) { Importer.TheLog.LogWarning(ifcSurface.StepId, "Cannot find the UClosed attribute of this surface, setting to Unknown", true); UClosed = IFCLogical.Unknown; } bool foundVClosed = false; VClosed = IFCImportHandleUtil.GetOptionalLogicalAttribute(ifcSurface, "VClosed", out foundVClosed); if (!foundVClosed) { Importer.TheLog.LogWarning(ifcSurface.StepId, "Cannot find the VClosed attribute of this surface, setting to Unknown", true); VClosed = IFCLogical.Unknown; } }
protected override void Process(IFCAnyHandle ifcCurve) { base.Process(ifcCurve); bool foundDegree = false; Degree = IFCImportHandleUtil.GetRequiredIntegerAttribute(ifcCurve, "Degree", out foundDegree); if (!foundDegree) { Importer.TheLog.LogError(ifcCurve.StepId, "Cannot find the degree of this curve", true); } IList <IFCAnyHandle> controlPoints = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(ifcCurve, "ControlPointsList"); if (controlPoints == null || controlPoints.Count == 0) { Importer.TheLog.LogError(ifcCurve.StepId, "This curve has invalid number of control points", true); } IList <XYZ> controlPointLists = new List <XYZ>(); foreach (IFCAnyHandle point in controlPoints) { XYZ pointXYZ = IFCPoint.ProcessScaledLengthIFCCartesianPoint(point); controlPointLists.Add(pointXYZ); } ControlPointsList = controlPointLists; bool foundClosedCurve = false; IFCLogical closedCurve = IFCImportHandleUtil.GetOptionalLogicalAttribute(ifcCurve, "ClosedCurve", out foundClosedCurve); if (!foundClosedCurve) { Importer.TheLog.LogWarning(ifcCurve.StepId, "Cannot find the ClosedCurve property of this curve, ignoring", false); ClosedCurve = null; } else { ClosedCurve = (closedCurve == IFCLogical.True); } }
/// <summary> /// Processes an IfcDerivedUnit. /// </summary> /// <param name="unitHnd">The unit handle.</param> void ProcessIFCDerivedUnit(IFCAnyHandle unitHnd) { List <IFCAnyHandle> elements = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(unitHnd, "Elements"); IList <KeyValuePair <IFCUnit, int> > derivedElementUnitHnds = new List <KeyValuePair <IFCUnit, int> >(); foreach (IFCAnyHandle subElement in elements) { IFCAnyHandle derivedElementUnitHnd = IFCImportHandleUtil.GetRequiredInstanceAttribute(subElement, "Unit", false); IFCUnit subUnit = IFCAnyHandleUtil.IsNullOrHasNoValue(derivedElementUnitHnd) ? null : IFCUnit.ProcessIFCUnit(derivedElementUnitHnd); if (subUnit != null) { bool found; int exponent = IFCImportHandleUtil.GetRequiredIntegerAttribute(subElement, "Exponent", out found); if (found) { derivedElementUnitHnds.Add(new KeyValuePair <IFCUnit, int>(subUnit, exponent)); } } } // the DerivedUnitExpectedTypes object is a description of one possible set of base units for a particular derived unit. // The IList allows for possible different interpretations. For example, Volumetric Flow Rate could be defined by m^3/s (length ^ 3 / time) or L/s (volume / time). IList <DerivedUnitExpectedTypes> expectedTypesList = new List <DerivedUnitExpectedTypes>(); string unitType = IFCAnyHandleUtil.GetEnumerationAttribute(unitHnd, "UnitType"); if (string.Compare(unitType, "LINEARVELOCITYUNIT", true) == 0) { UnitType = UnitType.UT_HVAC_Velocity; UnitSystem = UnitSystem.Metric; // Support only m / s. DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_METERS_PER_SECOND, UnitSymbolType.UST_M_PER_S); expectedTypes.AddExpectedType(1, UnitType.UT_Length); expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT"); expectedTypesList.Add(expectedTypes); } else if (string.Compare(unitType, "THERMALTRANSMITTANCEUNIT", true) == 0) { UnitType = UnitType.UT_HVAC_CoefficientOfHeatTransfer; UnitSystem = UnitSystem.Metric; // Support W / (K * m^2) or kg / (K * s^3) DerivedUnitExpectedTypes expectedTypesWinvKinvM2 = new DerivedUnitExpectedTypes(UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN, UnitSymbolType.UST_WATT_PER_SQ_M_K); expectedTypesWinvKinvM2.AddExpectedType(1, UnitType.UT_HVAC_Power); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to. expectedTypesWinvKinvM2.AddExpectedType(-1, UnitType.UT_HVAC_Temperature); expectedTypesWinvKinvM2.AddExpectedType(-2, UnitType.UT_Length); expectedTypesList.Add(expectedTypesWinvKinvM2); DerivedUnitExpectedTypes expectedTypesWinvKinvArea = new DerivedUnitExpectedTypes(UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN, UnitSymbolType.UST_WATT_PER_SQ_M_K); expectedTypesWinvKinvArea.AddExpectedType(1, UnitType.UT_HVAC_Power); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to. expectedTypesWinvKinvArea.AddExpectedType(-1, UnitType.UT_HVAC_Temperature); expectedTypesWinvKinvArea.AddExpectedType(-1, UnitType.UT_Area); expectedTypesList.Add(expectedTypesWinvKinvArea); DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN, UnitSymbolType.UST_WATT_PER_SQ_M_K); expectedTypes.AddExpectedType(1, UnitType.UT_Mass); expectedTypes.AddExpectedType(-1, UnitType.UT_HVAC_Temperature); expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT"); expectedTypesList.Add(expectedTypes); } else if (string.Compare(unitType, "VOLUMETRICFLOWRATEUNIT", true) == 0) { UnitType = UnitType.UT_HVAC_Airflow; UnitSystem = UnitSystem.Metric; // Support L / s or m^3 / s in the IFC file. // L / s DerivedUnitExpectedTypes expectedTypesLPerS = new DerivedUnitExpectedTypes(UnitName.DUT_LITERS_PER_SECOND, UnitSymbolType.UST_L_PER_S); expectedTypesLPerS.AddExpectedType(1, UnitType.UT_Volume); expectedTypesLPerS.AddCustomExpectedType(-1, "TIMEUNIT"); expectedTypesList.Add(expectedTypesLPerS); // m^3 / s. DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_CUBIC_METERS_PER_SECOND, UnitSymbolType.UST_CU_M_PER_S); expectedTypes.AddExpectedType(3, UnitType.UT_Length); expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT"); expectedTypesList.Add(expectedTypes); } else if (string.Compare(unitType, "MASSDENSITYUNIT", true) == 0) { UnitType = UnitType.UT_MassDensity; UnitSystem = UnitSystem.Metric; // Support kg / m^3 in the IFC file. // kg / m^3. DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_KILOGRAMS_PER_CUBIC_METER, UnitSymbolType.UST_KG_PER_CU_M); expectedTypes.AddExpectedType(1, UnitType.UT_Mass); expectedTypes.AddExpectedType(-3, UnitType.UT_Length); expectedTypesList.Add(expectedTypes); } else if (string.Compare(unitType, "USERDEFINED", true) == 0) { // Look at the sub-types to see what we support. string userDefinedType = IFCImportHandleUtil.GetOptionalStringAttribute(unitHnd, "UserDefinedType", null); if (!string.IsNullOrWhiteSpace(userDefinedType)) { if (string.Compare(userDefinedType, "Luminous Efficacy", true) == 0) { UnitType = UnitType.UT_Electrical_Efficacy; UnitSystem = UnitSystem.Metric; // Support only lm / W. DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_LUMENS_PER_WATT, UnitSymbolType.UST_LM_PER_W); expectedTypes.AddExpectedType(-1, UnitType.UT_Mass); expectedTypes.AddExpectedType(-2, UnitType.UT_Length); expectedTypes.AddCustomExpectedType(3, "TIMEUNIT"); expectedTypes.AddExpectedType(1, UnitType.UT_Electrical_Luminous_Flux); expectedTypesList.Add(expectedTypes); } else if (string.Compare(userDefinedType, "Friction Loss", true) == 0) { UnitType = UnitType.UT_HVAC_Friction; UnitSystem = UnitSystem.Metric; // Support only Pa / m. DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_PASCALS_PER_METER, UnitSymbolType.UST_PASCAL_PER_M); expectedTypes.AddExpectedType(-2, UnitType.UT_Length); expectedTypes.AddExpectedType(1, UnitType.UT_Mass); expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT"); expectedTypesList.Add(expectedTypes); } } } foreach (DerivedUnitExpectedTypes derivedUnitExpectedTypes in expectedTypesList) { double scaleFactor = 1.0; if (derivedUnitExpectedTypes.Matches(derivedElementUnitHnds, out scaleFactor)) { // Found a match. UnitName = derivedUnitExpectedTypes.UnitName; UnitSymbol = derivedUnitExpectedTypes.UnitSymbol; ScaleFactor = scaleFactor; return; } } Importer.TheLog.LogUnhandledUnitTypeError(unitHnd, unitType); }
/// <summary> /// Processes IfcRepresentationContext attributes. /// </summary> /// <param name="ifcRepresentationContext">The IfcRepresentationContext handle.</param> override protected void Process(IFCAnyHandle ifcRepresentationContext) { base.Process(ifcRepresentationContext); Identifier = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentationContext, "ContextIdentifier", null); Type = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentationContext, "ContextType", null); if (IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationContext, IFCEntityType.IfcGeometricRepresentationContext)) { bool found = false; CoordinateSpaceDimension = IFCImportHandleUtil.GetRequiredIntegerAttribute(ifcRepresentationContext, "CoordinateSpaceDimension", out found); if (!found) { CoordinateSpaceDimension = 3; // Don't throw, just set to default 3D. } Precision = IFCImportHandleUtil.GetOptionalScaledLengthAttribute(ifcRepresentationContext, "Precision", IFCImportFile.TheFile.Document.Application.VertexTolerance); IFCAnyHandle worldCoordinateSystem = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcRepresentationContext, "WorldCoordinateSystem", false); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(worldCoordinateSystem)) { WorldCoordinateSystem = IFCLocation.ProcessIFCAxis2Placement(worldCoordinateSystem); } else { WorldCoordinateSystem = Transform.Identity; } bool isSubContext = IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC2x2) && IFCAnyHandleUtil.IsSubTypeOf(ifcRepresentationContext, IFCEntityType.IfcGeometricRepresentationSubContext); if (isSubContext) { IFCAnyHandle parentContext = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcRepresentationContext, "ParentContext", true); ParentContext = IFCRepresentationContext.ProcessIFCRepresentationContext(parentContext); TrueNorth = ParentContext.TrueNorth; } else { // This used to fail for IfcGeometricRepresentationSubContext, because the TrueNorth attribute was derived from // the IfcGeometricRepresentationContext, and the toolkit returned what seemed to be a valid handle that actually // wasn't. The code has now been rewritten to avoid this issue, but we will keep the try/catch block in case we // were also catching other serious issues. try { // By default, True North points in the Y-Direction. IFCAnyHandle trueNorth = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcRepresentationContext, "TrueNorth"); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(trueNorth)) { TrueNorth = IFCPoint.ProcessNormalizedIFCDirection(trueNorth); } else { TrueNorth = XYZ.BasisY; } } catch { TrueNorth = XYZ.BasisY; } } if (isSubContext) { TargetScale = IFCImportHandleUtil.GetOptionalPositiveRatioAttribute(ifcRepresentationContext, "TargetScale", 1.0); TargetView = IFCEnums.GetSafeEnumerationAttribute <IFCGeometricProjection>(ifcRepresentationContext, "TargetView", IFCGeometricProjection.NotDefined); UserDefinedTargetView = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentationContext, "UserDefinedTargetView", null); } } }
/// <summary> /// Processes an IfcDerivedUnit. /// </summary> /// <param name="unitHnd">The unit handle.</param> void ProcessIFCDerivedUnit(IFCAnyHandle unitHnd) { List <IFCAnyHandle> elements = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(unitHnd, "Elements"); IList <KeyValuePair <IFCUnit, int> > derivedElementUnitHnds = new List <KeyValuePair <IFCUnit, int> >(); foreach (IFCAnyHandle subElement in elements) { IFCAnyHandle derivedElementUnitHnd = IFCImportHandleUtil.GetRequiredInstanceAttribute(subElement, "Unit", false); IFCUnit subUnit = IFCAnyHandleUtil.IsNullOrHasNoValue(derivedElementUnitHnd) ? null : IFCUnit.ProcessIFCUnit(derivedElementUnitHnd); if (subUnit != null) { bool found; int exponent = IFCImportHandleUtil.GetRequiredIntegerAttribute(subElement, "Exponent", out found); if (found) { derivedElementUnitHnds.Add(new KeyValuePair <IFCUnit, int>(subUnit, exponent)); } } } // the DerivedUnitExpectedTypes object is a description of one possible set of base units for a particular derived unit. // The IList allows for possible different interpretations. For example, Volumetric Flow Rate could be defined by m^3/s (length ^ 3 / time) or L/s (volume / time). IList <DerivedUnitExpectedTypes> expectedTypesList = new List <DerivedUnitExpectedTypes>(); string unitType = IFCAnyHandleUtil.GetEnumerationAttribute(unitHnd, "UnitType"); if (string.Compare(unitType, "LINEARVELOCITYUNIT", true) == 0) { Spec = SpecTypeId.HvacVelocity; UnitSystem = UnitSystem.Metric; // Support only m / s. DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.MetersPerSecond, SymbolTypeId.MPerS); expectedTypes.AddExpectedType(1, SpecTypeId.Length); expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT"); expectedTypesList.Add(expectedTypes); } else if (string.Compare(unitType, "THERMALTRANSMITTANCEUNIT", true) == 0) { Spec = SpecTypeId.HeatTransferCoefficient; UnitSystem = UnitSystem.Metric; // Support W / (K * m^2) or kg / (K * s^3) DerivedUnitExpectedTypes expectedTypesWinvKinvM2 = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerSquareMeterKelvin, SymbolTypeId.WPerMSup2K); expectedTypesWinvKinvM2.AddExpectedType(1, SpecTypeId.HvacPower); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to. expectedTypesWinvKinvM2.AddExpectedType(-1, SpecTypeId.HvacTemperature); expectedTypesWinvKinvM2.AddExpectedType(-2, SpecTypeId.Length); expectedTypesList.Add(expectedTypesWinvKinvM2); DerivedUnitExpectedTypes expectedTypesWinvKinvArea = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerSquareMeterKelvin, SymbolTypeId.WPerMSup2K); expectedTypesWinvKinvArea.AddExpectedType(1, SpecTypeId.HvacPower); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to. expectedTypesWinvKinvArea.AddExpectedType(-1, SpecTypeId.HvacTemperature); expectedTypesWinvKinvArea.AddExpectedType(-1, SpecTypeId.Area); expectedTypesList.Add(expectedTypesWinvKinvArea); DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerSquareMeterKelvin, SymbolTypeId.WPerMSup2K); expectedTypes.AddExpectedType(1, SpecTypeId.Mass); expectedTypes.AddExpectedType(-1, SpecTypeId.HvacTemperature); expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT"); expectedTypesList.Add(expectedTypes); } else if (string.Compare(unitType, "VOLUMETRICFLOWRATEUNIT", true) == 0) { Spec = SpecTypeId.AirFlow; UnitSystem = UnitSystem.Metric; // Support L / s or m^3 / s in the IFC file. // L / s DerivedUnitExpectedTypes expectedTypesLPerS = new DerivedUnitExpectedTypes(UnitTypeId.LitersPerSecond, SymbolTypeId.LPerS); expectedTypesLPerS.AddExpectedType(1, SpecTypeId.Volume); expectedTypesLPerS.AddCustomExpectedType(-1, "TIMEUNIT"); expectedTypesList.Add(expectedTypesLPerS); // m^3 / s. DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.CubicMetersPerSecond, SymbolTypeId.MSup3PerS); expectedTypes.AddExpectedType(3, SpecTypeId.Length); expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT"); expectedTypesList.Add(expectedTypes); } else if (string.Compare(unitType, "MASSDENSITYUNIT", true) == 0) { Spec = SpecTypeId.MassDensity; UnitSystem = UnitSystem.Metric; // Support kg / m^3 in the IFC file. // kg / m^3. DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.KilogramsPerCubicMeter, SymbolTypeId.KgPerMSup3); expectedTypes.AddExpectedType(1, SpecTypeId.Mass); expectedTypes.AddExpectedType(-3, SpecTypeId.Length); expectedTypesList.Add(expectedTypes); } else if (string.Compare(unitType, "LINEARFORCEUNIT", true) == 0) { Spec = SpecTypeId.LinearForce; UnitSystem = UnitSystem.Metric; // Support N / m in the IFC file. DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.NewtonsPerMeter, SymbolTypeId.NPerM); expectedTypes.AddExpectedType(1, SpecTypeId.LinearForce); expectedTypesList.Add(expectedTypes); // Support N / m in basic units DerivedUnitExpectedTypes expectedTypes2 = new DerivedUnitExpectedTypes(UnitTypeId.NewtonsPerMeter, SymbolTypeId.NPerM); expectedTypes2.AddExpectedType(1, SpecTypeId.Mass); expectedTypes2.AddExpectedType(1, SpecTypeId.Length); expectedTypes2.AddCustomExpectedType(-2, "TIMEUNIT"); expectedTypes2.AddExpectedType(-1, SpecTypeId.Length); expectedTypesList.Add(expectedTypes2); } else if (string.Compare(unitType, "PLANARFORCEUNIT", true) == 0) { Spec = SpecTypeId.AreaForce; UnitSystem = UnitSystem.Metric; // Support N / m^2 in the IFC file. DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.NewtonsPerSquareMeter, SymbolTypeId.NPerMSup2); expectedTypes.AddExpectedType(1, SpecTypeId.AreaForce); expectedTypesList.Add(expectedTypes); // Support N / m in basic units DerivedUnitExpectedTypes expectedTypes2 = new DerivedUnitExpectedTypes(UnitTypeId.NewtonsPerSquareMeter, SymbolTypeId.NPerMSup2); expectedTypes2.AddExpectedType(1, SpecTypeId.Mass); expectedTypes2.AddExpectedType(1, SpecTypeId.Length); expectedTypes2.AddCustomExpectedType(-2, "TIMEUNIT"); expectedTypes2.AddExpectedType(-2, SpecTypeId.Length); expectedTypesList.Add(expectedTypes2); } else if (string.Compare(unitType, "USERDEFINED", true) == 0) { // Look at the sub-types to see what we support. string userDefinedType = IFCImportHandleUtil.GetOptionalStringAttribute(unitHnd, "UserDefinedType", null); if (!string.IsNullOrWhiteSpace(userDefinedType)) { if (string.Compare(userDefinedType, "Luminous Efficacy", true) == 0) { Spec = SpecTypeId.Efficacy; UnitSystem = UnitSystem.Metric; // Support only lm / W. DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.LumensPerWatt, SymbolTypeId.LmPerW); expectedTypes.AddExpectedType(-1, SpecTypeId.Mass); expectedTypes.AddExpectedType(-2, SpecTypeId.Length); expectedTypes.AddCustomExpectedType(3, "TIMEUNIT"); expectedTypes.AddExpectedType(1, SpecTypeId.LuminousFlux); expectedTypesList.Add(expectedTypes); } else if (string.Compare(userDefinedType, "Friction Loss", true) == 0) { Spec = SpecTypeId.HvacFriction; UnitSystem = UnitSystem.Metric; // Support only Pa / m. DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.PascalsPerMeter, SymbolTypeId.PaPerM); expectedTypes.AddExpectedType(-2, SpecTypeId.Length); expectedTypes.AddExpectedType(1, SpecTypeId.Mass); expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT"); expectedTypesList.Add(expectedTypes); } } } foreach (DerivedUnitExpectedTypes derivedUnitExpectedTypes in expectedTypesList) { double scaleFactor = 1.0; if (derivedUnitExpectedTypes.Matches(derivedElementUnitHnds, out scaleFactor)) { // Found a match. Unit = derivedUnitExpectedTypes.Unit; Symbol = derivedUnitExpectedTypes.Symbol; ScaleFactor = scaleFactor; return; } } Importer.TheLog.LogUnhandledUnitTypeError(unitHnd, unitType); }
/// <summary> /// Processes an IfcDerivedUnit. /// </summary> /// <param name="unitHnd">The unit handle.</param> void ProcessIFCDerivedUnit(IFCAnyHandle unitHnd) { List <IFCAnyHandle> elements = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(unitHnd, "Elements"); IList <KeyValuePair <IFCUnit, int> > derivedElementUnitHnds = new List <KeyValuePair <IFCUnit, int> >(); foreach (IFCAnyHandle subElement in elements) { IFCAnyHandle derivedElementUnitHnd = IFCImportHandleUtil.GetRequiredInstanceAttribute(subElement, "Unit", false); IFCUnit subUnit = IFCAnyHandleUtil.IsNullOrHasNoValue(derivedElementUnitHnd) ? null : IFCUnit.ProcessIFCUnit(derivedElementUnitHnd); if (subUnit != null) { bool found; int exponent = IFCImportHandleUtil.GetRequiredIntegerAttribute(subElement, "Exponent", out found); if (found) { derivedElementUnitHnds.Add(new KeyValuePair <IFCUnit, int>(subUnit, exponent)); } } } ISet <Tuple <int, UnitType, string> > expectedTypes = new HashSet <Tuple <int, UnitType, string> >(); string unitType = IFCAnyHandleUtil.GetEnumerationAttribute(unitHnd, "UnitType"); if (string.Compare(unitType, "THERMALTRANSMITTANCEUNIT", true) == 0) { UnitType = UnitType.UT_HVAC_CoefficientOfHeatTransfer; UnitSystem = UnitSystem.Metric; UnitName = UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN; // Support only kg / (K * s^3). expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(1, UnitType.UT_Mass, null)); expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(-1, UnitType.UT_HVAC_Temperature, null)); expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(-3, UnitType.UT_Custom, "TIMEUNIT")); } else if (string.Compare(unitType, "VOLUMETRICFLOWRATEUNIT", true) == 0) { UnitType = UnitType.UT_HVAC_Airflow; UnitSystem = UnitSystem.Metric; UnitName = UnitName.DUT_CUBIC_METERS_PER_SECOND; // Support only m^3 / s. expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(3, UnitType.UT_Length, null)); expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(-1, UnitType.UT_Custom, "TIMEUNIT")); } else if (string.Compare(unitType, "USERDEFINED", true) == 0) { // Look at the sub-types to see what we support. string userDefinedType = IFCImportHandleUtil.GetOptionalStringAttribute(unitHnd, "UserDefinedType", null); if (!string.IsNullOrWhiteSpace(userDefinedType)) { if (string.Compare(userDefinedType, "Luminous Efficacy", true) == 0) { UnitType = UnitType.UT_Electrical_Efficacy; UnitSystem = UnitSystem.Metric; UnitName = UnitName.DUT_LUMENS_PER_WATT; // Support only lm / W. expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(-1, UnitType.UT_Mass, null)); expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(-2, UnitType.UT_Length, null)); expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(3, UnitType.UT_Custom, "TIMEUNIT")); expectedTypes.Add(new Tuple <int, Autodesk.Revit.DB.UnitType, string>(1, UnitType.UT_Electrical_Luminous_Flux, null)); } } } double scaleFactor = 1.0; if (derivedElementUnitHnds.Count == expectedTypes.Count) { foreach (KeyValuePair <IFCUnit, int> derivedElementUnitHnd in derivedElementUnitHnds) { int dimensionality = derivedElementUnitHnd.Value; Tuple <int, UnitType, string> currKey = new Tuple <int, UnitType, string>(dimensionality, derivedElementUnitHnd.Key.UnitType, derivedElementUnitHnd.Key.CustomUnitType); if (expectedTypes.Contains(currKey)) { expectedTypes.Remove(currKey); scaleFactor *= Math.Pow(derivedElementUnitHnd.Key.ScaleFactor, dimensionality); } else { break; } } // Found all supported units. if (expectedTypes.Count == 0) { ScaleFactor = scaleFactor; return; } } IFCImportFile.TheLog.LogUnhandledUnitTypeError(unitHnd, unitType); }