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