// At the moment, the expected input for this function is either an IfcProduct or // an IfcProductDefinitionShape. We register IfcRepresentations inside IfcProductDefinitionShapes. private static void PotentiallyFixPresentationLayerAssignment(Element element, ICollection <IFCAnyHandle> entityHandles) { // Not supported for IFC2x2. Avoid computations below. if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { return; } // We may have a situation where we have a presentation layer override, but the native code doesn't // have that functionality. In this case, we will create an entry here, and reconcile the difference // during the end export operation. string ifcCADLayerOverride = RepresentationUtil.GetPresentationLayerOverride(element); if (string.IsNullOrWhiteSpace(ifcCADLayerOverride)) { return; } foreach (IFCAnyHandle entityHandle in entityHandles) { IList <IFCAnyHandle> representations = null; if (IFCAnyHandleUtil.IsSubTypeOf(entityHandle, IFCEntityType.IfcProduct)) { representations = IFCAnyHandleUtil.GetProductRepresentations(entityHandle); } else if (IFCAnyHandleUtil.IsSubTypeOf(entityHandle, IFCEntityType.IfcProductDefinitionShape)) { representations = IFCAnyHandleUtil.GetRepresentations(entityHandle); } // Not currently supported. if (representations == null) { continue; } foreach (IFCAnyHandle representation in representations) { ExporterCacheManager.PresentationLayerSetCache.AddRepresentationToLayer(ifcCADLayerOverride, representation); } } }
/// <summary> /// Exports curtain object as container. /// </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="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportCurtainObjectCommonAsContainer(ICollection <ElementId> allSubElements, Element wallElement, ExporterIFC exporterIFC, ProductWrapper origWrapper, PlacementSetter currSetter) { if (wallElement == null) { return; } string overrideCADLayer = RepresentationUtil.GetPresentationLayerOverride(wallElement); using (ExporterStateManager.CADLayerOverrideSetter layerSetter = new ExporterStateManager.CADLayerOverrideSetter(overrideCADLayer)) { HashSet <ElementId> alreadyVisited = new HashSet <ElementId>(); // just in case. Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions(); { foreach (ElementId subElemId in allSubElements) { using (ProductWrapper productWrapper = ProductWrapper.Create(origWrapper)) { Element subElem = wallElement.Document.GetElement(subElemId); if (subElem == null) { continue; } if (alreadyVisited.Contains(subElem.Id)) { continue; } alreadyVisited.Add(subElem.Id); // Respect element visibility settings. if (!ElementFilteringUtil.CanExportElement(exporterIFC, subElem, false) || !ElementFilteringUtil.IsElementVisible(subElem)) { continue; } GeometryElement geomElem = subElem.get_Geometry(geomOptions); if (geomElem == null) { continue; } try { if (subElem is FamilyInstance) { string ifcEnumType; IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, subElem, out ifcEnumType); if (subElem is Mullion) { if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { ProxyElementExporter.Export(exporterIFC, subElem, geomElem, productWrapper, exportType); } else { IFCAnyHandle currLocalPlacement = currSetter.LocalPlacement; if (exportType.ExportInstance == IFCEntityType.IfcCurtainWall) { // By default, panels and mullions are set to the same category as their parent. In this case, // ask to get the exportType from the category id, since we don't want to inherit the parent class. ifcEnumType = "MULLION"; exportType.SetValueWithPair(IFCEntityType.IfcMemberType, ifcEnumType); } FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem(exporterIFC, subElem as Mullion, exportType, exportType.ValidatedPredefinedType, productWrapper, ElementId.InvalidElementId, null, currLocalPlacement); } } else { FamilyInstance subFamInst = subElem as FamilyInstance; if (exportType.ExportInstance == IFCEntityType.IfcCurtainWall) { // By default, panels and mullions are set to the same category as their parent. In this case, // ask to get the exportType from the category id, since we don't want to inherit the parent class. ElementId catId = CategoryUtil.GetSafeCategoryId(subElem); exportType = ElementFilteringUtil.GetExportTypeFromCategoryId(catId, out ifcEnumType); } if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { if ((exportType.ExportInstance == IFCEntityType.UnKnown) || (exportType.ExportInstance == IFCEntityType.IfcPlate) || (exportType.ExportInstance == IFCEntityType.IfcMember)) { exportType.SetValueWithPair(IFCEntityType.IfcBuildingElementProxy, ifcEnumType); } } else { if (exportType.ExportInstance == IFCEntityType.UnKnown) { ifcEnumType = "CURTAIN_PANEL"; exportType.SetValueWithPair(IFCEntityType.IfcPlateType, ifcEnumType); } } IFCAnyHandle currLocalPlacement = currSetter.LocalPlacement; using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData()) { FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem(exporterIFC, subFamInst, exportType, ifcEnumType, productWrapper, ElementId.InvalidElementId, null, currLocalPlacement); } } } else if (subElem is CurtainGridLine) { ProxyElementExporter.Export(exporterIFC, subElem, geomElem, productWrapper); } else if (subElem is Wall) { WallExporter.ExportWall(exporterIFC, null, subElem, null, geomElem, productWrapper); } } catch (Exception ex) { if (ExporterUtil.IsFatalException(wallElement.Document, ex)) { throw ex; } continue; } } } } } }
/// <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)) { gridRepresentationData.m_IFCCADLayer = RepresentationUtil.GetPresentationLayerOverride(grid); } // 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); }
// Augment the information from the internally created handles. This includes: // 1. Adding material information // 2. Patching the presentation layer assignment. private static void AugmentHandleInformation(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ICollection <IFCAnyHandle> entityHandles) { // Not supported for IFC2x2. Avoid computations below. if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { return; } ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, element); bool fixMaterialId = matId != ElementId.InvalidElementId; // We may have a situation where we have a presentation layer override, but the native code // doesn't have that functionality. In this case, we will create an entry here, and // reconcile the difference during the end export operation. string ifcCADLayerOverride = RepresentationUtil.GetPresentationLayerOverride(element); bool fixIfcCADLayerOverride = !string.IsNullOrWhiteSpace(ifcCADLayerOverride); if (!fixIfcCADLayerOverride && !fixMaterialId) { return; } Document document = element.Document; foreach (IFCAnyHandle entityHandle in entityHandles) { IList <IFCAnyHandle> representations = null; if (IFCAnyHandleUtil.IsSubTypeOf(entityHandle, IFCEntityType.IfcProduct)) { representations = IFCAnyHandleUtil.GetProductRepresentations(entityHandle); } else if (IFCAnyHandleUtil.IsSubTypeOf(entityHandle, IFCEntityType.IfcProductDefinitionShape)) { representations = IFCAnyHandleUtil.GetRepresentations(entityHandle); } // Not currently supported. if (representations == null) { continue; } foreach (IFCAnyHandle representation in representations) { if (fixIfcCADLayerOverride) { ExporterCacheManager.PresentationLayerSetCache.AddRepresentationToLayer(ifcCADLayerOverride, representation); } if (fixMaterialId) { HashSet <IFCAnyHandle> repItemSet = IFCAnyHandleUtil.GetAggregateInstanceAttribute <HashSet <IFCAnyHandle> >(representation, "Items"); foreach (IFCAnyHandle repItem in repItemSet) { BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, false, repItem, matId); } } } } }