/// <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> /// <param name="elevation">The optional level elevation.</param> /// <returns>The handle, or null if not created.</returns> private static IFCAnyHandle CreateBeamAxis(ExporterIFC exporterIFC, Element element, ElementId catId, BeamAxisInfo axisInfo, Transform offsetTransform, double elevation) { 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 = -(offsetTransform.Origin); curveOffset -= new XYZ(0, 0, elevation); } 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); }
/// <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; 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; IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, offsetLCS, 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); }
/// <summary> /// Get the handles of Grid Axes. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="sameDirectionAxes">The grid axes in the same direction of one level.</param> /// <param name="representations">The representation of grid axis.</param> /// <returns>The list of handles of grid axes.</returns> private static List <IFCAnyHandle> CreateIFCGridAxisAndRepresentations(ExporterIFC exporterIFC, ProductWrapper productWrapper, IList <Grid> sameDirectionAxes, IList <IFCAnyHandle> representations, GridRepresentationData gridRepresentationData) { if (sameDirectionAxes.Count == 0) { return(null); } IDictionary <ElementId, List <IFCAnyHandle> > gridAxisMap = new Dictionary <ElementId, List <IFCAnyHandle> >(); IDictionary <ElementId, List <IFCAnyHandle> > gridRepMap = new Dictionary <ElementId, List <IFCAnyHandle> >(); IFCFile ifcFile = exporterIFC.GetFile(); Grid baseGrid = sameDirectionAxes[0]; Transform lcs = Transform.Identity; List <IFCAnyHandle> ifcGridAxes = new List <IFCAnyHandle>(); foreach (Grid grid in sameDirectionAxes) { // Because the IfcGrid is a collection of Revit Grids, any one of them can override the IFC CAD Layer. // We will take the first name, and not do too much checking. if (string.IsNullOrWhiteSpace(gridRepresentationData.m_IFCCADLayer)) { ParameterUtil.GetStringValueFromElementOrSymbol(grid, "IFCCadLayer", out gridRepresentationData.m_IFCCADLayer); } // Get the handle of curve. XYZ projectionDirection = lcs.BasisZ; IFCAnyHandle axisCurve; if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { axisCurve = GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, grid.Curve, lcs, projectionDirection); } else { IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, lcs, projectionDirection, false); ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, grid.Curve, XYZ.Zero, false); IList <IFCAnyHandle> curves = info.GetCurves(); if (curves.Count != 1) { throw new Exception("IFC: expected 1 curve when export curve element."); } axisCurve = curves[0]; } bool sameSense = true; if (baseGrid.Curve is Line) { Line baseLine = baseGrid.Curve as Line; Line axisLine = grid.Curve as Line; sameSense = (axisLine.Direction.IsAlmostEqualTo(baseLine.Direction)); } IFCAnyHandle ifcGridAxis = IFCInstanceExporter.CreateGridAxis(ifcFile, grid.Name, axisCurve, sameSense); ifcGridAxes.Add(ifcGridAxis); HashSet <IFCAnyHandle> AxisCurves = new HashSet <IFCAnyHandle>(); AxisCurves.Add(axisCurve); IFCAnyHandle repItemHnd = IFCInstanceExporter.CreateGeometricCurveSet(ifcFile, AxisCurves); // get the weight and color from the GridType to create the curve style. GridType gridType = grid.Document.GetElement(grid.GetTypeId()) as GridType; IFCData curveWidth = null; if (ExporterCacheManager.ExportOptionsCache.ExportAnnotations) { int outWidth; double width = (ParameterUtil.GetIntValueFromElement(gridType, BuiltInParameter.GRID_END_SEGMENT_WEIGHT, out outWidth) != null) ? outWidth : 1; curveWidth = IFCDataUtil.CreateAsPositiveLengthMeasure(width); } if (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { int outColor; int color = (ParameterUtil.GetIntValueFromElement(gridType, BuiltInParameter.GRID_END_SEGMENT_COLOR, out outColor) != null) ? outColor : 0; double blueVal = 0.0; double greenVal = 0.0; double redVal = 0.0; GeometryUtil.GetRGBFromIntValue(color, out blueVal, out greenVal, out redVal); IFCAnyHandle colorHnd = IFCInstanceExporter.CreateColourRgb(ifcFile, null, redVal, greenVal, blueVal); BodyExporter.CreateCurveStyleForRepItem(exporterIFC, repItemHnd, curveWidth, colorHnd); } HashSet <IFCAnyHandle> curveSet = new HashSet <IFCAnyHandle>(); curveSet.Add(repItemHnd); gridRepresentationData.m_Grids.Add(grid); gridRepresentationData.m_curveSets.Add(curveSet); } return(ifcGridAxes); }
/// <summary> /// Exports a curve element to IFC curve annotation. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="curveElement"> /// The curve element to be exported. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportCurveElement(ExporterIFC exporterIFC, CurveElement curveElement, GeometryElement geometryElement, ProductWrapper productWrapper) { if (geometryElement == null || !ShouldCurveElementBeExported(curveElement)) { return; } SketchPlane sketchPlane = curveElement.SketchPlane; if (sketchPlane == 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.IfcAnnotation; if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, curveElement)) { IFCAnyHandle localPlacement = setter.LocalPlacement; IFCAnyHandle axisPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement); Plane planeSK = sketchPlane.GetPlane(); XYZ projDir = planeSK.Normal; XYZ origin = planeSK.Origin; bool useOffsetTrf = false; if (projDir.IsAlmostEqualTo(XYZ.BasisZ)) { XYZ offset = XYZ.BasisZ * setter.Offset; origin -= offset; } else { useOffsetTrf = true; } Transform curveLCS = GeometryUtil.CreateTransformFromPlane(planeSK); curveLCS.Origin = origin; IList <IFCAnyHandle> curves = null; if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { Transform trf = null; if (useOffsetTrf) { XYZ offsetOrig = -XYZ.BasisZ * setter.Offset; trf = Transform.CreateTranslation(offsetOrig); } curves = new List <IFCAnyHandle>(); //Curve curve = (geometryElement as GeometryObject) as Curve; List <Curve> curvesFromGeomElem = GeometryUtil.GetCurvesFromGeometryElement(geometryElement); foreach (Curve curve in curvesFromGeomElem) { IFCAnyHandle curveHnd = GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, curve, trf); //IList<int> segmentIndex = null; //IList<IList<double>> pointList = GeometryUtil.PointListFromCurve(exporterIFC, curve, trf, 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 curveHnd = IFCInstanceExporter.CreateIndexedPolyCurve(file, pointListHnd, segmentIndexList, false); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveHnd)) { curves.Add(curveHnd); } } } else { IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, curveLCS, projDir, false); if (useOffsetTrf) { XYZ offsetOrig = -XYZ.BasisZ * setter.Offset; Transform trf = Transform.CreateTranslation(offsetOrig); ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false, trf); } else { ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false); } curves = info.GetCurves(); } if (curves.Count != 1) { throw new Exception("IFC: expected 1 curve when export curve element."); } HashSet <IFCAnyHandle> curveSet = new HashSet <IFCAnyHandle>(curves); IFCAnyHandle repItemHnd = IFCInstanceExporter.CreateGeometricCurveSet(file, curveSet); IFCAnyHandle curveStyle = file.CreateStyle(exporterIFC, repItemHnd); CurveAnnotationCache annotationCache = ExporterCacheManager.CurveAnnotationCache; IFCAnyHandle curveAnno = annotationCache.GetAnnotation(sketchPlane.Id, curveStyle); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveAnno)) { AddCurvesToAnnotation(curveAnno, curves); } else { curveAnno = CreateCurveAnnotation(exporterIFC, curveElement, curveElement.Category.Id, sketchPlane.Id, curveLCS, curveStyle, setter, localPlacement, repItemHnd); productWrapper.AddAnnotation(curveAnno, setter.LevelInfo, true); annotationCache.AddAnnotation(sketchPlane.Id, curveStyle, curveAnno); } } transaction.Commit(); } }
/// <summary> /// Exports a curve element to IFC curve annotation. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="curveElement"> /// The curve element to be exported. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The IFCProductWrapper. /// </param> public static void ExportCurveElement(ExporterIFC exporterIFC, CurveElement curveElement, GeometryElement geometryElement, IFCProductWrapper productWrapper) { if (geometryElement == null || !ShouldCurveElementBeExported(curveElement)) { return; } SketchPlane sketchPlane = curveElement.SketchPlane; if (sketchPlane == null) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, curveElement)) { IFCAnyHandle localPlacement = setter.GetPlacement(); IFCAnyHandle axisPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement); Plane planeSK = sketchPlane.Plane; XYZ projDir = planeSK.Normal; XYZ origin = planeSK.Origin; bool useOffsetTrf = false; if (projDir.IsAlmostEqualTo(XYZ.BasisZ)) { XYZ offset = XYZ.BasisZ * setter.Offset; origin -= offset; } else { useOffsetTrf = true; } Plane plane = new Plane(planeSK.XVec, planeSK.YVec, origin); IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, plane, projDir, false); if (useOffsetTrf) { XYZ offsetOrig = -XYZ.BasisZ * setter.Offset; Transform trf = Transform.get_Translation(offsetOrig); ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false, trf); } else { ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false); } IList <IFCAnyHandle> curves = info.GetCurves(); if (curves.Count != 1) { throw new Exception("IFC: expected 1 curve when export curve element."); } HashSet <IFCAnyHandle> curveSet = new HashSet <IFCAnyHandle>(curves); IFCAnyHandle repItemHnd = IFCInstanceExporter.CreateGeometricCurveSet(file, curveSet); IFCAnyHandle curveStyle = file.CreateStyle(exporterIFC, repItemHnd); CurveAnnotationCache annotationCache = ExporterCacheManager.CurveAnnotationCache; IFCAnyHandle curveAnno = annotationCache.GetAnnotation(sketchPlane.Id, curveStyle); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveAnno)) { AddCurvesToAnnotation(curveAnno, curves); } else { curveAnno = CreateCurveAnnotation(exporterIFC, curveElement, curveElement.Category.Id, sketchPlane.Id, plane, curveStyle, setter, localPlacement, repItemHnd); productWrapper.AddAnnotation(curveAnno, setter.GetLevelInfo(), true); annotationCache.AddAnnotation(sketchPlane.Id, curveStyle, curveAnno); } } transaction.Commit(); } }
/// <summary> /// Exports a beam to IFC beam. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="element"> /// The element to be exported. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportBeam(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { if (geometryElement == null) { return; } IFCFile file = exporterIFC.GetFile(); double scale = exporterIFC.LinearScale; 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.get_EndPoint(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 (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element, null, canExportAxis ? orientTrf : null, ExporterUtil.GetBaseLevelIdForElement(element))) { IFCAnyHandle localPlacement = setter.GetPlacement(); 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 = -offsetTransform.Origin / scale; } 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)); IFCAnyHandle beam = IFCInstanceExporter.CreateBeam(file, instanceGUID, exporterIFC.GetOwnerHistoryHandle(), instanceName, instanceDescription, instanceObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, instanceTag); 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); 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(); } }
/// <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 curve element to IFC curve annotation. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="curveElement"> /// The curve element to be exported. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportCurveElement(ExporterIFC exporterIFC, CurveElement curveElement, GeometryElement geometryElement, ProductWrapper productWrapper) { if (geometryElement == null || !ShouldCurveElementBeExported(curveElement)) { return; } SketchPlane sketchPlane = curveElement.SketchPlane; if (sketchPlane == 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>("IfcAnnotation", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, curveElement)) { IFCAnyHandle localPlacement = setter.LocalPlacement; IFCAnyHandle axisPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement); Plane planeSK = sketchPlane.GetPlane(); XYZ projDir = planeSK.Normal; XYZ origin = planeSK.Origin; bool useOffsetTrf = false; if (projDir.IsAlmostEqualTo(XYZ.BasisZ)) { XYZ offset = XYZ.BasisZ * setter.Offset; origin -= offset; } else { useOffsetTrf = true; } Transform curveLCS = GeometryUtil.CreateTransformFromPlane(planeSK); curveLCS.Origin = origin; IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, curveLCS, projDir, false); if (useOffsetTrf) { XYZ offsetOrig = -XYZ.BasisZ * setter.Offset; Transform trf = Transform.CreateTranslation(offsetOrig); ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false, trf); } else { ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false); } IList <IFCAnyHandle> curves = info.GetCurves(); if (curves.Count != 1) { throw new Exception("IFC: expected 1 curve when export curve element."); } HashSet <IFCAnyHandle> curveSet = new HashSet <IFCAnyHandle>(curves); IFCAnyHandle repItemHnd = IFCInstanceExporter.CreateGeometricCurveSet(file, curveSet); IFCAnyHandle curveStyle = file.CreateStyle(exporterIFC, repItemHnd); CurveAnnotationCache annotationCache = ExporterCacheManager.CurveAnnotationCache; IFCAnyHandle curveAnno = annotationCache.GetAnnotation(sketchPlane.Id, curveStyle); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveAnno)) { AddCurvesToAnnotation(curveAnno, curves); } else { curveAnno = CreateCurveAnnotation(exporterIFC, curveElement, curveElement.Category.Id, sketchPlane.Id, curveLCS, curveStyle, setter, localPlacement, repItemHnd); productWrapper.AddAnnotation(curveAnno, setter.LevelInfo, true); annotationCache.AddAnnotation(sketchPlane.Id, curveStyle, curveAnno); } } transaction.Commit(); } }