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

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

            IFCGeometryInfo info = IFCGeometryInfo.CreateFaceGeometryInfo(eps);

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

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

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

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


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

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

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

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

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

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

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

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

            shapeReps.Add(shapeRep);

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

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

            prodDefRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
            return(prodDefRep);
        }
Ejemplo n.º 2
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);
                //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);
        }