/// <summary>
        /// Creates a SweptSolid, Brep, SolidModel or SurfaceModel product definition shape representation, based on the geometry and IFC version.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="bodyExporterOptions">The body exporter options.</param>
        /// <param name="extraReps">Extra representations (e.g. Axis, Boundary).  May be null.</param>
        /// <param name="extrusionCreationData">The extrusion creation data.</param>
        /// <param name="bodyData">The body data.</param>
        /// <returns>The handle.</returns>
        public static IFCAnyHandle CreateAppropriateProductDefinitionShape(ExporterIFC exporterIFC, Element element, ElementId categoryId,
            GeometryElement geometryElement, BodyExporterOptions bodyExporterOptions, IList<IFCAnyHandle> extraReps, 
            IFCExtrusionCreationData extrusionCreationData, out BodyData bodyData)
        {
            bodyData = null;
            SolidMeshGeometryInfo info = null;
            IList<GeometryObject> geometryList = new List<GeometryObject>();

            if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x2)
            {
                info = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement, Transform.Identity);
                IList<Mesh> meshes = info.GetMeshes();
                if (meshes.Count == 0)
                {
                    IList<Solid> solidList = info.GetSolids();
                    foreach (Solid solid in solidList)
                    {
                        geometryList.Add(solid);
                    }
                }
            }

            if (geometryList.Count == 0)
                geometryList.Add(geometryElement);
            else
                bodyExporterOptions.TryToExportAsExtrusion = true;
           
            bodyData = BodyExporter.ExportBody(exporterIFC, element, categoryId, ElementId.InvalidElementId, geometryList,
                bodyExporterOptions, extrusionCreationData);
            IFCAnyHandle bodyRep = bodyData.RepresentationHnd;
            List<IFCAnyHandle> bodyReps = new List<IFCAnyHandle>();
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
            {
                if (extrusionCreationData != null)
                    extrusionCreationData.ClearOpenings();
            }
            else
                bodyReps.Add(bodyRep);

            if (extraReps != null)
            {
                foreach (IFCAnyHandle hnd in extraReps)
                    bodyReps.Add(hnd);
            }

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

            if (bodyReps.Count == 0)
                return null;
            return IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, bodyReps);
        }
        /// <summary>
        /// Creates a Brep product definition shape representation.
        /// </summary>
        /// <param name="application">The Revit application object.</param>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="geometryObject">The geometry object.</param>
        /// <param name="extraReps">Extra representations (e.g. Axis, Footprint).  May be null.</param>
        /// <param name="options">The settings for how to export the body.</param>
        /// <param name="extrusionCreationData">The extrusion creation data.</param>
        /// <param name="bodyData">The body data.</param>
        /// <returns>The handle.</returns>
        public static IFCAnyHandle CreateBRepProductDefinitionShape(Autodesk.Revit.ApplicationServices.Application application,
                                                                    ExporterIFC exporterIFC, Element element, ElementId categoryId,
                                                                    IList <GeometryObject> geometryObjectIn, IList <IFCAnyHandle> extraReps,
                                                                    BodyExporterOptions bodyExporterOptions, IFCExtrusionCreationData extrusionCreationData, out BodyData bodyData)
        {
            bodyData = BodyExporter.ExportBody(application, exporterIFC, element, categoryId, geometryObjectIn,
                                               bodyExporterOptions, extrusionCreationData);
            IFCAnyHandle        bodyRep  = bodyData.RepresentationHnd;
            List <IFCAnyHandle> bodyReps = new List <IFCAnyHandle>();

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
            {
                if (extrusionCreationData != null)
                {
                    extrusionCreationData.ClearOpenings();
                }
            }
            else
            {
                bodyReps.Add(bodyRep);
            }

            if (extraReps != null)
            {
                foreach (IFCAnyHandle hnd in extraReps)
                {
                    bodyReps.Add(hnd);
                }
            }

            if (bodyReps.Count == 0)
            {
                return(null);
            }
            return(IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, bodyReps));
        }
Exemple #3
0
        /// <summary>
        /// Exports an element as IFC railing.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="element">
        /// The element to be exported.
        /// </param>
        /// <param name="geometryElement">
        /// The geometry element.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        public static void ExportRailing(ExporterIFC exporterIFC, Element element, GeometryElement geomElem, string ifcEnumType, ProductWrapper productWrapper)
        {
            // Check the intended IFC entity or type name is in the exclude list specified in the UI
            Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcRailing;
            if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
            {
                return;
            }

            ElementType elemType    = element.Document.GetElement(element.GetTypeId()) as ElementType;
            IFCFile     file        = exporterIFC.GetFile();
            Options     geomOptions = GeometryUtil.GetIFCExportGeometryOptions();

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        IFCAnyHandle           localPlacement = setter.LocalPlacement;
                        StairRampContainerInfo stairRampInfo  = null;
                        ElementId hostId     = GetStairOrRampHostId(exporterIFC, element as Railing);
                        Transform inverseTrf = Transform.Identity;
                        if (hostId != ElementId.InvalidElementId)
                        {
                            stairRampInfo = ExporterCacheManager.StairRampContainerInfoCache.GetStairRampContainerInfo(hostId);
                            IFCAnyHandle stairRampLocalPlacement = stairRampInfo.LocalPlacements[0];
                            Transform    relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(stairRampLocalPlacement, localPlacement);
                            inverseTrf = relTrf.Inverse;

                            IFCAnyHandle railingLocalPlacement = ExporterUtil.CreateLocalPlacement(file, stairRampLocalPlacement,
                                                                                                   inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX);
                            localPlacement = railingLocalPlacement;
                        }
                        ecData.SetLocalPlacement(localPlacement);

                        SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geomElem);
                        IList <Solid>         solids        = solidMeshInfo.GetSolids();
                        IList <Mesh>          meshes        = solidMeshInfo.GetMeshes();

                        Railing           railingElem   = element as Railing;
                        IList <ElementId> subElementIds = CollectSubElements(railingElem);

                        foreach (ElementId subElementId in subElementIds)
                        {
                            Element subElement = railingElem.Document.GetElement(subElementId);
                            if (subElement != null)
                            {
                                GeometryElement subElementGeom = GeometryUtil.GetOneLevelGeometryElement(subElement.get_Geometry(geomOptions), 0);

                                SolidMeshGeometryInfo subElementSolidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(subElementGeom);
                                IList <Solid>         subElementSolids        = subElementSolidMeshInfo.GetSolids();
                                IList <Mesh>          subElementMeshes        = subElementSolidMeshInfo.GetMeshes();
                                foreach (Solid subElementSolid in subElementSolids)
                                {
                                    solids.Add(subElementSolid);
                                }
                                foreach (Mesh subElementMesh in subElementMeshes)
                                {
                                    meshes.Add(subElementMesh);
                                }
                            }
                        }

                        ElementId           catId               = CategoryUtil.GetSafeCategoryId(element);
                        BodyData            bodyData            = null;
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium);
                        //bodyExporterOptions.UseGroupsIfPossible = true;
                        //bodyExporterOptions.UseMappedGeometriesIfPossible = true;

                        if (solids.Count > 0 || meshes.Count > 0)
                        {
                            bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, solids, meshes, bodyExporterOptions, ecData);
                        }
                        else
                        {
                            IList <GeometryObject> geomlist = new List <GeometryObject>();
                            geomlist.Add(geomElem);
                            bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, geomlist, bodyExporterOptions, ecData);
                        }

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

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

                        IList <GeometryObject> geomObjects = new List <GeometryObject>();
                        foreach (Solid solid in solids)
                        {
                            geomObjects.Add(solid);
                        }
                        foreach (Mesh mesh in meshes)
                        {
                            geomObjects.Add(mesh);
                        }

                        Transform boundingBoxTrf = (bodyData.OffsetTransform != null) ? bodyData.OffsetTransform.Inverse : Transform.Identity;
                        boundingBoxTrf = inverseTrf.Multiply(boundingBoxTrf);
                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geomObjects, boundingBoxTrf);
                        if (boundingBoxRep != null)
                        {
                            representations.Add(boundingBoxRep);
                        }

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

                        IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

                        string instanceGUID = GUIDUtil.CreateGUID(element);

                        //string railingType = IFCValidateEntry.GetValidIFCPredefinedType(element, ifcEnumType);

                        IFCAnyHandle railing = IFCInstanceExporter.CreateRailing(exporterIFC, element, instanceGUID, ownerHistory,
                                                                                 ecData.GetLocalPlacement(), prodRep, ifcEnumType);

                        bool associateToLevel = (hostId == ElementId.InvalidElementId);

                        productWrapper.AddElement(element, railing, setter, ecData, associateToLevel);
                        OpeningUtil.CreateOpeningsIfNecessary(railing, element, ecData, bodyData.OffsetTransform,
                                                              exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper);

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

                        // Create multi-story duplicates of this railing.
                        if (stairRampInfo != null)
                        {
                            stairRampInfo.AddComponent(0, railing);

                            List <IFCAnyHandle> stairHandles = stairRampInfo.StairOrRampHandles;
                            for (int ii = 1; ii < stairHandles.Count; ii++)
                            {
                                IFCAnyHandle railingLocalPlacement = stairRampInfo.LocalPlacements[ii];
                                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(railingLocalPlacement))
                                {
                                    IFCAnyHandle railingHndCopy = CopyRailingHandle(exporterIFC, element, catId, railingLocalPlacement, railing);
                                    stairRampInfo.AddComponent(ii, railingHndCopy);
                                    productWrapper.AddElement(element, railingHndCopy, (IFCLevelInfo)null, ecData, false);
                                    CategoryUtil.CreateMaterialAssociation(exporterIFC, railingHndCopy, bodyData.MaterialIds);
                                }
                            }

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

            Part part = partElement as Part;

            if (part == null)
            {
                return;
            }

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

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

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

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

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

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

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

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

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

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

            GeometryElement geometryElement = partElement.get_Geometry(options);

            if (geometryElement == null)
            {
                return;
            }

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

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

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

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

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

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

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

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

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

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

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

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

                        IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

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

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

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

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

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

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

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

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

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

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

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

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

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

                        transaction.Commit();
                    }
                }
            }
            finally
            {
                if (standalonePlacementSetter != null)
                {
                    standalonePlacementSetter.Dispose();
                }
            }
        }
Exemple #5
0
        /// <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,
                                  IFCExportInfoPair exportType, string ifcEnumType, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                // CQ_TODO: Clean up this code by at least factoring it out.

                // If we are exporting a duct segment, we may need to split it into parts by level. Create a list of ranges.
                IList <ElementId> levels = new List <ElementId>();
                IList <IFCRange>  ranges = new List <IFCRange>();

                // We will not split duct segments if the assemblyId is set, as we would like to keep the original duct segment
                // associated with the assembly, on the level of the assembly.
                if ((exportType.ExportType == IFCEntityType.IfcDuctSegmentType) &&
                    (ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting) &&
                    (element.AssemblyInstanceId == ElementId.InvalidElementId))
                {
                    LevelUtil.CreateSplitLevelRangesForElement(exporterIFC, exportType, element, out levels,
                                                               out ranges);
                }

                int numPartsToExport = ranges.Count;
                {
                    ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                    BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                    if (0 == numPartsToExport)
                    {
                        // Check for containment override
                        IFCAnyHandle overrideContainerHnd = null;
                        ElementId    overrideContainerId  = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd);

                        using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd))
                        {
                            IFCAnyHandle localPlacementToUse = setter.LocalPlacement;
                            BodyData     bodyData            = null;
                            using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                            {
                                extraParams.SetLocalPlacement(localPlacementToUse);
                                IFCAnyHandle productRepresentation =
                                    RepresentationUtil.CreateAppropriateProductDefinitionShape(
                                        exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, extraParams, out bodyData);
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(productRepresentation))
                                {
                                    extraParams.ClearOpenings();
                                    return(false);
                                }

                                ExportAsMappedItem(exporterIFC, element, file, exportType, ifcEnumType, extraParams,
                                                   setter, localPlacementToUse, productRepresentation,
                                                   productWrapper);
                            }
                        }
                    }
                    else
                    {
                        for (int ii = 0; ii < numPartsToExport; ii++)
                        {
                            // Check for containment override
                            IFCAnyHandle overrideContainerHnd = null;
                            ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd);

                            using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, levels[ii], overrideContainerHnd))
                            {
                                IFCAnyHandle localPlacementToUse = setter.LocalPlacement;

                                using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                                {
                                    SolidMeshGeometryInfo solidMeshCapsule =
                                        GeometryUtil.GetClippedSolidMeshGeometry(geometryElement, ranges[ii]);

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

                                    IList <GeometryObject> geomObjects =
                                        FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(element.Document,
                                                                                          exporterIFC, ref solids, ref polyMeshes);

                                    if (geomObjects.Count == 0 && (solids.Count > 0 || polyMeshes.Count > 0))
                                    {
                                        return(false);
                                    }

                                    bool tryToExportAsExtrusion = (!exporterIFC.ExportAs2x2 ||
                                                                   (exportType.ExportInstance == IFCEntityType.IfcColumn));

                                    if (exportType.ExportInstance == IFCEntityType.IfcColumn)
                                    {
                                        extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;
                                    }
                                    else
                                    {
                                        extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryXYZ;
                                    }

                                    BodyData bodyData = null;
                                    if (geomObjects.Count > 0)
                                    {
                                        bodyData = BodyExporter.ExportBody(exporterIFC, element, catId,
                                                                           ElementId.InvalidElementId, geomObjects,
                                                                           bodyExporterOptions, extraParams);
                                    }
                                    else
                                    {
                                        IList <GeometryObject> exportedGeometries = new List <GeometryObject>();
                                        exportedGeometries.Add(geometryElement);
                                        bodyData = BodyExporter.ExportBody(exporterIFC, element, catId,
                                                                           ElementId.InvalidElementId,
                                                                           exportedGeometries, bodyExporterOptions,
                                                                           extraParams);
                                    }

                                    List <IFCAnyHandle> bodyReps = new List <IFCAnyHandle>();
                                    bodyReps.Add(bodyData.RepresentationHnd);

                                    IFCAnyHandle productRepresentation =
                                        IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null,
                                                                                         null, bodyReps);
                                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(productRepresentation))
                                    {
                                        extraParams.ClearOpenings();
                                        return(false);
                                    }

                                    ExportAsMappedItem(exporterIFC, element, file, exportType, ifcEnumType,
                                                       extraParams, setter, localPlacementToUse,
                                                       productRepresentation, productWrapper);
                                }
                            }
                        }
                    }
                }

                tr.Commit();
            }
            return(true);
        }
        /// <summary>
        /// Exports a beam to IFC beam if it has an axis representation and only one Solid as its geometry, ideally as an extrusion, potentially with clippings and openings.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element to be exported.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <param name="dontExport">An output value that says that the element shouldn't be exported at all.</param>
        /// <returns>The created handle.</returns>
        /// <remarks>In the original implementation, the ExportBeam function would export each beam as its own individual geometry (that is, not use representation maps).
        /// For non-standard beams, this could result in massive IFC files.  Now, we use the ExportBeamAsStandardElement function and limit its scope, and instead
        /// resort to the standard FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem for more complicated objects categorized as beams.  This has the following pros and cons:
        /// Pro: possiblity for massively reduced file sizes for files containing repeated complex beam families
        /// Con: some beams that may have had an "Axis" representation before will no longer have them, although this possibility is minimized.
        /// Con: some beams that have 1 Solid and an axis, but that Solid will be heavily faceted, won't be helped by this improvement.
        /// It is intended that we phase out this routine entirely and instead teach ExportFamilyInstanceAsMappedItem how to sometimes export the Axis representation for beams.</remarks>
        public static IFCAnyHandle ExportBeamAsStandardElement(ExporterIFC exporterIFC,
                                                               Element element, GeometryElement geometryElement, ProductWrapper productWrapper, out bool dontExport)
        {
            dontExport = true;
            IList <GeometryObject> geomObjects = BeamGeometryToExport(exporterIFC, element, geometryElement, out dontExport);

            if (dontExport)
            {
                return(null);
            }

            IFCAnyHandle beam = null;
            IFCFile      file = exporterIFC.GetFile();

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                BeamAxisInfo axisInfo      = GetBeamAxisTransform(element);
                bool         canExportAxis = (axisInfo != null);

                Curve     curve         = canExportAxis ? axisInfo.Axis : null;
                XYZ       beamDirection = canExportAxis ? axisInfo.AxisDirection : null;
                Transform orientTrf     = canExportAxis ? axisInfo.LCSAsTransform : null;

                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, orientTrf))
                {
                    IFCAnyHandle localPlacement = setter.LocalPlacement;
                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(localPlacement);
                        if (canExportAxis && (orientTrf.BasisX != null))
                        {
                            extrusionCreationData.CustomAxis            = beamDirection;
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom;
                        }
                        else
                        {
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryXY;
                        }

                        ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                        // There may be an offset to make the local coordinate system
                        // be near the origin.  This offset will be used to move the axis to the new LCS.
                        Transform offsetTransform = null;

                        // The list of materials in the solids or meshes.
                        ICollection <ElementId> materialIds = null;

                        // The representation handle generated from one of the methods below.
                        BeamBodyAsExtrusionInfo extrusionInfo = CreateBeamGeometryAsExtrusion(exporterIFC, element, catId, geomObjects, axisInfo);
                        if (extrusionInfo != null && extrusionInfo.DontExport)
                        {
                            dontExport = true;
                            return(null);
                        }

                        IFCAnyHandle repHnd = (extrusionInfo != null) ? extrusionInfo.RepresentationHandle : null;

                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            materialIds = extrusionInfo.Materials;
                            extrusionCreationData.Slope = extrusionInfo.Slope;
                        }
                        else
                        {
                            // Here is where we limit the scope of how complex a case we will still try to export as a standard element.
                            // This is explicitly added so that many curved beams that can be represented by a reasonable facetation because of the
                            // SweptSolidExporter can still have an Axis representation.
                            BodyData bodyData = null;

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                            if (geomObjects != null && geomObjects.Count == 1 && geomObjects[0] is Solid)
                            {
                                bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId,
                                                                   geomObjects[0], bodyExporterOptions, extrusionCreationData);

                                repHnd          = bodyData.RepresentationHnd;
                                materialIds     = bodyData.MaterialIds;
                                offsetTransform = bodyData.OffsetTransform;
                            }
                        }

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            extrusionCreationData.ClearOpenings();
                            return(null);
                        }

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

                        IFCAnyHandle axisRep = CreateBeamAxis(exporterIFC, element, catId, axisInfo, offsetTransform);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisRep))
                        {
                            representations.Add(axisRep);
                        }
                        representations.Add(repHnd);

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

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

                        string instanceGUID        = GUIDUtil.CreateGUID(element);
                        string instanceName        = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceObjectType  = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element));
                        string instanceTag         = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));
                        string preDefinedType      = "BEAM"; // Default predefined type for Beam
                        preDefinedType = IFCValidateEntry.GetValidIFCType(element, preDefinedType);

                        beam = IFCInstanceExporter.CreateBeam(file, instanceGUID, ExporterCacheManager.OwnerHistoryHandle,
                                                              instanceName, instanceDescription, instanceObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, instanceTag, preDefinedType);

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

                        OpeningUtil.CreateOpeningsIfNecessary(beam, element, extrusionCreationData, offsetTransform, exporterIFC,
                                                              extrusionCreationData.GetLocalPlacement(), setter, productWrapper);

                        FamilyTypeInfo typeInfo = new FamilyTypeInfo();
                        typeInfo.ScaledDepth          = extrusionCreationData.ScaledLength;
                        typeInfo.ScaledArea           = extrusionCreationData.ScaledArea;
                        typeInfo.ScaledInnerPerimeter = extrusionCreationData.ScaledInnerPerimeter;
                        typeInfo.ScaledOuterPerimeter = extrusionCreationData.ScaledOuterPerimeter;
                        PropertyUtil.CreateBeamColumnBaseQuantities(exporterIFC, beam, element, typeInfo, null);

                        if (materialIds.Count != 0)
                        {
                            CategoryUtil.CreateMaterialAssociations(exporterIFC, beam, materialIds);
                        }

                        // Register the beam's IFC handle for later use by truss and beam system export.
                        ExporterCacheManager.ElementToHandleCache.Register(element.Id, beam);
                    }
                }

                transaction.Commit();
                return(beam);
            }
        }
Exemple #7
0
        /// <summary>
        /// Exports a gutter element.
        /// </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>
        public static void ExportGutter(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

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

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions();
                        IFCAnyHandle        bodyRep             = BodyExporter.ExportBody(exporterIFC, element, categoryId, ElementId.InvalidElementId,
                                                                                          geometryElement, bodyExporterOptions, ecData).RepresentationHnd;
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                        {
                            if (ecData != null)
                            {
                                ecData.ClearOpenings();
                            }
                            return;
                        }

                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                        string       originalTag  = NamingUtil.CreateIFCElementId(element);

                        // In Revit, we don't have a corresponding type, so we create one for every gutter.
                        IFCAnyHandle        origin      = ExporterUtil.CreateAxis2Placement3D(file);
                        IFCAnyHandle        repMap3dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyRep);
                        List <IFCAnyHandle> repMapList  = new List <IFCAnyHandle>();
                        repMapList.Add(repMap3dHnd);
                        string elementTypeName = NamingUtil.CreateIFCObjectName(exporterIFC, element);

                        string       typeGuid = GUIDUtil.CreateSubElementGUID(element, (int)IFCHostedSweepSubElements.PipeSegmentType);
                        IFCAnyHandle style    = IFCInstanceExporter.CreatePipeSegmentType(file, typeGuid, ownerHistory,
                                                                                          elementTypeName, null, null, null, repMapList, originalTag,
                                                                                          elementTypeName, IFCPipeSegmentType.Gutter);

                        List <IFCAnyHandle> representationMaps = GeometryUtil.GetRepresentationMaps(style);
                        IFCAnyHandle        mappedItem         = ExporterUtil.CreateDefaultMappedItem(file, representationMaps[0]);

                        ISet <IFCAnyHandle> representations = new HashSet <IFCAnyHandle>();
                        representations.Add(mappedItem);

                        IFCAnyHandle bodyMappedItemRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC,
                                                                                                    element, categoryId, exporterIFC.Get3DContextHandle("Body"), representations);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyMappedItemRep))
                        {
                            return;
                        }

                        List <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>();
                        shapeReps.Add(bodyMappedItemRep);

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

                        IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
                        IFCAnyHandle localPlacementToUse;
                        ElementId    roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse);
                        if (roomId == ElementId.InvalidElementId)
                        {
                            localPlacementToUse = ecData.GetLocalPlacement();
                        }

                        string guid        = GUIDUtil.CreateGUID(element);
                        string name        = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string description = NamingUtil.GetDescriptionOverride(element, null);
                        string objectType  = NamingUtil.GetObjectTypeOverride(element, elementTypeName);
                        string tag         = NamingUtil.GetTagOverride(element, originalTag);

                        IFCAnyHandle elemHnd = IFCInstanceExporter.CreateFlowSegment(file, guid,
                                                                                     ownerHistory, name, description, objectType, localPlacementToUse, prodRep, tag);

                        bool containedInSpace = (roomId != ElementId.InvalidElementId);
                        productWrapper.AddElement(element, elemHnd, setter.LevelInfo, ecData, !containedInSpace);

                        if (containedInSpace)
                        {
                            ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, elemHnd);
                        }

                        // Associate segment with type.
                        ExporterCacheManager.TypeRelationsCache.Add(style, elemHnd);

                        OpeningUtil.CreateOpeningsIfNecessary(elemHnd, element, ecData, null,
                                                              exporterIFC, localPlacementToUse, setter, productWrapper);
                    }

                    tr.Commit();
                }
            }
        }
        /// <summary>
        /// Exports an element as IFC railing.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="element">
        /// The element to be exported.
        /// </param>
        /// <param name="geometryElement">
        /// The geometry element.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        public static void ExportRailing(ExporterIFC exporterIFC, Element element, GeometryElement geomElem, string ifcEnumType, ProductWrapper productWrapper)
        {
            // Check the intended IFC entity or type name is in the exclude list specified in the UI
            Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcRailing;
            if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
            {
                return;
            }

            ElementType elemType    = element.Document.GetElement(element.GetTypeId()) as ElementType;
            IFCFile     file        = exporterIFC.GetFile();
            Options     geomOptions = GeometryUtil.GetIFCExportGeometryOptions();

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                // Check for containment override
                IFCAnyHandle overrideContainerHnd = null;
                ElementId    overrideContainerId  = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd);

                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        IFCAnyHandle           localPlacement = setter.LocalPlacement;
                        StairRampContainerInfo stairRampInfo  = null;
                        ElementId hostId     = GetStairOrRampHostId(exporterIFC, element as Railing);
                        Transform inverseTrf = Transform.Identity;
                        if (hostId != ElementId.InvalidElementId)
                        {
                            stairRampInfo = ExporterCacheManager.StairRampContainerInfoCache.GetStairRampContainerInfo(hostId);
                            IFCAnyHandle stairRampLocalPlacement = stairRampInfo.LocalPlacements[0];
                            Transform    relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(stairRampLocalPlacement, localPlacement);
                            inverseTrf = relTrf.Inverse;

                            IFCAnyHandle railingLocalPlacement = ExporterUtil.CreateLocalPlacement(file, stairRampLocalPlacement,
                                                                                                   inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX);
                            localPlacement = railingLocalPlacement;
                        }
                        ecData.SetLocalPlacement(localPlacement);

                        SolidMeshGeometryInfo  solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geomElem);
                        IList <Solid>          solids        = solidMeshInfo.GetSolids();
                        IList <Mesh>           meshes        = solidMeshInfo.GetMeshes();
                        IList <GeometryObject> gObjs         = FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(element.Document, exporterIFC, ref solids, ref meshes);

                        Railing           railingElem   = element as Railing;
                        IList <ElementId> subElementIds = CollectSubElements(railingElem);

                        foreach (ElementId subElementId in subElementIds)
                        {
                            Element subElement = railingElem.Document.GetElement(subElementId);
                            if (subElement != null)
                            {
                                GeometryElement allLevelsGeometry = subElement.get_Geometry(geomOptions);
                                var             oneLevelGeom      = GeometryUtil.GetOneLevelGeometryElement(allLevelsGeometry, 0);
                                GeometryElement subElementGeom    = oneLevelGeom.element;
                                // Get rail terminations geometry
                                List <GeometryElement> overallGeometry = GeometryUtil.GetAdditionalOneLevelGeometry(allLevelsGeometry, oneLevelGeom.symbolId);
                                overallGeometry.Add(subElementGeom);

                                foreach (GeometryElement subGeomentry in overallGeometry)
                                {
                                    SolidMeshGeometryInfo  subElementSolidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(subGeomentry);
                                    IList <Solid>          subElemSolids           = subElementSolidMeshInfo.GetSolids();
                                    IList <Mesh>           subElemMeshes           = subElementSolidMeshInfo.GetMeshes();
                                    IList <GeometryObject> partGObjs = FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(element.Document, exporterIFC, ref subElemSolids, ref subElemMeshes);

                                    foreach (Solid subElSolid in subElemSolids)
                                    {
                                        solids.Add(subElSolid);
                                    }
                                    foreach (Mesh subElMesh in subElemMeshes)
                                    {
                                        meshes.Add(subElMesh);
                                    }
                                }
                            }
                        }

                        ElementId           catId               = CategoryUtil.GetSafeCategoryId(element);
                        BodyData            bodyData            = null;
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium);

                        if (solids.Count > 0 || meshes.Count > 0)
                        {
                            bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, solids, meshes, bodyExporterOptions, ecData);
                        }
                        else
                        {
                            IList <GeometryObject> geomlist = new List <GeometryObject>();
                            geomlist.Add(geomElem);
                            bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, geomlist, bodyExporterOptions, ecData);
                        }

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

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

                        IList <GeometryObject> geomObjects = new List <GeometryObject>(solids);
                        foreach (Mesh mesh in meshes)
                        {
                            geomObjects.Add(mesh);
                        }

                        Transform boundingBoxTrf = (bodyData.OffsetTransform != null) ? bodyData.OffsetTransform.Inverse : Transform.Identity;
                        boundingBoxTrf = inverseTrf.Multiply(boundingBoxTrf);
                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geomObjects, boundingBoxTrf);
                        if (boundingBoxRep != null)
                        {
                            representations.Add(boundingBoxRep);
                        }

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

                        IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

                        string instanceGUID = GUIDUtil.CreateGUID(element);

                        IFCExportInfoPair exportInfo = ExporterUtil.GetProductExportType(exporterIFC, element, out ifcEnumType);

                        IFCAnyHandle railing = IFCInstanceExporter.CreateGenericIFCEntity(exportInfo, exporterIFC, element, instanceGUID, ownerHistory,
                                                                                          ecData.GetLocalPlacement(), prodRep);

                        bool associateToLevel = (hostId == ElementId.InvalidElementId);

                        productWrapper.AddElement(element, railing, setter, ecData, associateToLevel, exportInfo);
                        OpeningUtil.CreateOpeningsIfNecessary(railing, element, ecData, bodyData.OffsetTransform,
                                                              exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper);

                        IFCAnyHandle      singleMaterialOverrideHnd = null;
                        IList <ElementId> matIds       = null;
                        ElementId         defaultMatId = ElementId.InvalidElementId;
                        ElementId         matId        = CategoryUtil.GetBaseMaterialIdForElement(element);

                        // Get IfcSingleMaterialOverride to work for railing
                        singleMaterialOverrideHnd = ExporterUtil.GetSingleMaterial(exporterIFC, element, matId);
                        if (singleMaterialOverrideHnd != null)
                        {
                            matIds = new List <ElementId> {
                                matId
                            };
                        }
                        else
                        {
                            matIds       = bodyData.MaterialIds;
                            defaultMatId = matIds[0];

                            // Check if all the items are the same, then get the first material id
                            if (matIds.All(x => x == defaultMatId))
                            {
                                matIds = new List <ElementId> {
                                    defaultMatId
                                };
                            }
                        }

                        CategoryUtil.CreateMaterialAssociationWithShapeAspect(exporterIFC, element, railing, bodyData.RepresentationItemInfo);

                        // Create multi-story duplicates of this railing.
                        if (stairRampInfo != null)
                        {
                            stairRampInfo.AddComponent(0, railing);

                            List <IFCAnyHandle> stairHandles = stairRampInfo.StairOrRampHandles;
                            int levelCount = stairHandles.Count;

                            if (levelCount > 0 && railingElem != null)
                            {
                                Stairs stairs = railingElem.Document.GetElement(railingElem.HostId) as Stairs;
                                if ((stairs?.MultistoryStairsId ?? ElementId.InvalidElementId) != ElementId.InvalidElementId)
                                {
                                    // If the railing is hosted by stairs, don't use stairHandles.Count,
                                    // use ids (count) of levels the railing is placed on.
                                    ISet <ElementId> multistoryStairsPlacementLevels = railingElem.GetMultistoryStairsPlacementLevels();
                                    if (multistoryStairsPlacementLevels != null)
                                    {
                                        levelCount = multistoryStairsPlacementLevels.Count;
                                    }
                                }
                            }

                            for (int ii = 1; ii < levelCount; ii++)
                            {
                                IFCAnyHandle railingLocalPlacement = stairRampInfo.LocalPlacements[ii];
                                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(railingLocalPlacement))
                                {
                                    IFCAnyHandle railingHndCopy = CopyRailingHandle(exporterIFC, element, catId,
                                                                                    railingLocalPlacement, railing, ii);
                                    stairRampInfo.AddComponent(ii, railingHndCopy);
                                    productWrapper.AddElement(element, railingHndCopy, (IFCLevelInfo)null, ecData, false, exportInfo);
                                    CategoryUtil.CreateMaterialAssociationWithShapeAspect(exporterIFC, element, railingHndCopy, bodyData.RepresentationItemInfo);
                                }
                            }

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

            Part part = partElement as Part;

            if (part == null)
            {
                return;
            }

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

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

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

            ElementId partExportLevel = null;

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

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

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

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

            GeometryElement geometryElement = partElement.get_Geometry(options);

            if (geometryElement == null)
            {
                return;
            }

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

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

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

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

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

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

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

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

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

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

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

                        IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                        transaction.Commit();
                    }
                }
            }
            finally
            {
                if (standalonePlacementSetter != null)
                {
                    standalonePlacementSetter.Dispose();
                }
            }
        }
Exemple #10
0
        /// <summary>
        /// Exports a beam to IFC beam if it has an axis representation and only one Solid as its geometry, ideally as an extrusion, potentially with clippings and openings.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element to be exported.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <param name="dontExport">An output value that says that the element shouldn't be exported at all.</param>
        /// <returns>The created handle.</returns>
        /// <remarks>In the original implementation, the ExportBeam function would export each beam as its own individual geometry (that is, not use representation maps).
        /// For non-standard beams, this could result in massive IFC files.  Now, we use the ExportBeamAsStandardElement function and limit its scope, and instead
        /// resort to the standard FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem for more complicated objects categorized as beams.  This has the following pros and cons:
        /// Pro: possiblity for massively reduced file sizes for files containing repeated complex beam families
        /// Con: some beams that may have had an "Axis" representation before will no longer have them, although this possibility is minimized.
        /// Con: some beams that have 1 Solid and an axis, but that Solid will be heavily faceted, won't be helped by this improvement.
        /// It is intended that we phase out this routine entirely and instead teach ExportFamilyInstanceAsMappedItem how to sometimes export the Axis representation for beams.</remarks>
        public static IFCAnyHandle ExportBeamAsStandardElement(ExporterIFC exporterIFC,
                                                               Element element, IFCExportInfoPair exportType, GeometryElement geometryElement, ProductWrapper productWrapper, out bool dontExport)
        {
            dontExport = true;
            IList <GeometryObject> geomObjects = BeamGeometryToExport(exporterIFC, element, geometryElement, out dontExport);

            if (dontExport)
            {
                return(null);
            }

            IFCAnyHandle       beam = null;
            IFCFile            file = exporterIFC.GetFile();
            MaterialAndProfile materialAndProfile = null;
            IFCAnyHandle       materialProfileSet = null;

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                BeamAxisInfo axisInfo      = GetBeamAxisTransform(element);
                bool         canExportAxis = (axisInfo != null);

                Curve     curve         = canExportAxis ? axisInfo.Axis : null;
                XYZ       beamDirection = canExportAxis ? axisInfo.AxisDirection : null;
                Transform orientTrf     = canExportAxis ? axisInfo.LCSAsTransform : null;

                // Check for containment override
                IFCAnyHandle overrideContainerHnd = null;
                ElementId    overrideContainerId  = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd);
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, orientTrf, overrideContainerId, overrideContainerHnd))
                {
                    IFCAnyHandle localPlacement = setter.LocalPlacement;
                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(localPlacement);
                        if (canExportAxis && (orientTrf.BasisX != null))
                        {
                            extrusionCreationData.CustomAxis            = beamDirection;
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom;
                        }
                        else
                        {
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryXY;
                        }

                        ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                        // There may be an offset to make the local coordinate system
                        // be near the origin.  This offset will be used to move the axis to the new LCS.
                        Transform offsetTransform = null;

                        // The list of materials in the solids or meshes.
                        ICollection <ElementId> materialIds = null;

                        // If the beam is a FamilyInstance, and it uses transformed FamilySymbol geometry only, then
                        // let's only try to CreateBeamGeometryAsExtrusion unsuccesfully once.  Otherwise, we can spend a lot of time trying
                        // unsuccessfully to do so.
                        bool tryToCreateBeamGeometryAsExtrusion = true;

                        //bool useFamilySymbolGeometry = (element is FamilyInstance) ? !ExporterIFCUtils.UsesInstanceGeometry(element as FamilyInstance) : false;
                        bool      useFamilySymbolGeometry = (element is FamilyInstance) ? !GeometryUtil.UsesInstanceGeometry(element as FamilyInstance) : false;
                        ElementId beamTypeId = element.GetTypeId();
                        if (useFamilySymbolGeometry)
                        {
                            tryToCreateBeamGeometryAsExtrusion = !ExporterCacheManager.CanExportBeamGeometryAsExtrusionCache.ContainsKey(beamTypeId) ||
                                                                 ExporterCacheManager.CanExportBeamGeometryAsExtrusionCache[beamTypeId];
                        }

                        // The representation handle generated from one of the methods below.
                        BeamBodyAsExtrusionInfo extrusionInfo = null;
                        if (tryToCreateBeamGeometryAsExtrusion)
                        {
                            extrusionInfo = CreateBeamGeometryAsExtrusion(exporterIFC, element, catId, geomObjects, axisInfo);
                            if (useFamilySymbolGeometry)
                            {
                                ExporterCacheManager.CanExportBeamGeometryAsExtrusionCache[beamTypeId] = (extrusionInfo != null);
                            }
                        }

                        if (extrusionInfo != null && extrusionInfo.DontExport)
                        {
                            dontExport = true;
                            return(null);
                        }

                        IFCAnyHandle repHnd = (extrusionInfo != null) ? extrusionInfo.RepresentationHandle : null;

                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            materialIds = extrusionInfo.Materials;
                            extrusionCreationData.Slope = extrusionInfo.Slope;
                        }
                        else
                        {
                            // Here is where we limit the scope of how complex a case we will still try to export as a standard element.
                            // This is explicitly added so that many curved beams that can be represented by a reasonable facetation because of the
                            // SweptSolidExporter can still have an Axis representation.
                            BodyData bodyData = null;

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                            if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)
                            {
                                bodyExporterOptions.CollectMaterialAndProfile = false;
                            }
                            else
                            {
                                bodyExporterOptions.CollectMaterialAndProfile = true;
                            }

                            if (geomObjects != null && geomObjects.Count == 1 && geomObjects[0] is Solid)
                            {
                                bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId,
                                                                   geomObjects[0], bodyExporterOptions, extrusionCreationData);

                                repHnd      = bodyData.RepresentationHnd;
                                materialIds = bodyData.MaterialIds;
                                if (!bodyData.OffsetTransform.IsIdentity)
                                {
                                    offsetTransform = bodyData.OffsetTransform;
                                }
                                materialAndProfile = bodyData.MaterialAndProfile;
                            }
                        }

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            extrusionCreationData.ClearOpenings();
                            return(null);
                        }

                        IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();
                        IFCAnyHandle         axisRep         = CreateBeamAxis(exporterIFC, element, catId, axisInfo, offsetTransform);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisRep))
                        {
                            representations.Add(axisRep);
                        }
                        representations.Add(repHnd);

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

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

                        string instanceGUID = GUIDUtil.CreateGUID(element);
                        beam = IFCInstanceExporter.CreateBeam(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, extrusionCreationData.GetLocalPlacement(), prodRep, exportType.ValidatedPredefinedType);


                        IFCAnyHandle mpSetUsage;
                        if (materialProfileSet != null)
                        {
                            mpSetUsage = IFCInstanceExporter.CreateMaterialProfileSetUsage(file, materialProfileSet, null, null);
                        }

                        productWrapper.AddElement(element, beam, setter, extrusionCreationData, true, exportType);

                        ExportBeamType(exporterIFC, productWrapper, beam, element, exportType.ValidatedPredefinedType);

                        OpeningUtil.CreateOpeningsIfNecessary(beam, element, extrusionCreationData, offsetTransform, exporterIFC,
                                                              extrusionCreationData.GetLocalPlacement(), setter, productWrapper);

                        FamilyTypeInfo typeInfo = new FamilyTypeInfo();
                        typeInfo.ScaledDepth          = extrusionCreationData.ScaledLength;
                        typeInfo.ScaledArea           = extrusionCreationData.ScaledArea;
                        typeInfo.ScaledInnerPerimeter = extrusionCreationData.ScaledInnerPerimeter;
                        typeInfo.ScaledOuterPerimeter = extrusionCreationData.ScaledOuterPerimeter;
                        PropertyUtil.CreateBeamColumnBaseQuantities(exporterIFC, beam, element, typeInfo, null);

                        if (materialIds.Count != 0)
                        {
                            CategoryUtil.CreateMaterialAssociation(exporterIFC, beam, materialIds);
                        }

                        // Register the beam's IFC handle for later use by truss and beam system export.
                        ExporterCacheManager.ElementToHandleCache.Register(element.Id, beam, exportType);
                    }
                }

                transaction.Commit();
                return(beam);
            }
        }
        /// <summary>
        /// Exports a ramp to IfcRamp, without decomposing into separate runs and landings.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="ifcEnumType">The ramp type.</param>
        /// <param name="ramp">The ramp element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="numFlights">The number of flights for a multistory ramp.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportRamp(ExporterIFC exporterIFC, string ifcEnumType, Element ramp, GeometryElement geometryElement,
                                      int numFlights, ProductWrapper productWrapper)
        {
            if (ramp == null || geometryElement == null)
            {
                return;
            }

            // Check the intended IFC entity or type name is in the exclude list specified in the UI
            Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcRamp;
            if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
            {
                return;
            }

            // TESTING
            foreach (GeometryObject geomObj in geometryElement)
            {
                Visibility visibility = geomObj.Visibility;
            }

            IFCFile   file       = exporterIFC.GetFile();
            ElementId categoryId = CategoryUtil.GetSafeCategoryId(ramp);

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, ramp))
                {
                    IFCAnyHandle contextOfItemsFootPrint = exporterIFC.Get3DContextHandle("FootPrint");
                    IFCAnyHandle contextOfItemsAxis      = exporterIFC.Get3DContextHandle("Axis");

                    Transform    trf          = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, placementSetter.LocalPlacement);
                    IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

                    IList <(Solid body, Face largestTopFace)> rampFlights = null;
                    IList <Solid> landings = null;
                    if (IdentifyRampFlightAndLanding(geometryElement, out rampFlights, out landings))
                    {
                        string       rampGUID           = GUIDUtil.CreateGUID(ramp);
                        IFCAnyHandle rampLocalPlacement = placementSetter.LocalPlacement;
                        string       predefType         = "NOTDEFINED"; //Temporary
                        IFCAnyHandle rampContainerHnd   = IFCInstanceExporter.CreateRamp(exporterIFC, ramp, rampGUID, ownerHistory, rampLocalPlacement, null, predefType);
                        // Create appropriate type
                        IFCExportInfoPair exportType = new IFCExportInfoPair();
                        exportType.SetValueWithPair(IFCEntityType.IfcRamp);
                        IFCAnyHandle rampTypeHnd = ExporterUtil.CreateGenericTypeFromElement(ramp, exportType, exporterIFC.GetFile(), ownerHistory, predefType, productWrapper);
                        ExporterCacheManager.TypeRelationsCache.Add(rampTypeHnd, rampContainerHnd);
                        productWrapper.AddElement(ramp, rampContainerHnd, placementSetter.LevelInfo, null, true);

                        //Breakdown the Ramp into its components: RampFlights and Landings
                        int rampFlightIndex = 0;
                        int landingIndex    = 0;
                        HashSet <IFCAnyHandle> rampComponents = new HashSet <IFCAnyHandle>();
                        foreach ((Solid body, Face topFace)rampFlight in rampFlights)
                        {
                            using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                            {
                                ecData.AllowVerticalOffsetOfBReps = false;
                                ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, placementSetter.LocalPlacement, null));
                                ecData.ReuseLocalPlacement = true;
                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                                BodyData            bodyData            = BodyExporter.ExportBody(exporterIFC, ramp, categoryId, ElementId.InvalidElementId, rampFlight.body, bodyExporterOptions, ecData);

                                IFCAnyHandle bodyRep = bodyData.RepresentationHnd;
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                                {
                                    ecData.ClearOpenings();
                                    continue;
                                }
                                IList <IFCAnyHandle> reps = new List <IFCAnyHandle>();
                                reps.Add(bodyRep);

                                //if (!ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2)
                                //{
                                //   CreateWalkingLineAndFootprint(exporterIFC, run, bodyData, categoryId, trf, ref reps);
                                //}

                                Transform boundingBoxTrf         = (bodyData.OffsetTransform == null) ? Transform.Identity : bodyData.OffsetTransform.Inverse;
                                IList <GeometryObject> solidList = new List <GeometryObject>();
                                solidList.Add(rampFlight.body);
                                IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, solidList, boundingBoxTrf);
                                if (boundingBoxRep != null)
                                {
                                    reps.Add(boundingBoxRep);
                                }

                                IFCAnyHandle representation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, reps);

                                rampFlightIndex++;
                                string flightGUID     = GUIDUtil.CreateSubElementGUID(ramp, rampFlightIndex);
                                string origFlightName = IFCAnyHandleUtil.GetStringAttribute(rampContainerHnd, "Name") + " " + rampFlightIndex;
                                string flightName     = NamingUtil.GetOverrideStringValue(ramp, "IfcRampFlight.Name (" + rampFlightIndex + ")", origFlightName);

                                IFCAnyHandle flightLocalPlacement = ecData.GetLocalPlacement();
                                string       flightPredefType     = NamingUtil.GetOverrideStringValue(ramp, "IfcRampFlight.PredefinedType (" + rampFlightIndex + ")", null);

                                IFCAnyHandle rampFlightHnd = IFCInstanceExporter.CreateRampFlight(exporterIFC, null, flightGUID, ownerHistory, flightLocalPlacement,
                                                                                                  representation, flightPredefType);
                                IFCAnyHandleUtil.OverrideNameAttribute(rampFlightHnd, flightName);
                                rampComponents.Add(rampFlightHnd);

                                // Create type
                                IFCExportInfoPair flightEportType = new IFCExportInfoPair();
                                flightEportType.SetValueWithPair(IFCEntityType.IfcRampFlight);
                                IFCAnyHandle flightTypeHnd = IFCInstanceExporter.CreateGenericIFCType(flightEportType, null, exporterIFC.GetFile(), null, null, flightPredefType);
                                IFCAnyHandleUtil.OverrideNameAttribute(flightTypeHnd, flightName);
                                ExporterCacheManager.TypeRelationsCache.Add(flightTypeHnd, rampFlightHnd);

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

                                IFCAnyHandle psetRampFlightCommonHnd = CreatePSetRampFlightCommon(exporterIFC, file, ramp, rampFlightIndex, rampFlight.topFace);

                                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(psetRampFlightCommonHnd))
                                {
                                    HashSet <IFCAnyHandle> relatedObjects = new HashSet <IFCAnyHandle>()
                                    {
                                        rampFlightHnd
                                    };
                                    ExporterUtil.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, relatedObjects, psetRampFlightCommonHnd);
                                }
                            }
                        }
                        foreach (Solid landing in landings)
                        {
                            using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                            {
                                ecData.AllowVerticalOffsetOfBReps = false;
                                ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, placementSetter.LocalPlacement, null));
                                ecData.ReuseLocalPlacement = true;
                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                                BodyData            bodyData            = BodyExporter.ExportBody(exporterIFC, ramp, categoryId, ElementId.InvalidElementId, landing, bodyExporterOptions, ecData);

                                IFCAnyHandle bodyRep = bodyData.RepresentationHnd;
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                                {
                                    ecData.ClearOpenings();
                                    continue;
                                }
                                IList <IFCAnyHandle> reps = new List <IFCAnyHandle>();
                                reps.Add(bodyRep);

                                //if (!ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2)
                                //{
                                //   CreateWalkingLineAndFootprint(exporterIFC, run, bodyData, categoryId, trf, ref reps);
                                //}

                                Transform boundingBoxTrf         = (bodyData.OffsetTransform == null) ? Transform.Identity : bodyData.OffsetTransform.Inverse;
                                IList <GeometryObject> solidList = new List <GeometryObject>();
                                solidList.Add(landing);
                                IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, solidList, boundingBoxTrf);
                                if (boundingBoxRep != null)
                                {
                                    reps.Add(boundingBoxRep);
                                }

                                IFCAnyHandle representation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, reps);

                                landingIndex++;
                                string landingGUID     = GUIDUtil.CreateSubElementGUID(ramp, landingIndex);
                                string origLandingName = IFCAnyHandleUtil.GetStringAttribute(rampContainerHnd, "Name") + " " + landingIndex;
                                string landingName     = NamingUtil.GetOverrideStringValue(ramp, "IfcRampLanding.Name (" + landingIndex + ")", origLandingName);

                                IFCAnyHandle landingLocalPlacement = ecData.GetLocalPlacement();
                                string       landingPredefType     = "LANDING";

                                IFCAnyHandle rampLandingHnd = IFCInstanceExporter.CreateSlab(exporterIFC, ramp, landingGUID, ownerHistory, landingLocalPlacement,
                                                                                             representation, landingPredefType);
                                IFCAnyHandleUtil.OverrideNameAttribute(rampLandingHnd, landingName);
                                rampComponents.Add(rampLandingHnd);

                                // Create type
                                IFCExportInfoPair landingEportType = new IFCExportInfoPair();
                                landingEportType.SetValueWithPair(IFCEntityType.IfcSlab);
                                IFCAnyHandle landingTypeHnd = IFCInstanceExporter.CreateGenericIFCType(landingEportType, null, exporterIFC.GetFile(), null, null, landingPredefType);
                                IFCAnyHandleUtil.OverrideNameAttribute(landingTypeHnd, landingName);
                                ExporterCacheManager.TypeRelationsCache.Add(landingTypeHnd, rampLandingHnd);

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

                                IFCAnyHandle psetSlabCommonHnd = CreatePSetRampLandingCommon(exporterIFC, file, ramp, landingIndex);

                                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(psetSlabCommonHnd))
                                {
                                    HashSet <IFCAnyHandle> relatedObjects = new HashSet <IFCAnyHandle>()
                                    {
                                        rampLandingHnd
                                    };
                                    ExporterUtil.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, relatedObjects, psetSlabCommonHnd);
                                }
                            }
                        }

                        if (rampComponents.Count > 0)
                        {
                            IFCInstanceExporter.CreateRelAggregates(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, rampContainerHnd, rampComponents);
                        }
                    }
                    else
                    {
                        using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                        {
                            ecData.SetLocalPlacement(placementSetter.LocalPlacement);
                            ecData.ReuseLocalPlacement = false;

                            GeometryElement rampGeom = GeometryUtil.GetOneLevelGeometryElement(geometryElement, numFlights);

                            BodyData bodyData;

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                            IFCAnyHandle        representation      = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                                                 ramp, categoryId, rampGeom, bodyExporterOptions, null, ecData, out bodyData);

                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation))
                            {
                                ecData.ClearOpenings();
                                return;
                            }

                            string       containedRampGuid           = GUIDUtil.CreateSubElementGUID(ramp, (int)IFCRampSubElements.ContainedRamp);
                            IFCAnyHandle containedRampLocalPlacement = ExporterUtil.CreateLocalPlacement(file, ecData.GetLocalPlacement(), null);
                            string       rampType = GetIFCRampType(ifcEnumType);

                            List <IFCAnyHandle> components = new List <IFCAnyHandle>();
                            IList <IFCExtrusionCreationData> componentExtrusionData = new List <IFCExtrusionCreationData>();
                            IFCAnyHandle containedRampHnd = IFCInstanceExporter.CreateRamp(exporterIFC, ramp, containedRampGuid, ownerHistory,
                                                                                           containedRampLocalPlacement, representation, rampType);
                            components.Add(containedRampHnd);
                            componentExtrusionData.Add(ecData);
                            //productWrapper.AddElement(containedRampHnd, placementSetter.LevelInfo, ecData, false);
                            CategoryUtil.CreateMaterialAssociation(exporterIFC, containedRampHnd, bodyData.MaterialIds);

                            string       guid           = GUIDUtil.CreateGUID(ramp);
                            IFCAnyHandle localPlacement = ecData.GetLocalPlacement();

                            IFCAnyHandle rampHnd = IFCInstanceExporter.CreateRamp(exporterIFC, ramp, guid, ownerHistory,
                                                                                  localPlacement, null, rampType);

                            productWrapper.AddElement(ramp, rampHnd, placementSetter.LevelInfo, ecData, true);

                            StairRampContainerInfo stairRampInfo = new StairRampContainerInfo(rampHnd, components, localPlacement);
                            ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(ramp.Id, stairRampInfo);

                            ExportMultistoryRamp(exporterIFC, ramp, numFlights, rampHnd, components, componentExtrusionData, placementSetter,
                                                 productWrapper);
                        }
                    }
                }
                tr.Commit();
            }
        }
Exemple #12
0
        /// <summary>
        /// Exports an element as IFC railing.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="element">
        /// The element to be exported.
        /// </param>
        /// <param name="geometryElement">
        /// The geometry element.
        /// </param>
        /// <param name="productWrapper">
        /// The IFCProductWrapper.
        /// </param>
        public static void ExportRailing(ExporterIFC exporterIFC, Element element, GeometryElement geomElem, string ifcEnumType, IFCProductWrapper productWrapper)
        {
            ElementType elemType    = element.Document.GetElement(element.GetTypeId()) as ElementType;
            IFCFile     file        = exporterIFC.GetFile();
            Options     geomOptions = GeometryUtil.GetIFCExportGeometryOptions();

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(setter.GetPlacement());

                        SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSolidMeshGeometry(geomElem, Transform.Identity);
                        IList <Solid>         solids        = solidMeshInfo.GetSolids();
                        IList <Mesh>          meshes        = solidMeshInfo.GetMeshes();

                        Railing           railingElem   = element as Railing;
                        IList <ElementId> subElementIds = CollectSubElements(railingElem);

                        foreach (ElementId subElementId in subElementIds)
                        {
                            Element subElement = railingElem.Document.GetElement(subElementId);
                            if (subElement != null)
                            {
                                GeometryElement subElementGeom = GeometryUtil.GetOneLevelGeometryElement(subElement.get_Geometry(geomOptions));

                                SolidMeshGeometryInfo subElementSolidMeshInfo = GeometryUtil.GetSolidMeshGeometry(subElementGeom, Transform.Identity);
                                IList <Solid>         subElementSolids        = subElementSolidMeshInfo.GetSolids();
                                IList <Mesh>          subElementMeshes        = subElementSolidMeshInfo.GetMeshes();
                                foreach (Solid subElementSolid in subElementSolids)
                                {
                                    solids.Add(subElementSolid);
                                }
                                foreach (Mesh subElementMesh in subElementMeshes)
                                {
                                    meshes.Add(subElementMesh);
                                }
                            }
                        }

                        ElementId           catId               = CategoryUtil.GetSafeCategoryId(element);
                        BodyData            bodyData            = null;
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        //bodyExporterOptions.UseGroupsIfPossible = true;
                        //bodyExporterOptions.UseMappedGeometriesIfPossible = true;
                        bodyExporterOptions.TessellationLevel = BodyExporterOptions.BodyTessellationLevel.Coarse;

                        if (solids.Count > 0 || meshes.Count > 0)
                        {
                            bodyData = BodyExporter.ExportBody(element.Document.Application, exporterIFC, element, catId, solids, meshes, bodyExporterOptions, ecData);
                        }
                        else
                        {
                            IList <GeometryObject> geomlist = new List <GeometryObject>();
                            geomlist.Add(geomElem);
                            bodyData = BodyExporter.ExportBody(element.Document.Application, exporterIFC, element, catId, geomlist, bodyExporterOptions, ecData);
                        }

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

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

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

                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

                        string instanceGUID                = ExporterIFCUtils.CreateGUID(element);
                        string origInstanceName            = exporterIFC.GetName();
                        string instanceName                = NamingUtil.GetNameOverride(element, origInstanceName);
                        string instanceDescription         = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceObjectType          = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName());
                        string instanceElemId              = NamingUtil.CreateIFCElementId(element);
                        Toolkit.IFCRailingType railingType = GetIFCRailingType(element, ifcEnumType);

                        IFCAnyHandle railing = IFCInstanceExporter.CreateRailing(file, instanceGUID, ownerHistory,
                                                                                 instanceName, instanceDescription, instanceObjectType, ecData.GetLocalPlacement(),
                                                                                 prodRep, instanceElemId, railingType);

                        ElementId hostId           = GetStairOrRampHostId(exporterIFC, element as Railing);
                        bool      associateToLevel = (hostId == ElementId.InvalidElementId) && LevelUtil.AssociateElementToLevel(element);

                        productWrapper.AddElement(railing, setter, ecData, associateToLevel);
                        OpeningUtil.CreateOpeningsIfNecessary(railing, element, ecData, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper);

                        CategoryUtil.CreateMaterialAssociations(element.Document, exporterIFC, railing, bodyData.MaterialIds);

                        // Create multi-story duplicates of this railing.
                        if (hostId != ElementId.InvalidElementId)
                        {
                            StairRampContainerInfo stairRampInfo = ExporterCacheManager.StairRampContainerInfoCache.GetStairRampContainerInfo(hostId);
                            stairRampInfo.AddComponent(0, railing);

                            List <IFCAnyHandle> stairHandles = stairRampInfo.StairOrRampHandles;
                            for (int ii = 1; ii < stairHandles.Count; ii++)
                            {
                                IFCAnyHandle railingLocalPlacement = stairRampInfo.LocalPlacements[ii];
                                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(railingLocalPlacement))
                                {
                                    IFCAnyHandle railingHndCopy = CopyRailingHandle(exporterIFC, element, catId, railingLocalPlacement, railing);
                                    stairRampInfo.AddComponent(ii, railingHndCopy);
                                    productWrapper.AddElement(railingHndCopy, (IFCLevelInfo)null, ecData, false);
                                    CategoryUtil.CreateMaterialAssociations(element.Document, exporterIFC, railingHndCopy, bodyData.MaterialIds);
                                }
                            }

                            ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(hostId, stairRampInfo);
                        }

                        PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper);
                    }
                    transaction.Commit();
                }
            }
        }
Exemple #13
0
        /// <summary>
        /// Exports a gutter element.
        /// </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 IFCProductWrapper.</param>
        public static void ExportGutter(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, IFCProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(setter.GetPlacement());

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions();
                        IFCAnyHandle        bodyRep             = BodyExporter.ExportBody(element.Document.Application, exporterIFC, element, categoryId,
                                                                                          geometryElement, bodyExporterOptions, ecData).RepresentationHnd;
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                        {
                            if (ecData != null)
                            {
                                ecData.ClearOpenings();
                            }
                            return;
                        }

                        IFCAnyHandle        origin      = ExporterUtil.CreateAxis2Placement3D(file);
                        IFCAnyHandle        repMap3dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyRep);
                        List <IFCAnyHandle> repMapList  = new List <IFCAnyHandle>();
                        repMapList.Add(repMap3dHnd);
                        string       elementTypeName = NamingUtil.CreateIFCObjectName(exporterIFC, element);
                        IFCAnyHandle style           = IFCInstanceExporter.CreatePipeSegmentType(file, ExporterIFCUtils.CreateGUID(element), exporterIFC.GetOwnerHistoryHandle(),
                                                                                                 elementTypeName, null, null, null, repMapList, NamingUtil.CreateIFCElementId(element), elementTypeName, IFCPipeSegmentType.Gutter);


                        List <IFCAnyHandle> representationMaps = GeometryUtil.GetRepresentationMaps(style);
                        IFCAnyHandle        mappedItem         = ExporterUtil.CreateDefaultMappedItem(file, representationMaps[0]);

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

                        IFCAnyHandle bodyMappedItemRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC,
                                                                                                    element, categoryId, exporterIFC.Get3DContextHandle("Body"), representations);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyMappedItemRep))
                        {
                            return;
                        }

                        List <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>();
                        shapeReps.Add(bodyMappedItemRep);

                        IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
                        IFCAnyHandle localPlacementToUse;
                        ElementId    roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse);
                        if (roomId == ElementId.InvalidElementId)
                        {
                            localPlacementToUse = ecData.GetLocalPlacement();
                        }
                        string       name        = NamingUtil.GetNameOverride(element, NamingUtil.CreateIFCName(exporterIFC, -1));
                        string       description = NamingUtil.GetDescriptionOverride(element, null);
                        string       objectType  = NamingUtil.GetObjectTypeOverride(element, elementTypeName);
                        IFCAnyHandle elemHnd     = IFCInstanceExporter.CreateFlowSegment(file, ExporterIFCUtils.CreateGUID(element),
                                                                                         exporterIFC.GetOwnerHistoryHandle(), name, description, objectType, localPlacementToUse, prodRep,
                                                                                         NamingUtil.CreateIFCElementId(element));

                        if (roomId == ElementId.InvalidElementId)
                        {
                            productWrapper.AddElement(elemHnd, setter.GetLevelInfo(), ecData, true);
                        }
                        else
                        {
                            exporterIFC.RelateSpatialElement(roomId, elemHnd);
                            productWrapper.AddElement(elemHnd, setter.GetLevelInfo(), ecData, false);
                        }

                        OpeningUtil.CreateOpeningsIfNecessary(elemHnd, element, ecData, exporterIFC,
                                                              localPlacementToUse, setter, productWrapper);
                    }

                    tr.Commit();
                }
            }
        }
Exemple #14
0
        /// <summary>
        /// Exports a Rebar to IFC ReinforcingMesh.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="element">
        /// The element to be exported.
        /// </param>
        /// <param name="productWrapper">
        /// The IFCProductWrapper.
        /// </param>
        public static void ExportRebar(ExporterIFC exporterIFC,
                                       Rebar element, Autodesk.Revit.DB.View filterView, IFCProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element))
                {
                    GeometryElement rebarGeometry = ExporterIFCUtils.GetRebarGeometry(element, filterView);

                    // only options are: Not Export, BuildingElementProxy, or ReinforcingBar/Mesh, depending on layout.
                    // Not Export is handled previously, and ReinforcingBar vs Mesh will be determined below.
                    string        ifcEnumType;
                    IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, element, out ifcEnumType);

                    if (exportType == IFCExportType.ExportBuildingElementProxy)
                    {
                        if (rebarGeometry != null)
                        {
                            ProxyElementExporter.ExportBuildingElementProxy(exporterIFC, element, rebarGeometry, productWrapper);
                            transaction.Commit();
                        }
                        return;
                    }

                    IFCAnyHandle prodRep = null;
                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(setter.GetPlacement());

                        if (rebarGeometry != null)
                        {
                            ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                            prodRep = BodyExporter.ExportBody(element.Document.Application, exporterIFC, element, categoryId, rebarGeometry, bodyExporterOptions,
                                                              extrusionCreationData).RepresentationHnd;
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep))
                            {
                                extrusionCreationData.ClearOpenings();
                            }
                        }

                        double scale = exporterIFC.LinearScale;

                        double barLength = element.TotalLength * scale;
                        if (MathUtil.IsAlmostZero(barLength))
                        {
                            return;
                        }

                        int quantity = element.Quantity;
                        if (quantity < 1)
                        {
                            return;
                        }

                        ElementId    typeId      = element.GetTypeId();
                        RebarBarType elementType = element.Document.GetElement(element.GetTypeId()) as RebarBarType;
                        double       diameter    = elementType == null ? 1.0 / 12.0 : elementType.BarDiameter;
                        double       longitudinalBarNominalDiameter  = diameter * scale;
                        double       longitudinalBarCrossSectionArea = (element.Volume * scale * scale * scale) / barLength;

                        string       steelGradeOpt = null;
                        IFCAnyHandle elemHnd       = null;

                        string rebarGUID        = ExporterIFCUtils.CreateGUID(element);
                        string origRebarName    = exporterIFC.GetName();
                        string rebarName        = NamingUtil.GetNameOverride(element, origRebarName);
                        string rebarDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string rebarObjectType  = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element));
                        string rebarElemId      = NamingUtil.CreateIFCElementId(element);

                        if (element.LayoutRule == RebarLayoutRule.Single || (quantity == 1))
                        {
                            IFCReinforcingBarRole role = IFCReinforcingBarRole.NotDefined;
                            elemHnd = IFCInstanceExporter.CreateReinforcingBar(file, rebarGUID, exporterIFC.GetOwnerHistoryHandle(),
                                                                               rebarName, rebarDescription, rebarObjectType, extrusionCreationData.GetLocalPlacement(),
                                                                               prodRep, rebarElemId, steelGradeOpt, longitudinalBarNominalDiameter, longitudinalBarCrossSectionArea,
                                                                               barLength, role, null);
                        }
                        else
                        {
                            double meshLength;
                            double longitudinalBarSpacing;
                            double val = element.ArrayLength * scale;

                            if (element.LayoutRule == RebarLayoutRule.NumberWithSpacing)
                            {
                                longitudinalBarSpacing = val;
                                meshLength             = val * (quantity - 1);
                            }
                            else
                            {
                                meshLength             = val;
                                longitudinalBarSpacing = val / (quantity - 1);
                            }

                            double meshWidth = diameter * scale; // array is in one direction only.
                            double transverseBarNominalDiameter  = longitudinalBarNominalDiameter;
                            double transverseBarCrossSectionArea = longitudinalBarCrossSectionArea;
                            double transverseBarSpacing          = longitudinalBarSpacing;

                            elemHnd = IFCInstanceExporter.CreateReinforcingMesh(file, rebarGUID,
                                                                                exporterIFC.GetOwnerHistoryHandle(), rebarName,
                                                                                rebarDescription, rebarObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, rebarElemId,
                                                                                steelGradeOpt, meshLength, meshWidth, longitudinalBarNominalDiameter,
                                                                                transverseBarNominalDiameter, longitudinalBarCrossSectionArea,
                                                                                transverseBarCrossSectionArea, longitudinalBarSpacing,
                                                                                transverseBarSpacing);
                        }

                        productWrapper.AddElement(elemHnd, setter.GetLevelInfo(), extrusionCreationData, true);

                        PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper);
                    }
                }
                transaction.Commit();
            }
        }
        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);
        }
        /// <summary>
        /// Exports a gutter element.
        /// </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>
        public static void ExportGutter(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            // Check the intended IFC entity or type name is in the exclude list specified in the UI
            Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcPipeSegmentType;
            if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                // Check for containment override
                IFCAnyHandle overrideContainerHnd = null;
                ElementId    overrideContainerId  = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd);

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

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                        IFCAnyHandle        bodyRep             = BodyExporter.ExportBody(exporterIFC, element, categoryId, ElementId.InvalidElementId,
                                                                                          geometryElement, bodyExporterOptions, ecData).RepresentationHnd;
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                        {
                            if (ecData != null)
                            {
                                ecData.ClearOpenings();
                            }
                            return;
                        }
                        string originalTag = NamingUtil.CreateIFCElementId(element);

                        // In Revit, we don't have a corresponding type, so we create one for every gutter.
                        IFCAnyHandle        origin      = ExporterUtil.CreateAxis2Placement3D(file);
                        IFCAnyHandle        repMap3dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyRep);
                        List <IFCAnyHandle> repMapList  = new List <IFCAnyHandle>();
                        repMapList.Add(repMap3dHnd);
                        string elementTypeName = NamingUtil.CreateIFCObjectName(exporterIFC, element);

                        string       typeGuid = GUIDUtil.CreateSubElementGUID(element, (int)IFCHostedSweepSubElements.PipeSegmentType);
                        IFCAnyHandle style    = IFCInstanceExporter.CreatePipeSegmentType(file, null, null, repMapList, IFCPipeSegmentType.Gutter);
                        IFCAnyHandleUtil.OverrideNameAttribute(style, elementTypeName);
                        IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcPipeSegmentType, IFCPipeSegmentType.Gutter.ToString());

                        IFCAnyHandleUtil.SetAttribute(style, "Tag", originalTag);
                        ExporterUtil.SetGlobalId(style, typeGuid);
                        IFCAnyHandleUtil.SetAttribute(style, "ElementType", elementTypeName);

                        List <IFCAnyHandle> representationMaps = GeometryUtil.GetRepresentationMaps(style);
                        IFCAnyHandle        mappedItem         = ExporterUtil.CreateDefaultMappedItem(file, representationMaps[0]);

                        ISet <IFCAnyHandle> representations = new HashSet <IFCAnyHandle>();
                        representations.Add(mappedItem);

                        IFCAnyHandle bodyMappedItemRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC,
                                                                                                    element, categoryId, exporterIFC.Get3DContextHandle("Body"), representations);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyMappedItemRep))
                        {
                            return;
                        }

                        List <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>();
                        shapeReps.Add(bodyMappedItemRep);

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

                        IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
                        IFCAnyHandle localPlacementToUse;
                        ElementId    roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse);
                        if (roomId == ElementId.InvalidElementId)
                        {
                            localPlacementToUse = ecData.GetLocalPlacement();
                        }

                        string guid = GUIDUtil.CreateGUID(element);

                        IFCAnyHandle elemHnd = IFCInstanceExporter.CreateFlowSegment(exporterIFC, element, guid,
                                                                                     ExporterCacheManager.OwnerHistoryHandle, localPlacementToUse, prodRep);

                        bool containedInSpace = (roomId != ElementId.InvalidElementId);
                        productWrapper.AddElement(element, elemHnd, setter.LevelInfo, ecData, !containedInSpace, exportInfo);

                        if (containedInSpace)
                        {
                            ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, elemHnd);
                        }

                        // Associate segment with type.
                        ExporterCacheManager.TypeRelationsCache.Add(style, elemHnd);

                        OpeningUtil.CreateOpeningsIfNecessary(elemHnd, element, ecData, null,
                                                              exporterIFC, localPlacementToUse, setter, productWrapper);
                    }

                    tr.Commit();
                }
            }
        }
        /// <summary>
        /// Exports a Rebar Coupler,
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="coupler">The RebarCoupler element.</param>
        /// <param name="productWrapper">The product wrapper.</param>
        public static void ExportCoupler(ExporterIFC exporterIFC, RebarCoupler coupler, ProductWrapper productWrapper)
        {
            if (coupler == null)
            {
                return;
            }

            FamilySymbol familySymbol = ExporterCacheManager.Document.GetElement(coupler.GetTypeId()) as FamilySymbol;

            if (familySymbol == null)
            {
                return;
            }

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

            ElementId categoryId = CategoryUtil.GetSafeCategoryId(coupler);

            IFCFile           file         = exporterIFC.GetFile();
            IFCAnyHandle      ownerHistory = ExporterCacheManager.OwnerHistoryHandle;
            Options           options      = GeometryUtil.GetIFCExportGeometryOptions();;
            string            ifcEnumType;
            IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, coupler, out ifcEnumType);

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                FamilyTypeInfo currentTypeInfo = ExporterCacheManager.FamilySymbolToTypeInfoCache.Find(coupler.GetTypeId(), false, exportType.ExportType);
                bool           found           = currentTypeInfo.IsValid();
                if (!found)
                {
                    string typeObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, familySymbol);

                    HashSet <IFCAnyHandle> propertySetsOpt = new HashSet <IFCAnyHandle>();

                    GeometryElement exportGeometry = familySymbol.get_Geometry(options);

                    BodyData            bodyData            = null;
                    BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                    bodyData = BodyExporter.ExportBody(exporterIFC, coupler, categoryId, ElementId.InvalidElementId, exportGeometry, bodyExporterOptions, null);

                    List <IFCAnyHandle> repMap = new List <IFCAnyHandle>();
                    IFCAnyHandle        origin = ExporterUtil.CreateAxis2Placement3D(file);;
                    repMap.Add(IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyData.RepresentationHnd));

                    IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, propertySetsOpt, repMap, coupler, familySymbol);

                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle))
                    {
                        string applicableOccurrence = NamingUtil.GetObjectTypeOverride(familySymbol, typeObjectType);
                        if (!string.IsNullOrEmpty(applicableOccurrence))
                        {
                            IFCAnyHandleUtil.SetAttribute(styleHandle, "ApplicableOccurrence", applicableOccurrence);
                        }
                        currentTypeInfo.Style = styleHandle;
                        ExporterCacheManager.FamilySymbolToTypeInfoCache.Register(coupler.GetTypeId(), false, exportType.ExportType, currentTypeInfo);
                    }
                }

                int nCouplerQuantity = coupler.GetCouplerQuantity();
                if (nCouplerQuantity <= 0)
                {
                    return;
                }

                ISet <IFCAnyHandle> createdRebarCouplerHandles = new HashSet <IFCAnyHandle>();
                string origInstanceName = NamingUtil.GetNameOverride(coupler, NamingUtil.GetIFCName(coupler));

                for (int idx = 0; idx < nCouplerQuantity; idx++)
                {
                    string instanceGUID = GUIDUtil.CreateSubElementGUID(coupler, idx);

                    IFCAnyHandle style = currentTypeInfo.Style;
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(style))
                    {
                        return;
                    }

                    IList <IFCAnyHandle> repMapList = GeometryUtil.GetRepresentationMaps(style);
                    if (repMapList == null)
                    {
                        return;
                    }
                    if (repMapList.Count == 0)
                    {
                        return;
                    }

                    IList <IFCAnyHandle> shapeReps        = new List <IFCAnyHandle>();
                    IFCAnyHandle         contextOfItems3d = exporterIFC.Get3DContextHandle("Body");
                    ISet <IFCAnyHandle>  representations  = new HashSet <IFCAnyHandle>();
                    representations.Add(ExporterUtil.CreateDefaultMappedItem(file, repMapList[0], XYZ.Zero));
                    IFCAnyHandle shapeRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, coupler, categoryId, contextOfItems3d, representations);
                    shapeReps.Add(shapeRep);

                    IFCAnyHandle productRepresentation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, shapeReps);

                    Transform trf = coupler.GetCouplerPositionTransform(idx);

                    using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, coupler, trf, null))
                    {
                        IFCAnyHandle      instanceHandle     = null;
                        IFCExportInfoPair exportMechFastener = new IFCExportInfoPair();
                        exportMechFastener.SetValueWithPair(IFCEntityType.IfcMechanicalFastener);
                        instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportMechFastener, exporterIFC, coupler, instanceGUID, ownerHistory,
                                                                                    setter.LocalPlacement, productRepresentation);
                        string instanceName = NamingUtil.GetNameOverride(instanceHandle, coupler, origInstanceName + ": " + idx);
                        IFCAnyHandleUtil.SetAttribute(instanceHandle, "Name", instanceName);

                        if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                        {
                            // In IFC4 NominalDiameter and NominalLength attributes have been deprecated. PredefinedType attribute was added.
                            IFCAnyHandleUtil.SetAttribute(instanceHandle, "PredefinedType", Revit.IFC.Export.Toolkit.IFC4.IFCMechanicalFastenerType.USERDEFINED);
                        }
                        else
                        {
                            IFCAnyHandleUtil.SetAttribute(instanceHandle, "NominalDiameter", familySymbol.get_Parameter(BuiltInParameter.COUPLER_WIDTH).AsDouble());
                            IFCAnyHandleUtil.SetAttribute(instanceHandle, "NominalLength", familySymbol.get_Parameter(BuiltInParameter.COUPLER_LENGTH).AsDouble());
                        }

                        createdRebarCouplerHandles.Add(instanceHandle);

                        productWrapper.AddElement(coupler, instanceHandle, setter, null, true);
                    }
                }

                string couplerGUID = GUIDUtil.CreateGUID(coupler);

                if (nCouplerQuantity > 1)
                {
                    // Create a group to hold all of the created IFC entities, if the coupler aren't already in an assembly.
                    // We want to avoid nested groups of groups of couplers.
                    if (coupler.AssemblyInstanceId == ElementId.InvalidElementId)
                    {
                        string revitObjectType = exporterIFC.GetFamilyName();
                        string name            = NamingUtil.GetNameOverride(coupler, revitObjectType);
                        string description     = NamingUtil.GetDescriptionOverride(coupler, null);
                        string objectType      = NamingUtil.GetObjectTypeOverride(coupler, revitObjectType);

                        IFCAnyHandle rebarGroup = IFCInstanceExporter.CreateGroup(file, couplerGUID,
                                                                                  ownerHistory, name, description, objectType);

                        productWrapper.AddElement(coupler, rebarGroup);

                        IFCInstanceExporter.CreateRelAssignsToGroup(file, GUIDUtil.CreateGUID(), ownerHistory,
                                                                    null, null, createdRebarCouplerHandles, null, rebarGroup);
                    }
                }
                else
                {
                    // We will update the GUID of the one created element to be the element GUID.
                    // This will allow the IfcGUID parameter to be use/set if appropriate.
                    ExporterUtil.SetGlobalId(createdRebarCouplerHandles.ElementAt(0), couplerGUID);
                }

                tr.Commit();
            }
        }
        /// <summary>
        /// Exports a beam to IFC beam.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="element">
        /// The element to be exported.
        /// </param>
        /// <param name="geometryElement">
        /// The geometry element.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        public static void ExportBeam(ExporterIFC exporterIFC,
                                      Element element, GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            if (geometryElement == null)
            {
                return;
            }

            IFCFile file  = exporterIFC.GetFile();
            double  scale = exporterIFC.LinearScale;

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                LocationCurve locCurve  = element.Location as LocationCurve;
                Transform     orientTrf = Transform.Identity;

                bool         canExportAxis = (locCurve != null);
                IFCAnyHandle axisRep       = null;

                XYZ   beamDirection = null;
                XYZ   projDir       = null;
                Curve curve         = null;

                Plane plane = null;
                if (canExportAxis)
                {
                    curve = locCurve.Curve;
                    if (curve is Line)
                    {
                        Line line = curve as Line;
                        XYZ  planeY, planeOrig;
                        planeOrig     = line.get_EndPoint(0);
                        beamDirection = line.Direction;
                        if (Math.Abs(beamDirection.Z) < 0.707)  // approx 1.0/sqrt(2.0)
                        {
                            planeY = XYZ.BasisZ.CrossProduct(beamDirection);
                        }
                        else
                        {
                            planeY = XYZ.BasisX.CrossProduct(beamDirection);
                        }
                        planeY           = planeY.Normalize();
                        projDir          = beamDirection.CrossProduct(planeY);
                        plane            = new Plane(beamDirection, planeY, planeOrig);
                        orientTrf.BasisX = beamDirection; orientTrf.BasisY = planeY; orientTrf.BasisZ = projDir; orientTrf.Origin = planeOrig;
                    }
                    else if (curve is Arc)
                    {
                        XYZ yDir, center;
                        Arc arc = curve as Arc;
                        beamDirection    = arc.XDirection; yDir = arc.YDirection; projDir = arc.Normal; center = arc.Center;
                        plane            = new Plane(beamDirection, yDir, center);
                        orientTrf.BasisX = beamDirection; orientTrf.BasisY = yDir; orientTrf.BasisZ = projDir; orientTrf.Origin = center;
                    }
                    else
                    {
                        canExportAxis = false;
                    }
                }

                using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element, null, canExportAxis ? orientTrf : null, ExporterUtil.GetBaseLevelIdForElement(element)))
                {
                    IFCAnyHandle          localPlacement = setter.GetPlacement();
                    SolidMeshGeometryInfo solidMeshInfo  = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);

                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(localPlacement);
                        if (canExportAxis && (orientTrf.BasisX != null))
                        {
                            extrusionCreationData.CustomAxis            = beamDirection;
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom;
                        }
                        else
                        {
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryXY;
                        }

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

                        ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                        // The representation handle generated from one of the methods below.
                        IFCAnyHandle repHnd = null;

                        // The list of materials in the solids or meshes.
                        ICollection <ElementId> materialIds = new HashSet <ElementId>();

                        // There may be an offset to make the local coordinate system
                        // be near the origin.  This offset will be used to move the axis to the new LCS.
                        Transform offsetTransform = null;

                        // If we have a beam with a Linear location line that only has one solid geometry,
                        // we will try to use the ExtrusionAnalyzer to generate an extrusion with 0 or more clippings.
                        // This code is currently limited in that it will not process beams with openings, so we
                        // use other methods below if this one fails.
                        if (solids.Count == 1 && meshes.Count == 0 && (canExportAxis && (curve is Line)))
                        {
                            bool completelyClipped;
                            beamDirection = orientTrf.BasisX;
                            Plane beamExtrusionPlane = new Plane(orientTrf.BasisY, orientTrf.BasisZ, orientTrf.Origin);
                            repHnd = ExtrusionExporter.CreateExtrusionWithClipping(exporterIFC, element,
                                                                                   catId, solids[0], beamExtrusionPlane, beamDirection, null, out completelyClipped);
                            if (completelyClipped)
                            {
                                return;
                            }

                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                            {
                                // This is used by the BeamSlopeCalculator.  This should probably be generated automatically by
                                // CreateExtrusionWithClipping.
                                IFCExtrusionBasis bestAxis = (Math.Abs(beamDirection[0]) > Math.Abs(beamDirection[1])) ?
                                                             IFCExtrusionBasis.BasisX : IFCExtrusionBasis.BasisY;
                                extrusionCreationData.Slope = GeometryUtil.GetSimpleExtrusionSlope(beamDirection, bestAxis);
                                ElementId materialId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(solids[0], exporterIFC, element);
                                if (materialId != ElementId.InvalidElementId)
                                {
                                    materialIds.Add(materialId);
                                }
                            }
                        }

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            BodyData bodyData = null;

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                            if (solids.Count > 0 || meshes.Count > 0)
                            {
                                bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId,
                                                                   solids, meshes, bodyExporterOptions, extrusionCreationData);
                            }
                            else
                            {
                                IList <GeometryObject> geomlist = new List <GeometryObject>();
                                geomlist.Add(geometryElement);
                                bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId,
                                                                   geomlist, bodyExporterOptions, extrusionCreationData);
                            }
                            repHnd          = bodyData.RepresentationHnd;
                            materialIds     = bodyData.MaterialIds;
                            offsetTransform = bodyData.OffsetTransform;
                        }

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            extrusionCreationData.ClearOpenings();
                            return;
                        }

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

                        if (canExportAxis)
                        {
                            XYZ curveOffset = new XYZ(0, 0, 0);
                            if (offsetTransform != null)
                            {
                                curveOffset = -offsetTransform.Origin / scale;
                            }
                            else
                            {
                                // Note that we do not have to have any scaling adjustment here, since the curve origin is in the
                                // same internal coordinate system as the curve.
                                curveOffset = -plane.Origin;
                            }

                            Plane           offsetPlane = new Plane(plane.XVec, plane.YVec, XYZ.Zero);
                            IFCGeometryInfo info        = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, offsetPlane, projDir, false);
                            ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, curve, curveOffset, true);

                            IList <IFCAnyHandle> axis_items = info.GetCurves();

                            if (axis_items.Count > 0)
                            {
                                string identifierOpt         = "Axis";    // this is by IFC2x2 convention, not temporary
                                string representationTypeOpt = "Curve2D"; // this is by IFC2x2 convention, not temporary
                                axisRep = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, exporterIFC.Get3DContextHandle(identifierOpt),
                                                                                       identifierOpt, representationTypeOpt, axis_items);
                                representations.Add(axisRep);
                            }
                        }
                        representations.Add(repHnd);

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

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

                        string instanceGUID        = GUIDUtil.CreateGUID(element);
                        string instanceName        = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceObjectType  = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element));
                        string instanceTag         = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

                        IFCAnyHandle beam = IFCInstanceExporter.CreateBeam(file, instanceGUID, exporterIFC.GetOwnerHistoryHandle(),
                                                                           instanceName, instanceDescription, instanceObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, instanceTag);

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

                        OpeningUtil.CreateOpeningsIfNecessary(beam, element, extrusionCreationData, offsetTransform, exporterIFC,
                                                              extrusionCreationData.GetLocalPlacement(), setter, productWrapper);

                        FamilyTypeInfo typeInfo = new FamilyTypeInfo();
                        typeInfo.ScaledDepth          = extrusionCreationData.ScaledLength;
                        typeInfo.ScaledArea           = extrusionCreationData.ScaledArea;
                        typeInfo.ScaledInnerPerimeter = extrusionCreationData.ScaledInnerPerimeter;
                        typeInfo.ScaledOuterPerimeter = extrusionCreationData.ScaledOuterPerimeter;
                        PropertyUtil.CreateBeamColumnBaseQuantities(exporterIFC, beam, element, typeInfo);

                        if (materialIds.Count != 0)
                        {
                            CategoryUtil.CreateMaterialAssociations(exporterIFC, beam, materialIds);
                        }

                        // Register the beam's IFC handle for later use by truss and beam system export.
                        ExporterCacheManager.ElementToHandleCache.Register(element.Id, beam);
                    }
                }

                transaction.Commit();
            }
        }
Exemple #19
0
        /// <summary>
        /// Creates an opening from a solid.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="hostObjHnd">The host object handle.</param>
        /// <param name="hostElement">The host element.</param>
        /// <param name="insertElement">The insert element.</param>
        /// <param name="openingGUID">The GUID for the opening, depending on how the opening is created.</param>
        /// <param name="solid">The solid.</param>
        /// <param name="scaledHostWidth">The scaled host width.</param>
        /// <param name="isRecess">True if it is recess.</param>
        /// <param name="extrusionCreationData">The extrusion creation data.</param>
        /// <param name="setter">The placement setter.</param>
        /// <param name="localWrapper">The product wrapper.</param>
        /// <returns>The created opening handle.</returns>
        static public IFCAnyHandle CreateOpening(ExporterIFC exporterIFC, IFCAnyHandle hostObjHnd, Element hostElement, Element insertElement, string openingGUID,
                                                 Solid solid, double scaledHostWidth, bool isRecess, IFCExtrusionCreationData extrusionCreationData, PlacementSetter setter, ProductWrapper localWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            ElementId catId = CategoryUtil.GetSafeCategoryId(insertElement);

            XYZ  prepToWall;
            bool isLinearWall = GetOpeningDirection(hostElement, out prepToWall);

            if (isLinearWall)
            {
                extrusionCreationData.CustomAxis            = prepToWall;
                extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom;
            }

            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
            BodyData            bodyData            = BodyExporter.ExportBody(exporterIFC, insertElement, catId, ElementId.InvalidElementId,
                                                                              solid, bodyExporterOptions, extrusionCreationData);

            IFCAnyHandle openingRepHnd = bodyData.RepresentationHnd;

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(openingRepHnd))
            {
                extrusionCreationData.ClearOpenings();
                return(null);
            }
            IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();

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

            IFCAnyHandle openingPlacement    = extrusionCreationData.GetLocalPlacement();
            IFCAnyHandle hostObjPlacementHnd = IFCAnyHandleUtil.GetObjectPlacement(hostObjHnd);
            Transform    relTransform        = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(openingPlacement, hostObjPlacementHnd);

            openingPlacement = ExporterUtil.CreateLocalPlacement(file, hostObjPlacementHnd,
                                                                 relTransform.Origin, relTransform.BasisZ, relTransform.BasisX);

            IFCAnyHandle ownerHistory        = exporterIFC.GetOwnerHistoryHandle();
            double       scaledOpeningLength = extrusionCreationData.ScaledLength;
            string       openingObjectType   = "Opening";

            if (!MathUtil.IsAlmostZero(scaledHostWidth) && !MathUtil.IsAlmostZero(scaledOpeningLength))
            {
                openingObjectType = scaledOpeningLength < (scaledHostWidth - MathUtil.Eps()) ? "Recess" : "Opening";
            }
            else
            {
                openingObjectType = isRecess ? "Recess" : "Opening";
            }

            string openingName = NamingUtil.GetNameOverride(insertElement, null);

            if (string.IsNullOrEmpty(openingName))
            {
                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjHnd))
                {
                    openingName = IFCAnyHandleUtil.GetStringAttribute(hostObjHnd, "Name");
                }
                else
                {
                    openingName = NamingUtil.GetNameOverride(hostElement, NamingUtil.CreateIFCObjectName(exporterIFC, hostElement));
                }
            }

            IFCAnyHandle openingHnd = IFCInstanceExporter.CreateOpeningElement(file, openingGUID, ownerHistory, openingName, null,
                                                                               openingObjectType, openingPlacement, prodRep, null);

            if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
            {
                PropertyUtil.CreateOpeningQuantities(exporterIFC, openingHnd, extrusionCreationData);
            }

            if (localWrapper != null)
            {
                Element elementForProperties = null;
                if (GUIDUtil.IsGUIDFor(insertElement, openingGUID))
                {
                    elementForProperties = insertElement;
                }

                localWrapper.AddElement(insertElement, openingHnd, setter, extrusionCreationData, true);
            }

            string voidGuid = GUIDUtil.CreateGUID();

            IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, hostObjHnd, openingHnd);
            return(openingHnd);
        }
Exemple #20
0
        /// <summary>
        /// Export the individual part (IfcBuildingElementPart).
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="partElement">The part element to export.</param>
        /// <param name="geometryElement">The geometry of part.</param>
        /// <param name="productWrapper">The ProductWrapper object.</param>
        public static void ExportPart(ExporterIFC exporterIFC, Element partElement, ProductWrapper productWrapper,
                                      IFCPlacementSetter placementSetter, IFCAnyHandle originalPlacement, IFCRange range, IFCExtrusionAxes ifcExtrusionAxes,
                                      Element hostElement, ElementId overrideLevelId, bool asBuildingElement)
        {
            if (!ElementFilteringUtil.IsElementVisible(partElement))
            {
                return;
            }

            Part part = partElement as Part;

            if (part == null)
            {
                return;
            }

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

            ElementId partExportLevel = null;

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

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

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

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

            GeometryElement geometryElement = partElement.get_Geometry(options);

            if (geometryElement == null)
            {
                return;
            }

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

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

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

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

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

                        ElementId catId = CategoryUtil.GetSafeCategoryId(partElement);

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

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

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

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

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

                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

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

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

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

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

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

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

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

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

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

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

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

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