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

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

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

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

                string openingObjectType = "Opening";

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

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

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

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

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

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

                    string voidGuid = GUIDUtil.CreateGUID();
                    IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, elementHandle, openingElement);
                }
            }
        }
        /// <summary>
        /// Exports a geometry element to boundary representation.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="exportBoundaryRep">True if to export boundary representation.</param>
        /// <param name="exportAsFacetation">True if to export the geometry as facetation.</param>
        /// <param name="bodyRep">Body representation.</param>
        /// <param name="boundaryRep">Boundary representation.</param>
        /// <returns>True if success, false if fail.</returns>
        public static bool ExportSurface(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
           bool exportBoundaryRep, bool exportAsFacetation, ref IFCAnyHandle bodyRep, ref IFCAnyHandle boundaryRep)
        {
            if (geometryElement == null)
                return false;

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

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

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

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

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

            IFCAnyHandle surface = IFCInstanceExporter.CreateFaceBasedSurfaceModel(file, faceSets);
            BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, doc, surface, BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element));

            IList<IFCAnyHandle> surfaceItems = new List<IFCAnyHandle>();
            surfaceItems.Add(surface);

            ElementId catId = CategoryUtil.GetSafeCategoryId(element);

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

            ICollection<IFCAnyHandle> boundaryRepresentations = ifcGeomInfo.GetRepresentations();
            if (exportBoundaryRep && boundaryRepresentations.Count > 0)
            {
                boundaryRep = RepresentationUtil.CreateBoundaryRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("FootPrint"), boundaryRepresentations, 
                    boundaryRep);
            }

            return true;
        }
Ejemplo n.º 3
0
        private static IFCAnyHandle ExportBoundingBoxBase(ExporterIFC exporterIFC, XYZ cornerXYZ, double xDim, double yDim, double zDim)
        {
            double eps = MathUtil.Eps();
            if (xDim < eps || yDim < eps || zDim < eps)
                return null;

            IFCFile file = exporterIFC.GetFile();
            IFCAnyHandle cornerHnd = ExporterUtil.CreateCartesianPoint(file, cornerXYZ);
            IFCAnyHandle boundingBoxItem = IFCInstanceExporter.CreateBoundingBox(file, cornerHnd, xDim, yDim, zDim);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(boundingBoxItem))
                return null;

            IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Box");
            return RepresentationUtil.CreateBoundingBoxRep(exporterIFC, contextOfItems, boundingBoxItem);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets material handle from material id or creates one if there is none.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="materialId">The material id.</param>
        /// <returns>The handle.</returns>
        public static IFCAnyHandle GetOrCreateMaterialHandle(ExporterIFC exporterIFC, ElementId materialId)
        {
            Document     document           = ExporterCacheManager.Document;
            IFCAnyHandle materialNameHandle = ExporterCacheManager.MaterialHandleCache.Find(materialId);

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(materialNameHandle))
            {
                string materialName = " <Unnamed>";
                if (materialId != ElementId.InvalidElementId)
                {
                    Material material = document.GetElement(materialId) as Material;
                    if (material != null)
                    {
                        materialName = material.Name;
                    }
                }
                materialNameHandle = IFCInstanceExporter.CreateMaterial(exporterIFC.GetFile(), materialName);

                ExporterCacheManager.MaterialHandleCache.Register(materialId, materialNameHandle);

                // associate Material with SurfaceStyle if necessary.
                IFCFile file = exporterIFC.GetFile();
                if (materialId != ElementId.InvalidElementId && !ExporterCacheManager.ExportOptionsCache.ExportAs2x2 && materialNameHandle.HasValue)
                {
                    HashSet <IFCAnyHandle> matRepHandles = IFCAnyHandleUtil.GetHasRepresentation(materialNameHandle);
                    if (matRepHandles.Count == 0)
                    {
                        Material matElem = document.GetElement(materialId) as Material;

                        ElementId fillPatternId       = (matElem != null) ? matElem.CutPatternId : ElementId.InvalidElementId;
                        Autodesk.Revit.DB.Color color = (matElem != null) ? matElem.CutPatternColor : new Color(0, 0, 0);

                        double planScale = 100.0;

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

                        bool hasFill = false;

                        IFCAnyHandle styledRepItem = null;
                        IFCAnyHandle matStyleHnd   = CategoryUtil.GetOrCreateMaterialStyle(document, exporterIFC, materialId);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(matStyleHnd))
                        {
                            styles.Add(matStyleHnd);

                            bool supportCutStyles = !ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2;
                            if (fillPatternId != ElementId.InvalidElementId && supportCutStyles)
                            {
                                IFCAnyHandle cutStyleHnd = exporterIFC.GetOrCreateFillPattern(fillPatternId, color, planScale);
                                if (cutStyleHnd.HasValue)
                                {
                                    styles.Add(cutStyleHnd);
                                    hasFill = true;
                                }
                            }

                            IFCAnyHandle presStyleHnd = IFCInstanceExporter.CreatePresentationStyleAssignment(file, styles);

                            HashSet <IFCAnyHandle> presStyleSet = new HashSet <IFCAnyHandle>();
                            presStyleSet.Add(presStyleHnd);

                            IFCAnyHandle styledItemHnd = IFCInstanceExporter.CreateStyledItem(file, styledRepItem, presStyleSet, null);

                            IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("");

                            string repId   = "Style";
                            string repType = (hasFill) ? "Material and Cut Pattern" : "Material";
                            HashSet <IFCAnyHandle> repItems = new HashSet <IFCAnyHandle>();
                            repItems.Add(styledItemHnd);

                            IFCAnyHandle styleRepHnd = IFCInstanceExporter.CreateStyledRepresentation(file, contextOfItems, repId, repType, repItems);

                            List <IFCAnyHandle> repList = new List <IFCAnyHandle>();
                            repList.Add(styleRepHnd);

                            IFCAnyHandle matDefRepHnd = IFCInstanceExporter.CreateMaterialDefinitionRepresentation(file, null, null, repList, materialNameHandle);
                        }
                    }
                }
            }
            return(materialNameHandle);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Create the handle corresponding to the "Axis" IfcRepresentation for a beam, if possible.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC class.</param>
        /// <param name="element">The beam element.</param>
        /// <param name="catId">The beam category id.</param>
        /// <param name="axisInfo">The optional beam axis information.</param>
        /// <param name="offsetTransform">The optional offset transform applied to the "Body" representation.</param>
        /// <returns>The handle, or null if not created.</returns>
        private static IFCAnyHandle CreateBeamAxis(ExporterIFC exporterIFC, Element element, ElementId catId, BeamAxisInfo axisInfo, Transform offsetTransform)
        {
            if (axisInfo == null)
            {
                return(null);
            }

            Curve     curve   = axisInfo.Axis;
            XYZ       projDir = axisInfo.AxisNormal;
            Transform lcs     = axisInfo.LCSAsTransform;

            string representationTypeOpt = "Curve2D"; // This is by IFC2x2+ convention.

            XYZ curveOffset = XYZ.Zero;

            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 = -lcs.Origin;
            }

            Transform offsetLCS = new Transform(lcs);

            offsetLCS.Origin = XYZ.Zero;
            IList <IFCAnyHandle> axis_items = null;

            if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)
            {
                IFCFile                 file         = exporterIFC.GetFile();
                IList <int>             segmentIndex = null;
                IList <IList <double> > pointList    = GeometryUtil.PointListFromCurve(exporterIFC, curve, null, null, out segmentIndex);

                // For now because of no support in creating IfcLineIndex and IfcArcIndex yet, it is set to null
                //IList<IList<int>> segmentIndexList = new List<IList<int>>();
                //segmentIndexList.Add(segmentIndex);
                IList <IList <int> > segmentIndexList = null;

                IFCAnyHandle pointListHnd = IFCInstanceExporter.CreateCartesianPointList3D(file, pointList);
                IFCAnyHandle axisHnd      = IFCInstanceExporter.CreateIndexedPolyCurve(file, pointListHnd, segmentIndexList, false);
                axis_items = new List <IFCAnyHandle>();
                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisHnd))
                {
                    axis_items.Add(axisHnd);
                    representationTypeOpt = "Curve3D";   // We use Curve3D for IFC4RV Axis
                }
            }
            else
            {
                IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, offsetLCS, projDir, false);
                ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, curve, curveOffset, true);

                axis_items = info.GetCurves();
            }

            if (axis_items.Count > 0)
            {
                string       identifierOpt = "Axis"; // This is by IFC2x2+ convention.
                IFCAnyHandle axisRep       = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, exporterIFC.Get3DContextHandle(identifierOpt),
                                                                                          identifierOpt, representationTypeOpt, axis_items);
                return(axisRep);
            }

            return(null);
        }
        /// <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();
                }
            }
        }
Ejemplo n.º 7
0
      /// <summary>
      /// Gets material handle from material id or creates one if there is none.
      /// </summary>
      /// <param name="exporterIFC">The ExporterIFC object.</param>
      /// <param name="materialId">The material id.</param>
      /// <returns>The handle.</returns>
      public static IFCAnyHandle GetOrCreateMaterialHandle(ExporterIFC exporterIFC, ElementId materialId)
      {
         Document document = ExporterCacheManager.Document;
         IFCAnyHandle materialNameHandle = ExporterCacheManager.MaterialHandleCache.Find(materialId);
         if (IFCAnyHandleUtil.IsNullOrHasNoValue(materialNameHandle))
         {
            string materialName = " <Unnamed>";
            if (materialId != ElementId.InvalidElementId)
            {
               Material material = document.GetElement(materialId) as Material;
               if (material != null)
               {
                  materialName = material.Name;
               }
            }
            materialNameHandle = IFCInstanceExporter.CreateMaterial(exporterIFC.GetFile(), materialName);

            ExporterCacheManager.MaterialHandleCache.Register(materialId, materialNameHandle);

            // associate Material with SurfaceStyle if necessary.
            IFCFile file = exporterIFC.GetFile();
            if (materialId != ElementId.InvalidElementId && !ExporterCacheManager.ExportOptionsCache.ExportAs2x2 && materialNameHandle.HasValue)
            {
               HashSet<IFCAnyHandle> matRepHandles = IFCAnyHandleUtil.GetHasRepresentation(materialNameHandle);
               if (matRepHandles.Count == 0)
               {
                  Material matElem = document.GetElement(materialId) as Material;

                  ElementId fillPatternId = (matElem != null) ? matElem.CutPatternId : ElementId.InvalidElementId;
                  Autodesk.Revit.DB.Color color = (matElem != null) ? GetSafeColor(matElem.CutPatternColor) : new Color(0, 0, 0);

                  double planScale = 100.0;

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

                  bool hasFill = false;

                  IFCAnyHandle styledRepItem = null;
                  IFCAnyHandle matStyleHnd = CategoryUtil.GetOrCreateMaterialStyle(document, exporterIFC, materialId);
                  if (!IFCAnyHandleUtil.IsNullOrHasNoValue(matStyleHnd))
                  {
                     styles.Add(matStyleHnd);

                     bool supportCutStyles = !ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2;
                     if (fillPatternId != ElementId.InvalidElementId && supportCutStyles)
                     {
                        IFCAnyHandle cutStyleHnd = exporterIFC.GetOrCreateFillPattern(fillPatternId, color, planScale);
                        if (cutStyleHnd.HasValue)
                        {
                           styles.Add(cutStyleHnd);
                           hasFill = true;
                        }
                     }

                     IFCAnyHandle presStyleHnd = IFCInstanceExporter.CreatePresentationStyleAssignment(file, styles);

                     HashSet<IFCAnyHandle> presStyleSet = new HashSet<IFCAnyHandle>();
                     presStyleSet.Add(presStyleHnd);

                     IFCAnyHandle styledItemHnd = IFCInstanceExporter.CreateStyledItem(file, styledRepItem, presStyleSet, null);

                     IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("");

                     string repId = "Style";
                     string repType = (hasFill) ? "Material and Cut Pattern" : "Material";
                     HashSet<IFCAnyHandle> repItems = new HashSet<IFCAnyHandle>();
                     repItems.Add(styledItemHnd);

                     IFCAnyHandle styleRepHnd = IFCInstanceExporter.CreateStyledRepresentation(file, contextOfItems, repId, repType, repItems);

                     List<IFCAnyHandle> repList = new List<IFCAnyHandle>();
                     repList.Add(styleRepHnd);

                     IFCAnyHandle matDefRepHnd = IFCInstanceExporter.CreateMaterialDefinitionRepresentation(file, null, null, repList, materialNameHandle);
                  }
               }
            }
         }
         return materialNameHandle;
      }
        /// <summary>
        /// Exports a geometry element to boundary representation.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="exportBoundaryRep">True if to export boundary representation.</param>
        /// <param name="exportAsFacetation">True if to export the geometry as facetation.</param>
        /// <param name="bodyRep">Body representation.</param>
        /// <param name="boundaryRep">Boundary representation.</param>
        /// <returns>True if success, false if fail.</returns>
        public static bool ExportSurface(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                         bool exportBoundaryRep, bool exportAsFacetation, ref IFCAnyHandle bodyRep, ref IFCAnyHandle boundaryRep)
        {
            if (geometryElement == null)
            {
                return(false);
            }

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

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

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

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

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

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

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

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

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

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

            surfaceItems.Add(surface);

            ElementId catId = CategoryUtil.GetSafeCategoryId(element);

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

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

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

            return(true);
        }
Ejemplo n.º 9
0
        private static IFCAnyHandle TryToCreateAsExtrusion(ExporterIFC exporterIFC, 
            Wall wallElement, 
            IList<IList<IFCConnectedWallData>> connectedWalls,
            IList<Solid> solids,
            IList<Mesh> meshes,
            double baseWallElevation, 
            ElementId catId, 
            Curve baseCurve, 
            Curve trimmedCurve,
            Plane wallLCS, 
            double scaledDepth, 
            IFCRange zSpan, 
            IFCRange range, 
            PlacementSetter setter,
            out IList<IFCExtrusionData> cutPairOpenings, 
            out bool isCompletelyClipped, 
            out double scaledFootprintArea, 
            out double scaledLength)
        {
            cutPairOpenings = new List<IFCExtrusionData>();

            IFCAnyHandle bodyRep;
            scaledFootprintArea = 0;

            double unscaledLength = trimmedCurve != null ? trimmedCurve.Length : 0;
            scaledLength = UnitUtil.ScaleLength(unscaledLength);

            XYZ localOrig = wallLCS.Origin;

            // Check to see if the wall has geometry given the specified range.
            if (!WallHasGeometryToExport(wallElement, solids, meshes, range, out isCompletelyClipped))
                return null;

            // This is our major check here that goes into internal code.  If we have enough information to faithfully reproduce
            // the wall as an extrusion with clippings and openings, we will continue.  Otherwise, export it as a BRep.
            if (!CanExportWallGeometryAsExtrusion(wallElement, range))
                return null;

            // extrusion direction.
            XYZ extrusionDir = GetWallHeightDirection(wallElement);

            // create extrusion boundary.
            bool alwaysThickenCurve = IsWallBaseRectangular(wallElement, trimmedCurve);
            
            double unscaledWidth = wallElement.Width;
            IList<CurveLoop> boundaryLoops = GetBoundaryLoopsFromWall(exporterIFC, wallElement, alwaysThickenCurve, trimmedCurve, unscaledWidth);
            if (boundaryLoops == null || boundaryLoops.Count == 0)
                    return null;

            double fullUnscaledLength = baseCurve.Length;
            double unscaledFootprintArea = ExporterIFCUtils.ComputeAreaOfCurveLoops(boundaryLoops);
            scaledFootprintArea = UnitUtil.ScaleArea(unscaledFootprintArea);
            // We are going to do a little sanity check here.  If the scaledFootprintArea is significantly less than the 
            // width * length of the wall footprint, we probably calculated the area wrong, and will abort.
            // This could occur because of a door or window that cuts a corner of the wall (i.e., has no wall material on one side).
            // We want the scaledFootprintArea to be at least (95% of approximateBaseArea - 2 * side wall area).  
            // The "side wall area" is an approximate value that takes into account potential wall joins.  
            // This prevents us from doing extra work for many small walls because of joins.  We'll allow 1' (~30 cm) per side for this.
            double approximateUnscaledBaseArea = unscaledWidth * fullUnscaledLength;
            if (unscaledFootprintArea < (approximateUnscaledBaseArea * .95 - 2 * unscaledWidth))
            {
                // Can't handle the case where we don't have a simple extrusion to begin with.
                if (!alwaysThickenCurve)
                    return null;

                boundaryLoops = GetBoundaryLoopsFromBaseCurve(wallElement, connectedWalls, baseCurve, trimmedCurve, unscaledWidth, scaledDepth);
                if (boundaryLoops == null || boundaryLoops.Count == 0)
                return null;
            }

            // origin gets scaled later.
            double baseWallZOffset = localOrig[2] - ((range == null) ? baseWallElevation : Math.Min(range.Start, baseWallElevation));
            XYZ modifiedSetterOffset = new XYZ(0, 0, setter.Offset + baseWallZOffset);

            IFCAnyHandle baseBodyItemHnd = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, boundaryLoops, wallLCS,
                extrusionDir, scaledDepth);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(baseBodyItemHnd))
                return null;

            IFCAnyHandle bodyItemHnd = AddClippingsToBaseExtrusion(exporterIFC, wallElement,
               modifiedSetterOffset, range, zSpan, baseBodyItemHnd, out cutPairOpenings);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItemHnd))
                return null;
            bool hasClipping = bodyItemHnd.Id != baseBodyItemHnd.Id;

            ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(wallElement);
            IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, wallElement.Document,
                baseBodyItemHnd, matId);

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

            // Check whether wall has opening. If it has, exporting it in the Reference View will need to be in a tessellated geometry that includes the opening cut
            IList<IFCOpeningData> openingDataList = ExporterIFCUtils.GetOpeningData(exporterIFC, wallElement, wallLCS, range);
            bool wallHasOpening = openingDataList.Count > 0;
            BodyExporterOptions options = new BodyExporterOptions(true);

            IFCAnyHandle contextOfItemsBody = exporterIFC.Get3DContextHandle("Body");
            if (!hasClipping)
            {
                // Check whether wall has opening. If it has, exporting it in Reference View will need to be in a tesselated geometry that includes the opening cut
                if (ExporterUtil.IsReferenceView() && wallHasOpening)
                {
                    List<GeometryObject> geomList = new List<GeometryObject>();
                    bodyItems.Clear();       // Since we will change the geometry, clear existing extrusion data first
                    if (solids.Count > 0)
                        foreach (GeometryObject solid in solids)
                            geomList.Add(solid);
                    if (meshes.Count > 0)
                        foreach (GeometryObject mesh in meshes)
                            geomList.Add(mesh);
                    foreach (GeometryObject geom in geomList)
                    {
                        IFCAnyHandle triangulatedBodyItem = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, wallElement, options, geom);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedBodyItem)) 
                            bodyItems.Add(triangulatedBodyItem);
                    }
                    bodyRep = RepresentationUtil.CreateTessellatedRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems, null);
                }
                else
                    bodyRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems, null);
            }
            else
            {
                // Create TessellatedRep geometry if it is Reference View.
                if (ExporterUtil.IsReferenceView())
                {
                    List<GeometryObject> geomList = new List<GeometryObject>();
                    // The native function AddClippingsToBaseExtrusion will create the IfcBooleanClippingResult entity and therefore here we need to delete it
                    foreach (IFCAnyHandle item in bodyItems)
                    {
                        item.Dispose();     //Still DOES NOT work, the IfcBooleanClippingResult is still orphaned in the IFC file!
                    }
                    bodyItems.Clear();       // Since we will change the geometry, clear existing extrusion data first

                    if (solids.Count > 0)
                        foreach (GeometryObject solid in solids)
                            geomList.Add(solid);
                    if (meshes.Count > 0)
                        foreach (GeometryObject mesh in meshes)
                            geomList.Add(mesh);
                    foreach (GeometryObject geom in geomList)
                    {
                        IFCAnyHandle triangulatedBodyItem = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, wallElement, options, geom);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedBodyItem)) 
                            bodyItems.Add(triangulatedBodyItem);
                    }
                    bodyRep = RepresentationUtil.CreateTessellatedRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems, null);
                }
                else
                    bodyRep = RepresentationUtil.CreateClippingRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems);
            }

            return bodyRep;
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Exports list of geometries to IFC body representation.
        /// </summary>
        /// <param name="application">The Revit application.</param>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="geometryList">The geometry list.</param>
        /// <param name="tryToExportAsExtrusion">True if try to export as extrusion.</param>
        /// <param name="exportBodyParams">The extrusion creation data.</param>
        /// <returns>The representation handle.</returns>
        public static IFCAnyHandle ExportBody(Autodesk.Revit.ApplicationServices.Application application, ExporterIFC exporterIFC, ElementId categoryId,
           IList<GeometryObject> geometryList, bool tryToExportAsExtrusion,
           IFCExtrusionCreationData exportBodyParams)
        {
            IFCAnyHandle body = IFCAnyHandle.Create();

            int sizeOfGeometry = geometryList.Count;
            if (sizeOfGeometry == 0)
                return body;

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

            double eps = application.VertexTolerance * scale;

            HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();
            if (tryToExportAsExtrusion)
            {
                // Check to see if we have Geometries or GFaces.
                // We will have the specific all GFaces case and then the generic case.
                IList<Face> faces = new List<Face>();
                bool allFaces = true;
                foreach (GeometryObject geometryObject in geometryList)
                {
                    if (geometryObject is Face)
                        faces.Add(geometryObject as Face);
                    else
                    {
                        allFaces = false;
                        break;
                    }
                }

                int numExtrusionsToCreate = allFaces ? 1 : sizeOfGeometry;

                try
                {
                    for (int ii = 0; ii < numExtrusionsToCreate && tryToExportAsExtrusion; ii++)
                    {
                        SetBestMaterialIdInExporter(geometryList[ii], exporterIFC);

                        IList<IFCExtrusionData> extrusionList = new List<IFCExtrusionData>();

                        IFCExtrusionAxes axesToExtrudeIn = exportBodyParams != null ? exportBodyParams.PossibleExtrusionAxes : IFCExtrusionAxes.TryDefault;
                        XYZ directionToExtrudeIn = XYZ.Zero;
                        if (exportBodyParams != null && exportBodyParams.HasCustomAxis)
                            directionToExtrudeIn = exportBodyParams.CustomAxis;

                        IFCExtrusionCalculatorOptions extrusionOptions =
                           new IFCExtrusionCalculatorOptions(exporterIFC, axesToExtrudeIn, directionToExtrudeIn,
                              scale);

                        bool canExportAsExtrusion = false;
                        if (allFaces)
                            extrusionList = IFCExtrusionCalculatorUtils.CalculateExtrusionData(extrusionOptions, faces);
                        else
                            extrusionList = IFCExtrusionCalculatorUtils.CalculateExtrusionData(extrusionOptions, geometryList[ii]);

                        if (extrusionList.Count > 0)
                        {
                            if (exportBodyParams != null && exportBodyParams.AreInnerRegionsOpenings)
                            {
                                IList<CurveLoop> curveLoops = extrusionList[0].GetLoops();
                                XYZ extrudedDirection = extrusionList[0].ExtrusionDirection;

                                int numLoops = curveLoops.Count;
                                for (int jj = numLoops - 1; jj > 0; jj--)
                                {
                                    AddOpeningData(exportBodyParams, extrusionList[0], curveLoops[jj]);
                                }
                                extrusionList[0].ClearLoops();
                            }

                            canExportAsExtrusion = false;
                            IFCAnyHandle extrusionHandle = CreateExtrudedSolidFromExtrusionData(exporterIFC, categoryId, extrusionList[0]);
                            if (extrusionHandle.HasValue)
                            {
                                bodyItems.Add(extrusionHandle);

                                IFCExtrusionBasis whichBasis = extrusionList[0].ExtrusionBasis;
                                IList<CurveLoop> curveLoops = extrusionList[0].GetLoops();
                                XYZ extrusionDirection = extrusionList[0].ExtrusionDirection;

                                canExportAsExtrusion = (whichBasis >= 0);

                                if (exportBodyParams != null)
                                {
                                    double zOff = (whichBasis == IFCExtrusionBasis.BasisZ) ? (1.0 - Math.Abs(extrusionDirection[2])) : Math.Abs(extrusionDirection[2]);
                                    double scaledAngle = Math.Asin(zOff) * 180 / Math.PI;
                                    exportBodyParams.Slope = scaledAngle;
                                    exportBodyParams.ScaledLength = extrusionList[0].ScaledExtrusionLength;
                                    exportBodyParams.CustomAxis = extrusionDirection;
                                    for (int kk = 1; kk < extrusionList.Count; kk++)
                                    {
                                        AddOpeningData(exportBodyParams, extrusionList[kk]);
                                    }

                                    Plane plane = null;
                                    double height = 0.0, width = 0.0;
                                    if (ComputeHeightWidthOfCurveLoop(curveLoops[0], plane, out height, out width))
                                    {
                                        exportBodyParams.ScaledHeight = height * scale;
                                        exportBodyParams.ScaledWidth = width * scale;
                                    }

                                    double area = ExporterIFCUtils.ComputeAreaOfCurveLoops(curveLoops);
                                    if (area > 0.0)
                                    {
                                        exportBodyParams.ScaledArea = area * scale * scale;
                                    }

                                    double innerPerimeter = ComputeInnerPerimeterOfCurveLoops(curveLoops);
                                    double outerPerimeter = ComputeOuterPerimeterOfCurveLoops(curveLoops);
                                    if (innerPerimeter > 0.0)
                                        exportBodyParams.ScaledInnerPerimeter = innerPerimeter * scale;
                                    if (outerPerimeter > 0.0)
                                        exportBodyParams.ScaledOuterPerimeter = outerPerimeter * scale;
                                }
                            }
                            else
                            {
                                if (exportBodyParams != null)
                                    exportBodyParams.ClearOpenings();
                            }
                        }
                        else
                        {
                            tryToExportAsExtrusion = false;
                        }
                    }
                }
                catch
                {
                    tryToExportAsExtrusion = false;
                }

                if (tryToExportAsExtrusion)
                {
                    body = RepresentationUtil.CreateSweptSolidRep(exporterIFC, categoryId, contextOfItems, bodyItems, body);
                    return body;
                }
            }

            // We couldn't export it as an extrusion; export as a faceted solid or a surface model.
            DeleteHandles(bodyItems);
            bodyItems.Clear();

            // generate "bottom corner" of bbox; create new local placement if passed in.
            // need to transform, but not scale, this point to make it the new origin.
            using (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
            {
                if (exportBodyParams != null)
                    transformSetter.InitializeFromBoundingBox(exporterIFC, geometryList, exportBodyParams);

                HashSet<IFCAnyHandle> faceSet = new HashSet<IFCAnyHandle>(); // for export as surface.
                bool exportAsBReps = true;

                foreach (GeometryObject geometryObject in geometryList)
                {
                    SetBestMaterialIdInExporter(geometryObject, exporterIFC);

                    IFCGeometryInfo faceListInfo = IFCGeometryInfo.CreateFaceGeometryInfo(eps);
                    ExporterIFCUtils.CollectGeometryInfo(exporterIFC, faceListInfo, geometryObject, XYZ.Zero, false);

                    IList<ICollection<IFCAnyHandle>> faceSetList = faceListInfo.GetFaces();

                    int numBReps = faceSetList.Count;
                    if (numBReps == 0)
                        continue;

                    foreach (ICollection<IFCAnyHandle> currentFaceSet in faceSetList)
                    {
                        if (currentFaceSet.Count == 0)
                            continue;

                        if (exportAsBReps)
                        {
                            if ((currentFaceSet.Count < 4) || !CanCreateClosedShell(currentFaceSet))
                            {
                                // fix all previous bodyItems.
                                exportAsBReps = false;
                                foreach (IFCAnyHandle bodyItem in bodyItems)
                                {
                                    if (bodyItem.HasValue)
                                    {
                                        IFCAnyHandle closedShellHnd = IFCGeometryUtils.GetFaceOuterBoundary(bodyItem);
                                        if (closedShellHnd.HasValue)
                                        {
                                            ICollection<IFCAnyHandle> faces = IFCGeometryUtils.GetClosedShellFaces(closedShellHnd);
                                            IFCAnyHandle faceSetHnd = file.CreateConnectedFaceSet(faces);
                                            faceSet.Add(faceSetHnd); // only one item.
                                            closedShellHnd.Delete();
                                        }
                                        bodyItem.Delete();
                                    }
                                }
                                bodyItems.Clear();
                            }
                        }

                        if (exportAsBReps)
                        {
                            IFCAnyHandle faceOuter = file.CreateClosedShell(currentFaceSet);
                            IFCAnyHandle brepHnd = RepresentationUtil.CreateFacetedBRep(exporterIFC, faceOuter);
                            if (brepHnd.HasValue)
                                bodyItems.Add(brepHnd); // only one item.
                        }
                        else
                        {
                            // TODO: add layer assignment info.
                            IFCAnyHandle faceSetHnd = file.CreateConnectedFaceSet(currentFaceSet);
                            faceSet.Add(faceSetHnd); // only one item.
                        }
                    }
                }

                if (faceSet.Count > 0)
                {
                    IFCAnyHandle surfaceModel = file.CreateFaceBasedSurfaceModel(faceSet);
                    bodyItems.Add(surfaceModel); // only one item.
                }

                if (bodyItems.Count == 0)
                    return body;

                if (exportAsBReps)
                    body = RepresentationUtil.CreateBRepRep(exporterIFC, categoryId, contextOfItems, bodyItems);
                else
                    body = RepresentationUtil.CreateSurfaceRep(exporterIFC, categoryId, contextOfItems, bodyItems, false);

                return body;
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Create the handle corresponding to the "Axis" IfcRepresentation for a beam, if possible.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC class.</param>
        /// <param name="element">The beam element.</param>
        /// <param name="catId">The beam category id.</param>
        /// <param name="axisInfo">The optional beam axis information.</param>
        /// <param name="offsetTransform">The optional offset transform applied to the "Body" representation.</param>
        /// <returns>The handle, or null if not created.</returns>
        private static IFCAnyHandle CreateBeamAxis(ExporterIFC exporterIFC, Element element, ElementId catId, BeamAxisInfo axisInfo, Transform offsetTransform)
        {
            if (axisInfo == null)
            {
                return(null);
            }

            Curve     curve   = axisInfo.Axis;
            XYZ       projDir = axisInfo.AxisNormal;
            Transform lcs     = axisInfo.LCSAsTransform;

            string representationTypeOpt = "Curve2D"; // This is by IFC2x2+ convention.

            XYZ curveOffset = XYZ.Zero;

            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 = -lcs.Origin;
            }

            Transform offsetLCS = new Transform(lcs);

            offsetLCS.Origin = XYZ.Zero;
            IList <IFCAnyHandle> axis_items = null;

            if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)
            {
                IFCAnyHandle axisHnd = GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, curve);
                axis_items = new List <IFCAnyHandle>();
                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisHnd))
                {
                    axis_items.Add(axisHnd);
                    representationTypeOpt = "Curve3D";   // We use Curve3D for IFC4RV Axis
                }
            }
            else
            {
                IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, offsetLCS, projDir, false);
                ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, curve, curveOffset, true);

                axis_items = info.GetCurves();
            }

            if (axis_items.Count > 0)
            {
                string       identifierOpt = "Axis"; // This is by IFC2x2+ convention.
                IFCAnyHandle axisRep       = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, exporterIFC.Get3DContextHandle(identifierOpt),
                                                                                          identifierOpt, representationTypeOpt, axis_items);
                return(axisRep);
            }

            return(null);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Exports a Rebar to IFC ReinforcingBar.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element to be exported.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>The list of IfcReinforcingBar handles created.</returns>
        public static ISet <IFCAnyHandle> ExportRebar(ExporterIFC exporterIFC, Element element, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();
            HashSet <IFCAnyHandle> createdRebars = new HashSet <IFCAnyHandle>();

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    if (element is Rebar)
                    {
                        GeometryElement rebarGeometry = ExporterIFCUtils.GetRebarGeometry(element as Rebar, ExporterCacheManager.ExportOptionsCache.FilterViewForExport);

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

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

                    IFCAnyHandle prodRep = null;

                    double totalBarLengthUnscale = GetRebarTotalLength(element);
                    double volumeUnscale         = GetRebarVolume(element);
                    double totalBarLength        = UnitUtil.ScaleLength(totalBarLengthUnscale);

                    if (MathUtil.IsAlmostZero(totalBarLength))
                    {
                        return(null);
                    }

                    ElementId materialId = ElementId.InvalidElementId;
                    ParameterUtil.GetElementIdValueFromElementOrSymbol(element, BuiltInParameter.MATERIAL_ID_PARAM, out materialId);

                    Document     doc         = element.Document;
                    ElementId    typeId      = element.GetTypeId();
                    RebarBarType elementType = doc.GetElement(element.GetTypeId()) as RebarBarType;
                    double       diameter    = UnitUtil.ScaleLength(elementType == null ? 1.0 / 12.0 : elementType.BarDiameter);
                    double       radius      = diameter / 2.0;
                    double       longitudinalBarNominalDiameter  = diameter;
                    double       longitudinalBarCrossSectionArea = UnitUtil.ScaleArea(volumeUnscale / totalBarLengthUnscale);
                    double       barLength = totalBarLength / GetRebarQuantity(element);

                    IList <Curve> baseCurves           = GetRebarCenterlineCurves(element, true, false, false);
                    int           numberOfBarPositions = GetNumberOfBarPositions(element);

                    string steelGrade = NamingUtil.GetOverrideStringValue(element, "SteelGrade", null);

                    // Allow use of IFC2x3 or IFC4 naming.
                    string predefinedType = NamingUtil.GetOverrideStringValue(element, "BarRole", null);
                    if (string.IsNullOrWhiteSpace(predefinedType))
                    {
                        predefinedType = NamingUtil.GetOverrideStringValue(element, "PredefinedType", null);
                    }
                    IFCReinforcingBarRole role = GetReinforcingBarRole(predefinedType);

                    string origRebarName    = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                    string rebarDescription = NamingUtil.GetDescriptionOverride(element, null);
                    string rebarObjectType  = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element));
                    string rebarTag         = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

                    const int maxBarGUIDS = IFCReinforcingBarSubElements.BarEnd - IFCReinforcingBarSubElements.BarStart + 1;
                    ElementId categoryId  = CategoryUtil.GetSafeCategoryId(element);

                    IFCAnyHandle originalPlacement = setter.LocalPlacement;

                    for (int i = 0; i < numberOfBarPositions; i++)
                    {
                        if (!DoesBarExistAtPosition(element, i))
                        {
                            continue;
                        }

                        string rebarName = NamingUtil.GetNameOverride(element, origRebarName + ": " + i);

                        Transform barTrf = GetBarPositionTransform(element, i);

                        IList <Curve> curves   = new List <Curve>();
                        double        endParam = 0.0;
                        foreach (Curve baseCurve in baseCurves)
                        {
                            if (baseCurve is Arc || baseCurve is Ellipse)
                            {
                                if (baseCurve.IsBound)
                                {
                                    endParam += UnitUtil.ScaleAngle(baseCurve.GetEndParameter(1) - baseCurve.GetEndParameter(0));
                                }
                                else
                                {
                                    endParam += UnitUtil.ScaleAngle(2 * Math.PI);
                                }
                            }
                            else
                            {
                                endParam += 1.0;
                            }
                            curves.Add(baseCurve.CreateTransformed(barTrf));
                        }

                        IFCAnyHandle           compositeCurve = GeometryUtil.CreateCompositeCurve(exporterIFC, curves);
                        IFCAnyHandle           sweptDiskSolid = IFCInstanceExporter.CreateSweptDiskSolid(file, compositeCurve, radius, null, 0, endParam);
                        HashSet <IFCAnyHandle> bodyItems      = new HashSet <IFCAnyHandle>();
                        bodyItems.Add(sweptDiskSolid);

                        IFCAnyHandle         shapeRep  = RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC, element, categoryId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null);
                        IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>();
                        shapeReps.Add(shapeRep);
                        prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);

                        IFCAnyHandle copyLevelPlacement = (i == 0) ? originalPlacement : ExporterUtil.CopyLocalPlacement(file, originalPlacement);

                        string rebarGUID = (i < maxBarGUIDS) ?
                                           GUIDUtil.CreateSubElementGUID(element, i + (int)IFCReinforcingBarSubElements.BarStart) :
                                           GUIDUtil.CreateGUID();
                        IFCAnyHandle elemHnd = IFCInstanceExporter.CreateReinforcingBar(file, rebarGUID, exporterIFC.GetOwnerHistoryHandle(),
                                                                                        rebarName, rebarDescription, rebarObjectType, copyLevelPlacement,
                                                                                        prodRep, rebarTag, steelGrade, longitudinalBarNominalDiameter, longitudinalBarCrossSectionArea,
                                                                                        barLength, role, null);
                        createdRebars.Add(elemHnd);

                        productWrapper.AddElement(element, elemHnd, setter.LevelInfo, null, true);
                        ExporterCacheManager.HandleToElementCache.Register(elemHnd, element.Id);

                        CategoryUtil.CreateMaterialAssociation(exporterIFC, elemHnd, materialId);
                    }
                }
                transaction.Commit();
            }
            return(createdRebars);
        }
Ejemplo n.º 13
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.ExportBodyAsTriangulatedFaceSet(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);
        }
        /// <summary>
        /// Create the handle corresponding to the "Axis" IfcRepresentation for a structural member objects, if possible.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC class.</param>
        /// <param name="element">The structural member element.</param>
        /// <param name="catId">The structural member category id.</param>
        /// <param name="axisInfo">The optional structural member axis information.</param>
        /// <param name="offsetTransform">The optional offset transform applied to the "Body" representation.</param>
        /// <returns>The handle, or null if not created.</returns>
        public static IFCAnyHandle CreateStructuralMemberAxis(ExporterIFC exporterIFC, Element element, ElementId catId, StructuralMemberAxisInfo axisInfo, Transform newTransformLCS)
        {
            if (axisInfo == null)
            {
                return(null);
            }

            // This Axis should have been transformed into its ECS position previously (in GetStructuralMemberAxisTransform())
            Curve     curve  = axisInfo.Axis;
            Transform offset = Transform.Identity;

            if (newTransformLCS != null)
            {
                // We need to flip the Left-handed transform to the right-hand one as IFC only support right-handed coordinate system
                if (newTransformLCS.Determinant < 0)
                {
                    XYZ orig = newTransformLCS.Origin;
                    newTransformLCS.Origin = XYZ.Zero;
                    offset        = FlipYTrf().Multiply(newTransformLCS);
                    offset.Origin = orig;
                }
                else
                {
                    offset = newTransformLCS;
                }
            }

            // Calculate the transformation matrix to tranform the original Axis Curve at its ECS into the new ECS assigned in the offset
            curve = curve.CreateTransformed(offset.Inverse.Multiply(axisInfo.LCSAsTransform));

            IDictionary <IFCFuzzyXYZ, IFCAnyHandle> cachePoints = new Dictionary <IFCFuzzyXYZ, IFCAnyHandle>();
            IFCAnyHandle         ifcCurveHnd = GeometryUtil.CreateIFCCurveFromRevitCurve(exporterIFC.GetFile(), exporterIFC, curve, true, cachePoints);
            IList <IFCAnyHandle> axis_items  = new List <IFCAnyHandle>();

            if (!(IFCAnyHandleUtil.IsNullOrHasNoValue(ifcCurveHnd)))
            {
                axis_items.Add(ifcCurveHnd);
            }

            if (axis_items.Count > 0)
            {
                string       identifierOpt         = "Axis";    // This is by IFC2x2+ convention.
                string       representationTypeOpt = "Curve3D"; // This is by IFC2x2+ convention.
                IFCAnyHandle axisRep = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, exporterIFC.Get3DContextHandle(identifierOpt),
                                                                                    identifierOpt, representationTypeOpt, axis_items);
                return(axisRep);
            }

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

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

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

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

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

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

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

                surface = IFCInstanceExporter.CreateFaceBasedSurfaceModel(file, faceSets);

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

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

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

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

            surfaceItems.Add(surface);

            ElementId catId = CategoryUtil.GetSafeCategoryId(element);

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

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

            return(true);
        }
Ejemplo n.º 16
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)
        {
            // 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);

                        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);

                        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();
                }
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Exports a gutter element.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The IFCProductWrapper.</param>
        public static void ExportGutter(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, IFCProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

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

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

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

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


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

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

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

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

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

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

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

                    tr.Commit();
                }
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Exports a CeilingAndFloor element to IFC.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="floor">The floor element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportCeilingAndFloorElement(ExporterIFC exporterIFC, CeilingAndFloor floorElement, GeometryElement geometryElement,
                                                        ProductWrapper productWrapper)
        {
            if (geometryElement == null)
            {
                return;
            }

            // export parts or not
            bool exportParts = PartExporter.CanExportParts(floorElement);

            if (exportParts && !PartExporter.CanExportElementInPartExport(floorElement, floorElement.LevelId, false))
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

            string        ifcEnumType;
            IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, floorElement, out ifcEnumType);

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                bool canExportAsContainerOrWithExtrusionAnalyzer = (!exportParts && (floorElement is Floor));

                if (canExportAsContainerOrWithExtrusionAnalyzer)
                {
                    // Try to export the Floor slab as a container.  If that succeeds, we are done.
                    // If we do export the floor as a container, it will take care of the local placement and transform there, so we need to leave
                    // this out of the IFCTransformSetter and PlacementSetter scopes below, or else we'll get double transforms.
                    IFCAnyHandle floorHnd = RoofExporter.ExportRoofOrFloorAsContainer(exporterIFC, ifcEnumType, floorElement, geometryElement, productWrapper);
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(floorHnd))
                    {
                        tr.Commit();
                        return;
                    }
                }

                IList <IFCAnyHandle> slabHnds        = new List <IFCAnyHandle>();
                IList <IFCAnyHandle> brepSlabHnds    = new List <IFCAnyHandle>();
                IList <IFCAnyHandle> nonBrepSlabHnds = new List <IFCAnyHandle>();

                using (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
                {
                    using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, floorElement))
                    {
                        IFCAnyHandle localPlacement = placementSetter.LocalPlacement;
                        IFCAnyHandle ownerHistory   = ExporterCacheManager.OwnerHistoryHandle;

                        // The routine ExportExtrudedSlabOpenings is called if exportedAsInternalExtrusion is true, and it requires having a valid level association.
                        // Disable calling ExportSlabAsExtrusion if we can't handle potential openings.
                        bool canExportAsInternalExtrusion = placementSetter.LevelInfo != null;
                        bool exportedAsInternalExtrusion  = false;

                        ElementId catId = CategoryUtil.GetSafeCategoryId(floorElement);

                        IList <IFCAnyHandle>             prodReps        = new List <IFCAnyHandle>();
                        IList <ShapeRepresentationType>  repTypes        = new List <ShapeRepresentationType>();
                        IList <IList <CurveLoop> >       extrusionLoops  = new List <IList <CurveLoop> >();
                        IList <IFCExtrusionCreationData> loopExtraParams = new List <IFCExtrusionCreationData>();
                        Plane floorPlane = GeometryUtil.CreateDefaultPlane();

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

                        if (canExportAsContainerOrWithExtrusionAnalyzer)
                        {
                            Floor floor = floorElement as Floor;

                            // Next, try to use the ExtrusionAnalyzer for the limited cases it handles - 1 solid, no openings, end clippings only.
                            // Also limited to cases with line and arc boundaries.
                            //
                            SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                            IList <Solid>         solids        = solidMeshInfo.GetSolids();
                            IList <Mesh>          meshes        = solidMeshInfo.GetMeshes();

                            if (solids.Count == 1 && meshes.Count == 0)
                            {
                                bool completelyClipped;
                                // floorExtrusionDirection is set to (0, 0, -1) because extrusionAnalyzerFloorPlane is computed from the top face of the floor
                                XYZ floorExtrusionDirection = new XYZ(0, 0, -1);
                                XYZ modelOrigin             = XYZ.Zero;

                                XYZ floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top);
                                if (floorOrigin == null)
                                {
                                    // GetVerticalProjectionPoint may return null if FloorFace.Top is an edited face that doesn't
                                    // go through the Revit model origin.  We'll try the midpoint of the bounding box instead.
                                    BoundingBoxXYZ boundingBox = floorElement.get_BoundingBox(null);
                                    modelOrigin = (boundingBox.Min + boundingBox.Max) / 2.0;
                                    floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top);
                                }

                                if (floorOrigin != null)
                                {
                                    XYZ   floorDir = floor.GetNormalAtVerticalProjectionPoint(floorOrigin, FloorFace.Top);
                                    Plane extrusionAnalyzerFloorPlane = new Plane(floorDir, floorOrigin);

                                    GenerateAdditionalInfo additionalInfo     = ExporterCacheManager.ExportOptionsCache.ExportAs4 ? GenerateAdditionalInfo.GenerateFootprint : GenerateAdditionalInfo.None;
                                    HandleAndData          floorAndProperties =
                                        ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, floorElement,
                                                                                                   catId, solids[0], extrusionAnalyzerFloorPlane, floorExtrusionDirection, null, out completelyClipped,
                                                                                                   addInfo: additionalInfo);
                                    if (completelyClipped)
                                    {
                                        return;
                                    }
                                    if (floorAndProperties.Handle != null)
                                    {
                                        IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();
                                        representations.Add(floorAndProperties.Handle);

                                        // Footprint representation will only be exported in export to IFC4
                                        if (((additionalInfo & GenerateAdditionalInfo.GenerateFootprint) != 0) && (floorAndProperties.FootprintRepHandle != null))
                                        {
                                            representations.Add(floorAndProperties.FootprintRepHandle);
                                        }

                                        IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);
                                        prodReps.Add(prodRep);
                                        repTypes.Add(ShapeRepresentationType.SweptSolid);

                                        if (floorAndProperties.Data != null)
                                        {
                                            loopExtraParams.Add(floorAndProperties.Data);
                                        }
                                    }
                                }
                            }
                        }

                        // Use internal routine as backup that handles openings.
                        if (prodReps.Count == 0 && canExportAsInternalExtrusion)
                        {
                            //IList<IFCAnyHandle> prodRepsTmp = new List<IFCAnyHandle>();
                            exportedAsInternalExtrusion = ExporterIFCUtils.ExportSlabAsExtrusion(exporterIFC, floorElement,
                                                                                                 geometryElement, transformSetter, localPlacement, out localPlacements, out prodReps,
                                                                                                 out extrusionLoops, out loopExtraParams, floorPlane);
                            for (int ii = 0; ii < prodReps.Count; ii++)
                            {
                                // all are extrusions
                                repTypes.Add(ShapeRepresentationType.SweptSolid);

                                // Footprint representation will only be exported in export to IFC4
                                if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                                {
                                    // Get back the representations, we need to add the Footprint to it
                                    //IList<IFCAnyHandle> representations = IFCAnyHandleUtil.GetRepresentations(prodRepsTmp[ii]);

                                    if (extrusionLoops.Count > ii)
                                    {
                                        if (extrusionLoops[ii].Count > 0)
                                        {
                                            // Get the extrusion footprint using the first Curveloop. Transform needs to be obtained from the returned local placement
                                            Transform    lcs   = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, localPlacements[ii]);
                                            Plane        plane = new Plane(lcs.BasisX, lcs.BasisY, lcs.Origin);
                                            IFCAnyHandle footprintGeomRepItem = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, extrusionLoops[ii][0], plane, floorPlane.Normal);

                                            IFCAnyHandle        contextOfItemsFootprint = exporterIFC.Get3DContextHandle("FootPrint");
                                            ISet <IFCAnyHandle> repItem = new HashSet <IFCAnyHandle>();
                                            repItem.Add(footprintGeomRepItem);
                                            IFCAnyHandle footprintShapeRepresentation = RepresentationUtil.CreateBaseShapeRepresentation(exporterIFC, contextOfItemsFootprint, "FootPrint", "Curve2D", repItem);
                                            //representations.Add(footprintShapeRepresentation);
                                            IList <IFCAnyHandle> reps = new List <IFCAnyHandle>();
                                            reps.Add(footprintShapeRepresentation);
                                            IFCAnyHandleUtil.AddRepresentations(prodReps[ii], reps);
                                        }
                                    }
                                    //IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);
                                    //prodReps.Add(prodRep);
                                }
                                else
                                {
                                    //prodReps.Add(prodRepsTmp[ii]);
                                }

                                // We do not need the prodRepsTmp anymore, delete the handle:
                                //prodRepsTmp[ii].Delete();
                            }
                        }

                        if (prodReps.Count == 0)
                        {
                            using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                            {
                                // Brep representation using tesellation after ExportSlabAsExtrusion does not return prodReps
                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium);
                                BodyData            bodyData;
                                IFCAnyHandle        prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                                            floorElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData);
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd))
                                {
                                    ecData.ClearOpenings();
                                    return;
                                }

                                prodReps.Add(prodDefHnd);
                                repTypes.Add(bodyData.ShapeRepresentationType);
                            }
                        }

                        // Create the slab from either the extrusion or the BRep information.
                        string ifcGUID = GUIDUtil.CreateGUID(floorElement);

                        int numReps = exportParts ? 1 : prodReps.Count;

                        string entityType = null;

                        switch (exportType)
                        {
                        case IFCExportType.IfcFooting:
                            if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                            {
                                entityType = IFCValidateEntry.GetValidIFCType <Revit.IFC.Export.Toolkit.IFC4.IFCFootingType>(floorElement, ifcEnumType, null);
                            }
                            else
                            {
                                entityType = IFCValidateEntry.GetValidIFCType <IFCFootingType>(floorElement, ifcEnumType, null);
                            }
                            break;

                        case IFCExportType.IfcCovering:
                            entityType = IFCValidateEntry.GetValidIFCType <IFCCoveringType>(floorElement, ifcEnumType, "FLOORING");
                            break;

                        case IFCExportType.IfcRamp:
                            if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                            {
                                entityType = IFCValidateEntry.GetValidIFCType <Revit.IFC.Export.Toolkit.IFC4.IFCRampType>(floorElement, ifcEnumType, null);
                            }
                            else
                            {
                                entityType = IFCValidateEntry.GetValidIFCType <IFCRampType>(floorElement, ifcEnumType, null);
                            }
                            break;

                        default:
                            bool            isBaseSlab      = false;
                            AnalyticalModel analyticalModel = floorElement.GetAnalyticalModel();
                            if (analyticalModel != null)
                            {
                                AnalyzeAs slabFoundationType = analyticalModel.GetAnalyzeAs();
                                isBaseSlab = (slabFoundationType == AnalyzeAs.SlabOnGrade) || (slabFoundationType == AnalyzeAs.Mat);
                            }
                            entityType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(floorElement, ifcEnumType, isBaseSlab ? "BASESLAB" : "FLOOR");
                            break;
                        }

                        for (int ii = 0; ii < numReps; ii++)
                        {
                            string ifcName        = NamingUtil.GetNameOverride(floorElement, NamingUtil.GetIFCNamePlusIndex(floorElement, ii == 0 ? -1 : ii + 1));
                            string ifcDescription = NamingUtil.GetDescriptionOverride(floorElement, null);
                            string ifcObjectType  = NamingUtil.GetObjectTypeOverride(floorElement, exporterIFC.GetFamilyName());
                            string ifcTag         = NamingUtil.GetTagOverride(floorElement, NamingUtil.CreateIFCElementId(floorElement));

                            string       currentGUID       = (ii == 0) ? ifcGUID : GUIDUtil.CreateGUID();
                            IFCAnyHandle localPlacementHnd = exportedAsInternalExtrusion ? localPlacements[ii] : localPlacement;

                            IFCAnyHandle slabHnd = null;

                            // TODO: replace with CreateGenericBuildingElement.
                            switch (exportType)
                            {
                            case IFCExportType.IfcFooting:
                                slabHnd = IFCInstanceExporter.CreateFooting(file, currentGUID, ownerHistory, ifcName,
                                                                            ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                                                            ifcTag, entityType);
                                break;

                            case IFCExportType.IfcCovering:
                                slabHnd = IFCInstanceExporter.CreateCovering(file, currentGUID, ownerHistory, ifcName,
                                                                             ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                                                             ifcTag, entityType);
                                break;

                            case IFCExportType.IfcRamp:
                                slabHnd = IFCInstanceExporter.CreateRamp(file, currentGUID, ownerHistory, ifcName,
                                                                         ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                                                         ifcTag, entityType);
                                break;

                            default:
                                //if ((canExportAsInternalExtrusion || exportedAsInternalExtrusion) && ExporterCacheManager.ExportOptionsCache.ExportAs4)
                                //{
                                //    slabHnd = IFCInstanceExporter.CreateSlabStandardCase(file, currentGUID, ownerHistory, ifcName,
                                //        ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                //        ifcTag, entityType);
                                //}
                                //else
                                slabHnd = IFCInstanceExporter.CreateSlab(file, currentGUID, ownerHistory, ifcName,
                                                                         ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                                                         ifcTag, entityType);
                                break;
                            }

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

                            if (exportParts)
                            {
                                PartExporter.ExportHostPart(exporterIFC, floorElement, slabHnd, productWrapper, placementSetter, localPlacementHnd, null);
                            }

                            slabHnds.Add(slabHnd);

                            if (!exportParts)
                            {
                                if (repTypes[ii] == ShapeRepresentationType.Brep)
                                {
                                    brepSlabHnds.Add(slabHnd);
                                }
                                else
                                {
                                    nonBrepSlabHnds.Add(slabHnd);
                                }
                            }
                        }

                        for (int ii = 0; ii < numReps; ii++)
                        {
                            IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null;
                            productWrapper.AddElement(floorElement, slabHnds[ii], placementSetter, loopExtraParam, true);
                        }

                        // This call to the native function appears to create Brep opening also when appropriate. But the creation of the IFC instances is not
                        //   controllable from the managed code. Therefore in some cases BRep geometry for Opening will still be exported even in the Reference View
                        if (exportedAsInternalExtrusion)
                        {
                            ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, floorElement, placementSetter.LevelInfo,
                                                                        localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative());
                        }
                        //// For now we have to be content without IfcOpeningStandardCase from the openings created by this native call because it is too much to
                        ////    "reverse engineer" the IFChandle
                        //foreach (IFCAnyHandle slabHandle in slabHnds)
                        //{
                        //    updateOpeningProfileRep(exporterIFC, slabHandle);
                        //}
                    }

                    if (!exportParts)
                    {
                        if (nonBrepSlabHnds.Count > 0)
                        {
                            HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, nonBrepSlabHnds,
                                                                         geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false);
                        }
                        if (brepSlabHnds.Count > 0)
                        {
                            HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, brepSlabHnds,
                                                                         geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, true);
                        }
                    }
                }
                tr.Commit();

                return;
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Exports list of geometries to IFC body representation.
        /// </summary>
        /// <param name="application">The Revit application.</param>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="geometryListIn">The geometry list.</param>
        /// <param name="options">The settings for how to export the body.</param>
        /// <param name="exportBodyParams">The extrusion creation data.</param>
        /// <returns>The BodyData containing the handle, offset and material ids.</returns>
        public static BodyData ExportBody(Autodesk.Revit.ApplicationServices.Application application, 
            ExporterIFC exporterIFC,
            Element element, 
            ElementId categoryId,
            IList<GeometryObject> geometryListIn,
            BodyExporterOptions options,
            IFCExtrusionCreationData exportBodyParams) 
        {
            BodyData bodyData = new BodyData();
            if (geometryListIn.Count == 0)
                return bodyData;

            Document document = element.Document;
            bool tryToExportAsExtrusion = options.TryToExportAsExtrusion;
            bool canExportSolidModelRep = false;

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

            double eps = application.VertexTolerance * scale;

            IList<GeometryObject> splitGeometryList = new List<GeometryObject>();

            bool allFaces = true;
            foreach (GeometryObject geomObject in geometryListIn)
            {
                try
                {
                    bool split = false;
                    if (geomObject is Solid)
                    {
                        Solid solid = geomObject as Solid;
                        IList<Solid> splitVolumes = SolidUtils.SplitVolumes(solid);
                        allFaces = false;

                        if (splitVolumes != null && splitVolumes.Count != 0)
                        {
                            split = true;
                            foreach (Solid currSolid in splitVolumes)
                            {
                                splitGeometryList.Add(currSolid);
                                // The geometry element created by SplitVolumesis a copy which will have its own allocated
                                // membership - this needs to be stored and disposed of (see AllocatedGeometryObjectCache
                                // for details)
                                ExporterCacheManager.AllocatedGeometryObjectCache.AddGeometryObject(currSolid);
                            }
                        }
                    }
                    else if (allFaces && !(geomObject is Face))
                        allFaces = false;

                    if (!split)
                        splitGeometryList.Add(geomObject);
                }
                catch
                {
                    splitGeometryList.Add(geomObject);
                }
            }

            IList<IFCAnyHandle> bodyItems = new List<IFCAnyHandle>();
            IList<ElementId> materialIdsForExtrusions = new List<ElementId>();

            IList<int> exportAsBRep = new List<int>();
            IList<int> exportAsExtrusion = new List<int>();
            
            using (IFCTransaction tr = new IFCTransaction(file))
            {
                if (tryToExportAsExtrusion)
                {
                    // Check to see if we have Geometries or GFaces.
                    // We will have the specific all GFaces case and then the generic case.
                    IList<Face> faces = null;

                    if (allFaces)
                    {
                        faces = new List<Face>();
                        foreach (GeometryObject geometryObject in splitGeometryList)
                        {
                            faces.Add(geometryObject as Face);
                        }
                    }

                    int numExtrusionsToCreate = allFaces ? 1 : splitGeometryList.Count;

                    IList<IList<IFCExtrusionData>> extrusionLists = new List<IList<IFCExtrusionData>>();
                    for (int ii = 0; ii < numExtrusionsToCreate && tryToExportAsExtrusion; ii++)
                    {
                        IList<IFCExtrusionData> extrusionList = new List<IFCExtrusionData>();

                        IFCExtrusionAxes axesToExtrudeIn = exportBodyParams != null ? exportBodyParams.PossibleExtrusionAxes : IFCExtrusionAxes.TryDefault;
                        XYZ directionToExtrudeIn = XYZ.Zero;
                        if (exportBodyParams != null && exportBodyParams.HasCustomAxis)
                            directionToExtrudeIn = exportBodyParams.CustomAxis;

                        IFCExtrusionCalculatorOptions extrusionOptions =
                           new IFCExtrusionCalculatorOptions(exporterIFC, axesToExtrudeIn, directionToExtrudeIn, scale);

                        if (allFaces)
                            extrusionList = IFCExtrusionCalculatorUtils.CalculateExtrusionData(extrusionOptions, faces);
                        else
                            extrusionList = IFCExtrusionCalculatorUtils.CalculateExtrusionData(extrusionOptions, splitGeometryList[ii]);

                        if (extrusionList.Count == 0)
                        {
                            if (!canExportSolidModelRep)
                            {
                                tryToExportAsExtrusion = false;
                                break;
                            }
                            exportAsBRep.Add(ii);
                        }
                        else
                        {
                            extrusionLists.Add(extrusionList);
                            exportAsExtrusion.Add(ii);
                        }
                    }

                    int numCreatedExtrusions = extrusionLists.Count;
                    for (int ii = 0; (ii < numCreatedExtrusions) && tryToExportAsExtrusion; ii++)
                    {
                        int geomIndex = exportAsExtrusion[ii];
                        bodyData.AddMaterial(SetBestMaterialIdInExporter(splitGeometryList[geomIndex], exporterIFC));

                        if (exportBodyParams != null && exportBodyParams.AreInnerRegionsOpenings)
                        {
                            IList<CurveLoop> curveLoops = extrusionLists[ii][0].GetLoops();
                            XYZ extrudedDirection = extrusionLists[ii][0].ExtrusionDirection;

                            int numLoops = curveLoops.Count;
                            for (int jj = numLoops - 1; jj > 0; jj--)
                            {
                                ExtrusionExporter.AddOpeningData(exportBodyParams, extrusionLists[ii][0], curveLoops[jj]);
                                extrusionLists[ii][0].RemoveLoopAt(jj);
                            }
                        }

                        bool exportedAsExtrusion = false;
                        IFCExtrusionBasis whichBasis = extrusionLists[ii][0].ExtrusionBasis;
                        if (whichBasis >= 0)
                        {
                            IFCAnyHandle extrusionHandle = ExtrusionExporter.CreateExtrudedSolidFromExtrusionData(exporterIFC, element, extrusionLists[ii][0]);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionHandle))
                            {
                                bodyItems.Add(extrusionHandle);
                                materialIdsForExtrusions.Add(exporterIFC.GetMaterialIdForCurrentExportState());

                                IList<CurveLoop> curveLoops = extrusionLists[ii][0].GetLoops();
                                XYZ extrusionDirection = extrusionLists[ii][0].ExtrusionDirection;

                                if (exportBodyParams != null)
                                {
                                    double zOff = (whichBasis == IFCExtrusionBasis.BasisZ) ? (1.0 - Math.Abs(extrusionDirection[2])) : Math.Abs(extrusionDirection[2]);
                                    double scaledAngle = Math.Asin(zOff) * 180 / Math.PI;
                                    exportBodyParams.Slope = scaledAngle;
                                    exportBodyParams.ScaledLength = extrusionLists[ii][0].ScaledExtrusionLength;
                                    exportBodyParams.ExtrusionDirection = extrusionDirection;
                                    for (int kk = 1; kk < extrusionLists[ii].Count; kk++)
                                    {
                                        ExtrusionExporter.AddOpeningData(exportBodyParams, extrusionLists[ii][kk]);
                                    }

                                    Plane plane = null;
                                    double height = 0.0, width = 0.0;
                                    if (ExtrusionExporter.ComputeHeightWidthOfCurveLoop(curveLoops[0], plane, out height, out width))
                                    {
                                        exportBodyParams.ScaledHeight = height * scale;
                                        exportBodyParams.ScaledWidth = width * scale;
                                    }

                                    double area = ExporterIFCUtils.ComputeAreaOfCurveLoops(curveLoops);
                                    if (area > 0.0)
                                    {
                                        exportBodyParams.ScaledArea = area * scale * scale;
                                    }

                                    double innerPerimeter = ExtrusionExporter.ComputeInnerPerimeterOfCurveLoops(curveLoops);
                                    double outerPerimeter = ExtrusionExporter.ComputeOuterPerimeterOfCurveLoops(curveLoops);
                                    if (innerPerimeter > 0.0)
                                        exportBodyParams.ScaledInnerPerimeter = innerPerimeter * scale;
                                    if (outerPerimeter > 0.0)
                                        exportBodyParams.ScaledOuterPerimeter = outerPerimeter * scale;
                                }
                                exportedAsExtrusion = true;
                            }
                        }

                        if (!exportedAsExtrusion)
                        {
                            if (!canExportSolidModelRep)
                            {
                                tryToExportAsExtrusion = false;
                                break;
                            }
                            exportAsBRep.Add(ii);
                        }
                    }
                }

                if ((exportAsBRep.Count == 0) && tryToExportAsExtrusion)
                {
                    int sz = bodyItems.Count();
                    for (int ii = 0; ii < sz; ii++)
                        BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, bodyItems[ii], materialIdsForExtrusions[ii]);

                    bodyData.RepresentationHnd =
                        RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItems, bodyData.RepresentationHnd);
                }

                if (tryToExportAsExtrusion)
                    tr.Commit();
                else
                    tr.RollBack();

                if ((exportAsBRep.Count == 0) && tryToExportAsExtrusion)
                    return bodyData;
            }
            
            // We couldn't export it as an extrusion; export as a solid, brep, or a surface model.
            if (!canExportSolidModelRep)
            {
                exportAsExtrusion.Clear();
                bodyItems.Clear();
                if (exportBodyParams != null)
                    exportBodyParams.ClearOpenings();
            }

            if (exportAsExtrusion.Count == 0)
                exportAsBRep.Clear();

            // generate "bottom corner" of bbox; create new local placement if passed in.
            // need to transform, but not scale, this point to make it the new origin.
            // We will only do this if we didn't create any extrusions at all.
            using (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
            {
                if (exportBodyParams != null && (exportAsBRep.Count == 0))
                    bodyData.BrepOffsetTransform = transformSetter.InitializeFromBoundingBox(exporterIFC, splitGeometryList, exportBodyParams);

                return ExportBodyAsBRep(exporterIFC, splitGeometryList, exportAsBRep, bodyItems, element, categoryId, contextOfItems, eps, options, bodyData);
            }
        }
Ejemplo n.º 20
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>();

            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);
        }
        /// <summary>
        /// Creates IFC room/space/area item, not include boundaries. 
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="spatialElement">
        /// The spatial element.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        /// <param name="setter">
        /// The IFCPlacementSetter.
        /// </param>
        /// <returns>
        /// True if created successfully, false otherwise.
        /// </returns>
        static bool CreateIFCSpace(ExporterIFC exporterIFC, SpatialElement spatialElement, ProductWrapper productWrapper, IFCPlacementSetter setter)
        {
            IList<CurveLoop> curveLoops = null;
            try
            {
                SpatialElementBoundaryOptions options = ExporterIFCUtils.GetSpatialElementBoundaryOptions(exporterIFC, spatialElement);
                curveLoops = ExporterIFCUtils.GetRoomBoundaryAsCurveLoopArray(spatialElement, options, true);
            }
            catch (Autodesk.Revit.Exceptions.InvalidOperationException)
            {
                //Some spatial elements are not placed that have no boundary loops. Don't export them.
                return false;
            }

            Autodesk.Revit.DB.Document document = spatialElement.Document;
            ElementId levelId = spatialElement.Level != null ? spatialElement.Level.Id : ElementId.InvalidElementId;
            double scale = exporterIFC.LinearScale;

            ElementId catId = spatialElement.Category != null ? spatialElement.Category.Id : ElementId.InvalidElementId;

            double dArea = 0.0;
            if (ParameterUtil.GetDoubleValueFromElement(spatialElement, BuiltInParameter.ROOM_AREA, out dArea))
                dArea *= (scale * scale);

            IFCLevelInfo levelInfo = exporterIFC.GetLevelInfo(levelId);

            string strSpaceNumber = null;
            string strSpaceName = null;
            string strSpaceDesc = null;

            bool isArea = spatialElement is Area;
            if (!isArea)
            {
                if (!ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ROOM_NUMBER, out strSpaceNumber))
                    strSpaceNumber = null;

                if (!ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ROOM_NAME, out strSpaceName))
                    strSpaceName = null;

                if (!ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS, out strSpaceDesc))
                    strSpaceDesc = null;
            }
            else
            {
                // Default to true to preserve previous behavior.
                bool? exportGSADesignGrossArea = ExporterCacheManager.ExportOptionsCache.ExportGSAGrossDesignArea;
                if (!exportGSADesignGrossArea.HasValue || exportGSADesignGrossArea.Value)
                {
                    Element level = document.GetElement(levelId);
                    if (level != null)
                    {
                        strSpaceNumber = level.Name + " GSA Design Gross Area";
                    }
                }
            }

            string name = strSpaceNumber;
            string longName = strSpaceName;
            string desc = strSpaceDesc;

            IFCFile file = exporterIFC.GetFile();

            IFCAnyHandle localPlacement = setter.GetPlacement();
            ElementType elemType = document.GetElement(spatialElement.GetTypeId()) as ElementType;
            IFCInternalOrExternal internalOrExternal = CategoryUtil.IsElementExternal(spatialElement, true) ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal;

            double roomHeight = 0.0;

            roomHeight = GetHeight(spatialElement, scale, levelId, levelInfo);
            if (roomHeight <= 0.0)
                return false;

            double bottomOffset;
            ParameterUtil.GetDoubleValueFromElement(spatialElement, BuiltInParameter.ROOM_LOWER_OFFSET, out bottomOffset);

            XYZ zDir = new XYZ(0, 0, 1);
            XYZ orig = new XYZ(0, 0, levelInfo.Elevation + bottomOffset);

            Plane plane = new Plane(zDir, orig); // room calculated as level offset.

            GeometryElement geomElem = null;
            if (spatialElement is Autodesk.Revit.DB.Architecture.Room)
            {
                Autodesk.Revit.DB.Architecture.Room room = spatialElement as Autodesk.Revit.DB.Architecture.Room;
                geomElem = room.ClosedShell;
            }
            else if (spatialElement is Autodesk.Revit.DB.Mechanical.Space)
            {
                Autodesk.Revit.DB.Mechanical.Space space = spatialElement as Autodesk.Revit.DB.Mechanical.Space;
                geomElem = space.ClosedShell;
            }

            IFCAnyHandle spaceHnd = null;
            using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
            {
                extraParams.SetLocalPlacement(localPlacement);
                extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;

                using (IFCTransaction transaction2 = new IFCTransaction(file))
                {
                    IFCAnyHandle repHnd = null;
                    if (!ExporterCacheManager.ExportOptionsCache.Use2DRoomBoundaryForRoomVolumeCreation && geomElem != null)
                    {
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        bodyExporterOptions.TessellationLevel = BodyExporterOptions.BodyTessellationLevel.Coarse;
                        repHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, spatialElement,
                            catId, geomElem, bodyExporterOptions, null, extraParams);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                            extraParams.ClearOpenings();
                    }
                    else
                    {
                        IFCAnyHandle shapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, plane, zDir, roomHeight);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
                            return false;
                        IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document,
                            shapeRep, ElementId.InvalidElementId);

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

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

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

                    extraParams.ScaledHeight = roomHeight;
                    extraParams.ScaledArea = dArea;

                    string spatialElementName = NamingUtil.GetNameOverride(spatialElement, name);
                    string spatialElementDescription = NamingUtil.GetDescriptionOverride(spatialElement, desc);
                    string spatialElementObjectType = NamingUtil.GetObjectTypeOverride(spatialElement, null);

                    double? spaceElevationWithFlooring = null;
                    double elevationWithFlooring = 0.0;
                    if (ParameterUtil.GetDoubleValueFromElement(spatialElement, "IfcElevationWithFlooring", out elevationWithFlooring) == true)
                        spaceElevationWithFlooring = elevationWithFlooring;
                    spaceHnd = IFCInstanceExporter.CreateSpace(file, GUIDUtil.CreateGUID(spatialElement),
                                                  exporterIFC.GetOwnerHistoryHandle(),
                                                  spatialElementName,spatialElementDescription, spatialElementObjectType,
                                                  extraParams.GetLocalPlacement(), repHnd, longName, Toolkit.IFCElementComposition.Element,
                                                  internalOrExternal, spaceElevationWithFlooring);

                    transaction2.Commit();
                }

                productWrapper.AddSpace(spaceHnd, levelInfo, extraParams, true);
            }

            // Save room handle for later use/relationships
            ExporterCacheManager.SpatialElementHandleCache.Register(spatialElement.Id, spaceHnd);
            exporterIFC.RegisterSpatialElementHandle(spatialElement.Id, spaceHnd);

            // Find Ceiling as a Space boundary and keep the relationship in a cache for use later
            Boolean ret = getCeilingSpaceBoundary(spatialElement);

            if (!MathUtil.IsAlmostZero(dArea) && !(ExporterCacheManager.ExportOptionsCache.FileVersion == IFCVersion.IFCCOBIE) &&
                !ExporterCacheManager.ExportOptionsCache.ExportAs2x3CoordinationView2 && !ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
            {
                ExporterIFCUtils.CreatePreCOBIEGSAQuantities(exporterIFC, spaceHnd, "GSA Space Areas", (isArea ? "GSA Design Gross Area" : "GSA BIM Area"), dArea);
            }

            // Export BaseQuantities for SpatialElement
            if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities && !(ExporterCacheManager.ExportOptionsCache.FileVersion == IFCVersion.IFCCOBIE))
            {
                // Skip this step. The "standard" quantities will be exported at the end of export element process in exportElement (Exporter.cs)
                // ExporterIFCUtils.CreateNonCOBIERoomQuantities(exporterIFC, spaceHnd, spatialElement, dArea, roomHeight);
            }

            // Create general classification for Spatial element from ClassificationCode(s). This is not done here but rather at the end of exportElement process
            // ClassificationUtil.CreateClassification(exporterIFC, file, spatialElement, spaceHnd, "");

            // Export Classifications for SpatialElement for GSA/COBIE.
            if (ExporterCacheManager.ExportOptionsCache.FileVersion == IFCVersion.IFCCOBIE)
            {
                CreateCOBIESpaceClassifications(exporterIFC, file, spaceHnd, document.ProjectInformation, spatialElement);
            }

            return true;
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Main implementation to export walls.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="element">
        /// The element.
        /// </param>
        /// <param name="geometryElement">
        /// The geometry element.
        /// </param>
        /// <param name="origWrapper">
        /// The ProductWrapper.
        /// </param>
        /// <param name="overrideLevelId">
        /// The level id.
        /// </param>
        /// <param name="range">
        /// The range to be exported for the element.
        /// </param>
        /// <returns>
        /// The exported wall handle.
        /// </returns>
        public static IFCAnyHandle ExportWallBase(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
           ProductWrapper origWrapper, ElementId overrideLevelId, IFCRange range)
        {
            IFCFile file = exporterIFC.GetFile();
            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (ProductWrapper localWrapper = ProductWrapper.Create(origWrapper))
                {
                    ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                    Wall wallElement = element as Wall;
                    FamilyInstance famInstWallElem = element as FamilyInstance;
                    FaceWall faceWall = element as FaceWall;
                    
                    if (wallElement == null && famInstWallElem == null && faceWall == null)
                        return null;

                    if (wallElement != null && IsWallCompletelyClipped(wallElement, exporterIFC, range))
                        return null;

                    Document doc = element.Document;
                    double scale = exporterIFC.LinearScale;
                    
                    double baseWallElevation = 0.0;
                    ElementId baseLevelId = ExporterUtil.GetBaseLevelIdForElement(element);
                    if (baseLevelId != ElementId.InvalidElementId)
                    {
                        Element baseLevel = doc.GetElement(baseLevelId);
                        if (baseLevel is Level)
                            baseWallElevation = (baseLevel as Level).Elevation;
                    }
                    
                    IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                    IFCAnyHandle contextOfItemsAxis = exporterIFC.Get3DContextHandle("Axis");
                    IFCAnyHandle contextOfItemsBody = exporterIFC.Get3DContextHandle("Body");

                    IFCRange zSpan = new IFCRange();
                    double depth = 0.0;
                    bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End));

                    bool exportParts = PartExporter.CanExportParts(element);
                    if (exportParts && !PartExporter.CanExportElementInPartExport(element, validRange ? overrideLevelId : element.Level.Id, validRange))
                        return null;

                    // get bounding box height so that we can subtract out pieces properly.
                    // only for Wall, not FamilyInstance.
                    if (wallElement != null && geometryElement != null)
                    {
                        BoundingBoxXYZ boundingBox = element.get_BoundingBox(null);
                        if (boundingBox == null)
                            return null;
                        zSpan = new IFCRange(boundingBox.Min.Z, boundingBox.Max.Z);

                        // if we have a top clipping plane, modify depth accordingly.
                        double bottomHeight = validRange ? Math.Max(zSpan.Start, range.Start) : zSpan.Start;
                        double topHeight = validRange ? Math.Min(zSpan.End, range.End) : zSpan.End;
                        depth = topHeight - bottomHeight;
                        if (MathUtil.IsAlmostZero(depth))
                            return null;
                        depth *= scale;
                    }

                    IFCAnyHandle axisRep = null;
                    IFCAnyHandle bodyRep = null;

                    bool exportingAxis = false;
                    Curve curve = null;

                    bool exportedAsWallWithAxis = false;
                    bool exportedBodyDirectly = false;
                    bool exportingInplaceOpenings = false;

                    Curve centerCurve = GetWallAxis(wallElement);

                    XYZ localXDir = new XYZ(1, 0, 0);
                    XYZ localYDir = new XYZ(0, 1, 0);
                    XYZ localZDir = new XYZ(0, 0, 1);
                    XYZ localOrig = new XYZ(0, 0, 0);
                    double eps = MathUtil.Eps();

                    if (centerCurve != null)
                    {
                        Curve baseCurve = GetWallAxisAtBaseHeight(wallElement);
                        curve = GetWallTrimmedCurve(wallElement, baseCurve);

                        IFCRange curveBounds;
                        XYZ oldOrig;
                        GeometryUtil.GetAxisAndRangeFromCurve(curve, out curveBounds, out localXDir, out oldOrig);

                        localOrig = oldOrig;
                        if (baseCurve != null)
                        {
                            if (!validRange || (MathUtil.IsAlmostEqual(range.Start, zSpan.Start)))
                            {
                                XYZ newOrig = baseCurve.Evaluate(curveBounds.Start, false);
                                if (!validRange && (zSpan.Start < newOrig[2] - eps))
                                    localOrig = new XYZ(localOrig.X, localOrig.Y, zSpan.Start);
                                else
                                    localOrig = new XYZ(localOrig.X, localOrig.Y, newOrig[2]);
                            }
                            else
                            {
                                localOrig = new XYZ(localOrig.X, localOrig.Y, range.Start);
                            }
                        }

                        double dist = localOrig[2] - oldOrig[2];
                        if (!MathUtil.IsAlmostZero(dist))
                        {
                            XYZ moveVec = new XYZ(0, 0, dist);
                            curve = GeometryUtil.MoveCurve(curve, moveVec);
                        }
                        localYDir = localZDir.CrossProduct(localXDir);

                        // ensure that X and Z axes are orthogonal.
                        double xzDot = localZDir.DotProduct(localXDir);
                        if (!MathUtil.IsAlmostZero(xzDot))
                            localXDir = localYDir.CrossProduct(localZDir);
                    }
                    else
                    {
                        BoundingBoxXYZ boundingBox = element.get_BoundingBox(null);
                        if (boundingBox != null)
                        {
                            XYZ bBoxMin = boundingBox.Min;
                            XYZ bBoxMax = boundingBox.Max;
                            if (validRange)
                                localOrig = new XYZ(bBoxMin.X, bBoxMin.Y, range.Start);
                            else
                                localOrig = boundingBox.Min;

                            XYZ localXDirMax = null;
                            Transform bTrf = boundingBox.Transform;
                            XYZ localXDirMax1 = new XYZ(bBoxMax.X, localOrig.Y, localOrig.Z);
                            localXDirMax1 = bTrf.OfPoint(localXDirMax1);
                            XYZ localXDirMax2 = new XYZ(localOrig.X, bBoxMax.Y, localOrig.Z);
                            localXDirMax2 = bTrf.OfPoint(localXDirMax2);
                            if (localXDirMax1.DistanceTo(localOrig) >= localXDirMax2.DistanceTo(localOrig))
                                localXDirMax = localXDirMax1;
                            else
                                localXDirMax = localXDirMax2;
                            localXDir = localXDirMax.Subtract(localOrig);
                            localXDir = localXDir.Normalize();
                            localYDir = localZDir.CrossProduct(localXDir);

                            // ensure that X and Z axes are orthogonal.
                            double xzDot = localZDir.DotProduct(localXDir);
                            if (!MathUtil.IsAlmostZero(xzDot))
                                localXDir = localYDir.CrossProduct(localZDir);
                        }
                    }

                    Transform orientationTrf = Transform.Identity;
                    orientationTrf.BasisX = localXDir;
                    orientationTrf.BasisY = localYDir;
                    orientationTrf.BasisZ = localZDir;
                    orientationTrf.Origin = localOrig;

                    if (overrideLevelId == ElementId.InvalidElementId)
                        overrideLevelId = ExporterUtil.GetBaseLevelIdForElement(element);
                    using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element, null, orientationTrf, overrideLevelId))
                    {
                        IFCAnyHandle localPlacement = setter.GetPlacement();

                        Plane plane = new Plane(localXDir, localYDir, localOrig);  // project curve to XY plane.
                        XYZ projDir = XYZ.BasisZ;

                        // two representations: axis, body.         
                        {
                            if (!exportParts && (centerCurve != null) && (GeometryUtil.CurveIsLineOrArc(centerCurve)))
                            {
                                exportingAxis = true;

                                string identifierOpt = "Axis";	// IFC2x2 convention
                                string representationTypeOpt = "Curve2D";  // IFC2x2 convention

                                IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, plane, projDir, false);
                                ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, curve, XYZ.Zero, true);
                                IList<IFCAnyHandle> axisItems = info.GetCurves();

                                if (axisItems.Count == 0)
                                {
                                    exportingAxis = false;
                                }
                                else
                                {
                                    HashSet<IFCAnyHandle> axisItemSet = new HashSet<IFCAnyHandle>();
                                    foreach (IFCAnyHandle axisItem in axisItems)
                                        axisItemSet.Add(axisItem);

                                    axisRep = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, contextOfItemsAxis,
                                       identifierOpt, representationTypeOpt, axisItemSet);
                                }
                            }
                        }

                        IList<IFCExtrusionData> cutPairOpenings = new List<IFCExtrusionData>();
                        Document document = element.Document;

                        IList<Solid> solids = new List<Solid>();
                        IList<Mesh> meshes = new List<Mesh>();

                        if (!exportParts && wallElement != null && exportingAxis && curve != null)
                        {
                            SolidMeshGeometryInfo solidMeshInfo =
                                (range == null) ? GeometryUtil.GetSplitSolidMeshGeometry(geometryElement) :
                                    GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range);

                            solids = solidMeshInfo.GetSolids();
                            meshes = solidMeshInfo.GetMeshes();
                            if (solids.Count == 0 && meshes.Count == 0)
                                return null;

                            bool useNewCode = false;
                            if (useNewCode && solids.Count == 1 && meshes.Count == 0)
                            {
                                bool completelyClipped;
                                bodyRep = ExtrusionExporter.CreateExtrusionWithClipping(exporterIFC, wallElement, catId, solids[0],
                                    plane, projDir, range, out completelyClipped);

                                if (completelyClipped)
                                    return null;

                                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                                {
                                    exportedAsWallWithAxis = true;
                                    exportedBodyDirectly = true;
                                }
                                else
                                {
                                    exportedAsWallWithAxis = false;
                                    exportedBodyDirectly = false;
                                }
                            }

                            if (!exportedAsWallWithAxis)
                            {
                                // Fallback - use native routines to try to export wall.
                                bool isCompletelyClipped;
                                bodyRep = FallbackTryToCreateAsExtrusion(exporterIFC, wallElement, solidMeshInfo, baseWallElevation,
                                    catId, curve, plane, depth, zSpan, range, setter,
                                    out cutPairOpenings, out isCompletelyClipped);
                                if (isCompletelyClipped)
                                    return null;
                                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                                    exportedAsWallWithAxis = true;
                            }
                        }

                        using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                        {
                            BodyData bodyData = null;

                            if (!exportedAsWallWithAxis)
                            {
                                SolidMeshGeometryInfo solidMeshCapsule = null;

                                if (wallElement != null || faceWall != null)
                                {
                                    if (validRange)
                                    {
                                        solidMeshCapsule = GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range);
                                    }
                                    else
                                    {
                                        solidMeshCapsule = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                                    }
                                    if (solidMeshCapsule.SolidsCount() == 0 && solidMeshCapsule.MeshesCount() == 0)
                                    {
                                        return null;
                                    }
                                }
                                else
                                {
                                    GeometryElement geomElemToUse = GetGeometryFromInplaceWall(famInstWallElem);
                                    if (geomElemToUse != null)
                                    {
                                        exportingInplaceOpenings = true;
                                    }
                                    else
                                    {
                                        exportingInplaceOpenings = false;
                                        geomElemToUse = geometryElement;
                                    }
                                    Transform trf = Transform.Identity;
                                    if (geomElemToUse != geometryElement)
                                        trf = famInstWallElem.GetTransform();
                                    solidMeshCapsule = GeometryUtil.GetSplitSolidMeshGeometry(geomElemToUse, trf);
                                }

                                solids = solidMeshCapsule.GetSolids();
                                meshes = solidMeshCapsule.GetMeshes();

                                extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;   // only allow vertical extrusions!
                                extraParams.AreInnerRegionsOpenings = true;

                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                                
                                // Swept solids are not natively exported as part of CV2.0.  
                                // We have removed the UI toggle for this, so that it is by default false, but keep for possible future use.
                                if (ExporterCacheManager.ExportOptionsCache.ExportAdvancedSweptSolids)
                                    bodyExporterOptions.TryToExportAsSweptSolid = true;

                                ElementId overrideMaterialId = ElementId.InvalidElementId;
                                if (wallElement != null)
                                    overrideMaterialId = HostObjectExporter.GetFirstLayerMaterialId(wallElement);

                                if (!exportParts)
                                {
                                    if ((solids.Count > 0) || (meshes.Count > 0))
                                    {
                                        bodyRep = BodyExporter.ExportBody(exporterIFC, element, catId, overrideMaterialId,
                                            solids, meshes, bodyExporterOptions, extraParams).RepresentationHnd;
                                    }
                                    else
                                    {
                                        IList<GeometryObject> geomElemList = new List<GeometryObject>();
                                        geomElemList.Add(geometryElement);
                                        bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, overrideMaterialId,
                                            geomElemList, bodyExporterOptions, extraParams);
                                        bodyRep = bodyData.RepresentationHnd;
                                    }

                                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                                    {
                                        extraParams.ClearOpenings();
                                        return null;
                                    }
                                }

                                // We will be able to export as a IfcWallStandardCase as long as we have an axis curve.
                                XYZ extrDirUsed = XYZ.Zero;
                                if (extraParams.HasExtrusionDirection)
                                {
                                    extrDirUsed = extraParams.ExtrusionDirection;
                                    if (MathUtil.IsAlmostEqual(Math.Abs(extrDirUsed[2]), 1.0))
                                    {
                                        if ((solids.Count == 1) && (meshes.Count == 0))
                                            exportedAsWallWithAxis = exportingAxis;
                                        exportedBodyDirectly = true;
                                    }
                                }
                            }

                            IFCAnyHandle prodRep = null;
                            if (!exportParts)
                            {
                                IList<IFCAnyHandle> representations = new List<IFCAnyHandle>();
                                if (exportingAxis)
                                    representations.Add(axisRep);

                                representations.Add(bodyRep);

                                IFCAnyHandle boundingBoxRep = null;
                                if ((solids.Count > 0) || (meshes.Count > 0))
                                    boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, solids, meshes, Transform.Identity);
                                else
                                    boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity);

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

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

                            ElementId matId = ElementId.InvalidElementId;
                            string objectType = NamingUtil.CreateIFCObjectName(exporterIFC, element);
                            IFCAnyHandle wallHnd = null;

                            string elemGUID = (validRange) ? GUIDUtil.CreateGUID() : GUIDUtil.CreateGUID(element);
                            string elemName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                            string elemDesc = NamingUtil.GetDescriptionOverride(element, null);
                            string elemObjectType = NamingUtil.GetObjectTypeOverride(element, objectType);
                            string elemTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

                            // For Foundation and Retaining walls, allow exporting as IfcFooting instead.
                            bool exportAsFooting = false;
                            string enumTypeValue = null;

                            if (wallElement != null)
                            {
                                WallType wallType = wallElement.WallType;

                                if (wallType != null)
                                {
                                    int wallFunction;
                                    if (ParameterUtil.GetIntValueFromElement(wallType, BuiltInParameter.FUNCTION_PARAM, out wallFunction) != null)
                                    {
                                        if (wallFunction == (int)WallFunction.Retaining || wallFunction == (int)WallFunction.Foundation)
                                        {
                                            // In this case, allow potential to export foundation and retaining walls as footing.
                                            IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, wallElement, out enumTypeValue);
                                            if (exportType == IFCExportType.ExportFooting)
                                                exportAsFooting = true;
                                        }
                                    }
                                }
                            }

                            if (exportedAsWallWithAxis)
                            {
                                if (exportAsFooting)
                                {
                                    Toolkit.IFCFootingType footingType = FootingExporter.GetIFCFootingType(element, enumTypeValue);
                                    wallHnd = IFCInstanceExporter.CreateFooting(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                        localPlacement, exportParts ? null : prodRep, elemTag, footingType);
                                }
                                else if (exportParts)
                                {
                                    wallHnd = IFCInstanceExporter.CreateWall(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                        localPlacement, null, elemTag);
                                }
                                else
                                {
                                    wallHnd = IFCInstanceExporter.CreateWallStandardCase(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                        localPlacement, prodRep, elemTag);
                                }

                                if (exportParts)
                                    PartExporter.ExportHostPart(exporterIFC, element, wallHnd, localWrapper, setter, localPlacement, overrideLevelId);

                                localWrapper.AddElement(element, wallHnd, setter, extraParams, true);

                                if (!exportParts)
                                {
                                    OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, cutPairOpenings, null,
                                        exporterIFC, localPlacement, setter, localWrapper);
                                    if (exportedBodyDirectly)
                                    {
                                        Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity;
                                        OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, extraParams, offsetTransform,
                                            exporterIFC, localPlacement, setter, localWrapper);
                                    }
                                    else
                                    {
                                        ICollection<IFCAnyHandle> beforeOpenings = localWrapper.GetAllObjects();
                                        double scaledWidth = wallElement.Width * scale;
                                        ExporterIFCUtils.AddOpeningsToElement(exporterIFC, wallHnd, wallElement, scaledWidth, range, setter, localPlacement, localWrapper.ToNative());
                                        ICollection<IFCAnyHandle> afterOpenings = localWrapper.GetAllObjects();
                                        if (beforeOpenings.Count != afterOpenings.Count)
                                        {
                                            foreach (IFCAnyHandle before in beforeOpenings)
                                                afterOpenings.Remove(before);
                                            foreach (IFCAnyHandle potentiallyBadOpening in afterOpenings)
                                            {
                                                PotentiallyCorrectOpeningOrientationAndOpeningType(potentiallyBadOpening, localPlacement, scaledWidth);
                                            }
                                        }
                                    }
                                }

                                // export Base Quantities
                                if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
                                {
                                    CreateWallBaseQuantities(exporterIFC, wallElement, wallHnd, depth);
                                }
                            }
                            else
                            {
                                if (exportAsFooting)
                                {
                                    Toolkit.IFCFootingType footingType = FootingExporter.GetIFCFootingType(element, enumTypeValue);
                                    wallHnd = IFCInstanceExporter.CreateFooting(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                        localPlacement, exportParts ? null : prodRep, elemTag, footingType);
                                }
                                else
                                {
                                    wallHnd = IFCInstanceExporter.CreateWall(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                        localPlacement, exportParts ? null : prodRep, elemTag);
                                }

                                if (exportParts)
                                    PartExporter.ExportHostPart(exporterIFC, element, wallHnd, localWrapper, setter, localPlacement, overrideLevelId);

                                localWrapper.AddElement(element, wallHnd, setter, extraParams, true);

                                if (!exportParts)
                                {
                                    // Only export one material for 2x2; for future versions, export the whole list.
                                    if (exporterIFC.ExportAs2x2 || famInstWallElem != null)
                                    {
                                        matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(solids, meshes, element);
                                        if (matId != ElementId.InvalidElementId)
                                            CategoryUtil.CreateMaterialAssociation(exporterIFC, wallHnd, matId);
                                    }

                                    if (exportingInplaceOpenings)
                                    {
                                        ExporterIFCUtils.AddOpeningsToElement(exporterIFC, wallHnd, famInstWallElem, 0.0, range, setter, localPlacement, localWrapper.ToNative());
                                    }

                                    if (exportedBodyDirectly)
                                    {
                                        Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity;
                                        OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, extraParams, offsetTransform,
                                            exporterIFC, localPlacement, setter, localWrapper);
                                    }
                                }
                            }

                            ElementId wallLevelId = (validRange) ? setter.LevelId : ElementId.InvalidElementId;

                            if ((wallElement != null || faceWall != null) && !exportParts)
                            {
                                HostObject hostObject = null;
                                if (wallElement != null)
                                    hostObject = wallElement;
                                else
                                    hostObject = faceWall;
                                if (!exporterIFC.ExportAs2x2 || exportedAsWallWithAxis)
                                    HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, localWrapper.GetAnElement(),
                                        geometryElement, localWrapper, wallLevelId, Toolkit.IFCLayerSetDirection.Axis2, !exportedAsWallWithAxis);
                            }

                            ExportWallType(exporterIFC, localWrapper, wallHnd, element, matId, exportedAsWallWithAxis, exportAsFooting);

                            exporterIFC.RegisterSpaceBoundingElementHandle(wallHnd, element.Id, wallLevelId);

                            tr.Commit();
                            return wallHnd;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Creates a extruded product definition shape representation.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The base element.</param>
        /// <param name="categoryId">The category of the element.</param>
        /// <param name="curveLoops">The curve loops defining the extruded surface.</param>
        /// <param name="plane">The extrusion base plane.</param>
        /// <param name="extrDirVec">The extrusion direction.</param>
        /// <param name="extrusionSize">The scaled extrusion length.</param>
        /// <returns>The handle.</returns>
        public static IFCAnyHandle CreateExtrudedProductDefShape(ExporterIFC exporterIFC, Element element, ElementId categoryId,
            IList<CurveLoop> curveLoops, Plane plane, XYZ extrDirVec, double extrusionSize)
        {
            IFCFile file = exporterIFC.GetFile();

            IFCAnyHandle extrusionHnd = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, plane,
                extrDirVec, extrusionSize);

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionHnd))
                return null;

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

            IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body");
            IFCAnyHandle shapeRepHnd = CreateSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItems, null);

            IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>();
            shapeReps.Add(shapeRepHnd);
            return IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
        }
Ejemplo n.º 24
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();
            }
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Main implementation to export walls.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="element">
        /// The element.
        /// </param>
        /// <param name="geometryElement">
        /// The geometry element.
        /// </param>
        /// <param name="origWrapper">
        /// The IFCProductWrapper.
        /// </param>
        /// <param name="overrideLevelId">
        /// The level id.
        /// </param>
        /// <param name="range">
        /// The range to be exported for the element.
        /// </param>
        /// <returns>
        /// The exported wall handle.
        /// </returns>
        public static IFCAnyHandle ExportWallBase(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
           IFCProductWrapper origWrapper, ElementId overrideLevelId, IFCRange range)
        {
            using (IFCProductWrapper localWrapper = IFCProductWrapper.Create(origWrapper))
            {
                ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                Wall wallElement = element as Wall;
                FamilyInstance famInstWallElem = element as FamilyInstance;

                if (wallElement == null && famInstWallElem == null)
                    return null;

                if (wallElement != null && IsWallCompletelyClipped(wallElement, exporterIFC, range))
                    return null;

                // get global values.
                Document doc = element.Document;
                double scale = exporterIFC.LinearScale;

                IFCFile file = exporterIFC.GetFile();
                IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                IFCAnyHandle contextOfItemsAxis = exporterIFC.Get3DContextHandle("Axis");
                IFCAnyHandle contextOfItemsBody = exporterIFC.Get3DContextHandle("Body");
              
                IFCRange zSpan = new IFCRange();
                double depth = 0.0;
                bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End));

                bool exportParts = PartExporter.CanExportParts(wallElement);
                if (exportParts && !PartExporter.CanExportElementInPartExport(wallElement, validRange? overrideLevelId : wallElement.Level.Id, validRange))
                    return null;

                // get bounding box height so that we can subtract out pieces properly.
                // only for Wall, not FamilyInstance.
                if (wallElement != null && geometryElement != null)
                {
                    BoundingBoxXYZ boundingBox = element.get_BoundingBox(null);
                    if (boundingBox == null)
                        return null;
                    zSpan = new IFCRange(boundingBox.Min.Z, boundingBox.Max.Z);

                    // if we have a top clipping plane, modify depth accordingly.
                    double bottomHeight = validRange ? Math.Max(zSpan.Start, range.Start) : zSpan.Start;
                    double topHeight = validRange ? Math.Min(zSpan.End, range.End) : zSpan.End;
                    depth = topHeight - bottomHeight;
                    if (MathUtil.IsAlmostZero(depth))
                        return null;
                    depth *= scale;
                }

                IFCAnyHandle axisRep = null;
                IFCAnyHandle bodyRep = null;

                bool exportingAxis = false;
                Curve curve = null;

                bool exportedAsWallWithAxis = false;
                bool exportedBodyDirectly = false;
                bool exportingInplaceOpenings = false;

                Curve centerCurve = GetWallAxis(wallElement);

                XYZ localXDir = new XYZ(1, 0, 0);
                XYZ localYDir = new XYZ(0, 1, 0);
                XYZ localZDir = new XYZ(0, 0, 1);
                XYZ localOrig = new XYZ(0, 0, 0);
                double eps = MathUtil.Eps();

                if (centerCurve != null)
                {
                    Curve baseCurve = GetWallAxisAtBaseHeight(wallElement);
                    curve = GetWallTrimmedCurve(wallElement, baseCurve);

                    IFCRange curveBounds;
                    XYZ oldOrig;
                    GeometryUtil.GetAxisAndRangeFromCurve(curve, out curveBounds, out localXDir, out oldOrig);

                    localOrig = oldOrig;
                    if (baseCurve != null)
                    {
                        if (!validRange || (MathUtil.IsAlmostEqual(range.Start, zSpan.Start)))
                        {
                            XYZ newOrig = baseCurve.Evaluate(curveBounds.Start, false);
                            if (!validRange && (zSpan.Start < newOrig[2] - eps))
                                localOrig = new XYZ(localOrig.X, localOrig.Y, zSpan.Start);
                            else
                                localOrig = new XYZ(localOrig.X, localOrig.Y, newOrig[2]);
                        }
                        else
                        {
                            localOrig = new XYZ(localOrig.X, localOrig.Y, range.Start);
                        }
                    }

                    double dist = localOrig[2] - oldOrig[2];
                    if (!MathUtil.IsAlmostZero(dist))
                    {
                        XYZ moveVec = new XYZ(0, 0, dist);
                        curve = GeometryUtil.MoveCurve(curve, moveVec);
                    }
                    localYDir = localZDir.CrossProduct(localXDir);

                    // ensure that X and Z axes are orthogonal.
                    double xzDot = localZDir.DotProduct(localXDir);
                    if (!MathUtil.IsAlmostZero(xzDot))
                        localXDir = localYDir.CrossProduct(localZDir);
                }

                Transform orientationTrf = Transform.Identity;
                orientationTrf.BasisX = localXDir;
                orientationTrf.BasisY = localYDir;
                orientationTrf.BasisZ = localZDir;
                orientationTrf.Origin = localOrig;

                using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element, null, orientationTrf, overrideLevelId))
                {
                    IFCAnyHandle localPlacement = setter.GetPlacement();

                    Plane plane = new Plane(localXDir, localYDir, localOrig);  // project curve to XY plane.
                    XYZ projDir = XYZ.BasisZ;

                    // two representations: axis, body.         
                    {
                        if ((centerCurve != null) && (GeometryUtil.CurveIsLineOrArc(centerCurve)))
                        {
                            exportingAxis = true;

                            string identifierOpt = "Axis";	// IFC2x2 convention
                            string representationTypeOpt = "Curve2D";  // IFC2x2 convention

                            IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, plane, projDir, false);
                            ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, curve, XYZ.Zero, true);
                            IList<IFCAnyHandle> axisItems = info.GetCurves();

                            if (axisItems.Count == 0)
                            {
                                exportingAxis = false;
                            }
                            else
                            {
                                HashSet<IFCAnyHandle> axisItemSet = new HashSet<IFCAnyHandle>();
                                foreach (IFCAnyHandle axisItem in axisItems)
                                    axisItemSet.Add(axisItem);

                                axisRep = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, contextOfItemsAxis,
                                   identifierOpt, representationTypeOpt, axisItemSet);
                            }
                        }
                    }

                    IList<IFCExtrusionData> cutPairOpenings = new List<IFCExtrusionData>();
                    Document document = element.Document;

                    if (wallElement != null && exportingAxis && curve != null)
                    {
                        SolidMeshGeometryInfo solidMeshInfo = 
                            (range == null) ? GeometryUtil.GetSolidMeshGeometry(geometryElement, Transform.Identity) :
                                GeometryUtil.GetClippedSolidMeshGeometry(geometryElement, range);
                                
                        IList<Solid> solids = solidMeshInfo.GetSolids();
                        IList<Mesh> meshes = solidMeshInfo.GetMeshes();
                        if (solids.Count == 0 && meshes.Count == 0)
                            return null;

                        bool useNewCode = false;
                        if (useNewCode && solids.Count == 1 && meshes.Count == 0)
                        {
                            bool completelyClipped;
                            bodyRep = ExtrusionExporter.CreateExtrusionWithClipping(exporterIFC, wallElement, catId, solids[0], 
                                plane, projDir, range, out completelyClipped);

                            if (completelyClipped)
                                return null;

                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                            {
                                exportedAsWallWithAxis = true;
                                exportedBodyDirectly = true;
                            }
                            else
                            {
                                exportedAsWallWithAxis = false;
                                exportedBodyDirectly = false;
                            }
                        }
                            
                        if (!exportedAsWallWithAxis)
                        {
                            // Fallback - use native routines to try to export wall.
                            bool isCompletelyClipped;
                            bodyRep = FallbackTryToCreateAsExtrusion(exporterIFC, wallElement, solidMeshInfo,
                                catId, curve, plane, depth, zSpan, range, setter, 
                                out cutPairOpenings, out isCompletelyClipped);
                            if (isCompletelyClipped)
                                return null;
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                                exportedAsWallWithAxis = true;
                        }
                    }
                
                    using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                    {
                        ElementId matId = ElementId.InvalidElementId;

                        if (!exportedAsWallWithAxis)
                        {
                            SolidMeshGeometryInfo solidMeshCapsule = null;

                            if (wallElement != null)
                            {
                                if (validRange)
                                {
                                    solidMeshCapsule = GeometryUtil.GetClippedSolidMeshGeometry(geometryElement, range);
                                }
                                else
                                {
                                    solidMeshCapsule = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                                }
                                if (solidMeshCapsule.SolidsCount() == 0 && solidMeshCapsule.MeshesCount() == 0)
                                {
                                    return null;
                                }
                            }
                            else
                            {
                                GeometryElement geomElemToUse = GetGeometryFromInplaceWall(famInstWallElem);
                                if (geomElemToUse != null)
                                {
                                    exportingInplaceOpenings = true;
                                }
                                else
                                {
                                    exportingInplaceOpenings = false;
                                    geomElemToUse = geometryElement;
                                }
                                Transform trf = Transform.Identity;
                                if (geomElemToUse != geometryElement)
                                    trf = famInstWallElem.GetTransform();
                                solidMeshCapsule = GeometryUtil.GetSolidMeshGeometry(geomElemToUse, trf);
                            }

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

                            extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;   // only allow vertical extrusions!
                            extraParams.AreInnerRegionsOpenings = true;

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                            if ((solids.Count > 0) || (meshes.Count > 0))
                            {
                                matId = BodyExporter.GetBestMaterialIdForGeometry(solids, meshes);
                                bodyRep = BodyExporter.ExportBody(element.Document.Application, exporterIFC, element, catId,
                                    solids, meshes, bodyExporterOptions, extraParams).RepresentationHnd;
                            }
                            else
                            {
                                IList<GeometryObject> geomElemList = new List<GeometryObject>();
                                geomElemList.Add(geometryElement);
                                BodyData bodyData = BodyExporter.ExportBody(element.Document.Application, exporterIFC, element, catId,
                                    geomElemList, bodyExporterOptions, extraParams);
                                bodyRep = bodyData.RepresentationHnd;
                            }

                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                            {
                                extraParams.ClearOpenings();
                                return null;
                            }

                            // We will be able to export as a IfcWallStandardCase as long as we have an axis curve.
                            XYZ extrDirUsed = XYZ.Zero;
                            if (extraParams.HasExtrusionDirection)
                            {
                                extrDirUsed = extraParams.ExtrusionDirection;
                                if (MathUtil.IsAlmostEqual(Math.Abs(extrDirUsed[2]), 1.0))
                                {
                                    if ((solids.Count == 1) && (meshes.Count == 0))
                                        exportedAsWallWithAxis = exportingAxis;
                                    exportedBodyDirectly = true;
                                }
                            }
                        }

                        IFCAnyHandle prodRep = null;
                        IList<IFCAnyHandle> representations = new List<IFCAnyHandle>();
                        if (exportingAxis)
                            representations.Add(axisRep);

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

                        string objectType = NamingUtil.CreateIFCObjectName(exporterIFC, element);
                        IFCAnyHandle wallHnd = null;

                        string elemGUID = (validRange) ? ExporterIFCUtils.CreateGUID() : ExporterIFCUtils.CreateGUID(element);
                        string elemName = NamingUtil.GetNameOverride(element, exporterIFC.GetName());
                        string elemDesc = NamingUtil.GetDescriptionOverride(element, null);
                        string elemObjectType = NamingUtil.GetObjectTypeOverride(element, objectType);
                        string elemId = NamingUtil.CreateIFCElementId(element);

                        if (exportedAsWallWithAxis)
                        {
                            wallHnd = IFCInstanceExporter.CreateWallStandardCase(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                localPlacement, exportParts ? null : prodRep, elemId);

                            if (exportParts)
                                PartExporter.ExportHostPart(exporterIFC, wallElement, wallHnd, localWrapper, setter, localPlacement, overrideLevelId);

                            localWrapper.AddElement(wallHnd, setter, extraParams, true);

                            OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, cutPairOpenings, exporterIFC, localPlacement, setter, localWrapper);
                            if (exportedBodyDirectly)
                            {
                                OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, extraParams, exporterIFC, localPlacement, setter, localWrapper);
                            }
                            else
                            {
                                double scaledWidth = wallElement.Width * scale;
                                ExporterIFCUtils.AddOpeningsToElement(exporterIFC, wallHnd, wallElement, scaledWidth, range, setter, localPlacement, localWrapper);
                            }

                            // export Base Quantities
                            if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
                            {
                                CreateWallBaseQuantities(exporterIFC, wallElement, wallHnd, depth);
                            }
                        }
                        else
                        {
                            wallHnd = IFCInstanceExporter.CreateWall(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                localPlacement, exportParts ? null : prodRep, elemId);

                            if (exportParts)
                                PartExporter.ExportHostPart(exporterIFC, wallElement, wallHnd, localWrapper, setter, localPlacement, overrideLevelId);

                            localWrapper.AddElement(wallHnd, setter, extraParams, true);

                            // Only export one material for 2x2; for future versions, export the whole list.
                            if (exporterIFC.ExportAs2x2 && (matId != ElementId.InvalidElementId) && !exportParts)
                            {
                                CategoryUtil.CreateMaterialAssociation(doc, exporterIFC, wallHnd, matId);
                            }

                            if (exportingInplaceOpenings)
                            {
                                ExporterIFCUtils.AddOpeningsToElement(exporterIFC, wallHnd, famInstWallElem, 0.0, range, setter, localPlacement, localWrapper);
                            }

                            if (exportedBodyDirectly)
                                OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, extraParams, exporterIFC, localPlacement, setter, localWrapper);
                        }

                        PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, localWrapper);

                        ElementId wallLevelId = (validRange) ? setter.LevelId : ElementId.InvalidElementId;

                        if (wallElement != null && !exportParts)
                        {
                            if (!exporterIFC.ExportAs2x2 || exportedAsWallWithAxis) //will move this check into ExportHostObject
                                HostObjectExporter.ExportHostObjectMaterials(exporterIFC, wallElement, localWrapper.GetAnElement(),
                                    geometryElement, localWrapper, wallLevelId, Toolkit.IFCLayerSetDirection.Axis2);
                        }

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

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

            if (familySymbol == null)
            {
                return;
            }

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

            ElementId categoryId = CategoryUtil.GetSafeCategoryId(coupler);

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

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                FamilyTypeInfo currentTypeInfo = ExporterCacheManager.TypeObjectsCache.Find(coupler.GetTypeId(), false, exportType);
                bool           found           = currentTypeInfo.IsValid();
                if (!found)
                {
                    string typeGUID            = GUIDUtil.CreateGUID(familySymbol);
                    string typeName            = NamingUtil.GetIFCName(familySymbol);
                    string typeObjectType      = NamingUtil.CreateIFCObjectName(exporterIFC, familySymbol);
                    string applicableOccurance = NamingUtil.GetObjectTypeOverride(familySymbol, typeObjectType);
                    string typeDescription     = NamingUtil.GetDescriptionOverride(familySymbol, null);
                    string typeElemId          = NamingUtil.CreateIFCElementId(familySymbol);

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

                    GeometryElement exportGeometry = familySymbol.get_Geometry(options);

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

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

                    IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, typeGUID, typeName,
                                                                                    typeDescription, applicableOccurance, propertySetsOpt, repMap, typeElemId, typeName, coupler, familySymbol);

                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle))
                    {
                        currentTypeInfo.Style = styleHandle;
                        ExporterCacheManager.TypeObjectsCache.Register(coupler.GetTypeId(), false, exportType, currentTypeInfo);
                    }
                }

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

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

                for (int idx = 0; idx < nCouplerQuantity; idx++)
                {
                    string instanceGUID        = GUIDUtil.CreateSubElementGUID(coupler, idx);
                    string instanceName        = NamingUtil.GetNameOverride(coupler, origInstanceName + ": " + idx);
                    string objectType          = NamingUtil.CreateIFCObjectName(exporterIFC, coupler);
                    string instanceObjectType  = NamingUtil.GetObjectTypeOverride(coupler, objectType);
                    string instanceDescription = NamingUtil.GetDescriptionOverride(coupler, null);
                    string instanceElemId      = NamingUtil.CreateIFCElementId(coupler);
                    string instanceTag         = NamingUtil.GetTagOverride(coupler, NamingUtil.CreateIFCElementId(coupler));

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

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

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

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

                    Transform trf = coupler.GetCouplerPositionTransform(idx);

                    using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, coupler, trf, null))
                    {
                        IFCAnyHandle instanceHandle = null;
                        instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(Common.Enums.IFCEntityType.IfcMechanicalFastener, file, instanceGUID, ownerHistory,
                                                                                    instanceName, instanceDescription, instanceObjectType, setter.LocalPlacement, productRepresentation, instanceTag);

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

                        createdRebarCouplerHandles.Add(instanceHandle);

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

                string couplerGUID = GUIDUtil.CreateGUID(coupler);

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

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

                        productWrapper.AddElement(coupler, rebarGroup);

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

                tr.Commit();
            }
        }
        /// <summary>
        /// Exports 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 IFCPlacementSetter object.
        /// </param>
        /// <param name="localPlacement">
        /// The local placement handle.
        /// </param>
        /// <returns>
        /// The handle.
        /// </returns>
        public static IFCAnyHandle ExportCurtainObjectCommonAsOneBRep(ElementSet allSubElements, Element wallElement,
           ExporterIFC exporterIFC, IFCPlacementSetter setter, IFCAnyHandle localPlacement)
        {
            IFCAnyHandle prodDefRep = IFCAnyHandle.Create();
            double eps = wallElement.Document.Application.VertexTolerance * exporterIFC.LinearScale;

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

            IFCGeometryInfo info = IFCGeometryInfo.CreateSurfaceGeometryInfo(eps);

            HashSet<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 = new Options();
            foreach (Element subElem in allSubElements)
            {
                GeometryElement geometryElement = subElem.get_Geometry(geomOptions);
                if (geometryElement == null)
                    continue;

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

                ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false);
                IFCAnyHandle outer = file.CreateClosedShell(info.GetSurfaces());

                if (outer.HasValue)
                    bodyItems.Add(RepresentationUtil.CreateFacetedBRep(exporterIFC, outer));
            }

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

            ElementId catId = CategoryUtil.GetSafeCategoryId(wallElement);
            IFCAnyHandle shapeRep = RepresentationUtil.CreateBRepRep(exporterIFC, catId, contextOfItems, bodyItems);
            if (!shapeRep.HasValue)
                return prodDefRep;

            IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>();
            shapeReps.Add(shapeRep);
            prodDefRep = file.CreateProductDefinitionShape(IFCLabel.Create(), IFCLabel.Create(), shapeReps);
            return prodDefRep;
        }
        /// <summary>
        /// Exports a family instance as a mapped item.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="familyInstance">
        /// The family instance to be exported.
        /// </param>
        /// <param name="exportType">
        /// The export type.
        /// </param>
        /// <param name="ifcEnumType">
        /// The string value represents the IFC type.
        /// </param>
        /// <param name="wrapper">
        /// The IFCProductWrapper.
        /// </param>
        /// <param name="overrideLevelId">
        /// The level id.
        /// </param>
        /// <param name="range">
        /// The range of this family instance to be exported.
        /// </param>
        public static void ExportFamilyInstanceAsMappedItem(ExporterIFC exporterIFC,
           FamilyInstance familyInstance, IFCExportType exportType, string ifcEnumType,
           IFCProductWrapper wrapper, ElementId overrideLevelId, UV range)
        {
            Document doc = familyInstance.Document;
            IFCFile file = exporterIFC.GetFile();

            FamilySymbol familySymbol = ExporterIFCUtils.GetOriginalSymbol(familyInstance);
            if (familySymbol == null)
                return;

            IFCProductWrapper familyProductWrapper = IFCProductWrapper.Create(wrapper);
            double scale = exporterIFC.LinearScale;

            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

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

            //string emptyString = "";
            string familyName = familySymbol.Name;
            IFCLabel objectType = IFCLabel.Create(familyName);

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

            IList<IFCExtrusionData> cutPairOpeningsForColumns = new List<IFCExtrusionData>();
            IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData();

            Transform trf = familyInstance.GetTransform();

            // Extra information if we are exporting a door or a window.
            IFCDoorWindowInfo doorWindowInfo = null;
            if (exportType == IFCExportType.ExportDoorType)
                doorWindowInfo = IFCDoorWindowInfo.CreateDoorInfo(exporterIFC, familyInstance, familySymbol, hostElement, overrideLevelId, trf);
            else if (exportType == IFCExportType.ExportWindowType)
                doorWindowInfo = IFCDoorWindowInfo.CreateWindowInfo(exporterIFC, familyInstance, familySymbol, hostElement, overrideLevelId, trf);

            IFCTypeInfo typeInfo = new IFCTypeInfo();
            XYZ extraOffset = XYZ.Zero;

            bool flipped = doorWindowInfo != null ? doorWindowInfo.IsSymbolFlipped : false;
            IFCTypeInfo currentTypeInfo = exporterIFC.FindType(familySymbol.Id, flipped);
            bool found = currentTypeInfo.IsValid();

            Family family = familySymbol.Family;

            // TODO: this code to be removed by ExtrusionAnalyzer code.
            bool trySpecialColumnCreation = ((exportType == IFCExportType.ExportColumnType) && (!family.IsInPlace));

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

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

                // TODO: this code to be removed by ExtrusionAnalyzer code.
                if (trySpecialColumnCreation)
                {
                    XYZ rangeOffset = trf.Origin;
                    IFCFamilyInstanceExtrusionExportResults results;
                    if (range != null)
                    {
                        results = ExporterIFCUtils.ExportFamilyInstanceAsExtrusion(exporterIFC, familyInstance, useInstanceGeometry, range, overrideLevelId, extraParams);
                    }
                    else
                    {
                        results = ExporterIFCUtils.ExportFamilyInstanceAsExtrusion(exporterIFC, familyInstance, useInstanceGeometry, overrideLevelId, extraParams);
                    }
                    bodyRepresentation = results.GetExtrusionHandle();
                    extraOffset = results.ExtraOffset;
                    cutPairOpeningsForColumns = results.GetCutPairOpenings();

                    if (bodyRepresentation.HasValue)
                    {
                        typeInfo.MaterialId = results.MaterialId;
                        // add in level for real columns, not in-place ones.
                        Element actualLevel =
                           (overrideLevelId == ElementId.InvalidElementId) ? familyInstance.Level : doc.get_Element(overrideLevelId);
                        if (actualLevel != null)
                        {
                            IFCLevelInfo levelInfo = exporterIFC.GetLevelInfo(actualLevel.Id);
                            double nonStoryLevelOffset = LevelUtil.GetNonStoryLevelOffsetIfAny(exporterIFC, actualLevel as Level);
                            if (range != null)
                            {
                                rangeOffset = new XYZ(rangeOffset.X, rangeOffset.Y, levelInfo.Elevation + nonStoryLevelOffset);
                            }
                        }
                    }

                    rangeOffset += extraOffset;
                    trf.Origin = rangeOffset;
                }

                Transform doorWindowTrf = Transform.Identity;
                IFCAnyHandle dummyPlacement = IFCAnyHandle.Create();
                if (doorWindowInfo != null)
                {
                    doorWindowTrf = ExporterIFCUtils.GetTransformForDoorOrWindow(familyInstance, familySymbol, doorWindowInfo);
                }
                else
                {
                    dummyPlacement = file.CreateLocalPlacement(IFCAnyHandle.Create(), file.CreateAxis2Placement3D());
                    extraParams.SetLocalPlacement(dummyPlacement);
                }

                bool needToCreate2d = (!exporterIFC.ExportAs2x2);
                bool needToCreate3d = (!bodyRepresentation.HasValue);

                if (needToCreate2d || needToCreate3d)
                {
                    using (IFCTransformSetter trfSetter = IFCTransformSetter.Create())
                    {
                        if (doorWindowInfo != null)
                        {
                            trfSetter.Initialize(exporterIFC, doorWindowTrf);
                        }

                        Options options = new Options();
                        GeometryElement exportGeometry =
                           useInstanceGeometry ? familyInstance.get_Geometry(options) : familySymbol.get_Geometry(options);
                        if (exportGeometry == null)
                            return;

                        if (needToCreate3d)
                        {
                            IFCSolidMeshGeometryInfo solidMeshInfo;

                            if (range == null)
                                solidMeshInfo = ExporterIFCUtils.GetSolidMeshGeometry(exporterIFC, exportGeometry, Transform.Identity);
                            else
                                solidMeshInfo = ExporterIFCUtils.GetClippedSolidMeshGeometry(exporterIFC, range, exportGeometry);

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

                            bool tryToExportAsExtrusion = (!exporterIFC.ExportAs2x2 || (exportType == IFCExportType.ExportColumnType));

                            if (exportType == IFCExportType.ExportColumnType)
                            {
                                extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;
                            }
                            else
                            {
                                extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryXYZ;
                            }

                            if (solids.Count > 0 || polyMeshes.Count > 0)
                            {
                                bodyRepresentation = BodyExporter.ExportBody(familyInstance.Document.Application, exporterIFC, categoryId, solids, polyMeshes,
                                    tryToExportAsExtrusion, extraParams);
                                typeInfo.MaterialId = BodyExporter.GetBestMaterialIdForGeometry(solids, polyMeshes);
                            }
                            else
                            {
                                IList<GeometryObject> exportedGeometries = new List<GeometryObject>();
                                exportedGeometries.Add(exportGeometry);
                                bodyRepresentation = BodyExporter.ExportBody(familyInstance.Document.Application, exporterIFC, categoryId, exportedGeometries,
                                   tryToExportAsExtrusion, extraParams);
                            }

                            if (!bodyRepresentation.HasValue)
                            {
                                extraParams.ClearOpenings();
                                return;
                            }
                        }

                        // if exporting IFC2x3 (or later), export 2D plan rep of family (if it exists).
                        if (needToCreate2d)
                        {
                            HashSet<IFCAnyHandle> curveSet = new HashSet<IFCAnyHandle>();
                            {
                                Transform planeTrf = doorWindowTrf.Inverse;
                                Plane plane = new Plane(planeTrf.get_Basis(0), planeTrf.get_Basis(1), planeTrf.Origin);
                                XYZ projDir = new XYZ(0, 0, 1);

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

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

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

                if (doorWindowInfo != null)
                {
                    typeInfo.SetStyleTransform(doorWindowTrf.Inverse);
                }
                else
                {
                    if (!MathUtil.IsAlmostZero(extraOffset.DotProduct(extraOffset)))
                    {
                        Transform newTransform = typeInfo.GetStyleTransform();
                        XYZ newOrig = newTransform.Origin + extraOffset;
                        newTransform.Origin = newOrig;
                        typeInfo.SetStyleTransform(newTransform);
                    }
                    typeInfo.SetStyleTransform(ExporterIFCUtils.GetUnscaledTransform(exporterIFC, extraParams.GetLocalPlacement()));
                }

                IFCLabel descriptionOpt = IFCLabel.Create();
                IFCLabel applicableOccurrenceOpt = IFCLabel.Create();

                IFCAnyHandle origin = file.CreateAxis2Placement3D();
                IFCAnyHandle repMap2dHnd = IFCAnyHandle.Create();
                IFCAnyHandle repMap3dHnd = file.CreateRepresentationMap(origin, bodyRepresentation);

                IList<IFCAnyHandle> repMapList = new List<IFCAnyHandle>();
                repMapList.Add(repMap3dHnd);
                if (planRepresentation.HasValue)
                {
                    repMap2dHnd = file.CreateRepresentationMap(origin, planRepresentation);
                    repMapList.Add(repMap2dHnd);
                }

                // for Door, Window
                bool paramTakesPrecedence = false; // For Revit, this is currently always false.
                bool sizeable = false;

                // for many
                HashSet<IFCAnyHandle> propertySets = new HashSet<IFCAnyHandle>();

                IFCLabel guid = IFCLabel.CreateGUID(familySymbol);
                IFCLabel symIdAsLabel = NamingUtil.CreateIFCElementId(familySymbol);

                // This covers many generic types.  If we can't find it in the list here, do custom exports.
                IFCAnyHandle typeStyle = FamilyExporterUtil.ExportGenericType(file, exportType, ifcEnumType, guid,
                   ownerHistory, objectType, descriptionOpt, applicableOccurrenceOpt, propertySets, repMapList, symIdAsLabel, objectType,
                   familyInstance, familySymbol);

                // Cover special cases not covered above.
                if (!typeStyle.HasValue)
                {
                    switch (exportType)
                    {
                        case IFCExportType.ExportColumnType:
                            {
                                // If we are using the instance GRep, then we have to create a generic GUID for the
                                // column type, as they share the same ElementId.
                                IFCLabel colGUID = IFCLabel.Create();
                                IFCLabel colElemId = IFCLabel.Create();

                                if (useInstanceGeometry)
                                {
                                    colGUID = IFCLabel.CreateGUID();
                                    colElemId = NamingUtil.CreateIFCElementId(familyInstance);
                                }
                                else
                                {
                                    colGUID = guid;
                                    colElemId = NamingUtil.CreateIFCElementId(familySymbol);
                                }

                                string columnType = "Column";
                                typeStyle = file.CreateColumnType(columnType, colGUID, ownerHistory, objectType,
                                   descriptionOpt, applicableOccurrenceOpt, propertySets, repMapList, colElemId,
                                   objectType, familyInstance, familySymbol);

                                break;
                            }
                        case IFCExportType.ExportDoorType:
                            {
                                string constructionType = string.Empty;
                                ParameterUtil.GetStringValueFromElementOrSymbol(familyInstance, "Construction", out constructionType);

                                IFCAnyHandle doorLining = DoorWindowUtil.CreateDoorLiningProperties(exporterIFC, familyInstance);
                                if (doorLining.HasValue)
                                    propertySets.Add(doorLining);

                                IList<IFCAnyHandle> doorPanels = DoorWindowUtil.CreateDoorPanelProperties(exporterIFC, doorWindowInfo,
                                   familyInstance);
                                propertySets.UnionWith(doorPanels);

                                IFCLabel doorStyleGUID = IFCLabel.CreateGUID();
                                IFCLabel doorStyleElemId = NamingUtil.CreateIFCElementId(familyInstance);
                                typeStyle = file.CreateDoorStyle(doorStyleGUID, ownerHistory, objectType,
                                   descriptionOpt, applicableOccurrenceOpt, propertySets, repMapList, doorStyleElemId,
                                   doorWindowInfo.DoorOperationType, constructionType, paramTakesPrecedence, sizeable);
                                break;
                            }
                        case IFCExportType.ExportSystemFurnitureElementType:
                            {
                                IFCLabel furnitureId = NamingUtil.CreateIFCElementId(familyInstance);
                                typeStyle = file.CreateSystemFurnitureElementType(guid, ownerHistory, objectType,
                                   descriptionOpt, applicableOccurrenceOpt, propertySets, repMapList, furnitureId,
                                   objectType);
                                break;
                            }
                        case IFCExportType.ExportWindowType:
                            {
                                IFCWindowStyleOperation operationType = DoorWindowUtil.GetIFCWindowStyleOperation(familySymbol);
                                string constructionType = DoorWindowUtil.GetIFCWindowStyleConstruction(familyInstance, "");

                                IFCAnyHandle windowLining = DoorWindowUtil.CreateWindowLiningProperties(exporterIFC, familyInstance, descriptionOpt);
                                if (windowLining.HasValue)
                                    propertySets.Add(windowLining);

                                IList<IFCAnyHandle> windowPanels =
                                   DoorWindowUtil.CreateWindowPanelProperties(exporterIFC, familyInstance, descriptionOpt);
                                propertySets.UnionWith(windowPanels);

                                IFCLabel windowStyleGUID = IFCLabel.CreateGUID();
                                IFCLabel windowStyleElemId = NamingUtil.CreateIFCElementId(familyInstance);
                                typeStyle = file.CreateWindowStyle(windowStyleGUID, ownerHistory, objectType,
                                   descriptionOpt, applicableOccurrenceOpt, propertySets, repMapList, windowStyleElemId,
                                   operationType, constructionType, paramTakesPrecedence, sizeable);
                                break;
                            }
                        case IFCExportType.ExportBuildingElementProxy:
                        default:
                            {
                                typeInfo.Set2DMapHandle(repMap2dHnd);
                                typeInfo.Set3DMapHandle(repMap3dHnd);
                                break;
                            }
                    }
                }

                typeInfo.SetStyle(typeStyle);

                // Transfer extraParams information for certain types.
                if (typeStyle.HasValue)
                {
                    if (((exportType == IFCExportType.ExportColumnType) && trySpecialColumnCreation) ||
                       (exportType == IFCExportType.ExportMemberType))
                    {
                        typeInfo.ScaledArea = extraParams.ScaledArea;
                        typeInfo.ScaledDepth = extraParams.ScaledLength;
                        typeInfo.ScaledInnerPerimeter = extraParams.ScaledInnerPerimeter;
                        typeInfo.ScaledOuterPerimeter = extraParams.ScaledOuterPerimeter;
                    }
                }
            }
            else if (!creatingType && (trySpecialColumnCreation))
            {
                // still need to modify instance trf for columns.
                trf.Origin += GetLevelOffsetForExtrudedColumns(exporterIFC, familyInstance, overrideLevelId, extraParams);
            }

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

            // we'll pretend we succeeded, but we'll do nothing.
            if (!typeInfo.GetStyle().HasValue && !typeInfo.Get2DMapHandle().HasValue && !typeInfo.Get3DMapHandle().HasValue)
                return;

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

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

            trf = trf.Multiply(typeInfo.GetStyleTransform());

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

                // for proxies, we store the IfcRepresentationMap directly since there is no style.
                IList<IFCAnyHandle> repMapList = IFCGeometryUtils.GetRepresentationMaps(typeInfo.GetStyle());
                int numReps = repMapList.Count;

                IFCAnyHandle repMap2dHnd = typeInfo.Get2DMapHandle();
                IFCAnyHandle repMap3dHnd = typeInfo.Get3DMapHandle();
                if (!repMap3dHnd.HasValue && (numReps > 0))
                    repMap3dHnd = repMapList[0];
                if (!repMap2dHnd.HasValue && (numReps > 1))
                    repMap2dHnd = repMapList[1];

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

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

            IFCLabel noDescriptionOpt = IFCLabel.Create();
            IFCLabel noNameOpt = IFCLabel.Create();
            IFCAnyHandle rep = file.CreateProductDefinitionShape(noNameOpt, noDescriptionOpt, shapeReps);

            IFCAnyHandle instanceHandle = IFCAnyHandle.Create();
            using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, familyInstance, trf, null, overrideLevelId))
            {
                IFCLabel instanceGUID = IFCLabel.CreateGUID(familyInstance);
                IFCLabel origInstanceName = NamingUtil.CreateIFCName(exporterIFC, -1);
                IFCLabel instanceName = NamingUtil.GetNameOverride(familyInstance, origInstanceName);
                IFCLabel instanceDescription = NamingUtil.GetDescriptionOverride(familyInstance, noDescriptionOpt);
                IFCLabel instanceObjectType = NamingUtil.GetObjectTypeOverride(familyInstance, objectType);
                IFCLabel instanceElemId = NamingUtil.CreateIFCElementId(familyInstance);

                IFCAnyHandle localPlacement = setter.GetPlacement();
                instanceHandle = FamilyExporterUtil.ExportGenericInstance(exportType, exporterIFC, familyInstance,
                   wrapper, setter, extraParams, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType,
                   rep, instanceElemId);

                switch (exportType)
                {
                    case IFCExportType.ExportColumnType:
                        {
                            IFCAnyHandle placementToUse = localPlacement;
                            if (!useInstanceGeometry)
                            {
                                Transform openingTrf = new Transform(oldTrf);
                                Transform extraRot = new Transform(oldTrf);
                                extraRot.Origin = XYZ.Zero;
                                openingTrf = openingTrf.Multiply(extraRot);
                                openingTrf = openingTrf.Multiply(typeInfo.GetStyleTransform());

                                IFCAnyHandle openingRelativePlacement = file.CreateAxis2Placement3D(openingTrf.Origin * scale,
                                   openingTrf.get_Basis(2), openingTrf.get_Basis(0));
                                IFCAnyHandle openingPlacement = ExporterUtil.CopyLocalPlacement(file, localPlacement);
                                IFCGeometryUtils.SetRelativePlacement(openingPlacement, openingRelativePlacement);
                                placementToUse = openingPlacement;
                            }

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

                            //export Base Quantities.
                            ExporterIFCUtils.CreateBeamColumnBaseQuantities(exporterIFC, instanceHandle, familyInstance, typeInfo);

                            CategoryUtil.CreateMaterialAssociation(doc, exporterIFC, instanceHandle, typeInfo.MaterialId);

                            ExporterIFCUtils.CreateColumnPropertySet(exporterIFC, familyInstance, extraParams, wrapper);
                            break;
                        }
                    case IFCExportType.ExportDoorType:
                    case IFCExportType.ExportWindowType:
                        {
                            double doorHeight = doorWindowInfo.OpeningHeight;
                            if (doorHeight < MathUtil.Eps())
                                doorHeight = GetMinSymbolHeight(familySymbol);
                            double doorWidth = doorWindowInfo.OpeningWidth;
                            if (doorWidth < MathUtil.Eps())
                                doorWidth = GetMinSymbolWidth(familySymbol);

                            IFCMeasureValue height = IFCMeasureValue.Create(doorHeight * scale);
                            IFCMeasureValue width = IFCMeasureValue.Create(doorWidth * scale);

                            if (!doorWindowInfo.GetLocalPlacement().HasValue)
                                doorWindowInfo.SetLocalPlacement(localPlacement);

                            IFCAnyHandle doorWindowOrigLocalPlacement = doorWindowInfo.GetLocalPlacement();
                            Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(localPlacement, doorWindowOrigLocalPlacement);

                            IFCAnyHandle doorWindowRelativePlacement = file.CreateAxis2Placement3D(relTrf);
                            IFCAnyHandle doorWindowLocalPlacement =
                               file.CreateLocalPlacement(doorWindowOrigLocalPlacement, doorWindowRelativePlacement);
                            if (exportType == IFCExportType.ExportDoorType)
                                instanceHandle = file.CreateDoor(instanceGUID, ownerHistory,
                                   instanceName, instanceDescription, instanceObjectType, doorWindowLocalPlacement,
                                   rep, instanceElemId, height, width);
                            else if (exportType == IFCExportType.ExportWindowType)
                                instanceHandle = file.CreateWindow(instanceGUID, ownerHistory,
                                   instanceName, instanceDescription, instanceObjectType, doorWindowLocalPlacement,
                                   rep, instanceElemId, height, width);
                            wrapper.AddElement(instanceHandle, setter, extraParams, true);

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

                            // only necessary when exporting as possible breps.
                            OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, exporterIFC,
                               doorWindowLocalPlacement, setter, wrapper);
                            if (exporterIFC.ExportBaseQuantities)
                                ExporterIFCUtils.CreateDoorWindowBaseQuantities(exporterIFC, instanceHandle, (doorHeight * scale), (doorWidth * scale));

                            if (exportType == IFCExportType.ExportDoorType)
                                ExporterIFCUtils.CreateDoorPropertySet(exporterIFC, familyInstance, wrapper);
                            else
                                ExporterIFCUtils.CreateWindowPropertySet(exporterIFC, familyInstance, wrapper);
                            break;
                        }
                    case IFCExportType.ExportMemberType:
                        {
                            OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, exporterIFC,
                              localPlacement, setter, wrapper);
                            CategoryUtil.CreateMaterialAssociation(doc, exporterIFC, instanceHandle, typeInfo.MaterialId);

                            //export Base Quantities.
                            ExporterIFCUtils.CreateBeamColumnBaseQuantities(exporterIFC, instanceHandle, familyInstance, typeInfo);
                            // TODO: create PropertySet!
                            //createMemberPropertySet(exporter, pFamInst, pWrapper, extraParams);
                            ExporterIFCUtils.CreateGenericElementPropertySet(exporterIFC, familyInstance, wrapper);
                            break;
                        }
                    case IFCExportType.ExportPlateType:
                        {
                            OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, exporterIFC,
                              localPlacement, setter, wrapper);
                            CategoryUtil.CreateMaterialAssociation(doc, exporterIFC, instanceHandle, typeInfo.MaterialId);

                            // TODO: create PropertySet!
                            //createPlatePropertySet(exporter, pFamInst, pWrapper, extraParams);
                            ExporterIFCUtils.CreateGenericElementPropertySet(exporterIFC, familyInstance, wrapper);
                            break;
                        }
                    case IFCExportType.ExportTransportElementType:
                        {
                            string operationTypeOpt = "";
                            IFCMeasureValue capByWeightOpt = IFCMeasureValue.Create();
                            IFCMeasureValue capByNumOpt = IFCMeasureValue.Create();

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

                            instanceHandle = file.CreateTransportElement(instanceGUID, ownerHistory,
                               instanceName, instanceDescription, instanceObjectType,
                               localPlacementToUse, rep, instanceElemId, operationTypeOpt, capByWeightOpt, capByNumOpt,
                               familyInstance, familySymbol);

                            if (roomId == ElementId.InvalidElementId)
                            {
                                wrapper.AddElement(instanceHandle, setter, extraParams, true);
                            }
                            else
                            {
                                exporterIFC.RelateSpatialElement(roomId, instanceHandle);
                                wrapper.AddElement(instanceHandle, setter, extraParams, false);
                            }

                            ExporterIFCUtils.CreateGenericElementPropertySet(exporterIFC, familyInstance, wrapper);
                            break;
                        }
                    case IFCExportType.ExportBuildingElementProxy:
                    default:
                        {
                            bool isBuildingElementProxy = (exportType == IFCExportType.ExportBuildingElementProxy);

                            if (!isBuildingElementProxy)
                            {
                                if (FamilyExporterUtil.IsDistributionControlElementSubType(exportType))
                                {
                                    IFCLabel controlElementId = IFCLabel.Create();
                                    IFCAnyHandle localPlacementToUse;
                                    ElementId roomId = setter.UpdateRoomRelativeCoordinates(familyInstance, out localPlacementToUse);

                                    instanceHandle = file.CreateDistributionControlElement(instanceGUID,
                                       ownerHistory, instanceName, instanceDescription, instanceObjectType,
                                       localPlacement, rep, instanceElemId, controlElementId);

                                    if (roomId == ElementId.InvalidElementId)
                                    {
                                        wrapper.AddElement(instanceHandle, setter, extraParams, true);
                                    }
                                    else
                                    {
                                        exporterIFC.RelateSpatialElement(roomId, instanceHandle);
                                        wrapper.AddElement(instanceHandle, setter, extraParams, false);
                                    }

                                    OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, exporterIFC,
                                       localPlacement, setter, wrapper);
                                }
                                else if (!instanceHandle.HasValue)
                                {
                                    isBuildingElementProxy = true;
                                }
                            }

                            if (isBuildingElementProxy)
                            {
                                IFCElementComposition proxyType = IFCElementComposition.Element;
                                IFCAnyHandle localPlacementToUse;
                                ElementId roomId = setter.UpdateRoomRelativeCoordinates(familyInstance, out localPlacementToUse);

                                instanceHandle = file.CreateBuildingElementProxy(instanceGUID,
                                   ownerHistory, instanceName, instanceDescription, instanceObjectType,
                                   localPlacementToUse, rep, instanceElemId, proxyType);

                                if (roomId == ElementId.InvalidElementId)
                                {
                                    wrapper.AddElement(instanceHandle, setter, extraParams, true);
                                }
                                else
                                {
                                    exporterIFC.RelateSpatialElement(roomId, instanceHandle);
                                    wrapper.AddElement(instanceHandle, setter, extraParams, false);
                                }

                                OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, exporterIFC,
                                   localPlacement, setter, wrapper);
                            }

                            ExporterIFCUtils.CreateGenericElementPropertySet(exporterIFC, familyInstance, wrapper);
                            break;
                        }
                }

                if (instanceHandle.HasValue)
                {
                    if (doorWindowInfo != null)
                    {
                        if (doorWindowInfo.GetOpening().HasValue)
                        {
                            IFCLabel relGUID = IFCLabel.CreateGUID();
                            file.CreateRelFillsElement(relGUID, ownerHistory, IFCLabel.Create(), IFCLabel.Create(), doorWindowInfo.GetOpening(), instanceHandle);
                        }
                        else if (doorWindowInfo.NeedsOpening)
                        {
                            bool added = doorWindowInfo.SetDelayedFamilyInstance(instanceHandle, localPlacement, doorWindowInfo.AssignedLevelId);
                            if (added)
                                exporterIFC.RegisterDoorWindowForOpeningUpdate(doorWindowInfo);
                            else
                            {
                                // we need to fill a later opening.
                                exporterIFC.RegisterDoorWindowForUncreatedOpening(familyInstance.Id, instanceHandle);
                            }
                        }
                    }

                    if (typeInfo.GetStyle().HasValue)
                        exporterIFC.AddTypeRelation(typeInfo.GetStyle(), instanceHandle);
                }
            }
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Creates openings if there is necessary.
        /// </summary>
        /// <param name="elementHandle">
        /// The element handle to create openings.
        /// </param>
        /// <param name="element">
        /// The element to create openings.
        /// </param>
        /// <param name="info">
        /// The extrusion datas.
        /// </param>
        /// <param name="extraParams">
        /// The extrusion creation data.
        /// </param>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="originalPlacement">
        /// The original placement handle.
        /// </param>
        /// <param name="setter">
        /// The IFCPlacementSetter.
        /// </param>
        /// <param name="wrapper">
        /// The IFCProductWrapper.
        /// </param>
        private static void CreateOpeningsIfNecessaryBase(IFCAnyHandle elementHandle, Element element, IList <IFCExtrusionData> info,
                                                          IFCExtrusionCreationData extraParams, ExporterIFC exporterIFC,
                                                          IFCAnyHandle originalPlacement, IFCPlacementSetter setter, IFCProductWrapper wrapper)
        {
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(elementHandle))
            {
                return;
            }

            int sz = info.Count;

            if (sz == 0)
            {
                return;
            }

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

            string openingObjectType = "Opening";

            int openingNumber = 1;

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

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

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

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

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

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

                string voidGuid = ExporterIFCUtils.CreateGUID();
                IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, elementHandle, openingElement);
            }
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Gets material handle from material id or creates one if there is none.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="materialId">The material id.</param>
        /// <returns>The handle.</returns>
        public static IFCAnyHandle GetOrCreateMaterialHandle(ExporterIFC exporterIFC, ElementId materialId)
        {
            Document     document           = ExporterCacheManager.Document;
            IFCAnyHandle materialNameHandle = ExporterCacheManager.MaterialHandleCache.Find(materialId);

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(materialNameHandle))
            {
                string materialName = "<Unnamed>";
                string description  = null;
                string category     = null;
                if (materialId != ElementId.InvalidElementId)
                {
                    Material material = document.GetElement(materialId) as Material;
                    if (material != null)
                    {
                        materialName = NamingUtil.GetMaterialName(material);

                        if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                        {
                            category    = NamingUtil.GetMaterialCategoryName(material);
                            description = NamingUtil.GetOverrideStringValue(material, "IfcDescription", null);
                        }
                    }
                }

                IFCFile file = exporterIFC.GetFile();
                materialNameHandle = IFCInstanceExporter.CreateMaterial(file, materialName, description: description, category: category);

                ExporterCacheManager.MaterialHandleCache.Register(materialId, materialNameHandle);

                // associate Material with SurfaceStyle if necessary.
                if (materialId != ElementId.InvalidElementId && !ExporterCacheManager.ExportOptionsCache.ExportAs2x2 && materialNameHandle.HasValue)
                {
                    HashSet <IFCAnyHandle> matRepHandles = IFCAnyHandleUtil.GetHasRepresentation(materialNameHandle);
                    if (matRepHandles.Count == 0)
                    {
                        Material matElem = document.GetElement(materialId) as Material;

                        // TODO_DOUBLE_PATTERN - deal with background pattern
                        ElementId fillPatternId = (matElem != null) ? matElem.CutForegroundPatternId : ElementId.InvalidElementId;
                        Color     color         = (matElem != null) ? GetSafeColor(matElem.CutForegroundPatternColor) : new Color(0, 0, 0);

                        double planScale = 100.0;

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

                        bool hasFill = false;

                        IFCAnyHandle styledRepItem = null;
                        IFCAnyHandle matStyleHnd   = GetOrCreateMaterialStyle(document, file, materialId);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(matStyleHnd) && !ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)
                        {
                            styles.Add(matStyleHnd);

                            bool supportCutStyles = !ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2;
                            if (fillPatternId != ElementId.InvalidElementId && supportCutStyles)
                            {
                                IFCAnyHandle cutStyleHnd = exporterIFC.GetOrCreateFillPattern(fillPatternId, color, planScale);
                                if (cutStyleHnd.HasValue)
                                {
                                    styles.Add(cutStyleHnd);
                                    hasFill = true;
                                }
                            }

                            IFCAnyHandle styledItemHnd;
                            if (ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4)
                            {
                                IFCAnyHandle presStyleHnd = IFCInstanceExporter.CreatePresentationStyleAssignment(file, styles);

                                HashSet <IFCAnyHandle> presStyleSet = new HashSet <IFCAnyHandle>();
                                presStyleSet.Add(presStyleHnd);

                                styledItemHnd = IFCInstanceExporter.CreateStyledItem(file, styledRepItem, presStyleSet, null);
                            }
                            else
                            {
                                styledItemHnd = IFCInstanceExporter.CreateStyledItem(file, styledRepItem, styles, null);
                            }

                            IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("");

                            string repId   = "Style";
                            string repType = (hasFill) ? "Material and Cut Pattern" : "Material";
                            HashSet <IFCAnyHandle> repItems = new HashSet <IFCAnyHandle>();

                            repItems.Add(styledItemHnd);

                            IFCAnyHandle styleRepHnd = IFCInstanceExporter.CreateStyledRepresentation(file, contextOfItems, repId, repType, repItems);

                            List <IFCAnyHandle> repList = new List <IFCAnyHandle>();
                            repList.Add(styleRepHnd);

                            IFCAnyHandle matDefRepHnd = IFCInstanceExporter.CreateMaterialDefinitionRepresentation(file, null, null, repList, materialNameHandle);
                        }
                    }
                }
            }
            return(materialNameHandle);
        }
Ejemplo n.º 31
0
        /// <summary>
        /// Exports a geometry element to boundary representation.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="exportBoundaryRep">True if to export boundary representation.</param>
        /// <param name="exportAsFacetation">True if to export the geometry as facetation.</param>
        /// <param name="bodyRep">Body representation.</param>
        /// <param name="boundaryRep">Boundary representation.</param>
        /// <returns>True if success, false if fail.</returns>
        public static bool ExportSurface(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                         bool exportBoundaryRep, bool exportAsFacetation, ref IFCAnyHandle bodyRep, ref IFCAnyHandle boundaryRep)
        {
            if (geometryElement == null)
            {
                return(false);
            }

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

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

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

            IFCFile file = exporterIFC.GetFile();
            HashSet <IFCAnyHandle> faceSets = new HashSet <IFCAnyHandle>();
            IList <ICollection <IFCAnyHandle> > faceList = ifcGeomInfo.GetFaces();

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

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

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

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

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

            surfaceItems.Add(surface);

            ElementId catId = CategoryUtil.GetSafeCategoryId(element);

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

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

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

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

            int sz = info.Count;

            if (sz == 0)
            {
                return;
            }

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

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

                string openingObjectType = "Opening";

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

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

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

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

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

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

                    string voidGuid = GUIDUtil.CreateGUID();
                    IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, elementHandle, openingElement);
                }
            }
        }
Ejemplo n.º 33
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();
                }
            }
        }
Ejemplo n.º 34
0
        /// <summary>
        /// Exports an element as an IfcReinforcingMesh.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if exported successfully, false otherwise.</returns>
        public static bool ExportFabricSheet(ExporterIFC exporterIFC, FabricSheet sheet,
                                             GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            if (sheet == null || geometryElement == null)
            {
                return(false);
            }

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

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

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(sheet);

                        ElementId materialId = ElementId.InvalidElementId;
                        ParameterUtil.GetElementIdValueFromElementOrSymbol(sheet, BuiltInParameter.MATERIAL_ID_PARAM, out materialId);

                        string       guid            = GUIDUtil.CreateGUID(sheet);
                        IFCAnyHandle ownerHistory    = exporterIFC.GetOwnerHistoryHandle();
                        string       revitObjectType = exporterIFC.GetFamilyName();
                        string       name            = NamingUtil.GetNameOverride(sheet, revitObjectType);
                        string       description     = NamingUtil.GetDescriptionOverride(sheet, null);
                        string       objectType      = NamingUtil.GetObjectTypeOverride(sheet, revitObjectType);

                        IFCAnyHandle localPlacement = ecData.GetLocalPlacement();
                        string       elementTag     = NamingUtil.CreateIFCElementId(sheet);

                        string steelGrade = NamingUtil.GetOverrideStringValue(sheet, "SteelGrade", null);
                        double?meshLength = sheet.CutOverallLength;
                        double?meshWidth  = sheet.CutOverallWidth;

                        Element         fabricSheetTypeElem = doc.GetElement(sheet.GetTypeId());
                        FabricSheetType fabricSheetType     = (fabricSheetTypeElem == null) ? null : (fabricSheetTypeElem as FabricSheetType);

                        double longitudinalBarNominalDiameter  = 0.0;
                        double transverseBarNominalDiameter    = 0.0;
                        double longitudinalBarCrossSectionArea = 0.0;
                        double transverseBarCrossSectionArea   = 0.0;
                        double longitudinalBarSpacing          = 0.0;
                        double transverseBarSpacing            = 0.0;
                        if (fabricSheetType != null)
                        {
                            Element        majorFabricWireTypeElem = doc.GetElement(fabricSheetType.MajorDirectionWireType);
                            FabricWireType majorFabricWireType     = (majorFabricWireTypeElem == null) ? null : (majorFabricWireTypeElem as FabricWireType);
                            if (majorFabricWireType != null)
                            {
                                longitudinalBarNominalDiameter = UnitUtil.ScaleLength(majorFabricWireType.WireDiameter);
                                double localRadius = longitudinalBarNominalDiameter / 2.0;
                                longitudinalBarCrossSectionArea = localRadius * localRadius * Math.PI;
                            }

                            Element        minorFabricWireTypeElem = doc.GetElement(fabricSheetType.MinorDirectionWireType);
                            FabricWireType minorFabricWireType     = (minorFabricWireTypeElem == null) ? null : (minorFabricWireTypeElem as FabricWireType);
                            if (minorFabricWireType != null)
                            {
                                transverseBarNominalDiameter = UnitUtil.ScaleLength(minorFabricWireType.WireDiameter);
                                double localRadius = transverseBarNominalDiameter / 2.0;
                                transverseBarCrossSectionArea = localRadius * localRadius * Math.PI;
                            }

                            longitudinalBarSpacing = UnitUtil.ScaleLength(fabricSheetType.MajorSpacing);
                            transverseBarSpacing   = UnitUtil.ScaleLength(fabricSheetType.MinorSpacing);
                        }

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

                        IList <Curve> wireCenterlines = sheet.GetWireCenterlines(WireDistributionDirection.Major);
                        foreach (Curve wireCenterline in wireCenterlines)
                        {
                            IFCAnyHandle bodyItem = CreateSweptDiskSolid(exporterIFC, file, wireCenterline, longitudinalBarNominalDiameter);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItem))
                            {
                                bodyItems.Add(bodyItem);
                            }
                        }

                        wireCenterlines = sheet.GetWireCenterlines(WireDistributionDirection.Minor);
                        foreach (Curve wireCenterline in wireCenterlines)
                        {
                            IFCAnyHandle bodyItem = CreateSweptDiskSolid(exporterIFC, file, wireCenterline, transverseBarNominalDiameter);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItem))
                            {
                                bodyItems.Add(bodyItem);
                            }
                        }

                        IFCAnyHandle shapeRep = (bodyItems.Count > 0) ?
                                                RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC, sheet, categoryId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null) :
                                                null;
                        IList <IFCAnyHandle> shapeReps = null;
                        if (shapeRep != null)
                        {
                            shapeReps = new List <IFCAnyHandle>();
                            shapeReps.Add(shapeRep);
                        }
                        IFCAnyHandle prodRep = (shapeReps != null) ? IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps) : null;

                        IFCAnyHandle fabricSheet = IFCInstanceExporter.CreateReinforcingMesh(file, guid,
                                                                                             ownerHistory, name, description, objectType, localPlacement, prodRep, elementTag,
                                                                                             steelGrade, meshLength, meshWidth, longitudinalBarNominalDiameter, transverseBarNominalDiameter,
                                                                                             longitudinalBarCrossSectionArea, transverseBarCrossSectionArea,
                                                                                             longitudinalBarSpacing, transverseBarSpacing);

                        ElementId fabricAreaId = sheet.FabricAreaOwnerId;
                        if (fabricAreaId != ElementId.InvalidElementId)
                        {
                            HashSet <IFCAnyHandle> fabricSheets = null;
                            if (!ExporterCacheManager.FabricAreaHandleCache.TryGetValue(fabricAreaId, out fabricSheets))
                            {
                                fabricSheets = new HashSet <IFCAnyHandle>();
                                ExporterCacheManager.FabricAreaHandleCache[fabricAreaId] = fabricSheets;
                            }
                            fabricSheets.Add(fabricSheet);
                        }

                        productWrapper.AddElement(sheet, fabricSheet, placementSetter.LevelInfo, ecData, true);

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

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

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

            Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcRoof;
            if (elementIsFloor)
            {
                elementClassTypeEnum = Common.Enums.IFCEntityType.IfcSlab;
            }

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

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

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

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

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

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

                                IFCAnyHandle prodRepHnd = null;

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

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

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

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

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

                                ElementId catId = CategoryUtil.GetSafeCategoryId(element);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                                transaction.Commit();
                                return(hostObjectHandle);
                            }
                        }
                    }
                    finally
                    {
                        exporterIFC.ClearFaceWithElementHandleMap();
                    }
                }
            }
        }
        /// <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 IFCPlacementSetter 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, IFCPlacementSetter setter, IFCAnyHandle localPlacement)
        {
            IFCAnyHandle prodDefRep = null;
            Document document = wallElement.Document;
            double eps = document.Application.VertexTolerance * exporterIFC.LinearScale;

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

            IFCGeometryInfo info = IFCGeometryInfo.CreateFaceGeometryInfo(eps);

            IList<IFCAnyHandle> bodyItems = new List<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;
        }
Ejemplo n.º 37
0
        /// <summary>
        /// Exports a staircase to IfcStair, composing into separate runs and landings.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="ifcEnumType">The stairs type.</param>
        /// <param name="stair">The stairs element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="numFlights">The number of flights for a multistory staircase.</param>
        /// <param name="productWrapper">The IFCProductWrapper.</param>
        public static void ExportStairsAsContainer(ExporterIFC exporterIFC, string ifcEnumType, Stairs stair, GeometryElement geometryElement,
            int numFlights, IFCProductWrapper productWrapper)
        {
            if (stair == null || geometryElement == null)
                return;

            Document doc = stair.Document;
            Autodesk.Revit.ApplicationServices.Application app = doc.Application;
            IFCFile file = exporterIFC.GetFile();
            Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions();
            ElementId categoryId = CategoryUtil.GetSafeCategoryId(stair);

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (IFCPlacementSetter placementSetter = IFCPlacementSetter.Create(exporterIFC, stair))
                {
                    HashSet<ElementId> materialIds = new HashSet<ElementId>();

                    List<IFCAnyHandle> componentHandles = new List<IFCAnyHandle>();
                    IList<IFCExtrusionCreationData> componentExtrusionData = new List<IFCExtrusionCreationData>();

                    IFCAnyHandle contextOfItemsFootPrint = exporterIFC.Get3DContextHandle("FootPrint");

                    Transform trf = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, placementSetter.GetPlacement());
                    Plane boundaryPlane = new Plane(trf.BasisX, trf.BasisY, trf.Origin);
                    XYZ boundaryProjDir = trf.BasisZ;

                    IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                    string stairGUID = ExporterIFCUtils.CreateGUID(stair);
                    string origStairName = exporterIFC.GetName();
                    string stairName = NamingUtil.GetNameOverride(stair, origStairName);
                    string stairDescription = NamingUtil.GetDescriptionOverride(stair, null);
                    string stairObjectType = NamingUtil.GetObjectTypeOverride(stair, NamingUtil.CreateIFCObjectName(exporterIFC, stair));
                    IFCAnyHandle stairLocalPlacement = placementSetter.GetPlacement();
                    string stairElementTag = NamingUtil.CreateIFCElementId(stair);
                    IFCStairType stairType = GetIFCStairType(ifcEnumType);

                    IFCAnyHandle stairContainerHnd = IFCInstanceExporter.CreateStair(file, stairGUID, ownerHistory, stairName,
                        stairDescription, stairObjectType, stairLocalPlacement, null, stairElementTag, stairType);
                    productWrapper.AddElement(stairContainerHnd, placementSetter.GetLevelInfo(), null, LevelUtil.AssociateElementToLevel(stair));

                    // Get List of runs to export their geometry.
                    ICollection<ElementId> runIds = stair.GetStairsRuns();
                    int index = 0;
                    foreach (ElementId runId in runIds)
                    {
                        index++;
                        StairsRun run = doc.GetElement(runId) as StairsRun;

                        using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                        {
                            ecData.AllowVerticalOffsetOfBReps = false;
                            ecData.SetLocalPlacement(placementSetter.GetPlacement());
                            ecData.ReuseLocalPlacement = false;

                            GeometryElement runGeometryElement = run.get_Geometry(geomOptions);

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                            BodyData bodyData = BodyExporter.ExportBody(app, exporterIFC, run, categoryId, runGeometryElement,
                                bodyExporterOptions, ecData);

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

                            foreach (ElementId materialId in bodyData.MaterialIds)
                                materialIds.Add(materialId);

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

                            Transform runBoundaryTrf = trf.Multiply(bodyData.BrepOffsetTransform);
                            Plane runBoundaryPlane = new Plane(runBoundaryTrf.BasisX, runBoundaryTrf.BasisY, runBoundaryTrf.Origin);
                            XYZ runBoundaryProjDir = runBoundaryTrf.BasisZ;

                            CurveLoop boundary = run.GetFootprintBoundary();
                            IFCAnyHandle boundaryHnd = ExporterIFCUtils.CreateCurveFromCurveLoop(exporterIFC, boundary,
                                runBoundaryPlane, runBoundaryProjDir);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(boundaryHnd))
                            {
                                HashSet<IFCAnyHandle> geomSelectSet = new HashSet<IFCAnyHandle>();
                                geomSelectSet.Add(boundaryHnd);

                                HashSet<IFCAnyHandle> boundaryItems = new HashSet<IFCAnyHandle>();
                                boundaryItems.Add(IFCInstanceExporter.CreateGeometricSet(file, geomSelectSet));

                                IFCAnyHandle boundaryRep = RepresentationUtil.CreateGeometricSetRep(exporterIFC, run, categoryId, "FootPrint",
                                    contextOfItemsFootPrint, boundaryItems);
                                reps.Add(boundaryRep);
                            }

                            CurveLoop walkingLine = run.GetStairsPath();
                            IFCAnyHandle walkingLineHnd = ExporterIFCUtils.CreateCurveFromCurveLoop(exporterIFC, walkingLine,
                                runBoundaryPlane, runBoundaryProjDir);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(walkingLineHnd))
                            {
                                HashSet<IFCAnyHandle> geomSelectSet = new HashSet<IFCAnyHandle>();
                                geomSelectSet.Add(walkingLineHnd);

                                HashSet<IFCAnyHandle> walkingLineItems = new HashSet<IFCAnyHandle>();
                                walkingLineItems.Add(IFCInstanceExporter.CreateGeometricSet(file, geomSelectSet));

                                IFCAnyHandle walkingLineRep = RepresentationUtil.CreateGeometricSetRep(exporterIFC, run, categoryId, "Axis",
                                    contextOfItemsFootPrint, walkingLineItems);
                                reps.Add(walkingLineRep);
                            }

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

                            string runGUID = ExporterIFCUtils.CreateGUID(run);
                            string origRunName = origStairName + " Run " + index;
                            string runName = NamingUtil.GetNameOverride(run, origRunName);
                            string runDescription = NamingUtil.GetDescriptionOverride(run, stairDescription);
                            string runObjectType = NamingUtil.GetObjectTypeOverride(run, stairObjectType);
                            IFCAnyHandle runLocalPlacement = ecData.GetLocalPlacement();
                            string runElementTag = NamingUtil.CreateIFCElementId(run);

                            IFCAnyHandle stairFlightHnd = IFCInstanceExporter.CreateStairFlight(file, runGUID, ownerHistory,
                                runName, runDescription, runObjectType, runLocalPlacement, representation, runElementTag,
                                run.ActualRisersNumber, run.ActualTreadsNumber, stair.ActualRiserHeight, stair.ActualTreadDepth);

                            componentHandles.Add(stairFlightHnd);
                            componentExtrusionData.Add(ecData);

                            productWrapper.AddElement(stairFlightHnd, placementSetter.GetLevelInfo(), ecData, false);

                            ExporterCacheManager.HandleToElementCache.Register(stairFlightHnd, run.Id);
                        }
                    }

                    // Get List of landings to export their geometry.
                    ICollection<ElementId> landingIds = stair.GetStairsLandings();
                    index = 0;
                    foreach (ElementId landingId in landingIds)
                    {
                        index++;
                        StairsLanding landing = doc.GetElement(landingId) as StairsLanding;

                        using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                        {
                            ecData.AllowVerticalOffsetOfBReps = false;
                            ecData.SetLocalPlacement(placementSetter.GetPlacement());
                            ecData.ReuseLocalPlacement = false;

                            GeometryElement landingGeometryElement = landing.get_Geometry(geomOptions);

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                            BodyData bodyData = BodyExporter.ExportBody(app, exporterIFC, landing, categoryId, landingGeometryElement,
                                bodyExporterOptions, ecData);

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

                            foreach (ElementId materialId in bodyData.MaterialIds)
                                materialIds.Add(materialId);

                            // create Boundary rep.
                            IList<IFCAnyHandle> reps = new List<IFCAnyHandle>();
                            reps.Add(bodyRep);

                            Transform landingBoundaryTrf = trf.Multiply(bodyData.BrepOffsetTransform);
                            Plane landingBoundaryPlane = new Plane(landingBoundaryTrf.BasisX, landingBoundaryTrf.BasisY, landingBoundaryTrf.Origin);
                            XYZ landingBoundaryProjDir = landingBoundaryTrf.BasisZ;

                            CurveLoop boundary = landing.GetFootprintBoundary();
                            IFCAnyHandle boundaryHnd = ExporterIFCUtils.CreateCurveFromCurveLoop(exporterIFC, boundary,
                                landingBoundaryPlane, landingBoundaryProjDir);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(boundaryHnd))
                            {
                                HashSet<IFCAnyHandle> geomSelectSet = new HashSet<IFCAnyHandle>();
                                geomSelectSet.Add(boundaryHnd);

                                HashSet<IFCAnyHandle> boundaryItems = new HashSet<IFCAnyHandle>();
                                boundaryItems.Add(IFCInstanceExporter.CreateGeometricSet(file, geomSelectSet));

                                IFCAnyHandle boundaryRep = RepresentationUtil.CreateGeometricSetRep(exporterIFC, landing, categoryId, "FootPrint",
                                    contextOfItemsFootPrint, boundaryItems);
                                reps.Add(boundaryRep);
                            }

                            CurveLoop walkingLine = landing.GetStairsPath();
                            IFCAnyHandle walkingLineHnd = ExporterIFCUtils.CreateCurveFromCurveLoop(exporterIFC, walkingLine,
                                landingBoundaryPlane, landingBoundaryProjDir);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(walkingLineHnd))
                            {
                                HashSet<IFCAnyHandle> geomSelectSet = new HashSet<IFCAnyHandle>();
                                geomSelectSet.Add(walkingLineHnd);

                                HashSet<IFCAnyHandle> walkingLineItems = new HashSet<IFCAnyHandle>();
                                walkingLineItems.Add(IFCInstanceExporter.CreateGeometricSet(file, geomSelectSet));

                                IFCAnyHandle walkingLineRep = RepresentationUtil.CreateGeometricSetRep(exporterIFC, landing, categoryId, "Axis",
                                    contextOfItemsFootPrint, walkingLineItems);
                                reps.Add(walkingLineRep);
                            }

                            string landingGUID = ExporterIFCUtils.CreateGUID(landing);
                            string origLandingName = origStairName + " Landing " + index;
                            string landingName = NamingUtil.GetNameOverride(landing, origLandingName);
                            string landingDescription = NamingUtil.GetDescriptionOverride(landing, stairDescription);
                            string landingObjectType = NamingUtil.GetObjectTypeOverride(landing, stairObjectType);
                            IFCAnyHandle landingLocalPlacement = ecData.GetLocalPlacement();
                            string landingElementTag = NamingUtil.CreateIFCElementId(landing);

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

                            IFCAnyHandle landingHnd = IFCInstanceExporter.CreateSlab(file, landingGUID, ownerHistory,
                                landingName, landingDescription, landingObjectType, landingLocalPlacement, representation, landingElementTag,
                                IFCSlabType.Landing);

                            componentHandles.Add(landingHnd);
                            componentExtrusionData.Add(ecData);

                            productWrapper.AddElement(landingHnd, placementSetter.GetLevelInfo(), ecData, false);
                            ExporterCacheManager.HandleToElementCache.Register(landingHnd, landing.Id);
                        }
                    }

                    // Get List of supports to export their geometry.  Supports are not exposed to API, so export as generic Element.
                    ICollection<ElementId> supportIds = stair.GetStairsSupports();
                    index = 0;
                    foreach (ElementId supportId in supportIds)
                    {
                        index++;
                        Element support = doc.GetElement(supportId);

                        using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                        {
                            ecData.SetLocalPlacement(placementSetter.GetPlacement());
                            ecData.ReuseLocalPlacement = false;

                            GeometryElement supportGeometryElement = support.get_Geometry(geomOptions);
                            BodyData bodyData;
                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                            IFCAnyHandle representation = RepresentationUtil.CreateBRepProductDefinitionShape(app, exporterIFC,
                                support, categoryId, supportGeometryElement, bodyExporterOptions, null, ecData, out bodyData);

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

                            foreach (ElementId materialId in bodyData.MaterialIds)
                                materialIds.Add(materialId);

                            string supportGUID = ExporterIFCUtils.CreateGUID(support);
                            string origSupportName = origStairName + " Stringer " + index;
                            string supportName = NamingUtil.GetNameOverride(support, origSupportName);
                            string supportDescription = NamingUtil.GetDescriptionOverride(support, stairDescription);
                            string supportObjectType = NamingUtil.GetObjectTypeOverride(support, stairObjectType);
                            IFCAnyHandle supportLocalPlacement = ecData.GetLocalPlacement();
                            string supportElementTag = NamingUtil.CreateIFCElementId(support);

                            IFCAnyHandle type = GetMemberTypeHandle(exporterIFC, support);

                            IFCAnyHandle supportHnd = IFCInstanceExporter.CreateMember(file, supportGUID, ownerHistory,
                                supportName, supportDescription, supportObjectType, supportLocalPlacement, representation, supportElementTag);

                            componentHandles.Add(supportHnd);
                            componentExtrusionData.Add(ecData);

                            productWrapper.AddElement(supportHnd, placementSetter.GetLevelInfo(), ecData, false);

                            ExporterCacheManager.TypeRelationsCache.Add(type, supportHnd);
                        }
                    }

                    StairRampContainerInfo stairRampInfo = new StairRampContainerInfo(stairContainerHnd, componentHandles, null);
                    ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(stair.Id, stairRampInfo);

                    CategoryUtil.CreateMaterialAssociations(stair.Document, exporterIFC, stairContainerHnd, materialIds);

                    ExportMultistoryStair(exporterIFC, stair, numFlights, stairContainerHnd, componentHandles, componentExtrusionData,
                         materialIds, placementSetter, productWrapper);
                }
                tr.Commit();
            }
        }
Ejemplo n.º 38
0
        /// <summary>
        /// Exports a Rebar to IFC ReinforcingBar.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element to be exported.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>The list of IfcReinforcingBar handles created.</returns>
        public static ISet<IFCAnyHandle> ExportRebar(ExporterIFC exporterIFC, Element element, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();
            HashSet<IFCAnyHandle> createdRebars = new HashSet<IFCAnyHandle>();

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    if (element is Rebar)
                    {
                        GeometryElement rebarGeometry = ExporterIFCUtils.GetRebarGeometry(element as Rebar, ExporterCacheManager.ExportOptionsCache.FilterViewForExport);

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

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

                    IFCAnyHandle prodRep = null;

                    double totalBarLengthUnscale = GetRebarTotalLength(element);
                    double volumeUnscale = GetRebarVolume(element);
                    double totalBarLength = UnitUtil.ScaleLength(totalBarLengthUnscale);

                    if (MathUtil.IsAlmostZero(totalBarLength))
                        return null;

                    ElementId materialId = ElementId.InvalidElementId;
                    ParameterUtil.GetElementIdValueFromElementOrSymbol(element, BuiltInParameter.MATERIAL_ID_PARAM, out materialId);

                    Document doc = element.Document;
                    ElementId typeId = element.GetTypeId();
                    RebarBarType elementType = doc.GetElement(element.GetTypeId()) as RebarBarType;
                    double diameter = UnitUtil.ScaleLength(elementType == null ? 1.0 / 12.0 : elementType.BarDiameter);
                    double radius = diameter / 2.0;
                    double longitudinalBarNominalDiameter = diameter;
                    double longitudinalBarCrossSectionArea = UnitUtil.ScaleArea(volumeUnscale / totalBarLengthUnscale);
                    double barLength = totalBarLength / GetRebarQuantity(element);

                    IList<Curve> baseCurves = GetRebarCenterlineCurves(element, true, false, false);
                    int numberOfBarPositions = GetNumberOfBarPositions(element);

                    string steelGrade = NamingUtil.GetOverrideStringValue(element, "SteelGrade", null);
                    
                    // Allow use of IFC2x3 or IFC4 naming.
                    string predefinedType = NamingUtil.GetOverrideStringValue(element, "BarRole", null);
                    if (string.IsNullOrWhiteSpace(predefinedType))
                        predefinedType = NamingUtil.GetOverrideStringValue(element, "PredefinedType", null);
                    IFCReinforcingBarRole role = GetReinforcingBarRole(predefinedType);

                    string origRebarName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                    string rebarDescription = NamingUtil.GetDescriptionOverride(element, null);
                    string rebarObjectType = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element));
                    string rebarTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));
                    
                    const int maxBarGUIDS = IFCReinforcingBarSubElements.BarEnd - IFCReinforcingBarSubElements.BarStart + 1;
                    ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

                    IFCAnyHandle originalPlacement = setter.LocalPlacement;

                    for (int i = 0; i < numberOfBarPositions; i++)
                    {
                        if (!DoesBarExistAtPosition(element, i))
                            continue;

                        string rebarName = NamingUtil.GetNameOverride(element, origRebarName + ": " + i);

                        Transform barTrf = GetBarPositionTransform(element, i);

                        IList<Curve> curves = new List<Curve>();
                        double endParam = 0.0;
                        foreach (Curve baseCurve in baseCurves)
                        {
                            if (baseCurve is Arc || baseCurve is Ellipse)
                            {
                                if (baseCurve.IsBound)
                                    endParam += UnitUtil.ScaleAngle(baseCurve.GetEndParameter(1) - baseCurve.GetEndParameter(0));
                                else
                                    endParam += UnitUtil.ScaleAngle(2 * Math.PI);
                            }
                            else
                                endParam += 1.0;
                            curves.Add(baseCurve.CreateTransformed(barTrf));
                        }

                        IFCAnyHandle compositeCurve = GeometryUtil.CreateCompositeCurve(exporterIFC, curves);
                        IFCAnyHandle sweptDiskSolid = IFCInstanceExporter.CreateSweptDiskSolid(file, compositeCurve, radius, null, 0, endParam);
                        HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();
                        bodyItems.Add(sweptDiskSolid);

                        IFCAnyHandle shapeRep = RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC, element, categoryId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null);
                        IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>();
                        shapeReps.Add(shapeRep);
                        prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);

                        IFCAnyHandle copyLevelPlacement = (i == 0) ? originalPlacement : ExporterUtil.CopyLocalPlacement(file, originalPlacement);

                        string rebarGUID = (i < maxBarGUIDS) ?
                            GUIDUtil.CreateSubElementGUID(element, i + (int)IFCReinforcingBarSubElements.BarStart) :
                            GUIDUtil.CreateGUID();
                        IFCAnyHandle elemHnd = IFCInstanceExporter.CreateReinforcingBar(file, rebarGUID, exporterIFC.GetOwnerHistoryHandle(),
                            rebarName, rebarDescription, rebarObjectType, copyLevelPlacement,
                            prodRep, rebarTag, steelGrade, longitudinalBarNominalDiameter, longitudinalBarCrossSectionArea,
                            barLength, role, null);
                        createdRebars.Add(elemHnd);

                        productWrapper.AddElement(element, elemHnd, setter.LevelInfo, null, true);
                        ExporterCacheManager.HandleToElementCache.Register(elemHnd, element.Id);

                        CategoryUtil.CreateMaterialAssociation(exporterIFC, elemHnd, materialId);
                    }
                }
                transaction.Commit();
            }
            return createdRebars;
        }
        /// <summary>
        /// Create IFC room/space/area item, not include boundaries. 
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="spatialElement">
        /// The spatial element.
        /// </param>
        /// <param name="productWrapper">
        /// The IFCProductWrapper.
        /// </param>
        /// <param name="setter">
        /// The IFCPlacementSetter.
        /// </param>
        /// <returns>
        /// True if created successfully, false otherwise.
        /// </returns>
        static void CreateIFCSpace(ExporterIFC exporterIFC, SpatialElement spatialElement, IFCProductWrapper productWrapper, IFCPlacementSetter setter)
        {
            Autodesk.Revit.DB.Document document = spatialElement.Document;
            ElementId levelId = spatialElement.Level != null ? spatialElement.Level.Id : ElementId.InvalidElementId;
            double scale = exporterIFC.LinearScale;

            ElementId catId = spatialElement.Category != null ? spatialElement.Category.Id : ElementId.InvalidElementId;

            double dArea = 0.0;

            Parameter param = spatialElement.get_Parameter(BuiltInParameter.ROOM_AREA);
            if (param != null)
            {
                dArea = param.AsDouble();
                dArea *= (scale * scale);
            }


            SpatialElementBoundaryOptions options = ExporterIFCUtils.GetSpatialElementBoundaryOptions(exporterIFC, spatialElement);
            IList<CurveLoop> curveLoops = ExporterIFCUtils.GetRoomBoundaryAsCurveLoopArray(spatialElement, options, true);

            IFCLevelInfo levelInfo = exporterIFC.GetLevelInfo(levelId);

            string strSpaceNumber = null;
            string strSpaceName = null;
            string strSpaceDesc = null;

            bool isArea = spatialElement is Area;
            if (!isArea)
            {
                Parameter paramRoomNum = spatialElement.get_Parameter(BuiltInParameter.ROOM_NUMBER);
                if (paramRoomNum != null)
                {
                    strSpaceNumber = paramRoomNum.AsString();
                }

                Parameter paramRoomName = spatialElement.get_Parameter(BuiltInParameter.ROOM_NAME);
                if (paramRoomName != null)
                {
                    strSpaceName = paramRoomName.AsString();
                }

                Parameter paramRoomComm = spatialElement.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS);
                if (paramRoomComm != null)
                {
                    strSpaceDesc = paramRoomComm.AsString();
                }
            }
            else
            {
                Element level = document.get_Element(levelId);
                if (level != null)
                {
                    strSpaceNumber = level.Name + " GSA Design Gross Area";
                }
            }

            //assign empty string if it is null
            if (strSpaceNumber == null) strSpaceNumber = "";
            if (strSpaceName == null) strSpaceName = "";
            if (strSpaceDesc == null) strSpaceDesc = "";
            IFCLabel name = IFCLabel.Create(strSpaceNumber);
            IFCLabel longName = IFCLabel.Create(strSpaceName);
            IFCLabel desc = IFCLabel.Create(strSpaceDesc);

            IFCFile file = exporterIFC.GetFile();

            IFCAnyHandle localPlacement = setter.GetPlacement();
            ElementType elemType = document.get_Element(spatialElement.GetTypeId()) as ElementType;
            bool isObjectExternal = CategoryUtil.IsElementExternal(spatialElement);
            IFCMeasureValue elevationWithFlooring = IFCMeasureValue.Create();

            double roomHeight = 0.0;

            roomHeight = GetHeight(spatialElement, scale, levelInfo);

            double bottomOffset = 0.0;
            Parameter paramBottomOffset = spatialElement.get_Parameter(BuiltInParameter.ROOM_LOWER_OFFSET);
            bottomOffset = paramBottomOffset != null ? paramBottomOffset.AsDouble() : 0.0;

            XYZ zDir = new XYZ(0, 0, 1);
            XYZ orig = new XYZ(0, 0, levelInfo.Elevation + bottomOffset);

            Plane plane = new Plane(zDir, orig); // room calculated as level offset.

            GeometryElement geomElem = null;
            if (spatialElement is Autodesk.Revit.DB.Architecture.Room)
            {
                Autodesk.Revit.DB.Architecture.Room room = spatialElement as Autodesk.Revit.DB.Architecture.Room;
                geomElem = room.ClosedShell;
            }
            else if (spatialElement is Autodesk.Revit.DB.Mechanical.Space)
            {
                Autodesk.Revit.DB.Mechanical.Space space = spatialElement as Autodesk.Revit.DB.Mechanical.Space;
                geomElem = space.ClosedShell;
            }

            IFCAnyHandle spaceHnd = null;
            IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData();
            extraParams.SetLocalPlacement(localPlacement);
            extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;

            using (IFCTransaction tr2 = new IFCTransaction(file))
            {
                IFCAnyHandle repHnd = null;
                if (!(exporterIFC.ExportAs2x2 || Use2DRoomBoundaryForRoomVolumeCalculation()) && geomElem != null)
                {

                    IFCSolidMeshGeometryInfo solidMeshInfo = ExporterIFCUtils.GetSolidMeshGeometry(exporterIFC, geomElem, Transform.Identity);
                    IList<Solid> solids = solidMeshInfo.GetSolids();
                    IList<Mesh> polyMeshes = solidMeshInfo.GetMeshes();

                    bool tryToExportAsExtrusion = true;
                    if (solids.Count != 1 || polyMeshes.Count != 0)
                        tryToExportAsExtrusion = false;

                    IList<GeometryObject> geomObjects = new List<GeometryObject>();

                    foreach (Solid solid in solids)
                        geomObjects.Add(solid);

                    IFCAnyHandle shapeRep = BodyExporter.ExportBody(spatialElement.Document.Application, exporterIFC, catId, geomObjects, tryToExportAsExtrusion, extraParams);
                    IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>();
                    shapeReps.Add(shapeRep);
                    repHnd = file.CreateProductDefinitionShape(IFCLabel.Create(), IFCLabel.Create(), shapeReps);
                }
                else
                {
                    IFCAnyHandle shapeRep = file.CreateExtrudedSolidFromCurveLoop(exporterIFC, catId, curveLoops, plane, zDir, roomHeight); //pScaledOrig?
                    HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();
                    bodyItems.Add(shapeRep);
                    shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, catId, exporterIFC.Get3DContextHandle(), bodyItems, IFCAnyHandle.Create());
                    IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>();
                    shapeReps.Add(shapeRep);
                    repHnd = file.CreateProductDefinitionShape(IFCLabel.Create(), IFCLabel.Create(), shapeReps);
                }

                extraParams.ScaledHeight = roomHeight;
                extraParams.ScaledArea = dArea;

                spaceHnd = file.CreateSpace(IFCLabel.CreateGUID(spatialElement),
                                                  exporterIFC.GetOwnerHistoryHandle(),
                                                  NamingUtil.GetNameOverride(spatialElement, name),
                                                  NamingUtil.GetDescriptionOverride(spatialElement, desc),
                                                  NamingUtil.GetObjectTypeOverride(spatialElement, IFCLabel.Create()),
                                                  extraParams.GetLocalPlacement(), repHnd, longName, IFCElementComposition.Element
                                                  , isObjectExternal, elevationWithFlooring);
                tr2.Commit();
            }

            productWrapper.AddSpace(spaceHnd, levelInfo, extraParams, true);

            // Save room handle for later use/relationships
            exporterIFC.RegisterSpatialElementHandle(spatialElement.Id, spaceHnd);

            if (!MathUtil.IsAlmostZero(dArea) && !(exporterIFC.FileVersion == IFCVersion.IFCCOBIE))
            {
                ExporterIFCUtils.CreatePreCOBIEGSAQuantities(exporterIFC, spaceHnd, "GSA Space Areas", (isArea ? "GSA Design Gross Area" : "GSA BIM Area"), dArea);
            }

            // Export BaseQuantities for RoomElem
            if (exporterIFC.ExportBaseQuantities && !(exporterIFC.FileVersion == IFCVersion.IFCCOBIE))
            {
                ExporterIFCUtils.CreateNonCOBIERoomQuantities(exporterIFC, spaceHnd, spatialElement, dArea, roomHeight);
            }
        }
Ejemplo n.º 40
0
        /// <summary>
        /// Exports a CeilingAndFloor element to IFC.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="floor">The floor element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportCeilingAndFloorElement(ExporterIFC exporterIFC, CeilingAndFloor floorElement, ref GeometryElement geometryElement,
                                                        ProductWrapper productWrapper)
        {
            if (geometryElement == null)
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

            string            ifcEnumType;
            IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, floorElement, out ifcEnumType);
            IFCAnyHandle      type       = null;

            if (!ElementFilteringUtil.IsElementVisible(floorElement))
            {
                return;
            }

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

            Document doc = floorElement.Document;

            using (SubTransaction tempPartTransaction = new SubTransaction(doc))
            {
                MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, floorElement, productWrapper);
                // For IFC4RV export, Element will be split into its parts(temporarily) in order to export the wall by its parts
                // If Parts are created by code and not by user then their names should be equal to Material names.
                bool setMaterialNameToPartName         = ExporterUtil.CreateParts(floorElement, layersetInfo.MaterialIds.Count, ref geometryElement);
                ExporterUtil.ExportPartAs exportPartAs = ExporterUtil.CanExportByComponentsOrParts(floorElement);
                bool exportByComponents = exportPartAs == ExporterUtil.ExportPartAs.ShapeAspect;
                bool exportParts        = exportPartAs == ExporterUtil.ExportPartAs.Part;

                if (exportParts && !PartExporter.CanExportElementInPartExport(floorElement, floorElement.LevelId, false))
                {
                    return;
                }

                using (IFCTransaction tr = new IFCTransaction(file))
                {
                    bool canExportAsContainerOrWithExtrusionAnalyzer = (!exportParts && (floorElement is Floor));

                    if (canExportAsContainerOrWithExtrusionAnalyzer)
                    {
                        // Try to export the Floor slab as a container.  If that succeeds, we are done.
                        // If we do export the floor as a container, it will take care of the local placement and transform there, so we need to leave
                        // this out of the IFCTransformSetter and PlacementSetter scopes below, or else we'll get double transforms.
                        IFCAnyHandle floorHnd = RoofExporter.ExportRoofOrFloorAsContainer(exporterIFC, floorElement, geometryElement, productWrapper);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(floorHnd))
                        {
                            tr.Commit();
                            return;
                        }
                    }

                    IList <IFCAnyHandle> slabHnds        = new List <IFCAnyHandle>();
                    IList <IFCAnyHandle> brepSlabHnds    = new List <IFCAnyHandle>();
                    IList <IFCAnyHandle> nonBrepSlabHnds = new List <IFCAnyHandle>();

                    IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

                    using (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
                    {
                        // Check for containment override
                        IFCAnyHandle overrideContainerHnd = null;
                        ElementId    overrideContainerId  = ParameterUtil.OverrideContainmentParameter(exporterIFC, floorElement, out overrideContainerHnd);

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

                            // The routine ExportExtrudedSlabOpenings is called if exportedAsInternalExtrusion is true, and it requires having a valid level association.
                            // Disable calling ExportSlabAsExtrusion if we can't handle potential openings.
                            bool canExportAsInternalExtrusion = placementSetter.LevelInfo != null && !ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView;
                            bool exportedAsInternalExtrusion  = false;

                            ElementId catId = CategoryUtil.GetSafeCategoryId(floorElement);

                            IList <IFCAnyHandle>             prodReps        = new List <IFCAnyHandle>();
                            IList <ShapeRepresentationType>  repTypes        = new List <ShapeRepresentationType>();
                            IList <IList <CurveLoop> >       extrusionLoops  = new List <IList <CurveLoop> >();
                            IList <IFCExtrusionCreationData> loopExtraParams = new List <IFCExtrusionCreationData>();
                            Plane floorPlane = GeometryUtil.CreateDefaultPlane();

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

                            if (!exportParts)
                            {
                                if (canExportAsContainerOrWithExtrusionAnalyzer)
                                {
                                    Floor floor = floorElement as Floor;

                                    // Next, try to use the ExtrusionAnalyzer for the limited cases it handles - 1 solid, no openings, end clippings only.
                                    // Also limited to cases with line and arc boundaries.
                                    //
                                    SolidMeshGeometryInfo  solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                                    IList <Solid>          solids        = solidMeshInfo.GetSolids();
                                    IList <Mesh>           meshes        = solidMeshInfo.GetMeshes();
                                    IList <GeometryObject> gObjs         = FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(floorElement.Document, exporterIFC, ref solids, ref meshes);

                                    if (solids.Count == 1 && meshes.Count == 0)
                                    {
                                        bool completelyClipped;
                                        // floorExtrusionDirection is set to (0, 0, -1) because extrusionAnalyzerFloorPlane is computed from the top face of the floor
                                        XYZ floorExtrusionDirection = new XYZ(0, 0, -1);
                                        XYZ modelOrigin             = XYZ.Zero;

                                        XYZ floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top);
                                        if (floorOrigin == null)
                                        {
                                            // GetVerticalProjectionPoint may return null if FloorFace.Top is an edited face that doesn't
                                            // go through the Revit model origin.  We'll try the midpoint of the bounding box instead.
                                            BoundingBoxXYZ boundingBox = floorElement.get_BoundingBox(null);
                                            modelOrigin = (boundingBox.Min + boundingBox.Max) / 2.0;
                                            floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top);
                                        }

                                        if (floorOrigin != null)
                                        {
                                            XYZ   floorDir = floor.GetNormalAtVerticalProjectionPoint(floorOrigin, FloorFace.Top);
                                            Plane extrusionAnalyzerFloorBasePlane = GeometryUtil.CreatePlaneByNormalAtOrigin(floorDir);

                                            GenerateAdditionalInfo additionalInfo = GenerateAdditionalInfo.GenerateBody;
                                            additionalInfo |= ExporterCacheManager.ExportOptionsCache.ExportAs4 ?
                                                              GenerateAdditionalInfo.GenerateFootprint : GenerateAdditionalInfo.None;

                                            // Skip generate body item for IFC4RV. It will be handled later in PartExporter.ExportHostPartAsShapeAspects()
                                            if (exportByComponents)
                                            {
                                                additionalInfo &= ~GenerateAdditionalInfo.GenerateBody;
                                            }

                                            HandleAndData floorAndProperties =
                                                ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, floorElement,
                                                                                                           catId, solids[0], extrusionAnalyzerFloorBasePlane, floorOrigin, floorExtrusionDirection, null, out completelyClipped,
                                                                                                           addInfo: additionalInfo);
                                            if (completelyClipped)
                                            {
                                                return;
                                            }

                                            IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();
                                            if (floorAndProperties.Handle != null)
                                            {
                                                representations.Add(floorAndProperties.Handle);
                                                repTypes.Add(ShapeRepresentationType.SweptSolid);
                                            }

                                            // Footprint representation will only be exported in export to IFC4
                                            if (((additionalInfo & GenerateAdditionalInfo.GenerateFootprint) != 0) && (floorAndProperties.FootprintInfo != null))
                                            {
                                                IFCAnyHandle footprintShapeRep = floorAndProperties.FootprintInfo.CreateFootprintShapeRepresentation(exporterIFC);
                                                representations.Add(footprintShapeRep);
                                            }

                                            if (exportByComponents)
                                            {
                                                IFCAnyHandle prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, floorElement, catId, geometryElement, representations);
                                                prodReps.Add(prodRep);
                                            }
                                            else if (representations.Count > 0 && floorAndProperties.Handle != null) // Only when at least the body rep exists will come here
                                            {
                                                IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);
                                                prodReps.Add(prodRep);
                                            }

                                            if (floorAndProperties.Data != null)
                                            {
                                                loopExtraParams.Add(floorAndProperties.Data);
                                            }
                                        }
                                    }
                                }

                                // Use internal routine as backup that handles openings.
                                if (prodReps.Count == 0 && canExportAsInternalExtrusion && !exportByComponents)
                                {
                                    exportedAsInternalExtrusion = ExporterIFCUtils.ExportSlabAsExtrusion(exporterIFC, floorElement,
                                                                                                         geometryElement, transformSetter, localPlacement, out localPlacements, out prodReps,
                                                                                                         out extrusionLoops, out loopExtraParams, floorPlane);
                                    PotentiallyFixPresentationLayerAssignment(floorElement, prodReps);
                                    for (int ii = 0; ii < prodReps.Count; ii++)
                                    {
                                        // all are extrusions
                                        repTypes.Add(ShapeRepresentationType.SweptSolid);

                                        // Footprint representation will only be exported in export to IFC4
                                        if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                                        {
                                            if (extrusionLoops.Count > ii)
                                            {
                                                if (extrusionLoops[ii].Count > 0)
                                                {
                                                    // Get the extrusion footprint using the first Curveloop. Transform needs to be obtained from the returned local placement
                                                    Transform    lcs = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, localPlacements[ii]);
                                                    IFCAnyHandle footprintGeomRepItem = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, extrusionLoops[ii][0], lcs, floorPlane.Normal);

                                                    IFCAnyHandle        contextOfItemsFootprint = exporterIFC.Get3DContextHandle("FootPrint");
                                                    ISet <IFCAnyHandle> repItem = new HashSet <IFCAnyHandle>();
                                                    repItem.Add(footprintGeomRepItem);
                                                    IFCAnyHandle         footprintShapeRepresentation = RepresentationUtil.CreateBaseShapeRepresentation(exporterIFC, contextOfItemsFootprint, "FootPrint", "Curve2D", repItem);
                                                    IList <IFCAnyHandle> reps = new List <IFCAnyHandle>();
                                                    reps.Add(footprintShapeRepresentation);
                                                    IFCAnyHandleUtil.AddRepresentations(prodReps[ii], reps);
                                                }
                                            }
                                        }
                                    }
                                }

                                IFCAnyHandle prodDefHnd;
                                if (prodReps.Count == 0)
                                {
                                    if (exportByComponents)
                                    {
                                        prodDefHnd = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, floorElement, catId, geometryElement, null);
                                        prodReps.Add(prodDefHnd);
                                    }
                                    else
                                    {
                                        using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                                        {
                                            // Brep representation using tesellation after ExportSlabAsExtrusion does not return prodReps
                                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium);
                                            BodyData            bodyData;
                                            prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                                    floorElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData);
                                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd))
                                            {
                                                ecData.ClearOpenings();
                                                return;
                                            }

                                            prodReps.Add(prodDefHnd);
                                            repTypes.Add(bodyData.ShapeRepresentationType);
                                        }
                                    }
                                }
                            }

                            // Create the slab from either the extrusion or the BRep information.
                            string ifcGUID = GUIDUtil.CreateGUID(floorElement);

                            int numReps = exportParts ? 1 : prodReps.Count;

                            // Deal with a couple of cases that have non-standard defaults.
                            switch (exportType.ExportInstance)
                            {
                            case IFCEntityType.IfcCovering:
                                exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType <IFCCoveringType>(floorElement, ifcEnumType, "FLOORING");
                                break;

                            case IFCEntityType.IfcSlab:
                                bool            isBaseSlab      = false;
                                AnalyticalModel analyticalModel = floorElement.GetAnalyticalModel();
                                if (analyticalModel != null)
                                {
                                    AnalyzeAs slabFoundationType = analyticalModel.GetAnalyzeAs();
                                    isBaseSlab = (slabFoundationType == AnalyzeAs.SlabOnGrade) || (slabFoundationType == AnalyzeAs.Mat);
                                }
                                exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(floorElement, ifcEnumType, isBaseSlab ? "BASESLAB" : "FLOOR");
                                break;
                            }

                            for (int ii = 0; ii < numReps; ii++)
                            {
                                string ifcName = NamingUtil.GetNameOverride(floorElement, NamingUtil.GetIFCNamePlusIndex(floorElement, ii == 0 ? -1 : ii + 1));

                                string       currentGUID       = (ii == 0) ? ifcGUID : GUIDUtil.CreateGUID();
                                IFCAnyHandle localPlacementHnd = exportedAsInternalExtrusion ? localPlacements[ii] : localPlacement;

                                IFCAnyHandle slabHnd = null;
                                slabHnd = IFCInstanceExporter.CreateGenericIFCEntity(exportType, exporterIFC, floorElement, currentGUID, ownerHistory,
                                                                                     localPlacementHnd, exportParts ? null : prodReps[ii]);
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd))
                                {
                                    return;
                                }

                                if (!string.IsNullOrEmpty(ifcName))
                                {
                                    IFCAnyHandleUtil.OverrideNameAttribute(slabHnd, ifcName);
                                }

                                // Pre IFC4 Slab does not have PredefinedType
                                if (!string.IsNullOrEmpty(exportType.ValidatedPredefinedType) && !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4)
                                {
                                    IFCAnyHandleUtil.SetAttribute(slabHnd, "PredefinedType", exportType.ValidatedPredefinedType, true);
                                }
                                if (exportParts)
                                {
                                    PartExporter.ExportHostPart(exporterIFC, floorElement, slabHnd, productWrapper, placementSetter, localPlacementHnd, null, setMaterialNameToPartName);
                                }
                                else if (exportByComponents)
                                {
                                    IFCExtrusionCreationData partECData            = new IFCExtrusionCreationData();
                                    IFCAnyHandle             hostShapeRepFromParts = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, floorElement, prodReps[ii],
                                                                                                                               productWrapper, placementSetter, localPlacement, ElementId.InvalidElementId, layersetInfo, partECData);
                                    loopExtraParams.Add(partECData);
                                }

                                slabHnds.Add(slabHnd);

                                // For IFC4RV, export of the geometry is already handled in PartExporter.ExportHostPartAsShapeAspects()
                                if (!exportParts && !exportByComponents)
                                {
                                    if (repTypes[ii] == ShapeRepresentationType.Brep || repTypes[ii] == ShapeRepresentationType.Tessellation)
                                    {
                                        brepSlabHnds.Add(slabHnd);
                                    }
                                    else
                                    {
                                        nonBrepSlabHnds.Add(slabHnd);
                                    }
                                }
                            }

                            for (int ii = 0; ii < numReps; ii++)
                            {
                                IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null;
                                productWrapper.AddElement(floorElement, slabHnds[ii], placementSetter, loopExtraParam, true, exportType);

                                type = ExporterUtil.CreateGenericTypeFromElement(floorElement, exportType, file, ownerHistory, exportType.ValidatedPredefinedType, productWrapper);
                                ExporterCacheManager.TypeRelationsCache.Add(type, slabHnds[ii]);

                                ExporterUtil.AddIntoComplexPropertyCache(slabHnds[ii], layersetInfo);
                            }

                            // This call to the native function appears to create Brep opening also when appropriate. But the creation of the IFC instances is not
                            //   controllable from the managed code. Therefore in some cases BRep geometry for Opening will still be exported even in the Reference View
                            if (exportedAsInternalExtrusion)
                            {
                                ISet <IFCAnyHandle> oldCreatedObjects = productWrapper.GetAllObjects();
                                ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, floorElement, placementSetter.LevelInfo,
                                                                            localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative());
                                ISet <IFCAnyHandle> newCreatedObjects = productWrapper.GetAllObjects();
                                newCreatedObjects.ExceptWith(oldCreatedObjects);
                                PotentiallyFixPresentationLayerAssignment(floorElement, newCreatedObjects);
                            }
                        }

                        if (!exportParts)
                        {
                            if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)
                            {
                                HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, productWrapper.GetAnElement(),
                                                                             geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false, type);
                            }
                            else
                            {
                                if (nonBrepSlabHnds.Count > 0)
                                {
                                    HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, nonBrepSlabHnds,
                                                                                 geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false, type);
                                }

                                if (brepSlabHnds.Count > 0)
                                {
                                    HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, brepSlabHnds,
                                                                                 geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, true, type);
                                }
                            }
                        }
                    }

                    tr.Commit();
                    return;
                }
            }
        }
        /// <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 (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(setter.GetPlacement());

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

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

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


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

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

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

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

                        IFCAnyHandle 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 name = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string description = NamingUtil.GetDescriptionOverride(element, null);
                        string objectType = NamingUtil.GetObjectTypeOverride(element, elementTypeName);
                        string Tag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

                        IFCAnyHandle elemHnd = IFCInstanceExporter.CreateFlowSegment(file, GUIDUtil.CreateGUID(element),
                            exporterIFC.GetOwnerHistoryHandle(), name, description, objectType, localPlacementToUse, prodRep,
                            Tag);

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

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

                    tr.Commit();
                }
            }
        }
        /// <summary>
        /// Creates IFC room/space/area item, not include boundaries. 
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="spatialElement">The spatial element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <param name="setter">The PlacementSetter.</param>
        /// <returns>True if created successfully, false otherwise.</returns>
        static bool CreateIFCSpace(ExporterIFC exporterIFC, SpatialElement spatialElement, ProductWrapper productWrapper, 
            PlacementSetter setter, out SpatialElementGeometryResults results)
        {
            results = null;

            IList<CurveLoop> curveLoops = null;
            try
            {
                // Avoid throwing for a spatial element with no location.
                if (spatialElement.Location == null)
                    return false;

                SpatialElementBoundaryOptions options = GetSpatialElementBoundaryOptions(spatialElement);
                curveLoops = ExporterIFCUtils.GetRoomBoundaryAsCurveLoopArray(spatialElement, options, true);
            }
            catch (Autodesk.Revit.Exceptions.InvalidOperationException)
            {
                //Some spatial elements are not placed that have no boundary loops. Don't export them.
                return false;
            }

            Autodesk.Revit.DB.Document document = spatialElement.Document;
            ElementId levelId = spatialElement.LevelId;

            ElementId catId = spatialElement.Category != null ? spatialElement.Category.Id : ElementId.InvalidElementId;

            double dArea = 0.0;
            if (ParameterUtil.GetDoubleValueFromElement(spatialElement, BuiltInParameter.ROOM_AREA, out dArea) != null)
                dArea = UnitUtil.ScaleArea(dArea);

            IFCLevelInfo levelInfo = exporterIFC.GetLevelInfo(levelId);

            string strSpaceNumber = null;
            string strSpaceName = null;
            string strSpaceDesc = null;

            if (ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ROOM_NUMBER, out strSpaceNumber) == null)
                strSpaceNumber = null;

            if (ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ROOM_NAME, out strSpaceName) == null)
                strSpaceName = null;

            if (ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS, out strSpaceDesc) == null)
                strSpaceDesc = null;

            string name = strSpaceNumber;
            string longName = strSpaceName;
            string desc = strSpaceDesc;

            IFCFile file = exporterIFC.GetFile();

            IFCAnyHandle localPlacement = setter.LocalPlacement;
            ElementType elemType = document.GetElement(spatialElement.GetTypeId()) as ElementType;
            IFCInternalOrExternal internalOrExternal = CategoryUtil.IsElementExternal(spatialElement) ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal;

            double scaledRoomHeight = GetScaledHeight(spatialElement, levelId, levelInfo);
            if (scaledRoomHeight <= 0.0)
                return false;

            double bottomOffset;
            ParameterUtil.GetDoubleValueFromElement(spatialElement, BuiltInParameter.ROOM_LOWER_OFFSET, out bottomOffset);

         double elevation = (levelInfo != null) ? levelInfo.Elevation : 0.0;
            XYZ zDir = new XYZ(0, 0, 1);
         XYZ orig = new XYZ(0, 0, elevation + bottomOffset);

            Plane plane = new Plane(zDir, orig); // room calculated as level offset.

            GeometryElement geomElem = null;
            bool isArea = (spatialElement is Area);
            Area spatialElementAsArea = isArea ? (spatialElement as Area) : null;

            if (spatialElement is Autodesk.Revit.DB.Architecture.Room)
            {
                Autodesk.Revit.DB.Architecture.Room room = spatialElement as Autodesk.Revit.DB.Architecture.Room;
                geomElem = room.ClosedShell;
            }
            else if (spatialElement is Autodesk.Revit.DB.Mechanical.Space)
            {
                Autodesk.Revit.DB.Mechanical.Space space = spatialElement as Autodesk.Revit.DB.Mechanical.Space;
                geomElem = space.ClosedShell;
            }
            else if (isArea)
            {
                Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions();
                geomElem = spatialElementAsArea.get_Geometry(geomOptions);
            }

            IFCAnyHandle spaceHnd = null;
            string spatialElementName = null;
            using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
            {
                extraParams.SetLocalPlacement(localPlacement);
                extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;

                using (IFCTransaction transaction2 = new IFCTransaction(file))
                {
                    IFCAnyHandle repHnd = null;
                    if (!ExporterCacheManager.ExportOptionsCache.Use2DRoomBoundaryForRoomVolumeCreation && geomElem != null)
                    {
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        bodyExporterOptions.TessellationLevel = BodyExporter.GetTessellationLevel();
                        repHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, spatialElement,
                            catId, geomElem, bodyExporterOptions, null, extraParams, false);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                            extraParams.ClearOpenings();
                    }
                    else
                    {
                        IFCAnyHandle shapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, plane, zDir, scaledRoomHeight);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
                            return false;
                        IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document,
                            shapeRep, ElementId.InvalidElementId);

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

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

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

                    extraParams.ScaledHeight = scaledRoomHeight;
                    extraParams.ScaledArea = dArea;

                    spatialElementName = NamingUtil.GetNameOverride(spatialElement, name);
                    string spatialElementDescription = NamingUtil.GetDescriptionOverride(spatialElement, desc);
                    string spatialElementObjectType = NamingUtil.GetObjectTypeOverride(spatialElement, null);
                    string spatialElementLongName = NamingUtil.GetLongNameOverride(spatialElement, longName);
                    
                    double? spaceElevationWithFlooring = null;
                    double elevationWithFlooring = 0.0;
                    if (ParameterUtil.GetDoubleValueFromElement(spatialElement, null, "IfcElevationWithFlooring", out elevationWithFlooring) != null)
                        spaceElevationWithFlooring = UnitUtil.ScaleLength(elevationWithFlooring);
                    spaceHnd = IFCInstanceExporter.CreateSpace(file, GUIDUtil.CreateGUID(spatialElement),
                                                  ExporterCacheManager.OwnerHistoryHandle,
                                                  spatialElementName, spatialElementDescription, spatialElementObjectType,
                                                  extraParams.GetLocalPlacement(), repHnd, spatialElementLongName, Toolkit.IFCElementComposition.Element,
                                                  internalOrExternal, spaceElevationWithFlooring);

                    transaction2.Commit();
                }

                if (spaceHnd != null)
                {
                    productWrapper.AddSpace(spatialElement, spaceHnd, levelInfo, extraParams, true);
                    if (isArea)
                    {
                        Element areaScheme = spatialElementAsArea.AreaScheme;
                        if (areaScheme != null)
                        {
                            ElementId areaSchemeId = areaScheme.Id;
                            HashSet<IFCAnyHandle> areas = null;
                            if (!ExporterCacheManager.AreaSchemeCache.TryGetValue(areaSchemeId, out areas))
                            {
                                areas = new HashSet<IFCAnyHandle>();
                                ExporterCacheManager.AreaSchemeCache[areaSchemeId] = areas;
                            }
                            areas.Add(spaceHnd);
                        }
                    }
                }
            }

            // Save room handle for later use/relationships
            ExporterCacheManager.SpaceInfoCache.SetSpaceHandle(spatialElement, spaceHnd);

            // Find Ceiling as a Space boundary and keep the relationship in a cache for use later
            bool ret = GetCeilingSpaceBoundary(spatialElement, out results);

         if (!MathUtil.IsAlmostZero(dArea) && !(ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE) &&
                !ExporterCacheManager.ExportOptionsCache.ExportAs2x3CoordinationView2 && !ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
            {
                bool isDesignGrossArea = (string.Compare(spatialElementName, "GSA Design Gross Area") > 0);
                PropertyUtil.CreatePreCOBIEGSAQuantities(exporterIFC, spaceHnd, "GSA Space Areas", (isDesignGrossArea ? "GSA Design Gross Area" : "GSA BIM Area"), dArea);
            }

            // Export Classifications for SpatialElement for GSA/COBIE.
         if (ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE)
            {
                ProjectInfo projectInfo = document.ProjectInformation;
                if (projectInfo != null)
                    CreateCOBIESpaceClassifications(exporterIFC, file, spaceHnd, projectInfo, spatialElement);
            }

            return true;
        }
Ejemplo n.º 43
0
        /// <summary>
        /// Main implementation to export walls.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="connectedWalls">Information about walls joined to this wall.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="origWrapper">The ProductWrapper.</param>
        /// <param name="overrideLevelId">The level id.</param>
        /// <param name="range">The range to be exported for the element.</param>
        /// <returns>The exported wall handle.</returns>
        public static IFCAnyHandle ExportWallBase(ExporterIFC exporterIFC, Element element, IList<IList<IFCConnectedWallData>> connectedWalls,
            GeometryElement geometryElement, ProductWrapper origWrapper, ElementId overrideLevelId, IFCRange range)
        {
            // Check cases where we choose not to export early.
            ElementId catId = CategoryUtil.GetSafeCategoryId(element);

            Wall wallElement = element as Wall;
            FamilyInstance famInstWallElem = element as FamilyInstance;
            FaceWall faceWall = element as FaceWall;

            bool exportingWallElement = (wallElement != null);
            bool exportingFamilyInstance = (famInstWallElem != null);
            bool exportingFaceWall = (faceWall != null);

            if (!exportingWallElement && !exportingFamilyInstance && !exportingFaceWall)
                return null;

            if (exportingWallElement && IsWallCompletelyClipped(wallElement, exporterIFC, range))
                return null;

            IFCRange zSpan = null;
            double depth = 0.0;
            bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End));

            bool exportParts = PartExporter.CanExportParts(element);
            if (exportParts && !PartExporter.CanExportElementInPartExport(element, validRange ? overrideLevelId : element.LevelId, validRange))
                return null;

            IList<Solid> solids = new List<Solid>();
            IList<Mesh> meshes = new List<Mesh>();
            bool exportingInplaceOpenings = false;

            if (!exportParts)
            {
                if (exportingWallElement || exportingFaceWall)
                {
                    GetSolidsAndMeshes(geometryElement, range, ref solids, ref meshes);
                    if (solids.Count == 0 && meshes.Count == 0)
                        return null;
                }
                else
                {
                    GeometryElement geomElemToUse = GetGeometryFromInplaceWall(famInstWallElem);
                    if (geomElemToUse != null)
                    {
                        exportingInplaceOpenings = true;
                    }
                    else
                    {
                        exportingInplaceOpenings = false;
                        geomElemToUse = geometryElement;
                    }
                    Transform trf = Transform.Identity;
                    if (geomElemToUse != geometryElement)
                        trf = famInstWallElem.GetTransform();

                    SolidMeshGeometryInfo solidMeshCapsule = GeometryUtil.GetSplitSolidMeshGeometry(geomElemToUse, trf);
                    solids = solidMeshCapsule.GetSolids();
                    meshes = solidMeshCapsule.GetMeshes();
                }
            }

            IFCFile file = exporterIFC.GetFile();
            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (ProductWrapper localWrapper = ProductWrapper.Create(origWrapper))
                {
                    // get bounding box height so that we can subtract out pieces properly.
                    // only for Wall, not FamilyInstance.
                    if (exportingWallElement && geometryElement != null)
                    {
                        // There is a problem in the API where some walls with vertical structures are overreporting their height,
                        // making it appear as if there are clipping problems on export.  We will work around this by getting the
                        // height directly from the solid(s).
                        if (solids.Count > 0 && meshes.Count == 0)
                        {
                            zSpan = GetBoundingBoxOfSolids(solids);
                        }
                        else
                        {
                            BoundingBoxXYZ boundingBox = wallElement.get_BoundingBox(null);
                            if (boundingBox != null)
                                zSpan = GetBoundingBoxZRange(boundingBox);
                        }

                        if (zSpan == null)
                            return null;

                        // if we have a top clipping plane, modify depth accordingly.
                        double bottomHeight = validRange ? Math.Max(zSpan.Start, range.Start) : zSpan.Start;
                        double topHeight = validRange ? Math.Min(zSpan.End, range.End) : zSpan.End;
                        depth = topHeight - bottomHeight;
                        if (MathUtil.IsAlmostZero(depth))
                            return null;
                        depth = UnitUtil.ScaleLength(depth);
                    }
                    else
                    {
                        zSpan = new IFCRange();
                    }

                    Document doc = element.Document;

                    double baseWallElevation = 0.0;
                    ElementId baseLevelId = PlacementSetter.GetBaseLevelIdForElement(element);
                    if (baseLevelId != ElementId.InvalidElementId)
                    {
                        Element baseLevel = doc.GetElement(baseLevelId);
                        if (baseLevel is Level)
                            baseWallElevation = (baseLevel as Level).Elevation;
                    }

                    IFCAnyHandle axisRep = null;
                    IFCAnyHandle bodyRep = null;

                    bool exportingAxis = false;
                    Curve trimmedCurve = null;

                    bool exportedAsWallWithAxis = false;
                    bool exportedBodyDirectly = false;

                    Curve centerCurve = GetWallAxis(wallElement);

                    XYZ localXDir = new XYZ(1, 0, 0);
                    XYZ localYDir = new XYZ(0, 1, 0);
                    XYZ localZDir = new XYZ(0, 0, 1);
                    XYZ localOrig = new XYZ(0, 0, 0);
                    double eps = MathUtil.Eps();

                    if (centerCurve != null)
                    {
                        Curve baseCurve = GetWallAxisAtBaseHeight(wallElement);
                        trimmedCurve = GetWallTrimmedCurve(wallElement, baseCurve);

                        IFCRange curveBounds;
                        XYZ oldOrig;
                        GeometryUtil.GetAxisAndRangeFromCurve(trimmedCurve, out curveBounds, out localXDir, out oldOrig);

                        // Move the curve to the bottom of the geometry or the bottom of the range, which is higher.
                        if (baseCurve != null)
                            localOrig = new XYZ(oldOrig.X, oldOrig.Y, validRange ? Math.Max(range.Start, zSpan.Start) : zSpan.Start);
                        else
                            localOrig = oldOrig;

                        double dist = localOrig[2] - oldOrig[2];
                        if (!MathUtil.IsAlmostZero(dist))
                        {
                            XYZ moveVec = new XYZ(0, 0, dist);
                            trimmedCurve = GeometryUtil.MoveCurve(trimmedCurve, moveVec);
                        }
                        localYDir = localZDir.CrossProduct(localXDir);

                        // ensure that X and Z axes are orthogonal.
                        double xzDot = localZDir.DotProduct(localXDir);
                        if (!MathUtil.IsAlmostZero(xzDot))
                            localXDir = localYDir.CrossProduct(localZDir);
                    }
                    else
                    {
                        BoundingBoxXYZ boundingBox = element.get_BoundingBox(null);
                        if (boundingBox != null)
                        {
                            XYZ bBoxMin = boundingBox.Min;
                            XYZ bBoxMax = boundingBox.Max;
                            if (validRange)
                                localOrig = new XYZ(bBoxMin.X, bBoxMin.Y, range.Start);
                            else
                                localOrig = boundingBox.Min;

                            XYZ localXDirMax = null;
                            Transform bTrf = boundingBox.Transform;
                            XYZ localXDirMax1 = new XYZ(bBoxMax.X, localOrig.Y, localOrig.Z);
                            localXDirMax1 = bTrf.OfPoint(localXDirMax1);
                            XYZ localXDirMax2 = new XYZ(localOrig.X, bBoxMax.Y, localOrig.Z);
                            localXDirMax2 = bTrf.OfPoint(localXDirMax2);
                            if (localXDirMax1.DistanceTo(localOrig) >= localXDirMax2.DistanceTo(localOrig))
                                localXDirMax = localXDirMax1;
                            else
                                localXDirMax = localXDirMax2;
                            localXDir = localXDirMax.Subtract(localOrig);
                            localXDir = localXDir.Normalize();
                            localYDir = localZDir.CrossProduct(localXDir);

                            // ensure that X and Z axes are orthogonal.
                            double xzDot = localZDir.DotProduct(localXDir);
                            if (!MathUtil.IsAlmostZero(xzDot))
                                localXDir = localYDir.CrossProduct(localZDir);
                        }
                    }

                    IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

                    Transform orientationTrf = Transform.Identity;
                    orientationTrf.BasisX = localXDir;
                    orientationTrf.BasisY = localYDir;
                    orientationTrf.BasisZ = localZDir;
                    orientationTrf.Origin = localOrig;

                    double scaledFootprintArea = 0;
                    double scaledLength = 0;

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

                        // The local coordinate system of the wall as defined by IFC for IfcWallStandardCase.
                        Plane wallLCS = new Plane(localXDir, localYDir, localOrig);  // project curve to XY plane.
                        XYZ projDir = XYZ.BasisZ;

                        // two representations: axis, body.         
                        {
                            if (!exportParts && (centerCurve != null) && (GeometryUtil.CurveIsLineOrArc(centerCurve)))
                            {
                                exportingAxis = true;

                                string identifierOpt = "Axis";	// IFC2x2 convention
                                string representationTypeOpt = "Curve2D";  // IFC2x2 convention

                                IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, wallLCS, projDir, false);
                                ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, trimmedCurve, XYZ.Zero, true);
                                IList<IFCAnyHandle> axisItems = info.GetCurves();

                                if (axisItems.Count == 0)
                                {
                                    exportingAxis = false;
                                }
                                else
                                {
                                    HashSet<IFCAnyHandle> axisItemSet = new HashSet<IFCAnyHandle>();
                                    foreach (IFCAnyHandle axisItem in axisItems)
                                        axisItemSet.Add(axisItem);

                                    IFCAnyHandle contextOfItemsAxis = exporterIFC.Get3DContextHandle("Axis");
                                    axisRep = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, contextOfItemsAxis,
                                       identifierOpt, representationTypeOpt, axisItemSet);
                                }
                            }
                        }

                        IList<IFCExtrusionData> cutPairOpenings = new List<IFCExtrusionData>();

                        if (!exportParts && exportingWallElement && exportingAxis && trimmedCurve != null)
                        {
                                    bool isCompletelyClipped;
                            bodyRep = TryToCreateAsExtrusion(exporterIFC, wallElement, connectedWalls, solids, meshes, baseWallElevation,
                                catId, centerCurve, trimmedCurve, wallLCS, depth, zSpan, range, setter,
                                        out cutPairOpenings, out isCompletelyClipped, out scaledFootprintArea, out scaledLength);
                                    if (isCompletelyClipped)
                                        return null;
                                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                                        exportedAsWallWithAxis = true;
                                }

                        using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                        {
                            BodyData bodyData = null;

                            if (!exportedAsWallWithAxis)
                            {
                                extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;   // only allow vertical extrusions!
                                extraParams.AreInnerRegionsOpenings = true;

                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                                
                                // Swept solids are not natively exported as part of CV2.0.  
                                // We have removed the UI toggle for this, so that it is by default false, but keep for possible future use.
                                if (ExporterCacheManager.ExportOptionsCache.ExportAdvancedSweptSolids)
                                    bodyExporterOptions.TryToExportAsSweptSolid = true;

                                ElementId overrideMaterialId = ElementId.InvalidElementId;
                                if (exportingWallElement)
                                    overrideMaterialId = HostObjectExporter.GetFirstLayerMaterialId(wallElement);

                                if (!exportParts)
                                {
                                    if ((solids.Count > 0) || (meshes.Count > 0))
                                    {
                                        bodyRep = BodyExporter.ExportBody(exporterIFC, element, catId, overrideMaterialId,
                                            solids, meshes, bodyExporterOptions, extraParams).RepresentationHnd;
                                    }
                                    else
                                    {
                                        IList<GeometryObject> geomElemList = new List<GeometryObject>();
                                        geomElemList.Add(geometryElement);
                                        bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, overrideMaterialId,
                                            geomElemList, bodyExporterOptions, extraParams);
                                        bodyRep = bodyData.RepresentationHnd;
                                    }

                                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                                    {
                                        extraParams.ClearOpenings();
                                        return null;
                                    }
                                }

                                // We will be able to export as a IfcWallStandardCase as long as we have an axis curve.
                                XYZ extrDirUsed = XYZ.Zero;
                                if (extraParams.HasExtrusionDirection)
                                {
                                    extrDirUsed = extraParams.ExtrusionDirection;
                                    if (MathUtil.IsAlmostEqual(Math.Abs(extrDirUsed[2]), 1.0))
                                    {
                                        if ((solids.Count == 1) && (meshes.Count == 0))
                                            exportedAsWallWithAxis = exportingAxis;
                                        exportedBodyDirectly = true;
                                    }
                                }
                            }

                            IFCAnyHandle prodRep = null;
                            if (!exportParts)
                            {
                                IList<IFCAnyHandle> representations = new List<IFCAnyHandle>();
                                if (exportingAxis)
                                    representations.Add(axisRep);

                                representations.Add(bodyRep);

                                IFCAnyHandle boundingBoxRep = null;
                                if ((solids.Count > 0) || (meshes.Count > 0))
                                    boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, solids, meshes, Transform.Identity);
                                else
                                    boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity);

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

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

                            ElementId matId = ElementId.InvalidElementId;
                            string objectType = NamingUtil.CreateIFCObjectName(exporterIFC, element);
                            IFCAnyHandle wallHnd = null;

                            string elemGUID = null;
                            int subElementIndex = ExporterStateManager.GetCurrentRangeIndex();
                            if (subElementIndex == 0)
                                elemGUID = GUIDUtil.CreateGUID(element);
                            else if (subElementIndex <= ExporterStateManager.RangeIndexSetter.GetMaxStableGUIDs())
                                elemGUID = GUIDUtil.CreateSubElementGUID(element, subElementIndex + (int)IFCGenericSubElements.SplitInstanceStart - 1);
                            else
                                elemGUID = GUIDUtil.CreateGUID();
                            
                            string elemName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                            string elemDesc = NamingUtil.GetDescriptionOverride(element, null);
                            string elemObjectType = NamingUtil.GetObjectTypeOverride(element, objectType);
                            string elemTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

                            string ifcType = IFCValidateEntry.GetValidIFCType(element, null);

                            // For Foundation and Retaining walls, allow exporting as IfcFooting instead.
                            bool exportAsFooting = false;
                            if (exportingWallElement)
                            {
                                WallType wallType = wallElement.WallType;

                                if (wallType != null)
                                {
                                    int wallFunction;
                                    if (ParameterUtil.GetIntValueFromElement(wallType, BuiltInParameter.FUNCTION_PARAM, out wallFunction) != null)
                                    {
                                        if (wallFunction == (int)WallFunction.Retaining || wallFunction == (int)WallFunction.Foundation)
                                        {
                                            // In this case, allow potential to export foundation and retaining walls as footing.
                                            string enumTypeValue = null;
                                            IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, wallElement, out enumTypeValue);
                                            if (exportType == IFCExportType.IfcFooting)
                                                exportAsFooting = true;
                                        }
                                    }
                                }
                            }

                            if (exportedAsWallWithAxis)
                            {
                                if (exportAsFooting)
                                {
                                    wallHnd = IFCInstanceExporter.CreateFooting(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                        localPlacement, exportParts ? null : prodRep, elemTag, ifcType);
                                }
                                else
                                {
                                    bool exportAsWall = exportParts;
                                    if (!exportAsWall)
                                    {
                                        // (For Reference View export) If the representation returned earlier is of type Tessellation, create IfcWall instead.
                                        foreach (IFCAnyHandle pRep in IFCAnyHandleUtil.GetRepresentations(prodRep))
                                        {
                                            if (String.Compare(IFCAnyHandleUtil.GetRepresentationType(pRep), "Tessellation") == 0)
                                            {
                                                exportAsWall = true;
                                                break;
                                            }
                                        }
                                    }

                                    if (exportAsWall)
                                    {
                                        wallHnd = IFCInstanceExporter.CreateWall(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                                localPlacement, null, elemTag, ifcType);
                                    }
                                    else
                                    {
                                        wallHnd = IFCInstanceExporter.CreateWallStandardCase(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                            localPlacement, prodRep, elemTag, ifcType);
                                    }
                                }

                                if (exportParts)
                                    PartExporter.ExportHostPart(exporterIFC, element, wallHnd, localWrapper, setter, localPlacement, overrideLevelId);

                                localWrapper.AddElement(element, wallHnd, setter, extraParams, true);

                                if (!exportParts)
                                {
                                    OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, cutPairOpenings, null,
                                        exporterIFC, localPlacement, setter, localWrapper);
                                    if (exportedBodyDirectly)
                                    {
                                        Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity;
                                        OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, extraParams, offsetTransform,
                                            exporterIFC, localPlacement, setter, localWrapper);
                                    }
                                    else
                                    {
                                        double scaledWidth = UnitUtil.ScaleLength(wallElement.Width);
                                        OpeningUtil.AddOpeningsToElement(exporterIFC, wallHnd, wallElement, null, scaledWidth, range, setter, localPlacement, localWrapper);
                                    }
                                }

                                // export Base Quantities
                                if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
                                {
                                    scaledFootprintArea = MathUtil.AreaIsAlmostZero(scaledFootprintArea) ? extraParams.ScaledArea : scaledFootprintArea;
                                    scaledLength = MathUtil.IsAlmostZero(scaledLength) ? extraParams.ScaledLength : scaledLength;
                                    PropertyUtil.CreateWallBaseQuantities(exporterIFC, wallElement, solids, meshes, wallHnd, scaledLength, depth, scaledFootprintArea);
                                }
                            }
                            else
                            {
                                if (exportAsFooting)
                                {
                                    wallHnd = IFCInstanceExporter.CreateFooting(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                        localPlacement, exportParts ? null : prodRep, elemTag, ifcType);
                                }
                                else
                                {
                                    wallHnd = IFCInstanceExporter.CreateWall(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                        localPlacement, exportParts ? null : prodRep, elemTag, ifcType);
                                }

                                if (exportParts)
                                    PartExporter.ExportHostPart(exporterIFC, element, wallHnd, localWrapper, setter, localPlacement, overrideLevelId);

                                localWrapper.AddElement(element, wallHnd, setter, extraParams, true);

                                if (!exportParts)
                                {
                                    // Only export one material for 2x2; for future versions, export the whole list.
                                    if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2 || exportingFamilyInstance)
                                    {
                                        matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(solids, meshes, element);
                                        if (matId != ElementId.InvalidElementId)
                                            CategoryUtil.CreateMaterialAssociation(exporterIFC, wallHnd, matId);
                                    }

                                    if (exportingInplaceOpenings)
                                    {
                                        OpeningUtil.AddOpeningsToElement(exporterIFC, wallHnd, famInstWallElem, null, 0.0, range, setter, localPlacement, localWrapper);
                                    }

                                    if (exportedBodyDirectly)
                                    {
                                        Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity;
                                        OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, extraParams, offsetTransform,
                                            exporterIFC, localPlacement, setter, localWrapper);
                                    }
                                }
                            }

                            ElementId wallLevelId = (validRange) ? setter.LevelId : ElementId.InvalidElementId;

                            if ((exportingWallElement || exportingFaceWall) && !exportParts)
                            {
                                HostObject hostObject = null;
                                if (exportingWallElement)
                                    hostObject = wallElement;
                                else
                                    hostObject = faceWall;
                                if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x2 || exportedAsWallWithAxis)
                                    HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, localWrapper.GetAnElement(),
                                        geometryElement, localWrapper, wallLevelId, Toolkit.IFCLayerSetDirection.Axis2, !exportedAsWallWithAxis);
                            }

                            ExportWallType(exporterIFC, localWrapper, wallHnd, element, matId, exportedAsWallWithAxis, exportAsFooting);

                            SpaceBoundingElementUtil.RegisterSpaceBoundingElementHandle(exporterIFC, wallHnd, element.Id, wallLevelId);

                            tr.Commit();
                            return wallHnd;
                        }
                    }
                }
            }
        }
Ejemplo n.º 44
0
        /// <summary>
        /// Export one IFCGrid in one level.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="levelId">The level ID.</param>
        /// <param name="sameDirectionAxesU">The U axes of grids.</param>
        /// <param name="sameDirectionAxesV">The V axes of grids.</param>
        /// <param name="sameDirectionAxesW">The W axes of grids.</param>
        public static void ExportGrid(ExporterIFC exporterIFC, ElementId levelId, List<Grid> sameDirectionAxesU, List<Grid> sameDirectionAxesV, List<Grid> sameDirectionAxesW)
        {

            List<IFCAnyHandle> axesU = null;
            List<IFCAnyHandle> axesV = null;
            List<IFCAnyHandle> axesW = null;
            List<IFCAnyHandle> representations = new List<IFCAnyHandle>();

            using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, true))
            {
                IFCFile ifcFile = exporterIFC.GetFile();
                using (IFCTransaction transaction = new IFCTransaction(ifcFile))
                {
                    GridRepresentationData gridRepresentationData = new GridRepresentationData();

                    axesU = CreateIFCGridAxisAndRepresentations(exporterIFC, productWrapper, sameDirectionAxesU, representations, gridRepresentationData);
                    axesV = CreateIFCGridAxisAndRepresentations(exporterIFC, productWrapper, sameDirectionAxesV, representations, gridRepresentationData);
                    if (sameDirectionAxesW != null)
                        axesW = CreateIFCGridAxisAndRepresentations(exporterIFC, productWrapper, sameDirectionAxesW, representations, gridRepresentationData);

                    IFCAnyHandle contextOfItemsFootPrint = exporterIFC.Get3DContextHandle("FootPrint");
                    string identifierOpt = "FootPrint";
                    string representationTypeOpt = "GeometricCurveSet";

                    int numGridsToExport = gridRepresentationData.m_Grids.Count;
                    if (numGridsToExport == 0)
                        return;

                    bool useIFCCADLayer = !string.IsNullOrWhiteSpace(gridRepresentationData.m_IFCCADLayer);
                    
                    IFCAnyHandle shapeRepresentation = null;

                    HashSet<IFCAnyHandle> allCurves = new HashSet<IFCAnyHandle>();
                    for (int ii = 0; ii < numGridsToExport; ii++)
                        allCurves.UnionWith(gridRepresentationData.m_curveSets[ii]);

                    if (useIFCCADLayer)
                    {
                        shapeRepresentation = RepresentationUtil.CreateShapeRepresentation(exporterIFC, contextOfItemsFootPrint,
                            identifierOpt, representationTypeOpt, allCurves, gridRepresentationData.m_IFCCADLayer);
                    }
                    else
                    {
                        ElementId catId = CategoryUtil.GetSafeCategoryId(gridRepresentationData.m_Grids[0]);
                        shapeRepresentation = RepresentationUtil.CreateShapeRepresentation(exporterIFC, gridRepresentationData.m_Grids[0], catId,
                                contextOfItemsFootPrint, identifierOpt, representationTypeOpt, allCurves);
                    }
                    representations.Add(shapeRepresentation);

                    IFCAnyHandle productRep = IFCInstanceExporter.CreateProductDefinitionShape(ifcFile, null, null, representations);

                    IFCLevelInfo levelInfo = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, levelId);

                    string gridGUID = GUIDUtil.CreateGUID();
                    // Get the first grid's override name, if cannot find it, use null.
                    string gridName = GetGridName(sameDirectionAxesU, sameDirectionAxesV, sameDirectionAxesW);
                    IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                    IFCAnyHandle gridLevelHandle = levelInfo.GetBuildingStorey();
                    IFCAnyHandle levelObjectPlacement = IFCAnyHandleUtil.GetInstanceAttribute(gridLevelHandle, "ObjectPlacement");
                    double elev = levelInfo.Elevation;
                    double scaleFactor = exporterIFC.LinearScale;
                    double elevation = elev * scaleFactor;
                    XYZ orig = new XYZ(0.0, 0.0, elevation);
                    IFCAnyHandle copyLevelPlacement = ExporterUtil.CopyLocalPlacement(ifcFile, levelObjectPlacement);
                    IFCAnyHandle ifcGrid = IFCInstanceExporter.CreateGrid(ifcFile, gridGUID, ownerHistory, gridName, null, null, copyLevelPlacement, productRep, axesU, axesV, axesW);
                    productWrapper.AddElement(null, ifcGrid, levelInfo, null, true);

                    transaction.Commit();
                }
            }
        }
Ejemplo n.º 45
0
        /// <summary>
        /// Export one IFCGrid in one level.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="levelId">The level ID.</param>
        /// <param name="sameDirectionAxesU">The U axes of grids.</param>
        /// <param name="sameDirectionAxesV">The V axes of grids.</param>
        /// <param name="sameDirectionAxesW">The W axes of grids.</param>
        public static void ExportGrid(ExporterIFC exporterIFC, ElementId levelId, List <Grid> sameDirectionAxesU, List <Grid> sameDirectionAxesV, List <Grid> sameDirectionAxesW)
        {
            List <IFCAnyHandle> axesU           = null;
            List <IFCAnyHandle> axesV           = null;
            List <IFCAnyHandle> axesW           = null;
            List <IFCAnyHandle> representations = new List <IFCAnyHandle>();

            using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, true))
            {
                IFCFile ifcFile = exporterIFC.GetFile();
                using (IFCTransaction transaction = new IFCTransaction(ifcFile))
                {
                    GridRepresentationData gridRepresentationData = new GridRepresentationData();

                    axesU = CreateIFCGridAxisAndRepresentations(exporterIFC, productWrapper, sameDirectionAxesU, representations, gridRepresentationData);
                    axesV = CreateIFCGridAxisAndRepresentations(exporterIFC, productWrapper, sameDirectionAxesV, representations, gridRepresentationData);
                    if (sameDirectionAxesW != null)
                    {
                        axesW = CreateIFCGridAxisAndRepresentations(exporterIFC, productWrapper, sameDirectionAxesW, representations, gridRepresentationData);
                    }

                    IFCAnyHandle contextOfItemsFootPrint = exporterIFC.Get3DContextHandle("FootPrint");
                    string       identifierOpt           = "FootPrint";
                    string       representationTypeOpt   = "GeometricCurveSet";

                    int numGridsToExport = gridRepresentationData.m_Grids.Count;
                    if (numGridsToExport == 0)
                    {
                        return;
                    }

                    bool useIFCCADLayer = !string.IsNullOrWhiteSpace(gridRepresentationData.m_IFCCADLayer);

                    IFCAnyHandle shapeRepresentation = null;

                    HashSet <IFCAnyHandle> allCurves = new HashSet <IFCAnyHandle>();
                    for (int ii = 0; ii < numGridsToExport; ii++)
                    {
                        allCurves.UnionWith(gridRepresentationData.m_curveSets[ii]);
                    }

                    if (useIFCCADLayer)
                    {
                        shapeRepresentation = RepresentationUtil.CreateShapeRepresentation(exporterIFC, contextOfItemsFootPrint,
                                                                                           identifierOpt, representationTypeOpt, allCurves, gridRepresentationData.m_IFCCADLayer);
                    }
                    else
                    {
                        ElementId catId = CategoryUtil.GetSafeCategoryId(gridRepresentationData.m_Grids[0]);
                        shapeRepresentation = RepresentationUtil.CreateShapeRepresentation(exporterIFC, gridRepresentationData.m_Grids[0], catId,
                                                                                           contextOfItemsFootPrint, identifierOpt, representationTypeOpt, allCurves);
                    }
                    representations.Add(shapeRepresentation);

                    IFCAnyHandle productRep = IFCInstanceExporter.CreateProductDefinitionShape(ifcFile, null, null, representations);

                    // We will associate the grid with its level, unless there are no levels in the file, in which case we'll associate it with the building.
                    IFCLevelInfo levelInfo    = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, levelId);
                    bool         useLevelInfo = (levelInfo != null);

                    string gridGUID = GUIDUtil.CreateGUID();

                    // Get the first grid's override name, if cannot find it, use null.
                    string       gridName             = GetGridName(sameDirectionAxesU, sameDirectionAxesV, sameDirectionAxesW);
                    IFCAnyHandle ownerHistory         = ExporterCacheManager.OwnerHistoryHandle;
                    IFCAnyHandle gridLevelHandle      = useLevelInfo ? levelInfo.GetBuildingStorey() : ExporterCacheManager.BuildingHandle;
                    IFCAnyHandle levelObjectPlacement = IFCAnyHandleUtil.GetObjectPlacement(gridLevelHandle);
                    double       elev               = useLevelInfo ? levelInfo.Elevation : 0.0;
                    double       elevation          = UnitUtil.ScaleLength(elev);
                    XYZ          orig               = new XYZ(0.0, 0.0, elevation);
                    IFCAnyHandle copyLevelPlacement = ExporterUtil.CopyLocalPlacement(ifcFile, levelObjectPlacement);
                    IFCAnyHandle ifcGrid            = IFCInstanceExporter.CreateGrid(ifcFile, gridGUID, ownerHistory, gridName, null, null, copyLevelPlacement, productRep, axesU, axesV, axesW);

                    productWrapper.AddElement(null, ifcGrid, levelInfo, null, true);

                    transaction.Commit();
                }
            }
        }
Ejemplo n.º 46
0
        /// <summary>
        /// Create the handle corresponding to the "Axis" IfcRepresentation for a beam, if possible.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC class.</param>
        /// <param name="element">The beam element.</param>
        /// <param name="catId">The beam category id.</param>
        /// <param name="axisInfo">The optional beam axis information.</param>
        /// <param name="offsetTransform">The optional offset transform applied to the "Body" representation.</param>
        /// <returns>The handle, or null if not created.</returns>
        private static IFCAnyHandle CreateBeamAxis(ExporterIFC exporterIFC, Element element, ElementId catId, BeamAxisInfo axisInfo, Transform offsetTransform)
        {
            if (axisInfo == null)
            {
                return(null);
            }

            Curve curve   = axisInfo.Axis;
            XYZ   projDir = axisInfo.AxisNormal;
            Plane plane   = axisInfo.LCSAsPlane;

            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.
                string       representationTypeOpt = "Curve2D"; // This is by IFC2x2+ convention.
                IFCAnyHandle axisRep = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, exporterIFC.Get3DContextHandle(identifierOpt),
                                                                                    identifierOpt, representationTypeOpt, axis_items);
                return(axisRep);
            }

            return(null);
        }
Ejemplo n.º 47
0
        /// <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();
            }
        }
Ejemplo n.º 48
0
        /// <summary>
        /// Exports a Rebar to IFC ReinforcingBar.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="rebarItem">The rebar to be exported.  This might be an element or a sub-element.</param>
        /// <param name="rebarElement">The element that contains the rebar to be exported.  This may be the same as rebarItem.</param>
        /// <param name="itemIndex">If greater than 0, the index of the first rebar in the rebarItem in the rebarElement, used for naming and GUID creation.</param>
        /// <param name="productWrapper">The ProductWrapper object.</param>
        /// <returns>The set of handles created, to add to the ProductWrapper in the calling function.</returns>
        private static ISet <DelayedProductWrapper> ExportRebar(ExporterIFC exporterIFC, object rebarItem, Element rebarElement, int itemIndex, 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.IfcReinforcingBar;
            if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
            {
                return(null);
            }

            IFCFile file = exporterIFC.GetFile();
            HashSet <DelayedProductWrapper> createdRebars = new HashSet <DelayedProductWrapper>();

            int rebarQuantity = GetRebarQuantity(rebarItem);

            if (rebarQuantity == 0)
            {
                return(null);
            }

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, rebarElement))
                {
                    bool         cannotExportRebar = false;
                    IFCAnyHandle rebarHandle       = ExportRebarAsProxyElementInView(exporterIFC, rebarElement, productWrapper, out cannotExportRebar);
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(rebarHandle) || cannotExportRebar)
                    {
                        if (!cannotExportRebar)
                        {
                            transaction.Commit();
                        }
                        return(null); // Rebar doesn't create a group.
                    }

                    IFCAnyHandle prodRep = null;

                    double totalBarLengthUnscale = GetRebarTotalLength(rebarItem);
                    double volumeUnscale         = GetRebarVolume(rebarItem);
                    double totalBarLength        = UnitUtil.ScaleLength(totalBarLengthUnscale);

                    if (MathUtil.IsAlmostZero(totalBarLength))
                    {
                        return(null);
                    }

                    ElementId materialId = ElementId.InvalidElementId;
                    ParameterUtil.GetElementIdValueFromElementOrSymbol(rebarElement, BuiltInParameter.MATERIAL_ID_PARAM, out materialId);

                    double diameter = GetBarDiameter(rebarItem);
                    double radius   = diameter / 2.0;
                    double longitudinalBarNominalDiameter  = diameter;
                    double longitudinalBarCrossSectionArea = UnitUtil.ScaleArea(volumeUnscale / totalBarLengthUnscale);

                    int numberOfBarPositions = GetNumberOfBarPositions(rebarItem);

                    string steelGrade = NamingUtil.GetOverrideStringValue(rebarElement, "SteelGrade", null);

                    // Allow use of IFC2x3 or IFC4 naming.
                    string predefinedType = NamingUtil.GetOverrideStringValue(rebarElement, "BarRole", null);
                    if (string.IsNullOrWhiteSpace(predefinedType))
                    {
                        predefinedType = NamingUtil.GetOverrideStringValue(rebarElement, "PredefinedType", null);
                    }
                    IFCReinforcingBarRole role = GetReinforcingBarRole(predefinedType);

                    string origRebarName = NamingUtil.GetNameOverride(rebarElement, NamingUtil.GetIFCName(rebarElement));

                    const int maxBarGUIDS = IFCReinforcingBarSubElements.BarEnd - IFCReinforcingBarSubElements.BarStart + 1;
                    ElementId categoryId  = CategoryUtil.GetSafeCategoryId(rebarElement);

                    IFCAnyHandle originalPlacement = setter.LocalPlacement;

                    // Potential issue : totalBarLength has a rounded value but individual lengths (from centerlines) do not have rounded values.
                    // Also dividing a rounded totalBarLength does not result in barLength rounded by the same round value.
                    double        barLength  = totalBarLength / rebarQuantity;
                    IList <Curve> baseCurves = GetRebarCenterlineCurves(rebarItem, true, false, false);

                    ElementId    barLengthParamId   = new ElementId(BuiltInParameter.REBAR_ELEM_LENGTH);
                    ParameterSet rebarElementParams = rebarElement.Parameters;
                    for (int ii = 0; ii < numberOfBarPositions; ii++)
                    {
                        if (!DoesBarExistAtPosition(rebarItem, ii))
                        {
                            continue;
                        }

                        Rebar rebar = rebarElement as Rebar;
                        if ((rebar != null) && (rebar.DistributionType == DistributionType.VaryingLength || rebar.IsRebarFreeForm()))
                        {
                            baseCurves = GetRebarCenterlineCurves(rebar, true, false, false, MultiplanarOption.IncludeOnlyPlanarCurves, ii);
                            DoubleParameterValue barLengthParamVal = rebar.GetParameterValueAtIndex(barLengthParamId, ii) as DoubleParameterValue;
                            if (barLengthParamVal != null)
                            {
                                barLength = barLengthParamVal.Value;
                            }
                        }


                        string rebarNameFormated = origRebarName;

                        int indexForNamingAndGUID = (itemIndex > 0) ? ii + itemIndex : ii + 1;

                        string rebarName = NamingUtil.GetNameOverride(rebarElement, rebarNameFormated + ": " + indexForNamingAndGUID);

                        Transform barTrf = GetBarPositionTransform(rebarItem, ii);

                        IList <Curve> curves   = new List <Curve>();
                        double        endParam = 0.0;
                        foreach (Curve baseCurve in baseCurves)
                        {
                            if (baseCurve is Arc || baseCurve is Ellipse)
                            {
                                if (baseCurve.IsBound)
                                {
                                    endParam += UnitUtil.ScaleAngle(baseCurve.GetEndParameter(1) - baseCurve.GetEndParameter(0));
                                }
                                else
                                {
                                    endParam += UnitUtil.ScaleAngle(2 * Math.PI);
                                }
                            }
                            else
                            {
                                endParam += 1.0;
                            }
                            curves.Add(baseCurve.CreateTransformed(barTrf));
                        }

                        IFCAnyHandle           compositeCurve = GeometryUtil.CreateCompositeCurve(exporterIFC, curves);
                        IFCAnyHandle           sweptDiskSolid = IFCInstanceExporter.CreateSweptDiskSolid(file, compositeCurve, radius, null, 0, endParam);
                        HashSet <IFCAnyHandle> bodyItems      = new HashSet <IFCAnyHandle>();
                        bodyItems.Add(sweptDiskSolid);

                        IFCAnyHandle         shapeRep  = RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC, rebarElement, categoryId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null);
                        IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>();
                        shapeReps.Add(shapeRep);
                        prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);

                        IFCAnyHandle copyLevelPlacement = (ii == 0) ? originalPlacement : ExporterUtil.CopyLocalPlacement(file, originalPlacement);

                        string rebarGUID = (indexForNamingAndGUID < maxBarGUIDS) ?
                                           GUIDUtil.CreateSubElementGUID(rebarElement, indexForNamingAndGUID + (int)IFCReinforcingBarSubElements.BarStart - 1) :
                                           GUIDUtil.CreateGUID();
                        IFCAnyHandle elemHnd = IFCInstanceExporter.CreateReinforcingBar(exporterIFC, rebarElement, rebarGUID, ExporterCacheManager.OwnerHistoryHandle,
                                                                                        copyLevelPlacement, prodRep, steelGrade, longitudinalBarNominalDiameter, longitudinalBarCrossSectionArea, barLength, role, null);
                        IFCAnyHandleUtil.OverrideNameAttribute(elemHnd, rebarName);

                        // We will not add the element ot the productWrapper here, but instead in the function that calls
                        // ExportRebar.  The reason for this is that we don't currently know if the handles such be associated
                        // to the level or not, depending on whether they will or won't be grouped.
                        createdRebars.Add(new DelayedProductWrapper(rebarElement, elemHnd, setter.LevelInfo));

                        CacheSubelementParameterValues(rebarElement, rebarElementParams, ii, elemHnd);

                        ExporterCacheManager.HandleToElementCache.Register(elemHnd, rebarElement.Id);
                        CategoryUtil.CreateMaterialAssociation(exporterIFC, elemHnd, materialId);
                    }
                }
                transaction.Commit();
            }
            return(createdRebars);
        }
Ejemplo n.º 49
0
        /// <summary>
        /// Exports an element as an IfcReinforcingMesh.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if exported successfully, false otherwise.</returns>
        public static bool ExportFabricSheet(ExporterIFC exporterIFC, FabricSheet sheet,
            GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            if (sheet == null || geometryElement == null)
                return false;

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

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (IFCPlacementSetter placementSetter = IFCPlacementSetter.Create(exporterIFC, sheet, null, null, ExporterUtil.GetBaseLevelIdForElement(sheet)))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(placementSetter.GetPlacement());

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(sheet);

                        ElementId materialId = ElementId.InvalidElementId;
                        ParameterUtil.GetElementIdValueFromElementOrSymbol(sheet, BuiltInParameter.MATERIAL_ID_PARAM, out materialId);
                        double scale = exporterIFC.LinearScale;

                        string guid = GUIDUtil.CreateGUID(sheet);
                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                        string revitObjectType = exporterIFC.GetFamilyName();
                        string name = NamingUtil.GetNameOverride(sheet, revitObjectType);
                        string description = NamingUtil.GetDescriptionOverride(sheet, null);
                        string objectType = NamingUtil.GetObjectTypeOverride(sheet, revitObjectType);

                        IFCAnyHandle localPlacement = ecData.GetLocalPlacement();
                        string elementTag = NamingUtil.CreateIFCElementId(sheet);

                        string steelGrade = NamingUtil.GetOverrideStringValue(sheet, "SteelGrade", null);
                        double? meshLength = sheet.CutOverallLength;
                        double? meshWidth = sheet.CutOverallWidth;

                        Element fabricSheetTypeElem = doc.GetElement(sheet.GetTypeId());
                        FabricSheetType fabricSheetType = (fabricSheetTypeElem == null) ? null : (fabricSheetTypeElem as FabricSheetType);

                        double longitudinalBarNominalDiameter = 0.0;
                        double transverseBarNominalDiameter = 0.0;
                        double longitudinalBarCrossSectionArea = 0.0;
                        double transverseBarCrossSectionArea = 0.0;
                        double longitudinalBarSpacing = 0.0;
                        double transverseBarSpacing = 0.0;
                        if (fabricSheetType != null)
                        {
                            Element majorFabricWireTypeElem = doc.GetElement(fabricSheetType.MajorDirectionWireType);
                            FabricWireType majorFabricWireType = (majorFabricWireTypeElem == null) ? null : (majorFabricWireTypeElem as FabricWireType);
                            if (majorFabricWireType != null)
                            {
                                longitudinalBarNominalDiameter = majorFabricWireType.WireDiameter * scale;
                                double localRadius = longitudinalBarNominalDiameter / 2.0;
                                longitudinalBarCrossSectionArea = localRadius * localRadius * Math.PI;
                            }

                            Element minorFabricWireTypeElem = doc.GetElement(fabricSheetType.MinorDirectionWireType);
                            FabricWireType minorFabricWireType = (minorFabricWireTypeElem == null) ? null : (minorFabricWireTypeElem as FabricWireType);
                            if (minorFabricWireType != null)
                            {
                                transverseBarNominalDiameter = minorFabricWireType.WireDiameter * scale;
                                double localRadius = transverseBarNominalDiameter / 2.0;
                                transverseBarCrossSectionArea = localRadius * localRadius * Math.PI;
                            }

                            longitudinalBarSpacing = fabricSheetType.MajorSpacing * scale;
                            transverseBarSpacing = fabricSheetType.MinorSpacing * scale;
                        }

                        IList<IFCAnyHandle> bodyItems = new List<IFCAnyHandle>();
                        
                        IList<Curve> wireCenterlines = sheet.GetWireCenterlines(WireDistributionDirection.Major);
                        foreach (Curve wireCenterline in wireCenterlines)
                        {
                            IFCAnyHandle bodyItem = CreateSweptDiskSolid(exporterIFC, file, wireCenterline, longitudinalBarNominalDiameter);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItem))
                                bodyItems.Add(bodyItem);
                        }

                        wireCenterlines = sheet.GetWireCenterlines(WireDistributionDirection.Minor);
                        foreach (Curve wireCenterline in wireCenterlines)
                        {
                            IFCAnyHandle bodyItem = CreateSweptDiskSolid(exporterIFC, file, wireCenterline, transverseBarNominalDiameter);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItem))
                                bodyItems.Add(bodyItem);
                        }

                        IFCAnyHandle shapeRep = (bodyItems.Count > 0) ?
                            RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC, sheet, categoryId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null) :
                            null;
                        IList<IFCAnyHandle> shapeReps = null;
                        if (shapeRep != null)
                        {
                            shapeReps = new List<IFCAnyHandle>();
                            shapeReps.Add(shapeRep);
                        }
                        IFCAnyHandle prodRep = (shapeReps != null) ? IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps) : null;

                        IFCAnyHandle fabricSheet = IFCInstanceExporter.CreateReinforcingMesh(file, guid,
                            ownerHistory, name, description, objectType, localPlacement, prodRep, elementTag,
                            steelGrade, meshLength, meshWidth, longitudinalBarNominalDiameter, transverseBarNominalDiameter,
                            longitudinalBarCrossSectionArea, transverseBarCrossSectionArea,
                            longitudinalBarSpacing, transverseBarSpacing);

                        ElementId fabricAreaId = sheet.FabricAreaOwnerId;
                        if (fabricAreaId != ElementId.InvalidElementId)
                        {
                            HashSet<IFCAnyHandle> fabricSheets = null;
                            if (!ExporterCacheManager.FabricAreaHandleCache.TryGetValue(fabricAreaId, out fabricSheets))
                            {
                                fabricSheets = new HashSet<IFCAnyHandle>();
                                ExporterCacheManager.FabricAreaHandleCache[fabricAreaId] = fabricSheets;
                            }
                            fabricSheets.Add(fabricSheet);
                        }

                        productWrapper.AddElement(sheet, fabricSheet, placementSetter.GetLevelInfo(), ecData, true);

                        CategoryUtil.CreateMaterialAssociation(exporterIFC, fabricSheet, materialId);
                    }
                }
                tr.Commit();
                return true;
            }
        }
Ejemplo n.º 50
0
        private static HandleAndAnalyzer CreateExtrusionWithClippingBase(ExporterIFC exporterIFC, Element element, 
            ElementId catId, IList<Solid> solids, Plane plane, XYZ projDir, IFCRange range, out bool completelyClipped, out HashSet<ElementId> materialIds)
        {
            IFCFile file = exporterIFC.GetFile();
            using (IFCTransaction tr = new IFCTransaction(file))
            {
                completelyClipped = false;
                materialIds = new HashSet<ElementId>();
                HandleAndAnalyzer retVal = new HandleAndAnalyzer();
                HashSet<IFCAnyHandle> extrusionBodyItems = new HashSet<IFCAnyHandle>();
                HashSet<IFCAnyHandle> extrusionBooleanBodyItems = new HashSet<IFCAnyHandle>();
                HashSet<IFCAnyHandle> extrusionClippingBodyItems = new HashSet<IFCAnyHandle>();
                foreach (Solid solid in solids)
                {
                    bool hasClippingResult = false;
                    bool hasBooleanResult = false;
                    ElementId materialId = ElementId.InvalidElementId;
                    retVal = CreateExtrsionWithClippingAndOpening(exporterIFC, element, catId, solid, plane, projDir, range,
                        out completelyClipped, out hasClippingResult, out hasBooleanResult, out materialId);

                    if (retVal != null && retVal.Handle != null)
                    {
                        materialIds.Add(materialId);
                        IFCAnyHandle repHandle = retVal.Handle;
                        if (hasBooleanResult) // if both have boolean and clipping result, use boolean one.
                            extrusionBooleanBodyItems.Add(repHandle);
                        else if (hasClippingResult)
                            extrusionClippingBodyItems.Add(repHandle);
                        else
                            extrusionBodyItems.Add(repHandle);

                    }
                    else
                    {
                        tr.RollBack();
                        return retVal;
                    }
                }

                IFCAnyHandle contextOfItemsBody = exporterIFC.Get3DContextHandle("Body");

                if (extrusionBodyItems.Count > 0 && (extrusionClippingBodyItems.Count == 0 && extrusionBooleanBodyItems.Count == 0))
                {
                    retVal.Handle = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, contextOfItemsBody,
                        extrusionBodyItems, null);
                }
                else if (extrusionClippingBodyItems.Count > 0 && (extrusionBodyItems.Count == 0 && extrusionBooleanBodyItems.Count == 0))
                {
                    retVal.Handle = RepresentationUtil.CreateClippingRep(exporterIFC, element, catId, contextOfItemsBody,
                        extrusionClippingBodyItems);
                }
                else if (extrusionBooleanBodyItems.Count > 0 && (extrusionBodyItems.Count == 0 && extrusionClippingBodyItems.Count == 0))
                {
                    retVal.Handle = RepresentationUtil.CreateCSGRep(exporterIFC, element, catId, contextOfItemsBody,
                        extrusionBooleanBodyItems);
                }
                else
                {
                    IFCAnyHandle finalBodyItemHnd = null;

                    ICollection<IFCAnyHandle> booleanBodyItems = extrusionClippingBodyItems.Union<IFCAnyHandle>(extrusionBooleanBodyItems).ToList();

                    finalBodyItemHnd = booleanBodyItems.ElementAt(0);
                    booleanBodyItems.Remove(finalBodyItemHnd);

                    // union non-boolean result first with a boolean result
                    foreach (IFCAnyHandle bodyRep in extrusionBodyItems)
                    {
                        finalBodyItemHnd = IFCInstanceExporter.CreateBooleanResult(exporterIFC.GetFile(), IFCBooleanOperator.Union,
                             finalBodyItemHnd, bodyRep);
                    }

                    foreach (IFCAnyHandle bodyRep in booleanBodyItems)
                    {
                        finalBodyItemHnd = IFCInstanceExporter.CreateBooleanResult(exporterIFC.GetFile(), IFCBooleanOperator.Union,
                             finalBodyItemHnd, bodyRep);
                    }

                    extrusionBodyItems.Clear();
                    extrusionBodyItems.Add(finalBodyItemHnd);
                    retVal.Handle = RepresentationUtil.CreateCSGRep(exporterIFC, element, catId, contextOfItemsBody,
                        extrusionBodyItems);
                }
                tr.Commit();
                return retVal;
            }
        }
Ejemplo n.º 51
0
        private static IFCAnyHandle FallbackTryToCreateAsExtrusion(ExporterIFC exporterIFC, Wall wallElement, SolidMeshGeometryInfo smCapsule,
            ElementId catId, Curve curve, Plane plane, double depth, IFCRange zSpan, IFCRange range, IFCPlacementSetter setter, 
            out IList<IFCExtrusionData> cutPairOpenings, out bool isCompletelyClipped)
        {
            cutPairOpenings = new List<IFCExtrusionData>();

            IFCAnyHandle bodyRep;
            isCompletelyClipped = false;

            XYZ localOrig = plane.Origin;

            bool hasExtrusion = HasElevationProfile(wallElement);
            if (hasExtrusion)
            {
                IList<CurveLoop> loops = GetElevationProfile(wallElement);
                if (loops.Count == 0)
                    hasExtrusion = false;
                else
                {
                    IList<IList<CurveLoop>> sortedLoops = ExporterIFCUtils.SortCurveLoops(loops);
                    if (sortedLoops.Count == 0)
                        return null;

                    // Current limitation: can't handle wall split into multiple disjointed pieces.
                    int numSortedLoops = sortedLoops.Count;
                    if (numSortedLoops > 1)
                        return null;

                    bool ignoreExtrusion = true;
                    bool cantHandle = false;
                    bool hasGeometry = false;
                    for (int ii = 0; (ii < numSortedLoops) && !cantHandle; ii++)
                    {
                        int sortedLoopSize = sortedLoops[ii].Count;
                        if (sortedLoopSize == 0)
                            continue;
                        if (!ExporterIFCUtils.IsCurveLoopConvexWithOpenings(sortedLoops[ii][0], wallElement, range, out ignoreExtrusion))
                        {
                            if (ignoreExtrusion)
                            {
                                // we need more information.  Is there something to export?  If so, we'll
                                // ignore the extrusion.  Otherwise, we will fail.

                                if (smCapsule.SolidsCount() == 0 && smCapsule.MeshesCount() == 0)
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                cantHandle = true;
                            }
                            hasGeometry = true;
                        }
                        else
                        {
                            hasGeometry = true;
                        }
                    }

                    if (!hasGeometry)
                    {
                        isCompletelyClipped = true;
                        return null;
                    }

                    if (cantHandle)
                        return null;
                }
            }

            if (!CanExportWallGeometryAsExtrusion(wallElement, range))
                return null;

            // extrusion direction.
            XYZ extrusionDir = GetWallHeightDirection(wallElement);

            // create extrusion boundary.
            IList<CurveLoop> boundaryLoops = new List<CurveLoop>();

            bool alwaysThickenCurve = IsWallBaseRectangular(wallElement, curve);

            if (!alwaysThickenCurve)
            {
                boundaryLoops = GetLoopsFromTopBottomFace(wallElement, exporterIFC);
                if (boundaryLoops.Count == 0)
                    return null;
            }
            else
            {
                CurveLoop newLoop = CurveLoop.CreateViaThicken(curve, wallElement.Width, XYZ.BasisZ);
                if (newLoop == null)
                    return null;

                if (!newLoop.IsCounterclockwise(XYZ.BasisZ))
                    newLoop = GeometryUtil.ReverseOrientation(newLoop);
                boundaryLoops.Add(newLoop);
            }

            // origin gets scaled later.
            XYZ setterOffset = new XYZ(0, 0, setter.Offset + (localOrig[2] - setter.BaseOffset));

            IFCAnyHandle baseBodyItemHnd = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, boundaryLoops, plane,
                extrusionDir, depth);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(baseBodyItemHnd))
                return null;

            IFCAnyHandle bodyItemHnd = AddClippingsToBaseExtrusion(exporterIFC, wallElement,
               setterOffset, range, zSpan, baseBodyItemHnd, out cutPairOpenings);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItemHnd))
                return null;

            IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, wallElement.Document,
                baseBodyItemHnd, ElementId.InvalidElementId);

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

            IFCAnyHandle contextOfItemsBody = exporterIFC.Get3DContextHandle("Body");
            if (baseBodyItemHnd.Id == bodyItemHnd.Id)
            {
                bodyRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems, null);
            }
            else
            {
                bodyRep = RepresentationUtil.CreateClippingRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems);
            }

            return bodyRep;
        }
Ejemplo n.º 52
0
        /// <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();
            }
        }
Ejemplo n.º 53
0
        /// <summary>
        /// Exports a family instance as a mapped item.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="familyInstance">
        /// The family instance to be exported.
        /// </param>
        /// <param name="exportType">
        /// The export type.
        /// </param>
        /// <param name="ifcEnumType">
        /// The string value represents the IFC type.
        /// </param>
        /// <param name="wrapper">
        /// The ProductWrapper.
        /// </param>
        /// <param name="overrideLevelId">
        /// The level id.
        /// </param>
        /// <param name="range">
        /// The range of this family instance to be exported.
        /// </param>
        public static void ExportFamilyInstanceAsMappedItem(ExporterIFC exporterIFC,
            FamilyInstance familyInstance, IFCExportType exportType, string ifcEnumType,
            ProductWrapper wrapper, ElementId overrideLevelId, IFCRange range, IFCAnyHandle parentLocalPlacement)
        {
            bool exportParts = PartExporter.CanExportParts(familyInstance);
            bool isSplit = range != null;
            if (exportParts && !PartExporter.CanExportElementInPartExport(familyInstance, isSplit ? overrideLevelId : familyInstance.Level.Id, isSplit))
                return;

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

            FamilySymbol familySymbol = ExporterIFCUtils.GetOriginalSymbol(familyInstance);
            if (familySymbol == null)
                return;

            ProductWrapper familyProductWrapper = ProductWrapper.Create(wrapper);
            double scale = exporterIFC.LinearScale;
            Options options = GeometryUtil.GetIFCExportGeometryOptions();

            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

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

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

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

            IList<IFCExtrusionData> cutPairOpeningsForColumns = new List<IFCExtrusionData>();
            using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
            {
                Transform trf = familyInstance.GetTransform();

                // Extra information if we are exporting a door or a window.
                IFCDoorWindowInfo doorWindowInfo = null;
                if (exportType == IFCExportType.ExportDoorType)
                    doorWindowInfo = IFCDoorWindowInfo.CreateDoorInfo(exporterIFC, familyInstance, familySymbol, hostElement, overrideLevelId, trf);
                else if (exportType == IFCExportType.ExportWindowType)
                    doorWindowInfo = IFCDoorWindowInfo.CreateWindowInfo(exporterIFC, familyInstance, familySymbol, hostElement, overrideLevelId, trf);

                FamilyTypeInfo typeInfo = new FamilyTypeInfo();
                XYZ extraOffset = XYZ.Zero;

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

                Family family = familySymbol.Family;

                // TODO: this code to be removed by ExtrusionAnalyzer code.
                bool trySpecialColumnCreation = ((exportType == IFCExportType.ExportColumnType) && (!family.IsInPlace));
                IList<GeometryObject> geomObjects = new List<GeometryObject>();
                Transform brepOffsetTransform = null;

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

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

                    // TODO: this code to be removed by ExtrusionAnalyzer code.
                    if (trySpecialColumnCreation)
                    {
                        XYZ rangeOffset = trf.Origin;
                        IFCFamilyInstanceExtrusionExportResults results;

                        results = ExporterIFCUtils.ExportFamilyInstanceAsExtrusion(exporterIFC, familyInstance, useInstanceGeometry, range, overrideLevelId, extraParams);

                        bodyRepresentation = results.GetExtrusionHandle();
                        extraOffset = results.ExtraOffset;
                        cutPairOpeningsForColumns = results.GetCutPairOpenings();

                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepresentation))
                        {
                            typeInfo.MaterialIds.Add(results.MaterialId);
                            // add in level for real columns, not in-place ones.
                            Element actualLevel =
                               (overrideLevelId == ElementId.InvalidElementId) ? familyInstance.Level : doc.GetElement(overrideLevelId);
                            if (actualLevel != null)
                            {
                                IFCLevelInfo levelInfo = exporterIFC.GetLevelInfo(actualLevel.Id);
                                double nonStoryLevelOffset = LevelUtil.GetNonStoryLevelOffsetIfAny(exporterIFC, actualLevel as Level);
                                if (range != null)
                                {
                                    rangeOffset = new XYZ(rangeOffset.X, rangeOffset.Y, levelInfo.Elevation + nonStoryLevelOffset);
                                }
                            }
                        }

                        rangeOffset += extraOffset;
                        trf.Origin = rangeOffset;
                    }

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

                    bool needToCreate2d = ExporterCacheManager.ExportOptionsCache.ExportAnnotations;
                    bool needToCreate3d = IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepresentation);

                    if (needToCreate2d || needToCreate3d)
                    {
                        using (IFCTransformSetter trfSetter = IFCTransformSetter.Create())
                        {
                            if (doorWindowInfo != null)
                            {
                                trfSetter.Initialize(exporterIFC, doorWindowTrf);
                            }

                            GeometryElement exportGeometry =
                               useInstanceGeometry ? familyInstance.get_Geometry(options) : familySymbol.get_Geometry(options);
                            if (exportGeometry == null)
                                return;

                            if (needToCreate3d)
                            {
                                SolidMeshGeometryInfo solidMeshCapsule = null;

                                if (range == null)
                                {
                                    solidMeshCapsule = GeometryUtil.GetSolidMeshGeometry(exportGeometry, Transform.Identity);
                                }
                                else
                                {
                                    solidMeshCapsule = GeometryUtil.GetClippedSolidMeshGeometry(exportGeometry, range);
                                }

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

                                if (range != null && (solids.Count == 0 && polyMeshes.Count == 0))
                                    return; // no proper split geometry

                                geomObjects = FamilyExporterUtil.RemoveSolidsAndMeshesSetToDontExport(doc, exporterIFC, solids, polyMeshes);
                                if (geomObjects.Count == 0 && (solids.Count > 0 || polyMeshes.Count > 0))
                                    return;

                                bool tryToExportAsExtrusion = (!exporterIFC.ExportAs2x2 || (exportType == IFCExportType.ExportColumnType));

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

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

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

                                BodyData bodyData = null;
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepresentation))
                                {
                                    BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(tryToExportAsExtrusion);
                                    if (geomObjects.Count > 0)
                                    {
                                        bodyData = BodyExporter.ExportBody(familyInstance.Document.Application, exporterIFC, familyInstance, categoryId, ElementId.InvalidElementId,
                                            geomObjects, bodyExporterOptions, extraParams);
                                        typeInfo.MaterialIds = bodyData.MaterialIds;
                                    }
                                    else
                                    {
                                        IList<GeometryObject> exportedGeometries = new List<GeometryObject>();
                                        exportedGeometries.Add(exportGeometry);
                                        bodyData = BodyExporter.ExportBody(familyInstance.Document.Application, exporterIFC, familyInstance, categoryId, ElementId.InvalidElementId,
                                            exportedGeometries, bodyExporterOptions, extraParams);
                                    }
                                    bodyRepresentation = bodyData.RepresentationHnd;
                                    brepOffsetTransform = bodyData.BrepOffsetTransform;
                                }

                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepresentation))
                                {
                                    extraParams.ClearOpenings();
                                    return;
                                }
                            }

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

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

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

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

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

                    if (doorWindowInfo != null)
                    {
                        typeInfo.StyleTransform = doorWindowTrf.Inverse;
                    }
                    else
                    {
                        if (!MathUtil.IsAlmostZero(extraOffset.DotProduct(extraOffset)))
                        {
                            Transform newTransform = typeInfo.StyleTransform;
                            XYZ newOrig = newTransform.Origin + extraOffset;
                            newTransform.Origin = newOrig;
                            typeInfo.StyleTransform = newTransform;
                        }
                        typeInfo.StyleTransform = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, extraParams.GetLocalPlacement());
                    }

                    IFCAnyHandle origin = ExporterUtil.CreateAxis2Placement3D(file);
                    IFCAnyHandle repMap2dHnd = null;
                    IFCAnyHandle repMap3dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyRepresentation);

                    IList<IFCAnyHandle> repMapList = new List<IFCAnyHandle>();
                    repMapList.Add(repMap3dHnd);
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(planRepresentation))
                    {
                        repMap2dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, planRepresentation);
                        repMapList.Add(repMap2dHnd);
                    }

                    // for Door, Window
                    bool paramTakesPrecedence = false; // For Revit, this is currently always false.
                    bool sizeable = false;

                    // for many
                    HashSet<IFCAnyHandle> propertySets = new HashSet<IFCAnyHandle>();

                    string guid = GUIDUtil.CreateGUID(familySymbol);
                    string symId = NamingUtil.CreateIFCElementId(familySymbol);

                    // This covers many generic types.  If we can't find it in the list here, do custom exports.
                    IFCAnyHandle typeStyle = FamilyExporterUtil.ExportGenericType(file, exportType, ifcEnumType, guid,
                       ownerHistory, objectType, null, null, propertySets, repMapList, symId, objectType,
                       familyInstance, familySymbol);

                    // Cover special cases not covered above.
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(typeStyle))
                    {
                        switch (exportType)
                        {
                            case IFCExportType.ExportColumnType:
                                {
                                    // If we are using the instance GRep, then we have to create a generic GUID for the
                                    // column type, as they share the same ElementId.
                                    string colGUID = null;
                                    string colElemId = null;

                                    if (useInstanceGeometry)
                                        colGUID = GUIDUtil.CreateGUID();
                                    else
                                        colGUID = guid;
                                    colElemId = NamingUtil.CreateIFCElementId(familySymbol);

                                    string columnType = "Column";
                                    typeStyle = IFCInstanceExporter.CreateColumnType(file, colGUID, ownerHistory, objectType,
                                       null, null, propertySets, repMapList, colElemId,
                                       objectType, GetColumnType(familyInstance, columnType));

                                    break;
                                }
                            case IFCExportType.ExportDoorType:
                                {
                                    string constructionType = string.Empty;
                                    ParameterUtil.GetStringValueFromElementOrSymbol(familyInstance, "Construction", out constructionType);

                                    IFCAnyHandle doorLining = DoorWindowUtil.CreateDoorLiningProperties(exporterIFC, familyInstance);
                                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(doorLining))
                                        propertySets.Add(doorLining);

                                    IList<IFCAnyHandle> doorPanels = DoorWindowUtil.CreateDoorPanelProperties(exporterIFC, doorWindowInfo,
                                       familyInstance);
                                    propertySets.UnionWith(doorPanels);

                                    string doorStyleGUID = GUIDUtil.CreateGUID();
                                    string doorStyleElemId = NamingUtil.CreateIFCElementId(familySymbol);
                                    typeStyle = IFCInstanceExporter.CreateDoorStyle(file, doorStyleGUID, ownerHistory, objectType,
                                       null, null, propertySets, repMapList, doorStyleElemId,
                                       GetDoorStyleOperation(doorWindowInfo.DoorOperationType), GetDoorStyleConstruction(familyInstance, constructionType),
                                       paramTakesPrecedence, sizeable);
                                    break;
                                }
                            case IFCExportType.ExportSystemFurnitureElementType:
                                {
                                    string furnitureId = NamingUtil.CreateIFCElementId(familySymbol);
                                    typeStyle = IFCInstanceExporter.CreateSystemFurnitureElementType(file, guid, ownerHistory, objectType,
                                       null, null, propertySets, repMapList, furnitureId,
                                       objectType);
                                    break;
                                }
                            case IFCExportType.ExportWindowType:
                                {
                                    Toolkit.IFCWindowStyleOperation operationType = DoorWindowUtil.GetIFCWindowStyleOperation(familySymbol);
                                    IFCWindowStyleConstruction constructionType = DoorWindowUtil.GetIFCWindowStyleConstruction(familyInstance, "");

                                    IFCAnyHandle windowLining = DoorWindowUtil.CreateWindowLiningProperties(exporterIFC, familyInstance, null);
                                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(windowLining))
                                        propertySets.Add(windowLining);

                                    IList<IFCAnyHandle> windowPanels =
                                       DoorWindowUtil.CreateWindowPanelProperties(exporterIFC, familyInstance, null);
                                    propertySets.UnionWith(windowPanels);

                                    string windowStyleGUID = GUIDUtil.CreateGUID();
                                    string windowStyleElemId = NamingUtil.CreateIFCElementId(familySymbol);
                                    typeStyle = IFCInstanceExporter.CreateWindowStyle(file, windowStyleGUID, ownerHistory, objectType,
                                       null, null, propertySets, repMapList, windowStyleElemId,
                                       constructionType, operationType, paramTakesPrecedence, sizeable);
                                    break;
                                }
                            case IFCExportType.ExportBuildingElementProxy:
                            default:
                                {
                                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repMap2dHnd))
                                        typeInfo.Map2DHandle = repMap2dHnd;
                                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repMap3dHnd))
                                        typeInfo.Map3DHandle = repMap3dHnd;
                                    break;
                                }
                        }
                    }

                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(typeStyle))
                    {
                        CategoryUtil.CreateMaterialAssociations(doc, exporterIFC, typeStyle, typeInfo.MaterialIds);

                        typeInfo.Style = typeStyle;

                        if (((exportType == IFCExportType.ExportColumnType) && trySpecialColumnCreation) ||
                           (exportType == IFCExportType.ExportMemberType))
                        {
                            typeInfo.ScaledArea = extraParams.ScaledArea;
                            typeInfo.ScaledDepth = extraParams.ScaledLength;
                            typeInfo.ScaledInnerPerimeter = extraParams.ScaledInnerPerimeter;
                            typeInfo.ScaledOuterPerimeter = extraParams.ScaledOuterPerimeter;
                        }

                        ClassificationUtil.CreateUniformatClassification(exporterIFC, file, familySymbol, typeStyle);
                    }
                }
                else if (!creatingType && (trySpecialColumnCreation))
                {
                    // still need to modify instance trf for columns.
                    trf.Origin += GetLevelOffsetForExtrudedColumns(exporterIFC, familyInstance, overrideLevelId, extraParams);
                }

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

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

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

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

                trf = trf.Multiply(typeInfo.StyleTransform);

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

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

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

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

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

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

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

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

                IFCAnyHandle instanceHandle = null;
                using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, familyInstance, trf, null, overrideLevelId))
                {
                    string instanceGUID = GUIDUtil.CreateGUID(familyInstance);
                    string instanceName = NamingUtil.GetIFCName(familyInstance);
                    string instanceDescription = NamingUtil.GetDescriptionOverride(familyInstance, null);
                    string instanceObjectType = NamingUtil.GetObjectTypeOverride(familyInstance, objectType);
                    string instanceElemId = NamingUtil.CreateIFCElementId(familyInstance);

                    IFCAnyHandle localPlacement = setter.GetPlacement();
                    IFCAnyHandle overrideLocalPlacement = null;

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

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

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

                    if (exportParts)
                    {
                        PartExporter.ExportHostPart(exporterIFC, familyInstance, instanceHandle, familyProductWrapper, setter, setter.GetPlacement(), overrideLevelId);
                    }

                    if (ElementFilteringUtil.IsMEPType(exportType))
                        ExporterCacheManager.MEPCache.Register(familyInstance, instanceHandle);

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

                                        IFCAnyHandle openingRelativePlacement = ExporterUtil.CreateAxis2Placement3D(file, openingTrf.Origin * scale,
                                           openingTrf.get_Basis(2), openingTrf.get_Basis(0));
                                        IFCAnyHandle openingPlacement = ExporterUtil.CopyLocalPlacement(file, localPlacement);
                                        GeometryUtil.SetRelativePlacement(openingPlacement, openingRelativePlacement);
                                        placementToUse = openingPlacement;
                                    }
                                }

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

                                //export Base Quantities.
                                PropertyUtil.CreateBeamColumnBaseQuantities(exporterIFC, instanceHandle, familyInstance, typeInfo);

                                PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, familyInstance, wrapper);
                                break;
                            }
                        case IFCExportType.ExportDoorType:
                        case IFCExportType.ExportWindowType:
                            {
                                double doorHeight = doorWindowInfo.OpeningHeight;
                                if (doorHeight < MathUtil.Eps())
                                    doorHeight = GetMinSymbolHeight(familySymbol);
                                double doorWidth = doorWindowInfo.OpeningWidth;
                                if (doorWidth < MathUtil.Eps())
                                    doorWidth = GetMinSymbolWidth(familySymbol);

                                double height = doorHeight * scale;
                                double width = doorWidth * scale;

                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(doorWindowInfo.GetLocalPlacement()))
                                    doorWindowInfo.SetLocalPlacement(localPlacement);

                                IFCAnyHandle doorWindowOrigLocalPlacement = doorWindowInfo.GetLocalPlacement();
                                Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(localPlacement, doorWindowOrigLocalPlacement);

                                IFCAnyHandle doorWindowRelativePlacement = ExporterUtil.CreateAxis2Placement3D(file, relTrf.Origin, relTrf.BasisZ, relTrf.BasisX);
                                IFCAnyHandle doorWindowLocalPlacement =
                                   IFCInstanceExporter.CreateLocalPlacement(file, doorWindowOrigLocalPlacement, doorWindowRelativePlacement);
                                if (exportType == IFCExportType.ExportDoorType)
                                    instanceHandle = IFCInstanceExporter.CreateDoor(file, instanceGUID, ownerHistory,
                                       instanceName, instanceDescription, instanceObjectType, doorWindowLocalPlacement,
                                       rep, instanceElemId, height, width);
                                else if (exportType == IFCExportType.ExportWindowType)
                                    instanceHandle = IFCInstanceExporter.CreateWindow(file, instanceGUID, ownerHistory,
                                       instanceName, instanceDescription, instanceObjectType, doorWindowLocalPlacement,
                                       rep, instanceElemId, height, width);
                                wrapper.AddElement(instanceHandle, setter, extraParams, true);

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

                                IFCAnyHandle placementToUse = doorWindowLocalPlacement;
                                if (!useInstanceGeometry)
                                {
                                    // correct the placement to the symbol space
                                    bool needToCreateOpenings = OpeningUtil.NeedToCreateOpenings(instanceHandle, extraParams);
                                    if (needToCreateOpenings)
                                    {
                                        Transform openingTrf = Transform.Identity;
                                        openingTrf.Origin = new XYZ(0, 0, setter.Offset);
                                        openingTrf = openingTrf.Multiply(doorWindowTrf);
                                        XYZ scaledOrigin = openingTrf.Origin * exporterIFC.LinearScale;
                                        IFCAnyHandle openingRelativePlacement = ExporterUtil.CreateAxis2Placement3D(file, scaledOrigin, openingTrf.BasisZ, openingTrf.BasisX);
                                        IFCAnyHandle openingLocalPlacement =
                                           IFCInstanceExporter.CreateLocalPlacement(file, doorWindowLocalPlacement, openingRelativePlacement);
                                        placementToUse = openingLocalPlacement;
                                    }
                                }
                                // only necessary when exporting as possible breps.
                                OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, exporterIFC,
                                   placementToUse, setter, wrapper);
                                if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
                                    ExporterIFCUtils.CreateDoorWindowBaseQuantities(exporterIFC, instanceHandle, (doorHeight * scale), (doorWidth * scale));

                                PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, familyInstance, wrapper);
                                break;
                            }
                        case IFCExportType.ExportMemberType:
                            {
                                OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, exporterIFC,
                                   localPlacement, setter, wrapper);

                                //export Base Quantities.
                                PropertyUtil.CreateBeamColumnBaseQuantities(exporterIFC, instanceHandle, familyInstance, typeInfo);
                                // TODO: create PropertySet!
                                //createMemberPropertySet(exporter, pFamInst, pWrapper, extraParams);
                                PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, familyInstance, wrapper);
                                break;
                            }
                        case IFCExportType.ExportPlateType:
                            {
                                OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, familyInstance, extraParams, exporterIFC,
                                   localPlacement, setter, wrapper);

                                // TODO: create PropertySet!
                                //createPlatePropertySet(exporter, pFamInst, pWrapper, extraParams);
                                PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, familyInstance, wrapper);
                                break;
                            }
                        case IFCExportType.ExportTransportElementType:
                            {
                                IFCAnyHandle localPlacementToUse;
                                ElementId roomId = setter.UpdateRoomRelativeCoordinates(familyInstance, out localPlacementToUse);

                                instanceHandle = IFCInstanceExporter.CreateTransportElement(file, instanceGUID, ownerHistory,
                                   instanceName, instanceDescription, instanceObjectType,
                                   localPlacementToUse, rep, instanceElemId, null, null, null);

                                if (roomId == ElementId.InvalidElementId)
                                {
                                    wrapper.AddElement(instanceHandle, setter, extraParams, true);
                                }
                                else
                                {
                                    exporterIFC.RelateSpatialElement(roomId, instanceHandle);
                                    wrapper.AddElement(instanceHandle, setter, extraParams, false);
                                }

                                PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, familyInstance, wrapper);
                                break;
                            }
                        case IFCExportType.ExportBuildingElementProxy:
                        default:
                            {
                                bool isBuildingElementProxy = (exportType == IFCExportType.ExportBuildingElementProxy);

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

                                if (!isBuildingElementProxy)
                                {
                                    if (FamilyExporterUtil.IsDistributionControlElementSubType(exportType))
                                    {
                                        instanceHandle = IFCInstanceExporter.CreateDistributionControlElement(file, instanceGUID,
                                           ownerHistory, instanceName, instanceDescription, instanceObjectType,
                                           localPlacementToUse, rep, instanceElemId, null);

                                        if (roomId == ElementId.InvalidElementId)
                                        {
                                            wrapper.AddElement(instanceHandle, setter, extraParams, true);
                                        }
                                        else
                                        {
                                            exporterIFC.RelateSpatialElement(roomId, instanceHandle);
                                            wrapper.AddElement(instanceHandle, setter, extraParams, false);
                                        }
                                    }
                                    else if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle))
                                    {
                                        isBuildingElementProxy = true;
                                    }
                                }

                                if (isBuildingElementProxy)
                                {
                                    Toolkit.IFCElementComposition proxyType = Toolkit.IFCElementComposition.Element;

                                    instanceHandle = IFCInstanceExporter.CreateBuildingElementProxy(file, instanceGUID,
                                       ownerHistory, instanceName, instanceDescription, instanceObjectType,
                                       localPlacementToUse, rep, instanceElemId, proxyType);

                                    if (roomId == ElementId.InvalidElementId)
                                    {
                                        wrapper.AddElement(instanceHandle, setter, extraParams, true);
                                    }
                                    else
                                    {
                                        exporterIFC.RelateSpatialElement(roomId, instanceHandle);
                                        wrapper.AddElement(instanceHandle, setter, extraParams, false);
                                    }
                                }

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

                                        IFCAnyHandle openingRelativePlacement = ExporterUtil.CreateAxis2Placement3D(file, openingTrf.Origin * scale,
                                           openingTrf.get_Basis(2), openingTrf.get_Basis(0));
                                        IFCAnyHandle openingPlacement = ExporterUtil.CopyLocalPlacement(file, localPlacement);
                                        GeometryUtil.SetRelativePlacement(openingPlacement, openingRelativePlacement);
                                        placementToUse = openingPlacement;
                                    }
                                }

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

                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle))
                    {
                        if (doorWindowInfo != null)
                        {
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(doorWindowInfo.GetOpening()))
                            {
                                string relGUID = GUIDUtil.CreateGUID();
                                IFCInstanceExporter.CreateRelFillsElement(file, relGUID, ownerHistory, null, null, doorWindowInfo.GetOpening(), instanceHandle);
                            }
                            else if (doorWindowInfo.NeedsOpening)
                            {
                                bool added = doorWindowInfo.SetDelayedFamilyInstance(instanceHandle, localPlacement, doorWindowInfo.AssignedLevelId);
                                if (added)
                                    exporterIFC.RegisterDoorWindowForOpeningUpdate(doorWindowInfo);
                                else
                                {
                                    // we need to fill a later opening.
                                    exporterIFC.RegisterDoorWindowForUncreatedOpening(familyInstance.Id, instanceHandle);
                                }
                            }
                        }

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

                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(typeInfo.Style))
                            ExporterCacheManager.TypeRelationsCache.Add(typeInfo.Style, instanceHandle);
                    }
                }
            }
        }
Ejemplo n.º 54
0
        /// <summary>
        /// Exports list of geometries to IFC body representation.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="geometryListIn">The geometry list.</param>
        /// <param name="options">The settings for how to export the body.</param>
        /// <param name="exportBodyParams">The extrusion creation data.</param>
        /// <returns>The BodyData containing the handle, offset and material ids.</returns>
        public static BodyData ExportBody(ExporterIFC exporterIFC,
            Element element,
            ElementId categoryId,
            ElementId overrideMaterialId,
            IList<GeometryObject> geometryList,
            BodyExporterOptions options,
            IFCExtrusionCreationData exportBodyParams)
        {
            BodyData bodyData = new BodyData();
            if (geometryList.Count == 0)
                return bodyData;

            Document document = element.Document;
            bool tryToExportAsExtrusion = options.TryToExportAsExtrusion;
            bool canExportSolidModelRep = tryToExportAsExtrusion && ExporterCacheManager.ExportOptionsCache.CanExportSolidModelRep;

            bool useCoarseTessellation = (ExporterCacheManager.ExportOptionsCache.LevelOfDetail < 4);
            bool allowAdvancedBReps = ExporterCacheManager.ExportOptionsCache.ExportAs4 && !ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView;

            // We will try to export as a swept solid if the option is set, and we are either exporting to a schema that allows it,
            // or we are using a coarse tessellation, in which case we will export the swept solid as an optimzed BRep.
            bool tryToExportAsSweptSolid = options.TryToExportAsSweptSolid && (allowAdvancedBReps || useCoarseTessellation);

            // We will allow exporting swept solids as BReps or TriangulatedFaceSet if we are exporting to a schema before IFC4, or to a Reference View MVD, 
            // and we allow coarse representations.  In the future, we may allow more control here.
            // Note that we disable IFC4 because in IFC4, we will export it as a true swept solid instead, except for the Reference View MVD.
            bool tryToExportAsSweptSolidAsTessellation = tryToExportAsSweptSolid && useCoarseTessellation && !allowAdvancedBReps;

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

            double eps = UnitUtil.ScaleLength(element.Document.Application.VertexTolerance);

            bool allFaces = true;
            foreach (GeometryObject geomObject in geometryList)
            {
                if (!(geomObject is Face))
                {
                    allFaces = false;
                    break;
                }
            }

            IList<IFCAnyHandle> bodyItems = new List<IFCAnyHandle>();
            IList<ElementId> materialIdsForExtrusions = new List<ElementId>();

            // This is a list of geometries that can be exported using the coarse facetation of the SweptSolidExporter.
            IList<KeyValuePair<int, SimpleSweptSolidAnalyzer>> exportAsBRep = new List<KeyValuePair<int, SimpleSweptSolidAnalyzer>>();

            IList<int> exportAsSweptSolid = new List<int>();
            IList<int> exportAsExtrusion = new List<int>();

            bool hasExtrusions = false;
            bool hasSweptSolids = false;
            bool hasSweptSolidsAsBReps = false;
            ShapeRepresentationType hasRepresentationType = ShapeRepresentationType.Undefined;

            BoundingBoxXYZ bbox = GeometryUtil.GetBBoxOfGeometries(geometryList);
            XYZ unscaledTrfOrig = new XYZ();

            int numItems = geometryList.Count;
            bool tryExtrusionAnalyzer = tryToExportAsExtrusion && (options.ExtrusionLocalCoordinateSystem != null) && (numItems == 1) && (geometryList[0] is Solid);
            bool supportOffsetTransformForExtrusions = !(tryExtrusionAnalyzer || tryToExportAsSweptSolidAsTessellation);
            bool useOffsetTransformForExtrusions = (options.AllowOffsetTransform && supportOffsetTransformForExtrusions && (exportBodyParams != null));

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                // generate "bottom corner" of bbox; create new local placement if passed in.
                // need to transform, but not scale, this point to make it the new origin.
                using (TransformSetter transformSetter = TransformSetter.Create())
                {
                    if (useOffsetTransformForExtrusions)
                        bodyData.OffsetTransform = transformSetter.InitializeFromBoundingBox(exporterIFC, bbox, exportBodyParams, out unscaledTrfOrig);

                    // If we passed in an ExtrusionLocalCoordinateSystem, and we have 1 Solid, we will try to create an extrusion using the ExtrusionAnalyzer.
                    // If we succeed, we will skip the rest of the routine, otherwise we will try with the backup extrusion method.
                    // This doesn't yet create fallback information for solid models that are hybrid extrusions and BReps.
                    if (tryToExportAsExtrusion)
                    {
                        if (tryExtrusionAnalyzer)
                        {
                            using (IFCTransaction extrusionTransaction = new IFCTransaction(file))
                            {
                                Plane extrusionPlane = new Plane(
                                        options.ExtrusionLocalCoordinateSystem.BasisY,
                                        options.ExtrusionLocalCoordinateSystem.BasisZ,
                                        options.ExtrusionLocalCoordinateSystem.Origin);
                                XYZ extrusionDirection = options.ExtrusionLocalCoordinateSystem.BasisX;

                                bool completelyClipped;
                                HandleAndData extrusionData = ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, element,
                                    CategoryUtil.GetSafeCategoryId(element), geometryList[0] as Solid, extrusionPlane,
                                    extrusionDirection, null, out completelyClipped);
                                if (!completelyClipped && !IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionData.Handle) && extrusionData.BaseExtrusions != null && extrusionData.BaseExtrusions.Count == 1)
                                {
                                    HashSet<ElementId> materialIds = extrusionData.MaterialIds;

                                    // We skip setting and getting the material id from the exporter as unnecessary.
                                    ElementId matIdFromGeom = (materialIds != null && materialIds.Count > 0) ? materialIds.First() : ElementId.InvalidElementId;
                                    ElementId matId = (overrideMaterialId != ElementId.InvalidElementId) ? overrideMaterialId : matIdFromGeom;

                                    bodyItems.Add(extrusionData.BaseExtrusions[0]);
                                    materialIdsForExtrusions.Add(matId);
                                    if (matId != ElementId.InvalidElementId)
                                        bodyData.AddMaterial(matId);
                                    bodyData.RepresentationHnd = extrusionData.Handle;
                                    bodyData.ShapeRepresentationType = extrusionData.ShapeRepresentationType;

                                    if (exportBodyParams != null && extrusionData.Data != null)
                                    {
                                        exportBodyParams.Slope = extrusionData.Data.Slope;
                                        exportBodyParams.ScaledLength = extrusionData.Data.ScaledLength;
                                        exportBodyParams.ExtrusionDirection = extrusionData.Data.ExtrusionDirection;

                                        exportBodyParams.ScaledHeight = extrusionData.Data.ScaledHeight;
                                        exportBodyParams.ScaledWidth = extrusionData.Data.ScaledWidth;

                                        exportBodyParams.ScaledArea = extrusionData.Data.ScaledArea;
                                        exportBodyParams.ScaledInnerPerimeter = extrusionData.Data.ScaledInnerPerimeter;
                                        exportBodyParams.ScaledOuterPerimeter = extrusionData.Data.ScaledOuterPerimeter;
                                    }

                                    hasExtrusions = true;
                                    extrusionTransaction.Commit();
                                }
                                else
                                {
                                    extrusionTransaction.RollBack();
                                }
                            }
                        }

                        // Only try if ExtrusionAnalyzer wasn't called, or failed.
                        if (!hasExtrusions)
                        {
                            // Check to see if we have Geometries or GFaces.
                            // We will have the specific all GFaces case and then the generic case.
                            IList<Face> faces = null;

                            if (allFaces)
                            {
                                faces = new List<Face>();
                                foreach (GeometryObject geometryObject in geometryList)
                                {
                                    faces.Add(geometryObject as Face);
                                }
                            }

                            // Options used if we try to export extrusions.
                            IFCExtrusionAxes axesToExtrudeIn = exportBodyParams != null ? exportBodyParams.PossibleExtrusionAxes : IFCExtrusionAxes.TryDefault;
                            XYZ directionToExtrudeIn = XYZ.Zero;
                            if (exportBodyParams != null && exportBodyParams.HasCustomAxis)
                                directionToExtrudeIn = exportBodyParams.CustomAxis;

                            double lengthScale = UnitUtil.ScaleLengthForRevitAPI();
                            IFCExtrusionCalculatorOptions extrusionOptions =
                               new IFCExtrusionCalculatorOptions(exporterIFC, axesToExtrudeIn, directionToExtrudeIn, lengthScale);

                            int numExtrusionsToCreate = allFaces ? 1 : geometryList.Count;

                            IList<IList<IFCExtrusionData>> extrusionLists = new List<IList<IFCExtrusionData>>();
                            for (int ii = 0; ii < numExtrusionsToCreate; ii++)
                            {
                                IList<IFCExtrusionData> extrusionList = new List<IFCExtrusionData>();

                                if (tryToExportAsExtrusion)
                                {
                                    if (allFaces)
                                        extrusionList = IFCExtrusionCalculatorUtils.CalculateExtrusionData(extrusionOptions, faces);
                                    else
                                        extrusionList = IFCExtrusionCalculatorUtils.CalculateExtrusionData(extrusionOptions, geometryList[ii]);
                                }

                                if (extrusionList.Count == 0)
                                {
                                    // If we are trying to create swept solids, we will keep going, but we won't try to create more extrusions unless we are also exporting a solid model.
                                    if (tryToExportAsSweptSolid)
                                    {
                                        if (!canExportSolidModelRep)
                                            tryToExportAsExtrusion = false;
                                        exportAsSweptSolid.Add(ii);
                                    }
                                    else if (!canExportSolidModelRep)
                                    {
                                        tryToExportAsExtrusion = false;
                                        break;
                                    }
                                    else
                                        exportAsBRep.Add(new KeyValuePair<int, SimpleSweptSolidAnalyzer>(ii, null));
                                }
                                else
                                {
                                    extrusionLists.Add(extrusionList);
                                    exportAsExtrusion.Add(ii);
                                }
                            }

                            int numCreatedExtrusions = extrusionLists.Count;
                            for (int ii = 0; ii < numCreatedExtrusions && tryToExportAsExtrusion; ii++)
                            {
                                int geomIndex = exportAsExtrusion[ii];

                                ElementId matId = SetBestMaterialIdInExporter(geometryList[geomIndex], element, overrideMaterialId, exporterIFC);
                                if (matId != ElementId.InvalidElementId)
                                    bodyData.AddMaterial(matId);

                                if (exportBodyParams != null && exportBodyParams.AreInnerRegionsOpenings)
                                {
                                    IList<CurveLoop> curveLoops = extrusionLists[ii][0].GetLoops();
                                    XYZ extrudedDirection = extrusionLists[ii][0].ExtrusionDirection;

                                    int numLoops = curveLoops.Count;
                                    for (int jj = numLoops - 1; jj > 0; jj--)
                                    {
                                        ExtrusionExporter.AddOpeningData(exportBodyParams, extrusionLists[ii][0], curveLoops[jj]);
                                        extrusionLists[ii][0].RemoveLoopAt(jj);
                                    }
                                }

                                bool exportedAsExtrusion = false;
                                IFCExtrusionBasis whichBasis = extrusionLists[ii][0].ExtrusionBasis;
                                if (whichBasis >= 0)
                                {
                                    IFCAnyHandle extrusionHandle = ExtrusionExporter.CreateExtrudedSolidFromExtrusionData(exporterIFC, element, extrusionLists[ii][0]);
                                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionHandle))
                                    {
                                        bodyItems.Add(extrusionHandle);
                                        materialIdsForExtrusions.Add(exporterIFC.GetMaterialIdForCurrentExportState());

                                        IList<CurveLoop> curveLoops = extrusionLists[ii][0].GetLoops();
                                        XYZ extrusionDirection = extrusionLists[ii][0].ExtrusionDirection;

                                        if (exportBodyParams != null)
                                        {
                                            exportBodyParams.Slope = GeometryUtil.GetSimpleExtrusionSlope(extrusionDirection, whichBasis);
                                            exportBodyParams.ScaledLength = extrusionLists[ii][0].ScaledExtrusionLength;
                                            exportBodyParams.ExtrusionDirection = extrusionDirection;
                                            for (int kk = 1; kk < extrusionLists[ii].Count; kk++)
                                            {
                                                ExtrusionExporter.AddOpeningData(exportBodyParams, extrusionLists[ii][kk]);
                                            }

                                            Plane plane = null;
                                            double height = 0.0, width = 0.0;
                                            if (ExtrusionExporter.ComputeHeightWidthOfCurveLoop(curveLoops[0], plane, out height, out width))
                                            {
                                                exportBodyParams.ScaledHeight = UnitUtil.ScaleLength(height);
                                                exportBodyParams.ScaledWidth = UnitUtil.ScaleLength(width);
                                            }

                                            double area = ExporterIFCUtils.ComputeAreaOfCurveLoops(curveLoops);
                                            if (area > 0.0)
                                            {
                                                exportBodyParams.ScaledArea = UnitUtil.ScaleArea(area);
                                            }

                                            double innerPerimeter = ExtrusionExporter.ComputeInnerPerimeterOfCurveLoops(curveLoops);
                                            double outerPerimeter = ExtrusionExporter.ComputeOuterPerimeterOfCurveLoops(curveLoops);
                                            if (innerPerimeter > 0.0)
                                                exportBodyParams.ScaledInnerPerimeter = UnitUtil.ScaleLength(innerPerimeter);
                                            if (outerPerimeter > 0.0)
                                                exportBodyParams.ScaledOuterPerimeter = UnitUtil.ScaleLength(outerPerimeter);
                                        }
                                        exportedAsExtrusion = true;
                                        hasExtrusions = true;
                                    }
                                }

                                if (!exportedAsExtrusion)
                                {
                                    if (tryToExportAsSweptSolid)
                                        exportAsSweptSolid.Add(ii);
                                    else if (!canExportSolidModelRep)
                                    {
                                        tryToExportAsExtrusion = false;
                                        break;
                                    }
                                    else
                                        exportAsBRep.Add(new KeyValuePair<int, SimpleSweptSolidAnalyzer>(ii, null));
                                }
                            }
                        }
                    }

                    if (tryToExportAsSweptSolid)
                    {
                        int numCreatedSweptSolids = exportAsSweptSolid.Count;
                        for (int ii = 0; (ii < numCreatedSweptSolids) && tryToExportAsSweptSolid; ii++)
                        {
                            bool exported = false;
                            int geomIndex = exportAsSweptSolid[ii];
                            Solid solid = geometryList[geomIndex] as Solid;
                            SimpleSweptSolidAnalyzer simpleSweptSolidAnalyzer = null;
                            // TODO: allFaces to SweptSolid
                            if (solid != null)
                            {
                                // TODO: give normal hint below if we have an idea.
                                simpleSweptSolidAnalyzer = SweptSolidExporter.CanExportAsSweptSolid(exporterIFC, solid, null);

                                // If we are exporting as a BRep, we will keep the analyzer for later, if it isn't null.
                                if (simpleSweptSolidAnalyzer != null)
                                {
                                    if (!tryToExportAsSweptSolidAsTessellation)
                                    {
                                        SweptSolidExporter sweptSolidExporter = SweptSolidExporter.Create(exporterIFC, element, simpleSweptSolidAnalyzer, solid);
                                        IFCAnyHandle sweptHandle = (sweptSolidExporter != null) ? sweptSolidExporter.RepresentationItem : null;

                                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(sweptHandle))
                                        {
                                            bodyItems.Add(sweptHandle);
                                            materialIdsForExtrusions.Add(exporterIFC.GetMaterialIdForCurrentExportState());
                                            exported = true;
                                            hasRepresentationType = sweptSolidExporter.RepresentationType;

                                            // These are the only two valid cases for true sweep export: either an extrusion or a sweep.
                                            // We don't expect regular BReps or triangulated face sets here.
                                            if (sweptSolidExporter.isSpecificRepresentationType(ShapeRepresentationType.SweptSolid))
                                                hasExtrusions = true;
                                            else if (sweptSolidExporter.isSpecificRepresentationType(ShapeRepresentationType.AdvancedSweptSolid))
                                                hasSweptSolids = true;
                                        }
                                        else
                                            simpleSweptSolidAnalyzer = null;    // Didn't work for some reason.
                                    }
                                }
                            }

                            if (!exported)
                            {
                                exportAsBRep.Add(new KeyValuePair<int, SimpleSweptSolidAnalyzer>(geomIndex, simpleSweptSolidAnalyzer));
                                hasSweptSolidsAsBReps |= (simpleSweptSolidAnalyzer != null);
                            }
                        }
                    }

                    bool exportSucceeded = (exportAsBRep.Count == 0) && (tryToExportAsExtrusion || tryToExportAsSweptSolid)
                                && (hasExtrusions || hasSweptSolids || hasRepresentationType != ShapeRepresentationType.Undefined);
                    if (exportSucceeded || canExportSolidModelRep)
                    {
                        int sz = bodyItems.Count();
                        for (int ii = 0; ii < sz; ii++)
                            BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, bodyItems[ii], materialIdsForExtrusions[ii]);

                        if (exportSucceeded)
                        {
                            if (bodyData.RepresentationHnd == null)
                            {
                                HashSet<IFCAnyHandle> bodyItemSet = new HashSet<IFCAnyHandle>();
                                bodyItemSet.UnionWith(bodyItems);
                                if (hasExtrusions && !hasSweptSolids)
                                {
                                    bodyData.RepresentationHnd =
                                        RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet, bodyData.RepresentationHnd);
                                    bodyData.ShapeRepresentationType = ShapeRepresentationType.SweptSolid;
                                }
                                else if (hasSweptSolids && !hasExtrusions)
                                {
                                    bodyData.RepresentationHnd =
                                        RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet, bodyData.RepresentationHnd);
                                    bodyData.ShapeRepresentationType = ShapeRepresentationType.AdvancedSweptSolid;
                                }
                                else if (hasRepresentationType == ShapeRepresentationType.Tessellation)
                                {
                                    bodyData.RepresentationHnd =
                                        RepresentationUtil.CreateTessellatedRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet, bodyData.RepresentationHnd);
                                    bodyData.ShapeRepresentationType = ShapeRepresentationType.Tessellation;
                                }
                                else
                                {
                                    bodyData.RepresentationHnd =
                                        RepresentationUtil.CreateSolidModelRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet);
                                    bodyData.ShapeRepresentationType = ShapeRepresentationType.SolidModel;
                                }
                            }

                            // TODO: include BRep, CSG, Clipping

                            XYZ lpOrig = ((bodyData != null) && (bodyData.OffsetTransform != null)) ? bodyData.OffsetTransform.Origin : new XYZ();
                            transformSetter.CreateLocalPlacementFromOffset(exporterIFC, bbox, exportBodyParams, lpOrig, unscaledTrfOrig);
                            tr.Commit();
                            return bodyData;
                        }
                    }

                    // If we are going to export a solid model, keep the created items.
                    if (!canExportSolidModelRep)
                        tr.RollBack();
                    else
                        tr.Commit();
                }

                // We couldn't export it as an extrusion; export as a solid, brep, or a surface model.
                if (!canExportSolidModelRep)
                {
                    exportAsExtrusion.Clear();
                    bodyItems.Clear();
                    if (exportBodyParams != null)
                        exportBodyParams.ClearOpenings();
                }

                if (exportAsExtrusion.Count == 0)
                {
                    // We used to clear exportAsBRep, but we need the SimpleSweptSolidAnalyzer information, so we will fill out the rest.
                    int numGeoms = geometryList.Count;
                    IList<KeyValuePair<int, SimpleSweptSolidAnalyzer>> newExportAsBRep = new List<KeyValuePair<int, SimpleSweptSolidAnalyzer>>(numGeoms);
                    int exportAsBRepCount = exportAsBRep.Count;
                    int currIndex = 0;
                    for (int ii = 0; ii < numGeoms; ii++)
                    {
                        if ((currIndex < exportAsBRepCount) && (ii == exportAsBRep[currIndex].Key))
                        {
                            newExportAsBRep.Add(exportAsBRep[currIndex]);
                            currIndex++;
                        }
                        else
                            newExportAsBRep.Add(new KeyValuePair<int, SimpleSweptSolidAnalyzer>(ii, null));
                    }
                    exportAsBRep = newExportAsBRep;
                }
            }

            // If we created some extrusions that we are using (e.g., creating a solid model), and we didn't use an offset transform for the extrusions, don't do it here either.
            bool supportOffsetTransformForBreps = !hasSweptSolidsAsBReps;
            bool disallowOffsetTransformForBreps = (exportAsExtrusion.Count > 0) && !useOffsetTransformForExtrusions;
            bool useOffsetTransformForBReps = options.AllowOffsetTransform && supportOffsetTransformForBreps && !disallowOffsetTransformForBreps;

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (TransformSetter transformSetter = TransformSetter.Create())
                {
                    // Need to do extra work to support offset transforms if we are using the sweep analyzer.
                    if (useOffsetTransformForBReps)
                        bodyData.OffsetTransform = transformSetter.InitializeFromBoundingBox(exporterIFC, bbox, exportBodyParams, out unscaledTrfOrig);

                    BodyData brepBodyData =
                        ExportBodyAsBRep(exporterIFC, geometryList, exportAsBRep, bodyItems, element, categoryId, overrideMaterialId, contextOfItems, eps, options, bodyData);
                    if (brepBodyData == null)
                        tr.RollBack();
                    else
                    {
                        XYZ lpOrig = ((bodyData != null) && (bodyData.OffsetTransform != null)) ? bodyData.OffsetTransform.Origin : new XYZ();
                        transformSetter.CreateLocalPlacementFromOffset(exporterIFC, bbox, exportBodyParams, lpOrig, unscaledTrfOrig);
                        tr.Commit();
                    }
                    return brepBodyData;
                }
            }
        }
Ejemplo n.º 55
0
        /// <summary>
        ///  Exports a roof or floor as a container of multiple roof slabs.  Returns the handle, if successful.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="element">The roof or floor element.</param>
        /// <param name="geometry">The geometry of the element.</param>
        /// <param name="productWrapper">The product wrapper.</param>
        /// <returns>The roof handle.</returns>
        /// <remarks>For floors, if there is only one component, return null, as we do not want to create a container.</remarks>
        public static IFCAnyHandle ExportRoofOrFloorAsContainer(ExporterIFC exporterIFC,
                                                                Element element, GeometryElement geometry, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

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

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

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

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

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

            Document doc = element.Document;

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

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

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

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

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

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


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

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

                                    IFCAnyHandle prodRepHnd = null;

                                    string elementGUID = GUIDUtil.CreateGUID(element);

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

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

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

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

                                    ElementId catId = CategoryUtil.GetSafeCategoryId(element);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                                            ExporterUtil.AddIntoComplexPropertyCache(slabHnd, layersetInfo);

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

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

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

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


                                    transaction.Commit();
                                    return(hostObjectHandle);
                                }
                            }
                        }
                        catch
                        {
                            // SOmething wrong with the above process, unable to create the extrusion data. Reset any internal handles that may have been partially created since they are not committed
                            productWrapper.ClearInternalHandleWrapperData(element);
                            return(null);
                        }
                        finally
                        {
                            exporterIFC.ClearFaceWithElementHandleMap();
                        }
                    }
                }
            }
        }
        private static HandleAndAnalyzer CreateExtrusionWithClippingBase(ExporterIFC exporterIFC, Element element,
            ElementId catId, IList<Solid> solids, Plane plane, XYZ projDir, IFCRange range, out bool completelyClipped, out HashSet<ElementId> materialIds)
        {
            IFCFile file = exporterIFC.GetFile();
            bool mustUseTessellation = false;

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                completelyClipped = false;
                materialIds = new HashSet<ElementId>();
                HandleAndAnalyzer retVal = new HandleAndAnalyzer();
                HashSet<IFCAnyHandle> extrusionBodyItems = new HashSet<IFCAnyHandle>();
                HashSet<IFCAnyHandle> extrusionBooleanBodyItems = new HashSet<IFCAnyHandle>();
                HashSet<IFCAnyHandle> extrusionClippingBodyItems = new HashSet<IFCAnyHandle>();
                foreach (Solid solid in solids)
                {
                    bool hasClippingResult = false;
                    bool hasBooleanResult = false;
                    ElementId materialId = ElementId.InvalidElementId;
                    HandleAndAnalyzer currRetVal = CreateExtrusionWithClippingAndOpening(exporterIFC, element, catId, solid, plane, projDir, range,
                        out completelyClipped, out hasClippingResult, out hasBooleanResult, out materialId);

                    if (currRetVal != null && currRetVal.Handle != null)
                    {
                        // If any of the solid is of the type of Clipping or Boolean and export is for Reference View, exit the loop and collect the geometries entirely
                        //   for TriangulatedFaceSet
                        if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && (hasClippingResult || hasBooleanResult))
                        {
                            mustUseTessellation = true;
                            break;
                        }

                        materialIds.Add(materialId);
                        IFCAnyHandle repHandle = currRetVal.Handle;
                        if (hasBooleanResult) // if both have boolean and clipping result, use boolean one.
                            extrusionBooleanBodyItems.Add(repHandle);
                        else if (hasClippingResult)
                            extrusionClippingBodyItems.Add(repHandle);
                        else
                            extrusionBodyItems.Add(repHandle);
                    }
                    else
                    {
                        tr.RollBack();

                        // TODO: include this cleanup in RollBack(), to avoid issues.
                        ExporterCacheManager.MaterialIdToStyleHandleCache.RemoveInvalidHandles(materialIds, IFCEntityType.IfcSurfaceStyle);
                        ExporterCacheManager.PresentationStyleAssignmentCache.RemoveInvalidHandles(materialIds);
                        return retVal;
                    }

                    // currRetVal will only have one extrusion.  Use the analyzer from the "last" extrusion.  Should only really be used for one extrusion.
                    retVal.Analyzer = currRetVal.Analyzer;
                    retVal.BaseExtrusions.Add(currRetVal.BaseExtrusions[0]);
                }

                IFCAnyHandle contextOfItemsBody = exporterIFC.Get3DContextHandle("Body");

                // Handle Tessellation here for Reference View export. If all are extrusions, it should not get in here
                if (mustUseTessellation)
                {
                    BodyExporterOptions options = new BodyExporterOptions(true);
                    Document document = element.Document;
                    ElementId materialId = ElementId.InvalidElementId;
                    materialIds.Clear();
                    extrusionBodyItems.Clear();

                    foreach (Solid solid in solids)
                    {
                        IFCAnyHandle triangulatedBodyItem = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, element, options, solid);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedBodyItem))
                            extrusionBodyItems.Add(triangulatedBodyItem);
                        materialId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(solid, exporterIFC, element);
                        materialIds.Add(materialId);
                        BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, triangulatedBodyItem, materialId);
                    }
                    retVal.Handle = RepresentationUtil.CreateTessellatedRep(exporterIFC, element, catId, contextOfItemsBody, extrusionBodyItems, null);
                    retVal.ShapeRepresentationType = ShapeRepresentationType.Tessellation;
                }
                else
                {
                    if (extrusionBodyItems.Count > 0 && (extrusionClippingBodyItems.Count == 0 && extrusionBooleanBodyItems.Count == 0))
                    {
                        retVal.Handle = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, contextOfItemsBody,
                            extrusionBodyItems, null);
                        retVal.ShapeRepresentationType = ShapeRepresentationType.SweptSolid;
                    }
                    else if (extrusionClippingBodyItems.Count > 0 && (extrusionBodyItems.Count == 0 && extrusionBooleanBodyItems.Count == 0))
                    {
                        retVal.Handle = RepresentationUtil.CreateClippingRep(exporterIFC, element, catId, contextOfItemsBody,
                            extrusionClippingBodyItems);
                        retVal.ShapeRepresentationType = ShapeRepresentationType.Clipping;
                    }
                    else if (extrusionBooleanBodyItems.Count > 0 && (extrusionBodyItems.Count == 0 && extrusionClippingBodyItems.Count == 0))
                    {
                        retVal.Handle = RepresentationUtil.CreateCSGRep(exporterIFC, element, catId, contextOfItemsBody,
                            extrusionBooleanBodyItems);
                        retVal.ShapeRepresentationType = ShapeRepresentationType.CSG;
                    }
                    else
                    {
                        IFCAnyHandle finalBodyItemHnd = null;

                        ICollection<IFCAnyHandle> booleanBodyItems = extrusionClippingBodyItems.Union<IFCAnyHandle>(extrusionBooleanBodyItems).ToList();

                        finalBodyItemHnd = booleanBodyItems.ElementAt(0);
                        booleanBodyItems.Remove(finalBodyItemHnd);

                        // union non-boolean result first with a boolean result
                        foreach (IFCAnyHandle bodyRep in extrusionBodyItems)
                        {
                            finalBodyItemHnd = IFCInstanceExporter.CreateBooleanResult(exporterIFC.GetFile(), IFCBooleanOperator.Union,
                                 finalBodyItemHnd, bodyRep);
                        }

                        foreach (IFCAnyHandle bodyRep in booleanBodyItems)
                        {
                            finalBodyItemHnd = IFCInstanceExporter.CreateBooleanResult(exporterIFC.GetFile(), IFCBooleanOperator.Union,
                                 finalBodyItemHnd, bodyRep);
                        }

                        extrusionBodyItems.Clear();
                        extrusionBodyItems.Add(finalBodyItemHnd);

                        retVal.Handle = RepresentationUtil.CreateCSGRep(exporterIFC, element, catId, contextOfItemsBody,
                            extrusionBodyItems);
                        retVal.ShapeRepresentationType = ShapeRepresentationType.CSG;
                    }
                }

                tr.Commit();
                return retVal;
            }
        }
Ejemplo n.º 57
0
        /// <summary>
        /// Exports a Rebar to IFC ReinforcingMesh.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="element">
        /// The element to be exported.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        public static void ExportRebar(ExporterIFC exporterIFC,
            Element element, Autodesk.Revit.DB.View filterView, ProductWrapper productWrapper)
        {
            try
            {
                IFCFile file = exporterIFC.GetFile();

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

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

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

                        IFCAnyHandle prodRep = null;

                        double scale = exporterIFC.LinearScale;

                        double totalBarLengthUnscale = GetRebarTotalLength(element);
                        double volumeUnscale = GetRebarVolume(element);
                        double totalBarLength = totalBarLengthUnscale * scale;

                        if (MathUtil.IsAlmostZero(totalBarLength))
                            return;

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

                        IList<Curve> baseCurves = GetRebarCenterlineCurves(element, true, false, false);
                        int numberOfBarPositions = GetNumberOfBarPositions(element);
                        for (int i = 0; i < numberOfBarPositions; i++)
                        {
                            if (!DoesBarExistAtPosition(element, i))
                                continue;

                            Transform barTrf = GetBarPositionTransform(element, i);

                            IList<Curve> curves = new List<Curve>();
                            foreach (Curve baseCurve in baseCurves)
                            {
                                curves.Add(baseCurve.get_Transformed(barTrf));
                            }

                            IFCAnyHandle compositeCurve = GeometryUtil.CreateCompositeCurve(exporterIFC, curves);
                            IFCAnyHandle sweptDiskSolid = IFCInstanceExporter.CreateSweptDiskSolid(file, compositeCurve, radius, null, 0, 1);
                            HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();
                            bodyItems.Add(sweptDiskSolid);
                            ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);
                            IFCAnyHandle shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, categoryId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null);
                            IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>();
                            shapeReps.Add(shapeRep);
                            prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);

                            string steelGradeOpt = null;
                            IFCAnyHandle elemHnd = null;

                            string rebarGUID = GUIDUtil.CreateGUID(element);
                            string rebarName = NamingUtil.GetIFCName(element);
                            string rebarDescription = NamingUtil.GetDescriptionOverride(element, null);
                            string rebarObjectType = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element));
                            string rebarElemId = NamingUtil.CreateIFCElementId(element);

                            IFCReinforcingBarRole role = IFCReinforcingBarRole.NotDefined;
                            elemHnd = IFCInstanceExporter.CreateReinforcingBar(file, rebarGUID, exporterIFC.GetOwnerHistoryHandle(),
                                rebarName, rebarDescription, rebarObjectType, setter.GetPlacement(),
                                prodRep, rebarElemId, steelGradeOpt, longitudinalBarNominalDiameter, longitudinalBarCrossSectionArea,
                                barLength, role, null);

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

                            PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper);
                        }
                    }
                    transaction.Commit();
                }

            }
            catch (Exception)
            {
                // It will throw exception at GetBarPositionTransform when exporting rebars with Revit 2013 UR1 and before versions, so we skip the export.
                // It should not come here and will export the rebars properly at Revit later versions.
            }
        }
Ejemplo n.º 58
0
        /// <summary>
        ///  Exports a roof as a container of multiple roof slabs.  Returns the handle, if successful.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="ifcEnumType">The roof type.</param>
        /// <param name="element">The roof element.</param>
        /// <param name="geometry">The geometry of the element.</param>
        /// <param name="productWrapper">The product wrapper.</param>
        /// <returns>The roof handle.</returns>
        public static IFCAnyHandle ExportRoofAsContainer(ExporterIFC exporterIFC, string ifcEnumType, Element element, GeometryElement geometry, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

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

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

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

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

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

                                IFCAnyHandle prodRepHnd = null;

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

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

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

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

                                ElementId catId = CategoryUtil.GetSafeCategoryId(element);

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

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

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

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

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

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

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

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

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

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

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

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

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

                                transaction.Commit();
                                return(roofHandle);
                            }
                        }
                    }
                    finally
                    {
                        exporterIFC.ClearFaceWithElementHandleMap();
                    }
                }
            }
        }