示例#1
0
        private static void ExportAsMappedItem(ExporterIFC exporterIFC, Element element, IFCFile file, IFCExportType exportType, string ifcEnumType, IFCExtrusionCreationData extraParams,
                                               PlacementSetter setter, IFCAnyHandle localPlacementToUse, IFCAnyHandle productRepresentation, ProductWrapper productWrapper)
        {
            IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;
            ElementId    typeId       = element.GetTypeId();
            ElementType  type         = element.Document.GetElement(typeId) as ElementType;
            IFCAnyHandle styleHandle  = null;

            if (type != null)
            {
                FamilyTypeInfo currentTypeInfo = ExporterCacheManager.TypeObjectsCache.Find(typeId, false, exportType);

                bool found = currentTypeInfo.IsValid();
                if (!found)
                {
                    string typeObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, type);

                    HashSet <IFCAnyHandle> propertySetsOpt = new HashSet <IFCAnyHandle>();
                    IList <IFCAnyHandle>   repMapListOpt   = new List <IFCAnyHandle>();

                    styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, propertySetsOpt, repMapListOpt, element, type);
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle))
                    {
                        propertySetsOpt = ExporterUtil.ExtractElementTypeProperties(exporterIFC, type, styleHandle);
                        productWrapper.RegisterHandleWithElementType(type, styleHandle, propertySetsOpt);
                        string applicableOccurrence = NamingUtil.GetObjectTypeOverride(type, typeObjectType);
                        if (!string.IsNullOrEmpty(applicableOccurrence))
                        {
                            IFCAnyHandleUtil.SetAttribute(styleHandle, "ApplicableOccurrence", applicableOccurrence);
                        }
                        currentTypeInfo.Style = styleHandle;
                        ExporterCacheManager.TypeObjectsCache.Register(typeId, false, exportType, currentTypeInfo);
                    }
                }
                else
                {
                    styleHandle = currentTypeInfo.Style;
                }
            }

            string instanceGUID = GUIDUtil.CreateGUID(element);


            bool roomRelated = !FamilyExporterUtil.IsDistributionFlowElementSubType(exportType);

            ElementId roomId = ElementId.InvalidElementId;

            if (roomRelated)
            {
                roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse);
            }

            IFCAnyHandle instanceHandle = null;

            // For MEP objects
            string exportEntityStr = exportType.ToString();

            Common.Enums.IFCEntityType exportEntity;

            if (String.Compare(exportEntityStr.Substring(exportEntityStr.Length - 4), "Type", true) == 0)
            {
                exportEntityStr = exportEntityStr.Substring(0, (exportEntityStr.Length - 4));
            }
            if (Enum.TryParse(exportEntityStr, out exportEntity))
            {
                // For MEP object creation
                instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportEntity, exporterIFC, element, instanceGUID, ownerHistory,
                                                                            localPlacementToUse, productRepresentation);
            }

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle))
            {
                return;
            }

            if (roomId != ElementId.InvalidElementId)
            {
                //exporterIFC.RelateSpatialElement(roomId, instanceHandle);
                ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle);
                productWrapper.AddElement(element, instanceHandle, setter, extraParams, false);
            }
            else
            {
                productWrapper.AddElement(element, instanceHandle, setter, extraParams, true);
            }

            OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, element, extraParams, null, exporterIFC, localPlacementToUse, setter, productWrapper);

            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle))
            {
                ExporterCacheManager.TypeRelationsCache.Add(styleHandle, instanceHandle);
            }

            PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper.GetAllObjects());

            ExporterCacheManager.MEPCache.Register(element, instanceHandle);

            // add to system export cache
            // SystemExporter.ExportSystem(exporterIFC, element, instanceHandle);
        }
        /// <summary>
        /// Exports a family instance as a mapped item.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="familyInstance">The family instance to be exported.</param>
        /// <param name="exportType">The export type.</param>
        /// <param name="ifcEnumType">The string value represents the IFC type.</param>
        /// <param name="wrapper">The ProductWrapper.</param>
        /// <param name="overrideLevelId">The level id.</param>
        /// <param name="range">The range of this family instance to be exported.</param>
        public static void ExportFamilyInstanceAsMappedItem(ExporterIFC exporterIFC,
           FamilyInstance familyInstance, IFCExportType exportType, string ifcEnumType,
           ProductWrapper wrapper, ElementId overrideLevelId, IFCRange range, IFCAnyHandle parentLocalPlacement)
        {
            bool exportParts = PartExporter.CanExportParts(familyInstance);
            bool isSplit = range != null;
            if (exportParts && !PartExporter.CanExportElementInPartExport(familyInstance, isSplit ? overrideLevelId : familyInstance.LevelId, isSplit))
                return;

            Document doc = familyInstance.Document;
            IFCFile file = exporterIFC.GetFile();

            // The "originalFamilySymbol" has the right geometry, but should be used as little as possible.
            FamilySymbol originalFamilySymbol = ExporterIFCUtils.GetOriginalSymbol(familyInstance);
            FamilySymbol familySymbol = familyInstance.Symbol;
            if (originalFamilySymbol == null || familySymbol == null)
                return;

            ProductWrapper familyProductWrapper = ProductWrapper.Create(wrapper);
            Options options = GeometryUtil.GetIFCExportGeometryOptions();

            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

            HostObject hostElement = familyInstance.Host as HostObject; //hostElement could be null
            ElementId categoryId = CategoryUtil.GetSafeCategoryId(familySymbol);

            //string emptyString = "";
            string familyName = familySymbol.Name;
            string revitObjectType = familyName;

            // A Family Instance can have its own copy of geometry, or use the symbol's copy with a transform.
            // The routine below tells us whether to use the Instance's copy or the Symbol's copy.
            bool useInstanceGeometry = ExporterIFCUtils.UsesInstanceGeometry(familyInstance);
            Transform trf = familyInstance.GetTransform();

            using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
            {
                // Extra information if we are exporting a door or a window.
                DoorWindowInfo doorWindowInfo = null;
                if (exportType == IFCExportType.IfcDoorType)
                    doorWindowInfo = DoorWindowExporter.CreateDoor(exporterIFC, familyInstance, hostElement, overrideLevelId, trf);
                else if (exportType == IFCExportType.IfcWindowType)
                    doorWindowInfo = DoorWindowExporter.CreateWindow(exporterIFC, familyInstance, hostElement, overrideLevelId, trf);

                FamilyTypeInfo typeInfo = new FamilyTypeInfo();

                bool flipped = doorWindowInfo != null ? doorWindowInfo.FlippedSymbol : false;
                FamilyTypeInfo currentTypeInfo = ExporterCacheManager.TypeObjectsCache.Find(originalFamilySymbol.Id, flipped);
                bool found = currentTypeInfo.IsValid();

                Family family = familySymbol.Family;

                IList<GeometryObject> geomObjects = new List<GeometryObject>();
                Transform offsetTransform = null;

                Transform doorWindowTrf = Transform.Identity;
                // We will create a new mapped type if:
                // 1.  We are exporting part of a column or in-place wall (range != null), OR
                // 2.  We are using the instance's copy of the geometry (that it, it has unique geometry), OR
                // 3.  We haven't already created the type.
                bool creatingType = ((range != null) || useInstanceGeometry || !found);
                if (creatingType)
                {
                    IFCAnyHandle bodyRepresentation = null;
                    IFCAnyHandle planRepresentation = null;

                    IFCAnyHandle dummyPlacement = null;
                    if (doorWindowInfo != null)
                    {
                        doorWindowTrf = ExporterIFCUtils.GetTransformForDoorOrWindow(familyInstance, originalFamilySymbol,
                            doorWindowInfo.FlippedX, doorWindowInfo.FlippedY);
                    }
                    else
                    {
                        dummyPlacement = ExporterUtil.CreateLocalPlacement(file, null, null);
                        extraParams.SetLocalPlacement(dummyPlacement);
                    }

                    bool needToCreate2d = ExporterCacheManager.ExportOptionsCache.ExportAnnotations;
                    GeometryElement exportGeometry =
                       useInstanceGeometry ? familyInstance.get_Geometry(options) : originalFamilySymbol.get_Geometry(options);

                    if (!exportParts)
                    {
                        using (TransformSetter trfSetter = TransformSetter.Create())
                        {
                            if (doorWindowInfo != null)
                            {
                                trfSetter.Initialize(exporterIFC, doorWindowTrf);
                            }

                            if (exportGeometry == null)
                                return;

                            SolidMeshGeometryInfo solidMeshCapsule = null;

                            if (range == null)
                            {
                                solidMeshCapsule = GeometryUtil.GetSplitSolidMeshGeometry(exportGeometry);
                            }
                            else
                            {
                                solidMeshCapsule = GeometryUtil.GetSplitClippedSolidMeshGeometry(exportGeometry, range);
                            }

                            IList<Solid> solids = solidMeshCapsule.GetSolids();
                            IList<Mesh> polyMeshes = solidMeshCapsule.GetMeshes();

                            // If we are exporting parts, it is OK to have no geometry here - it will be added by the host Part.
                            bool hasSolidsOrMeshesInSymbol = (solids.Count > 0 || polyMeshes.Count > 0);

                            if (range != null && !hasSolidsOrMeshesInSymbol)
                                return; // no proper split geometry to export.

                            if (hasSolidsOrMeshesInSymbol)
                            {
                                geomObjects = FamilyExporterUtil.RemoveSolidsAndMeshesSetToDontExport(doc, exporterIFC, solids, polyMeshes);
                                if ((geomObjects.Count == 0))
                                    return; // no proper visible split geometry to export.
                            }
                            else
                                geomObjects.Add(exportGeometry);

                            bool tryToExportAsExtrusion = (!ExporterCacheManager.ExportOptionsCache.ExportAs2x2 || (exportType == IFCExportType.IfcColumnType));

                            if (exportType == IFCExportType.IfcColumnType)
                            {
                                extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;

                                if (ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2 && solids.Count > 0)
                                {
                                    LocationPoint point = familyInstance.Location as LocationPoint;
                                    XYZ orig = XYZ.Zero;
                                    if (point != null)
                                        orig = point.Point;

                                    Plane plane = new Plane(XYZ.BasisX, XYZ.BasisY, orig);
                                    bool completelyClipped = false;
                                    HashSet<ElementId> materialIds = null;
                                    bodyRepresentation = ExtrusionExporter.CreateExtrusionWithClipping(exporterIFC, familyInstance,
                                        categoryId, solids, plane, XYZ.BasisZ, null, out completelyClipped, out materialIds);
                                    typeInfo.MaterialIds = materialIds;
                                }
                            }
                            else
                            {
                                extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryXYZ;
                            }

                            BodyData bodyData = null;
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepresentation))
                            {
                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(tryToExportAsExtrusion);
                                bodyData = BodyExporter.ExportBody(exporterIFC, familyInstance, categoryId, ElementId.InvalidElementId,
                                    geomObjects, bodyExporterOptions, extraParams);
                                typeInfo.MaterialIds = bodyData.MaterialIds;
                                bodyRepresentation = bodyData.RepresentationHnd;
                                offsetTransform = bodyData.OffsetTransform;
                            }

                            // We will allow a door or window to be exported without any geometry, or an element with parts.
                            // Anything else doesn't really make sense.
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepresentation) && (doorWindowInfo == null))
                            {
                                extraParams.ClearOpenings();
                                return;
                            }
                        }

                        // By default: if exporting IFC2x3 or later, export 2D plan rep of family, if it exists, unless we are exporting Coordination View V2.
                        // This default can be overridden in the export options.
                        if (needToCreate2d)
                        {
                            XYZ curveOffset = new XYZ(0, 0, 0);
                            if (offsetTransform != null)
                                curveOffset = -UnitUtil.UnscaleLength(offsetTransform.Origin);

                            HashSet<IFCAnyHandle> curveSet = new HashSet<IFCAnyHandle>();
                            {
                                Transform planeTrf = doorWindowTrf.Inverse;
                                Plane plane = new Plane(planeTrf.get_Basis(0), planeTrf.get_Basis(1), planeTrf.Origin);
                                XYZ projDir = new XYZ(0, 0, 1);

                                IFCGeometryInfo IFCGeometryInfo = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, plane, projDir, true);
                                ExporterIFCUtils.CollectGeometryInfo(exporterIFC, IFCGeometryInfo, exportGeometry, curveOffset, false);

                                IList<IFCAnyHandle> curves = IFCGeometryInfo.GetCurves();
                                foreach (IFCAnyHandle curve in curves)
                                    curveSet.Add(curve);

                                if (curveSet.Count > 0)
                                {
                                    IFCAnyHandle contextOfItems2d = exporterIFC.Get2DContextHandle();
                                    IFCAnyHandle curveRepresentationItem = IFCInstanceExporter.CreateGeometricSet(file, curveSet);
                                    HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();
                                    bodyItems.Add(curveRepresentationItem);
                                    planRepresentation = RepresentationUtil.CreateGeometricSetRep(exporterIFC, familyInstance, categoryId, "FootPrint",
                                       contextOfItems2d, bodyItems);
                                }
                            }
                        }
                    }

                    if (doorWindowInfo != null)
                        typeInfo.StyleTransform = doorWindowTrf.Inverse;
                    else
                        typeInfo.StyleTransform = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, extraParams.GetLocalPlacement());

                    // for many
                    HashSet<IFCAnyHandle> propertySets = null;
                    IFCAnyHandle typeStyle = CreateFamilyTypeHandle(exporterIFC, typeInfo, doorWindowInfo, bodyRepresentation, planRepresentation,
                        familyInstance, familySymbol, originalFamilySymbol, useInstanceGeometry, exportParts,
                        exportType, revitObjectType, ifcEnumType, out propertySets);

                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(typeStyle))
                    {
                        wrapper.RegisterHandleWithElementType(familySymbol, typeStyle, propertySets);

                        CategoryUtil.CreateMaterialAssociations(exporterIFC, typeStyle, typeInfo.MaterialIds);

                        typeInfo.Style = typeStyle;

                        if ((exportType == IFCExportType.IfcColumnType) || (exportType == IFCExportType.IfcMemberType))
                        {
                            typeInfo.ScaledArea = extraParams.ScaledArea;
                            typeInfo.ScaledDepth = extraParams.ScaledLength;
                            typeInfo.ScaledInnerPerimeter = extraParams.ScaledInnerPerimeter;
                            typeInfo.ScaledOuterPerimeter = extraParams.ScaledOuterPerimeter;
                        }

                        ClassificationUtil.CreateClassification(exporterIFC, file, familySymbol, typeStyle);        // Create other generic classification from ClassificationCode(s)
                        ClassificationUtil.CreateUniformatClassification(exporterIFC, file, originalFamilySymbol, typeStyle);
                    }
                }

                if (found && !typeInfo.IsValid())
                    typeInfo = currentTypeInfo;

                // we'll pretend we succeeded, but we'll do nothing.
                if (!typeInfo.IsValid())
                    return;

                // add to the map, as long as we are not using range, not using instance geometry, and don't have extra openings.
                if ((range == null) && !useInstanceGeometry && (extraParams.GetOpenings().Count == 0))
                    ExporterCacheManager.TypeObjectsCache.Register(originalFamilySymbol.Id, flipped, typeInfo);

                // If we are using the instance geometry, ignore the transformation.
                if (useInstanceGeometry)
                    trf = Transform.Identity;

                if ((range != null) && exportParts)
                {
                    XYZ rangeOffset = trf.Origin;
                    rangeOffset += new XYZ(0, 0, range.Start);
                    trf.Origin = rangeOffset;
                }

                Transform originalTrf = new Transform(trf);
                XYZ scaledMapOrigin = XYZ.Zero;

                trf = trf.Multiply(typeInfo.StyleTransform);

                // create instance.  
                IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>();
                {
                    IFCAnyHandle contextOfItems2d = exporterIFC.Get2DContextHandle();
                    IFCAnyHandle contextOfItems3d = exporterIFC.Get3DContextHandle("Body");

                    // for proxies, we store the IfcRepresentationMap directly since there is no style.
                    IFCAnyHandle style = typeInfo.Style;
                    IList<IFCAnyHandle> repMapList = !IFCAnyHandleUtil.IsNullOrHasNoValue(style) ?
                        GeometryUtil.GetRepresentationMaps(style) : null;
                    int numReps = repMapList != null ? repMapList.Count : 0;

                    IFCAnyHandle repMap2dHnd = typeInfo.Map2DHandle;
                    IFCAnyHandle repMap3dHnd = typeInfo.Map3DHandle;
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(repMap3dHnd) && (numReps > 0))
                        repMap3dHnd = repMapList[0];
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(repMap2dHnd) && (numReps > 1))
                        repMap2dHnd = repMapList[1];

                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repMap3dHnd))
                    {
                        ISet<IFCAnyHandle> representations = new HashSet<IFCAnyHandle>();
                        representations.Add(ExporterUtil.CreateDefaultMappedItem(file, repMap3dHnd, scaledMapOrigin));
                        IFCAnyHandle shapeRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, familyInstance, categoryId, contextOfItems3d,
                            representations);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
                            return;
                        shapeReps.Add(shapeRep);
                    }

                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repMap2dHnd))
                    {
                        HashSet<IFCAnyHandle> representations = new HashSet<IFCAnyHandle>();
                        representations.Add(ExporterUtil.CreateDefaultMappedItem(file, repMap2dHnd, scaledMapOrigin));
                        IFCAnyHandle shapeRep = RepresentationUtil.CreatePlanMappedItemRep(exporterIFC, familyInstance, categoryId, contextOfItems2d,
                            representations);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
                            return;
                        shapeReps.Add(shapeRep);
                    }
                }

                IFCAnyHandle boundingBoxRep = null;
                Transform boundingBoxTrf = (offsetTransform != null) ? offsetTransform.Inverse : Transform.Identity;
                if (geomObjects.Count > 0)
                    boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geomObjects, boundingBoxTrf);
                else
                {
                    boundingBoxTrf = boundingBoxTrf.Multiply(trf.Inverse);
                    boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, familyInstance.get_Geometry(options), boundingBoxTrf);
                }

                if (boundingBoxRep != null)
                    shapeReps.Add(boundingBoxRep);

                IFCAnyHandle repHnd = (shapeReps.Count > 0) ? IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps) : null;

                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, familyInstance, trf, null, overrideLevelId))
                {
                    IFCAnyHandle instanceHandle = null;
                    IFCAnyHandle localPlacement = setter.LocalPlacement;

                    // We won't create the instance if: 
                    // (1) we are exporting to CV2.0, (2) we have no 2D, 3D, or bounding box geometry, and (3) we aren't exporting parts.
                    if (!(repHnd == null && ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2 && !exportParts))
                    {
                        string instanceGUID = null;

                        int subElementIndex = ExporterStateManager.GetCurrentRangeIndex();
                        if (subElementIndex == 0)
                            instanceGUID = GUIDUtil.CreateGUID(familyInstance);
                        else if (subElementIndex <= ExporterStateManager.RangeIndexSetter.GetMaxStableGUIDs())
                            instanceGUID = GUIDUtil.CreateSubElementGUID(familyInstance, subElementIndex + (int)IFCGenericSubElements.SplitInstanceStart - 1);
                        else
                            instanceGUID = GUIDUtil.CreateGUID();

                        string instanceName = NamingUtil.GetNameOverride(familyInstance, NamingUtil.GetIFCName(familyInstance));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(familyInstance, null);
                        string instanceObjectType = NamingUtil.GetObjectTypeOverride(familyInstance, revitObjectType);
                        string instanceTag = NamingUtil.GetTagOverride(familyInstance, NamingUtil.CreateIFCElementId(familyInstance));

                        IFCAnyHandle overrideLocalPlacement = null;
                        bool isChildInContainer = familyInstance.AssemblyInstanceId != ElementId.InvalidElementId;

                        if (parentLocalPlacement != null)
                        {
                            Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(parentLocalPlacement, localPlacement);
                            Transform inverseTrf = relTrf.Inverse;

                            IFCAnyHandle plateLocalPlacement = ExporterUtil.CreateLocalPlacement(file, parentLocalPlacement,
                                inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX);
                            overrideLocalPlacement = plateLocalPlacement;
                        }

                        instanceHandle = FamilyExporterUtil.ExportGenericInstance(exportType, exporterIFC, familyInstance,
                           wrapper, setter, extraParams, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType,
                           exportParts ? null : repHnd, instanceTag, overrideLocalPlacement);

                        if (exportParts)
                            PartExporter.ExportHostPart(exporterIFC, familyInstance, instanceHandle, familyProductWrapper, setter, setter.LocalPlacement, overrideLevelId);

                        if (ElementFilteringUtil.IsMEPType(exportType) || ElementFilteringUtil.ProxyForMEPType(familyInstance, exportType))
                        {
                            ExporterCacheManager.MEPCache.Register(familyInstance, instanceHandle);
                            // For ducts and pipes, check later if there is an associated duct or pipe.
                            if (exportType == IFCExportType.IfcDuctFittingType || exportType == IFCExportType.IfcPipeFittingType ||
                                exportType == IFCExportType.IfcDuctSegmentType || exportType == IFCExportType.IfcPipeSegmentType)
                                ExporterCacheManager.MEPCache.CoveredElementsCache.Add(familyInstance.Id);
                        }

                        switch (exportType)
                        {
                            case IFCExportType.IfcColumnType:
                                {
                                    IFCAnyHandle placementToUse = localPlacement;
                                    if (!useInstanceGeometry)
                                    {
                                        bool needToCreateOpenings = OpeningUtil.NeedToCreateOpenings(instanceHandle, extraParams);
                                        if (needToCreateOpenings)
                                        {
                                            Transform openingTrf = new Transform(originalTrf);
                                            Transform extraRot = new Transform(originalTrf);
                                            extraRot.Origin = XYZ.Zero;
                                            openingTrf = openingTrf.Multiply(extraRot);
                                            openingTrf = openingTrf.Multiply(typeInfo.StyleTransform);

                                            XYZ scaledOrigin = UnitUtil.ScaleLength(openingTrf.Origin);
                                            IFCAnyHandle openingRelativePlacement = ExporterUtil.CreateAxis2Placement3D(file, scaledOrigin,
                                               openingTrf.get_Basis(2), openingTrf.get_Basis(0));
                                            IFCAnyHandle openingPlacement = ExporterUtil.CopyLocalPlacement(file, localPlacement);
                                            GeometryUtil.SetRelativePlacement(openingPlacement, openingRelativePlacement);
                                            placementToUse = openingPlacement;
                                        }
                                    }

                                    OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, offsetTransform,
                                        exporterIFC, placementToUse, setter, wrapper);

                                    //export Base Quantities.
                                    PropertyUtil.CreateBeamColumnBaseQuantities(exporterIFC, instanceHandle, familyInstance, typeInfo, geomObjects);
                                    break;
                                }
                            case IFCExportType.IfcDoorType:
                            case IFCExportType.IfcWindowType:
                                {
                                    double doorHeight = GetMinSymbolHeight(originalFamilySymbol);
                                    double doorWidth = GetMinSymbolWidth(originalFamilySymbol);

                                    double height = UnitUtil.ScaleLength(doorHeight);
                                    double width = UnitUtil.ScaleLength(doorWidth);

                                    IFCAnyHandle doorWindowLocalPlacement = !IFCAnyHandleUtil.IsNullOrHasNoValue(overrideLocalPlacement) ?
                                        overrideLocalPlacement : localPlacement;
                                    if (exportType == IFCExportType.IfcDoorType)
                                        instanceHandle = IFCInstanceExporter.CreateDoor(file, instanceGUID, ownerHistory,
                                           instanceName, instanceDescription, instanceObjectType, doorWindowLocalPlacement,
                                           repHnd, instanceTag, height, width, doorWindowInfo.PreDefinedType,doorWindowInfo.DoorOperationTypeString,
                                           doorWindowInfo.UserDefinedOperationType);
                                    else if (exportType == IFCExportType.IfcWindowType)
                                        instanceHandle = IFCInstanceExporter.CreateWindow(file, instanceGUID, ownerHistory,
                                           instanceName, instanceDescription, instanceObjectType, doorWindowLocalPlacement,
                                           repHnd, instanceTag, height, width, doorWindowInfo.PreDefinedType, DoorWindowUtil.GetIFCWindowPartitioningType(originalFamilySymbol),
                                           doorWindowInfo.UserDefinedPartitioningType);
                                    wrapper.AddElement(familyInstance, instanceHandle, setter, extraParams, true);

                                    SpaceBoundingElementUtil.RegisterSpaceBoundingElementHandle(exporterIFC, instanceHandle, familyInstance.Id,
                                        setter.LevelId);

                                    IFCAnyHandle placementToUse = doorWindowLocalPlacement;
                                    if (!useInstanceGeometry)
                                    {
                                        // correct the placement to the symbol space
                                        bool needToCreateOpenings = OpeningUtil.NeedToCreateOpenings(instanceHandle, extraParams);
                                        if (needToCreateOpenings)
                                        {
                                            Transform openingTrf = Transform.Identity;
                                            openingTrf.Origin = new XYZ(0, 0, setter.Offset);
                                            openingTrf = openingTrf.Multiply(doorWindowTrf);
                                            XYZ scaledOrigin = UnitUtil.ScaleLength(openingTrf.Origin);
                                            IFCAnyHandle openingLocalPlacement = ExporterUtil.CreateLocalPlacement(file, doorWindowLocalPlacement,
                                                scaledOrigin, openingTrf.BasisZ, openingTrf.BasisX);
                                            placementToUse = openingLocalPlacement;
                                        }
                                    }

                                    OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, offsetTransform,
                                        exporterIFC, placementToUse, setter, wrapper);
                                    break;
                                }
                            case IFCExportType.IfcMemberType:
                                {
                                    OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, offsetTransform,
                                        exporterIFC, localPlacement, setter, wrapper);

                                    //export Base Quantities.
                                    PropertyUtil.CreateBeamColumnBaseQuantities(exporterIFC, instanceHandle, familyInstance, typeInfo, null);
                                    break;
                                }
                            case IFCExportType.IfcPlateType:
                                {
                                    OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, offsetTransform,
                                        exporterIFC, localPlacement, setter, wrapper);
                                    break;
                                }
                            case IFCExportType.IfcTransportElementType:
                                {
                                    IFCAnyHandle localPlacementToUse;
                                    ElementId roomId = setter.UpdateRoomRelativeCoordinates(familyInstance, out localPlacementToUse);

                                    string operationTypeStr;
                                    if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                                    {
                                        // It is PreDefinedType attribute in IFC4
                                        Toolkit.IFC4.IFCTransportElementType operationType = FamilyExporterUtil.GetPreDefinedType<Toolkit.IFC4.IFCTransportElementType>(familyInstance, ifcEnumType);
                                        operationTypeStr = operationType.ToString();
                                    }
                                    else
                                    {
                                        Toolkit.IFCTransportElementType operationType = FamilyExporterUtil.GetPreDefinedType<Toolkit.IFCTransportElementType>(familyInstance, ifcEnumType);
                                        operationTypeStr = operationType.ToString();
                                    }

                                    double capacityByWeight = 0.0;
                                    ParameterUtil.GetDoubleValueFromElementOrSymbol(familyInstance, "IfcCapacityByWeight", out capacityByWeight);
                                    double capacityByNumber = 0.0;
                                    ParameterUtil.GetDoubleValueFromElementOrSymbol(familyInstance, "IfcCapacityByNumber", out capacityByNumber);

                                    instanceHandle = IFCInstanceExporter.CreateTransportElement(file, instanceGUID, ownerHistory,
                                       instanceName, instanceDescription, instanceObjectType,
                                       localPlacementToUse, repHnd, instanceTag, operationTypeStr, capacityByWeight, capacityByNumber);

                                    bool containedInSpace = (roomId != ElementId.InvalidElementId);
                                    wrapper.AddElement(familyInstance, instanceHandle, setter, extraParams, !containedInSpace);
                                    if (containedInSpace)
                                         ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle);

                                    break;
                                }
                            //case IFCExportType.IfcBuildingElementProxy:
                            //case IFCExportType.IfcBuildingElementProxyType:
                            default:
                                {
                                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle))
                                    {
                                        bool isBuildingElementProxy =
                                            ((exportType == IFCExportType.IfcBuildingElementProxy) ||
                                            (exportType == IFCExportType.IfcBuildingElementProxyType));

                                        IFCAnyHandle localPlacementToUse = null;
                                    ElementId roomId = setter.UpdateRoomRelativeCoordinates(familyInstance, out localPlacementToUse);

                                        if (!isBuildingElementProxy && FamilyExporterUtil.IsDistributionControlElementSubType(exportType))
                                    {
                                            string ifcelementType = null;
                                            ParameterUtil.GetStringValueFromElement(familyInstance.Id, "IfcElementType", out ifcelementType);

                                            instanceHandle = IFCInstanceExporter.CreateDistributionControlElement(file, instanceGUID,
                                               ownerHistory, instanceName, instanceDescription, instanceObjectType,
                                               localPlacementToUse, repHnd, instanceTag, ifcelementType);
                                        }
                                        else 
                                    {
                                        instanceHandle = IFCInstanceExporter.CreateBuildingElementProxy(file, instanceGUID,
                                           ownerHistory, instanceName, instanceDescription, instanceObjectType,
                                           localPlacementToUse, repHnd, instanceTag, null);
                                        }

                                        bool containedInSpace = (roomId != ElementId.InvalidElementId);
                                        bool associateToLevel = containedInSpace ? false : !isChildInContainer;
                                        wrapper.AddElement(familyInstance, instanceHandle, setter, extraParams, associateToLevel);
                                        if (containedInSpace)
                                            ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle);
                                    }

                                    IFCAnyHandle placementToUse = localPlacement;
                                    if (!useInstanceGeometry)
                                    {
                                        bool needToCreateOpenings = OpeningUtil.NeedToCreateOpenings(instanceHandle, extraParams);
                                        if (needToCreateOpenings)
                                        {
                                            Transform openingTrf = new Transform(originalTrf);
                                            Transform extraRot = new Transform(originalTrf);
                                            extraRot.Origin = XYZ.Zero;
                                            openingTrf = openingTrf.Multiply(extraRot);
                                            openingTrf = openingTrf.Multiply(typeInfo.StyleTransform);

                                            XYZ scaledOrigin = UnitUtil.ScaleLength(openingTrf.Origin);
                                            IFCAnyHandle openingRelativePlacement = ExporterUtil.CreateAxis2Placement3D(file, scaledOrigin,
                                               openingTrf.get_Basis(2), openingTrf.get_Basis(0));
                                            IFCAnyHandle openingPlacement = ExporterUtil.CopyLocalPlacement(file, localPlacement);
                                            GeometryUtil.SetRelativePlacement(openingPlacement, openingRelativePlacement);
                                            placementToUse = openingPlacement;
                                        }
                                    }

                                    OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, offsetTransform,
                                        exporterIFC, placementToUse, setter, wrapper);
                                    break;
                                }
                        }

                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle))
                        {
                            ExporterCacheManager.HandleToElementCache.Register(instanceHandle, familyInstance.Id);

                            if (!exportParts)
                                CategoryUtil.CreateMaterialAssociations(exporterIFC, instanceHandle, typeInfo.MaterialIds);

                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(typeInfo.Style))
                                ExporterCacheManager.TypeRelationsCache.Add(typeInfo.Style, instanceHandle);
                        }
                    }

                    if (doorWindowInfo != null)
                    {
                        DoorWindowDelayedOpeningCreator delayedCreator = DoorWindowDelayedOpeningCreator.Create(exporterIFC, doorWindowInfo, instanceHandle, setter.LevelId);
                        if (delayedCreator != null)
                            ExporterCacheManager.DoorWindowDelayedOpeningCreatorCache.Add(delayedCreator);
                    }
                }
            }
        }
        /// <summary>
        /// Exports a MEP family instance.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="exportType">The export type of the element.
        /// <param name="ifcEnumType">The sub-type of the element.</param></param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if an entity was created, false otherwise.</returns>
        public static bool Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                  IFCExportType exportType, string ifcEnumType, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    IFCAnyHandle localPlacementToUse = setter.LocalPlacement;
                    using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                    {
                        extraParams.SetLocalPlacement(localPlacementToUse);

                        ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                        BodyExporterOptions bodyExporterOptions   = new BodyExporterOptions(true);
                        BodyData            bodyData              = null;
                        IFCAnyHandle        productRepresentation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                                               element, catId, geometryElement, bodyExporterOptions, null, extraParams, out bodyData);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(productRepresentation))
                        {
                            extraParams.ClearOpenings();
                            return(false);
                        }

                        IFCAnyHandle   ownerHistory    = exporterIFC.GetOwnerHistoryHandle();
                        ElementId      typeId          = element.GetTypeId();
                        ElementType    type            = element.Document.GetElement(typeId) as ElementType;
                        FamilyTypeInfo currentTypeInfo = ExporterCacheManager.TypeObjectsCache.Find(typeId, false);

                        bool found = currentTypeInfo.IsValid();
                        if (!found)
                        {
                            string typeGUID            = GUIDUtil.CreateGUID(type);
                            string typeName            = NamingUtil.GetNameOverride(type, NamingUtil.GetIFCName(type));
                            string typeObjectType      = NamingUtil.GetObjectTypeOverride(type, NamingUtil.CreateIFCObjectName(exporterIFC, type));
                            string applicableOccurence = NamingUtil.GetOverrideStringValue(type, "IfcApplicableOccurrence", typeObjectType);
                            string typeDescription     = NamingUtil.GetDescriptionOverride(type, null);
                            string typeTag             = NamingUtil.GetTagOverride(type, NamingUtil.CreateIFCElementId(type));
                            string typeElementType     = NamingUtil.GetOverrideStringValue(type, "IfcElementType", typeName);

                            IList <IFCAnyHandle> repMapListOpt = new List <IFCAnyHandle>();

                            IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, typeGUID, typeName,
                                                                                            typeDescription, applicableOccurence, null, repMapListOpt, typeTag, typeElementType, element, type);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle))
                            {
                                productWrapper.RegisterHandleWithElementType(type, styleHandle, null);

                                currentTypeInfo.Style = styleHandle;
                                ExporterCacheManager.TypeObjectsCache.Register(typeId, false, currentTypeInfo);
                            }
                        }
                        string instanceGUID        = GUIDUtil.CreateGUID(element);
                        string instanceName        = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string instanceObjectType  = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceTag         = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

                        bool roomRelated = !FamilyExporterUtil.IsDistributionFlowElementSubType(exportType);

                        ElementId roomId = ElementId.InvalidElementId;
                        if (roomRelated)
                        {
                            roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse);
                        }

                        IFCAnyHandle instanceHandle = null;

                        // For MEP objects
                        string exportEntityStr = exportType.ToString();
                        Common.Enums.IFCEntityType exportEntity;

                        if (String.Compare(exportEntityStr.Substring(exportEntityStr.Length - 4), "Type", true) == 0)
                        {
                            exportEntityStr = exportEntityStr.Substring(0, (exportEntityStr.Length - 4));
                        }
                        if (Enum.TryParse(exportEntityStr, out exportEntity))
                        {
                            // For MEP object creation
                            instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportEntity, file, instanceGUID, ownerHistory,
                                                                                        instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag);
                        }


                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle))
                        {
                            return(false);
                        }

                        bool relatedToSpace = (roomId != ElementId.InvalidElementId);
                        productWrapper.AddElement(element, instanceHandle, setter, extraParams, !relatedToSpace);
                        if (relatedToSpace)
                        {
                            ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle);
                        }

                        OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, element, extraParams, null,
                                                              exporterIFC, localPlacementToUse, setter, productWrapper);

                        if (currentTypeInfo.IsValid())
                        {
                            ExporterCacheManager.TypeRelationsCache.Add(currentTypeInfo.Style, instanceHandle);
                        }

                        if (bodyData != null && bodyData.MaterialIds.Count != 0)
                        {
                            CategoryUtil.CreateMaterialAssociations(exporterIFC, instanceHandle, bodyData.MaterialIds);
                        }

                        ExporterCacheManager.MEPCache.Register(element, instanceHandle);

                        tr.Commit();
                    }
                }
            }
            return(true);
        }
        private static bool ExportGenericElementAsMappedItem(ExporterIFC exporterIFC,
                                                             Element element, GeometryElement geomElem, IFCExportInfoPair exportType,
                                                             ProductWrapper wrapper)
        {
            GeometryInstance geometryInstance = GetTheGeometryInstance(geomElem);

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

            GeometryElement exportGeometry = geometryInstance.GetSymbolGeometry();

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

            ElementId   symbolId    = geometryInstance.GetSymbolGeometryId()?.SymbolId ?? ElementId.InvalidElementId;
            ElementType elementType = element.Document.GetElement(symbolId) as ElementType;

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

            Transform originalTrf = geometryInstance.Transform;

            // Can't handle mirrored transforms yet.
            if (originalTrf.HasReflection)
            {
                return(false);
            }

            ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

            IFCFile file = exporterIFC.GetFile();

            IList <Transform>        repMapTrfList = new List <Transform>();
            BodyData                 bodyData      = null;
            FamilyTypeInfo           typeInfo      = new FamilyTypeInfo();
            IFCExtrusionCreationData extraParams   = typeInfo.extraParams;

            Transform offsetTransform = Transform.Identity;

            // We will create a new mapped type if we haven't already created the type.
            FamilyTypeInfo currentTypeInfo = ExporterCacheManager.FamilySymbolToTypeInfoCache.Find(symbolId, false, exportType);
            bool           found           = currentTypeInfo.IsValid();

            if (!found)
            {
                IList <IFCAnyHandle> representations3D = new List <IFCAnyHandle>();

                IFCAnyHandle dummyPlacement = ExporterUtil.CreateLocalPlacement(file, null, null);
                extraParams.SetLocalPlacement(dummyPlacement);

                using (TransformSetter trfSetter = TransformSetter.Create())
                {
                    BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(false, ExportOptionsCache.ExportTessellationLevel.ExtraLow);

                    bodyData = BodyExporter.ExportBody(exporterIFC, element, categoryId,
                                                       ExporterUtil.GetSingleMaterial(element), exportGeometry,
                                                       bodyExporterOptions, extraParams);
                    typeInfo.MaterialIdList = bodyData.MaterialIds;
                    offsetTransform         = bodyData.OffsetTransform;

                    // This code does not handle openings yet.
                    // The intention for this is FabricationParts and DirectShapes which do not
                    // currently have opening.
                    // If they can have openings in the future, we can add this.
                    IFCAnyHandle bodyRepHnd = bodyData.RepresentationHnd;
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepHnd) || extraParams.GetOpenings().Count > 0)
                    {
                        return(false);
                    }

                    representations3D.Add(bodyRepHnd);
                    repMapTrfList.Add(null);
                }

                typeInfo.StyleTransform = ExporterIFCUtils.GetUnscaledTransform(exporterIFC,
                                                                                extraParams.GetLocalPlacement());

                IFCAnyHandle typeStyle = FamilyInstanceExporter.CreateTypeEntityHandle(exporterIFC,
                                                                                       ref typeInfo, null, representations3D, repMapTrfList, null,
                                                                                       element, elementType, elementType, false, false,
                                                                                       exportType, out HashSet <IFCAnyHandle> propertySets);

                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(typeStyle))
                {
                    wrapper.RegisterHandleWithElementType(elementType, exportType, typeStyle,
                                                          propertySets);

                    typeInfo.Style = typeStyle;

                    CategoryUtil.TryToCreateMaterialAssocation(exporterIFC, bodyData, elementType,
                                                               element, exportGeometry, typeStyle, typeInfo);

                    // Create other generic classification from ClassificationCode(s)
                    ClassificationUtil.CreateClassification(exporterIFC, file, elementType, typeStyle);
                    ClassificationUtil.CreateUniformatClassification(exporterIFC, file, elementType, typeStyle);
                }
            }

            if (found && !typeInfo.IsValid())
            {
                typeInfo = currentTypeInfo;
            }

            // we'll pretend we succeeded, but we'll do nothing.
            if (!typeInfo.IsValid())
            {
                return(false);
            }

            extraParams = typeInfo.extraParams;

            // We expect no openings, so always add to map.
            ExporterCacheManager.FamilySymbolToTypeInfoCache.Register(symbolId, false, exportType, typeInfo);

            XYZ       scaledMapOrigin = XYZ.Zero;
            Transform scaledTrf       = originalTrf.Multiply(typeInfo.StyleTransform);

            // create instance.
            IList <IFCAnyHandle> shapeReps = FamilyInstanceExporter.CreateShapeRepresentations(exporterIFC,
                                                                                               file, element, categoryId, typeInfo, scaledMapOrigin);

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

            Transform boundingBoxTrf = (offsetTransform != null) ? offsetTransform.Inverse : Transform.Identity;

            boundingBoxTrf = boundingBoxTrf.Multiply(scaledTrf.Inverse);
            IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geomElem, boundingBoxTrf);

            if (boundingBoxRep != null)
            {
                shapeReps.Add(boundingBoxRep);
            }

            IFCAnyHandle repHnd = (shapeReps.Count > 0) ? IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps) : null;

            using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, scaledTrf, null))
            {
                IFCAnyHandle instanceHandle            = null;
                IFCAnyHandle localPlacement            = setter.LocalPlacement;
                bool         materialAlreadyAssociated = false;

                // We won't create the instance if:
                // (1) we are exporting to CV2.0/RV, (2) we have no 2D, 3D, or bounding box geometry, and (3) we aren't exporting parts.
                if (!(repHnd == null &&
                      (ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2 ||
                       ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)))
                {
                    string instanceGUID = GUIDUtil.CreateGUID(element);

                    bool isChildInContainer = element.AssemblyInstanceId != ElementId.InvalidElementId;

                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle))
                    {
                        bool isBuildingElementProxy =
                            ((exportType.ExportInstance == IFCEntityType.IfcBuildingElementProxy) ||
                             (exportType.ExportType == IFCEntityType.IfcBuildingElementProxyType));

                        ElementId roomId = setter.UpdateRoomRelativeCoordinates(element,
                                                                                out IFCAnyHandle localPlacementToUse);
                        bool         containedInSpace = (roomId != ElementId.InvalidElementId) && (exportType.ExportInstance != IFCEntityType.IfcSystemFurnitureElement);
                        IFCAnyHandle ownerHistory     = ExporterCacheManager.OwnerHistoryHandle;

                        if (!isBuildingElementProxy)
                        {
                            instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportType, exporterIFC, element, instanceGUID,
                                                                                        ownerHistory, localPlacementToUse, repHnd);
                        }
                        else
                        {
                            instanceHandle = IFCInstanceExporter.CreateBuildingElementProxy(exporterIFC, element, instanceGUID,
                                                                                            ownerHistory, localPlacementToUse, repHnd, exportType.ValidatedPredefinedType);
                        }

                        bool associateToLevel = !containedInSpace && !isChildInContainer;
                        wrapper.AddElement(element, instanceHandle, setter, extraParams, associateToLevel, exportType);
                        if (containedInSpace)
                        {
                            ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle);
                        }
                    }

                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle))
                    {
                        if (ElementFilteringUtil.IsMEPType(exportType) || ElementFilteringUtil.ProxyForMEPType(element, exportType))
                        {
                            ExporterCacheManager.MEPCache.Register(element, instanceHandle);
                        }

                        ExporterCacheManager.HandleToElementCache.Register(instanceHandle, element.Id);

                        if (!materialAlreadyAssociated)
                        {
                            // Create material association for the instance only if the the istance geometry is different from the type
                            // or the type does not have any material association
                            IFCAnyHandle constituentSetHnd = ExporterCacheManager.MaterialSetCache.FindConstituentSetHnd(symbolId);
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(constituentSetHnd) &&
                                bodyData != null && bodyData.RepresentationItemInfo != null && bodyData.RepresentationItemInfo.Count > 0)
                            {
                                CategoryUtil.CreateMaterialAssociationWithShapeAspect(exporterIFC, element, instanceHandle, bodyData.RepresentationItemInfo);
                            }
                            else
                            {
                                // Create material association in case if bodyData is null
                                CategoryUtil.CreateMaterialAssociation(exporterIFC, instanceHandle, typeInfo.MaterialIdList);
                            }
                        }

                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(typeInfo.Style))
                        {
                            ExporterCacheManager.TypeRelationsCache.Add(typeInfo.Style, instanceHandle);
                        }
                    }
                }
            }
            return(true);
        }