示例#1
0
        /// <summary>
        /// Export the individual part (IfcBuildingElementPart).
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="partElement">The part element to export.</param>
        /// <param name="geometryElement">The geometry of part.</param>
        /// <param name="productWrapper">The ProductWrapper object.</param>
        /// <param name="placementSetter"></param>
        /// <param name="originalPlacement"></param>
        /// <param name="range"></param>
        /// <param name="ifcExtrusionAxes"></param>
        /// <param name="hostElement">The host of the part.  This can be null.</param>
        /// <param name="overrideLevelId">The id of the level that the part is one, overridding other sources.</param>
        /// <param name="asBuildingElement">If true, export the Part as a building element instead of an IfcElementPart.</param>
        public static void ExportPart(ExporterIFC exporterIFC, Element partElement, ProductWrapper productWrapper,
                                      PlacementSetter placementSetter, IFCAnyHandle originalPlacement, IFCRange range, IFCExtrusionAxes ifcExtrusionAxes,
                                      Element hostElement, ElementId overrideLevelId, bool asBuildingElement)
        {
            if (!ElementFilteringUtil.IsElementVisible(partElement))
            {
                return;
            }

            Part part = partElement as Part;

            if (part == null)
            {
                return;
            }

            // We don't know how to export a part as a building element if we don't know it's host.
            if (asBuildingElement && (hostElement == null))
            {
                return;
            }

            if (!asBuildingElement)
            {
                // Check the intended IFC entity or type name is in the exclude list specified in the UI
                Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcBuildingElementPart;
                if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
                {
                    return;
                }
            }
            else
            {
                string            ifcEnumType = null;
                IFCExportInfoPair exportType  = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType);

                // Check the intended IFC entity or type name is in the exclude list specified in the UI
                Common.Enums.IFCEntityType elementClassTypeEnum;
                if (Enum.TryParse <Common.Enums.IFCEntityType>(exportType.ToString(), out elementClassTypeEnum))
                {
                    if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
                    {
                        return;
                    }
                }
            }

            PlacementSetter standalonePlacementSetter = null;
            bool            standaloneExport          = hostElement == null || asBuildingElement;

            ElementId partExportLevelId = (overrideLevelId != null) ? overrideLevelId : null;

            if (partExportLevelId == null && standaloneExport)
            {
                partExportLevelId = partElement.LevelId;
            }

            if (partExportLevelId == null)
            {
                if (hostElement == null || (part.OriginalCategoryId != hostElement.Category.Id))
                {
                    return;
                }
                partExportLevelId = hostElement.LevelId;
            }

            if (ExporterCacheManager.PartExportedCache.HasExported(partElement.Id, partExportLevelId))
            {
                return;
            }

            Options options   = GeometryUtil.GetIFCExportGeometryOptions();
            View    ownerView = partElement.Document.GetElement(partElement.OwnerViewId) as View;

            if (ownerView != null)
            {
                options.View = ownerView;
            }

            GeometryElement geometryElement = partElement.get_Geometry(options);

            if (geometryElement == null)
            {
                return;
            }

            try
            {
                IFCFile file = exporterIFC.GetFile();
                using (IFCTransaction transaction = new IFCTransaction(file))
                {
                    IFCAnyHandle partPlacement = null;
                    if (standaloneExport)
                    {
                        Transform    orientationTrf       = Transform.Identity;
                        IFCAnyHandle overrideContainerHnd = null;
                        ElementId    overrideContainerId  = ParameterUtil.OverrideContainmentParameter(exporterIFC, partElement, out overrideContainerHnd);
                        if (overrideContainerId != ElementId.InvalidElementId && (partExportLevelId == null || partExportLevelId == ElementId.InvalidElementId))
                        {
                            partExportLevelId = overrideContainerId;
                        }

                        standalonePlacementSetter = PlacementSetter.Create(exporterIFC, partElement, null, orientationTrf, partExportLevelId, overrideContainerHnd);
                        partPlacement             = standalonePlacementSetter.LocalPlacement;
                    }
                    else
                    {
                        //partPlacement = ExporterUtil.CreateLocalPlacement(file, null, null);
                        partPlacement = ExporterUtil.CreateLocalPlacement(file, originalPlacement, null);
                    }

                    bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End));

                    SolidMeshGeometryInfo solidMeshInfo;
                    if (validRange)
                    {
                        solidMeshInfo = GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range);
                        if (solidMeshInfo.GetSolids().Count == 0 && solidMeshInfo.GetMeshes().Count == 0)
                        {
                            return;
                        }
                    }
                    else
                    {
                        solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                    }

                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(partPlacement);
                        extrusionCreationData.ReuseLocalPlacement   = false;
                        extrusionCreationData.PossibleExtrusionAxes = ifcExtrusionAxes;

                        IList <Solid>          solids = new List <Solid>();;
                        IList <Mesh>           meshes = new List <Mesh>();
                        IList <GeometryObject> gObjs  = FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(partElement.Document, exporterIFC, solidMeshInfo.GetSolids(), solidMeshInfo.GetMeshes());
                        foreach (GeometryObject gObj in gObjs)
                        {
                            if (gObj is Solid)
                            {
                                solids.Add(gObj as Solid);
                            }
                            else if (gObj is Mesh)
                            {
                                meshes.Add(gObj as Mesh);
                            }
                        }

                        ElementId catId     = CategoryUtil.GetSafeCategoryId(partElement);
                        ElementId hostCatId = CategoryUtil.GetSafeCategoryId(hostElement);

                        BodyData            bodyData            = null;
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                        if (solids.Count > 0 || meshes.Count > 0)
                        {
                            bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, solids, meshes,
                                                               bodyExporterOptions, extrusionCreationData);
                        }
                        else
                        {
                            IList <GeometryObject> geomlist = new List <GeometryObject>();
                            geomlist.Add(geometryElement);
                            bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, geomlist,
                                                               bodyExporterOptions, extrusionCreationData);
                        }

                        IFCAnyHandle bodyRep = bodyData.RepresentationHnd;
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                        {
                            extrusionCreationData.ClearOpenings();
                            return;
                        }

                        IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();
                        representations.Add(bodyRep);

                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity);
                        if (boundingBoxRep != null)
                        {
                            representations.Add(boundingBoxRep);
                        }

                        IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);

                        IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

                        string            partGUID    = GUIDUtil.CreateGUID(partElement);
                        string            ifcEnumType = null;
                        IFCExportInfoPair exportType  = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType);
                        IFCAnyHandle      ifcPart     = null;
                        if (!asBuildingElement)
                        {
                            ifcPart = IFCInstanceExporter.CreateBuildingElementPart(exporterIFC, partElement, partGUID, ownerHistory,
                                                                                    extrusionCreationData.GetLocalPlacement(), prodRep);
                        }
                        else
                        {
                            switch (exportType.ExportInstance)
                            {
                            case IFCEntityType.IfcColumn:
                                ifcPart = IFCInstanceExporter.CreateColumn(exporterIFC, partElement, partGUID, ownerHistory,
                                                                           extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType);
                                break;

                            case IFCEntityType.IfcCovering:
                                ifcPart = IFCInstanceExporter.CreateCovering(exporterIFC, partElement, partGUID, ownerHistory,
                                                                             extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType);
                                break;

                            case IFCEntityType.IfcFooting:
                                ifcPart = IFCInstanceExporter.CreateFooting(exporterIFC, partElement, partGUID, ownerHistory,
                                                                            extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType);
                                break;

                            case IFCEntityType.IfcPile:
                                ifcPart = IFCInstanceExporter.CreatePile(exporterIFC, partElement, partGUID, ownerHistory,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType, null);
                                break;

                            case IFCEntityType.IfcRoof:
                                ifcPart = IFCInstanceExporter.CreateRoof(exporterIFC, partElement, partGUID, ownerHistory,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType);
                                break;

                            case IFCEntityType.IfcSlab:
                            {
                                // TODO: fix this elsewhere.
                                if (ExporterUtil.IsNotDefined(ifcEnumType))
                                {
                                    if (hostCatId == new ElementId(BuiltInCategory.OST_Floors))
                                    {
                                        ifcEnumType = "FLOOR";
                                    }
                                    else if (hostCatId == new ElementId(BuiltInCategory.OST_Roofs))
                                    {
                                        ifcEnumType = "ROOF";
                                    }
                                }

                                ifcPart = IFCInstanceExporter.CreateSlab(exporterIFC, partElement, partGUID, ownerHistory,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType);
                            }
                            break;

                            case IFCEntityType.IfcWall:
                                ifcPart = IFCInstanceExporter.CreateWall(exporterIFC, partElement, partGUID, ownerHistory,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType);
                                break;

                            default:
                                ifcPart = IFCInstanceExporter.CreateBuildingElementProxy(exporterIFC, partElement, partGUID, ownerHistory,
                                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, exportType.ValidatedPredefinedType);
                                break;
                            }
                        }

                        bool            containedInLevel     = standaloneExport;
                        PlacementSetter whichPlacementSetter = containedInLevel ? standalonePlacementSetter : placementSetter;
                        productWrapper.AddElement(partElement, ifcPart, whichPlacementSetter, extrusionCreationData, containedInLevel, exportType);

                        OpeningUtil.CreateOpeningsIfNecessary(ifcPart, partElement, extrusionCreationData, bodyData.OffsetTransform, exporterIFC,
                                                              extrusionCreationData.GetLocalPlacement(), whichPlacementSetter, productWrapper);

                        //Add the exported part to exported cache.
                        TraceExportedParts(partElement, partExportLevelId, standaloneExport ? ElementId.InvalidElementId : hostElement.Id);

                        CategoryUtil.CreateMaterialAssociation(exporterIFC, ifcPart, bodyData.MaterialIds);

                        transaction.Commit();
                    }
                }
            }
            finally
            {
                if (standalonePlacementSetter != null)
                {
                    standalonePlacementSetter.Dispose();
                }
            }
        }
示例#2
0
        /// <summary>
        /// Export the individual part (IfcBuildingElementPart).
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="partElement">The part element to export.</param>
        /// <param name="geometryElement">The geometry of part.</param>
        /// <param name="productWrapper">The ProductWrapper object.</param>
        public static void ExportPart(ExporterIFC exporterIFC, Element partElement, ProductWrapper productWrapper,
                                      PlacementSetter placementSetter, IFCAnyHandle originalPlacement, IFCRange range, IFCExtrusionAxes ifcExtrusionAxes,
                                      Element hostElement, ElementId overrideLevelId, bool asBuildingElement)
        {
            if (!ElementFilteringUtil.IsElementVisible(partElement))
            {
                return;
            }

            Part part = partElement as Part;

            if (part == null)
            {
                return;
            }

            if (!asBuildingElement)
            {
                // Check the intended IFC entity or type name is in the exclude list specified in the UI
                Common.Enums.IFCEntityType elementClassTypeEnum;
                if (Enum.TryParse <Common.Enums.IFCEntityType>("IfcBuildingElementPart", out elementClassTypeEnum))
                {
                    if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
                    {
                        return;
                    }
                }
            }
            else
            {
                string        ifcEnumType = null;
                IFCExportType exportType  = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType);

                // Check the intended IFC entity or type name is in the exclude list specified in the UI
                Common.Enums.IFCEntityType elementClassTypeEnum;
                if (Enum.TryParse <Common.Enums.IFCEntityType>(exportType.ToString(), out elementClassTypeEnum))
                {
                    if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
                    {
                        return;
                    }
                }
            }

            PlacementSetter standalonePlacementSetter = null;
            bool            standaloneExport          = hostElement == null && !asBuildingElement;

            ElementId partExportLevel = null;

            if (standaloneExport || asBuildingElement)
            {
                partExportLevel = partElement.LevelId;
            }
            else
            {
                if (part.OriginalCategoryId != hostElement.Category.Id)
                {
                    return;
                }
                partExportLevel = hostElement.LevelId;
            }
            if (overrideLevelId != null)
            {
                partExportLevel = overrideLevelId;
            }

            if (ExporterCacheManager.PartExportedCache.HasExported(partElement.Id, partExportLevel))
            {
                return;
            }

            Options options   = GeometryUtil.GetIFCExportGeometryOptions();
            View    ownerView = partElement.Document.GetElement(partElement.OwnerViewId) as View;

            if (ownerView != null)
            {
                options.View = ownerView;
            }

            GeometryElement geometryElement = partElement.get_Geometry(options);

            if (geometryElement == null)
            {
                return;
            }

            try
            {
                IFCFile file = exporterIFC.GetFile();
                using (IFCTransaction transaction = new IFCTransaction(file))
                {
                    IFCAnyHandle partPlacement = null;
                    if (standaloneExport || asBuildingElement)
                    {
                        Transform orientationTrf = Transform.Identity;
                        standalonePlacementSetter = PlacementSetter.Create(exporterIFC, partElement, null, orientationTrf, partExportLevel);
                        partPlacement             = standalonePlacementSetter.LocalPlacement;
                    }
                    else
                    {
                        partPlacement = ExporterUtil.CreateLocalPlacement(file, originalPlacement, null);
                    }

                    bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End));

                    SolidMeshGeometryInfo solidMeshInfo;
                    if (validRange)
                    {
                        solidMeshInfo = GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range);
                        if (solidMeshInfo.GetSolids().Count == 0 && solidMeshInfo.GetMeshes().Count == 0)
                        {
                            return;
                        }
                    }
                    else
                    {
                        solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                    }

                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(partPlacement);
                        extrusionCreationData.ReuseLocalPlacement   = false;
                        extrusionCreationData.PossibleExtrusionAxes = ifcExtrusionAxes;

                        IList <Solid> solids = solidMeshInfo.GetSolids();
                        IList <Mesh>  meshes = solidMeshInfo.GetMeshes();

                        ElementId catId     = CategoryUtil.GetSafeCategoryId(partElement);
                        ElementId hostCatId = CategoryUtil.GetSafeCategoryId(hostElement);

                        BodyData            bodyData            = null;
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                        if (solids.Count > 0 || meshes.Count > 0)
                        {
                            bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, solids, meshes,
                                                               bodyExporterOptions, extrusionCreationData);
                        }
                        else
                        {
                            IList <GeometryObject> geomlist = new List <GeometryObject>();
                            geomlist.Add(geometryElement);
                            bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, geomlist,
                                                               bodyExporterOptions, extrusionCreationData);
                        }

                        IFCAnyHandle bodyRep = bodyData.RepresentationHnd;
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                        {
                            extrusionCreationData.ClearOpenings();
                            return;
                        }

                        IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();
                        representations.Add(bodyRep);

                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity);
                        if (boundingBoxRep != null)
                        {
                            representations.Add(boundingBoxRep);
                        }

                        IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);

                        IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

                        string partGUID        = GUIDUtil.CreateGUID(partElement);
                        string partName        = NamingUtil.GetNameOverride(partElement, NamingUtil.GetIFCName(partElement));
                        string partDescription = NamingUtil.GetDescriptionOverride(partElement, null);
                        string partObjectType  = NamingUtil.GetObjectTypeOverride(partElement, NamingUtil.CreateIFCObjectName(exporterIFC, partElement));
                        string partTag         = NamingUtil.GetTagOverride(partElement, NamingUtil.CreateIFCElementId(partElement));

                        IFCAnyHandle ifcPart = null;
                        if (!asBuildingElement)
                        {
                            ifcPart = IFCInstanceExporter.CreateBuildingElementPart(file, partGUID, ownerHistory, partName, partDescription,
                                                                                    partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag);
                        }
                        else
                        {
                            string        ifcEnumType = null;
                            IFCExportType exportType  = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType);

                            string defaultValue = null;
                            // This replicates old functionality before IFC4 addition, where the default for slab was "FLOOR".
                            // Really the export layer table should be fixed for this case.
                            if (string.IsNullOrWhiteSpace(ifcEnumType) && hostCatId == new ElementId(BuiltInCategory.OST_Floors))
                            {
                                ifcEnumType = "FLOOR";
                            }
                            ifcEnumType = IFCValidateEntry.GetValidIFCType(hostElement, ifcEnumType, defaultValue);

                            switch (exportType)
                            {
                            case IFCExportType.IfcColumnType:
                                ifcPart = IFCInstanceExporter.CreateColumn(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                           extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                break;

                            case IFCExportType.IfcCovering:
                                ifcPart = IFCInstanceExporter.CreateCovering(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                             extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                break;

                            case IFCExportType.IfcFooting:
                                ifcPart = IFCInstanceExporter.CreateFooting(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                            extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                break;

                            case IFCExportType.IfcPile:
                                ifcPart = IFCInstanceExporter.CreatePile(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType, null);
                                break;

                            case IFCExportType.IfcRoof:
                                ifcPart = IFCInstanceExporter.CreateRoof(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                break;

                            case IFCExportType.IfcSlab:
                                ifcPart = IFCInstanceExporter.CreateSlab(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                break;

                            case IFCExportType.IfcWall:
                                ifcPart = IFCInstanceExporter.CreateWall(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                break;

                            default:
                                ifcPart = IFCInstanceExporter.CreateBuildingElementProxy(file, partGUID, ownerHistory, partName, partDescription,
                                                                                         partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, null);
                                break;
                            }
                        }

                        bool            containedInLevel     = (standaloneExport || asBuildingElement);
                        PlacementSetter whichPlacementSetter = containedInLevel ? standalonePlacementSetter : placementSetter;
                        productWrapper.AddElement(partElement, ifcPart, whichPlacementSetter, extrusionCreationData, containedInLevel);

                        OpeningUtil.CreateOpeningsIfNecessary(ifcPart, partElement, extrusionCreationData, bodyData.OffsetTransform, exporterIFC,
                                                              extrusionCreationData.GetLocalPlacement(), whichPlacementSetter, productWrapper);

                        //Add the exported part to exported cache.
                        TraceExportedParts(partElement, partExportLevel, standaloneExport || asBuildingElement ? ElementId.InvalidElementId : hostElement.Id);

                        CategoryUtil.CreateMaterialAssociation(exporterIFC, ifcPart, bodyData.MaterialIds);

                        transaction.Commit();
                    }
                }
            }
            finally
            {
                if (standalonePlacementSetter != null)
                {
                    standalonePlacementSetter.Dispose();
                }
            }
        }
示例#3
0
        /// <summary>
        /// Export the individual part (IfcBuildingElementPart).
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="partElement">The part element to export.</param>
        /// <param name="geometryElement">The geometry of part.</param>
        /// <param name="productWrapper">The ProductWrapper object.</param>
        public static void ExportPart(ExporterIFC exporterIFC, Element partElement, ProductWrapper productWrapper,
                                      IFCPlacementSetter placementSetter, IFCAnyHandle originalPlacement, IFCRange range, IFCExtrusionAxes ifcExtrusionAxes,
                                      Element hostElement, ElementId overrideLevelId, bool asBuildingElement)
        {
            if (!ElementFilteringUtil.IsElementVisible(partElement))
            {
                return;
            }

            Part part = partElement as Part;

            if (part == null)
            {
                return;
            }

            IFCPlacementSetter standalonePlacementSetter = null;
            bool standaloneExport = hostElement == null && !asBuildingElement;

            ElementId partExportLevel = null;

            if (overrideLevelId != null)
            {
                partExportLevel = overrideLevelId;
            }
            else if (standaloneExport || asBuildingElement)
            {
                if (partElement.Level != null)
                {
                    partExportLevel = partElement.Level.Id;
                }
            }
            else
            {
                if (part.OriginalCategoryId != hostElement.Category.Id)
                {
                    return;
                }
                partExportLevel = hostElement.Level.Id;
            }

            if (ExporterCacheManager.PartExportedCache.HasExported(partElement.Id, partExportLevel))
            {
                return;
            }

            Options options   = GeometryUtil.GetIFCExportGeometryOptions();
            View    ownerView = partElement.Document.GetElement(partElement.OwnerViewId) as View;

            if (ownerView != null)
            {
                options.View = ownerView;
            }

            GeometryElement geometryElement = partElement.get_Geometry(options);

            if (geometryElement == null)
            {
                return;
            }

            try
            {
                IFCFile file = exporterIFC.GetFile();
                using (IFCTransaction transaction = new IFCTransaction(file))
                {
                    IFCAnyHandle partPlacement = null;
                    if (standaloneExport || asBuildingElement)
                    {
                        Transform orientationTrf = Transform.Identity;
                        standalonePlacementSetter = IFCPlacementSetter.Create(exporterIFC, partElement, null, orientationTrf, partExportLevel);
                        partPlacement             = standalonePlacementSetter.GetPlacement();
                    }
                    else
                    {
                        partPlacement = ExporterUtil.CreateLocalPlacement(file, originalPlacement, null);
                    }

                    bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End));

                    SolidMeshGeometryInfo solidMeshInfo;
                    if (validRange)
                    {
                        solidMeshInfo = GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range);
                        if (solidMeshInfo.GetSolids().Count == 0 && solidMeshInfo.GetMeshes().Count == 0)
                        {
                            return;
                        }
                    }
                    else
                    {
                        solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                    }

                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(partPlacement);
                        extrusionCreationData.ReuseLocalPlacement   = false;
                        extrusionCreationData.PossibleExtrusionAxes = ifcExtrusionAxes;

                        IList <Solid> solids = solidMeshInfo.GetSolids();
                        IList <Mesh>  meshes = solidMeshInfo.GetMeshes();

                        ElementId catId = CategoryUtil.GetSafeCategoryId(partElement);

                        BodyData            bodyData            = null;
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        if (solids.Count > 0 || meshes.Count > 0)
                        {
                            bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, solids, meshes,
                                                               bodyExporterOptions, extrusionCreationData);
                        }
                        else
                        {
                            IList <GeometryObject> geomlist = new List <GeometryObject>();
                            geomlist.Add(geometryElement);
                            bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, geomlist,
                                                               bodyExporterOptions, extrusionCreationData);
                        }

                        IFCAnyHandle bodyRep = bodyData.RepresentationHnd;
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                        {
                            extrusionCreationData.ClearOpenings();
                            return;
                        }

                        IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();
                        representations.Add(bodyRep);

                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity);
                        if (boundingBoxRep != null)
                        {
                            representations.Add(boundingBoxRep);
                        }

                        IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);

                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

                        string partGUID        = GUIDUtil.CreateGUID(partElement);
                        string partName        = NamingUtil.GetNameOverride(partElement, NamingUtil.GetIFCName(partElement));
                        string partDescription = NamingUtil.GetDescriptionOverride(partElement, null);
                        string partObjectType  = NamingUtil.GetObjectTypeOverride(partElement, NamingUtil.CreateIFCObjectName(exporterIFC, partElement));
                        string partTag         = NamingUtil.GetTagOverride(partElement, NamingUtil.CreateIFCElementId(partElement));

                        IFCAnyHandle ifcPart = null;
                        if (!asBuildingElement)
                        {
                            ifcPart = IFCInstanceExporter.CreateBuildingElementPart(file, partGUID, ownerHistory, partName, partDescription,
                                                                                    partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag);
                        }
                        else
                        {
                            string        ifcEnumType;
                            IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType);
                            switch (exportType)
                            {
                            case IFCExportType.ExportColumnType:
                                ifcPart = IFCInstanceExporter.CreateColumn(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                           extrusionCreationData.GetLocalPlacement(), prodRep, partTag);
                                break;

                            case IFCExportType.ExportCovering:
                                IFCCoveringType coveringType = CeilingExporter.GetIFCCoveringType(hostElement, ifcEnumType);
                                ifcPart = IFCInstanceExporter.CreateCovering(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                             extrusionCreationData.GetLocalPlacement(), prodRep, partTag, coveringType);
                                break;

                            case IFCExportType.ExportFooting:
                                IFCFootingType footingType = FootingExporter.GetIFCFootingType(hostElement, ifcEnumType);
                                ifcPart = IFCInstanceExporter.CreateFooting(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                            extrusionCreationData.GetLocalPlacement(), prodRep, partTag, footingType);
                                break;

                            case IFCExportType.ExportRoof:
                                IFCRoofType roofType = RoofExporter.GetIFCRoofType(ifcEnumType);
                                ifcPart = IFCInstanceExporter.CreateRoof(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, partTag, roofType);
                                break;

                            case IFCExportType.ExportSlab:
                                IFCSlabType slabType = FloorExporter.GetIFCSlabType(ifcEnumType);
                                ifcPart = IFCInstanceExporter.CreateSlab(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, partTag, slabType);
                                break;

                            case IFCExportType.ExportWall:
                                ifcPart = IFCInstanceExporter.CreateWall(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, partTag);
                                break;

                            default:
                                ifcPart = IFCInstanceExporter.CreateBuildingElementProxy(file, partGUID, ownerHistory, partName, partDescription,
                                                                                         partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, null);
                                break;
                            }
                        }

                        bool containedInLevel = (standaloneExport || asBuildingElement);
                        IFCPlacementSetter whichPlacementSetter = containedInLevel ? standalonePlacementSetter : placementSetter;
                        productWrapper.AddElement(partElement, ifcPart, whichPlacementSetter, extrusionCreationData, containedInLevel);

                        //Add the exported part to exported cache.
                        TraceExportedParts(partElement, partExportLevel, standaloneExport || asBuildingElement ? ElementId.InvalidElementId : hostElement.Id);

                        CategoryUtil.CreateMaterialAssociations(exporterIFC, ifcPart, bodyData.MaterialIds);

                        transaction.Commit();
                    }
                }
            }
            finally
            {
                if (standalonePlacementSetter != null)
                {
                    standalonePlacementSetter.Dispose();
                }
            }
        }