Esempio n. 1
0
        /// <summary>
        /// Processes an IFC unit in the property.
        /// </summary>
        /// <param name="ifcSimpleProperty">The simple property.</param>
        /// <param name="simplePropertyHandle">The simple property handle.</param>
        static protected void ProcessIFCSimplePropertyUnit(IFCSimpleProperty ifcSimpleProperty, IFCAnyHandle simplePropertyHandle)
        {
            IFCAnyHandle ifcUnitHandle = IFCImportHandleUtil.GetOptionalInstanceAttribute(simplePropertyHandle, "Unit");
            IFCUnit      ifcUnit       = (ifcUnitHandle != null) ? IFCUnit.ProcessIFCUnit(ifcUnitHandle) : null;

            if (ifcUnit == null)
            {
                if (ifcSimpleProperty.IFCPropertyValues.Count > 0)
                {
                    IFCPropertyValue propertyValue = ifcSimpleProperty.IFCPropertyValues[0];
                    if (propertyValue != null && propertyValue.HasValue() &&
                        (propertyValue.Type == IFCDataPrimitiveType.Integer) || (propertyValue.Type == IFCDataPrimitiveType.Double))
                    {
                        string   unitTypeName;
                        UnitType unitType = IFCDataUtil.GetUnitTypeFromData(propertyValue.Value, UnitType.UT_Undefined, out unitTypeName);
                        if (unitType != UnitType.UT_Undefined)
                        {
                            ifcUnit = IFCImportFile.TheFile.IFCUnits.GetIFCProjectUnit(unitType);
                        }
                        else
                        {
                            Importer.TheLog.LogWarning(simplePropertyHandle.StepId, "Unhandled unit type: " + unitTypeName, true);
                        }
                    }
                }
            }

            ifcSimpleProperty.m_IFCUnit = ifcUnit;
        }
Esempio n. 2
0
        /// <summary>
        /// Gets the unit of a type.
        /// </summary>
        /// <param name="specTypeId">Identifier of the spec.</param>
        /// <returns>The Unit object.</returns>
        public IFCUnit GetIFCProjectUnit(ForgeTypeId specTypeId)
        {
            IFCUnit projectUnit = null;

            if (m_ProjectUnitsDictionary.TryGetValue(specTypeId, out projectUnit))
            {
                return(projectUnit);
            }
            else
            {
                //default units
                if (specTypeId.Equals(SpecTypeId.Length))
                {
                    IFCUnit unit = IFCUnit.ProcessIFCDefaultUnit(specTypeId, UnitSystem.Metric, UnitTypeId.Meters, 1.0 / 0.3048);
                    m_ProjectUnitsDictionary[specTypeId] = unit;
                    return(unit);
                }
                else if (specTypeId.Equals(SpecTypeId.Area))
                {
                    IFCUnit projectLengthUnit = GetIFCProjectUnit(SpecTypeId.Length);

                    UnitSystem  unitSystem = projectLengthUnit.UnitSystem;
                    ForgeTypeId unitName   = unitSystem == UnitSystem.Metric ?
                                             UnitTypeId.SquareMeters : UnitTypeId.SquareFeet;
                    double scaleFactor = unitSystem == UnitSystem.Metric ?
                                         (1.0 / 0.3048) * (1.0 / 0.3048) : 1.0;

                    IFCUnit unit = IFCUnit.ProcessIFCDefaultUnit(specTypeId, unitSystem, unitName, scaleFactor);
                    m_ProjectUnitsDictionary[specTypeId] = unit;
                    return(unit);
                }
                else if (specTypeId.Equals(SpecTypeId.Volume))
                {
                    IFCUnit projectLengthUnit = GetIFCProjectUnit(SpecTypeId.Length);

                    UnitSystem  unitSystem = projectLengthUnit.UnitSystem;
                    ForgeTypeId unitName   = unitSystem == UnitSystem.Metric ?
                                             UnitTypeId.CubicMeters : UnitTypeId.CubicFeet;
                    double scaleFactor = unitSystem == UnitSystem.Metric ?
                                         (1.0 / 0.3048) * (1.0 / 0.3048) * (1.0 / 0.3048) : 1.0;

                    IFCUnit unit = IFCUnit.ProcessIFCDefaultUnit(specTypeId, unitSystem, unitName, scaleFactor);
                    m_ProjectUnitsDictionary[specTypeId] = unit;
                    return(unit);
                }
                else if (specTypeId.Equals(SpecTypeId.Angle))
                {
                    IFCUnit unit = IFCUnit.ProcessIFCDefaultUnit(specTypeId, UnitSystem.Metric, UnitTypeId.Degrees, Math.PI / 180);
                    m_ProjectUnitsDictionary[specTypeId] = unit;
                    return(unit);
                }
                else if (specTypeId.Equals(SpecTypeId.HvacTemperature))
                {
                    IFCUnit unit = IFCUnit.ProcessIFCDefaultUnit(specTypeId, UnitSystem.Metric, UnitTypeId.Kelvin, 1.0);
                    m_ProjectUnitsDictionary[specTypeId] = unit;
                    return(unit);
                }
            }
            return(null);
        }
Esempio n. 3
0
        /// <summary>
        /// Processes measure with unit.
        /// </summary>
        /// <param name="measureUnitHnd">The measure unit handle.</param>
        void ProcessIFCMeasureWithUnit(IFCAnyHandle measureUnitHnd)
        {
            double baseScale = 0.0;

            IFCData ifcData = measureUnitHnd.GetAttribute("ValueComponent");

            if (!ifcData.HasValue)
            {
                throw new InvalidOperationException("#" + measureUnitHnd.StepId + ": Missing required attribute ValueComponent.");
            }

            if (ifcData.PrimitiveType == IFCDataPrimitiveType.Double)
            {
                baseScale = ifcData.AsDouble();
            }
            else if (ifcData.PrimitiveType == IFCDataPrimitiveType.Integer)
            {
                baseScale = (double)ifcData.AsInteger();
            }

            if (MathUtil.IsAlmostZero(baseScale))
            {
                throw new InvalidOperationException("#" + measureUnitHnd.StepId + ": ValueComponent should not be almost zero.");
            }

            IFCAnyHandle unitHnd = IFCImportHandleUtil.GetRequiredInstanceAttribute(measureUnitHnd, "UnitComponent", true);

            IFCUnit unit = ProcessIFCUnit(unitHnd);

            CopyUnit(unit);
            ScaleFactor = unit.ScaleFactor * baseScale;
        }
Esempio n. 4
0
        /// <summary>
        /// Processes IfcProject attributes.
        /// </summary>
        /// <param name="ifcProjectHandle">The IfcProject handle.</param>
        protected override void Process(IFCAnyHandle ifcProjectHandle)
        {
            IFCAnyHandle unitsInContext = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcProjectHandle, "UnitsInContext", false);

            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(unitsInContext))
            {
                IList <IFCAnyHandle> units = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(unitsInContext, "Units");

                if (units != null)
                {
                    m_UnitsInContext = new HashSet <IFCUnit>();

                    foreach (IFCAnyHandle unit in units)
                    {
                        IFCUnit ifcUnit = IFCImportFile.TheFile.IFCUnits.ProcessIFCProjectUnit(unit);
                        if (!IFCUnit.IsNullOrInvalid(ifcUnit))
                        {
                            m_UnitsInContext.Add(ifcUnit);
                        }
                    }
                }
                else
                {
                    Importer.TheLog.LogMissingRequiredAttributeError(unitsInContext, "Units", false);
                }
            }

            // We need to process the units before we process the rest of the file, since we will scale values as we go along.
            base.Process(ifcProjectHandle);

            // process true north - take the first valid representation context that has a true north value.
            HashSet <IFCAnyHandle> repContexts = IFCAnyHandleUtil.GetAggregateInstanceAttribute <HashSet <IFCAnyHandle> >(ifcProjectHandle, "RepresentationContexts");

            if (repContexts != null)
            {
                foreach (IFCAnyHandle geomRepContextHandle in repContexts)
                {
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(geomRepContextHandle) &&
                        IFCAnyHandleUtil.IsSubTypeOf(geomRepContextHandle, IFCEntityType.IfcGeometricRepresentationContext))
                    {
                        IFCAnyHandle trueNorthHandle = IFCAnyHandleUtil.GetInstanceAttribute(geomRepContextHandle, "TrueNorth");
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(trueNorthHandle))
                        {
                            List <double> trueNorthDir = IFCAnyHandleUtil.GetAggregateDoubleAttribute <List <double> >(trueNorthHandle, "DirectionRatios");
                            if (trueNorthDir != null && trueNorthDir.Count >= 2)
                            {
                                m_TrueNorthDirection = trueNorthDir;
                                break;
                            }
                        }
                    }
                }
            }

            // Special read of IfcPresentationLayerAssignment if the INVERSE flag isn't properly set in the EXPRESS file.
            if (IFCImportFile.TheFile.SchemaVersion >= IFCSchemaVersion.IFC2x2)
            {
                IFCPresentationLayerAssignment.ProcessAllLayerAssignments();
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Gets the unit of a type.
        /// </summary>
        /// <param name="unitType">The unit type.</param>
        /// <returns>The Unit object.</returns>
        public IFCUnit GetIFCProjectUnit(UnitType unitType)
        {
            IFCUnit projectUnit = null;

            if (m_ProjectUnitsDictionary.TryGetValue(unitType, out projectUnit))
            {
                return(projectUnit);
            }
            else
            {
                //default units
                if (unitType == UnitType.UT_Length)
                {
                    IFCUnit unit = IFCUnit.ProcessIFCDefaultUnit(unitType, UnitSystem.Metric, UnitName.DUT_METERS, 1.0 / 0.3048);
                    m_ProjectUnitsDictionary[unitType] = unit;
                    return(unit);
                }
                else if (unitType == UnitType.UT_Area)
                {
                    IFCUnit projectLengthUnit = GetIFCProjectUnit(UnitType.UT_Length);

                    UnitSystem unitSystem = projectLengthUnit.UnitSystem;
                    UnitName   unitName   = unitSystem == UnitSystem.Metric ?
                                            UnitName.DUT_SQUARE_METERS : UnitName.DUT_SQUARE_FEET;
                    double scaleFactor = unitSystem == UnitSystem.Metric ?
                                         (1.0 / 0.3048) * (1.0 / 0.3048) : 1.0;

                    IFCUnit unit = IFCUnit.ProcessIFCDefaultUnit(unitType, unitSystem, unitName, scaleFactor);
                    m_ProjectUnitsDictionary[unitType] = unit;
                    return(unit);
                }
                else if (unitType == UnitType.UT_Volume)
                {
                    IFCUnit projectLengthUnit = GetIFCProjectUnit(UnitType.UT_Length);

                    UnitSystem unitSystem = projectLengthUnit.UnitSystem;
                    UnitName   unitName   = unitSystem == UnitSystem.Metric ?
                                            UnitName.DUT_CUBIC_METERS : UnitName.DUT_CUBIC_FEET;
                    double scaleFactor = unitSystem == UnitSystem.Metric ?
                                         (1.0 / 0.3048) * (1.0 / 0.3048) * (1.0 / 0.3048) : 1.0;

                    IFCUnit unit = IFCUnit.ProcessIFCDefaultUnit(unitType, unitSystem, unitName, scaleFactor);
                    m_ProjectUnitsDictionary[unitType] = unit;
                    return(unit);
                }
                else if (unitType == UnitType.UT_Angle)
                {
                    IFCUnit unit = IFCUnit.ProcessIFCDefaultUnit(unitType, UnitSystem.Metric, UnitName.DUT_DECIMAL_DEGREES, Math.PI / 180);
                    m_ProjectUnitsDictionary[unitType] = unit;
                    return(unit);
                }
                else if (unitType == UnitType.UT_HVAC_Temperature)
                {
                    IFCUnit unit = IFCUnit.ProcessIFCDefaultUnit(unitType, UnitSystem.Metric, UnitName.DUT_KELVIN, 1.0);
                    m_ProjectUnitsDictionary[unitType] = unit;
                    return(unit);
                }
            }
            return(null);
        }
Esempio n. 6
0
        /// <summary>
        /// Processes an IFC physical simple quantity.
        /// </summary>
        /// <param name="ifcPhysicalQuantity">The IfcPhysicalSimpleQuantity object.</param>
        /// <returns>The IFCPhysicalSimpleQuantity object.</returns>
        override protected void Process(IFCAnyHandle ifcPhysicalSimpleQuantity)
        {
            base.Process(ifcPhysicalSimpleQuantity);

            IFCAnyHandle unit = IFCImportHandleUtil.GetOptionalInstanceAttribute(ifcPhysicalSimpleQuantity, "Unit");

            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(unit))
            {
                IFCUnit = IFCUnit.ProcessIFCUnit(unit);
            }

            // Process subtypes of IfcPhysicalSimpleQuantity here.
            string attributeName = ifcPhysicalSimpleQuantity.TypeName.Substring(11) + "Value";

            Value        = ifcPhysicalSimpleQuantity.GetAttribute(attributeName);
            BaseUnitType = IFCDataUtil.GetUnitTypeFromData(Value, UnitType.UT_Undefined);

            if (BaseUnitType == UnitType.UT_Undefined)
            {
                // Determine it from the attributeName.
                if (string.Compare(attributeName, "LengthValue", true) == 0)
                {
                    BaseUnitType = UnitType.UT_Length;
                }
                else if (string.Compare(attributeName, "AreaValue", true) == 0)
                {
                    BaseUnitType = UnitType.UT_Area;
                }
                else if (string.Compare(attributeName, "VolumeValue", true) == 0)
                {
                    BaseUnitType = UnitType.UT_Volume;
                }
                else if (string.Compare(attributeName, "CountValue", true) == 0)
                {
                    BaseUnitType = UnitType.UT_Number;
                }
                else if (string.Compare(attributeName, "WeightValue", true) == 0)
                {
                    BaseUnitType = UnitType.UT_Mass;
                }
                else if (string.Compare(attributeName, "TimeValue", true) == 0)
                {
                    BaseUnitType = UnitType.UT_Number; // No time unit type in Revit.
                }
                else
                {
                    Importer.TheLog.LogWarning(Id, "Can't determine unit type for IfcPhysicalSimpleQuantity of type: " + attributeName, true);
                    BaseUnitType = UnitType.UT_Number;
                }
            }


            if (IFCUnit == null)
            {
                IFCUnit = IFCImportFile.TheFile.IFCUnits.GetIFCProjectUnit(BaseUnitType);
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Checks that the unit definition is valid for use.
        /// </summary>
        /// <param name="unit">The IFCUnit to check.</param>
        /// <returns>True if the IFCUnit is null, or has invalid parameters.</returns>
        public static bool IsNullOrInvalid(IFCUnit unit)
        {
            if (unit == null)
            {
                return(true);
            }

            return(unit.UnitType == UnitType.UT_Undefined || unit.UnitName == UnitName.DUT_UNDEFINED);
        }
Esempio n. 8
0
 // Note: the ScaleFactor will be likely overwritten.
 void CopyUnit(IFCUnit unit)
 {
     UnitType     = unit.UnitType;
     UnitName     = unit.UnitName;
     UnitSystem   = unit.UnitSystem;
     UnitSymbol   = unit.UnitSymbol;
     ScaleFactor  = unit.ScaleFactor;
     OffsetFactor = unit.OffsetFactor;
 }
Esempio n. 9
0
 // Note: the ScaleFactor will be likely overwritten.
 void CopyUnit(IFCUnit unit)
 {
     Spec         = unit.Spec;
     Unit         = unit.Unit;
     UnitSystem   = unit.UnitSystem;
     Symbol       = unit.Symbol;
     ScaleFactor  = unit.ScaleFactor;
     OffsetFactor = unit.OffsetFactor;
 }
Esempio n. 10
0
        /// <summary>
        /// Checks that the unit definition is valid for use.
        /// </summary>
        /// <param name="unit">The IFCUnit to check.</param>
        /// <returns>True if the IFCUnit is null, or has invalid parameters.</returns>
        public static bool IsNullOrInvalid(IFCUnit unit)
        {
            if (unit == null)
            {
                return(true);
            }

            return(unit.Spec.Empty() || unit.Unit.Empty());
        }
Esempio n. 11
0
        /// <summary>
        /// Processes IfcProject attributes.
        /// </summary>
        /// <param name="ifcProjectHandle">The IfcProject handle.</param>
        protected override void Process(IFCAnyHandle ifcProjectHandle)
        {
            IFCAnyHandle unitsInContext = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcProjectHandle, "UnitsInContext", false);

            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(unitsInContext))
            {
                IList <IFCAnyHandle> units = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(unitsInContext, "Units");

                if (units != null)
                {
                    m_UnitsInContext = new HashSet <IFCUnit>();

                    foreach (IFCAnyHandle unit in units)
                    {
                        IFCUnit ifcUnit = IFCImportFile.TheFile.IFCUnits.ProcessIFCProjectUnit(unit);
                        if (!IFCUnit.IsNullOrInvalid(ifcUnit))
                        {
                            m_UnitsInContext.Add(ifcUnit);
                        }
                    }
                }
                else
                {
                    Importer.TheLog.LogMissingRequiredAttributeError(unitsInContext, "Units", false);
                }
            }

            // We need to process the units before we process the rest of the file, since we will scale values as we go along.
            base.Process(ifcProjectHandle);

            // process true north - take the first valid representation context that has a true north value.
            HashSet <IFCAnyHandle> repContexts = IFCAnyHandleUtil.GetAggregateInstanceAttribute <HashSet <IFCAnyHandle> >(ifcProjectHandle, "RepresentationContexts");

            if (repContexts != null)
            {
                foreach (IFCAnyHandle geomRepContextHandle in repContexts)
                {
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(geomRepContextHandle) &&
                        IFCAnyHandleUtil.IsSubTypeOf(geomRepContextHandle, IFCEntityType.IfcGeometricRepresentationContext))
                    {
                        IFCRepresentationContext context = IFCRepresentationContext.ProcessIFCRepresentationContext(geomRepContextHandle);
                        if (TrueNorthDirection == null && context.TrueNorth != null)
                        {
                            // TODO: Verify that we don't have inconsistent true norths.  If we do, warn.
                            TrueNorthDirection = new UV(context.TrueNorth.X, context.TrueNorth.Y);
                        }

                        if (WorldCoordinateSystem == null && context.WorldCoordinateSystem != null && !context.WorldCoordinateSystem.IsIdentity)
                        {
                            WorldCoordinateSystem = context.WorldCoordinateSystem;
                        }
                    }
                }
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Processes a project unit.
        /// </summary>
        /// <param name="unitHnd">The unit handle.</param>
        /// <returns>The Unit object.</returns>
        public IFCUnit ProcessIFCProjectUnit(IFCAnyHandle unitHnd)
        {
            IFCUnit unit = IFCUnit.ProcessIFCUnit(unitHnd);

            if (unit != null)
            {
                m_ProjectUnitsDictionary[unit.Spec] = unit;
            }

            return(unit);
        }
Esempio n. 13
0
        /// <summary>
        /// Constructs a default IFCUnit of a specific type.
        /// </summary>
        /// <param name="unitType">The unit type.</param>
        /// <param name="unitSystem">The unit system.</param>
        /// <param name="unitName">The unit name.</param>
        /// <remarks>This is only intended to create a unit container for units that are necessary for the file,
        /// but are not found in the file.  It should not be used for IfcUnit entities in the file.</remarks>
        public static IFCUnit ProcessIFCDefaultUnit(ForgeTypeId specTypeId, UnitSystem unitSystem, ForgeTypeId unitTypeId, double?scaleFactor)
        {
            IFCUnit unit = new IFCUnit();

            unit.Spec       = specTypeId;
            unit.Unit       = unitTypeId;
            unit.UnitSystem = unitSystem;
            if (scaleFactor.HasValue)
            {
                unit.ScaleFactor = scaleFactor.Value;
            }
            unit.OffsetFactor = 0.0;

            return(unit);
        }
Esempio n. 14
0
        /// <summary>
        /// Constructs a default IFCUnit of a specific type.
        /// </summary>
        /// <param name="unitType">The unit type.</param>
        /// <param name="unitSystem">The unit system.</param>
        /// <param name="unitName">The unit name.</param>
        /// <remarks>This is only intended to create a unit container for units that are necessary for the file,
        /// but are not found in the file.  It should not be used for IfcUnit entities in the file.</remarks>
        public static IFCUnit ProcessIFCDefaultUnit(UnitType unitType, UnitSystem unitSystem, UnitName unitName, double?scaleFactor)
        {
            IFCUnit unit = new IFCUnit();

            unit.UnitType   = unitType;
            unit.UnitName   = unitName;
            unit.UnitSystem = unitSystem;
            if (scaleFactor.HasValue)
            {
                unit.ScaleFactor = scaleFactor.Value;
            }
            unit.OffsetFactor = 0.0;

            return(unit);
        }
Esempio n. 15
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected override void Create(Document doc)
        {
            Units documentUnits = new Units(doc.DisplayUnitSystem == DisplayUnit.METRIC ?
                                            UnitSystem.Metric : UnitSystem.Imperial);

            foreach (IFCUnit unit in UnitsInContext)
            {
                if (!IFCUnit.IsNullOrInvalid(unit))
                {
                    try
                    {
                        FormatOptions formatOptions = new FormatOptions(unit.Unit);
                        formatOptions.SetSymbolTypeId(unit.Symbol);
                        documentUnits.SetFormatOptions(unit.Spec, formatOptions);
                    }
                    catch (Exception ex)
                    {
                        Importer.TheLog.LogError(unit.Id, ex.Message, false);
                    }
                }
            }
            doc.SetUnits(documentUnits);

            // We will randomize unused grid names so that they don't conflict with new entries with the same name.
            // This is only for relink.
            foreach (ElementId gridId in Importer.TheCache.GridNameToElementMap.Values)
            {
                Grid grid = doc.GetElement(gridId) as Grid;
                if (grid == null)
                {
                    continue;
                }

                // Note that new Guid() is useless - it creates a GUID of all 0s.
                grid.Name = Guid.NewGuid().ToString();
            }

            base.Create(doc);

            // IfcProject usually won't create an element, as it contains no geometry.
            // If it doesn't, use the ProjectInfo element in the document to store its parameters.
            if (CreatedElementId == ElementId.InvalidElementId)
            {
                CreatedElementId = Importer.TheCache.ProjectInformationId;
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected override void Create(Document doc)
        {
            Units documentUnits = new Units(doc.DisplayUnitSystem == DisplayUnit.METRIC ?
                                            UnitSystem.Metric : UnitSystem.Imperial);

            foreach (IFCUnit unit in UnitsInContext)
            {
                if (!IFCUnit.IsNullOrInvalid(unit))
                {
                    try
                    {
                        FormatOptions formatOptions = new FormatOptions(unit.UnitName);
                        formatOptions.UnitSymbol = unit.UnitSymbol;
                        documentUnits.SetFormatOptions(unit.UnitType, formatOptions);
                    }
                    catch (Exception ex)
                    {
                        IFCImportFile.TheLog.LogError(unit.Id, ex.Message, false);
                    }
                }
            }
            doc.SetUnits(documentUnits);

            // We will randomize unused grid names so that they don't conflict with new entries with the same name.
            // This is only for relink.
            foreach (ElementId gridId in Importer.TheCache.GridNameToElementMap.Values)
            {
                Grid grid = doc.GetElement(gridId) as Grid;
                if (grid == null)
                {
                    continue;
                }

                grid.Name = new Guid().ToString();
            }

            base.Create(doc);
        }
Esempio n. 17
0
        /// <summary>
        /// Processes a unit.
        /// </summary>
        /// <param name="unitHnd">The unit handle.</param>
        /// <returns>The Unit object.</returns>
        public static IFCUnit ProcessIFCUnit(IFCAnyHandle unitHnd)
        {
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(unitHnd))
            {
                //LOG: ERROR: IfcUnit is null or has no value.
                return(null);
            }

            try
            {
                IFCEntity ifcUnit;
                if (!IFCImportFile.TheFile.EntityMap.TryGetValue(unitHnd.StepId, out ifcUnit))
                {
                    ifcUnit = new IFCUnit(unitHnd);
                }
                return(ifcUnit as IFCUnit);
            }
            catch (InvalidOperationException ex)
            {
                Importer.TheLog.LogError(unitHnd.StepId, ex.Message, false);
            }

            return(null);
        }
Esempio n. 18
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);
        }
Esempio n. 19
0
        /// <summary>
        /// Checks that the unit definition is valid for use.
        /// </summary>
        /// <param name="unit">The IFCUnit to check.</param>
        /// <returns>True if the IFCUnit is null, or has invalid parameters.</returns>
        public static bool IsNullOrInvalid(IFCUnit unit)
        {
            if (unit == null)
                return true;

            return (unit.UnitType == UnitType.UT_Undefined || unit.UnitName == UnitName.DUT_UNDEFINED);
        }
Esempio n. 20
0
        /// <summary>
        /// Create a quantity for a given element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element being created.</param>
        /// <param name="category">The element's category.</param>
        /// <param name="parameterMap">The parameters of the element.  Cached for performance.</param>
        /// <param name="propertySetName">The name of the containing property set.</param>
        /// <param name="createdParameters">The names of the created parameters.</param>
        public override void Create(Document doc, Element element, Category category, IFCObjectDefinition objDef, IFCParameterSetByGroup parameterGroupMap, string propertySetName, ISet <string> createdParameters)
        {
            double baseValue          = 0.0;
            IFCDataPrimitiveType type = Value.PrimitiveType;

            switch (type)
            {
            case IFCDataPrimitiveType.Double:
                baseValue = Value.AsDouble();
                break;

            case IFCDataPrimitiveType.Integer:
                // This case isn't valid, but could happen when repairing a file
                Importer.TheLog.LogWarning(Id, "Unexpected integer parameter type, repairing.", false);
                baseValue = Value.AsInteger();
                break;

            default:
                Importer.TheLog.LogError(Id, "Invalid parameter type: " + type.ToString() + " for IfcPhysicalSimpleQuantity", false);
                return;
            }

            double doubleValueToUse = Importer.TheProcessor.ScaleValues ?
                                      IFCUnit?.Convert(baseValue) ?? baseValue :
                                      baseValue;

            Parameter existingParameter     = null;
            string    originalParameterName = propertySetName + "." + Name;
            string    parameterName         = originalParameterName;

            if (!parameterGroupMap.TryFindParameter(parameterName, out existingParameter))
            {
                int parameterNameCount = 2;
                while (createdParameters.Contains(parameterName))
                {
                    parameterName = originalParameterName + " " + parameterNameCount;
                    parameterNameCount++;
                }
                if (parameterNameCount > 2)
                {
                    Importer.TheLog.LogWarning(Id, "Renamed parameter: " + originalParameterName + " to: " + parameterName, false);
                }

                if (existingParameter == null)
                {
                    ForgeTypeId specTypeId;
                    ForgeTypeId unitsTypeId = null;

                    if (IFCUnit != null)
                    {
                        specTypeId  = IFCUnit.Spec;
                        unitsTypeId = IFCUnit.Unit;
                    }
                    else
                    {
                        specTypeId = IFCDataUtil.GetUnitTypeFromData(Value, SpecTypeId.Number);
                    }

                    bool created = IFCPropertySet.AddParameterDouble(doc, element, category, objDef, parameterName, specTypeId, unitsTypeId, doubleValueToUse, Id);
                    if (created)
                    {
                        createdParameters.Add(parameterName);
                    }

                    return;
                }
            }

            bool setValue = true;

            switch (existingParameter.StorageType)
            {
            case StorageType.String:
                existingParameter.Set(doubleValueToUse.ToString());
                break;

            case StorageType.Double:
                existingParameter.Set(doubleValueToUse);
                break;

            default:
                setValue = false;
                break;
            }

            if (!setValue)
            {
                Importer.TheLog.LogError(Id, "Couldn't create parameter: " + Name + " of storage type: " + existingParameter.StorageType.ToString(), false);
            }
        }
Esempio n. 21
0
 // Note: the ScaleFactor will be likely overwritten.
 void CopyUnit(IFCUnit unit)
 {
     UnitType = unit.UnitType;
     UnitName = unit.UnitName;
     UnitSystem = unit.UnitSystem;
     UnitSymbol = unit.UnitSymbol;
     ScaleFactor = unit.ScaleFactor;
     OffsetFactor = unit.OffsetFactor;
 }
Esempio n. 22
0
        /// <summary>
        /// Processes a conversion based unit.
        /// </summary>
        /// <param name="convUnitHnd">The unit handle.</param>
        void ProcessIFCConversionBasedUnit(IFCAnyHandle convUnitHnd)
        {
            IFCAnyHandle measureWithUnitHnd = IFCAnyHandleUtil.GetInstanceAttribute(convUnitHnd, "ConversionFactor");

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(measureWithUnitHnd))
            {
                throw new InvalidOperationException("#" + convUnitHnd.StepId + ": Missing required attribute ConversionFactor.");
            }

            IFCUnit measureWithUnit = IFCUnit.ProcessIFCUnit(measureWithUnitHnd);

            if (measureWithUnit == null)
            {
                throw new InvalidOperationException("#" + convUnitHnd.StepId + ": Invalid base ConversionFactor, aborting.");
            }

            CopyUnit(measureWithUnit);

            // For some common cases, get the units correct.
            string unitType = IFCAnyHandleUtil.GetEnumerationAttribute(convUnitHnd, "UnitType");

            if (string.Compare(unitType, "LENGTHUNIT", true) == 0)
            {
                UnitType = UnitType.UT_Length;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "FOOT", true) == 0 ||
                    string.Compare(name, "FEET", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_FEET_FRACTIONAL_INCHES;
                    UnitSymbol = UnitSymbolType.UST_NONE;
                }
                else if (string.Compare(name, "INCH", true) == 0 ||
                         string.Compare(name, "INCHES", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_FRACTIONAL_INCHES;
                    UnitSymbol = UnitSymbolType.UST_NONE;
                }
            }
            else if (string.Compare(unitType, "PLANEANGLEUNIT", true) == 0)
            {
                UnitType = UnitType.UT_Angle;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "GRAD", true) == 0 ||
                    string.Compare(name, "GRADIAN", true) == 0 ||
                    string.Compare(name, "GRADS", true) == 0 ||
                    string.Compare(name, "GRADIANS", true) == 0)
                {
                    UnitSystem = UnitSystem.Metric;
                    UnitName   = UnitName.DUT_GRADS;
                    UnitSymbol = UnitSymbolType.UST_GRAD;
                }
                else if (string.Compare(name, "DEGREE", true) == 0 ||
                         string.Compare(name, "DEGREES", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_DECIMAL_DEGREES;
                    UnitSymbol = UnitSymbolType.UST_DEGREE_SYMBOL;
                }
            }
            else if (string.Compare(unitType, "AREAUNIT", true) == 0)
            {
                UnitType = UnitType.UT_Area;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "SQUARE FOOT", true) == 0 ||
                    string.Compare(name, "SQUARE_FOOT", true) == 0 ||
                    string.Compare(name, "SQUARE FEET", true) == 0 ||
                    string.Compare(name, "SQUARE_FEET", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_SQUARE_FEET;
                    UnitSymbol = UnitSymbolType.UST_FT_SUP_2;
                }
            }
            else if (string.Compare(unitType, "VOLUMEUNIT", true) == 0)
            {
                UnitType = UnitType.UT_Volume;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "CUBIC FOOT", true) == 0 ||
                    string.Compare(name, "CUBIC_FOOT", true) == 0 ||
                    string.Compare(name, "CUBIC FEET", true) == 0 ||
                    string.Compare(name, "CUBIC_FEET", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_CUBIC_FEET;
                    UnitSymbol = UnitSymbolType.UST_FT_SUP_3;
                }
            }
            else if (string.Compare(unitType, "THERMODYNAMICMEASUREUNIT", true) == 0)
            {
                UnitType = UnitType.UT_HVAC_Temperature;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if ((string.Compare(name, "F", true) == 0) ||
                    (string.Compare(name, "FAHRENHEIT", true) == 0))
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_FAHRENHEIT;
                    UnitSymbol = UnitSymbolType.UST_DEGREE_F;
                }
                else if ((string.Compare(name, "R", true) == 0) ||
                         (string.Compare(name, "RANKINE", true) == 0))
                {
                    UnitSystem = UnitSystem.Imperial;
                    UnitName   = UnitName.DUT_RANKINE;
                    UnitSymbol = UnitSymbolType.UST_DEGREE_R;
                }
            }
        }
Esempio n. 23
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);
        }
Esempio n. 24
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)
            {
                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);
        }
Esempio n. 25
0
        /// <summary>
        /// Processes a conversion based unit.
        /// </summary>
        /// <param name="convUnitHnd">The unit handle.</param>
        void ProcessIFCConversionBasedUnit(IFCAnyHandle convUnitHnd)
        {
            IFCAnyHandle measureWithUnitHnd = IFCAnyHandleUtil.GetInstanceAttribute(convUnitHnd, "ConversionFactor");

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(measureWithUnitHnd))
            {
                throw new InvalidOperationException("#" + convUnitHnd.StepId + ": Missing required attribute ConversionFactor.");
            }

            IFCUnit measureWithUnit = IFCUnit.ProcessIFCUnit(measureWithUnitHnd);

            if (measureWithUnit == null)
            {
                throw new InvalidOperationException("#" + convUnitHnd.StepId + ": Invalid base ConversionFactor, aborting.");
            }

            CopyUnit(measureWithUnit);

            // For some common cases, get the units correct.
            string unitType = IFCAnyHandleUtil.GetEnumerationAttribute(convUnitHnd, "UnitType");

            if (string.Compare(unitType, "LENGTHUNIT", true) == 0)
            {
                Spec = SpecTypeId.Length;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "FOOT", true) == 0 ||
                    string.Compare(name, "FEET", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.FeetFractionalInches;
                    Symbol     = new ForgeTypeId();
                }
                else if (string.Compare(name, "INCH", true) == 0 ||
                         string.Compare(name, "INCHES", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.FractionalInches;
                    Symbol     = new ForgeTypeId();
                }
            }
            else if (string.Compare(unitType, "PLANEANGLEUNIT", true) == 0)
            {
                Spec = SpecTypeId.Angle;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "GRAD", true) == 0 ||
                    string.Compare(name, "GRADIAN", true) == 0 ||
                    string.Compare(name, "GRADS", true) == 0 ||
                    string.Compare(name, "GRADIANS", true) == 0)
                {
                    UnitSystem = UnitSystem.Metric;
                    Unit       = UnitTypeId.Gradians;
                    Symbol     = SymbolTypeId.Grad;
                }
                else if (string.Compare(name, "DEGREE", true) == 0 ||
                         string.Compare(name, "DEGREES", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.Degrees;
                    Symbol     = SymbolTypeId.Degree;
                }
            }
            else if (string.Compare(unitType, "AREAUNIT", true) == 0)
            {
                Spec = SpecTypeId.Area;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "SQUARE FOOT", true) == 0 ||
                    string.Compare(name, "SQUARE_FOOT", true) == 0 ||
                    string.Compare(name, "SQUARE FEET", true) == 0 ||
                    string.Compare(name, "SQUARE_FEET", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.SquareFeet;
                    Symbol     = SymbolTypeId.FtSup2;
                }
            }
            else if (string.Compare(unitType, "VOLUMEUNIT", true) == 0)
            {
                Spec = SpecTypeId.Volume;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if (string.Compare(name, "CUBIC FOOT", true) == 0 ||
                    string.Compare(name, "CUBIC_FOOT", true) == 0 ||
                    string.Compare(name, "CUBIC FEET", true) == 0 ||
                    string.Compare(name, "CUBIC_FEET", true) == 0)
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.CubicFeet;
                    Symbol     = SymbolTypeId.FtSup3;
                }
            }
            else if (string.Compare(unitType, "THERMODYNAMICMEASUREUNIT", true) == 0)
            {
                Spec = SpecTypeId.HvacTemperature;
                string name = IFCAnyHandleUtil.GetStringAttribute(convUnitHnd, "Name");

                if ((string.Compare(name, "F", true) == 0) ||
                    (string.Compare(name, "FAHRENHEIT", true) == 0))
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.Fahrenheit;
                    Symbol     = SymbolTypeId.DegreeF;
                }
                else if ((string.Compare(name, "R", true) == 0) ||
                         (string.Compare(name, "RANKINE", true) == 0))
                {
                    UnitSystem = UnitSystem.Imperial;
                    Unit       = UnitTypeId.Rankine;
                    Symbol     = SymbolTypeId.DegreeR;
                }
            }
        }
Esempio n. 26
0
        /// <summary>
        /// Constructs a default IFCUnit of a specific type.
        /// </summary>
        /// <param name="unitType">The unit type.</param>
        /// <param name="unitSystem">The unit system.</param>
        /// <param name="unitName">The unit name.</param>
        /// <remarks>This is only intended to create a unit container for units that are necessary for the file,
        /// but are not found in the file.  It should not be used for IfcUnit entities in the file.</remarks>
        public static IFCUnit ProcessIFCDefaultUnit(UnitType unitType, UnitSystem unitSystem, UnitName unitName, double? scaleFactor)
        {
            IFCUnit unit = new IFCUnit();

            unit.UnitType = unitType;
            unit.UnitName = unitName;
            unit.UnitSystem = unitSystem;
            if (scaleFactor.HasValue)
                unit.ScaleFactor = scaleFactor.Value;
            unit.OffsetFactor = 0.0;

            return unit;
        }
Esempio n. 27
0
        /// <summary>
        /// Create a quantity for a given element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element being created.</param>
        /// <param name="parameterMap">The parameters of the element.  Cached for performance.</param>
        /// <param name="propertySetName">The name of the containing property set.</param>
        /// <param name="createdParameters">The names of the created parameters.</param>
        public override void Create(Document doc, Element element, IFCParameterSetByGroup parameterGroupMap, string propertySetName, ISet <string> createdParameters)
        {
            double doubleValueToUse = IFCUnit != null?IFCUnit.Convert(Value.AsDouble()) : Value.AsDouble();

            Parameter existingParameter     = null;
            string    originalParameterName = Name + "(" + propertySetName + ")";
            string    parameterName         = originalParameterName;

            if (!parameterGroupMap.TryFindParameter(parameterName, out existingParameter))
            {
                int parameterNameCount = 2;
                while (createdParameters.Contains(parameterName))
                {
                    parameterName = originalParameterName + " " + parameterNameCount;
                    parameterNameCount++;
                }
                if (parameterNameCount > 2)
                {
                    Importer.TheLog.LogWarning(Id, "Renamed parameter: " + originalParameterName + " to: " + parameterName, false);
                }

                if (existingParameter == null)
                {
                    UnitType unitType = UnitType.UT_Undefined;
                    if (IFCUnit != null)
                    {
                        unitType = IFCUnit.UnitType;
                    }
                    else
                    {
                        unitType = IFCDataUtil.GetUnitTypeFromData(Value, UnitType.UT_Number);
                    }

                    bool created = IFCPropertySet.AddParameterDouble(doc, element, parameterName, unitType, doubleValueToUse, Id);
                    if (created)
                    {
                        createdParameters.Add(parameterName);
                    }

                    return;
                }
            }

            bool setValue = true;

            switch (existingParameter.StorageType)
            {
            case StorageType.String:
                existingParameter.Set(doubleValueToUse.ToString());
                break;

            case StorageType.Double:
                existingParameter.Set(doubleValueToUse);
                break;

            default:
                setValue = false;
                break;
            }

            if (!setValue)
            {
                Importer.TheLog.LogError(Id, "Couldn't create parameter: " + Name + " of storage type: " + existingParameter.StorageType.ToString(), false);
            }
        }
Esempio n. 28
0
        /// <summary>
        /// Processes IfcProject attributes.
        /// </summary>
        /// <param name="ifcProjectHandle">The IfcProject handle.</param>
        protected override void Process(IFCAnyHandle ifcProjectHandle)
        {
            IFCAnyHandle unitsInContext = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcProjectHandle, "UnitsInContext", false);

            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(unitsInContext))
            {
                IList <IFCAnyHandle> units = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(unitsInContext, "Units");

                if (units != null)
                {
                    m_UnitsInContext = new HashSet <IFCUnit>();

                    foreach (IFCAnyHandle unit in units)
                    {
                        IFCUnit ifcUnit = IFCImportFile.TheFile.IFCUnits.ProcessIFCProjectUnit(unit);
                        if (!IFCUnit.IsNullOrInvalid(ifcUnit))
                        {
                            m_UnitsInContext.Add(ifcUnit);
                        }
                    }
                }
                else
                {
                    Importer.TheLog.LogMissingRequiredAttributeError(unitsInContext, "Units", false);
                }
            }

            var application  = IFCImportFile.TheFile.Document.Application;
            var projectUnits = IFCImportFile.TheFile.IFCUnits.GetIFCProjectUnit(SpecTypeId.Length);

            IFCImportFile.TheFile.VertexTolerance     = application.VertexTolerance;
            IFCImportFile.TheFile.ShortCurveTolerance = application.ShortCurveTolerance;
            Importer.TheProcessor.PostProcessProject(projectUnits?.ScaleFactor, projectUnits?.Unit);

            // We need to process the units before we process the rest of the file, since we will scale values as we go along.
            base.Process(ifcProjectHandle);

            // process true north - take the first valid representation context that has a true north value.
            HashSet <IFCAnyHandle> repContexts = IFCAnyHandleUtil.GetAggregateInstanceAttribute <HashSet <IFCAnyHandle> >(ifcProjectHandle, "RepresentationContexts");

            bool   hasMapConv = false;
            XYZ    geoRef     = XYZ.Zero;
            string geoRefName = null;
            double trueNorth  = 0.0;

            if (repContexts != null)
            {
                foreach (IFCAnyHandle geomRepContextHandle in repContexts)
                {
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(geomRepContextHandle) &&
                        IFCAnyHandleUtil.IsSubTypeOf(geomRepContextHandle, IFCEntityType.IfcGeometricRepresentationContext))
                    {
                        IFCRepresentationContext context = IFCRepresentationContext.ProcessIFCRepresentationContext(geomRepContextHandle);
                        if (TrueNorthDirection == null && context.TrueNorth != null)
                        {
                            // TODO: Verify that we don't have inconsistent true norths.  If we do, warn.
                            TrueNorthDirection = new UV(context.TrueNorth.X, context.TrueNorth.Y);
                        }

                        if (WorldCoordinateSystem == null && context.WorldCoordinateSystem != null && !context.WorldCoordinateSystem.IsIdentity)
                        {
                            WorldCoordinateSystem = context.WorldCoordinateSystem;
                        }

                        // Process Map Conversion if any
                        HashSet <IFCAnyHandle> coordOperation = IFCAnyHandleUtil.GetAggregateInstanceAttribute <HashSet <IFCAnyHandle> >(geomRepContextHandle, "HasCoordinateOperation");
                        if (coordOperation != null)
                        {
                            if (coordOperation.Count > 0)
                            {
                                if (IFCAnyHandleUtil.IsSubTypeOf(coordOperation.FirstOrDefault(), IFCEntityType.IfcMapConversion))
                                {
                                    hasMapConv = true;
                                    IFCAnyHandle mapConv  = coordOperation.FirstOrDefault();
                                    bool         found    = false;
                                    double       eastings = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(mapConv, "Eastings", out found);
                                    if (!found)
                                    {
                                        eastings = 0.0;
                                    }
                                    double northings = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(mapConv, "Northings", out found);
                                    if (!found)
                                    {
                                        northings = 0.0;
                                    }
                                    double orthogonalHeight = IFCImportHandleUtil.GetRequiredScaledLengthAttribute(mapConv, "OrthogonalHeight", out found);
                                    if (!found)
                                    {
                                        orthogonalHeight = 0.0;
                                    }
                                    double xAxisAbs = IFCImportHandleUtil.GetOptionalRealAttribute(mapConv, "XAxisAbscissa", 1.0);
                                    double xAxisOrd = IFCImportHandleUtil.GetOptionalRealAttribute(mapConv, "XAxisOrdinate", 0.0);
                                    trueNorth = Math.Atan2(xAxisOrd, xAxisAbs);
                                    //angleToNorth = -((xAxisAngle > -Math.PI / 2.0) ? xAxisAngle - Math.PI / 2.0 : xAxisAngle + Math.PI * 1.5);
                                    double scale = IFCImportHandleUtil.GetOptionalRealAttribute(mapConv, "Scale", 1.0);
                                    geoRef = new XYZ(scale * eastings, scale * northings, scale * orthogonalHeight);

                                    // Process the IfcProjectedCRS
                                    IFCAnyHandle projCRS = IFCAnyHandleUtil.GetInstanceAttribute(mapConv, "TargetCRS");
                                    if (projCRS != null && IFCAnyHandleUtil.IsSubTypeOf(projCRS, IFCEntityType.IfcProjectedCRS))
                                    {
                                        geoRefName = IFCImportHandleUtil.GetRequiredStringAttribute(projCRS, "Name", false);
                                        string       desc          = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "Description", null);
                                        string       geodeticDatum = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "GeodeticDatum", null);
                                        string       verticalDatum = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "VerticalDatum", null);
                                        string       mapProj       = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "MapProjection", null);
                                        string       mapZone       = IFCImportHandleUtil.GetOptionalStringAttribute(projCRS, "MapZone", null);
                                        IFCAnyHandle mapUnit       = IFCImportHandleUtil.GetOptionalInstanceAttribute(projCRS, "MapUnit");

                                        Document    doc         = IFCImportFile.TheFile.Document;
                                        ProjectInfo projectInfo = doc.ProjectInformation;

                                        // We add this here because we want to make sure that external processors (e.g., Navisworks)
                                        // get a chance to add a container for the parameters that get added below.  In general,
                                        // we should probably augment Processor.AddParameter to ensure that CreateOrUpdateElement
                                        // is called before anything is attempted to be added.  This is a special case, though,
                                        // as in Revit we don't actually create an element for the IfcProject.
                                        Importer.TheProcessor.CreateOrUpdateElement(Id, GlobalId, EntityType.ToString(), CategoryId.IntegerValue, null);

                                        Category category = IFCPropertySet.GetCategoryForParameterIfValid(projectInfo, Id);
                                        IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.Name", geoRefName, Id);
                                        if (!string.IsNullOrEmpty(desc))
                                        {
                                            IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.Description", desc, Id);
                                        }
                                        if (!string.IsNullOrEmpty(geodeticDatum))
                                        {
                                            IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.GeodeticDatum", geodeticDatum, Id);
                                        }
                                        if (!string.IsNullOrEmpty(verticalDatum))
                                        {
                                            IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.VerticalDatum", verticalDatum, Id);
                                        }
                                        if (!string.IsNullOrEmpty(mapProj))
                                        {
                                            IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.MapProjection", mapProj, Id);
                                        }
                                        if (!string.IsNullOrEmpty(mapZone))
                                        {
                                            IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.MapZone", mapZone, Id);
                                        }
                                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(mapUnit))
                                        {
                                            IFCUnit mapUnitIfc = IFCUnit.ProcessIFCUnit(mapUnit);
                                            string  unitStr    = UnitUtils.GetTypeCatalogStringForUnit(mapUnitIfc.Unit);
                                            IFCPropertySet.AddParameterString(doc, projectInfo, category, this, "IfcProjectedCRS.MapUnit", unitStr, Id);
                                            double convFactor = UnitUtils.Convert(1.0, mapUnitIfc.Unit, IFCImportFile.TheFile.IFCUnits.GetIFCProjectUnit(SpecTypeId.Length).Unit);
                                            eastings         = convFactor * eastings;
                                            northings        = convFactor * northings;
                                            orthogonalHeight = convFactor * orthogonalHeight;
                                            geoRef           = new XYZ(eastings, northings, orthogonalHeight);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                ProjectLocation projectLocation = IFCImportFile.TheFile.Document.ActiveProjectLocation;
                ProjectPosition projectPosition;
                if (projectLocation != null)
                {
                    if (hasMapConv)
                    {
                        projectPosition = new ProjectPosition(geoRef.X, geoRef.Y, geoRef.Z, trueNorth);
                        projectLocation.SetProjectPosition(XYZ.Zero, projectPosition);

                        if (!string.IsNullOrEmpty(geoRefName))
                        {
                            IFCImportFile.TheFile.Document.SiteLocation.SetGeoCoordinateSystem(geoRefName);
                        }
                    }
                    else
                    {
                        // Set initial project location based on the information above.
                        // This may be further modified by the site.
                        trueNorth = 0.0;
                        if (TrueNorthDirection != null)
                        {
                            trueNorth = -Math.Atan2(-TrueNorthDirection.U, TrueNorthDirection.V);
                        }

                        // TODO: Extend this to work properly if the world coordinate system
                        // isn't a simple translation.
                        XYZ origin = XYZ.Zero;
                        if (WorldCoordinateSystem != null)
                        {
                            geoRef = WorldCoordinateSystem.Origin;
                            double angleRot = Math.Atan2(WorldCoordinateSystem.BasisX.Y, WorldCoordinateSystem.BasisX.X);

                            // If it is translation only, or if the WCS rotation is equal to trueNorth, we assume they are the same
                            if (WorldCoordinateSystem.IsTranslation ||
                                MathUtil.IsAlmostEqual(angleRot, trueNorth))
                            {
                                WorldCoordinateSystem = null;
                            }
                            else
                            {
                                // If the trueNorth is not set (=0), set the trueNorth by the rotation of the WCS, otherwise add the angle
                                if (MathUtil.IsAlmostZero(trueNorth))
                                {
                                    trueNorth = angleRot;
                                }
                                else
                                {
                                    trueNorth += angleRot;
                                }

                                WorldCoordinateSystem = null;
                            }
                        }

                        projectPosition = new ProjectPosition(geoRef.X, geoRef.Y, geoRef.Z, trueNorth);
                        projectLocation.SetProjectPosition(XYZ.Zero, projectPosition);
                    }
                }
            }
        }
Esempio n. 29
0
        /// <summary>
        /// Processes a unit.
        /// </summary>
        /// <param name="unitHnd">The unit handle.</param>
        /// <returns>The Unit object.</returns>
        public static IFCUnit ProcessIFCUnit(IFCAnyHandle unitHnd)
        {
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(unitHnd))
            {
                //LOG: ERROR: IfcUnit is null or has no value.
                return null;
            }

            try
            {
                IFCEntity ifcUnit;
                if (!IFCImportFile.TheFile.EntityMap.TryGetValue(unitHnd.StepId, out ifcUnit))
                    ifcUnit = new IFCUnit(unitHnd);
                return (ifcUnit as IFCUnit);
            }
            catch (InvalidOperationException ex)
            {
                IFCImportFile.TheLog.LogError(unitHnd.StepId, ex.Message, false);
            }

            return null;
        }