private static bool ExportCustomFabricSheet(FabricSheetExportConfig cfg)
        {
            if (cfg.Equals(null) || cfg.Sheet.IsBent)
            {
                return(false);
            }

            string                 guid         = GUIDUtil.CreateGUID(cfg.Sheet);
            IFCAnyHandle           ownerHistory = ExporterCacheManager.OwnerHistoryHandle;
            HashSet <IFCAnyHandle> rebarHandles = new HashSet <IFCAnyHandle>();
            string                 matName      = NamingUtil.GetMaterialName(cfg.Doc, cfg.MaterialId);

            int ii = 0;

            do
            {
                WireDistributionDirection dir             = (WireDistributionDirection)ii;
                IList <Curve>             wireCenterlines = cfg.Sheet.GetWireCenterlines(dir);
                for (int jj = 0; jj < wireCenterlines.Count; jj++)
                {
                    double wireDiam = 0.0;

                    FabricWireItem wire = cfg.SheetType.GetWireItem(jj, dir);
                    if (cfg.Doc.GetElement(wire.WireType) is FabricWireType wireType)
                    {
                        wireDiam = UnitUtil.ScaleLength(wireType.WireDiameter);
                    }

                    IFCAnyHandle bodyItem = GeometryUtil.CreateSweptDiskSolid(cfg.ExporterIFC, cfg.File, wireCenterlines[jj], wireDiam / 2.0, null);
                    RepresentationUtil.CreateStyledItemAndAssign(cfg.File, cfg.Doc, cfg.MaterialId, bodyItem);

                    ISet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle> {
                        bodyItem
                    };
                    IFCAnyHandle shapeRep = null;
                    if (bodyItems.Count > 0)
                    {
                        shapeRep = RepresentationUtil.CreateAdvancedSweptSolidRep(cfg.ExporterIFC, cfg.Sheet, cfg.CategoryId,
                                                                                  cfg.ExporterIFC.Get3DContextHandle("Body"), bodyItems, null);
                    }
                    IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>();
                    if (shapeRep != null)
                    {
                        shapeReps.Add(shapeRep);
                    }

                    IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(cfg.File, null, null, shapeReps);
                    IFCAnyHandle handle  = IFCInstanceExporter.CreateReinforcingBar(cfg.ExporterIFC, cfg.Sheet, guid, ExporterCacheManager.OwnerHistoryHandle,
                                                                                    cfg.PlacementSetter.LocalPlacement, prodRep, matName, wireDiam, 0, 0, IFCReinforcingBarRole.NotDefined, null);
                    IFCAnyHandleUtil.SetAttribute(handle, "ObjectType", "Generic");
                    CategoryUtil.CreateMaterialAssociation(cfg.ExporterIFC, handle, cfg.MaterialId);
                    rebarHandles.Add(handle);
                }
                ii++;
            }while (ii < 2);

            IFCAnyHandle assemblyInstanceHnd = IFCInstanceExporter.CreateElementAssembly(cfg.ExporterIFC, cfg.Sheet, guid,
                                                                                         ownerHistory, cfg.PlacementSetter.LocalPlacement, null, null, IFCElementAssemblyType.UserDefined);
            IFCExportInfoPair assemblyExportInfo = new IFCExportInfoPair(IFCEntityType.IfcElementAssembly);

            cfg.ProductWrapper.AddElement(cfg.Sheet, assemblyInstanceHnd, cfg.PlacementSetter.LevelInfo, null, true, assemblyExportInfo);
            ExporterCacheManager.AssemblyInstanceCache.RegisterAssemblyInstance(cfg.Sheet.Id, assemblyInstanceHnd);
            IFCInstanceExporter.CreateRelAggregates(cfg.File, guid, ownerHistory, null, null, assemblyInstanceHnd, rebarHandles);

            return(true);
        }
        private static bool ExportStandardFabricSheet(FabricSheetExportConfig cfg)
        {
            if (cfg.Equals(null))
            {
                return(false);
            }

            string       guid         = GUIDUtil.CreateGUID(cfg.Sheet);
            IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

            int ii = 0;

            do
            {
                WireDistributionDirection dir             = (WireDistributionDirection)ii;
                IList <Curve>             wireCenterlines = cfg.Sheet?.GetWireCenterlines(dir);
                for (int jj = 0; jj < wireCenterlines.Count; jj++)
                {
                    double wireDiam = 0.0;

                    Element wireTypeElem = (dir == WireDistributionDirection.Major) ? cfg.Doc?.GetElement(cfg.SheetType?.MajorDirectionWireType) :
                                           cfg.Doc?.GetElement(cfg.SheetType?.MinorDirectionWireType);

                    if (wireTypeElem is FabricWireType wireType)
                    {
                        wireDiam = UnitUtil.ScaleLength(wireType.WireDiameter);
                    }
                    IFCAnyHandle bodyItem = GeometryUtil.CreateSweptDiskSolid(cfg.ExporterIFC, cfg.File, wireCenterlines[jj], wireDiam / 2.0, null);

                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItem))
                    {
                        cfg.BodyItems?.Add(bodyItem);
                        RepresentationUtil.CreateStyledItemAndAssign(cfg.File, cfg.Doc, cfg.MaterialId, bodyItem);
                    }
                }
                ii++;
            }while (ii < 2);

            IFCAnyHandle shapeRep = null;

            if (cfg.BodyItems.Count > 0)
            {
                shapeRep = RepresentationUtil.CreateAdvancedSweptSolidRep(cfg.ExporterIFC, cfg.Sheet, cfg.CategoryId,
                                                                          cfg.ExporterIFC.Get3DContextHandle("Body"), cfg.BodyItems, null);
            }

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

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

            IFCAnyHandle prodRep = (shapeReps != null) ? IFCInstanceExporter.CreateProductDefinitionShape(cfg.File, null, null, shapeReps) : null;

            FabricParams fabricParams = null;

            if (!ExporterCacheManager.FabricParamsCache.TryGetValue(cfg.Sheet.Id, out fabricParams))
            {
                fabricParams = new FabricParams(cfg.Sheet);
                ExporterCacheManager.FabricParamsCache[cfg.Sheet.Id] = fabricParams;
            }

            IFCAnyHandle handle = IFCInstanceExporter.CreateReinforcingMesh(cfg.ExporterIFC, cfg.Sheet, guid, ownerHistory, cfg.EcData.GetLocalPlacement(),
                                                                            prodRep, fabricParams.SteelGrade, fabricParams.MeshLength, fabricParams.MeshWidth,
                                                                            fabricParams.LongitudinalBarNominalDiameter, fabricParams.TransverseBarNominalDiameter,
                                                                            fabricParams.LongitudinalBarCrossSectionArea, fabricParams.TransverseBarCrossSectionArea,
                                                                            fabricParams.LongitudinalBarSpacing, fabricParams.TransverseBarSpacing);
            IFCExportInfoPair exportInfo   = new IFCExportInfoPair(IFCEntityType.IfcReinforcingMesh);
            ElementId         fabricAreaId = cfg.Sheet?.FabricAreaOwnerId;

            if (fabricAreaId != ElementId.InvalidElementId)
            {
                if (!ExporterCacheManager.FabricAreaHandleCache.TryGetValue(fabricAreaId, out HashSet <IFCAnyHandle> fabricSheets))
                {
                    fabricSheets = new HashSet <IFCAnyHandle>();
                    ExporterCacheManager.FabricAreaHandleCache[fabricAreaId] = fabricSheets;
                }
                fabricSheets.Add(handle);
            }
            cfg.ProductWrapper.AddElement(cfg.Sheet, handle, cfg.PlacementSetter?.LevelInfo, cfg.EcData, true, exportInfo);
            CategoryUtil.CreateMaterialAssociation(cfg.ExporterIFC, handle, cfg.MaterialId);

            return(true);
        }
        /// <summary>
        /// Exports an element as an IfcReinforcingMesh.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if exported successfully, false otherwise.</returns>
        public static bool ExportFabricSheet(ExporterIFC exporterIFC, FabricSheet sheet,
                                             GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            if (sheet == null || geometryElement == null)
            {
                return(false);
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                // Check for containment override
                ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, sheet, out IFCAnyHandle overrideContainerHnd);
                if (!(sheet.Document?.GetElement(sheet.GetTypeId()) is FabricSheetType fsType))
                {
                    return(false);
                }

                using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, sheet, null, null, overrideContainerId, overrideContainerHnd))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(placementSetter.LocalPlacement);

                        FabricSheetExportConfig config = new FabricSheetExportConfig()
                        {
                            BodyItems       = new HashSet <IFCAnyHandle>(),
                            CategoryId      = CategoryUtil.GetSafeCategoryId(sheet),
                            Doc             = sheet.Document,
                            Sheet           = sheet,
                            EcData          = ecData,
                            ExporterIFC     = exporterIFC,
                            File            = file,
                            PlacementSetter = placementSetter,
                            ProductWrapper  = productWrapper,
                            SheetType       = fsType
                        };

                        ParameterUtil.GetElementIdValueFromElementOrSymbol(config.Sheet, BuiltInParameter.MATERIAL_ID_PARAM, out ElementId materialId);
                        config.MaterialId = materialId;

                        bool status = true;
                        if (config.SheetType.IsCustom())
                        {
                            if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(IFCEntityType.IfcElementAssembly))
                            {
                                return(false);
                            }
                            else
                            {
                                status = ExportCustomFabricSheet(config);
                            }
                        }
                        else
                        {
                            if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(IFCEntityType.IfcReinforcingMesh))
                            {
                                return(false);
                            }
                            else
                            {
                                status = ExportStandardFabricSheet(config);
                            }
                        }

                        if (!status)
                        {
                            tr.RollBack();
                            return(false);
                        }
                    }
                }
                tr.Commit();
                return(true);
            }
        }