Beispiel #1
0
        /// <summary>
        /// Exports curtain object as one Brep.
        /// </summary>
        /// <param name="allSubElements">
        /// Collection of elements contained in the host curtain element.
        /// </param>
        /// <param name="wallElement">
        /// The curtain wall element.
        /// </param>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="setter">
        /// The PlacementSetter object.
        /// </param>
        /// <param name="localPlacement">
        /// The local placement handle.
        /// </param>
        /// <returns>
        /// The handle.
        /// </returns>
        public static IFCAnyHandle ExportCurtainObjectCommonAsOneBRep(ICollection <ElementId> allSubElements, Element wallElement,
                                                                      ExporterIFC exporterIFC, PlacementSetter setter, IFCAnyHandle localPlacement)
        {
            IFCAnyHandle prodDefRep = null;
            Document     document   = wallElement.Document;
            double       eps        = UnitUtil.ScaleLength(document.Application.VertexTolerance);

            IFCFile      file           = exporterIFC.GetFile();
            IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body");

            IFCGeometryInfo info = IFCGeometryInfo.CreateFaceGeometryInfo(eps);

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

            // Want to make sure we don't accidentally add a mullion or curtain line more than once.
            HashSet <ElementId> alreadyVisited = new HashSet <ElementId>();
            bool    useFallbackBREP            = true;
            Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions();

            foreach (ElementId subElemId in allSubElements)
            {
                Element         subElem  = wallElement.Document.GetElement(subElemId);
                GeometryElement geomElem = subElem.get_Geometry(geomOptions);
                if (geomElem == null)
                {
                    continue;
                }

                if (alreadyVisited.Contains(subElem.Id))
                {
                    continue;
                }
                alreadyVisited.Add(subElem.Id);


                // Export tessellated geometry when IFC4 Reference View is selected
                if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)
                {
                    BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(false, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                    IFCAnyHandle        triFaceSet          = BodyExporter.ExportBodyAsTessellatedFaceSet(exporterIFC, subElem, bodyExporterOptions, geomElem);
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triFaceSet))
                    {
                        bodyItems.Add(triFaceSet);
                        useFallbackBREP = false; // no need to do Brep since it is successful
                    }
                }
                // Export AdvancedFace before use fallback BREP
                else if (ExporterCacheManager.ExportOptionsCache.ExportAs4DesignTransferView)
                {
                    BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(false, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                    IFCAnyHandle        advancedBRep        = BodyExporter.ExportBodyAsAdvancedBrep(exporterIFC, subElem, bodyExporterOptions, geomElem);
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(advancedBRep))
                    {
                        bodyItems.Add(advancedBRep);
                        useFallbackBREP = false; // no need to do Brep since it is successful
                    }
                }

                if (useFallbackBREP)
                {
                    ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geomElem, XYZ.Zero, false);
                    HashSet <IFCAnyHandle> faces = new HashSet <IFCAnyHandle>(info.GetSurfaces());
                    IFCAnyHandle           outer = IFCInstanceExporter.CreateClosedShell(file, faces);

                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(outer))
                    {
                        bodyItems.Add(RepresentationUtil.CreateFacetedBRep(exporterIFC, document, outer, ElementId.InvalidElementId));
                    }
                }
            }

            if (bodyItems.Count == 0)
            {
                return(prodDefRep);
            }

            ElementId    catId = CategoryUtil.GetSafeCategoryId(wallElement);
            IFCAnyHandle shapeRep;

            // Use tessellated geometry in Reference View
            if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && !useFallbackBREP)
            {
                shapeRep = RepresentationUtil.CreateTessellatedRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems, null);
            }
            else if (ExporterCacheManager.ExportOptionsCache.ExportAs4DesignTransferView && !useFallbackBREP)
            {
                shapeRep = RepresentationUtil.CreateAdvancedBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems, null);
            }
            else
            {
                shapeRep = RepresentationUtil.CreateBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems);
            }

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
            {
                return(prodDefRep);
            }

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

            shapeReps.Add(shapeRep);

            IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, wallElement.get_Geometry(geomOptions), Transform.Identity);

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

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

            Part part = partElement as Part;

            if (part == null)
            {
                return;
            }

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

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

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

            ElementId partExportLevel = null;

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

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

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

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

            GeometryElement geometryElement = partElement.get_Geometry(options);

            if (geometryElement == null)
            {
                return;
            }

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

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

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

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

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

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

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

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

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

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

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

                        IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            Part part = partElement as Part;

            if (part == null)
            {
                return;
            }

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

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

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

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

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

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

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

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

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

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

            GeometryElement geometryElement = partElement.get_Geometry(options);

            if (geometryElement == null)
            {
                return;
            }

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

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

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

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

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

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

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

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

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

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

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

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

                        IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

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

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

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

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

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

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

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

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

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

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

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

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

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

                        transaction.Commit();
                    }
                }
            }
            finally
            {
                if (standalonePlacementSetter != null)
                {
                    standalonePlacementSetter.Dispose();
                }
            }
        }
Beispiel #7
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);
            }
        }
Beispiel #8
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 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();

            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.GetEndPoint(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 (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, canExportAxis ? orientTrf : null))
                {
                    IFCAnyHandle          localPlacement = setter.LocalPlacement;
                    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 = -UnitUtil.UnscaleLength(offsetTransform.Origin);
                            }
                            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));
                        string preDefinedType      = "BEAM"; // Default predefined type for Beam
                        preDefinedType = IFCValidateEntry.GetValidIFCType(element, preDefinedType);

                        IFCAnyHandle beam = IFCInstanceExporter.CreateBeam(file, instanceGUID, exporterIFC.GetOwnerHistoryHandle(),
                                                                           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();
            }
        }
Beispiel #10
0
        /// <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();
            }
        }
        /// <summary>
        /// Exports curtain object as one Brep.
        /// </summary>
        /// <param name="allSubElements">
        /// Collection of elements contained in the host curtain element.
        /// </param>
        /// <param name="wallElement">
        /// The curtain wall element.
        /// </param>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="setter">
        /// The PlacementSetter object.
        /// </param>
        /// <param name="localPlacement">
        /// The local placement handle.
        /// </param>
        /// <returns>
        /// The handle.
        /// </returns>
        public static IFCAnyHandle ExportCurtainObjectCommonAsOneBRep(ICollection <ElementId> allSubElements, Element wallElement,
                                                                      ExporterIFC exporterIFC, PlacementSetter setter, IFCAnyHandle localPlacement)
        {
            IFCAnyHandle prodDefRep = null;
            Document     document   = wallElement.Document;
            double       eps        = UnitUtil.ScaleLength(document.Application.VertexTolerance);

            IFCFile      file           = exporterIFC.GetFile();
            IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body");

            IFCGeometryInfo info = IFCGeometryInfo.CreateFaceGeometryInfo(eps);

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

            // Want to make sure we don't accidentally add a mullion or curtain line more than once.
            HashSet <ElementId> alreadyVisited = new HashSet <ElementId>();

            Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions();

            foreach (ElementId subElemId in allSubElements)
            {
                Element         subElem  = wallElement.Document.GetElement(subElemId);
                GeometryElement geomElem = subElem.get_Geometry(geomOptions);
                if (geomElem == null)
                {
                    continue;
                }

                if (alreadyVisited.Contains(subElem.Id))
                {
                    continue;
                }
                alreadyVisited.Add(subElem.Id);

                ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geomElem, XYZ.Zero, false);
                HashSet <IFCAnyHandle> faces = new HashSet <IFCAnyHandle>(info.GetSurfaces());
                IFCAnyHandle           outer = IFCInstanceExporter.CreateClosedShell(file, faces);

                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(outer))
                {
                    bodyItems.Add(RepresentationUtil.CreateFacetedBRep(exporterIFC, document, outer, ElementId.InvalidElementId));
                }
            }

            if (bodyItems.Count == 0)
            {
                return(prodDefRep);
            }

            ElementId    catId    = CategoryUtil.GetSafeCategoryId(wallElement);
            IFCAnyHandle shapeRep = RepresentationUtil.CreateBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems);

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
            {
                return(prodDefRep);
            }

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

            shapeReps.Add(shapeRep);

            IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, wallElement.get_Geometry(geomOptions), Transform.Identity);

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

            prodDefRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
            return(prodDefRep);
        }
        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);
        }
Beispiel #13
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))
            {
                // 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();
                }
            }
        }