Пример #1
0
        /// <summary>
        /// Creates openings if there is necessary.
        /// </summary>
        /// <param name="elementHandle">The element handle to create openings.</param>
        /// <param name="element">The element to create openings.</param>
        /// <param name="info">The extrusion data.</param>
        /// <param name="extraParams">The extrusion creation data.</param>
        /// <param name="offsetTransform">The offset transform from ExportBody, or the identity transform.</param>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="originalPlacement">The original placement handle.</param>
        /// <param name="setter">The PlacementSetter.</param>
        /// <param name="wrapper">The ProductWrapper.</param>
        private static void CreateOpeningsIfNecessaryBase(IFCAnyHandle elementHandle, Element element, IList<IFCExtrusionData> info,
            IFCExtrusionCreationData extraParams, Transform offsetTransform, ExporterIFC exporterIFC,
            IFCAnyHandle originalPlacement, PlacementSetter setter, ProductWrapper wrapper)
        {
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(elementHandle))
            return;

             int sz = info.Count;
             if (sz == 0)
            return;

             using (TransformSetter transformSetter = TransformSetter.Create())
             {
            if (offsetTransform != null)
               transformSetter.Initialize(exporterIFC, offsetTransform.Inverse);

            IFCFile file = exporterIFC.GetFile();
            ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);
            Document document = element.Document;

            string openingObjectType = "Opening";

            int openingNumber = 1;
            for (int curr = info.Count - 1; curr >= 0; curr--)
            {
               Transform extrusionTrf = Transform.Identity;
               IFCAnyHandle extrusionHandle = ExtrusionExporter.CreateExtrudedSolidFromExtrusionData(exporterIFC, element, info[curr]);
               if (IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionHandle))
                  continue;

               BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, extrusionHandle, ElementId.InvalidElementId);

               HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();
               bodyItems.Add(extrusionHandle);

               IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body");
               IFCAnyHandle bodyRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItems, null);
               IList<IFCAnyHandle> representations = new List<IFCAnyHandle>();
               representations.Add(bodyRep);

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

               IFCAnyHandle openingPlacement = ExporterUtil.CopyLocalPlacement(file, originalPlacement);
               string guid = GUIDUtil.CreateGUID();
               IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;
               string openingName = NamingUtil.GetIFCNamePlusIndex(element, openingNumber++);
               IFCAnyHandle openingElement = IFCInstanceExporter.CreateOpeningElement(exporterIFC, element, guid, ownerHistory,
                  openingPlacement, openingRep);
               IFCAnyHandleUtil.OverrideNameAttribute(openingElement, openingName);
               IFCAnyHandleUtil.SetAttribute(openingElement, "ObjectType", openingObjectType);
               IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcOpeningElement);
               wrapper.AddElement(null, openingElement, setter, extraParams, true, exportInfo);
               if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities && (extraParams != null))
                  PropertyUtil.CreateOpeningQuantities(exporterIFC, openingElement, extraParams);

               string voidGuid = GUIDUtil.CreateGUID();
               IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, elementHandle, openingElement);
            }
             }
        }
Пример #2
0
 /// <summary>
 /// Creates an IfcFacetedBrep handle.
 /// </summary>
 /// <param name="exporterIFC">The ExporterIFC object.</param>
 /// <param name="shell">The closed shell handle.</param>
 /// <returns>The handle.</returns>
 public static IFCAnyHandle CreateFacetedBRep(ExporterIFC exporterIFC, Document document, IFCAnyHandle shell, ElementId overrideMaterialId)
 {
     IFCFile file = exporterIFC.GetFile();
     IFCAnyHandle brep = IFCInstanceExporter.CreateFacetedBrep(file, shell);
     BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, brep, overrideMaterialId);
     return brep;
 }
Пример #3
0
        /// <summary>
        /// Creates an IfcFacetedBrep handle.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="shell">
        /// The closed shell handle.
        /// </param>
        /// <returns>
        /// The handle.
        /// </returns>
        public static IFCAnyHandle CreateFacetedBRep(ExporterIFC exporterIFC, Document document, IFCAnyHandle shell, ElementId overrideMaterialId)
        {
            IFCFile      file = exporterIFC.GetFile();
            IFCAnyHandle brep = IFCInstanceExporter.CreateFacetedBrep(file, shell);

            // Coordination View V2 does not support styled items by default.  IFC2x2 does, even if it isn't widely used, so we can't use ExportAnnotations.
            if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x3CoordinationView2)
            {
                BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, brep, overrideMaterialId);
            }
            return(brep);
        }
Пример #4
0
        /// <summary>
        /// Exports a geometry element to boundary representation.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="exportBoundaryRep">True if to export boundary representation.</param>
        /// <param name="exportAsFacetation">True if to export the geometry as facetation.</param>
        /// <param name="bodyRep">Body representation.</param>
        /// <param name="boundaryRep">Boundary representation.</param>
        /// <returns>True if success, false if fail.</returns>
        public static bool ExportSurface(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                         bool exportBoundaryRep, bool exportAsFacetation, ref IFCAnyHandle bodyRep, ref IFCAnyHandle boundaryRep)
        {
            if (geometryElement == null)
            {
                return(false);
            }

            IFCGeometryInfo ifcGeomInfo = null;
            Document        doc         = element.Document;
            Plane           plane       = GeometryUtil.CreateDefaultPlane();
            XYZ             projDir     = new XYZ(0, 0, 1);
            double          eps         = UnitUtil.ScaleLength(doc.Application.VertexTolerance);

            ifcGeomInfo = IFCGeometryInfo.CreateFaceGeometryInfo(exporterIFC, plane, projDir, eps, exportBoundaryRep);

            ExporterIFCUtils.CollectGeometryInfo(exporterIFC, ifcGeomInfo, geometryElement, XYZ.Zero, true);

            IFCFile      file = exporterIFC.GetFile();
            IFCAnyHandle surface;

            // Use tessellated geometry for surface in IFC Reference View
            if (ExporterUtil.IsReferenceView())
            {
                BodyExporterOptions options = new BodyExporterOptions(false);
                surface = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, element, options, geometryElement);
            }
            else
            {
                HashSet <IFCAnyHandle> faceSets = new HashSet <IFCAnyHandle>();
                IList <ICollection <IFCAnyHandle> > faceList = ifcGeomInfo.GetFaces();
                foreach (ICollection <IFCAnyHandle> faces in faceList)
                {
                    // no faces, don't complain.
                    if (faces.Count == 0)
                    {
                        continue;
                    }
                    HashSet <IFCAnyHandle> faceSet = new HashSet <IFCAnyHandle>(faces);
                    faceSets.Add(IFCInstanceExporter.CreateConnectedFaceSet(file, faceSet));
                }

                if (faceSets.Count == 0)
                {
                    return(false);
                }

                surface = IFCInstanceExporter.CreateFaceBasedSurfaceModel(file, faceSets);
            }

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

            BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, doc, surface, BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element));

            ISet <IFCAnyHandle> surfaceItems = new HashSet <IFCAnyHandle>();

            surfaceItems.Add(surface);

            ElementId catId = CategoryUtil.GetSafeCategoryId(element);

            bodyRep = RepresentationUtil.CreateSurfaceRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), surfaceItems,
                                                          exportAsFacetation, bodyRep);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
            {
                return(false);
            }

            ICollection <IFCAnyHandle> boundaryRepresentations = ifcGeomInfo.GetRepresentations();

            if (exportBoundaryRep && boundaryRepresentations.Count > 0)
            {
                HashSet <IFCAnyHandle> boundaryRepresentationSet = new HashSet <IFCAnyHandle>();
                boundaryRepresentationSet.UnionWith(boundaryRepresentations);
                boundaryRep = RepresentationUtil.CreateBoundaryRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("FootPrint"), boundaryRepresentationSet,
                                                                   boundaryRep);
            }

            return(true);
        }
Пример #5
0
        /// <summary>
        ///  Exports a roof or floor as a container of multiple roof slabs.  Returns the handle, if successful.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="ifcEnumType">The roof type.</param>
        /// <param name="element">The roof or floor element.</param>
        /// <param name="geometry">The geometry of the element.</param>
        /// <param name="productWrapper">The product wrapper.</param>
        /// <returns>The roof handle.</returns>
        /// <remarks>For floors, if there is only one component, return null, as we do not want to create a container.</remarks>
        public static IFCAnyHandle ExportRoofOrFloorAsContainer(ExporterIFC exporterIFC, string ifcEnumType, Element element, GeometryElement geometry, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            // We support ExtrusionRoofs, FootPrintRoofs, and Floors only.
            bool elementIsRoof  = (element is ExtrusionRoof) || (element is FootPrintRoof);
            bool elementIsFloor = (element is Floor);

            if (!elementIsRoof && !elementIsFloor)
            {
                return(null);
            }

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    IFCAnyHandle localPlacement = setter.LocalPlacement;
                    IList <HostObjectSubcomponentInfo> hostObjectSubcomponents = null;
                    try
                    {
                        hostObjectSubcomponents = ExporterIFCUtils.ComputeSubcomponents(element as HostObject);
                    }
                    catch
                    {
                        return(null);
                    }

                    if (hostObjectSubcomponents == null)
                    {
                        return(null);
                    }

                    int numSubcomponents = hostObjectSubcomponents.Count;
                    if (numSubcomponents == 0 || (elementIsFloor && numSubcomponents == 1))
                    {
                        return(null);
                    }

                    try
                    {
                        using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                        {
                            IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;
                            extrusionCreationData.SetLocalPlacement(localPlacement);
                            extrusionCreationData.ReuseLocalPlacement = true;

                            using (TransformSetter trfSetter = TransformSetter.Create())
                            {
                                IList <GeometryObject> geometryList = new List <GeometryObject>();
                                geometryList.Add(geometry);
                                trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, extrusionCreationData);

                                IFCAnyHandle prodRepHnd = null;

                                string elementGUID        = GUIDUtil.CreateGUID(element);
                                string elementName        = NamingUtil.GetIFCName(element);
                                string elementDescription = NamingUtil.GetDescriptionOverride(element, null);
                                string elementObjectType  = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName());
                                string elementId          = NamingUtil.CreateIFCElementId(element);
                                string hostObjectType     = IFCValidateEntry.GetValidIFCType(element, ifcEnumType);

                                IFCAnyHandle hostObjectHandle = null;
                                if (elementIsRoof)
                                {
                                    hostObjectHandle = IFCInstanceExporter.CreateRoof(file, elementGUID, ownerHistory, elementName, elementDescription,
                                                                                      elementObjectType, localPlacement, prodRepHnd, elementId, hostObjectType);
                                }
                                else
                                {
                                    hostObjectHandle = IFCInstanceExporter.CreateSlab(file, elementGUID, ownerHistory, elementName, elementDescription,
                                                                                      elementObjectType, localPlacement, prodRepHnd, elementId, hostObjectType);
                                }

                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjectHandle))
                                {
                                    return(null);
                                }

                                IList <IFCAnyHandle> elementHandles = new List <IFCAnyHandle>();
                                elementHandles.Add(hostObjectHandle);

                                // If element is floor, then the profile curve loop of hostObjectSubComponent is computed from the top face of the floor
                                // else if element is roof, then the profile curve loop is taken from the bottom face of the roof instead
                                XYZ extrusionDir = elementIsFloor ? new XYZ(0, 0, -1) : new XYZ(0, 0, 1);

                                ElementId catId = CategoryUtil.GetSafeCategoryId(element);

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

                                IList <CurveLoop> hostObjectOpeningLoops = new List <CurveLoop>();
                                double            maximumScaledDepth     = 0.0;

                                using (IFCExtrusionCreationData slabExtrusionCreationData = new IFCExtrusionCreationData())
                                {
                                    slabExtrusionCreationData.SetLocalPlacement(extrusionCreationData.GetLocalPlacement());
                                    slabExtrusionCreationData.ReuseLocalPlacement = false;
                                    slabExtrusionCreationData.ForceOffset         = true;

                                    int    loopNum         = 0;
                                    int    subElementStart = elementIsRoof ? (int)IFCRoofSubElements.RoofSlabStart : (int)IFCSlabSubElements.SubSlabStart;
                                    string subSlabType     = elementIsRoof ? "ROOF" : hostObjectType;

                                    foreach (HostObjectSubcomponentInfo hostObjectSubcomponent in hostObjectSubcomponents)
                                    {
                                        trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, slabExtrusionCreationData);
                                        Plane     plane = hostObjectSubcomponent.GetPlane();
                                        Transform lcs   = GeometryUtil.CreateTransformFromPlane(plane);

                                        IList <CurveLoop> curveLoops = new List <CurveLoop>();

                                        CurveLoop slabCurveLoop = hostObjectSubcomponent.GetCurveLoop();
                                        curveLoops.Add(slabCurveLoop);
                                        double slope = Math.Abs(plane.Normal.Z);

                                        double       scaledDepth          = UnitUtil.ScaleLength(hostObjectSubcomponent.Depth);
                                        double       scaledExtrusionDepth = scaledDepth * slope;
                                        IFCAnyHandle shapeRep             = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, scaledExtrusionDepth, false);
                                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
                                        {
                                            return(null);
                                        }

                                        ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(element as HostObject);
                                        BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, shapeRep, matId);

                                        HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>();
                                        bodyItems.Add(shapeRep);
                                        shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null);
                                        IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>();
                                        shapeReps.Add(shapeRep);

                                        IFCAnyHandle repHnd = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);

                                        // Allow support for up to 256 named IfcSlab components, as defined in IFCSubElementEnums.cs.
                                        string slabGUID = (loopNum < 256) ? GUIDUtil.CreateSubElementGUID(element, subElementStart + loopNum) : GUIDUtil.CreateGUID();

                                        IFCAnyHandle slabPlacement = ExporterUtil.CreateLocalPlacement(file, slabExtrusionCreationData.GetLocalPlacement(), null);
                                        IFCAnyHandle slabHnd       = IFCInstanceExporter.CreateSlab(file, slabGUID, ownerHistory, elementName,
                                                                                                    elementDescription, elementObjectType, slabPlacement, repHnd, elementId, subSlabType);

                                        //slab quantities
                                        slabExtrusionCreationData.ScaledLength         = scaledExtrusionDepth;
                                        slabExtrusionCreationData.ScaledArea           = UnitUtil.ScaleArea(UnitUtil.ScaleArea(hostObjectSubcomponent.AreaOfCurveLoop));
                                        slabExtrusionCreationData.ScaledOuterPerimeter = UnitUtil.ScaleLength(curveLoops[0].GetExactLength());
                                        slabExtrusionCreationData.Slope = UnitUtil.ScaleAngle(MathUtil.SafeAcos(Math.Abs(slope)));

                                        productWrapper.AddElement(null, slabHnd, setter, slabExtrusionCreationData, false);
                                        elementHandles.Add(slabHnd);
                                        slabHandles.Add(slabHnd);

                                        hostObjectOpeningLoops.Add(slabCurveLoop);
                                        maximumScaledDepth = Math.Max(maximumScaledDepth, scaledDepth);
                                        loopNum++;
                                    }
                                }

                                productWrapper.AddElement(element, hostObjectHandle, setter, extrusionCreationData, true);

                                ExporterUtil.RelateObjects(exporterIFC, null, hostObjectHandle, slabHandles);

                                OpeningUtil.AddOpeningsToElement(exporterIFC, elementHandles, hostObjectOpeningLoops, element, null, maximumScaledDepth,
                                                                 null, setter, localPlacement, productWrapper);

                                transaction.Commit();
                                return(hostObjectHandle);
                            }
                        }
                    }
                    finally
                    {
                        exporterIFC.ClearFaceWithElementHandleMap();
                    }
                }
            }
        }
Пример #6
0
        /// <summary>
        ///  Exports a roof as a container of multiple roof slabs.  Returns the handle, if successful.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="ifcEnumType">The roof type.</param>
        /// <param name="element">The roof element.</param>
        /// <param name="geometry">The geometry of the element.</param>
        /// <param name="productWrapper">The product wrapper.</param>
        /// <returns>The roof handle.</returns>
        public static IFCAnyHandle ExportRoofAsContainer(ExporterIFC exporterIFC, string ifcEnumType, Element element, GeometryElement geometry, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            if (!(element is ExtrusionRoof) && !(element is FootPrintRoof))
            {
                return(null);
            }

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    IFCAnyHandle   localPlacement = setter.LocalPlacement;
                    RoofComponents roofComponents = null;
                    try
                    {
                        roofComponents = ExporterIFCUtils.GetRoofComponents(exporterIFC, element as RoofBase);
                    }
                    catch
                    {
                        return(null);
                    }

                    if (roofComponents == null)
                    {
                        return(null);
                    }

                    try
                    {
                        using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                        {
                            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                            extrusionCreationData.SetLocalPlacement(localPlacement);
                            extrusionCreationData.ReuseLocalPlacement = true;

                            using (TransformSetter trfSetter = TransformSetter.Create())
                            {
                                IList <GeometryObject> geometryList = new List <GeometryObject>();
                                geometryList.Add(geometry);
                                trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, extrusionCreationData);

                                IFCAnyHandle prodRepHnd = null;

                                string elementGUID        = GUIDUtil.CreateGUID(element);
                                string elementName        = NamingUtil.GetIFCName(element);
                                string elementDescription = NamingUtil.GetDescriptionOverride(element, null);
                                string elementObjectType  = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName());
                                string elementId          = NamingUtil.CreateIFCElementId(element);
                                string roofType           = IFCValidateEntry.GetValidIFCType(element, ifcEnumType);

                                IFCAnyHandle roofHandle = IFCInstanceExporter.CreateRoof(file, elementGUID, ownerHistory, elementName, elementDescription,
                                                                                         elementObjectType, localPlacement, prodRepHnd, elementId, roofType);

                                IList <IFCAnyHandle> elementHandles = new List <IFCAnyHandle>();
                                elementHandles.Add(roofHandle);

                                //only thing supported right now.
                                XYZ extrusionDir = new XYZ(0, 0, 1);

                                ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                                IList <CurveLoop> roofCurveloops = roofComponents.GetCurveLoops();
                                IList <XYZ>       planeDirs      = roofComponents.GetPlaneDirections();
                                IList <XYZ>       planeOrigins   = roofComponents.GetPlaneOrigins();
                                IList <Face>      loopFaces      = roofComponents.GetLoopFaces();
                                double            scaledDepth    = roofComponents.ScaledDepth;
                                IList <double>    areas          = roofComponents.GetAreasOfCurveLoops();

                                IList <IFCAnyHandle> slabHandles = new List <IFCAnyHandle>();
                                using (IFCExtrusionCreationData slabExtrusionCreationData = new IFCExtrusionCreationData())
                                {
                                    slabExtrusionCreationData.SetLocalPlacement(extrusionCreationData.GetLocalPlacement());
                                    slabExtrusionCreationData.ReuseLocalPlacement = false;
                                    slabExtrusionCreationData.ForceOffset         = true;

                                    for (int numLoop = 0; numLoop < roofCurveloops.Count; numLoop++)
                                    {
                                        trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, slabExtrusionCreationData);
                                        Plane             plane      = new Plane(planeDirs[numLoop], planeOrigins[numLoop]);
                                        IList <CurveLoop> curveLoops = new List <CurveLoop>();
                                        curveLoops.Add(roofCurveloops[numLoop]);
                                        double       slope = Math.Abs(planeDirs[numLoop].Z);
                                        double       scaledExtrusionDepth = scaledDepth * slope;
                                        IFCAnyHandle shapeRep             = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, plane, extrusionDir, scaledExtrusionDepth);
                                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
                                        {
                                            return(null);
                                        }

                                        ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(element as HostObject);
                                        BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, shapeRep, matId);

                                        HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>();
                                        bodyItems.Add(shapeRep);
                                        shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null);
                                        IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>();
                                        shapeReps.Add(shapeRep);

                                        IFCAnyHandle repHnd = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);

                                        // Allow support for up to 256 named IfcSlab components, as defined in IFCSubElementEnums.cs.
                                        string slabGUID = (numLoop < 256) ? GUIDUtil.CreateSubElementGUID(element, (int)IFCRoofSubElements.RoofSlabStart + numLoop) : GUIDUtil.CreateGUID();

                                        IFCAnyHandle slabPlacement = ExporterUtil.CreateLocalPlacement(file, slabExtrusionCreationData.GetLocalPlacement(), null);
                                        IFCAnyHandle slabHnd       = IFCInstanceExporter.CreateSlab(file, slabGUID, ownerHistory, elementName,
                                                                                                    elementDescription, elementObjectType, slabPlacement, repHnd, elementId, "ROOF");

                                        //slab quantities
                                        slabExtrusionCreationData.ScaledLength         = scaledExtrusionDepth;
                                        slabExtrusionCreationData.ScaledArea           = UnitUtil.ScaleArea(areas[numLoop]);
                                        slabExtrusionCreationData.ScaledOuterPerimeter = UnitUtil.ScaleLength(curveLoops[0].GetExactLength());
                                        slabExtrusionCreationData.Slope = UnitUtil.ScaleAngle(Math.Acos(Math.Abs(planeDirs[numLoop].Z)));

                                        productWrapper.AddElement(null, slabHnd, setter, slabExtrusionCreationData, false);
                                        elementHandles.Add(slabHnd);
                                        slabHandles.Add(slabHnd);
                                    }
                                }

                                productWrapper.AddElement(element, roofHandle, setter, extrusionCreationData, true);

                                ExporterUtil.RelateObjects(exporterIFC, null, roofHandle, slabHandles);

                                OpeningUtil.AddOpeningsToElement(exporterIFC, elementHandles, roofCurveloops, element, null, roofComponents.ScaledDepth,
                                                                 null, setter, localPlacement, productWrapper);

                                transaction.Commit();
                                return(roofHandle);
                            }
                        }
                    }
                    finally
                    {
                        exporterIFC.ClearFaceWithElementHandleMap();
                    }
                }
            }
        }
Пример #7
0
        /// <summary>
        ///  Exports a roof or floor as a container of multiple roof slabs.  Returns the handle, if successful.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="element">The roof or floor element.</param>
        /// <param name="geometry">The geometry of the element.</param>
        /// <param name="productWrapper">The product wrapper.</param>
        /// <returns>The roof handle.</returns>
        /// <remarks>For floors, if there is only one component, return null, as we do not want to create a container.</remarks>
        public static IFCAnyHandle ExportRoofOrFloorAsContainer(ExporterIFC exporterIFC,
                                                                Element element, GeometryElement geometry, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            // We support ExtrusionRoofs, FootPrintRoofs, and Floors only.
            bool elementIsRoof  = (element is ExtrusionRoof) || (element is FootPrintRoof);
            bool elementIsFloor = (element is Floor);

            if (!elementIsRoof && !elementIsFloor)
            {
                return(null);
            }

            string            subSlabType    = null;
            IFCExportInfoPair roofExportType = ExporterUtil.GetProductExportType(exporterIFC, element, out _);

            if (roofExportType.IsUnKnown)
            {
                IFCEntityType elementClassTypeEnum =
                    elementIsFloor ? IFCEntityType.IfcSlab: IFCEntityType.IfcRoof;
                roofExportType = new IFCExportInfoPair(elementClassTypeEnum, "");
            }
            else
            {
                if (elementIsFloor)
                {
                    subSlabType = "FLOOR";
                }
                else if (elementIsRoof)
                {
                    subSlabType = "ROOF";
                }
            }

            // Check the intended IFC entity or type name is in the exclude list specified in the UI
            if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(roofExportType.ExportType))
            {
                return(null);
            }

            Document doc = element.Document;

            using (SubTransaction tempPartTransaction = new SubTransaction(doc))
            {
                using (IFCTransaction transaction = new IFCTransaction(file))
                {
                    MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, element, productWrapper);
                    bool hasLayers = false;
                    if (layersetInfo.MaterialIds.Count > 1)
                    {
                        hasLayers = true;
                    }
                    bool exportByComponents = ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && hasLayers;

                    // Check for containment override
                    IFCAnyHandle overrideContainerHnd = null;
                    ElementId    overrideContainerId  = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd);

                    // We want to delay creating entity handles until as late as possible, so that if we abort the IFC transaction,
                    // we don't have to delete elements.  This is both for performance reasons and to potentially extend the number
                    // of projects that can be exported by reducing (a small amount) of waste.
                    IList <HostObjectSubcomponentInfo> hostObjectSubcomponents = null;
                    try
                    {
                        hostObjectSubcomponents = ExporterIFCUtils.ComputeSubcomponents(element as HostObject);
                    }
                    catch
                    {
                        return(null);
                    }

                    if (hostObjectSubcomponents == null)
                    {
                        return(null);
                    }

                    int numSubcomponents = hostObjectSubcomponents.Count;
                    if (numSubcomponents == 0 || (elementIsFloor && numSubcomponents == 1))
                    {
                        return(null);
                    }

                    using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd))
                    {
                        IFCAnyHandle localPlacement = setter.LocalPlacement;


                        IFCAnyHandle hostObjectHandle = null;
                        try
                        {
                            using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                            {
                                IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;
                                extrusionCreationData.SetLocalPlacement(localPlacement);
                                extrusionCreationData.ReuseLocalPlacement = true;

                                using (TransformSetter trfSetter = TransformSetter.Create())
                                {
                                    IList <GeometryObject> geometryList = new List <GeometryObject>();
                                    geometryList.Add(geometry);
                                    trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, extrusionCreationData);

                                    IFCAnyHandle prodRepHnd = null;

                                    string elementGUID = GUIDUtil.CreateGUID(element);

                                    hostObjectHandle = IFCInstanceExporter.CreateGenericIFCEntity(
                                        roofExportType, exporterIFC, element, elementGUID, ownerHistory,
                                        localPlacement, prodRepHnd);

                                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjectHandle))
                                    {
                                        return(null);
                                    }

                                    IList <IFCAnyHandle> elementHandles = new List <IFCAnyHandle>();
                                    elementHandles.Add(hostObjectHandle);

                                    // If element is floor, then the profile curve loop of hostObjectSubComponent is computed from the top face of the floor
                                    // else if element is roof, then the profile curve loop is taken from the bottom face of the roof instead
                                    XYZ extrusionDir = elementIsFloor ? new XYZ(0, 0, -1) : new XYZ(0, 0, 1);

                                    ElementId catId = CategoryUtil.GetSafeCategoryId(element);

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

                                    IList <CurveLoop> hostObjectOpeningLoops = new List <CurveLoop>();
                                    double            maximumScaledDepth     = 0.0;

                                    using (IFCExtrusionCreationData slabExtrusionCreationData = new IFCExtrusionCreationData())
                                    {
                                        slabExtrusionCreationData.SetLocalPlacement(extrusionCreationData.GetLocalPlacement());
                                        slabExtrusionCreationData.ReuseLocalPlacement = false;
                                        slabExtrusionCreationData.ForceOffset         = true;

                                        int loopNum         = 0;
                                        int subElementStart = elementIsRoof ? (int)IFCRoofSubElements.RoofSlabStart : (int)IFCSlabSubElements.SubSlabStart;

                                        foreach (HostObjectSubcomponentInfo hostObjectSubcomponent in hostObjectSubcomponents)
                                        {
                                            trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, slabExtrusionCreationData);
                                            Plane     plane = hostObjectSubcomponent.GetPlane();
                                            Transform lcs   = GeometryUtil.CreateTransformFromPlane(plane);

                                            IList <CurveLoop> curveLoops = new List <CurveLoop>();

                                            CurveLoop slabCurveLoop = hostObjectSubcomponent.GetCurveLoop();
                                            curveLoops.Add(slabCurveLoop);
                                            double slope                      = Math.Abs(plane.Normal.Z);
                                            double scaledDepth                = UnitUtil.ScaleLength(hostObjectSubcomponent.Depth);
                                            double scaledExtrusionDepth       = scaledDepth * slope;
                                            IList <IFCAnyHandle> shapeReps    = new List <IFCAnyHandle>();
                                            IFCAnyHandle         prodDefShape = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
                                            string       shapeIdent           = "Body";
                                            IFCAnyHandle contextOfItems       = exporterIFC.Get3DContextHandle(shapeIdent);
                                            string       representationType   = ShapeRepresentationType.SweptSolid.ToString();

                                            // Create representation items based on the layers
                                            // Because in this case, the Roof components are not derived from Parts, but by "splitting" geometry part that can be extruded,
                                            //    the creation of the Items for IFC4RV will be different by using "manual" split based on the layer thickness
                                            HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>();
                                            if (!exportByComponents)
                                            {
                                                IFCAnyHandle itemShapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, scaledExtrusionDepth, false);
                                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(itemShapeRep))
                                                {
                                                    productWrapper.ClearInternalHandleWrapperData(element);
                                                    return(null);
                                                }
                                                ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(element as HostObject);
                                                BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, false, itemShapeRep, matId);
                                                bodyItems.Add(itemShapeRep);
                                            }
                                            else
                                            {
                                                double scaleProj = extrusionDir.DotProduct(plane.Normal);
                                                foreach (MaterialLayerSetInfo.MaterialInfo matLayerInfo in layersetInfo.MaterialIds)
                                                {
                                                    double       itemExtrDepth = matLayerInfo.m_matWidth;
                                                    IFCAnyHandle itemShapeRep  = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, itemExtrDepth, false);
                                                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(itemShapeRep))
                                                    {
                                                        productWrapper.ClearInternalHandleWrapperData(element);
                                                        return(null);
                                                    }

                                                    BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, false, itemShapeRep, matLayerInfo.m_baseMatId);

                                                    bodyItems.Add(itemShapeRep);
                                                    RepresentationUtil.CreateRepForShapeAspect(exporterIFC, element, prodDefShape, representationType, matLayerInfo.m_layerName, itemShapeRep);

                                                    XYZ offset = new XYZ(0, 0, itemExtrDepth / scaleProj); // offset is calculated as extent in the direction of extrusion
                                                    lcs.Origin += offset;
                                                }
                                            }

                                            IFCAnyHandle shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null);
                                            shapeReps.Add(shapeRep);
                                            IFCAnyHandleUtil.SetAttribute(prodDefShape, "Representations", shapeReps);

                                            // Allow support for up to 256 named IfcSlab components, as defined in IFCSubElementEnums.cs.
                                            string slabGUID = (loopNum < 256) ? GUIDUtil.CreateSubElementGUID(element, subElementStart + loopNum) : GUIDUtil.CreateGUID();

                                            IFCAnyHandle slabPlacement = ExporterUtil.CreateLocalPlacement(file, slabExtrusionCreationData.GetLocalPlacement(), null);
                                            IFCAnyHandle slabHnd       = IFCInstanceExporter.CreateSlab(exporterIFC, element, slabGUID, ownerHistory,
                                                                                                        slabPlacement, prodDefShape, subSlabType);
                                            IFCExportInfoPair exportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, subSlabType);

                                            //slab quantities
                                            slabExtrusionCreationData.ScaledLength         = scaledExtrusionDepth;
                                            slabExtrusionCreationData.ScaledArea           = UnitUtil.ScaleArea(UnitUtil.ScaleArea(hostObjectSubcomponent.AreaOfCurveLoop));
                                            slabExtrusionCreationData.ScaledOuterPerimeter = UnitUtil.ScaleLength(curveLoops[0].GetExactLength());
                                            slabExtrusionCreationData.Slope = UnitUtil.ScaleAngle(MathUtil.SafeAcos(Math.Abs(slope)));

                                            IFCExportInfoPair slabRoofExportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, subSlabType);
                                            productWrapper.AddElement(null, slabHnd, setter, slabExtrusionCreationData, false, slabRoofExportType);

                                            // Create type
                                            IFCAnyHandle slabRoofTypeHnd = ExporterUtil.CreateGenericTypeFromElement(element, slabRoofExportType, exporterIFC.GetFile(), ownerHistory, subSlabType, productWrapper);
                                            ExporterCacheManager.TypeRelationsCache.Add(slabRoofTypeHnd, slabHnd);

                                            elementHandles.Add(slabHnd);
                                            slabHandles.Add(slabHnd);

                                            hostObjectOpeningLoops.Add(slabCurveLoop);
                                            maximumScaledDepth = Math.Max(maximumScaledDepth, scaledDepth);
                                            loopNum++;

                                            ExporterUtil.AddIntoComplexPropertyCache(slabHnd, layersetInfo);

                                            // Create material association here
                                            if (layersetInfo != null && !IFCAnyHandleUtil.IsNullOrHasNoValue(layersetInfo.MaterialLayerSetHandle))
                                            {
                                                CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, layersetInfo.MaterialLayerSetHandle);
                                            }
                                        }
                                    }

                                    productWrapper.AddElement(element, hostObjectHandle, setter, extrusionCreationData, true, roofExportType);

                                    ExporterUtil.RelateObjects(exporterIFC, null, hostObjectHandle, slabHandles);

                                    OpeningUtil.AddOpeningsToElement(exporterIFC, elementHandles, hostObjectOpeningLoops, element, null, maximumScaledDepth,
                                                                     null, setter, localPlacement, productWrapper);


                                    transaction.Commit();
                                    return(hostObjectHandle);
                                }
                            }
                        }
                        catch
                        {
                            // SOmething wrong with the above process, unable to create the extrusion data. Reset any internal handles that may have been partially created since they are not committed
                            productWrapper.ClearInternalHandleWrapperData(element);
                            return(null);
                        }
                        finally
                        {
                            exporterIFC.ClearFaceWithElementHandleMap();
                        }
                    }
                }
            }
        }
Пример #8
0
        // Augment the information from the internally created handles.  This includes:
        // 1. Adding material information
        // 2. Patching the presentation layer assignment.
        private static void AugmentHandleInformation(ExporterIFC exporterIFC, Element element,
                                                     GeometryElement geometryElement, ICollection <IFCAnyHandle> entityHandles)
        {
            // Not supported for IFC2x2.  Avoid computations below.
            if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2)
            {
                return;
            }

            ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement,
                                                                                    element);
            bool fixMaterialId = matId != ElementId.InvalidElementId;

            // We may have a situation where we have a presentation layer override, but the native code
            // doesn't have that functionality.  In this case, we will create an entry here, and
            // reconcile the difference during the end export operation.
            string ifcCADLayerOverride    = RepresentationUtil.GetPresentationLayerOverride(element);
            bool   fixIfcCADLayerOverride = !string.IsNullOrWhiteSpace(ifcCADLayerOverride);

            if (!fixIfcCADLayerOverride && !fixMaterialId)
            {
                return;
            }

            Document document = element.Document;

            foreach (IFCAnyHandle entityHandle in entityHandles)
            {
                IList <IFCAnyHandle> representations = null;
                if (IFCAnyHandleUtil.IsSubTypeOf(entityHandle, IFCEntityType.IfcProduct))
                {
                    representations = IFCAnyHandleUtil.GetProductRepresentations(entityHandle);
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(entityHandle, IFCEntityType.IfcProductDefinitionShape))
                {
                    representations = IFCAnyHandleUtil.GetRepresentations(entityHandle);
                }

                // Not currently supported.
                if (representations == null)
                {
                    continue;
                }

                foreach (IFCAnyHandle representation in representations)
                {
                    if (fixIfcCADLayerOverride)
                    {
                        ExporterCacheManager.PresentationLayerSetCache.AddRepresentationToLayer(ifcCADLayerOverride, representation);
                    }

                    if (fixMaterialId)
                    {
                        HashSet <IFCAnyHandle> repItemSet =
                            IFCAnyHandleUtil.GetAggregateInstanceAttribute <HashSet <IFCAnyHandle> >(representation, "Items");
                        foreach (IFCAnyHandle repItem in repItemSet)
                        {
                            BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, false, repItem, matId);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Exports a geometry element to boundary representation.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="exportBoundaryRep">True if to export boundary representation.</param>
        /// <param name="exportAsFacetation">True if to export the geometry as facetation.</param>
        /// <param name="bodyRep">Body representation.</param>
        /// <param name="boundaryRep">Boundary representation.</param>
        /// <returns>True if success, false if fail.</returns>
        public static bool ExportSurface(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                         bool exportBoundaryRep, bool exportAsFacetation, ref IFCAnyHandle bodyRep, ref IFCAnyHandle boundaryRep)
        {
            if (geometryElement == null)
            {
                return(false);
            }

            IFCGeometryInfo ifcGeomInfo = null;
            Document        doc         = element.Document;
            Plane           plane       = GeometryUtil.CreateDefaultPlane();
            XYZ             projDir     = new XYZ(0, 0, 1);
            double          eps         = UnitUtil.ScaleLength(doc.Application.VertexTolerance);

            IFCFile      file = exporterIFC.GetFile();
            IFCAnyHandle surface;
            ICollection <IFCAnyHandle> boundaryRepresentations = new List <IFCAnyHandle>();

            // Use tessellated geometry for surface in IFC Reference View
            if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)
            {
                BodyExporterOptions options = new BodyExporterOptions(false, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                surface = BodyExporter.ExportBodyAsTessellatedFaceSet(exporterIFC, element, options, geometryElement);
                if (element is Autodesk.Revit.DB.Architecture.TopographySurface)
                {
                    // TODO: need to find a good way to create the right boundary outline!
                    //IList<XYZ> boundaryPoints = (element as Autodesk.Revit.DB.Architecture.TopographySurface).GetBoundaryPoints();
                    //if (boundaryPoints != null && boundaryPoints.Count > 0)
                    //{
                    //   IList<IFCAnyHandle> coords = new List<IFCAnyHandle>();
                    //   foreach (XYZ point in boundaryPoints)
                    //   {
                    //      XYZ scPoint = ExporterIFCUtils.TransformAndScalePoint(exporterIFC, point);
                    //      IList<double> uvPoint = new List<double>();
                    //      // SInce the projection direction is on Z-axis, simply ignoring the Z-value will do for this. And also the Site reference will follow the WCS
                    //      uvPoint.Add(scPoint.X);
                    //      uvPoint.Add(scPoint.Y);
                    //      IFCAnyHandle ifcCartesianPoint = IFCInstanceExporter.CreateCartesianPoint(file, uvPoint);
                    //      coords.Add(ifcCartesianPoint);
                    //   }
                    //   if (coords.Count >= 2)
                    //   {
                    //      IFCAnyHandle boundaryLines = IFCInstanceExporter.CreatePolyline(file, coords);
                    //      boundaryRepresentations.Add(boundaryLines);
                    //   }
                    //}
                }
            }
            else
            {
                ifcGeomInfo = IFCGeometryInfo.CreateFaceGeometryInfo(exporterIFC, plane, projDir, eps, exportBoundaryRep);

                ExporterIFCUtils.CollectGeometryInfo(exporterIFC, ifcGeomInfo, geometryElement, XYZ.Zero, true);

                HashSet <IFCAnyHandle> faceSets = new HashSet <IFCAnyHandle>();
                IList <ICollection <IFCAnyHandle> > faceList = ifcGeomInfo.GetFaces();
                foreach (ICollection <IFCAnyHandle> faces in faceList)
                {
                    // no faces, don't complain.
                    if (faces.Count == 0)
                    {
                        continue;
                    }
                    HashSet <IFCAnyHandle> faceSet = new HashSet <IFCAnyHandle>(faces);
                    faceSets.Add(IFCInstanceExporter.CreateConnectedFaceSet(file, faceSet));
                }

                if (faceSets.Count == 0)
                {
                    return(false);
                }

                surface = IFCInstanceExporter.CreateFaceBasedSurfaceModel(file, faceSets);

                // Collect Footprint data
                boundaryRepresentations = ifcGeomInfo.GetRepresentations();
            }

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

            BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, doc, surface, BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element));

            ISet <IFCAnyHandle> surfaceItems = new HashSet <IFCAnyHandle>();

            surfaceItems.Add(surface);

            ElementId catId = CategoryUtil.GetSafeCategoryId(element);

            bodyRep = RepresentationUtil.CreateSurfaceRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), surfaceItems,
                                                          exportAsFacetation, bodyRep);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
            {
                return(false);
            }

            if (exportBoundaryRep && boundaryRepresentations.Count > 0)
            {
                HashSet <IFCAnyHandle> boundaryRepresentationSet = new HashSet <IFCAnyHandle>();
                boundaryRepresentationSet.UnionWith(boundaryRepresentations);
                boundaryRep = RepresentationUtil.CreateBoundaryRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("FootPrint"), boundaryRepresentationSet,
                                                                   boundaryRep);
            }

            return(true);
        }
Пример #10
0
        /// <summary>
        /// Creates openings if there is necessary.
        /// </summary>
        /// <param name="elementHandle">
        /// The element handle to create openings.
        /// </param>
        /// <param name="element">
        /// The element to create openings.
        /// </param>
        /// <param name="info">
        /// The extrusion datas.
        /// </param>
        /// <param name="extraParams">
        /// The extrusion creation data.
        /// </param>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="originalPlacement">
        /// The original placement handle.
        /// </param>
        /// <param name="setter">
        /// The IFCPlacementSetter.
        /// </param>
        /// <param name="wrapper">
        /// The IFCProductWrapper.
        /// </param>
        private static void CreateOpeningsIfNecessaryBase(IFCAnyHandle elementHandle, Element element, IList <IFCExtrusionData> info,
                                                          IFCExtrusionCreationData extraParams, ExporterIFC exporterIFC,
                                                          IFCAnyHandle originalPlacement, IFCPlacementSetter setter, IFCProductWrapper wrapper)
        {
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(elementHandle))
            {
                return;
            }

            int sz = info.Count;

            if (sz == 0)
            {
                return;
            }

            IFCFile   file       = exporterIFC.GetFile();
            ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);
            Document  document   = element.Document;

            string openingObjectType = "Opening";

            int openingNumber = 1;

            for (int curr = info.Count - 1; curr >= 0; curr--)
            {
                IFCAnyHandle extrusionHandle = ExtrusionExporter.CreateExtrudedSolidFromExtrusionData(exporterIFC, element, info[curr]);
                if (IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionHandle))
                {
                    continue;
                }

                IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document,
                                                                                       extrusionHandle, ElementId.InvalidElementId);

                HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>();
                bodyItems.Add(extrusionHandle);

                IFCAnyHandle         contextOfItems  = exporterIFC.Get3DContextHandle("Body");
                IFCAnyHandle         bodyRep         = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItems, null);
                IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();
                representations.Add(bodyRep);

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

                IFCAnyHandle openingPlacement = ExporterUtil.CopyLocalPlacement(file, originalPlacement);
                string       guid             = ExporterIFCUtils.CreateGUID();
                IFCAnyHandle ownerHistory     = exporterIFC.GetOwnerHistoryHandle();
                string       openingName      = NamingUtil.GetNameOverride(element, NamingUtil.CreateIFCName(exporterIFC, openingNumber++));
                string       elementId        = NamingUtil.CreateIFCElementId(element);
                IFCAnyHandle openingElement   = IFCInstanceExporter.CreateOpeningElement(file, guid, ownerHistory,
                                                                                         openingName, null, openingObjectType, openingPlacement, openingRep, elementId);
                wrapper.AddElement(openingElement, setter, extraParams, true);
                if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities && (extraParams != null))
                {
                    ExporterIFCUtils.CreateOpeningQuantities(exporterIFC, openingElement, extraParams);
                }

                string voidGuid = ExporterIFCUtils.CreateGUID();
                IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, elementHandle, openingElement);
            }
        }