/// <summary> /// Create the "Body" IfcRepresentation for a beam if it is representable by an extrusion, possibly with clippings and openings. /// </summary> /// <param name="exporterIFC">The exporterIFC class.</param> /// <param name="element">The beam element.T</param> /// <param name="catId">The category id.</param> /// <param name="geomObjects">The list of solids and meshes representing the beam's geometry. /// <param name="axisInfo">The beam axis information.</param> /// <returns>The BeamBodyAsExtrusionInfo class which contains the created handle (if any) and other information, or null.</returns> private static BeamBodyAsExtrusionInfo CreateBeamGeometryAsExtrusion(ExporterIFC exporterIFC, Element element, ElementId catId, IList <GeometryObject> geomObjects, BeamAxisInfo axisInfo) { // 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 (geomObjects == null || geomObjects.Count != 1 || (!(geomObjects[0] is Solid)) || axisInfo == null || !(axisInfo.Axis is Line)) { return(null); } BeamBodyAsExtrusionInfo info = new BeamBodyAsExtrusionInfo(); info.DontExport = false; info.Materials = new HashSet <ElementId>(); info.Slope = 0.0; Transform orientTrf = axisInfo.LCSAsTransform; Solid solid = geomObjects[0] as Solid; bool completelyClipped; XYZ beamDirection = orientTrf.BasisX; XYZ planeXVec = orientTrf.BasisY.Normalize(); XYZ planeYVec = orientTrf.BasisZ.Normalize(); MaterialAndProfile materialAndProfile = null; FootPrintInfo footPrintInfo = null; Plane beamExtrusionBasePlane = GeometryUtil.CreatePlaneByXYVectorsAtOrigin(planeXVec, planeYVec); info.RepresentationHandle = ExtrusionExporter.CreateExtrusionWithClipping(exporterIFC, element, catId, solid, beamExtrusionBasePlane, orientTrf.Origin, beamDirection, null, out completelyClipped, out footPrintInfo, out materialAndProfile, addInfo: GenerateAdditionalInfo.GenerateProfileDef); if (completelyClipped) { info.DontExport = true; return(null); } if (!IFCAnyHandleUtil.IsNullOrHasNoValue(info.RepresentationHandle)) { // 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; info.Slope = GeometryUtil.GetSimpleExtrusionSlope(beamDirection, bestAxis); ElementId materialId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(solid, exporterIFC, element); if (materialId != ElementId.InvalidElementId) { info.Materials.Add(materialId); } } if (materialAndProfile != null) { info.materialAndProfile = materialAndProfile; } return(info); }
/// <summary> /// Creates a SweptSolidExporter. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="element">The element.</param> /// <param name="solid">The solid.</param> /// <param name="normal">The normal of the plane that the path lies on.</param> /// <returns>The SweptSolidExporter.</returns> public static SweptSolidExporter Create(ExporterIFC exporterIFC, Element element, SimpleSweptSolidAnalyzer sweptAnalyzer, GeometryObject geomObject, GenerateAdditionalInfo addInfo = GenerateAdditionalInfo.None) { try { if (sweptAnalyzer == null) { return(null); } SweptSolidExporter sweptSolidExporter = null; IList <Revit.IFC.Export.Utility.GeometryUtil.FaceBoundaryType> faceBoundaryTypes; IList <CurveLoop> faceBoundaries = GeometryUtil.GetFaceBoundaries(sweptAnalyzer.ProfileFace, null, out faceBoundaryTypes); string profileName = null; if (element != null) { ElementType type = element.Document.GetElement(element.GetTypeId()) as ElementType; if (type != null) { profileName = type.Name; } } // Is it really an extrusion? if (sweptAnalyzer.PathCurve is Line) { Line line = sweptAnalyzer.PathCurve as Line; // invalid case if (MathUtil.VectorsAreOrthogonal(line.Direction, sweptAnalyzer.ProfileFace.FaceNormal)) { return(null); } sweptSolidExporter = new SweptSolidExporter(); sweptSolidExporter.RepresentationType = ShapeRepresentationType.SweptSolid; Transform lcs = GeometryUtil.CreateTransformFromPlanarFace(sweptAnalyzer.ProfileFace); sweptSolidExporter.RepresentationItem = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, profileName, faceBoundaries, lcs, line.Direction, UnitUtil.ScaleLength(line.Length), false); if ((addInfo & GenerateAdditionalInfo.GenerateFootprint) != 0) { FootPrintInfo fInfo = new FootPrintInfo(); fInfo.LCSTransformUsed = lcs; fInfo.FootPrintHandle = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, faceBoundaries[0], lcs, line.Direction); sweptSolidExporter.FootprintInfo = fInfo; } } else { sweptSolidExporter = new SweptSolidExporter(); if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { // Use tessellated geometry in IFC Reference View if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView || ExporterCacheManager.ExportOptionsCache.ExportAs4General) { // TODO: Create CreateSimpleSweptSolidAsTessellation routine that takes advantage of the superior tessellation of this class. BodyExporterOptions options = new BodyExporterOptions(false, ExportOptionsCache.ExportTessellationLevel.ExtraLow); sweptSolidExporter.RepresentationItem = BodyExporter.ExportBodyAsTessellatedFaceSet(exporterIFC, element, options, geomObject)[0]; sweptSolidExporter.RepresentationType = ShapeRepresentationType.Tessellation; } else { sweptSolidExporter.RepresentationItem = CreateSimpleSweptSolid(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve); sweptSolidExporter.RepresentationType = ShapeRepresentationType.AdvancedSweptSolid; if ((addInfo & GenerateAdditionalInfo.GenerateFootprint) != 0) { FootPrintInfo fInfo = new FootPrintInfo(); Transform lcs = GeometryUtil.CreateTransformFromPlanarFace(sweptAnalyzer.ProfileFace); fInfo.LCSTransformUsed = lcs; fInfo.FootPrintHandle = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, faceBoundaries[0], lcs, sweptAnalyzer.ReferencePlaneNormal); sweptSolidExporter.FootprintInfo = fInfo; } } } else { sweptSolidExporter.Facets = CreateSimpleSweptSolidAsBRep(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve); sweptSolidExporter.RepresentationType = ShapeRepresentationType.Brep; } } return(sweptSolidExporter); } catch (Exception) { return(null); } }