/// <summary>
        /// Calculates number of risers for a stair.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="extrusionCreationData">
        /// The IFCExtrusionCreationData.
        /// </param>
        /// <param name="element">
        /// The element to calculate the value.
        /// </param>
        /// <param name="elementType">
        /// The element type.
        /// </param>
        /// <returns>
        /// True if the operation succeed, false otherwise.
        /// </returns>
        public override bool Calculate(ExporterIFC exporterIFC, IFCExtrusionCreationData extrusionCreationData, Element element, ElementType elementType)
        {
            bool valid = true;

            if (m_CurrentElement != element)
            {
                m_CurrentElement = element;
                if (StairsExporter.IsLegacyStairs(element))
                {
                    ExporterIFCUtils.GetLegacyStairsProperties(exporterIFC, element,
                                                               out m_NumberOfRisers, out m_NumberOfTreads,
                                                               out m_RiserHeight, out m_TreadLength, out m_TreadLengthAtInnerSide,
                                                               out m_NosingLength, out m_WaistThickness);
                    m_TreadLengthAtOffset = m_TreadLength;
                    m_WalkingLineOffset   = m_WaistThickness / 2.0;
                }
                else if (element is Stairs)
                {
                    Stairs stairs = element as Stairs;
                    m_NumberOfRisers = stairs.ActualRisersNumber;
                    m_NumberOfTreads = stairs.ActualTreadsNumber;
                    m_RiserHeight    = UnitUtil.ScaleLength(stairs.ActualRiserHeight);
                    m_TreadLength    = UnitUtil.ScaleLength(stairs.ActualTreadDepth);
                }
                else if (element is StairsRun)
                {
                    StairsRun     stairsRun     = element as StairsRun;
                    StairsRunType stairsRunType = stairsRun.Document.GetElement(stairsRun.GetTypeId()) as StairsRunType;
                    Stairs        stairs        = stairsRun.GetStairs();
                    StairsType    stairsType    = stairs.Document.GetElement(stairs.GetTypeId()) as StairsType;

                    m_NumberOfRisers      = stairs.ActualRisersNumber;
                    m_NumberOfTreads      = stairs.ActualTreadsNumber;
                    m_RiserHeight         = UnitUtil.ScaleLength(stairs.ActualRiserHeight);
                    m_TreadLength         = UnitUtil.ScaleLength(stairs.ActualTreadDepth);
                    m_TreadLengthAtOffset = m_TreadLength;
                    m_NosingLength        = UnitUtil.ScaleLength(stairsRunType.NosingLength);
                    m_WaistThickness      = UnitUtil.ScaleLength(stairsRun.ActualRunWidth);
                    m_WalkingLineOffset   = m_WaistThickness / 2.0;

                    double treadLengthAtInnerSide;
                    if (ParameterUtil.GetDoubleValueFromElement(stairsType,
                                                                BuiltInParameter.STAIRSTYPE_MINIMUM_TREAD_WIDTH_INSIDE_BOUNDARY, out treadLengthAtInnerSide) != null)
                    {
                        m_TreadLengthAtInnerSide = UnitUtil.ScaleLength(treadLengthAtInnerSide);
                    }
                    else
                    {
                        m_TreadLengthAtInnerSide = 0.0;
                    }
                }
                else
                {
                    valid = false;
                }
            }
            return(valid);
        }
        /// <summary>
        /// Calculates number of risers for a stair.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="extrusionCreationData">
        /// The IFCExtrusionCreationData.
        /// </param>
        /// <param name="element">
        /// The element to calculate the value.
        /// </param>
        /// <param name="elementType">
        /// The element type.
        /// </param>
        /// <returns>
        /// True if the operation succeed, false otherwise.
        /// </returns>
        public override bool Calculate(ExporterIFC exporterIFC, IFCExtrusionCreationData extrusionCreationData, Element element, ElementType elementType, EntryMap entryMap)
        {
            bool valid = true;

            if (StairsExporter.IsLegacyStairs(element))
            {
                double riserHeight, treadLength, nosingLength, waistThickness = 0;
                int    numberOfRisers, numberOfTreads = 0;
                ExporterIFCUtils.GetLegacyStairsProperties(exporterIFC, element,
                                                           out numberOfRisers, out numberOfTreads,
                                                           out riserHeight, out treadLength, out m_TreadLengthAtInnerSide,
                                                           out nosingLength, out waistThickness);
            }
            else if (element is Stairs || element is StairsRun)
            {
                Stairs stairs;
                if (element is StairsRun)
                {
                    StairsRun stairsRun = element as StairsRun;
                    stairs = stairsRun.GetStairs();
                }
                else
                {
                    stairs = element as Stairs;
                }

                StairsType stairsType = stairs.Document.GetElement(stairs.GetTypeId()) as StairsType;

                double treadLengthAtInnerSide;
                if (ParameterUtil.GetDoubleValueFromElement(stairsType,
                                                            BuiltInParameter.STAIRSTYPE_MINIMUM_TREAD_WIDTH_INSIDE_BOUNDARY, out treadLengthAtInnerSide) != null)
                {
                    m_TreadLengthAtInnerSide = UnitUtil.ScaleLength(treadLengthAtInnerSide);
                }

                if (m_TreadLengthAtInnerSide <= 0)
                {
                    m_TreadLengthAtInnerSide = UnitUtil.ScaleLength(stairs.ActualTreadDepth);
                }
            }
            else
            {
                valid = false;
            }

            // Get override from parameter
            double treadLengthAtInnerSideOverride = 0.0;

            if (ParameterUtil.GetDoubleValueFromElementOrSymbol(element, entryMap.RevitParameterName, out treadLengthAtInnerSideOverride) != null ||
                ParameterUtil.GetDoubleValueFromElementOrSymbol(element, entryMap.CompatibleRevitParameterName, out treadLengthAtInnerSideOverride) != null)
            {
                m_TreadLengthAtInnerSide = UnitUtil.ScaleArea(treadLengthAtInnerSideOverride);
            }

            return(valid);
        }
示例#3
0
        /// <summary>
        /// Calculates number of risers for a stair.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="extrusionCreationData">
        /// The IFCExtrusionCreationData.
        /// </param>
        /// <param name="element">
        /// The element to calculate the value.
        /// </param>
        /// <param name="elementType">
        /// The element type.
        /// </param>
        /// <returns>
        /// True if the operation succeed, false otherwise.
        /// </returns>
        public override bool Calculate(ExporterIFC exporterIFC, IFCExtrusionCreationData extrusionCreationData, Element element, ElementType elementType)
        {
            bool valid = true;

            if (m_CurrentElement != element)
            {
                double scale = exporterIFC.LinearScale;

                m_CurrentElement = element;
                if (StairsExporter.IsLegacyStairs(element))
                {
                    ExporterIFCUtils.GetLegacyStairsProperties(exporterIFC, element,
                                                               out m_NumberOfRisers, out m_NumberOfTreads,
                                                               out m_RiserHeight, out m_TreadLength, out m_TreadLengthAtInnerSide,
                                                               out m_NosingLength, out m_WaistThickness);
                    m_TreadLengthAtOffset = m_TreadLength;
                    m_WalkingLineOffset   = m_WaistThickness / 2.0;
                }
                else if (element is Stairs)
                {
                    Stairs stairs = element as Stairs;
                    m_NumberOfRisers = stairs.ActualRisersNumber;
                    m_NumberOfTreads = stairs.ActualTreadsNumber;
                    m_RiserHeight    = stairs.ActualRiserHeight * scale;
                    m_TreadLength    = stairs.ActualTreadDepth * scale;
                }
                else if (element is StairsRun)
                {
                    StairsRun     stairsRun     = element as StairsRun;
                    StairsRunType stairsRunType = stairsRun.Document.GetElement(stairsRun.GetTypeId()) as StairsRunType;
                    Stairs        stairs        = stairsRun.GetStairs();
                    StairsType    stairsType    = stairs.Document.GetElement(stairs.GetTypeId()) as StairsType;

                    m_NumberOfRisers      = stairs.ActualRisersNumber;
                    m_NumberOfTreads      = stairs.ActualTreadsNumber;
                    m_RiserHeight         = stairs.ActualRiserHeight * scale;
                    m_TreadLength         = stairs.ActualTreadDepth * scale;
                    m_TreadLengthAtOffset = m_TreadLength;
                    m_NosingLength        = stairsRunType.NosingLength * scale;
                    m_WaistThickness      = stairsRun.ActualRunWidth * scale;
                    m_WalkingLineOffset   = m_WaistThickness / 2.0;

                    Parameter treadLengthAtInnerSideParam = stairsType.get_Parameter(BuiltInParameter.STAIRSTYPE_MINIMUM_TREAD_WIDTH_INSIDE_BOUNDARY);
                    m_TreadLengthAtInnerSide = (treadLengthAtInnerSideParam != null) ? (treadLengthAtInnerSideParam.AsDouble() * scale) : 0.0;
                }
                else
                {
                    valid = false;
                }
            }
            return(valid);
        }
示例#4
0
        /// <summary>
        /// Calculates number of risers for a stair.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="extrusionCreationData">
        /// The IFCExtrusionCreationData.
        /// </param>
        /// <param name="element">
        /// The element to calculate the value.
        /// </param>
        /// <param name="elementType">
        /// The element type.
        /// </param>
        /// <returns>
        /// True if the operation succeed, false otherwise.
        /// </returns>
        public override bool Calculate(ExporterIFC exporterIFC, IFCExtrusionCreationData extrusionCreationData, Element element, ElementType elementType, EntryMap entryMap)
        {
            bool valid = true;

            if (StairsExporter.IsLegacyStairs(element))
            {
                double riserHeight, treadLength, treadLengthAtInnerSide, nosingLength, waistThickness = 0;
                int    numberOfRisers, numberOfTreads = 0;
                ExporterIFCUtils.GetLegacyStairsProperties(exporterIFC, element,
                                                           out numberOfRisers, out numberOfTreads,
                                                           out riserHeight, out treadLength, out treadLengthAtInnerSide,
                                                           out nosingLength, out waistThickness);
                m_WalkingLineOffset = waistThickness / 2.0;    // !! The waist thickness seems to be wrongly associated with the width of the run!
            }
            else if (element is Stairs)
            {
                Stairs stairs = element as Stairs;
                ICollection <ElementId> stairRuns = stairs.GetStairsRuns();
                if (stairRuns.Count > 0)
                {
                    // Get the run width from one of the run/flight to compute the walking line offset
                    StairsRun run = stairs.Document.GetElement(stairRuns.First()) as StairsRun;
                    m_WalkingLineOffset = run.ActualRunWidth / 2.0;
                }
            }
            else if (element is StairsRun)
            {
                StairsRun     stairsRun     = element as StairsRun;
                StairsRunType stairsRunType = stairsRun.Document.GetElement(stairsRun.GetTypeId()) as StairsRunType;
                m_WalkingLineOffset = stairsRun.ActualRunWidth / 2.0;
            }
            else
            {
                valid = false;
            }

            // Get override from parameter
            double walkingLineOffsetOverride = 0.0;

            if (ParameterUtil.GetDoubleValueFromElementOrSymbol(element, entryMap.RevitParameterName, out walkingLineOffsetOverride) != null ||
                ParameterUtil.GetDoubleValueFromElementOrSymbol(element, entryMap.CompatibleRevitParameterName, out walkingLineOffsetOverride) != null)
            {
                m_WalkingLineOffset = UnitUtil.ScaleArea(walkingLineOffsetOverride);
            }

            return(valid);
        }
        /// <summary>
        /// Calculates number of risers for a stair.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="extrusionCreationData">The IFCExtrusionCreationData.</param>
        /// <param name="element">The element to calculate the value.</param>
        /// <param name="elementType">The element type.</param>
        /// <returns>True if the operation succeed, false otherwise.</returns>
        public override bool Calculate(ExporterIFC exporterIFC, IFCExtrusionCreationData extrusionCreationData, Element element, ElementType elementType, EntryMap entryMap)
        {
            bool valid = true;

            if (StairsExporter.IsLegacyStairs(element))
            {
                double riserHeight, treadLength, treadLengthAtInnerSide, nosingLength, waistThickness = 0;
                int    numberOfTreads;

                ExporterIFCUtils.GetLegacyStairsProperties(exporterIFC, element,
                                                           out m_NumberOfRisers, out numberOfTreads,
                                                           out riserHeight, out treadLength, out treadLengthAtInnerSide,
                                                           out nosingLength, out waistThickness);
            }
            else if (element is Stairs)
            {
                Stairs stairs = element as Stairs;
                m_NumberOfRisers = stairs.ActualRisersNumber;
            }
            else if (element is StairsRun)
            {
                StairsRun     stairsRun     = element as StairsRun;
                StairsRunType stairsRunType = stairsRun.Document.GetElement(stairsRun.GetTypeId()) as StairsRunType;
                m_NumberOfRisers = stairsRun.ActualRisersNumber;
            }
            else
            {
                valid = false;
            }

            // Get override from parameter
            int?noRiserOverride = ParameterUtil.GetIntValueFromElementOrSymbol(element, entryMap.RevitParameterName);

            if (!noRiserOverride.HasValue)
            {
                noRiserOverride = ParameterUtil.GetIntValueFromElementOrSymbol(element, entryMap.CompatibleRevitParameterName);
            }

            if (noRiserOverride.HasValue)
            {
                m_NumberOfRisers = noRiserOverride.Value;
                valid            = true;
            }

            return(valid);
        }
        /// <summary>
        /// Calculates number of risers for a stair.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="extrusionCreationData">
        /// The IFCExtrusionCreationData.
        /// </param>
        /// <param name="element">
        /// The element to calculate the value.
        /// </param>
        /// <param name="elementType">
        /// The element type.
        /// </param>
        /// <returns>
        /// True if the operation succeed, false otherwise.
        /// </returns>
        public override bool Calculate(ExporterIFC exporterIFC, IFCExtrusionCreationData extrusionCreationData, Element element, ElementType elementType, EntryMap entryMap)
        {
            bool valid = true;

            if (StairsExporter.IsLegacyStairs(element))
            {
                double riserHeight, treadLength, treadLengthAtInnerSide, nosingLength, waistThickness = 0;
                int    numberOfRisers, numberOfTreads = 0;
                ExporterIFCUtils.GetLegacyStairsProperties(exporterIFC, element,
                                                           out numberOfRisers, out numberOfTreads,
                                                           out riserHeight, out treadLength, out treadLengthAtInnerSide,
                                                           out nosingLength, out waistThickness);
                m_TreadLengthAtOffset = treadLength;
            }
            else if (element is Stairs)
            {
                Stairs stairs = element as Stairs;
                m_TreadLengthAtOffset = UnitUtil.ScaleLength(stairs.ActualTreadDepth);
            }
            else if (element is StairsRun)
            {
                StairsRun stairsRun = element as StairsRun;
                Stairs    stairs    = stairsRun.GetStairs();
                m_TreadLengthAtOffset = UnitUtil.ScaleLength(stairs.ActualTreadDepth);
            }
            else
            {
                valid = false;
            }

            // Get override from parameter
            double treadLengthAtOffset = 0.0;

            if (ParameterUtil.GetDoubleValueFromElementOrSymbol(element, entryMap.RevitParameterName, out treadLengthAtOffset) != null ||
                ParameterUtil.GetDoubleValueFromElementOrSymbol(element, entryMap.CompatibleRevitParameterName, out treadLengthAtOffset) != null)
            {
                m_TreadLengthAtOffset = UnitUtil.ScaleArea(treadLengthAtOffset);
            }

            return(valid);
        }
示例#7
0
        /// <summary>
        /// Exports a ramp to IfcRamp.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The ramp element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            string  ifcEnumType = ExporterUtil.GetIFCTypeFromExportTable(exporterIFC, element);
            IFCFile file        = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                StairsExporter.ExportLegacyStairOrRampAsContainer(exporterIFC, ifcEnumType, element, geometryElement, productWrapper);

                // If we didn't create a handle here, then the element wasn't a "native" Ramp, and is likely a FamilyInstance or a DirectShape.
                if (IFCAnyHandleUtil.IsNullOrHasNoValue(productWrapper.GetAnElement()))
                {
                    int numFlights = GetNumFlightsForRamp(exporterIFC, element);
                    if (numFlights > 0)
                    {
                        ExportRamp(exporterIFC, ifcEnumType, element, geometryElement, numFlights, productWrapper);
                    }
                }

                tr.Commit();
            }
        }
        /// <summary>
        /// Calculates number of risers for a stair.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="extrusionCreationData">
        /// The IFCExtrusionCreationData.
        /// </param>
        /// <param name="element">
        /// The element to calculate the value.
        /// </param>
        /// <param name="elementType">
        /// The element type.
        /// </param>
        /// <returns>
        /// True if the operation succeed, false otherwise.
        /// </returns>
        public override bool Calculate(ExporterIFC exporterIFC, IFCExtrusionCreationData extrusionCreationData, Element element, ElementType elementType)
        {
            bool valid = true;

            if (StairsExporter.IsLegacyStairs(element))
            {
                double riserHeight, treadLengthAtInnerSide, nosingLength, waistThickness = 0;
                int    numberOfRisers, numberOfTreads = 0;
                ExporterIFCUtils.GetLegacyStairsProperties(exporterIFC, element,
                                                           out numberOfRisers, out numberOfTreads,
                                                           out riserHeight, out m_TreadLength, out treadLengthAtInnerSide,
                                                           out nosingLength, out waistThickness);
            }
            else if (element is Stairs)
            {
                Stairs stairs = element as Stairs;
                m_TreadLength = UnitUtil.ScaleLength(stairs.ActualTreadDepth);
            }
            else if (element is StairsRun)
            {
                StairsRun     stairsRun     = element as StairsRun;
                StairsRunType stairsRunType = stairsRun.Document.GetElement(stairsRun.GetTypeId()) as StairsRunType;
                Stairs        stairs        = stairsRun.GetStairs();

                m_TreadLength = UnitUtil.ScaleLength(stairs.ActualTreadDepth);
            }
            else
            {
                valid = false;
            }

            // Get override from parameter
            if (ParameterUtil.GetDoubleValueFromElementOrSymbol(element, "TreadLength", out m_TreadLength) != null)
            {
                m_TreadLength = UnitUtil.ScaleArea(m_TreadLength);
            }

            return(valid);
        }
示例#9
0
        /// <summary>
        /// Calculates number of risers for a stair.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="extrusionCreationData">
        /// The IFCExtrusionCreationData.
        /// </param>
        /// <param name="element">
        /// The element to calculate the value.
        /// </param>
        /// <param name="elementType">
        /// The element type.
        /// </param>
        /// <returns>
        /// True if the operation succeed, false otherwise.
        /// </returns>
        public override bool Calculate(ExporterIFC exporterIFC, IFCExtrusionCreationData extrusionCreationData, Element element, ElementType elementType, EntryMap entryMap)
        {
            bool valid = true;

            if (StairsExporter.IsLegacyStairs(element))
            {
                double riserHeight, treadLength, treadLengthAtInnerSide, waistThickness = 0;
                int    numberOfRisers, numberOfTreads = 0;
                ExporterIFCUtils.GetLegacyStairsProperties(exporterIFC, element,
                                                           out numberOfRisers, out numberOfTreads,
                                                           out riserHeight, out treadLength, out treadLengthAtInnerSide,
                                                           out m_NosingLength, out waistThickness);
            }
            else if (element is Stairs)
            {
                Stairs stairs = element as Stairs;
                ICollection <ElementId> stairRuns = stairs.GetStairsRuns();
                if (stairRuns.Count > 0)
                {
                    // Get the run width from one of the run/flight to compute the walking line offset
                    StairsRun     run           = stairs.Document.GetElement(stairRuns.First()) as StairsRun;
                    StairsRunType stairsRunType = run.Document.GetElement(run.GetTypeId()) as StairsRunType;
                    m_NosingLength = UnitUtil.ScaleLength(stairsRunType.NosingLength);
                }
            }
            else if (element is StairsRun)
            {
                StairsRun     stairsRun     = element as StairsRun;
                StairsRunType stairsRunType = stairsRun.Document.GetElement(stairsRun.GetTypeId()) as StairsRunType;
                m_NosingLength = UnitUtil.ScaleLength(stairsRunType.NosingLength);
            }
            else
            {
                valid = false;
            }
            return(valid);
        }
示例#10
0
        private static ElementId GetStairOrRampHostId(ExporterIFC exporterIFC, Railing railingElem)
        {
            ElementId returnHostId = ElementId.InvalidElementId;

            if (railingElem == null)
            {
                return(returnHostId);
            }

            ElementId hostId = railingElem.HostId;

            if (hostId == ElementId.InvalidElementId)
            {
                return(returnHostId);
            }

            if (!ExporterCacheManager.StairRampContainerInfoCache.ContainsStairRampContainerInfo(hostId))
            {
                return(returnHostId);
            }

            Element host = railingElem.Document.GetElement(hostId);

            if (host == null)
            {
                return(returnHostId);
            }

            if (!(host is Stairs) && !StairsExporter.IsLegacyStairs(host) && !RampExporter.IsRamp(host))
            {
                return(returnHostId);
            }

            returnHostId = hostId;
            return(returnHostId);
        }
示例#11
0
 /// <summary>
 /// Gets the number of flights of a multi-story ramp.
 /// </summary>
 /// <param name="exporterIFC">
 /// The exporter.
 /// </param>
 /// <param name="element">
 /// The element.
 /// </param>
 /// <returns>
 /// The number of flights (at least 1.)
 /// </returns>
 static public int GetNumFlightsForRamp(ExporterIFC exporterIFC, Element element)
 {
     return(StairsExporter.GetNumFlightsForLegacyStair(exporterIFC, element, GetDefaultHeightForRamp()));
 }
示例#12
0
 /// <summary>
 /// Gets the ramp height for a ramp.
 /// </summary>
 /// <param name="exporterIFC">
 /// The exporter.
 /// </param>
 /// <param name="element">
 /// The element.
 /// </param>
 /// <returns>
 /// The unscaled height.
 /// </returns>
 static public double GetRampHeight(ExporterIFC exporterIFC, Element element)
 {
     // Re-use the code for stairs height for legacy stairs.
     return(StairsExporter.GetStairsHeightForLegacyStair(exporterIFC, element, GetDefaultHeightForRamp()));
 }
示例#13
0
        /// <summary>
        /// Returns the base level of an element.  The method used to find the base level depends on the element type.
        /// </summary>
        public static ElementId GetBaseLevelIdForElement(Element elem)
        {
            // If the element is view specific, use the level of the parent view.
            if (elem.ViewSpecific)
            {
                ElementId viewId = elem.OwnerViewId;
                ElementId viewSpecificlevelId;
                if (ExporterCacheManager.DBViewsToExport.TryGetValue(viewId, out viewSpecificlevelId))
                {
                    return(viewSpecificlevelId);
                }
            }

            // Some elements will have a parameter that defines the base level.  Find it if possible.
            IList <BuiltInParameter> priortizedParameterList = new List <BuiltInParameter>();
            Element elemToCheck = elem;

            if (elem is Wall)
            {
                priortizedParameterList.Add(BuiltInParameter.WALL_BASE_CONSTRAINT);
            }
            else if (elem is FamilyInstance)
            {
                // If this is a nested family, check the top-level instance for the level parameter information.
                elemToCheck = (elem as FamilyInstance).SuperComponent;
                if (elemToCheck == null)
                {
                    elemToCheck = elem;
                }

                // Inplace wall parameter.
                priortizedParameterList.Add(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM);

                // There are two Family-related parameters for non-inplace walls: INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM and INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM.
                // We prioritize INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM over INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM.
                priortizedParameterList.Add(BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM);
                priortizedParameterList.Add(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM);
            }
            else if (elem is Truss)
            {
                priortizedParameterList.Add(BuiltInParameter.TRUSS_ELEMENT_REFERENCE_LEVEL_PARAM);
            }
            else if (elem is Stairs || StairsExporter.IsLegacyStairs(elem))
            {
                priortizedParameterList.Add(BuiltInParameter.STAIRS_BASE_LEVEL_PARAM);
            }
            else if (elem is ExtrusionRoof)
            {
                priortizedParameterList.Add(BuiltInParameter.ROOF_CONSTRAINT_LEVEL_PARAM);
            }

            // If the level parameter was found, use it.  Otherwise, try asking the element directly.
            foreach (BuiltInParameter levelParameterVal in priortizedParameterList)
            {
                Parameter levelParameter = elemToCheck.get_Parameter(levelParameterVal);
                if (levelParameter != null && levelParameter.StorageType == StorageType.ElementId)
                {
                    ElementId levelId = levelParameter.AsElementId();
                    if (levelId != ElementId.InvalidElementId)
                    {
                        return(levelId);
                    }
                }
            }

            // Didn't find a parameter; try asking the element directly.
            if (elem is MEPCurve)
            {
                Level level = (elem as MEPCurve).ReferenceLevel;
                if (level != null)
                {
                    return(level.Id);
                }
            }

            return(elem.LevelId);
        }
        /// <summary>
        /// Exports an element as an IFC assembly.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if exported successfully, false otherwise.</returns>
        public static bool ExportAssemblyInstanceElement(ExporterIFC exporterIFC, AssemblyInstance element,
                                                         ProductWrapper productWrapper)
        {
            if (element == null)
            {
                return(false);
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                IFCAnyHandle assemblyInstanceHnd = null;

                string          guid            = GUIDUtil.CreateGUID(element);
                IFCAnyHandle    ownerHistory    = ExporterCacheManager.OwnerHistoryHandle;
                IFCAnyHandle    localPlacement  = null;
                PlacementSetter placementSetter = null;
                IFCLevelInfo    levelInfo       = null;
                bool            relateToLevel   = true;

                string            ifcEnumType;
                IFCExportInfoPair exportAs = ExporterUtil.GetExportType(exporterIFC, element, out ifcEnumType);
                if (exportAs.ExportInstance == IFCEntityType.IfcSystem)
                {
                    string name        = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                    string description = NamingUtil.GetDescriptionOverride(element, null);
                    string objectType  = NamingUtil.GetObjectTypeOverride(element, NamingUtil.GetFamilyAndTypeName(element));
                    assemblyInstanceHnd = IFCInstanceExporter.CreateSystem(file, guid, ownerHistory, name, description, objectType);

                    // Create classification reference when System has classification filed name assigned to it
                    ClassificationUtil.CreateClassification(exporterIFC, file, element, assemblyInstanceHnd);

                    HashSet <IFCAnyHandle> relatedBuildings = new HashSet <IFCAnyHandle>();
                    relatedBuildings.Add(ExporterCacheManager.BuildingHandle);

                    IFCAnyHandle relServicesBuildings = IFCInstanceExporter.CreateRelServicesBuildings(file, GUIDUtil.CreateGUID(),
                                                                                                       ExporterCacheManager.OwnerHistoryHandle, null, null, assemblyInstanceHnd, relatedBuildings);

                    relateToLevel = false; // Already related to the building via IfcRelServicesBuildings.
                }
                else
                {
                    // Check for containment override
                    IFCAnyHandle overrideContainerHnd = null;
                    ElementId    overrideContainerId  = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd);

                    using (placementSetter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd))
                    {
                        IFCAnyHandle representation = null;

                        // We have limited support for exporting assemblies as other container types.
                        localPlacement = placementSetter.LocalPlacement;
                        levelInfo      = placementSetter.LevelInfo;

                        switch (exportAs.ExportInstance)
                        {
                        case IFCEntityType.IfcCurtainWall:
                            //case IFCExportType.IfcCurtainWallType:
                            //string cwPredefinedType = IFCValidateEntry.GetValidIFCPredefinedType(element, ifcEnumType, "IfcCurtainWallType");
                            assemblyInstanceHnd = IFCInstanceExporter.CreateCurtainWall(exporterIFC, element, guid,
                                                                                        ownerHistory, localPlacement, representation, ifcEnumType);
                            break;

                        case IFCEntityType.IfcRamp:
                            string rampPredefinedType = RampExporter.GetIFCRampType(ifcEnumType);
                            //rampPredefinedType = IFCValidateEntry.GetValidIFCPredefinedType(element, rampPredefinedType, "IfcRampType");
                            assemblyInstanceHnd = IFCInstanceExporter.CreateRamp(exporterIFC, element, guid,
                                                                                 ownerHistory, localPlacement, representation, rampPredefinedType);
                            break;

                        case IFCEntityType.IfcRoof:
                            //string roofPredefinedType = IFCValidateEntry.GetValidIFCPredefinedType(element, ifcEnumType, "IfcRoofType");
                            assemblyInstanceHnd = IFCInstanceExporter.CreateRoof(exporterIFC, element, guid,
                                                                                 ownerHistory, localPlacement, representation, ifcEnumType);
                            break;

                        case IFCEntityType.IfcStair:
                            string stairPredefinedType = StairsExporter.GetIFCStairType(ifcEnumType);
                            //stairPredefinedType = IFCValidateEntry.GetValidIFCPredefinedType(element, stairPredefinedType, "IfcStairType");
                            assemblyInstanceHnd = IFCInstanceExporter.CreateStair(exporterIFC, element, guid,
                                                                                  ownerHistory, localPlacement, representation, stairPredefinedType);
                            break;

                        case IFCEntityType.IfcWall:
                            //string wallPredefinedType = IFCValidateEntry.GetValidIFCPredefinedType(element, ifcEnumType, "IfcWallType");
                            assemblyInstanceHnd = IFCInstanceExporter.CreateWall(exporterIFC, element, guid,
                                                                                 ownerHistory, localPlacement, representation, ifcEnumType);
                            break;

                        default:
                            string objectType = NamingUtil.GetObjectTypeOverride(element, NamingUtil.GetFamilyAndTypeName(element));
                            IFCElementAssemblyType assemblyPredefinedType = GetPredefinedTypeFromObjectType(objectType);
                            assemblyInstanceHnd = IFCInstanceExporter.CreateElementAssembly(exporterIFC, element, guid,
                                                                                            ownerHistory, localPlacement, representation, IFCAssemblyPlace.NotDefined, assemblyPredefinedType);
                            break;
                        }
                    }
                }

                if (assemblyInstanceHnd == null)
                {
                    return(false);
                }

                // relateToLevel depends on how the AssemblyInstance is being mapped to IFC, above.
                productWrapper.AddElement(element, assemblyInstanceHnd, levelInfo, null, relateToLevel, exportAs);

                ExporterCacheManager.AssemblyInstanceCache.RegisterAssemblyInstance(element.Id, assemblyInstanceHnd);

                tr.Commit();
                return(true);
            }
        }
        /// <summary>
        /// Exports an element as an IFC assembly.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if exported successfully, false otherwise.</returns>
        public static bool ExportAssemblyInstanceElement(ExporterIFC exporterIFC, AssemblyInstance element,
                                                         ProductWrapper productWrapper)
        {
            if (element == null)
            {
                return(false);
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                IFCAnyHandle assemblyInstanceHnd = null;

                string          guid            = GUIDUtil.CreateGUID(element);
                IFCAnyHandle    ownerHistory    = exporterIFC.GetOwnerHistoryHandle();
                string          name            = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                string          description     = NamingUtil.GetDescriptionOverride(element, null);
                string          objectType      = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName());
                IFCAnyHandle    localPlacement  = null;
                PlacementSetter placementSetter = null;
                IFCLevelInfo    levelInfo       = null;

                string        ifcEnumType;
                IFCExportType exportAs = ExporterUtil.GetExportType(exporterIFC, element, out ifcEnumType);
                if (exportAs == IFCExportType.IfcSystem)
                {
                    assemblyInstanceHnd = IFCInstanceExporter.CreateSystem(file, guid,
                                                                           ownerHistory, name, description, objectType);

                    // Create classification reference when System has classification filed name assigned to it
                    ClassificationUtil.CreateClassification(exporterIFC, file, element, assemblyInstanceHnd);

                    HashSet <IFCAnyHandle> relatedBuildings = new HashSet <IFCAnyHandle>();
                    relatedBuildings.Add(ExporterCacheManager.BuildingHandle);

                    IFCAnyHandle relServicesBuildings = IFCInstanceExporter.CreateRelServicesBuildings(file, GUIDUtil.CreateGUID(),
                                                                                                       exporterIFC.GetOwnerHistoryHandle(), null, null, assemblyInstanceHnd, relatedBuildings);
                }
                else
                {
                    using (placementSetter = PlacementSetter.Create(exporterIFC, element))
                    {
                        string       elementTag     = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));
                        IFCAnyHandle representation = null;

                        // We have limited support for exporting assemblies as other container types.
                        localPlacement = placementSetter.LocalPlacement;
                        levelInfo      = placementSetter.LevelInfo;
                        ifcEnumType    = IFCValidateEntry.GetValidIFCType(element, ifcEnumType);

                        switch (exportAs)
                        {
                        case IFCExportType.IfcCurtainWall:
                            assemblyInstanceHnd = IFCInstanceExporter.CreateCurtainWall(file, guid,
                                                                                        ownerHistory, name, description, objectType, localPlacement, representation, elementTag);
                            break;

                        case IFCExportType.IfcRamp:
                            string rampPredefinedType = RampExporter.GetIFCRampType(ifcEnumType);
                            assemblyInstanceHnd = IFCInstanceExporter.CreateRamp(file, guid,
                                                                                 ownerHistory, name, description, objectType, localPlacement, representation, elementTag,
                                                                                 rampPredefinedType);
                            break;

                        case IFCExportType.IfcRoof:
                            assemblyInstanceHnd = IFCInstanceExporter.CreateRoof(file, guid,
                                                                                 ownerHistory, name, description, objectType, localPlacement, representation, elementTag,
                                                                                 ifcEnumType);
                            break;

                        case IFCExportType.IfcStair:
                            string stairPredefinedType = StairsExporter.GetIFCStairType(ifcEnumType);
                            assemblyInstanceHnd = IFCInstanceExporter.CreateStair(file, guid,
                                                                                  ownerHistory, name, description, objectType, localPlacement, representation, elementTag,
                                                                                  stairPredefinedType);
                            break;

                        case IFCExportType.IfcWall:
                            assemblyInstanceHnd = IFCInstanceExporter.CreateWall(file, guid,
                                                                                 ownerHistory, name, description, objectType, localPlacement, representation, elementTag,
                                                                                 ifcEnumType);
                            break;

                        default:
                            IFCElementAssemblyType assemblyPredefinedType = GetPredefinedTypeFromObjectType(objectType);
                            assemblyInstanceHnd = IFCInstanceExporter.CreateElementAssembly(file, guid,
                                                                                            ownerHistory, name, description, objectType, localPlacement, representation, elementTag,
                                                                                            IFCAssemblyPlace.NotDefined, assemblyPredefinedType);
                            break;
                        }
                    }
                }

                if (assemblyInstanceHnd == null)
                {
                    return(false);
                }

                bool relateToLevel = (levelInfo != null);
                productWrapper.AddElement(element, assemblyInstanceHnd, levelInfo, null, relateToLevel);

                ExporterCacheManager.AssemblyInstanceCache.RegisterAssemblyInstance(element.Id, assemblyInstanceHnd);

                tr.Commit();
                return(true);
            }
        }