Exemple #1
0
        /// <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);
                }
            }
        }
Exemple #6
0
        /// <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);
        }
Exemple #7
0
        /// <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);
        }