/// <summary>
        /// Create property sets for a given element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element being created.</param>
        /// <param name="propertySetsCreated">A concatenated string of property sets created, used to filter schedules.</returns>
        /// <param name="propertySetListName">The name of the parameter that contains the property set list name.</param>
        /// <param name="propertySets">The list of properties.</param>
        protected void CreatePropertySetsBase(Document doc, Element element, string propertySetsCreated, string propertySetListName,
                                              IDictionary <string, IFCPropertySetDefinition> propertySets)
        {
            if (propertySetsCreated == null)
            {
                propertySetsCreated = "";
            }

            if (propertySets != null && propertySets.Count > 0)
            {
                IFCParameterSetByGroup parameterGroupMap = IFCParameterSetByGroup.Create(element);
                foreach (IFCPropertySetDefinition propertySet in propertySets.Values)
                {
                    Tuple <string, bool> newPropertySetCreated = propertySet.CreatePropertySet(doc, element, this, parameterGroupMap);
                    if (newPropertySetCreated == null || !newPropertySetCreated.Item2 || string.IsNullOrWhiteSpace(newPropertySetCreated.Item1))
                    {
                        continue;
                    }

                    if (propertySetsCreated == "")
                    {
                        propertySetsCreated = newPropertySetCreated.Item1;
                    }
                    else
                    {
                        propertySetsCreated += ";" + newPropertySetCreated.Item1;
                    }
                }
            }
            // Add property set-based parameters.
            // We are going to create this "fake" parameter so that we can filter elements in schedules based on their property sets.
            Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);

            IFCPropertySet.AddParameterString(doc, element, category, this, propertySetListName, propertySetsCreated, Id);
        }
Exemple #2
0
        /// <summary>
        /// Create a property set for a given element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element being created.</param>
        /// <param name="parameterGroupMap">The parameters of the element.  Cached for performance.</param>
        /// <returns>The name of the property set created, if it was created, and a Boolean value if it should be added to the property set list.</returns>
        public override Tuple <string, bool> CreatePropertySet(Document doc, Element element, IFCObjectDefinition objDef, IFCParameterSetByGroup parameterGroupMap)
        {
            IDictionary <string, IFCData> parametersToAdd = new Dictionary <string, IFCData>();
            Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);

            foreach (KeyValuePair <Tuple <string, ForgeTypeId, AllowedValues>, double> property in DoubleProperties)
            {
                string    name = property.Key.Item1;
                Parameter existingParameter = null;
                if (!parameterGroupMap.TryFindParameter(name, out existingParameter))
                {
                    ForgeTypeId valueType = property.Key.Item2;
                    // If we aren't scaling values, all length values have come from Attributes
                    // and so will always be in feet.
                    ForgeTypeId unitType = (!Importer.TheProcessor.ScaleValues && valueType == SpecTypeId.Length) ?
                                           UnitTypeId.Feet : null;
                    IFCPropertySet.AddParameterDouble(doc, element, category, objDef, name, valueType, unitType, property.Value, Id);
                    continue;
                }

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

                case StorageType.Double:
                    existingParameter.Set(property.Value);
                    break;

                default:
                    Importer.TheLog.LogError(Id, "couldn't create parameter: " + name + " of storage type: " + existingParameter.StorageType.ToString(), false);
                    break;
                }
            }

            foreach (KeyValuePair <string, string> property in StringProperties)
            {
                string    name = property.Key;
                Parameter existingParameter = null;
                if (!parameterGroupMap.TryFindParameter(name, out existingParameter))
                {
                    IFCPropertySet.AddParameterString(doc, element, category, objDef, property.Key, property.Value, Id);
                    continue;
                }

                switch (existingParameter.StorageType)
                {
                case StorageType.String:
                    existingParameter.Set(property.Value);
                    break;

                default:
                    Importer.TheLog.LogError(Id, "couldn't create parameter: " + name + " of storage type: " + existingParameter.StorageType.ToString(), false);
                    break;
                }
            }

            return(Tuple.Create("\"" + EntityType.ToString() + "\"", false));
        }
Exemple #3
0
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);

            if (element != null)
            {
                Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);
                if (category != null)
                {
                    Parameter operationTypeParameter = element.get_Parameter(BuiltInParameter.DOOR_OPERATION_TYPE);
                    if (operationTypeParameter != null)
                    {
                        operationTypeParameter.Set(OperationType.ToString());
                    }
                    IFCPropertySet.AddParameterString(doc, element, category, "IfcOperationType", OperationType.ToString(), Id);

                    Parameter constructionTypeParameter = element.get_Parameter(BuiltInParameter.DOOR_CONSTRUCTION_TYPE);
                    if (constructionTypeParameter != null)
                    {
                        constructionTypeParameter.Set(ConstructionType.ToString());
                    }
                    IFCPropertySet.AddParameterString(doc, element, category, "IfcConstructionType", ConstructionType.ToString(), Id);
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);
            string parameterName = "LandTitleNumber";

            // TODO: move this to new shared parameter names override function.
            if (element is ProjectInfo)
            {
                parameterName = "IfcSite " + parameterName;
            }

            if (element != null)
            {
                string landTitleNumber = LandTitleNumber;
                if (!string.IsNullOrWhiteSpace(landTitleNumber))
                {
                    Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);
                    IFCPropertySet.AddParameterString(doc, element, category, this, parameterName, landTitleNumber, Id);
                }
            }

            ForgeTypeId lengthUnits = null;

            if (!Importer.TheProcessor.ScaleValues)
            {
                lengthUnits = IFCImportFile.TheFile.IFCUnits.GetIFCProjectUnit(SpecTypeId.Length)?.Unit;
            }

            Importer.TheProcessor.PostProcessSite(Id, RefLatitude,
                                                  RefLongitude, RefElevation, LandTitleNumber, lengthUnits,
                                                  ObjectLocation?.TotalTransform);
        }
Exemple #5
0
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);

            if (element != null)
            {
                Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);
                IFCPropertySet.AddParameterString(doc, element, category, this, "Flow Direction", FlowDirection.ToString(), Id);
            }
        }
Exemple #6
0
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);

            if (element != null)
            {
                Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);

                // Set "ElevationWithFlooring" parameter.
                IFCPropertySet.AddParameterDouble(doc, element, category, "ElevationWithFlooring", SpecTypeId.Length, ElevationWithFlooring, Id);

                // Set "PredefinedType" parameter.
                if (PredefinedType != null)
                {
                    if (IFCImportFile.TheFile.SchemaVersionAtLeast(IFCSchemaVersion.IFC4Obsolete))
                    {
                        IFCPropertySet.AddParameterString(doc, element, category, "PredefinedType", PredefinedType, Id);
                    }
                    else
                    {
                        IFCPropertySet.AddParameterString(doc, element, category, "InteriorOrExteriorSpace", PredefinedType, Id);
                    }
                }

                // Set "IfcZone" parameter.
                string zoneNames = null;
                foreach (IFCGroup zone in AssignmentGroups)
                {
                    if (!(zone is IFCZone))
                    {
                        continue;
                    }

                    string name = zone.Name;
                    if (string.IsNullOrWhiteSpace(name))
                    {
                        continue;
                    }

                    if (zoneNames == null)
                    {
                        zoneNames = name;
                    }
                    else
                    {
                        zoneNames += ";" + name;
                    }
                }

                if (zoneNames != null)
                {
                    IFCPropertySet.AddParameterString(doc, element, category, "IfcZone", zoneNames, Id);
                }
            }
        }
        /// <summary>
        /// Create a property set for a given element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element being created.</param>
        /// <param name="parameterGroupMap">The parameters of the element.  Cached for performance.</param>
        /// <returns>The name of the property set created, if it was created, and a Boolean value if it should be added to the property set list.</returns>
        public override Tuple <string, bool> CreatePropertySet(Document doc, Element element, IFCParameterSetByGroup parameterGroupMap)
        {
            IDictionary <string, IFCData> parametersToAdd = new Dictionary <string, IFCData>();
            Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);

            foreach (KeyValuePair <Tuple <string, ForgeTypeId, AllowedValues>, double> property in DoubleProperties)
            {
                string    name = property.Key.Item1;
                Parameter existingParameter = null;
                if (!parameterGroupMap.TryFindParameter(name, out existingParameter))
                {
                    IFCPropertySet.AddParameterDouble(doc, element, category, name, property.Key.Item2, property.Value, Id);
                    continue;
                }

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

                case StorageType.Double:
                    existingParameter.Set(property.Value);
                    break;

                default:
                    Importer.TheLog.LogError(Id, "couldn't create parameter: " + name + " of storage type: " + existingParameter.StorageType.ToString(), false);
                    break;
                }
            }

            foreach (KeyValuePair <string, string> property in StringProperties)
            {
                string    name = property.Key;
                Parameter existingParameter = null;
                if (!parameterGroupMap.TryFindParameter(name, out existingParameter))
                {
                    IFCPropertySet.AddParameterString(doc, element, category, property.Key, property.Value, Id);
                    continue;
                }

                switch (existingParameter.StorageType)
                {
                case StorageType.String:
                    existingParameter.Set(property.Value);
                    break;

                default:
                    Importer.TheLog.LogError(Id, "couldn't create parameter: " + name + " of storage type: " + existingParameter.StorageType.ToString(), false);
                    break;
                }
            }

            return(Tuple.Create("\"" + EntityType.ToString() + "\"", false));
        }
Exemple #8
0
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);

            if (element != null)
            {
                Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);
                IFCPropertySet.AddParameterString(doc, element, category, this, "IfcPredefinedType", PredefinedType, Id);
                IFCPropertySet.AddParameterString(doc, element, category, this, "IfcAssemblyPlace", AssemblyPlace.ToString(), Id);
            }
        }
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="element"></param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);

            if (element != null)
            {
                // Set "IfcElevation" parameter.
                Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);
                IFCPropertySet.AddParameterDouble(doc, element, category, this, "IfcElevation", SpecTypeId.Length, UnitTypeId.Feet, Elevation, Id);
            }
        }
Exemple #10
0
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);

            if (element != null)
            {
                Category category = (ContainedIn != null) || (ConnectedFrom != null) ?
                                    IFCPropertySet.GetCategoryForParameterIfValid(element, Id) : null;
                if (ContainedIn != null)
                {
                    string guid = ContainedIn.GlobalId;
                    if (!string.IsNullOrWhiteSpace(guid))
                    {
                        IFCPropertySet.AddParameterString(doc, element, category, this, "IfcElement ContainedIn IfcGUID", guid, Id);
                    }

                    string name = ContainedIn.Name;
                    if (!string.IsNullOrWhiteSpace(name))
                    {
                        IFCPropertySet.AddParameterString(doc, element, category, this, "IfcElement ContainedIn Name", name, Id);
                    }
                }

                if (ConnectedFrom != null)
                {
                    string guid = ConnectedFrom.GlobalId;
                    if (!string.IsNullOrWhiteSpace(guid))
                    {
                        IFCPropertySet.AddParameterString(doc, element, category, this, "IfcPort ConnectedFrom IfcGUID", guid, Id);
                    }

                    string name = ConnectedFrom.Name;
                    if (!string.IsNullOrWhiteSpace(name))
                    {
                        IFCPropertySet.AddParameterString(doc, element, category, this, "IfcPort ConnectedFrom Name", name, Id);
                    }
                }

                if (ConnectedTo != null)
                {
                    string guid = ConnectedTo.GlobalId;
                    if (!string.IsNullOrWhiteSpace(guid))
                    {
                        IFCPropertySet.AddParameterString(doc, element, category, this, "IfcPort ConnectedTo IfcGUID", guid, Id);
                    }

                    string name = ConnectedTo.Name;
                    if (!string.IsNullOrWhiteSpace(name))
                    {
                        IFCPropertySet.AddParameterString(doc, element, category, this, "IfcPort ConnectedTo Name", name, Id);
                    }
                }
            }
        }
Exemple #11
0
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);

            if (element != null)
            {
                if (!string.IsNullOrWhiteSpace(ElementType))
                {
                    Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);
                    IFCPropertySet.AddParameterString(doc, element, category, "IfcElementType", ElementType, Id);
                }
            }
        }
Exemple #12
0
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);

            if (element != null)
            {
                Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);

                // Set "Tag" parameter.
                string ifcTag = Tag;
                if (!string.IsNullOrWhiteSpace(ifcTag))
                {
                    IFCPropertySet.AddParameterString(doc, element, category, "IfcTag", ifcTag, Id);
                }

                IFCFeatureElementSubtraction ifcFeatureElementSubtraction = FillsOpening;
                if (ifcFeatureElementSubtraction != null)
                {
                    IFCElement ifcElement = ifcFeatureElementSubtraction.VoidsElement;
                    if (ifcElement != null)
                    {
                        string ifcContainerName = ifcElement.Name;
                        IFCPropertySet.AddParameterString(doc, element, category, "IfcContainedInHost", ifcContainerName, Id);
                    }
                }

                // Create two parameters for each port: one for name, and one for GUID.
                // Note that Ports will never be null, as it is initialized the first time it is accessed.
                int numPorts = 0;
                foreach (IFCPort port in Ports)
                {
                    string name = port.Name;
                    string guid = port.GlobalId;

                    if (!string.IsNullOrWhiteSpace(name))
                    {
                        string parameterName = "IfcElement HasPorts Name " + ((numPorts == 0) ? "" : (numPorts + 1).ToString());
                        IFCPropertySet.AddParameterString(doc, element, category, parameterName, name, Id);
                    }

                    if (!string.IsNullOrWhiteSpace(guid))
                    {
                        string parameterName = "IfcElement HasPorts IfcGUID " + ((numPorts == 0) ? "" : (numPorts + 1).ToString());
                        IFCPropertySet.AddParameterString(doc, element, category, parameterName, guid, Id);
                    }

                    numPorts++;
                }
            }
        }
        /// <summary>
        /// Create quantities for a given element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element being created.</param>
        /// <param name="parameterGroupMap">The parameters of the element.  Cached for performance.</param>
        /// <returns>The name of the property set created, if it was created, and a Boolean value if it should be added to the property set list.</returns>
        public override Tuple <string, bool> CreatePropertySet(Document doc, Element element, IFCObjectDefinition objDef, IFCParameterSetByGroup parameterGroupMap)
        {
            Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);

            string quotedName = "\"" + Name + "\"";

            ISet <string> parametersCreated = new HashSet <string>();

            foreach (IFCPhysicalQuantity quantity in IFCQuantities.Values)
            {
                quantity.Create(doc, element, category, objDef, parameterGroupMap, Name, parametersCreated);
            }

            return(Tuple.Create(quotedName, true));
        }
Exemple #14
0
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);

            if (element != null)
            {
                // Set "ObjectTypeOverride" parameter.
                string objectTypeOverride = ObjectType;
                if (!string.IsNullOrWhiteSpace(objectTypeOverride))
                {
                    Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);
                    IFCPropertySet.AddParameterString(doc, element, category, "ObjectTypeOverride", objectTypeOverride, Id);
                }
            }
        }
Exemple #15
0
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);

            if (element != null)
            {
                Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);
                if (category != null)
                {
                    Importer.TheProcessor.SetStringParameter(element, Id, BuiltInParameter.DOOR_OPERATION_TYPE, OperationType.ToString(), false);
                    Importer.TheProcessor.SetStringParameter(element, Id, BuiltInParameter.DOOR_CONSTRUCTION_TYPE, ConstructionType.ToString(), false);

                    IFCPropertySet.AddParameterString(doc, element, category, this, "IfcOperationType", OperationType.ToString(), Id);
                    IFCPropertySet.AddParameterString(doc, element, category, this, "IfcConstructionType", ConstructionType.ToString(), Id);
                }
            }
        }
Exemple #16
0
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);

            if (element != null)
            {
                Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);

                // Set "IfcPresentationLayer" parameter.
                string ifcPresentationLayer = null;
                foreach (string currLayer in PresentationLayerNames)
                {
                    if (string.IsNullOrWhiteSpace(currLayer))
                    {
                        continue;
                    }

                    if (ifcPresentationLayer == null)
                    {
                        ifcPresentationLayer = currLayer;
                    }
                    else
                    {
                        ifcPresentationLayer += "; " + currLayer;
                    }
                }

                if (ifcPresentationLayer != null)
                {
                    IFCPropertySet.AddParameterString(doc, element, category, this, "IfcPresentationLayer", ifcPresentationLayer, Id);
                }

                // Set the container name of the element.
                string containerName = ContainingStructure?.Name;
                if (containerName != null)
                {
                    IFCPropertySet.AddParameterString(doc, element, category, this, "IfcSpatialContainer", containerName, Id);
                    IFCPropertySet.AddParameterString(doc, element, category, this, "IfcSpatialContainer GUID", ContainingStructure.GlobalId, Id);
                }
            }
        }
Exemple #17
0
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);
            string parameterName = "LandTitleNumber";

            // TODO: move this to new shared parameter names override function.
            if (element is ProjectInfo)
            {
                parameterName = "IfcSite " + parameterName;
            }

            if (element != null)
            {
                string landTitleNumber = LandTitleNumber;
                if (!string.IsNullOrWhiteSpace(landTitleNumber))
                {
                    Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);
                    IFCPropertySet.AddParameterString(doc, element, category, parameterName, landTitleNumber, Id);
                }
            }
        }
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);


            if (element != null)
            {
                // Set "ObjectTypeOverride" parameter.
                string longName = LongName;
                if (!string.IsNullOrWhiteSpace(longName))
                {
                    string parameterName = "LongNameOverride";
                    if (element is ProjectInfo)
                    {
                        parameterName = EntityType.ToString() + " " + parameterName;
                    }

                    Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);
                    IFCPropertySet.AddParameterString(doc, element, category, this, parameterName, longName, Id);
                }
            }
        }
Exemple #19
0
        /// <summary>
        /// Creates or populates Revit element params based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        protected override void CreateParametersInternal(Document doc, Element element)
        {
            base.CreateParametersInternal(doc, element);

            if (element != null)
            {
                Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);

                // Set "Tag" parameter.
                string ifcTag = Tag;
                if (!string.IsNullOrWhiteSpace(ifcTag))
                {
                    IFCPropertySet.AddParameterString(doc, element, category, this, "IfcTag", ifcTag, Id);
                }

                // Set "ProxyType" parameter.
                string ifcProxyType = ProxyType;
                if (!string.IsNullOrWhiteSpace(ifcProxyType))
                {
                    IFCPropertySet.AddParameterString(doc, element, category, this, "IfcProxyType", ifcProxyType, Id);
                }
            }
        }
Exemple #20
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);
                    }
                }
            }
        }
        protected virtual void CreateParametersInternal(Document doc, Element element)
        {
            if (element != null)
            {
                Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);

                // Set the element name.
                SetName(doc, element, category);

                // Set the element description.
                SetDescription(doc, element, category);

                // The list of materials.
                SetMaterialParameter(doc, element, category);

                // Set the "IfcSystem" parameter.
                SetSystemParameter(doc, element, category);

                // Set the element GUID.
                bool             elementIsType = (element is ElementType);
                BuiltInParameter ifcGUIDId     = GetGUIDParameter(element, elementIsType);
                Parameter        guidParam     = element.get_Parameter(ifcGUIDId);
                if (guidParam != null)
                {
                    if (!guidParam.IsReadOnly)
                    {
                        guidParam.Set(GlobalId);
                    }
                }
                else
                {
                    ExporterIFCUtils.AddValueString(element, new ElementId(ifcGUIDId), GlobalId);
                }

                // Set the "IfcExportAs" parameter.
                string ifcExportAs = IFCCategoryUtil.GetCustomCategoryName(this);
                if (!string.IsNullOrWhiteSpace(ifcExportAs))
                {
                    IFCPropertySet.AddParameterString(doc, element, category, this, IFCSharedParameters.IfcExportAs, ifcExportAs, Id);
                }

                // Set the IFCElementAssembly Parameter
                if (Decomposes != null)
                {
                    string containerParamName     = (Decomposes is IFCElementAssembly) ? "IfcElementAssembly" : "IfcDecomposes";
                    string containerParamGUIDName = (Decomposes is IFCElementAssembly) ? "IfcElementAssemblyGUID" : "IfcDecomposesGUID";
                    IFCPropertySet.AddParameterString(doc, element, category, containerParamName, Decomposes.Name, Id);
                    IFCPropertySet.AddParameterString(doc, element, category, containerParamGUIDName, Decomposes.GlobalId, Id);
                }

                // Set additional parameters (if any), e.g. for Classification assignments
                if (AdditionalIntParameters.Count > 0)
                {
                    foreach (KeyValuePair <string, object> parItem in AdditionalIntParameters)
                    {
                        if (parItem.Value is string)
                        {
                            IFCPropertySet.AddParameterString(doc, element, category, parItem.Key, (string)parItem.Value, Id);
                        }
                        else if (parItem.Value is double)
                        {
                            IFCPropertySet.AddParameterDouble(doc, element, category, parItem.Key, SpecTypeId.Custom, (double)parItem.Value, Id);
                        }
                        else if (parItem.Value is int)
                        {
                            IFCPropertySet.AddParameterInt(doc, element, category, parItem.Key, (int)parItem.Value, Id);
                        }
                        else if (parItem.Value is bool)
                        {
                            IFCPropertySet.AddParameterBoolean(doc, element, category, parItem.Key, (bool)parItem.Value, Id);
                        }
                    }
                }
            }
        }
        protected virtual void CreateParametersInternal(Document doc, Element element)
        {
            if (element != null)
            {
                Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);

                Importer.TheProcessor.CreateOrUpdateElement(Id, GlobalId, EntityType.ToString(), CategoryId.IntegerValue, null);

                // Set the element name.
                SetName(doc, element, category);

                // Set the element description.
                SetDescription(doc, element, category);

                // The list of materials.
                SetMaterialParameter(doc, element, category);

                // Set the "IfcSystem" parameter.
                SetSystemParameter(doc, element, category);

                bool elementIsType = (element is ElementType);
                if (!string.IsNullOrWhiteSpace(GlobalId))
                {
                    BuiltInParameter ifcGUIDId = GetGUIDParameter(element, elementIsType);
                    Importer.TheProcessor.SetStringParameter(element, Id, ifcGUIDId, GlobalId, true);
                }

                // Set the built-in parameters.
                (string entityName, string predefinedType) = IFCCategoryUtil.GetEntityNameAndPredefinedType(this);
                if (!string.IsNullOrWhiteSpace(entityName))
                {
                    BuiltInParameter ifcExportElementAsParam = elementIsType ? BuiltInParameter.IFC_EXPORT_ELEMENT_TYPE_AS : BuiltInParameter.IFC_EXPORT_ELEMENT_AS;
                    Importer.TheProcessor.SetStringParameter(element, Id, ifcExportElementAsParam, entityName, true);
                }

                if (!string.IsNullOrWhiteSpace(predefinedType))
                {
                    BuiltInParameter ifcPredefinedTypeParam = elementIsType ? BuiltInParameter.IFC_EXPORT_PREDEFINEDTYPE_TYPE : BuiltInParameter.IFC_EXPORT_PREDEFINEDTYPE;
                    Importer.TheProcessor.SetStringParameter(element, Id, ifcPredefinedTypeParam, predefinedType, true);
                }
                // Set the IFCElementAssembly Parameter
                if (Decomposes != null)
                {
                    string containerParamName     = (Decomposes is IFCElementAssembly) ? "IfcElementAssembly" : "IfcDecomposes";
                    string containerParamGUIDName = (Decomposes is IFCElementAssembly) ? "IfcElementAssemblyGUID" : "IfcDecomposesGUID";
                    IFCPropertySet.AddParameterString(doc, element, category, this, containerParamName, Decomposes.Name, Id);
                    IFCPropertySet.AddParameterString(doc, element, category, this, containerParamGUIDName, Decomposes.GlobalId, Id);
                }

                // Set additional parameters (if any), e.g. for Classification assignments
                if (AdditionalIntParameters.Count > 0)
                {
                    foreach (KeyValuePair <string, object> parItem in AdditionalIntParameters)
                    {
                        if (parItem.Value is string)
                        {
                            IFCPropertySet.AddParameterString(doc, element, category, this, parItem.Key, (string)parItem.Value, Id);
                        }
                        else if (parItem.Value is double)
                        {
                            IFCPropertySet.AddParameterDouble(doc, element, category, this, parItem.Key, SpecTypeId.Custom, UnitTypeId.General, (double)parItem.Value, Id);
                        }
                        else if (parItem.Value is int)
                        {
                            IFCPropertySet.AddParameterInt(doc, element, category, this, parItem.Key, (int)parItem.Value, Id);
                        }
                        else if (parItem.Value is bool)
                        {
                            IFCPropertySet.AddParameterBoolean(doc, element, category, this, parItem.Key, (bool)parItem.Value, Id);
                        }
                    }
                }
            }
        }