/// <summary>
        /// Exports the top stories of a multistory ramp.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="ramp">The ramp element.</param>
        /// <param name="numFlights">The number of flights for a multistory ramp.</param>
        /// <param name="rampHnd">The stairs container handle.</param>
        /// <param name="components">The components handles.</param>
        /// <param name="ecData">The extrusion creation data.</param>
        /// <param name="componentECData">The extrusion creation data for the components.</param>
        /// <param name="placementSetter">The placement setter.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportMultistoryRamp(ExporterIFC exporterIFC, Element ramp, int numFlights,
            IFCAnyHandle rampHnd, IList<IFCAnyHandle> components, IList<IFCExtrusionCreationData> componentECData,
            PlacementSetter placementSetter, ProductWrapper productWrapper)
        {
            if (numFlights < 2)
                return;

            double heightNonScaled = GetRampHeight(exporterIFC, ramp);
            if (heightNonScaled < MathUtil.Eps())
                return;

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(rampHnd))
                return;

            IFCAnyHandle localPlacement = IFCAnyHandleUtil.GetObjectPlacement(rampHnd);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(localPlacement))
                return;

            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

            IFCFile file = exporterIFC.GetFile();

            IFCAnyHandle relPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement);
            IFCAnyHandle ptHnd = IFCAnyHandleUtil.GetLocation(relPlacement);
            IList<double> origCoords = IFCAnyHandleUtil.GetCoordinates(ptHnd);

            IList<IFCAnyHandle> rampLocalPlacementHnds = new List<IFCAnyHandle>();
            IList<IFCLevelInfo> levelInfos = new List<IFCLevelInfo>();
            for (int ii = 0; ii < numFlights - 1; ii++)
            {
                IFCAnyHandle newLevelHnd = null;

                // We are going to avoid internal scaling routines, and instead scale in .NET.
                double newOffsetUnscaled = 0.0;
                IFCLevelInfo currLevelInfo =
                    placementSetter.GetOffsetLevelInfoAndHandle(heightNonScaled * (ii + 1), 1.0, ramp.Document, out newLevelHnd, out newOffsetUnscaled);
                double newOffsetScaled = UnitUtil.ScaleLength(newOffsetUnscaled);

                levelInfos.Add(currLevelInfo);
                if (levelInfos[ii] == null)
                    levelInfos[ii] = placementSetter.LevelInfo;

                XYZ orig;
                if (ptHnd.HasValue)
                {
                    orig = new XYZ(origCoords[0], origCoords[1], newOffsetScaled);
                }
                else
                {
                    orig = new XYZ(0.0, 0.0, newOffsetScaled);
                }
                rampLocalPlacementHnds.Add(ExporterUtil.CreateLocalPlacement(file, newLevelHnd, orig, null, null));
            }

            IList<List<IFCAnyHandle>> newComponents = new List<List<IFCAnyHandle>>();
            for (int ii = 0; ii < numFlights - 1; ii++)
                newComponents.Add(new List<IFCAnyHandle>());

            int compIdx = 0;
            ElementId catId = CategoryUtil.GetSafeCategoryId(ramp);

            foreach (IFCAnyHandle component in components)
            {
                string componentName = IFCAnyHandleUtil.GetStringAttribute(component, "Name");
                string componentDescription = IFCAnyHandleUtil.GetStringAttribute(component, "Description");
                string componentObjectType = IFCAnyHandleUtil.GetStringAttribute(component, "ObjectType");
                string componentElementTag = IFCAnyHandleUtil.GetStringAttribute(component, "Tag");
                IFCAnyHandle componentProdRep = IFCAnyHandleUtil.GetInstanceAttribute(component, "Representation");

                IList<string> localComponentNames = new List<string>();
                IList<IFCAnyHandle> componentPlacementHnds = new List<IFCAnyHandle>();

                IFCAnyHandle localLocalPlacement = IFCAnyHandleUtil.GetObjectPlacement(component);
                IFCAnyHandle localRelativePlacement =
                    (localLocalPlacement == null) ? null : IFCAnyHandleUtil.GetInstanceAttribute(localLocalPlacement, "RelativePlacement");

                bool isSubRamp = component.IsSubTypeOf(IFCEntityType.IfcRamp.ToString());
                for (int ii = 0; ii < numFlights - 1; ii++)
                {
                    localComponentNames.Add((componentName == null) ? (ii + 2).ToString() : (componentName + ":" + (ii + 2)));
                    if (isSubRamp)
                        componentPlacementHnds.Add(ExporterUtil.CopyLocalPlacement(file, rampLocalPlacementHnds[ii]));
                    else
                        componentPlacementHnds.Add(IFCInstanceExporter.CreateLocalPlacement(file, rampLocalPlacementHnds[ii], localRelativePlacement));
                }

                IList<IFCAnyHandle> localComponentHnds = new List<IFCAnyHandle>();
                if (isSubRamp)
                {
                    string componentType = IFCAnyHandleUtil.GetEnumerationAttribute(component, ExporterCacheManager.ExportOptionsCache.ExportAs4 ? "PredefinedType" : "ShapeType");
                    string localRampType = GetIFCRampType(componentType);

                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, ramp, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateRamp(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, localRampType));
                    }
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcRampFlight))
                {
                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, ramp, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateRampFlight(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, "NOTDEFINED"));
                    }
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcSlab))
                {
                    string componentType = IFCAnyHandleUtil.GetEnumerationAttribute(component, "PredefinedType");
                    IFCSlabType localLandingType = FloorExporter.GetIFCSlabType(componentType);

                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, ramp, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateSlab(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, localLandingType.ToString()));
                    }
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcMember))
                {
                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, ramp, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateMember(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, "STRINGER"));
                    }
                }

                for (int ii = 0; ii < numFlights - 1; ii++)
                {
                    if (localComponentHnds[ii] != null)
                    {
                        newComponents[ii].Add(localComponentHnds[ii]);
                        productWrapper.AddElement(null, localComponentHnds[ii], levelInfos[ii], componentECData[compIdx], false);
                    }
                }
                compIdx++;
            }

            // finally add a copy of the container.
            IList<IFCAnyHandle> rampCopyHnds = new List<IFCAnyHandle>();
            for (int ii = 0; ii < numFlights - 1; ii++)
            {
                string rampName = IFCAnyHandleUtil.GetStringAttribute(rampHnd, "Name");
                string rampObjectType = IFCAnyHandleUtil.GetStringAttribute(rampHnd, "ObjectType");
                string rampDescription = IFCAnyHandleUtil.GetStringAttribute(rampHnd, "Description");
                string rampElementTag = IFCAnyHandleUtil.GetStringAttribute(rampHnd, "Tag");
                string rampTypeAsString = null;
                if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                    rampTypeAsString = IFCAnyHandleUtil.GetEnumerationAttribute(rampHnd, "PredefinedType");
                else
                    rampTypeAsString = IFCAnyHandleUtil.GetEnumerationAttribute(rampHnd, "ShapeType");
                string rampType = GetIFCRampType(rampTypeAsString);

                string containerRampName = rampName + ":" + (ii + 2);
                rampCopyHnds.Add(IFCInstanceExporter.CreateRamp(file, GUIDUtil.CreateGUID(), ownerHistory,
                    containerRampName, rampDescription, rampObjectType, rampLocalPlacementHnds[ii], null, rampElementTag, rampType));

                productWrapper.AddElement(ramp, rampCopyHnds[ii], levelInfos[ii], null, true);
            }

            for (int ii = 0; ii < numFlights - 1; ii++)
            {
                StairRampContainerInfo stairRampInfo = new StairRampContainerInfo(rampCopyHnds[ii], newComponents[ii],
                    rampLocalPlacementHnds[ii]);
                ExporterCacheManager.StairRampContainerInfoCache.AppendStairRampContainerInfo(ramp.Id, stairRampInfo);
            }
        }
Example #2
0
        /// <summary>
        /// Exports the top stories of a multistory staircase.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="stair">The stairs element.</param>
        /// <param name="numFlights">The number of flights for a multistory staircase.</param>
        /// <param name="stairHnd">The stairs container handle.</param>
        /// <param name="components">The components handles.</param>
        /// <param name="ecData">The extrusion creation data.</param>
        /// <param name="componentECData">The extrusion creation data for the components.</param>
        /// <param name="placementSetter">The placement setter.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportMultistoryStair(ExporterIFC exporterIFC, Element stair, int numFlights,
            IFCAnyHandle stairHnd, IList<IFCAnyHandle> components, IList<IFCExtrusionCreationData> componentECData,
            PlacementSetter placementSetter, ProductWrapper productWrapper)
        {
            if (numFlights < 2)
                return;

            double heightNonScaled = GetStairsHeight(exporterIFC, stair);
            if (heightNonScaled < MathUtil.Eps())
                return;

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(stairHnd))
                return;

            IFCAnyHandle localPlacement = IFCAnyHandleUtil.GetObjectPlacement(stairHnd);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(localPlacement))
                return;

            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

            IFCFile file = exporterIFC.GetFile();

            IFCAnyHandle relPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement);
            IFCAnyHandle ptHnd = IFCAnyHandleUtil.GetLocation(relPlacement);
            IList<double> origCoords = IFCAnyHandleUtil.GetCoordinates(ptHnd);

            ICollection<ElementId> runIds = null;
            ICollection<ElementId> landingIds = null;
            ICollection<ElementId> supportIds = null;

            if (stair is Stairs)
            {
                Stairs stairAsStairs = stair as Stairs;
                runIds = stairAsStairs.GetStairsRuns();
                landingIds = stairAsStairs.GetStairsLandings();
                supportIds = stairAsStairs.GetStairsSupports();
            }

            IList<IFCAnyHandle> stairLocalPlacementHnds = new List<IFCAnyHandle>();
            IList<IFCLevelInfo> levelInfos = new List<IFCLevelInfo>();
            for (int ii = 0; ii < numFlights - 1; ii++)
            {
                IFCAnyHandle newLevelHnd = null;

                // We are going to avoid internal scaling routines, and instead scale in .NET.
                double newOffsetUnscaled = 0.0;
                IFCLevelInfo currLevelInfo =
                    placementSetter.GetOffsetLevelInfoAndHandle(heightNonScaled * (ii + 1), 1.0, stair.Document, out newLevelHnd, out newOffsetUnscaled);
                double newOffsetScaled = UnitUtil.ScaleLength(newOffsetUnscaled); 
                
                levelInfos.Add(currLevelInfo);
                if (levelInfos[ii] == null)
                    levelInfos[ii] = placementSetter.LevelInfo;

                XYZ orig;
                if (ptHnd.HasValue)
                {
                    orig = new XYZ(origCoords[0], origCoords[1], newOffsetScaled);
                }
                else
                {
                    orig = new XYZ(0.0, 0.0, newOffsetScaled);
                }
                stairLocalPlacementHnds.Add(ExporterUtil.CreateLocalPlacement(file, newLevelHnd, orig, null, null));
            }

            IList<List<IFCAnyHandle>> newComponents = new List<List<IFCAnyHandle>>();
            for (int ii = 0; ii < numFlights - 1; ii++)
                newComponents.Add(new List<IFCAnyHandle>());

            int compIdx = 0;
            IEnumerator<ElementId> runIter = null;
            if (runIds != null)
            {
                runIter = runIds.GetEnumerator();
                runIter.MoveNext();
            }
            IEnumerator<ElementId> landingIter = null;
            if (landingIds != null)
            {
                landingIter = landingIds.GetEnumerator();
                landingIter.MoveNext();
            }
            IEnumerator<ElementId> supportIter = null;
            if (supportIds != null)
            {
                supportIter = supportIds.GetEnumerator();
                supportIter.MoveNext();
            }

            foreach (IFCAnyHandle component in components)
            {
                string componentName = IFCAnyHandleUtil.GetStringAttribute(component, "Name");
                string componentDescription = IFCAnyHandleUtil.GetStringAttribute(component, "Description");
                string componentObjectType = IFCAnyHandleUtil.GetStringAttribute(component, "ObjectType");
                string componentElementTag = IFCAnyHandleUtil.GetStringAttribute(component, "Tag");
                IFCAnyHandle componentProdRep = IFCAnyHandleUtil.GetInstanceAttribute(component, "Representation");

                IList<string> localComponentNames = new List<string>();
                IList<IFCAnyHandle> componentPlacementHnds = new List<IFCAnyHandle>();

                IFCAnyHandle localLocalPlacement = IFCAnyHandleUtil.GetObjectPlacement(component);
                IFCAnyHandle localRelativePlacement =
                    (localLocalPlacement == null) ? null : IFCAnyHandleUtil.GetInstanceAttribute(localLocalPlacement, "RelativePlacement");

                bool isSubStair = component.IsSubTypeOf(IFCEntityType.IfcStair.ToString());
                for (int ii = 0; ii < numFlights - 1; ii++)
                {
                    localComponentNames.Add((componentName == null) ? (ii + 2).ToString() : (componentName + ":" + (ii + 2)));
                    if (isSubStair)
                        componentPlacementHnds.Add(ExporterUtil.CopyLocalPlacement(file, stairLocalPlacementHnds[ii]));
                    else
                        componentPlacementHnds.Add(IFCInstanceExporter.CreateLocalPlacement(file, stairLocalPlacementHnds[ii], localRelativePlacement));
                }

                IList<IFCAnyHandle> localComponentHnds = new List<IFCAnyHandle>();
                if (isSubStair)
                {
                    string componentType = IFCAnyHandleUtil.GetEnumerationAttribute(component, "ShapeType");
                    string localStairType = GetIFCStairType(componentType);

                    ElementId catId = CategoryUtil.GetSafeCategoryId(stair);

                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, stair, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateStair(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, localStairType));
                    }
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcStairFlight))
                {
                    Element runElem = (runIter == null) ? stair : stair.Document.GetElement(runIter.Current);
                    Element runElemToUse = (runElem == null) ? stair : runElem;
                    ElementId catId = CategoryUtil.GetSafeCategoryId(runElemToUse);

                    int? numberOfRiser = IFCAnyHandleUtil.GetIntAttribute(component, "NumberOfRiser");
                    int? numberOfTreads = IFCAnyHandleUtil.GetIntAttribute(component, "NumberOfTreads");
                    double? riserHeight = IFCAnyHandleUtil.GetDoubleAttribute(component, "RiserHeight");
                    double? treadLength = IFCAnyHandleUtil.GetDoubleAttribute(component, "TreadLength");

                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, runElemToUse, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateStairFlight(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, numberOfRiser, numberOfTreads, riserHeight, treadLength, "NOTDEFINED"));
                    }
                    runIter.MoveNext();
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcSlab))
                {
                    Element landingElem = (landingIter == null) ? stair : stair.Document.GetElement(landingIter.Current);
                    Element landingElemToUse = (landingElem == null) ? stair : landingElem;
                    ElementId catId = CategoryUtil.GetSafeCategoryId(landingElemToUse);

                    string componentType = IFCValidateEntry.GetValidIFCType(landingElemToUse, IFCAnyHandleUtil.GetEnumerationAttribute(component, "PredefinedType"));
                    // IFCSlabType localLandingType = FloorExporter.GetIFCSlabType(componentType);

                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, landingElemToUse, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateSlab(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, componentType));
                    }

                    landingIter.MoveNext();
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcMember))
                {
                    Element supportElem = (supportIter == null) ? stair : stair.Document.GetElement(supportIter.Current);
                    Element supportElemToUse = (supportElem == null) ? stair : supportElem;
                    ElementId catId = CategoryUtil.GetSafeCategoryId(supportElemToUse);

                    IFCAnyHandle memberType = (supportElemToUse != stair) ? GetMemberTypeHandle(exporterIFC, supportElemToUse) : null;

                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                        ExporterUtil.CopyProductDefinitionShape(exporterIFC, supportElemToUse, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateMember(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, "STRINGER"));

                        if (memberType != null)
                            ExporterCacheManager.TypeRelationsCache.Add(memberType, localComponentHnds[ii]);
                    }

                    supportIter.MoveNext();
                }

                for (int ii = 0; ii < numFlights - 1; ii++)
                {
                    if (localComponentHnds[ii] != null)
                    {
                        newComponents[ii].Add(localComponentHnds[ii]);
                        productWrapper.AddElement(null, localComponentHnds[ii], levelInfos[ii], componentECData[compIdx], false);
                    }
                }
                compIdx++;
            }

            // finally add a copy of the container.
            IList<IFCAnyHandle> stairCopyHnds = new List<IFCAnyHandle>();
            for (int ii = 0; ii < numFlights - 1; ii++)
            {
                string stairName = IFCAnyHandleUtil.GetStringAttribute(stairHnd, "Name");
                string stairObjectType = IFCAnyHandleUtil.GetStringAttribute(stairHnd, "ObjectType");
                string stairDescription = IFCAnyHandleUtil.GetStringAttribute(stairHnd, "Description");
                string stairElementTag = IFCAnyHandleUtil.GetStringAttribute(stairHnd, "Tag");
                string stairTypeAsString = IFCAnyHandleUtil.GetEnumerationAttribute(stairHnd, "ShapeType");
                string stairType = GetIFCStairType(stairTypeAsString);

                string containerStairName = stairName + ":" + (ii + 2);
                stairCopyHnds.Add(IFCInstanceExporter.CreateStair(file, GUIDUtil.CreateGUID(), ownerHistory,
                    containerStairName, stairDescription, stairObjectType, stairLocalPlacementHnds[ii], null, stairElementTag, stairType));

                productWrapper.AddElement(stair, stairCopyHnds[ii], levelInfos[ii], null, true);
            }

            for (int ii = 0; ii < numFlights - 1; ii++)
            {
                StairRampContainerInfo stairRampInfo = new StairRampContainerInfo(stairCopyHnds[ii], newComponents[ii],
                    stairLocalPlacementHnds[ii]);
                ExporterCacheManager.StairRampContainerInfoCache.AppendStairRampContainerInfo(stair.Id, stairRampInfo);
            }
        }