/// <summary> /// Export the roof to IfcRoof containing its parts. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The roof element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The IFCProductWrapper.</param> public static void ExportRoofAsParts(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, IFCProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element)) { IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); IFCAnyHandle localPlacement = setter.GetPlacement(); using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { extrusionCreationData.SetLocalPlacement(setter.GetPlacement()); extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryXY; IFCAnyHandle prodRepHnd = null; string elementGUID = ExporterIFCUtils.CreateGUID(element); string origElementName = exporterIFC.GetName(); string elementName = NamingUtil.GetNameOverride(element, origElementName); string elementDescription = NamingUtil.GetDescriptionOverride(element, null); string elementObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string elementId = NamingUtil.CreateIFCElementId(element); //need to convert the string to enum string ifcEnumType = CategoryUtil.GetIFCEnumTypeName(exporterIFC, element); IFCAnyHandle roofHandle = IFCInstanceExporter.CreateRoof(file, elementGUID, ownerHistory, elementName, elementDescription, elementObjectType, localPlacement, prodRepHnd, elementId, GetIFCRoofType(ifcEnumType)); // Export the parts PartExporter.ExportHostPart(exporterIFC, element, roofHandle, productWrapper, setter, localPlacement, null); productWrapper.AddElement(roofHandle, setter, extrusionCreationData, LevelUtil.AssociateElementToLevel(element)); OpeningUtil.CreateOpeningsIfNecessary(roofHandle, element, extrusionCreationData, exporterIFC, extrusionCreationData.GetLocalPlacement(), setter, productWrapper); PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); } transaction.Commit(); } } }
/// <summary> /// Exports a CeilingAndFloor element to IFC. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="floor">The floor element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportCeilingAndFloorElement(ExporterIFC exporterIFC, CeilingAndFloor floorElement, ref GeometryElement geometryElement, ProductWrapper productWrapper) { if (geometryElement == null) { return; } IFCFile file = exporterIFC.GetFile(); string ifcEnumType; IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC, floorElement, out ifcEnumType); if (!ElementFilteringUtil.IsElementVisible(floorElement)) { return; } // Check the intended IFC entity or type name is in the exclude list specified in the UI IFCEntityType elementClassTypeEnum; if (Enum.TryParse(exportType.ExportInstance.ToString(), out elementClassTypeEnum) || Enum.TryParse(exportType.ExportType.ToString(), out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } Document doc = floorElement.Document; using (SubTransaction tempPartTransaction = new SubTransaction(doc)) { MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, floorElement, productWrapper); // For IFC4RV export, Element will be split into its parts(temporarily) in order to export the wall by its parts // If Parts are created by code and not by user then their names should be equal to Material names. bool setMaterialNameToPartName = ExporterUtil.CreateParts(floorElement, layersetInfo.MaterialIds.Count, ref geometryElement); ExporterUtil.ExportPartAs exportPartAs = ExporterUtil.CanExportByComponentsOrParts(floorElement); bool exportByComponents = exportPartAs == ExporterUtil.ExportPartAs.ShapeAspect; bool exportParts = exportPartAs == ExporterUtil.ExportPartAs.Part; if (exportParts && !PartExporter.CanExportElementInPartExport(floorElement, floorElement.LevelId, false)) { return; } using (IFCTransaction tr = new IFCTransaction(file)) { bool canExportAsContainerOrWithExtrusionAnalyzer = (!exportParts && (floorElement is Floor)); if (canExportAsContainerOrWithExtrusionAnalyzer) { // Try to export the Floor slab as a container. If that succeeds, we are done. // If we do export the floor as a container, it will take care of the local placement and transform there, so we need to leave // this out of the IFCTransformSetter and PlacementSetter scopes below, or else we'll get double transforms. IFCAnyHandle floorHnd = RoofExporter.ExportRoofOrFloorAsContainer(exporterIFC, floorElement, geometryElement, productWrapper); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(floorHnd)) { tr.Commit(); return; } } IList <IFCAnyHandle> slabHnds = new List <IFCAnyHandle>(); IList <IFCAnyHandle> brepSlabHnds = new List <IFCAnyHandle>(); IList <IFCAnyHandle> nonBrepSlabHnds = new List <IFCAnyHandle>(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle typeHandle = null; using (IFCTransformSetter transformSetter = IFCTransformSetter.Create()) { // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, floorElement, out overrideContainerHnd); using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, floorElement, null, null, overrideContainerId, overrideContainerHnd)) { IFCAnyHandle localPlacement = placementSetter.LocalPlacement; // The routine ExportExtrudedSlabOpenings is called if exportedAsInternalExtrusion is true, and it requires having a valid level association. // Disable calling ExportSlabAsExtrusion if we can't handle potential openings. bool canExportAsInternalExtrusion = placementSetter.LevelInfo != null && !ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView; bool exportedAsInternalExtrusion = false; ElementId catId = CategoryUtil.GetSafeCategoryId(floorElement); IList <IFCAnyHandle> prodReps = new List <IFCAnyHandle>(); IList <ShapeRepresentationType> repTypes = new List <ShapeRepresentationType>(); IList <IList <CurveLoop> > extrusionLoops = new List <IList <CurveLoop> >(); IList <IFCExtrusionCreationData> loopExtraParams = new List <IFCExtrusionCreationData>(); Plane floorPlane = GeometryUtil.CreateDefaultPlane(); IFCExtrusionCreationData ecData = new IFCExtrusionCreationData(); IList <IFCAnyHandle> localPlacements = new List <IFCAnyHandle>(); if (!exportParts) { if (canExportAsContainerOrWithExtrusionAnalyzer) { Floor floor = floorElement as Floor; // Next, try to use the ExtrusionAnalyzer for the limited cases it handles - 1 solid, no openings, end clippings only. // Also limited to cases with line and arc boundaries. // SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement); IList <Solid> solids = solidMeshInfo.GetSolids(); IList <Mesh> meshes = solidMeshInfo.GetMeshes(); IList <GeometryObject> gObjs = FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(floorElement.Document, exporterIFC, ref solids, ref meshes); if (solids.Count == 1 && meshes.Count == 0) { // floorExtrusionDirection is set to (0, 0, -1) because extrusionAnalyzerFloorPlane is computed from the top face of the floor XYZ floorExtrusionDirection = new XYZ(0, 0, -1); XYZ modelOrigin = XYZ.Zero; XYZ floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top); if (floorOrigin == null) { // GetVerticalProjectionPoint may return null if FloorFace.Top is an edited face that doesn't // go through the Revit model origin. We'll try the midpoint of the bounding box instead. BoundingBoxXYZ boundingBox = floorElement.get_BoundingBox(null); modelOrigin = (boundingBox.Min + boundingBox.Max) / 2.0; floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top); } if (floorOrigin != null) { XYZ floorDir = floor.GetNormalAtVerticalProjectionPoint(floorOrigin, FloorFace.Top); Plane extrusionAnalyzerFloorBasePlane = GeometryUtil.CreatePlaneByNormalAtOrigin(floorDir); GenerateAdditionalInfo additionalInfo = GenerateAdditionalInfo.GenerateBody; additionalInfo |= ExporterCacheManager.ExportOptionsCache.ExportAs4 ? GenerateAdditionalInfo.GenerateFootprint : GenerateAdditionalInfo.None; // Skip generate body item for IFC4RV. It will be handled later in PartExporter.ExportHostPartAsShapeAspects() if (exportByComponents) { additionalInfo &= ~GenerateAdditionalInfo.GenerateBody; } ExtrusionExporter.ExtraClippingData extraClippingData = null; HandleAndData floorAndProperties = ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, floorElement, false, catId, solids[0], extrusionAnalyzerFloorBasePlane, floorOrigin, floorExtrusionDirection, null, out extraClippingData, addInfo: additionalInfo); if (extraClippingData.CompletelyClipped) { return; } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); if (floorAndProperties.Handle != null) { representations.Add(floorAndProperties.Handle); repTypes.Add(ShapeRepresentationType.SweptSolid); } // Footprint representation will only be exported in export to IFC4 if (((additionalInfo & GenerateAdditionalInfo.GenerateFootprint) != 0) && (floorAndProperties.FootprintInfo != null)) { IFCAnyHandle footprintShapeRep = floorAndProperties.FootprintInfo.CreateFootprintShapeRepresentation(exporterIFC); representations.Add(footprintShapeRep); } if (exportByComponents) { IFCAnyHandle prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, floorElement, catId, geometryElement, representations); prodReps.Add(prodRep); } else if (representations.Count > 0 && floorAndProperties.Handle != null) // Only when at least the body rep exists will come here { IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); prodReps.Add(prodRep); } if (floorAndProperties.Data != null) { loopExtraParams.Add(floorAndProperties.Data); } } } } // Use internal routine as backup that handles openings. if (prodReps.Count == 0 && canExportAsInternalExtrusion && !exportByComponents) { exportedAsInternalExtrusion = ExporterIFCUtils.ExportSlabAsExtrusion(exporterIFC, floorElement, geometryElement, transformSetter, localPlacement, out localPlacements, out prodReps, out extrusionLoops, out loopExtraParams, floorPlane); if (exportedAsInternalExtrusion) { AugmentHandleInformation(exporterIFC, floorElement, geometryElement, prodReps); for (int ii = 0; ii < prodReps.Count; ii++) { // all are extrusions repTypes.Add(ShapeRepresentationType.SweptSolid); // Footprint representation will only be exported in export to IFC4 if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { if (extrusionLoops.Count > ii) { if (extrusionLoops[ii].Count > 0) { // Get the extrusion footprint using the first Curveloop. Transform needs to be obtained from the returned local placement Transform lcs = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, localPlacements[ii]); IFCAnyHandle footprintGeomRepItem = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, extrusionLoops[ii][0], lcs, floorPlane.Normal); IFCAnyHandle contextOfItemsFootprint = exporterIFC.Get3DContextHandle("FootPrint"); ISet <IFCAnyHandle> repItem = new HashSet <IFCAnyHandle>(); repItem.Add(footprintGeomRepItem); IFCAnyHandle footprintShapeRepresentation = RepresentationUtil.CreateBaseShapeRepresentation(exporterIFC, contextOfItemsFootprint, "FootPrint", "Curve2D", repItem); IList <IFCAnyHandle> reps = new List <IFCAnyHandle>(); reps.Add(footprintShapeRepresentation); IFCAnyHandleUtil.AddRepresentations(prodReps[ii], reps); } } } } } } IFCAnyHandle prodDefHnd; if (prodReps.Count == 0) { if (exportByComponents) { prodDefHnd = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, floorElement, catId, geometryElement, null); prodReps.Add(prodDefHnd); } else { // Brep representation using tesellation after ExportSlabAsExtrusion does not return prodReps BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium); BodyData bodyData; prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, floorElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd)) { ecData.ClearOpenings(); return; } prodReps.Add(prodDefHnd); repTypes.Add(bodyData.ShapeRepresentationType); } } } // Create the slab from either the extrusion or the BRep information. string ifcGUID = GUIDUtil.CreateGUID(floorElement); int numReps = exportParts ? 1 : prodReps.Count; // Deal with a couple of cases that have non-standard defaults. switch (exportType.ExportInstance) { case IFCEntityType.IfcCovering: exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType <IFCCoveringType>(floorElement, ifcEnumType, "FLOORING"); break; case IFCEntityType.IfcSlab: { bool isBaseSlab = false; AnalyticalToPhysicalAssociationManager manager = AnalyticalToPhysicalAssociationManager.GetAnalyticalToPhysicalAssociationManager(doc); if (manager != null) { ElementId counterPartId = manager.GetAssociatedElementId(floorElement.Id); if (counterPartId != ElementId.InvalidElementId) { Element counterpartElem = doc.GetElement(counterPartId); if (counterpartElem != null && counterpartElem is AnalyticalElement) { AnalyzeAs slabAnalyzeAs = (counterpartElem as AnalyticalElement).AnalyzeAs; isBaseSlab = (slabAnalyzeAs == AnalyzeAs.SlabOnGrade) || (slabAnalyzeAs == AnalyzeAs.Mat); } } } exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(floorElement, ifcEnumType, isBaseSlab ? "BASESLAB" : "FLOOR"); } break; } for (int ii = 0; ii < numReps; ii++) { string ifcName = NamingUtil.GetNameOverride(floorElement, NamingUtil.GetIFCNamePlusIndex(floorElement, ii == 0 ? -1 : ii + 1)); string currentGUID = (ii == 0) ? ifcGUID : GUIDUtil.GenerateIFCGuidFrom(floorElement, "Slab Copy " + ii.ToString()); IFCAnyHandle localPlacementHnd = exportedAsInternalExtrusion ? localPlacements[ii] : localPlacement; IFCAnyHandle slabHnd = null; slabHnd = IFCInstanceExporter.CreateGenericIFCEntity(exportType, exporterIFC, floorElement, currentGUID, ownerHistory, localPlacementHnd, exportParts ? null : prodReps[ii]); if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd)) { return; } if (!string.IsNullOrEmpty(ifcName)) { IFCAnyHandleUtil.OverrideNameAttribute(slabHnd, ifcName); } // Pre IFC4 Slab does not have PredefinedType if (!string.IsNullOrEmpty(exportType.ValidatedPredefinedType) && !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { IFCAnyHandleUtil.SetAttribute(slabHnd, "PredefinedType", exportType.ValidatedPredefinedType, true); } if (exportParts) { PartExporter.ExportHostPart(exporterIFC, floorElement, slabHnd, productWrapper, placementSetter, localPlacementHnd, null, setMaterialNameToPartName); } else if (exportByComponents) { IFCExtrusionCreationData partECData = new IFCExtrusionCreationData(); IFCAnyHandle hostShapeRepFromParts = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, floorElement, prodReps[ii], productWrapper, placementSetter, localPlacement, ElementId.InvalidElementId, layersetInfo, partECData); loopExtraParams.Add(partECData); } slabHnds.Add(slabHnd); // For IFC4RV, export of the geometry is already handled in PartExporter.ExportHostPartAsShapeAspects() if (!exportParts && !exportByComponents) { if (repTypes[ii] == ShapeRepresentationType.Brep || repTypes[ii] == ShapeRepresentationType.Tessellation) { brepSlabHnds.Add(slabHnd); } else { nonBrepSlabHnds.Add(slabHnd); } } OpeningUtil.CreateOpeningsIfNecessary(slabHnd, floorElement, ecData, null, exporterIFC, localPlacement, placementSetter, productWrapper); } typeHandle = ExporterUtil.CreateGenericTypeFromElement(floorElement, exportType, file, ownerHistory, exportType.ValidatedPredefinedType, productWrapper); for (int ii = 0; ii < numReps; ii++) { IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null; productWrapper.AddElement(floorElement, slabHnds[ii], placementSetter, loopExtraParam, true, exportType); ExporterCacheManager.TypeRelationsCache.Add(typeHandle, slabHnds[ii]); ExporterUtil.AddIntoComplexPropertyCache(slabHnds[ii], layersetInfo); } // This call to the native function appears to create Brep opening also when appropriate. But the creation of the IFC instances is not // controllable from the managed code. Therefore in some cases BRep geometry for Opening will still be exported even in the Reference View if (exportedAsInternalExtrusion) { ISet <IFCAnyHandle> oldCreatedObjects = productWrapper.GetAllObjects(); ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, floorElement, placementSetter.LevelInfo, localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative()); ISet <IFCAnyHandle> newCreatedObjects = productWrapper.GetAllObjects(); newCreatedObjects.ExceptWith(oldCreatedObjects); AugmentHandleInformation(exporterIFC, floorElement, geometryElement, newCreatedObjects); } } if (!exportParts) { if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, productWrapper.GetAnElement(), geometryElement, productWrapper, ElementId.InvalidElementId, IFCLayerSetDirection.Axis3, false, typeHandle); } else { if (nonBrepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, nonBrepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, IFCLayerSetDirection.Axis3, false, typeHandle); } if (brepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, brepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, IFCLayerSetDirection.Axis3, true, typeHandle); } } } } tr.Commit(); return; } } }
/// <summary> /// Exports a MEP family instance. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="element"> /// The element. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The IFCProductWrapper. /// </param> public static void Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, IFCProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { string ifcEnumType; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, element, out ifcEnumType); using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element)) { IFCAnyHandle localPlacementToUse = setter.GetPlacement(); using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData()) { ElementId catId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); IFCAnyHandle productRepresentation = RepresentationUtil.CreateBRepProductDefinitionShape(element.Document.Application, exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, extraParams); if (IFCAnyHandleUtil.IsNullOrHasNoValue(productRepresentation)) { extraParams.ClearOpenings(); return; } IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); ElementId typeId = element.GetTypeId(); ElementType type = element.Document.GetElement(typeId) as ElementType; FamilyTypeInfo currentTypeInfo = ExporterCacheManager.TypeObjectsCache.Find(typeId, false); bool found = currentTypeInfo.IsValid(); if (!found) { string typeGUID = ExporterIFCUtils.CreateGUID(type); string origTypeName = exporterIFC.GetName(); string typeName = NamingUtil.GetNameOverride(type, origTypeName); string typeObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, type); string applicableOccurance = NamingUtil.GetObjectTypeOverride(type, typeObjectType); string typeDescription = NamingUtil.GetDescriptionOverride(type, null); string typeElemId = NamingUtil.CreateIFCElementId(type); HashSet <IFCAnyHandle> propertySetsOpt = new HashSet <IFCAnyHandle>(); IList <IFCAnyHandle> repMapListOpt = new List <IFCAnyHandle>(); IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(file, exportType, ifcEnumType, typeGUID, ownerHistory, typeName, typeDescription, applicableOccurance, propertySetsOpt, repMapListOpt, typeElemId, typeName, element, type); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) { currentTypeInfo.Style = styleHandle; ExporterCacheManager.TypeObjectsCache.Register(typeId, false, currentTypeInfo); } } string instanceGUID = ExporterIFCUtils.CreateGUID(element); string origInstanceName = exporterIFC.GetName(); string instanceName = NamingUtil.GetNameOverride(element, origInstanceName); string objectType = NamingUtil.CreateIFCObjectName(exporterIFC, element); string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, objectType); string instanceDescription = NamingUtil.GetDescriptionOverride(element, null); string instanceElemId = NamingUtil.CreateIFCElementId(element); bool roomRelated = !FamilyExporterUtil.IsDistributionFlowElementSubType(exportType); ElementId roomId = ElementId.InvalidElementId; if (roomRelated) { roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse); } IFCAnyHandle instanceHandle = null; if (FamilyExporterUtil.IsFurnishingElementSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFurnishingElement(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsDistributionFlowElementSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateDistributionFlowElement(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsEnergyConversionDeviceSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateEnergyConversionDevice(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowFittingSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowFitting(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowMovingDeviceSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowMovingDevice(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowSegmentSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowSegment(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowStorageDeviceSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowStorageDevice(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowTerminalSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowTerminal(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowTreatmentDeviceSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowTreatmentDevice(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } else if (FamilyExporterUtil.IsFlowControllerSubType(exportType)) { instanceHandle = IFCInstanceExporter.CreateFlowController(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceElemId); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle)) { return; } if (roomId != ElementId.InvalidElementId) { exporterIFC.RelateSpatialElement(roomId, instanceHandle); productWrapper.AddElement(instanceHandle, setter, extraParams, false); } else { productWrapper.AddElement(instanceHandle, setter, extraParams, LevelUtil.AssociateElementToLevel(element)); } OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, element, extraParams, exporterIFC, localPlacementToUse, setter, productWrapper); if (currentTypeInfo.IsValid()) { ExporterCacheManager.TypeRelationsCache.Add(currentTypeInfo.Style, instanceHandle); } PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); ExporterCacheManager.MEPCache.Register(element, instanceHandle); tr.Commit(); } } } }
/// <summary> /// Export the individual part (IfcBuildingElementPart). /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="partElement">The part element to export.</param> /// <param name="geometryElement">The geometry of part.</param> /// <param name="productWrapper">The ProductWrapper object.</param> public static void ExportPart(ExporterIFC exporterIFC, Element partElement, ProductWrapper productWrapper, PlacementSetter placementSetter, IFCAnyHandle originalPlacement, IFCRange range, IFCExtrusionAxes ifcExtrusionAxes, Element hostElement, ElementId overrideLevelId, bool asBuildingElement) { if (!ElementFilteringUtil.IsElementVisible(partElement)) { return; } Part part = partElement as Part; if (part == null) { return; } if (!asBuildingElement) { // 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>("IfcBuildingElementPart", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } } else { string ifcEnumType = null; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType); // 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>(exportType.ToString(), out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } } PlacementSetter standalonePlacementSetter = null; bool standaloneExport = hostElement == null && !asBuildingElement; ElementId partExportLevel = null; if (standaloneExport || asBuildingElement) { partExportLevel = partElement.LevelId; } else { if (part.OriginalCategoryId != hostElement.Category.Id) { return; } partExportLevel = hostElement.LevelId; } if (overrideLevelId != null) { partExportLevel = overrideLevelId; } if (ExporterCacheManager.PartExportedCache.HasExported(partElement.Id, partExportLevel)) { return; } Options options = GeometryUtil.GetIFCExportGeometryOptions(); View ownerView = partElement.Document.GetElement(partElement.OwnerViewId) as View; if (ownerView != null) { options.View = ownerView; } GeometryElement geometryElement = partElement.get_Geometry(options); if (geometryElement == null) { return; } try { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { IFCAnyHandle partPlacement = null; if (standaloneExport || asBuildingElement) { Transform orientationTrf = Transform.Identity; standalonePlacementSetter = PlacementSetter.Create(exporterIFC, partElement, null, orientationTrf, partExportLevel); partPlacement = standalonePlacementSetter.LocalPlacement; } else { partPlacement = ExporterUtil.CreateLocalPlacement(file, originalPlacement, null); } bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End)); SolidMeshGeometryInfo solidMeshInfo; if (validRange) { solidMeshInfo = GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range); if (solidMeshInfo.GetSolids().Count == 0 && solidMeshInfo.GetMeshes().Count == 0) { return; } } else { solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement); } using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { extrusionCreationData.SetLocalPlacement(partPlacement); extrusionCreationData.ReuseLocalPlacement = false; extrusionCreationData.PossibleExtrusionAxes = ifcExtrusionAxes; IList <Solid> solids = solidMeshInfo.GetSolids(); IList <Mesh> meshes = solidMeshInfo.GetMeshes(); ElementId catId = CategoryUtil.GetSafeCategoryId(partElement); ElementId hostCatId = CategoryUtil.GetSafeCategoryId(hostElement); BodyData bodyData = null; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); if (solids.Count > 0 || meshes.Count > 0) { bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, solids, meshes, bodyExporterOptions, extrusionCreationData); } else { IList <GeometryObject> geomlist = new List <GeometryObject>(); geomlist.Add(geometryElement); bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, geomlist, bodyExporterOptions, extrusionCreationData); } IFCAnyHandle bodyRep = bodyData.RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { extrusionCreationData.ClearOpenings(); return; } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(bodyRep); IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); if (boundingBoxRep != null) { representations.Add(boundingBoxRep); } IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string partGUID = GUIDUtil.CreateGUID(partElement); string partName = NamingUtil.GetNameOverride(partElement, NamingUtil.GetIFCName(partElement)); string partDescription = NamingUtil.GetDescriptionOverride(partElement, null); string partObjectType = NamingUtil.GetObjectTypeOverride(partElement, NamingUtil.CreateIFCObjectName(exporterIFC, partElement)); string partTag = NamingUtil.GetTagOverride(partElement, NamingUtil.CreateIFCElementId(partElement)); IFCAnyHandle ifcPart = null; if (!asBuildingElement) { ifcPart = IFCInstanceExporter.CreateBuildingElementPart(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag); } else { string ifcEnumType = null; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType); string defaultValue = null; // This replicates old functionality before IFC4 addition, where the default for slab was "FLOOR". // Really the export layer table should be fixed for this case. if (string.IsNullOrWhiteSpace(ifcEnumType) && hostCatId == new ElementId(BuiltInCategory.OST_Floors)) { ifcEnumType = "FLOOR"; } ifcEnumType = IFCValidateEntry.GetValidIFCType(hostElement, ifcEnumType, defaultValue); switch (exportType) { case IFCExportType.IfcColumnType: ifcPart = IFCInstanceExporter.CreateColumn(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcCovering: ifcPart = IFCInstanceExporter.CreateCovering(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcFooting: ifcPart = IFCInstanceExporter.CreateFooting(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcPile: ifcPart = IFCInstanceExporter.CreatePile(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType, null); break; case IFCExportType.IfcRoof: ifcPart = IFCInstanceExporter.CreateRoof(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcSlab: ifcPart = IFCInstanceExporter.CreateSlab(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcWall: ifcPart = IFCInstanceExporter.CreateWall(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; default: ifcPart = IFCInstanceExporter.CreateBuildingElementProxy(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, null); break; } } bool containedInLevel = (standaloneExport || asBuildingElement); PlacementSetter whichPlacementSetter = containedInLevel ? standalonePlacementSetter : placementSetter; productWrapper.AddElement(partElement, ifcPart, whichPlacementSetter, extrusionCreationData, containedInLevel); OpeningUtil.CreateOpeningsIfNecessary(ifcPart, partElement, extrusionCreationData, bodyData.OffsetTransform, exporterIFC, extrusionCreationData.GetLocalPlacement(), whichPlacementSetter, productWrapper); //Add the exported part to exported cache. TraceExportedParts(partElement, partExportLevel, standaloneExport || asBuildingElement ? ElementId.InvalidElementId : hostElement.Id); CategoryUtil.CreateMaterialAssociation(exporterIFC, ifcPart, bodyData.MaterialIds); transaction.Commit(); } } } finally { if (standalonePlacementSetter != null) { standalonePlacementSetter.Dispose(); } } }
/// <summary> /// Exports a roof or floor as a container of multiple roof slabs. Returns the handle, if successful. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="ifcEnumType">The roof type.</param> /// <param name="element">The roof or floor element.</param> /// <param name="geometry">The geometry of the element.</param> /// <param name="productWrapper">The product wrapper.</param> /// <returns>The roof handle.</returns> /// <remarks>For floors, if there is only one component, return null, as we do not want to create a container.</remarks> public static IFCAnyHandle ExportRoofOrFloorAsContainer(ExporterIFC exporterIFC, string ifcEnumType, Element element, GeometryElement geometry, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); // We support ExtrusionRoofs, FootPrintRoofs, and Floors only. bool elementIsRoof = (element is ExtrusionRoof) || (element is FootPrintRoof); bool elementIsFloor = (element is Floor); if (!elementIsRoof && !elementIsFloor) { return(null); } using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { IFCAnyHandle localPlacement = setter.LocalPlacement; IList <HostObjectSubcomponentInfo> hostObjectSubcomponents = null; try { hostObjectSubcomponents = ExporterIFCUtils.ComputeSubcomponents(element as HostObject); } catch { return(null); } if (hostObjectSubcomponents == null) { return(null); } int numSubcomponents = hostObjectSubcomponents.Count; if (numSubcomponents == 0 || (elementIsFloor && numSubcomponents == 1)) { return(null); } try { using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; extrusionCreationData.SetLocalPlacement(localPlacement); extrusionCreationData.ReuseLocalPlacement = true; using (TransformSetter trfSetter = TransformSetter.Create()) { IList <GeometryObject> geometryList = new List <GeometryObject>(); geometryList.Add(geometry); trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, extrusionCreationData); IFCAnyHandle prodRepHnd = null; string elementGUID = GUIDUtil.CreateGUID(element); string elementName = NamingUtil.GetIFCName(element); string elementDescription = NamingUtil.GetDescriptionOverride(element, null); string elementObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string elementId = NamingUtil.CreateIFCElementId(element); string hostObjectType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType); IFCAnyHandle hostObjectHandle = null; if (elementIsRoof) { hostObjectHandle = IFCInstanceExporter.CreateRoof(file, elementGUID, ownerHistory, elementName, elementDescription, elementObjectType, localPlacement, prodRepHnd, elementId, hostObjectType); } else { hostObjectHandle = IFCInstanceExporter.CreateSlab(file, elementGUID, ownerHistory, elementName, elementDescription, elementObjectType, localPlacement, prodRepHnd, elementId, hostObjectType); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjectHandle)) { return(null); } IList <IFCAnyHandle> elementHandles = new List <IFCAnyHandle>(); elementHandles.Add(hostObjectHandle); // If element is floor, then the profile curve loop of hostObjectSubComponent is computed from the top face of the floor // else if element is roof, then the profile curve loop is taken from the bottom face of the roof instead XYZ extrusionDir = elementIsFloor ? new XYZ(0, 0, -1) : new XYZ(0, 0, 1); ElementId catId = CategoryUtil.GetSafeCategoryId(element); IList <IFCAnyHandle> slabHandles = new List <IFCAnyHandle>(); IList <CurveLoop> hostObjectOpeningLoops = new List <CurveLoop>(); double maximumScaledDepth = 0.0; using (IFCExtrusionCreationData slabExtrusionCreationData = new IFCExtrusionCreationData()) { slabExtrusionCreationData.SetLocalPlacement(extrusionCreationData.GetLocalPlacement()); slabExtrusionCreationData.ReuseLocalPlacement = false; slabExtrusionCreationData.ForceOffset = true; int loopNum = 0; int subElementStart = elementIsRoof ? (int)IFCRoofSubElements.RoofSlabStart : (int)IFCSlabSubElements.SubSlabStart; string subSlabType = elementIsRoof ? "ROOF" : hostObjectType; foreach (HostObjectSubcomponentInfo hostObjectSubcomponent in hostObjectSubcomponents) { trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, slabExtrusionCreationData); Plane plane = hostObjectSubcomponent.GetPlane(); Transform lcs = GeometryUtil.CreateTransformFromPlane(plane); IList <CurveLoop> curveLoops = new List <CurveLoop>(); CurveLoop slabCurveLoop = hostObjectSubcomponent.GetCurveLoop(); curveLoops.Add(slabCurveLoop); double slope = Math.Abs(plane.Normal.Z); double scaledDepth = UnitUtil.ScaleLength(hostObjectSubcomponent.Depth); double scaledExtrusionDepth = scaledDepth * slope; IFCAnyHandle shapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, scaledExtrusionDepth, false); if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep)) { return(null); } ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(element as HostObject); BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, shapeRep, matId); HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); bodyItems.Add(shapeRep); shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null); IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(shapeRep); IFCAnyHandle repHnd = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); // Allow support for up to 256 named IfcSlab components, as defined in IFCSubElementEnums.cs. string slabGUID = (loopNum < 256) ? GUIDUtil.CreateSubElementGUID(element, subElementStart + loopNum) : GUIDUtil.CreateGUID(); IFCAnyHandle slabPlacement = ExporterUtil.CreateLocalPlacement(file, slabExtrusionCreationData.GetLocalPlacement(), null); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, slabGUID, ownerHistory, elementName, elementDescription, elementObjectType, slabPlacement, repHnd, elementId, subSlabType); //slab quantities slabExtrusionCreationData.ScaledLength = scaledExtrusionDepth; slabExtrusionCreationData.ScaledArea = UnitUtil.ScaleArea(UnitUtil.ScaleArea(hostObjectSubcomponent.AreaOfCurveLoop)); slabExtrusionCreationData.ScaledOuterPerimeter = UnitUtil.ScaleLength(curveLoops[0].GetExactLength()); slabExtrusionCreationData.Slope = UnitUtil.ScaleAngle(MathUtil.SafeAcos(Math.Abs(slope))); productWrapper.AddElement(null, slabHnd, setter, slabExtrusionCreationData, false); elementHandles.Add(slabHnd); slabHandles.Add(slabHnd); hostObjectOpeningLoops.Add(slabCurveLoop); maximumScaledDepth = Math.Max(maximumScaledDepth, scaledDepth); loopNum++; } } productWrapper.AddElement(element, hostObjectHandle, setter, extrusionCreationData, true); ExporterUtil.RelateObjects(exporterIFC, null, hostObjectHandle, slabHandles); OpeningUtil.AddOpeningsToElement(exporterIFC, elementHandles, hostObjectOpeningLoops, element, null, maximumScaledDepth, null, setter, localPlacement, productWrapper); transaction.Commit(); return(hostObjectHandle); } } } finally { exporterIFC.ClearFaceWithElementHandleMap(); } } } }
/// <summary> /// Exports an element to IFC footing. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="element"> /// The element. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="ifcEnumType"> /// The string value represents the IFC type. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportFooting(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, string ifcEnumType, ProductWrapper productWrapper) { // export parts or not bool exportParts = PartExporter.CanExportParts(element); if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false)) { 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>("IfcFooting", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(setter.LocalPlacement); IFCAnyHandle prodRep = null; ElementId matId = ElementId.InvalidElementId; if (!exportParts) { ElementId catId = CategoryUtil.GetSafeCategoryId(element); matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, ecData, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) { ecData.ClearOpenings(); return; } } string instanceGUID = GUIDUtil.CreateGUID(element); string footingType = GetIFCFootingType(ifcEnumType); // need to keep it for legacy support when original data follows slightly diff naming footingType = IFCValidateEntry.GetValidIFCType(element, footingType); IFCAnyHandle footing = IFCInstanceExporter.CreateFooting(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, ecData.GetLocalPlacement(), prodRep, footingType); if (exportParts) { PartExporter.ExportHostPart(exporterIFC, element, footing, productWrapper, setter, setter.LocalPlacement, null); } else { if (matId != ElementId.InvalidElementId) { CategoryUtil.CreateMaterialAssociation(exporterIFC, footing, matId); } } productWrapper.AddElement(element, footing, setter, ecData, true); OpeningUtil.CreateOpeningsIfNecessary(footing, element, ecData, null, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); } } tr.Commit(); } }
/// <summary> /// Exports a roof to IfcRoof. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="ifcEnumType">The roof type.</param> /// <param name="roof">The roof element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportRoof(ExporterIFC exporterIFC, string ifcEnumType, Element roof, GeometryElement geometryElement, ProductWrapper productWrapper) { if (roof == null || geometryElement == null) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, roof)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { // If the roof is an in-place family, we will allow any arbitrary orientation. While this may result in some // in-place "cubes" exporting with the wrong direction, it is unlikely that an in-place family would be // used for this reason in the first place. ecData.PossibleExtrusionAxes = (roof is FamilyInstance) ? IFCExtrusionAxes.TryXYZ : IFCExtrusionAxes.TryZ; ecData.AreInnerRegionsOpenings = true; ecData.SetLocalPlacement(placementSetter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(roof); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); BodyData bodyData; IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, roof, categoryId, geometryElement, bodyExporterOptions, null, ecData, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) { ecData.ClearOpenings(); return; } bool exportSlab = ecData.ScaledLength > MathUtil.Eps(); string guid = GUIDUtil.CreateGUID(roof); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); //string predefinedType = GetIFCRoofType(ifcEnumType); string predefinedType = IFCValidateEntry.GetValidIFCPredefinedTypeType(ifcEnumType, "NOTDEFINED", IFCEntityType.IfcRoofType.ToString()); IFCAnyHandle roofHnd = IFCInstanceExporter.CreateRoof(exporterIFC, roof, guid, ownerHistory, localPlacement, exportSlab ? null : representation, predefinedType); // Export IfcRoofType IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcRoof, IFCEntityType.IfcRoofType, predefinedType); if (exportInfo.ExportType != IFCEntityType.UnKnown) { string overridePDefType; if (ParameterUtil.GetStringValueFromElementOrSymbol(roof, "IfcExportType", out overridePDefType) == null) // change IFCType to consistent parameter of IfcExportType { if (ParameterUtil.GetStringValueFromElementOrSymbol(roof, "IfcType", out overridePDefType) == null) // support IFCType for legacy support { if (string.IsNullOrEmpty(predefinedType)) { predefinedType = "NOTDEFINED"; } } } if (!string.IsNullOrEmpty(overridePDefType)) { exportInfo.ValidatedPredefinedType = overridePDefType; } else { exportInfo.ValidatedPredefinedType = predefinedType; } IFCAnyHandle typeHnd = ExporterUtil.CreateGenericTypeFromElement(roof, exportInfo, file, ownerHistory, predefinedType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(typeHnd, roofHnd); } productWrapper.AddElement(roof, roofHnd, placementSetter.LevelInfo, ecData, true); // will export its host object materials later if it is a roof if (!(roof is RoofBase)) { CategoryUtil.CreateMaterialAssociation(exporterIFC, roofHnd, bodyData.MaterialIds); } if (exportSlab) { string slabGUID = GUIDUtil.CreateSubElementGUID(roof, (int)IFCRoofSubElements.RoofSlabStart); string slabName = IFCAnyHandleUtil.GetStringAttribute(roofHnd, "Name") + ":1"; IFCAnyHandle slabLocalPlacementHnd = ExporterUtil.CopyLocalPlacement(file, localPlacement); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(exporterIFC, roof, slabGUID, ownerHistory, slabLocalPlacementHnd, representation, slabRoofPredefinedType); IFCAnyHandleUtil.OverrideNameAttribute(slabHnd, slabName); Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity; OpeningUtil.CreateOpeningsIfNecessary(slabHnd, roof, ecData, offsetTransform, exporterIFC, slabLocalPlacementHnd, placementSetter, productWrapper); ExporterUtil.RelateObject(exporterIFC, roofHnd, slabHnd); productWrapper.AddElement(null, slabHnd, placementSetter.LevelInfo, ecData, false); CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, bodyData.MaterialIds); // Create type IFCExportInfoPair slabRoofExportType = new IFCExportInfoPair(); slabRoofExportType.SetValueWithPair(IFCEntityType.IfcSlab); IFCAnyHandle slabRoofTypeHnd = ExporterUtil.CreateGenericTypeFromElement(roof, slabRoofExportType, exporterIFC.GetFile(), ownerHistory, slabRoofPredefinedType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(slabRoofTypeHnd, slabHnd); } } tr.Commit(); } } }
/// <summary> /// Export the individual part (IfcBuildingElementPart). /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="partElement">The part element to export.</param> /// <param name="geometryElement">The geometry of part.</param> /// <param name="productWrapper">The ProductWrapper object.</param> /// <param name="placementSetter"></param> /// <param name="originalPlacement"></param> /// <param name="range"></param> /// <param name="ifcExtrusionAxes"></param> /// <param name="hostElement">The host of the part. This can be null.</param> /// <param name="overrideLevelId">The id of the level that the part is one, overridding other sources.</param> /// <param name="asBuildingElement">If true, export the Part as a building element instead of an IfcElementPart.</param> public static void ExportPart(ExporterIFC exporterIFC, Element partElement, ProductWrapper productWrapper, PlacementSetter placementSetter, IFCAnyHandle originalPlacement, IFCRange range, IFCExtrusionAxes ifcExtrusionAxes, Element hostElement, ElementId overrideLevelId, bool asBuildingElement) { if (!ElementFilteringUtil.IsElementVisible(partElement)) { return; } Part part = partElement as Part; if (part == null) { return; } // We don't know how to export a part as a building element if we don't know it's host. if (asBuildingElement && (hostElement == null)) { return; } if (!asBuildingElement) { // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcBuildingElementPart; if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } else { string ifcEnumType = null; IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType); // 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>(exportType.ToString(), out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } } PlacementSetter standalonePlacementSetter = null; bool standaloneExport = hostElement == null || asBuildingElement; ElementId partExportLevelId = (overrideLevelId != null) ? overrideLevelId : null; if (partExportLevelId == null && standaloneExport) { partExportLevelId = partElement.LevelId; } if (partExportLevelId == null) { if (hostElement == null || (part.OriginalCategoryId != hostElement.Category.Id)) { return; } partExportLevelId = hostElement.LevelId; } if (ExporterCacheManager.PartExportedCache.HasExported(partElement.Id, partExportLevelId)) { return; } Options options = GeometryUtil.GetIFCExportGeometryOptions(); View ownerView = partElement.Document.GetElement(partElement.OwnerViewId) as View; if (ownerView != null) { options.View = ownerView; } GeometryElement geometryElement = partElement.get_Geometry(options); if (geometryElement == null) { return; } try { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { IFCAnyHandle partPlacement = null; if (standaloneExport) { Transform orientationTrf = Transform.Identity; IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, partElement, out overrideContainerHnd); if (overrideContainerId != ElementId.InvalidElementId && (partExportLevelId == null || partExportLevelId == ElementId.InvalidElementId)) { partExportLevelId = overrideContainerId; } standalonePlacementSetter = PlacementSetter.Create(exporterIFC, partElement, null, orientationTrf, partExportLevelId, overrideContainerHnd); partPlacement = standalonePlacementSetter.LocalPlacement; } else { //partPlacement = ExporterUtil.CreateLocalPlacement(file, null, null); partPlacement = ExporterUtil.CreateLocalPlacement(file, originalPlacement, null); } bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End)); SolidMeshGeometryInfo solidMeshInfo; if (validRange) { solidMeshInfo = GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range); if (solidMeshInfo.GetSolids().Count == 0 && solidMeshInfo.GetMeshes().Count == 0) { return; } } else { solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement); } using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { extrusionCreationData.SetLocalPlacement(partPlacement); extrusionCreationData.ReuseLocalPlacement = false; extrusionCreationData.PossibleExtrusionAxes = ifcExtrusionAxes; IList <Solid> solids = new List <Solid>();; IList <Mesh> meshes = new List <Mesh>(); IList <GeometryObject> gObjs = FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(partElement.Document, exporterIFC, solidMeshInfo.GetSolids(), solidMeshInfo.GetMeshes()); foreach (GeometryObject gObj in gObjs) { if (gObj is Solid) { solids.Add(gObj as Solid); } else if (gObj is Mesh) { meshes.Add(gObj as Mesh); } } ElementId catId = CategoryUtil.GetSafeCategoryId(partElement); ElementId hostCatId = CategoryUtil.GetSafeCategoryId(hostElement); BodyData bodyData = null; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); if (solids.Count > 0 || meshes.Count > 0) { bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, solids, meshes, bodyExporterOptions, extrusionCreationData); } else { IList <GeometryObject> geomlist = new List <GeometryObject>(); geomlist.Add(geometryElement); bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, geomlist, bodyExporterOptions, extrusionCreationData); } IFCAnyHandle bodyRep = bodyData.RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { extrusionCreationData.ClearOpenings(); return; } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(bodyRep); IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); if (boundingBoxRep != null) { representations.Add(boundingBoxRep); } IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string partGUID = GUIDUtil.CreateGUID(partElement); string ifcEnumType = null; IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType); IFCAnyHandle ifcPart = null; if (!asBuildingElement) { ifcPart = IFCInstanceExporter.CreateBuildingElementPart(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep); } else { switch (exportType.ExportInstance) { case IFCEntityType.IfcColumn: ifcPart = IFCInstanceExporter.CreateColumn(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; case IFCEntityType.IfcCovering: ifcPart = IFCInstanceExporter.CreateCovering(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; case IFCEntityType.IfcFooting: ifcPart = IFCInstanceExporter.CreateFooting(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; case IFCEntityType.IfcPile: ifcPart = IFCInstanceExporter.CreatePile(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType, null); break; case IFCEntityType.IfcRoof: ifcPart = IFCInstanceExporter.CreateRoof(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; case IFCEntityType.IfcSlab: { // TODO: fix this elsewhere. if (ExporterUtil.IsNotDefined(ifcEnumType)) { if (hostCatId == new ElementId(BuiltInCategory.OST_Floors)) { ifcEnumType = "FLOOR"; } else if (hostCatId == new ElementId(BuiltInCategory.OST_Roofs)) { ifcEnumType = "ROOF"; } } ifcPart = IFCInstanceExporter.CreateSlab(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); } break; case IFCEntityType.IfcWall: ifcPart = IFCInstanceExporter.CreateWall(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; default: ifcPart = IFCInstanceExporter.CreateBuildingElementProxy(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, exportType.ValidatedPredefinedType); break; } } bool containedInLevel = standaloneExport; PlacementSetter whichPlacementSetter = containedInLevel ? standalonePlacementSetter : placementSetter; productWrapper.AddElement(partElement, ifcPart, whichPlacementSetter, extrusionCreationData, containedInLevel, exportType); OpeningUtil.CreateOpeningsIfNecessary(ifcPart, partElement, extrusionCreationData, bodyData.OffsetTransform, exporterIFC, extrusionCreationData.GetLocalPlacement(), whichPlacementSetter, productWrapper); //Add the exported part to exported cache. TraceExportedParts(partElement, partExportLevelId, standaloneExport ? ElementId.InvalidElementId : hostElement.Id); CategoryUtil.CreateMaterialAssociation(exporterIFC, ifcPart, bodyData.MaterialIds); transaction.Commit(); } } } finally { if (standalonePlacementSetter != null) { standalonePlacementSetter.Dispose(); } } }
/// <summary> /// Exports a MEP family instance. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="exportType">The export type of the element. /// <param name="ifcEnumType">The sub-type of the element.</param></param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if an entity was created, false otherwise.</returns> public static bool Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, IFCExportType exportType, string ifcEnumType, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { IFCAnyHandle localPlacementToUse = setter.LocalPlacement; using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData()) { extraParams.SetLocalPlacement(localPlacementToUse); ElementId catId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); BodyData bodyData = null; IFCAnyHandle productRepresentation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, extraParams, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(productRepresentation)) { extraParams.ClearOpenings(); return(false); } IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); ElementId typeId = element.GetTypeId(); ElementType type = element.Document.GetElement(typeId) as ElementType; FamilyTypeInfo currentTypeInfo = ExporterCacheManager.TypeObjectsCache.Find(typeId, false); bool found = currentTypeInfo.IsValid(); if (!found) { string typeGUID = GUIDUtil.CreateGUID(type); string typeName = NamingUtil.GetNameOverride(type, NamingUtil.GetIFCName(type)); string typeObjectType = NamingUtil.GetObjectTypeOverride(type, NamingUtil.CreateIFCObjectName(exporterIFC, type)); string applicableOccurence = NamingUtil.GetOverrideStringValue(type, "IfcApplicableOccurrence", typeObjectType); string typeDescription = NamingUtil.GetDescriptionOverride(type, null); string typeTag = NamingUtil.GetTagOverride(type, NamingUtil.CreateIFCElementId(type)); string typeElementType = NamingUtil.GetOverrideStringValue(type, "IfcElementType", typeName); IList <IFCAnyHandle> repMapListOpt = new List <IFCAnyHandle>(); IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, typeGUID, typeName, typeDescription, applicableOccurence, null, repMapListOpt, typeTag, typeElementType, element, type); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) { productWrapper.RegisterHandleWithElementType(type, styleHandle, null); currentTypeInfo.Style = styleHandle; ExporterCacheManager.TypeObjectsCache.Register(typeId, false, currentTypeInfo); } } string instanceGUID = GUIDUtil.CreateGUID(element); string instanceName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element)); string instanceDescription = NamingUtil.GetDescriptionOverride(element, null); string instanceTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); bool roomRelated = !FamilyExporterUtil.IsDistributionFlowElementSubType(exportType); ElementId roomId = ElementId.InvalidElementId; if (roomRelated) { roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse); } IFCAnyHandle instanceHandle = null; // For MEP objects string exportEntityStr = exportType.ToString(); Common.Enums.IFCEntityType exportEntity; if (String.Compare(exportEntityStr.Substring(exportEntityStr.Length - 4), "Type", true) == 0) { exportEntityStr = exportEntityStr.Substring(0, (exportEntityStr.Length - 4)); } if (Enum.TryParse(exportEntityStr, out exportEntity)) { // For MEP object creation instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportEntity, file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle)) { return(false); } bool relatedToSpace = (roomId != ElementId.InvalidElementId); productWrapper.AddElement(element, instanceHandle, setter, extraParams, !relatedToSpace); if (relatedToSpace) { ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle); } OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, element, extraParams, null, exporterIFC, localPlacementToUse, setter, productWrapper); if (currentTypeInfo.IsValid()) { ExporterCacheManager.TypeRelationsCache.Add(currentTypeInfo.Style, instanceHandle); } if (bodyData != null && bodyData.MaterialIds.Count != 0) { CategoryUtil.CreateMaterialAssociations(exporterIFC, instanceHandle, bodyData.MaterialIds); } ExporterCacheManager.MEPCache.Register(element, instanceHandle); tr.Commit(); } } } return(true); }
/// <summary> /// Exports an element to IFC footing. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="element"> /// The element. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="ifcEnumType"> /// The string value represents the IFC type. /// </param> /// <param name="productWrapper"> /// The IFCProductWrapper. /// </param> public static void ExportFooting(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, string ifcEnumType, IFCProductWrapper productWrapper) { // export parts or not bool exportParts = PartExporter.CanExportParts(element); if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.Level.Id, false)) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(setter.GetPlacement()); IFCAnyHandle prodRep = null; if (!exportParts) { ElementId catId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); prodRep = RepresentationUtil.CreateBRepProductDefinitionShape(element.Document.Application, exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, ecData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) { ecData.ClearOpenings(); return; } } string instanceGUID = ExporterIFCUtils.CreateGUID(element); string origInstanceName = exporterIFC.GetName(); string instanceName = NamingUtil.GetNameOverride(element, origInstanceName); string instanceDescription = NamingUtil.GetDescriptionOverride(element, null); string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string instanceElemId = NamingUtil.CreateIFCElementId(element); Toolkit.IFCFootingType footingType = GetIFCFootingType(element, ifcEnumType); IFCAnyHandle footing = IFCInstanceExporter.CreateFooting(file, instanceGUID, exporterIFC.GetOwnerHistoryHandle(), instanceName, instanceDescription, instanceObjectType, ecData.GetLocalPlacement(), prodRep, instanceElemId, footingType); if (exportParts) { PartExporter.ExportHostPart(exporterIFC, element, footing, productWrapper, setter, setter.GetPlacement(), null); } productWrapper.AddElement(footing, setter, ecData, LevelUtil.AssociateElementToLevel(element)); OpeningUtil.CreateOpeningsIfNecessary(footing, element, ecData, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); } } tr.Commit(); } }
/// <summary> /// Exports a roof to IfcRoof. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="roof">The roof element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <param name="exportRoofAsSingleGeometry">Export roof as single geometry.</param> public static void ExportRoof(ExporterIFC exporterIFC, Element roof, ref GeometryElement geometryElement, ProductWrapper productWrapper, bool exportRoofAsSingleGeometry = false) { if (roof == null || geometryElement == null) { return; } string ifcEnumType; IFCExportInfoPair roofExportType = ExporterUtil.GetProductExportType(exporterIFC, roof, out ifcEnumType); if (roofExportType.IsUnKnown) { roofExportType = new IFCExportInfoPair(IFCEntityType.IfcRoof, ""); } MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, roof, productWrapper); IFCFile file = exporterIFC.GetFile(); Document doc = roof.Document; using (SubTransaction tempPartTransaction = new SubTransaction(doc)) { // For IFC4RV export, Roof will be split into its parts(temporarily) in order to export the roof by its parts ExporterUtil.CreateParts(roof, layersetInfo.MaterialIds.Count, ref geometryElement); bool exportByComponents = ExporterUtil.CanExportByComponentsOrParts(roof) == ExporterUtil.ExportPartAs.ShapeAspect; using (IFCTransaction tr = new IFCTransaction(file)) { // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, roof, out overrideContainerHnd); using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, roof, null, null, overrideContainerId, overrideContainerHnd)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { // If the roof is an in-place family, we will allow any arbitrary orientation. While this may result in some // in-place "cubes" exporting with the wrong direction, it is unlikely that an in-place family would be // used for this reason in the first place. ecData.PossibleExtrusionAxes = (roof is FamilyInstance) ? IFCExtrusionAxes.TryXYZ : IFCExtrusionAxes.TryZ; ecData.AreInnerRegionsOpenings = true; ecData.SetLocalPlacement(placementSetter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(roof); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); BodyData bodyData = null; IFCAnyHandle prodRep = null; IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); IList <ElementId> materialIds = new List <ElementId>(); if (!exportByComponents) { prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, roof, categoryId, geometryElement, bodyExporterOptions, null, ecData, out bodyData); if (bodyData != null && bodyData.MaterialIds != null) { materialIds = bodyData.MaterialIds; } } else { prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, roof, categoryId, geometryElement, representations); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) { ecData.ClearOpenings(); return; } bool exportSlab = ((ecData.ScaledLength > MathUtil.Eps() || exportByComponents) && roofExportType.ExportInstance == IFCEntityType.IfcRoof && !exportRoofAsSingleGeometry); string guid = GUIDUtil.CreateGUID(roof); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); IFCAnyHandle roofHnd = IFCInstanceExporter.CreateGenericIFCEntity( roofExportType, exporterIFC, roof, guid, ownerHistory, localPlacement, exportSlab ? null : prodRep); IFCAnyHandle typeHnd = ExporterUtil.CreateGenericTypeFromElement(roof, roofExportType, file, ownerHistory, roofExportType.ValidatedPredefinedType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(typeHnd, roofHnd); productWrapper.AddElement(roof, roofHnd, placementSetter.LevelInfo, ecData, true, roofExportType); if (!(roof is RoofBase)) { CategoryUtil.CreateMaterialAssociation(exporterIFC, roofHnd, materialIds); } if (exportByComponents && (exportSlab || exportRoofAsSingleGeometry)) { IFCAnyHandle hostShapeRepFromParts = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, roof, prodRep, productWrapper, placementSetter, localPlacement, ElementId.InvalidElementId, layersetInfo, ecData); } Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity; if (exportSlab) { string slabGUID = GUIDUtil.CreateSubElementGUID(roof, (int)IFCRoofSubElements.RoofSlabStart); IFCAnyHandle slabLocalPlacementHnd = ExporterUtil.CopyLocalPlacement(file, localPlacement); string slabName = IFCAnyHandleUtil.GetStringAttribute(roofHnd, "Name") + ":1"; IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(exporterIFC, roof, slabGUID, ownerHistory, slabLocalPlacementHnd, prodRep, slabRoofPredefinedType); IFCAnyHandleUtil.OverrideNameAttribute(slabHnd, slabName); OpeningUtil.CreateOpeningsIfNecessary(slabHnd, roof, ecData, offsetTransform, exporterIFC, slabLocalPlacementHnd, placementSetter, productWrapper); ExporterUtil.RelateObject(exporterIFC, roofHnd, slabHnd); IFCExportInfoPair slabRoofExportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, slabRoofPredefinedType); productWrapper.AddElement(null, slabHnd, placementSetter.LevelInfo, ecData, false, slabRoofExportType); // Create type IFCAnyHandle slabRoofTypeHnd = ExporterUtil.CreateGenericTypeFromElement(roof, slabRoofExportType, exporterIFC.GetFile(), ownerHistory, slabRoofPredefinedType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(slabRoofTypeHnd, slabHnd); ExporterUtil.AddIntoComplexPropertyCache(slabHnd, layersetInfo); // For earlier than IFC4 version of IFC export, the material association will be done at the Roof host level with MaterialSetUsage // This one is only for IFC4 and above if ((roof is RoofBase) && !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { if (layersetInfo != null && !IFCAnyHandleUtil.IsNullOrHasNoValue(layersetInfo.MaterialLayerSetHandle)) { CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, layersetInfo.MaterialLayerSetHandle); } else if (bodyData != null) { CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, bodyData.MaterialIds); } } } else { OpeningUtil.CreateOpeningsIfNecessary(roofHnd, roof, ecData, offsetTransform, exporterIFC, localPlacement, placementSetter, productWrapper); // For earlier than IFC4 version of IFC export, the material association will be done at the Roof host level with MaterialSetUsage // This one is only for IFC4 and above if ((roof is RoofBase) && !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4) { if (layersetInfo != null && !IFCAnyHandleUtil.IsNullOrHasNoValue(layersetInfo.MaterialLayerSetHandle)) { CategoryUtil.CreateMaterialAssociation(exporterIFC, roofHnd, layersetInfo.MaterialLayerSetHandle); } else if (layersetInfo != null && layersetInfo.MaterialIds != null) { materialIds = layersetInfo.MaterialIds.Select(x => x.m_baseMatId).ToList(); CategoryUtil.CreateMaterialAssociation(exporterIFC, roofHnd, materialIds); } } } } tr.Commit(); } } } }
/// <summary> /// Exports a roof or floor as a container of multiple roof slabs. Returns the handle, if successful. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="element">The roof or floor element.</param> /// <param name="geometry">The geometry of the element.</param> /// <param name="productWrapper">The product wrapper.</param> /// <returns>The roof handle.</returns> /// <remarks>For floors, if there is only one component, return null, as we do not want to create a container.</remarks> public static IFCAnyHandle ExportRoofOrFloorAsContainer(ExporterIFC exporterIFC, Element element, GeometryElement geometry, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); // We support ExtrusionRoofs, FootPrintRoofs, and Floors only. bool elementIsRoof = (element is ExtrusionRoof) || (element is FootPrintRoof); bool elementIsFloor = (element is Floor); if (!elementIsRoof && !elementIsFloor) { return(null); } string subSlabType = null; IFCExportInfoPair roofExportType = ExporterUtil.GetProductExportType(exporterIFC, element, out _); if (roofExportType.IsUnKnown) { IFCEntityType elementClassTypeEnum = elementIsFloor ? IFCEntityType.IfcSlab: IFCEntityType.IfcRoof; roofExportType = new IFCExportInfoPair(elementClassTypeEnum, ""); } else { if (elementIsFloor) { subSlabType = "FLOOR"; } else if (elementIsRoof) { subSlabType = "ROOF"; } } // Check the intended IFC entity or type name is in the exclude list specified in the UI if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(roofExportType.ExportType)) { return(null); } Document doc = element.Document; using (SubTransaction tempPartTransaction = new SubTransaction(doc)) { using (IFCTransaction transaction = new IFCTransaction(file)) { MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, element, productWrapper); bool hasLayers = false; if (layersetInfo.MaterialIds.Count > 1) { hasLayers = true; } bool exportByComponents = ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && hasLayers; // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd); // We want to delay creating entity handles until as late as possible, so that if we abort the IFC transaction, // we don't have to delete elements. This is both for performance reasons and to potentially extend the number // of projects that can be exported by reducing (a small amount) of waste. IList <HostObjectSubcomponentInfo> hostObjectSubcomponents = null; try { hostObjectSubcomponents = ExporterIFCUtils.ComputeSubcomponents(element as HostObject); } catch { return(null); } if (hostObjectSubcomponents == null) { return(null); } int numSubcomponents = hostObjectSubcomponents.Count; if (numSubcomponents == 0 || (elementIsFloor && numSubcomponents == 1)) { return(null); } using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd)) { IFCAnyHandle localPlacement = setter.LocalPlacement; IFCAnyHandle hostObjectHandle = null; try { using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; extrusionCreationData.SetLocalPlacement(localPlacement); extrusionCreationData.ReuseLocalPlacement = true; using (TransformSetter trfSetter = TransformSetter.Create()) { IList <GeometryObject> geometryList = new List <GeometryObject>(); geometryList.Add(geometry); trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, extrusionCreationData); IFCAnyHandle prodRepHnd = null; string elementGUID = GUIDUtil.CreateGUID(element); hostObjectHandle = IFCInstanceExporter.CreateGenericIFCEntity( roofExportType, exporterIFC, element, elementGUID, ownerHistory, localPlacement, prodRepHnd); if (IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjectHandle)) { return(null); } IList <IFCAnyHandle> elementHandles = new List <IFCAnyHandle>(); elementHandles.Add(hostObjectHandle); // If element is floor, then the profile curve loop of hostObjectSubComponent is computed from the top face of the floor // else if element is roof, then the profile curve loop is taken from the bottom face of the roof instead XYZ extrusionDir = elementIsFloor ? new XYZ(0, 0, -1) : new XYZ(0, 0, 1); ElementId catId = CategoryUtil.GetSafeCategoryId(element); IList <IFCAnyHandle> slabHandles = new List <IFCAnyHandle>(); IList <CurveLoop> hostObjectOpeningLoops = new List <CurveLoop>(); double maximumScaledDepth = 0.0; using (IFCExtrusionCreationData slabExtrusionCreationData = new IFCExtrusionCreationData()) { slabExtrusionCreationData.SetLocalPlacement(extrusionCreationData.GetLocalPlacement()); slabExtrusionCreationData.ReuseLocalPlacement = false; slabExtrusionCreationData.ForceOffset = true; int loopNum = 0; int subElementStart = elementIsRoof ? (int)IFCRoofSubElements.RoofSlabStart : (int)IFCSlabSubElements.SubSlabStart; foreach (HostObjectSubcomponentInfo hostObjectSubcomponent in hostObjectSubcomponents) { trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, slabExtrusionCreationData); Plane plane = hostObjectSubcomponent.GetPlane(); Transform lcs = GeometryUtil.CreateTransformFromPlane(plane); IList <CurveLoop> curveLoops = new List <CurveLoop>(); CurveLoop slabCurveLoop = hostObjectSubcomponent.GetCurveLoop(); curveLoops.Add(slabCurveLoop); double slope = Math.Abs(plane.Normal.Z); double scaledDepth = UnitUtil.ScaleLength(hostObjectSubcomponent.Depth); double scaledExtrusionDepth = scaledDepth * slope; IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); IFCAnyHandle prodDefShape = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); string shapeIdent = "Body"; IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle(shapeIdent); string representationType = ShapeRepresentationType.SweptSolid.ToString(); // Create representation items based on the layers // Because in this case, the Roof components are not derived from Parts, but by "splitting" geometry part that can be extruded, // the creation of the Items for IFC4RV will be different by using "manual" split based on the layer thickness HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); if (!exportByComponents) { IFCAnyHandle itemShapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, scaledExtrusionDepth, false); if (IFCAnyHandleUtil.IsNullOrHasNoValue(itemShapeRep)) { productWrapper.ClearInternalHandleWrapperData(element); return(null); } ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(element as HostObject); BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, false, itemShapeRep, matId); bodyItems.Add(itemShapeRep); } else { double scaleProj = extrusionDir.DotProduct(plane.Normal); foreach (MaterialLayerSetInfo.MaterialInfo matLayerInfo in layersetInfo.MaterialIds) { double itemExtrDepth = matLayerInfo.m_matWidth; IFCAnyHandle itemShapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, itemExtrDepth, false); if (IFCAnyHandleUtil.IsNullOrHasNoValue(itemShapeRep)) { productWrapper.ClearInternalHandleWrapperData(element); return(null); } BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, false, itemShapeRep, matLayerInfo.m_baseMatId); bodyItems.Add(itemShapeRep); RepresentationUtil.CreateRepForShapeAspect(exporterIFC, element, prodDefShape, representationType, matLayerInfo.m_layerName, itemShapeRep); XYZ offset = new XYZ(0, 0, itemExtrDepth / scaleProj); // offset is calculated as extent in the direction of extrusion lcs.Origin += offset; } } IFCAnyHandle shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null); shapeReps.Add(shapeRep); IFCAnyHandleUtil.SetAttribute(prodDefShape, "Representations", shapeReps); // Allow support for up to 256 named IfcSlab components, as defined in IFCSubElementEnums.cs. string slabGUID = (loopNum < 256) ? GUIDUtil.CreateSubElementGUID(element, subElementStart + loopNum) : GUIDUtil.CreateGUID(); IFCAnyHandle slabPlacement = ExporterUtil.CreateLocalPlacement(file, slabExtrusionCreationData.GetLocalPlacement(), null); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(exporterIFC, element, slabGUID, ownerHistory, slabPlacement, prodDefShape, subSlabType); IFCExportInfoPair exportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, subSlabType); //slab quantities slabExtrusionCreationData.ScaledLength = scaledExtrusionDepth; slabExtrusionCreationData.ScaledArea = UnitUtil.ScaleArea(UnitUtil.ScaleArea(hostObjectSubcomponent.AreaOfCurveLoop)); slabExtrusionCreationData.ScaledOuterPerimeter = UnitUtil.ScaleLength(curveLoops[0].GetExactLength()); slabExtrusionCreationData.Slope = UnitUtil.ScaleAngle(MathUtil.SafeAcos(Math.Abs(slope))); IFCExportInfoPair slabRoofExportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, subSlabType); productWrapper.AddElement(null, slabHnd, setter, slabExtrusionCreationData, false, slabRoofExportType); // Create type IFCAnyHandle slabRoofTypeHnd = ExporterUtil.CreateGenericTypeFromElement(element, slabRoofExportType, exporterIFC.GetFile(), ownerHistory, subSlabType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(slabRoofTypeHnd, slabHnd); elementHandles.Add(slabHnd); slabHandles.Add(slabHnd); hostObjectOpeningLoops.Add(slabCurveLoop); maximumScaledDepth = Math.Max(maximumScaledDepth, scaledDepth); loopNum++; ExporterUtil.AddIntoComplexPropertyCache(slabHnd, layersetInfo); // Create material association here if (layersetInfo != null && !IFCAnyHandleUtil.IsNullOrHasNoValue(layersetInfo.MaterialLayerSetHandle)) { CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, layersetInfo.MaterialLayerSetHandle); } } } productWrapper.AddElement(element, hostObjectHandle, setter, extrusionCreationData, true, roofExportType); ExporterUtil.RelateObjects(exporterIFC, null, hostObjectHandle, slabHandles); OpeningUtil.AddOpeningsToElement(exporterIFC, elementHandles, hostObjectOpeningLoops, element, null, maximumScaledDepth, null, setter, localPlacement, productWrapper); transaction.Commit(); return(hostObjectHandle); } } } catch { // SOmething wrong with the above process, unable to create the extrusion data. Reset any internal handles that may have been partially created since they are not committed productWrapper.ClearInternalHandleWrapperData(element); return(null); } finally { exporterIFC.ClearFaceWithElementHandleMap(); } } } } }
/// <summary> /// Exports an element as IFC covering. /// </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 ExportCovering(ExporterIFC exporterIFC, Element element, ref GeometryElement geomElem, string ifcEnumType, ProductWrapper productWrapper) { // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcCovering; if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } ElementType elemType = element.Document.GetElement(element.GetTypeId()) as ElementType; IFCFile file = exporterIFC.GetFile(); MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, element, productWrapper); using (IFCTransaction transaction = new IFCTransaction(file)) { // For IFC4RV export, Element will be split into its parts(temporarily) in order to export the wall by its parts // If Parts are created by code and not by user then their name should be equal to Material name. bool setMaterialNameToPartName = ExporterUtil.CreateParts(element, layersetInfo.MaterialIds.Count, ref geomElem); ExporterUtil.ExportPartAs exportPartAs = ExporterUtil.CanExportByComponentsOrParts(element); bool exportByComponents = exportPartAs == ExporterUtil.ExportPartAs.ShapeAspect; bool exportParts = exportPartAs == ExporterUtil.ExportPartAs.Part; if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false)) { return; } // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd); IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); IFCAnyHandle prodRep = null; if (!exportParts) { ecData.SetLocalPlacement(setter.LocalPlacement); ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); if (exportByComponents) { prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, element, categoryId, geomElem, representations); } else { prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, categoryId, geomElem, bodyExporterOptions, null, ecData, true); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) { ecData.ClearOpenings(); return; } } // We will use the category of the element to set a default value for the covering. string defaultCoveringEnumType = null; if (categoryId == new ElementId(BuiltInCategory.OST_Ceilings)) { defaultCoveringEnumType = "CEILING"; } else if (categoryId == new ElementId(BuiltInCategory.OST_Floors)) { defaultCoveringEnumType = "FLOORING"; } else if (categoryId == new ElementId(BuiltInCategory.OST_Roofs)) { defaultCoveringEnumType = "ROOFING"; } string instanceGUID = GUIDUtil.CreateGUID(element); string coveringType = IFCValidateEntry.GetValidIFCPredefinedTypeType(/*element,*/ ifcEnumType, defaultCoveringEnumType, "IfcCoveringType"); IFCAnyHandle covering = IFCInstanceExporter.CreateCovering(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, setter.LocalPlacement, prodRep, coveringType); if (exportParts) { PartExporter.ExportHostPart(exporterIFC, element, covering, productWrapper, setter, setter.LocalPlacement, null, setMaterialNameToPartName); } else if (exportByComponents) { IFCAnyHandle hostShapeRepFromParts = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, element, prodRep, productWrapper, setter, setter.LocalPlacement, ElementId.InvalidElementId, layersetInfo, ecData); } ExporterUtil.AddIntoComplexPropertyCache(covering, layersetInfo); IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcCovering, IFCEntityType.IfcCoveringType, coveringType); IFCAnyHandle typeHnd = ExporterUtil.CreateGenericTypeFromElement(element, exportInfo, file, ExporterCacheManager.OwnerHistoryHandle, coveringType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(typeHnd, covering); bool containInSpace = false; IFCAnyHandle localPlacementToUse = setter.LocalPlacement; // Ceiling containment in Space is generally required and not specific to any view if (ExporterCacheManager.CeilingSpaceRelCache.ContainsKey(element.Id)) { IList <ElementId> roomlist = ExporterCacheManager.CeilingSpaceRelCache[element.Id]; // Process Ceiling to be contained in a Space only when it is exactly bounding one Space if (roomlist.Count == 1) { productWrapper.AddElement(element, covering, setter, ecData, false, exportInfo); // Modify the Ceiling placement to be relative to the Space that it bounds IFCAnyHandle roomPlacement = IFCAnyHandleUtil.GetObjectPlacement(ExporterCacheManager.SpaceInfoCache.FindSpaceHandle(roomlist[0])); Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(roomPlacement, localPlacementToUse); Transform inverseTrf = relTrf.Inverse; IFCAnyHandle relLocalPlacement = ExporterUtil.CreateAxis2Placement3D(file, inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX); IFCAnyHandleUtil.SetAttribute(localPlacementToUse, "PlacementRelTo", roomPlacement); GeometryUtil.SetRelativePlacement(localPlacementToUse, relLocalPlacement); ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomlist[0], covering); containInSpace = true; } } // if not contained in Space, assign it to default containment in Level if (!containInSpace) { productWrapper.AddElement(element, covering, setter, ecData, true, exportInfo); } if (!exportParts) { Ceiling ceiling = element as Ceiling; if (ceiling != null) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, ceiling, covering, geomElem, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, null, null); } else { ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geomElem, element); CategoryUtil.CreateMaterialAssociation(exporterIFC, covering, matId); } } OpeningUtil.CreateOpeningsIfNecessary(covering, element, ecData, null, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); } } transaction.Commit(); } }
/// <summary> /// Exports a roof to IfcRoof. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="ifcEnumType">The roof type.</param> /// <param name="roof">The roof element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The IFCProductWrapper.</param> public static void ExportRoof(ExporterIFC exporterIFC, string ifcEnumType, Element roof, GeometryElement geometryElement, IFCProductWrapper productWrapper) { if (roof == null || geometryElement == null) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCPlacementSetter placementSetter = IFCPlacementSetter.Create(exporterIFC, roof)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ; ecData.AreInnerRegionsOpenings = true; ecData.SetLocalPlacement(placementSetter.GetPlacement()); ElementId categoryId = CategoryUtil.GetSafeCategoryId(roof); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); IFCAnyHandle representation = RepresentationUtil.CreateBRepProductDefinitionShape(roof.Document.Application, exporterIFC, roof, categoryId, geometryElement, bodyExporterOptions, null, ecData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) { ecData.ClearOpenings(); return; } bool exportSlab = ecData.ScaledLength > MathUtil.Eps(); string guid = ExporterIFCUtils.CreateGUID(roof); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string origRoofName = exporterIFC.GetName(); string roofName = NamingUtil.GetNameOverride(roof, origRoofName); string roofDescription = NamingUtil.GetDescriptionOverride(roof, null); string roofObjectType = NamingUtil.GetObjectTypeOverride(roof, NamingUtil.CreateIFCObjectName(exporterIFC, roof)); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); string elementTag = NamingUtil.CreateIFCElementId(roof); IFCRoofType roofType = GetIFCRoofType(ifcEnumType); IFCAnyHandle roofHnd = IFCInstanceExporter.CreateRoof(file, guid, ownerHistory, roofName, roofDescription, roofObjectType, localPlacement, exportSlab ? null : representation, elementTag, roofType); productWrapper.AddElement(roofHnd, placementSetter.GetLevelInfo(), ecData, LevelUtil.AssociateElementToLevel(roof)); if (exportSlab) { string slabGUID = ExporterIFCUtils.CreateSubElementGUID(roof, (int)IFCRoofSubElements.RoofSlabStart); string slabName = roofName + ":1"; IFCAnyHandle slabLocalPlacementHnd = ExporterUtil.CopyLocalPlacement(file, localPlacement); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, slabGUID, ownerHistory, slabName, roofDescription, roofObjectType, slabLocalPlacementHnd, representation, elementTag, IFCSlabType.Roof); OpeningUtil.CreateOpeningsIfNecessary(slabHnd, roof, ecData, exporterIFC, slabLocalPlacementHnd, placementSetter, productWrapper); ExporterUtil.RelateObject(exporterIFC, roofHnd, slabHnd); productWrapper.AddElement(slabHnd, placementSetter.GetLevelInfo(), ecData, false); } } tr.Commit(); } } }
/// <summary> /// Exports a roof as a container of multiple roof slabs. Returns the handle, if successful. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="ifcEnumType">The roof type.</param> /// <param name="element">The roof element.</param> /// <param name="geometry">The geometry of the element.</param> /// <param name="productWrapper">The product wrapper.</param> /// <returns>The roof handle.</returns> public static IFCAnyHandle ExportRoofAsContainer(ExporterIFC exporterIFC, string ifcEnumType, Element element, GeometryElement geometry, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); if (!(element is ExtrusionRoof) && !(element is FootPrintRoof)) { return(null); } using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { IFCAnyHandle localPlacement = setter.LocalPlacement; RoofComponents roofComponents = null; try { roofComponents = ExporterIFCUtils.GetRoofComponents(exporterIFC, element as RoofBase); } catch { return(null); } if (roofComponents == null) { return(null); } try { using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); extrusionCreationData.SetLocalPlacement(localPlacement); extrusionCreationData.ReuseLocalPlacement = true; using (TransformSetter trfSetter = TransformSetter.Create()) { IList <GeometryObject> geometryList = new List <GeometryObject>(); geometryList.Add(geometry); trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, extrusionCreationData); IFCAnyHandle prodRepHnd = null; string elementGUID = GUIDUtil.CreateGUID(element); string elementName = NamingUtil.GetIFCName(element); string elementDescription = NamingUtil.GetDescriptionOverride(element, null); string elementObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string elementId = NamingUtil.CreateIFCElementId(element); string roofType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType); IFCAnyHandle roofHandle = IFCInstanceExporter.CreateRoof(file, elementGUID, ownerHistory, elementName, elementDescription, elementObjectType, localPlacement, prodRepHnd, elementId, roofType); IList <IFCAnyHandle> elementHandles = new List <IFCAnyHandle>(); elementHandles.Add(roofHandle); //only thing supported right now. XYZ extrusionDir = new XYZ(0, 0, 1); ElementId catId = CategoryUtil.GetSafeCategoryId(element); IList <CurveLoop> roofCurveloops = roofComponents.GetCurveLoops(); IList <XYZ> planeDirs = roofComponents.GetPlaneDirections(); IList <XYZ> planeOrigins = roofComponents.GetPlaneOrigins(); IList <Face> loopFaces = roofComponents.GetLoopFaces(); double scaledDepth = roofComponents.ScaledDepth; IList <double> areas = roofComponents.GetAreasOfCurveLoops(); IList <IFCAnyHandle> slabHandles = new List <IFCAnyHandle>(); using (IFCExtrusionCreationData slabExtrusionCreationData = new IFCExtrusionCreationData()) { slabExtrusionCreationData.SetLocalPlacement(extrusionCreationData.GetLocalPlacement()); slabExtrusionCreationData.ReuseLocalPlacement = false; slabExtrusionCreationData.ForceOffset = true; for (int numLoop = 0; numLoop < roofCurveloops.Count; numLoop++) { trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, slabExtrusionCreationData); Plane plane = new Plane(planeDirs[numLoop], planeOrigins[numLoop]); IList <CurveLoop> curveLoops = new List <CurveLoop>(); curveLoops.Add(roofCurveloops[numLoop]); double slope = Math.Abs(planeDirs[numLoop].Z); double scaledExtrusionDepth = scaledDepth * slope; IFCAnyHandle shapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, plane, extrusionDir, scaledExtrusionDepth); if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep)) { return(null); } ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(element as HostObject); BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, shapeRep, matId); HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); bodyItems.Add(shapeRep); shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null); IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(shapeRep); IFCAnyHandle repHnd = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); // Allow support for up to 256 named IfcSlab components, as defined in IFCSubElementEnums.cs. string slabGUID = (numLoop < 256) ? GUIDUtil.CreateSubElementGUID(element, (int)IFCRoofSubElements.RoofSlabStart + numLoop) : GUIDUtil.CreateGUID(); IFCAnyHandle slabPlacement = ExporterUtil.CreateLocalPlacement(file, slabExtrusionCreationData.GetLocalPlacement(), null); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, slabGUID, ownerHistory, elementName, elementDescription, elementObjectType, slabPlacement, repHnd, elementId, "ROOF"); //slab quantities slabExtrusionCreationData.ScaledLength = scaledExtrusionDepth; slabExtrusionCreationData.ScaledArea = UnitUtil.ScaleArea(areas[numLoop]); slabExtrusionCreationData.ScaledOuterPerimeter = UnitUtil.ScaleLength(curveLoops[0].GetExactLength()); slabExtrusionCreationData.Slope = UnitUtil.ScaleAngle(Math.Acos(Math.Abs(planeDirs[numLoop].Z))); productWrapper.AddElement(null, slabHnd, setter, slabExtrusionCreationData, false); elementHandles.Add(slabHnd); slabHandles.Add(slabHnd); } } productWrapper.AddElement(element, roofHandle, setter, extrusionCreationData, true); ExporterUtil.RelateObjects(exporterIFC, null, roofHandle, slabHandles); OpeningUtil.AddOpeningsToElement(exporterIFC, elementHandles, roofCurveloops, element, null, roofComponents.ScaledDepth, null, setter, localPlacement, productWrapper); transaction.Commit(); return(roofHandle); } } } finally { exporterIFC.ClearFaceWithElementHandleMap(); } } } }
/// <summary> /// Exports an element to IfcPile. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="ifcEnumType">The string value represents the IFC type.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportPile(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, string ifcEnumType, ProductWrapper productWrapper) { // NOTE: We expect to incorporate this code into the generic FamilyInstanceExporter at some point. // export parts or not bool exportParts = PartExporter.CanExportParts(element); if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false)) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd); using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(setter.LocalPlacement); IFCAnyHandle prodRep = null; ElementId matId = ElementId.InvalidElementId; if (!exportParts) { ElementId catId = CategoryUtil.GetSafeCategoryId(element); matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); StructuralMemberAxisInfo axisInfo = StructuralMemberExporter.GetStructuralMemberAxisTransform(element); if (axisInfo != null) { ecData.CustomAxis = axisInfo.AxisDirection; ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom; } else { ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ; } prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, ecData, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) { ecData.ClearOpenings(); return; } } string instanceGUID = GUIDUtil.CreateGUID(element); IFCExportInfoPair exportInfo = new IFCExportInfoPair(Common.Enums.IFCEntityType.IfcPile, ifcEnumType); IFCAnyHandle pile = IFCInstanceExporter.CreatePile(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, ecData.GetLocalPlacement(), prodRep, ifcEnumType, null); // TODO: to allow shared geometry for Piles. For now, Pile export will not use shared geometry if (exportInfo.ExportType != Common.Enums.IFCEntityType.UnKnown) { IFCAnyHandle type = ExporterUtil.CreateGenericTypeFromElement(element, exportInfo, file, ExporterCacheManager.OwnerHistoryHandle, exportInfo.ValidatedPredefinedType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(type, pile); } if (exportParts) { PartExporter.ExportHostPart(exporterIFC, element, pile, productWrapper, setter, setter.LocalPlacement, null); } else { if (matId != ElementId.InvalidElementId) { CategoryUtil.CreateMaterialAssociation(exporterIFC, pile, matId); } } productWrapper.AddElement(element, pile, setter, ecData, true, exportInfo); OpeningUtil.CreateOpeningsIfNecessary(pile, element, ecData, null, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); } } tr.Commit(); } }
private static void ExportAsMappedItem(ExporterIFC exporterIFC, Element element, IFCFile file, IFCExportInfoPair exportType, string ifcEnumType, IFCExtrusionCreationData extraParams, PlacementSetter setter, IFCAnyHandle localPlacementToUse, IFCAnyHandle productRepresentation, ProductWrapper productWrapper) { IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; ElementId typeId = element.GetTypeId(); ElementType type = element.Document.GetElement(typeId) as ElementType; IFCAnyHandle styleHandle = null; ElementId matId = ElementId.InvalidElementId; Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions(); bool hasMaterialAssociatedToType = false; if (type != null) { FamilyTypeInfo currentTypeInfo = ExporterCacheManager.FamilySymbolToTypeInfoCache.Find(typeId, false, exportType); if (!currentTypeInfo.IsValid()) { string typeObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, type); HashSet <IFCAnyHandle> propertySetsOpt = new HashSet <IFCAnyHandle>(); IList <IFCAnyHandle> repMapListOpt = new List <IFCAnyHandle>(); styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, propertySetsOpt, repMapListOpt, element, type); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) { propertySetsOpt = ExporterUtil.ExtractElementTypeProperties(exporterIFC, type, styleHandle); productWrapper.RegisterHandleWithElementType(type, exportType, styleHandle, propertySetsOpt); currentTypeInfo.Style = styleHandle; ExporterCacheManager.FamilySymbolToTypeInfoCache.Register(typeId, false, exportType, currentTypeInfo); Element elementType = element.Document.GetElement(element.GetTypeId()); matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(element.get_Geometry(geomOptions), exporterIFC, elementType); if (matId == ElementId.InvalidElementId) { matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(element.get_Geometry(geomOptions), exporterIFC, element); } if (matId != ElementId.InvalidElementId) { currentTypeInfo.MaterialIdList = new List <ElementId>() { matId }; hasMaterialAssociatedToType = true; CategoryUtil.CreateMaterialAssociation(exporterIFC, styleHandle, matId); } } } else { styleHandle = currentTypeInfo.Style; if (currentTypeInfo.MaterialIdList != null && currentTypeInfo.MaterialIdList.Count > 0) { hasMaterialAssociatedToType = true; } } } string instanceGUID = GUIDUtil.CreateGUID(element); bool roomRelated = !FamilyExporterUtil.IsDistributionFlowElementSubType(exportType); ElementId roomId = ElementId.InvalidElementId; if (roomRelated) { roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse); } IFCAnyHandle instanceHandle = null; // For MEP objects //string exportEntityStr = exportType.ToString(); //Common.Enums.IFCEntityType exportEntity; //if (String.Compare(exportEntityStr.Substring(exportEntityStr.Length - 4), "Type", true) == 0) // exportEntityStr = exportEntityStr.Substring(0, (exportEntityStr.Length - 4)); //if (Enum.TryParse(exportEntityStr, out exportEntity)) //{ // For MEP object creation instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportType, exporterIFC, element, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation); //} if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle)) { return; } if (matId == ElementId.InvalidElementId && !hasMaterialAssociatedToType) { matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(element.get_Geometry(geomOptions), exporterIFC, element); if (matId != ElementId.InvalidElementId) { CategoryUtil.CreateMaterialAssociation(exporterIFC, instanceHandle, matId); } } if (roomId != ElementId.InvalidElementId) { //exporterIFC.RelateSpatialElement(roomId, instanceHandle); ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle); productWrapper.AddElement(element, instanceHandle, setter, extraParams, false, exportType); } else { productWrapper.AddElement(element, instanceHandle, setter, extraParams, true, exportType); } OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, element, extraParams, null, exporterIFC, localPlacementToUse, setter, productWrapper); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) { ExporterCacheManager.TypeRelationsCache.Add(styleHandle, instanceHandle); } PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper.GetAllObjects()); ExporterCacheManager.MEPCache.Register(element, instanceHandle); // add to system export cache // SystemExporter.ExportSystem(exporterIFC, element, instanceHandle); }
/// <summary> /// Exports a beam to IFC beam if it has an axis representation and only one Solid as its geometry, ideally as an extrusion, potentially with clippings and openings. /// </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> /// <param name="dontExport">An output value that says that the element shouldn't be exported at all.</param> /// <returns>The created handle.</returns> /// <remarks>In the original implementation, the ExportBeam function would export each beam as its own individual geometry (that is, not use representation maps). /// For non-standard beams, this could result in massive IFC files. Now, we use the ExportBeamAsStandardElement function and limit its scope, and instead /// resort to the standard FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem for more complicated objects categorized as beams. This has the following pros and cons: /// Pro: possiblity for massively reduced file sizes for files containing repeated complex beam families /// Con: some beams that may have had an "Axis" representation before will no longer have them, although this possibility is minimized. /// Con: some beams that have 1 Solid and an axis, but that Solid will be heavily faceted, won't be helped by this improvement. /// It is intended that we phase out this routine entirely and instead teach ExportFamilyInstanceAsMappedItem how to sometimes export the Axis representation for beams.</remarks> public static IFCAnyHandle ExportBeamAsStandardElement(ExporterIFC exporterIFC, Element element, IFCExportInfoPair exportType, GeometryElement geometryElement, ProductWrapper productWrapper, out bool dontExport) { dontExport = true; IList <GeometryObject> geomObjects = BeamGeometryToExport(exporterIFC, element, geometryElement, out dontExport); if (dontExport) { return(null); } IFCAnyHandle beam = null; IFCFile file = exporterIFC.GetFile(); MaterialAndProfile materialAndProfile = null; IFCAnyHandle materialProfileSet = null; using (IFCTransaction transaction = new IFCTransaction(file)) { BeamAxisInfo axisInfo = GetBeamAxisTransform(element); bool canExportAxis = (axisInfo != null); Curve curve = canExportAxis ? axisInfo.Axis : null; XYZ beamDirection = canExportAxis ? axisInfo.AxisDirection : null; Transform orientTrf = canExportAxis ? axisInfo.LCSAsTransform : null; // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd); using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, orientTrf, overrideContainerId, overrideContainerHnd)) { IFCAnyHandle localPlacement = setter.LocalPlacement; 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; } ElementId catId = CategoryUtil.GetSafeCategoryId(element); // 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; // The list of materials in the solids or meshes. ICollection <ElementId> materialIds = null; // If the beam is a FamilyInstance, and it uses transformed FamilySymbol geometry only, then // let's only try to CreateBeamGeometryAsExtrusion unsuccesfully once. Otherwise, we can spend a lot of time trying // unsuccessfully to do so. bool tryToCreateBeamGeometryAsExtrusion = true; //bool useFamilySymbolGeometry = (element is FamilyInstance) ? !ExporterIFCUtils.UsesInstanceGeometry(element as FamilyInstance) : false; bool useFamilySymbolGeometry = (element is FamilyInstance) ? !GeometryUtil.UsesInstanceGeometry(element as FamilyInstance) : false; ElementId beamTypeId = element.GetTypeId(); if (useFamilySymbolGeometry) { tryToCreateBeamGeometryAsExtrusion = !ExporterCacheManager.CanExportBeamGeometryAsExtrusionCache.ContainsKey(beamTypeId) || ExporterCacheManager.CanExportBeamGeometryAsExtrusionCache[beamTypeId]; } // The representation handle generated from one of the methods below. BeamBodyAsExtrusionInfo extrusionInfo = null; if (tryToCreateBeamGeometryAsExtrusion) { extrusionInfo = CreateBeamGeometryAsExtrusion(exporterIFC, element, catId, geomObjects, axisInfo); if (useFamilySymbolGeometry) { ExporterCacheManager.CanExportBeamGeometryAsExtrusionCache[beamTypeId] = (extrusionInfo != null); } } if (extrusionInfo != null && extrusionInfo.DontExport) { dontExport = true; return(null); } IFCAnyHandle repHnd = (extrusionInfo != null) ? extrusionInfo.RepresentationHandle : null; if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd)) { materialIds = extrusionInfo.Materials; extrusionCreationData.Slope = extrusionInfo.Slope; } else { // Here is where we limit the scope of how complex a case we will still try to export as a standard element. // This is explicitly added so that many curved beams that can be represented by a reasonable facetation because of the // SweptSolidExporter can still have an Axis representation. BodyData bodyData = null; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { bodyExporterOptions.CollectMaterialAndProfile = false; } else { bodyExporterOptions.CollectMaterialAndProfile = true; } if (geomObjects != null && geomObjects.Count == 1 && geomObjects[0] is Solid) { bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, geomObjects[0], bodyExporterOptions, extrusionCreationData); repHnd = bodyData.RepresentationHnd; materialIds = bodyData.MaterialIds; if (!bodyData.OffsetTransform.IsIdentity) { offsetTransform = bodyData.OffsetTransform; } materialAndProfile = bodyData.MaterialAndProfile; } } if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd)) { extrusionCreationData.ClearOpenings(); return(null); } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); IFCAnyHandle axisRep = CreateBeamAxis(exporterIFC, element, catId, axisInfo, offsetTransform); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisRep)) { 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); beam = IFCInstanceExporter.CreateBeam(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, extrusionCreationData.GetLocalPlacement(), prodRep, exportType.ValidatedPredefinedType); IFCAnyHandle mpSetUsage; if (materialProfileSet != null) { mpSetUsage = IFCInstanceExporter.CreateMaterialProfileSetUsage(file, materialProfileSet, null, null); } productWrapper.AddElement(element, beam, setter, extrusionCreationData, true, exportType); ExportBeamType(exporterIFC, productWrapper, beam, element, exportType.ValidatedPredefinedType); 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, null); if (materialIds.Count != 0) { CategoryUtil.CreateMaterialAssociation(exporterIFC, beam, materialIds); } // Register the beam's IFC handle for later use by truss and beam system export. ExporterCacheManager.ElementToHandleCache.Register(element.Id, beam, exportType); } } transaction.Commit(); return(beam); } }
/// <summary> /// Exports an element as IFC railing. /// </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 ExportRailing(ExporterIFC exporterIFC, Element element, GeometryElement geomElem, string ifcEnumType, ProductWrapper productWrapper) { // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcRailing; if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } ElementType elemType = element.Document.GetElement(element.GetTypeId()) as ElementType; IFCFile file = exporterIFC.GetFile(); Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { IFCAnyHandle localPlacement = setter.LocalPlacement; StairRampContainerInfo stairRampInfo = null; ElementId hostId = GetStairOrRampHostId(exporterIFC, element as Railing); Transform inverseTrf = Transform.Identity; if (hostId != ElementId.InvalidElementId) { stairRampInfo = ExporterCacheManager.StairRampContainerInfoCache.GetStairRampContainerInfo(hostId); IFCAnyHandle stairRampLocalPlacement = stairRampInfo.LocalPlacements[0]; Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(stairRampLocalPlacement, localPlacement); inverseTrf = relTrf.Inverse; IFCAnyHandle railingLocalPlacement = ExporterUtil.CreateLocalPlacement(file, stairRampLocalPlacement, inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX); localPlacement = railingLocalPlacement; } ecData.SetLocalPlacement(localPlacement); SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geomElem); IList <Solid> solids = solidMeshInfo.GetSolids(); IList <Mesh> meshes = solidMeshInfo.GetMeshes(); Railing railingElem = element as Railing; IList <ElementId> subElementIds = CollectSubElements(railingElem); foreach (ElementId subElementId in subElementIds) { Element subElement = railingElem.Document.GetElement(subElementId); if (subElement != null) { GeometryElement subElementGeom = GeometryUtil.GetOneLevelGeometryElement(subElement.get_Geometry(geomOptions), 0); SolidMeshGeometryInfo subElementSolidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(subElementGeom); IList <Solid> subElementSolids = subElementSolidMeshInfo.GetSolids(); IList <Mesh> subElementMeshes = subElementSolidMeshInfo.GetMeshes(); foreach (Solid subElementSolid in subElementSolids) { solids.Add(subElementSolid); } foreach (Mesh subElementMesh in subElementMeshes) { meshes.Add(subElementMesh); } } } ElementId catId = CategoryUtil.GetSafeCategoryId(element); BodyData bodyData = null; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium); //bodyExporterOptions.UseGroupsIfPossible = true; //bodyExporterOptions.UseMappedGeometriesIfPossible = true; if (solids.Count > 0 || meshes.Count > 0) { bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, solids, meshes, bodyExporterOptions, ecData); } else { IList <GeometryObject> geomlist = new List <GeometryObject>(); geomlist.Add(geomElem); bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, geomlist, bodyExporterOptions, ecData); } IFCAnyHandle bodyRep = bodyData.RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { if (ecData != null) { ecData.ClearOpenings(); } return; } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(bodyRep); IList <GeometryObject> geomObjects = new List <GeometryObject>(); foreach (Solid solid in solids) { geomObjects.Add(solid); } foreach (Mesh mesh in meshes) { geomObjects.Add(mesh); } Transform boundingBoxTrf = (bodyData.OffsetTransform != null) ? bodyData.OffsetTransform.Inverse : Transform.Identity; boundingBoxTrf = inverseTrf.Multiply(boundingBoxTrf); IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geomObjects, boundingBoxTrf); if (boundingBoxRep != null) { representations.Add(boundingBoxRep); } IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string instanceGUID = GUIDUtil.CreateGUID(element); //string railingType = IFCValidateEntry.GetValidIFCPredefinedType(element, ifcEnumType); IFCAnyHandle railing = IFCInstanceExporter.CreateRailing(exporterIFC, element, instanceGUID, ownerHistory, ecData.GetLocalPlacement(), prodRep, ifcEnumType); bool associateToLevel = (hostId == ElementId.InvalidElementId); productWrapper.AddElement(element, railing, setter, ecData, associateToLevel); OpeningUtil.CreateOpeningsIfNecessary(railing, element, ecData, bodyData.OffsetTransform, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); CategoryUtil.CreateMaterialAssociation(exporterIFC, railing, bodyData.MaterialIds); // Create multi-story duplicates of this railing. if (stairRampInfo != null) { stairRampInfo.AddComponent(0, railing); List <IFCAnyHandle> stairHandles = stairRampInfo.StairOrRampHandles; for (int ii = 1; ii < stairHandles.Count; ii++) { IFCAnyHandle railingLocalPlacement = stairRampInfo.LocalPlacements[ii]; if (!IFCAnyHandleUtil.IsNullOrHasNoValue(railingLocalPlacement)) { IFCAnyHandle railingHndCopy = CopyRailingHandle(exporterIFC, element, catId, railingLocalPlacement, railing); stairRampInfo.AddComponent(ii, railingHndCopy); productWrapper.AddElement(element, railingHndCopy, (IFCLevelInfo)null, ecData, false); CategoryUtil.CreateMaterialAssociation(exporterIFC, railingHndCopy, bodyData.MaterialIds); } } ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(hostId, stairRampInfo); } } transaction.Commit(); } } }
/// <summary> /// Exports an element to IfcPile. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="ifcEnumType">The string value represents the IFC type.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportPile(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, string ifcEnumType, ProductWrapper productWrapper) { // export parts or not bool exportParts = PartExporter.CanExportParts(element); if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false)) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(setter.LocalPlacement); IFCAnyHandle prodRep = null; ElementId matId = ElementId.InvalidElementId; if (!exportParts) { ElementId catId = CategoryUtil.GetSafeCategoryId(element); matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, ecData, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) { ecData.ClearOpenings(); return; } } string instanceGUID = GUIDUtil.CreateGUID(element); //string pileType = IFCValidateEntry.GetValidIFCPredefinedType(element, ifcEnumType); IFCAnyHandle pile = IFCInstanceExporter.CreatePile(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, ecData.GetLocalPlacement(), prodRep, ifcEnumType, null); if (exportParts) { PartExporter.ExportHostPart(exporterIFC, element, pile, productWrapper, setter, setter.LocalPlacement, null); } else { if (matId != ElementId.InvalidElementId) { CategoryUtil.CreateMaterialAssociation(exporterIFC, pile, matId); } } productWrapper.AddElement(element, pile, setter, ecData, true); OpeningUtil.CreateOpeningsIfNecessary(pile, element, ecData, null, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); } } tr.Commit(); } }
/// <summary> /// Exports a gutter element. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportGutter(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcPipeSegmentType; if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd); using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(setter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); IFCAnyHandle bodyRep = BodyExporter.ExportBody(exporterIFC, element, categoryId, ElementId.InvalidElementId, geometryElement, bodyExporterOptions, ecData).RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { if (ecData != null) { ecData.ClearOpenings(); } return; } string originalTag = NamingUtil.CreateIFCElementId(element); // In Revit, we don't have a corresponding type, so we create one for every gutter. IFCAnyHandle origin = ExporterUtil.CreateAxis2Placement3D(file); IFCAnyHandle repMap3dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyRep); List <IFCAnyHandle> repMapList = new List <IFCAnyHandle>(); repMapList.Add(repMap3dHnd); string elementTypeName = NamingUtil.CreateIFCObjectName(exporterIFC, element); string typeGuid = GUIDUtil.CreateSubElementGUID(element, (int)IFCHostedSweepSubElements.PipeSegmentType); IFCAnyHandle style = IFCInstanceExporter.CreatePipeSegmentType(file, null, null, repMapList, IFCPipeSegmentType.Gutter); IFCAnyHandleUtil.OverrideNameAttribute(style, elementTypeName); IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcPipeSegmentType, IFCPipeSegmentType.Gutter.ToString()); IFCAnyHandleUtil.SetAttribute(style, "Tag", originalTag); ExporterUtil.SetGlobalId(style, typeGuid); IFCAnyHandleUtil.SetAttribute(style, "ElementType", elementTypeName); List <IFCAnyHandle> representationMaps = GeometryUtil.GetRepresentationMaps(style); IFCAnyHandle mappedItem = ExporterUtil.CreateDefaultMappedItem(file, representationMaps[0]); ISet <IFCAnyHandle> representations = new HashSet <IFCAnyHandle>(); representations.Add(mappedItem); IFCAnyHandle bodyMappedItemRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, element, categoryId, exporterIFC.Get3DContextHandle("Body"), representations); if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyMappedItemRep)) { return; } List <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(bodyMappedItemRep); IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); if (boundingBoxRep != null) { shapeReps.Add(boundingBoxRep); } IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); IFCAnyHandle localPlacementToUse; ElementId roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse); if (roomId == ElementId.InvalidElementId) { localPlacementToUse = ecData.GetLocalPlacement(); } string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle elemHnd = IFCInstanceExporter.CreateFlowSegment(exporterIFC, element, guid, ExporterCacheManager.OwnerHistoryHandle, localPlacementToUse, prodRep); bool containedInSpace = (roomId != ElementId.InvalidElementId); productWrapper.AddElement(element, elemHnd, setter.LevelInfo, ecData, !containedInSpace, exportInfo); if (containedInSpace) { ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, elemHnd); } // Associate segment with type. ExporterCacheManager.TypeRelationsCache.Add(style, elemHnd); OpeningUtil.CreateOpeningsIfNecessary(elemHnd, element, ecData, null, exporterIFC, localPlacementToUse, setter, productWrapper); } tr.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> /// Exports an element as IFC covering. /// </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 ExportCovering(ExporterIFC exporterIFC, Element element, GeometryElement geomElem, string ifcEnumType, ProductWrapper productWrapper) { bool exportParts = PartExporter.CanExportParts(element); if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false)) { 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>("IfcCovering", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } ElementType elemType = element.Document.GetElement(element.GetTypeId()) as ElementType; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); IFCAnyHandle prodRep = null; if (!exportParts) { ecData.SetLocalPlacement(setter.LocalPlacement); ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, categoryId, geomElem, bodyExporterOptions, null, ecData, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) { ecData.ClearOpenings(); return; } } // We will use the category of the element to set a default value for the covering. string defaultCoveringEnumType = null; if (categoryId == new ElementId(BuiltInCategory.OST_Ceilings)) { defaultCoveringEnumType = "CEILING"; } else if (categoryId == new ElementId(BuiltInCategory.OST_Floors)) { defaultCoveringEnumType = "FLOORING"; } else if (categoryId == new ElementId(BuiltInCategory.OST_Roofs)) { defaultCoveringEnumType = "ROOFING"; } string instanceGUID = GUIDUtil.CreateGUID(element); string instanceName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string instanceDescription = NamingUtil.GetDescriptionOverride(element, null); string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string instanceTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); string coveringType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType, defaultCoveringEnumType); IFCAnyHandle covering = IFCInstanceExporter.CreateCovering(file, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, instanceName, instanceDescription, instanceObjectType, setter.LocalPlacement, prodRep, instanceTag, coveringType); if (exportParts) { PartExporter.ExportHostPart(exporterIFC, element, covering, productWrapper, setter, setter.LocalPlacement, null); } bool containInSpace = false; IFCAnyHandle localPlacementToUse = setter.LocalPlacement; // Ceiling containment in Space is generally required and not specific to any view if (ExporterCacheManager.CeilingSpaceRelCache.ContainsKey(element.Id)) { IList <ElementId> roomlist = ExporterCacheManager.CeilingSpaceRelCache[element.Id]; // Process Ceiling to be contained in a Space only when it is exactly bounding one Space if (roomlist.Count == 1) { productWrapper.AddElement(element, covering, setter, null, false); // Modify the Ceiling placement to be relative to the Space that it bounds IFCAnyHandle roomPlacement = IFCAnyHandleUtil.GetObjectPlacement(ExporterCacheManager.SpaceInfoCache.FindSpaceHandle(roomlist[0])); Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(roomPlacement, localPlacementToUse); Transform inverseTrf = relTrf.Inverse; IFCAnyHandle relLocalPlacement = ExporterUtil.CreateAxis2Placement3D(file, inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX); IFCAnyHandleUtil.SetAttribute(localPlacementToUse, "PlacementRelTo", roomPlacement); GeometryUtil.SetRelativePlacement(localPlacementToUse, relLocalPlacement); ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomlist[0], covering); containInSpace = true; } } // if not contained in Space, assign it to default containment in Level if (!containInSpace) { productWrapper.AddElement(element, covering, setter, null, true); } if (!exportParts) { Ceiling ceiling = element as Ceiling; if (ceiling != null) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, ceiling, covering, geomElem, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, null); } else { ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geomElem, exporterIFC, element); CategoryUtil.CreateMaterialAssociation(exporterIFC, covering, matId); } } OpeningUtil.CreateOpeningsIfNecessary(covering, element, ecData, null, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); } } transaction.Commit(); } }
private static void ExportAsMappedItem(ExporterIFC exporterIFC, Element element, IFCFile file, IFCExportType exportType, string ifcEnumType, IFCExtrusionCreationData extraParams, PlacementSetter setter, IFCAnyHandle localPlacementToUse, IFCAnyHandle productRepresentation, ProductWrapper productWrapper) { IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; ElementId typeId = element.GetTypeId(); ElementType type = element.Document.GetElement(typeId) as ElementType; IFCAnyHandle styleHandle = null; if (type != null) { FamilyTypeInfo currentTypeInfo = ExporterCacheManager.TypeObjectsCache.Find(typeId, false, exportType); bool found = currentTypeInfo.IsValid(); if (!found) { string typeObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, type); HashSet <IFCAnyHandle> propertySetsOpt = new HashSet <IFCAnyHandle>(); IList <IFCAnyHandle> repMapListOpt = new List <IFCAnyHandle>(); styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, propertySetsOpt, repMapListOpt, element, type); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) { propertySetsOpt = ExporterUtil.ExtractElementTypeProperties(exporterIFC, type, styleHandle); productWrapper.RegisterHandleWithElementType(type, styleHandle, propertySetsOpt); string applicableOccurrence = NamingUtil.GetObjectTypeOverride(type, typeObjectType); if (!string.IsNullOrEmpty(applicableOccurrence)) { IFCAnyHandleUtil.SetAttribute(styleHandle, "ApplicableOccurrence", applicableOccurrence); } currentTypeInfo.Style = styleHandle; ExporterCacheManager.TypeObjectsCache.Register(typeId, false, exportType, currentTypeInfo); } } else { styleHandle = currentTypeInfo.Style; } } string instanceGUID = GUIDUtil.CreateGUID(element); bool roomRelated = !FamilyExporterUtil.IsDistributionFlowElementSubType(exportType); ElementId roomId = ElementId.InvalidElementId; if (roomRelated) { roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse); } IFCAnyHandle instanceHandle = null; // For MEP objects string exportEntityStr = exportType.ToString(); Common.Enums.IFCEntityType exportEntity; if (String.Compare(exportEntityStr.Substring(exportEntityStr.Length - 4), "Type", true) == 0) { exportEntityStr = exportEntityStr.Substring(0, (exportEntityStr.Length - 4)); } if (Enum.TryParse(exportEntityStr, out exportEntity)) { // For MEP object creation instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportEntity, exporterIFC, element, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle)) { return; } if (roomId != ElementId.InvalidElementId) { //exporterIFC.RelateSpatialElement(roomId, instanceHandle); ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle); productWrapper.AddElement(element, instanceHandle, setter, extraParams, false); } else { productWrapper.AddElement(element, instanceHandle, setter, extraParams, true); } OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, element, extraParams, null, exporterIFC, localPlacementToUse, setter, productWrapper); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) { ExporterCacheManager.TypeRelationsCache.Add(styleHandle, instanceHandle); } PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper.GetAllObjects()); ExporterCacheManager.MEPCache.Register(element, instanceHandle); // add to system export cache // SystemExporter.ExportSystem(exporterIFC, element, instanceHandle); }
/// <summary> /// Exports a roof to IfcRoof. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="ifcEnumType">The roof type.</param> /// <param name="roof">The roof element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportRoof(ExporterIFC exporterIFC, string ifcEnumType, Element roof, GeometryElement geometryElement, ProductWrapper productWrapper) { if (roof == null || geometryElement == null) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, roof)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { // If the roof is an in-place family, we will allow any arbitrary orientation. While this may result in some // in-place "cubes" exporting with the wrong direction, it is unlikely that an in-place family would be // used for this reason in the first place. ecData.PossibleExtrusionAxes = (roof is FamilyInstance) ? IFCExtrusionAxes.TryXYZ : IFCExtrusionAxes.TryZ; ecData.AreInnerRegionsOpenings = true; ecData.SetLocalPlacement(placementSetter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(roof); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); BodyData bodyData; IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, roof, categoryId, geometryElement, bodyExporterOptions, null, ecData, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) { ecData.ClearOpenings(); return; } bool exportSlab = ecData.ScaledLength > MathUtil.Eps(); string guid = GUIDUtil.CreateGUID(roof); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string roofName = NamingUtil.GetNameOverride(roof, NamingUtil.GetIFCName(roof)); string roofDescription = NamingUtil.GetDescriptionOverride(roof, null); string roofObjectType = NamingUtil.GetObjectTypeOverride(roof, NamingUtil.CreateIFCObjectName(exporterIFC, roof)); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); string elementTag = NamingUtil.GetTagOverride(roof, NamingUtil.CreateIFCElementId(roof)); string roofType = GetIFCRoofType(ifcEnumType); roofType = IFCValidateEntry.GetValidIFCType(roof, ifcEnumType); IFCAnyHandle roofHnd = IFCInstanceExporter.CreateRoof(file, guid, ownerHistory, roofName, roofDescription, roofObjectType, localPlacement, exportSlab ? null : representation, elementTag, roofType); productWrapper.AddElement(roof, roofHnd, placementSetter.LevelInfo, ecData, true); // will export its host object materials later if it is a roof if (!(roof is RoofBase)) { CategoryUtil.CreateMaterialAssociations(exporterIFC, roofHnd, bodyData.MaterialIds); } if (exportSlab) { string slabGUID = GUIDUtil.CreateSubElementGUID(roof, (int)IFCRoofSubElements.RoofSlabStart); string slabName = roofName + ":1"; IFCAnyHandle slabLocalPlacementHnd = ExporterUtil.CopyLocalPlacement(file, localPlacement); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, slabGUID, ownerHistory, slabName, roofDescription, roofObjectType, slabLocalPlacementHnd, representation, elementTag, "ROOF"); Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity; OpeningUtil.CreateOpeningsIfNecessary(slabHnd, roof, ecData, offsetTransform, exporterIFC, slabLocalPlacementHnd, placementSetter, productWrapper); ExporterUtil.RelateObject(exporterIFC, roofHnd, slabHnd); productWrapper.AddElement(null, slabHnd, placementSetter.LevelInfo, ecData, false); CategoryUtil.CreateMaterialAssociations(exporterIFC, slabHnd, bodyData.MaterialIds); } } tr.Commit(); } } }
/// <summary> /// Exports a gutter element. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportGutter(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(setter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(); IFCAnyHandle bodyRep = BodyExporter.ExportBody(exporterIFC, element, categoryId, ElementId.InvalidElementId, geometryElement, bodyExporterOptions, ecData).RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { if (ecData != null) { ecData.ClearOpenings(); } return; } IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string originalTag = NamingUtil.CreateIFCElementId(element); // In Revit, we don't have a corresponding type, so we create one for every gutter. IFCAnyHandle origin = ExporterUtil.CreateAxis2Placement3D(file); IFCAnyHandle repMap3dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyRep); List <IFCAnyHandle> repMapList = new List <IFCAnyHandle>(); repMapList.Add(repMap3dHnd); string elementTypeName = NamingUtil.CreateIFCObjectName(exporterIFC, element); string typeGuid = GUIDUtil.CreateSubElementGUID(element, (int)IFCHostedSweepSubElements.PipeSegmentType); IFCAnyHandle style = IFCInstanceExporter.CreatePipeSegmentType(file, typeGuid, ownerHistory, elementTypeName, null, null, null, repMapList, originalTag, elementTypeName, IFCPipeSegmentType.Gutter); List <IFCAnyHandle> representationMaps = GeometryUtil.GetRepresentationMaps(style); IFCAnyHandle mappedItem = ExporterUtil.CreateDefaultMappedItem(file, representationMaps[0]); ISet <IFCAnyHandle> representations = new HashSet <IFCAnyHandle>(); representations.Add(mappedItem); IFCAnyHandle bodyMappedItemRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, element, categoryId, exporterIFC.Get3DContextHandle("Body"), representations); if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyMappedItemRep)) { return; } List <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(bodyMappedItemRep); IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); if (boundingBoxRep != null) { shapeReps.Add(boundingBoxRep); } IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); IFCAnyHandle localPlacementToUse; ElementId roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse); if (roomId == ElementId.InvalidElementId) { localPlacementToUse = ecData.GetLocalPlacement(); } string guid = GUIDUtil.CreateGUID(element); string name = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, elementTypeName); string tag = NamingUtil.GetTagOverride(element, originalTag); IFCAnyHandle elemHnd = IFCInstanceExporter.CreateFlowSegment(file, guid, ownerHistory, name, description, objectType, localPlacementToUse, prodRep, tag); bool containedInSpace = (roomId != ElementId.InvalidElementId); productWrapper.AddElement(element, elemHnd, setter.LevelInfo, ecData, !containedInSpace); if (containedInSpace) { ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, elemHnd); } // Associate segment with type. ExporterCacheManager.TypeRelationsCache.Add(style, elemHnd); OpeningUtil.CreateOpeningsIfNecessary(elemHnd, element, ecData, null, exporterIFC, localPlacementToUse, setter, productWrapper); } tr.Commit(); } } }
/// <summary> /// Exports an element to IFC footing. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="element"> /// The element. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="ifcEnumType"> /// The string value represents the IFC type. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportFooting(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, string ifcEnumType, ProductWrapper productWrapper) { // export parts or not bool exportParts = PartExporter.CanExportParts(element); if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false)) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(setter.LocalPlacement); IFCAnyHandle prodRep = null; ElementId matId = ElementId.InvalidElementId; if (!exportParts) { ElementId catId = CategoryUtil.GetSafeCategoryId(element); matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, ecData, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) { ecData.ClearOpenings(); return; } } string instanceGUID = GUIDUtil.CreateGUID(element); string instanceName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string instanceDescription = NamingUtil.GetDescriptionOverride(element, null); string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string instanceTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); string footingType = GetIFCFootingType(ifcEnumType); // need to keep it for legacy support when original data follows slightly diff naming footingType = IFCValidateEntry.GetValidIFCType(element, footingType); IFCAnyHandle footing = IFCInstanceExporter.CreateFooting(file, instanceGUID, exporterIFC.GetOwnerHistoryHandle(), instanceName, instanceDescription, instanceObjectType, ecData.GetLocalPlacement(), prodRep, instanceTag, footingType); if (exportParts) { PartExporter.ExportHostPart(exporterIFC, element, footing, productWrapper, setter, setter.LocalPlacement, null); } else { if (matId != ElementId.InvalidElementId) { CategoryUtil.CreateMaterialAssociation(exporterIFC, footing, matId); } } productWrapper.AddElement(element, footing, setter, ecData, true); OpeningUtil.CreateOpeningsIfNecessary(footing, element, ecData, null, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); } } tr.Commit(); } }
/// <summary> /// Exports a beam to IFC beam if it has an axis representation and only one Solid as its geometry, ideally as an extrusion, potentially with clippings and openings. /// </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> /// <param name="dontExport">An output value that says that the element shouldn't be exported at all.</param> /// <returns>The created handle.</returns> /// <remarks>In the original implementation, the ExportBeam function would export each beam as its own individual geometry (that is, not use representation maps). /// For non-standard beams, this could result in massive IFC files. Now, we use the ExportBeamAsStandardElement function and limit its scope, and instead /// resort to the standard FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem for more complicated objects categorized as beams. This has the following pros and cons: /// Pro: possiblity for massively reduced file sizes for files containing repeated complex beam families /// Con: some beams that may have had an "Axis" representation before will no longer have them, although this possibility is minimized. /// Con: some beams that have 1 Solid and an axis, but that Solid will be heavily faceted, won't be helped by this improvement. /// It is intended that we phase out this routine entirely and instead teach ExportFamilyInstanceAsMappedItem how to sometimes export the Axis representation for beams.</remarks> public static IFCAnyHandle ExportBeamAsStandardElement(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper, out bool dontExport) { dontExport = true; IList <GeometryObject> geomObjects = BeamGeometryToExport(exporterIFC, element, geometryElement, out dontExport); if (dontExport) { return(null); } IFCAnyHandle beam = null; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { BeamAxisInfo axisInfo = GetBeamAxisTransform(element); bool canExportAxis = (axisInfo != null); Curve curve = canExportAxis ? axisInfo.Axis : null; XYZ beamDirection = canExportAxis ? axisInfo.AxisDirection : null; Transform orientTrf = canExportAxis ? axisInfo.LCSAsTransform : null; using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, orientTrf)) { IFCAnyHandle localPlacement = setter.LocalPlacement; 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; } ElementId catId = CategoryUtil.GetSafeCategoryId(element); // 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; // The list of materials in the solids or meshes. ICollection <ElementId> materialIds = null; // The representation handle generated from one of the methods below. BeamBodyAsExtrusionInfo extrusionInfo = CreateBeamGeometryAsExtrusion(exporterIFC, element, catId, geomObjects, axisInfo); if (extrusionInfo != null && extrusionInfo.DontExport) { dontExport = true; return(null); } IFCAnyHandle repHnd = (extrusionInfo != null) ? extrusionInfo.RepresentationHandle : null; if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd)) { materialIds = extrusionInfo.Materials; extrusionCreationData.Slope = extrusionInfo.Slope; } else { // Here is where we limit the scope of how complex a case we will still try to export as a standard element. // This is explicitly added so that many curved beams that can be represented by a reasonable facetation because of the // SweptSolidExporter can still have an Axis representation. BodyData bodyData = null; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); if (geomObjects != null && geomObjects.Count == 1 && geomObjects[0] is Solid) { bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, geomObjects[0], bodyExporterOptions, extrusionCreationData); repHnd = bodyData.RepresentationHnd; materialIds = bodyData.MaterialIds; offsetTransform = bodyData.OffsetTransform; } } if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd)) { extrusionCreationData.ClearOpenings(); return(null); } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); IFCAnyHandle axisRep = CreateBeamAxis(exporterIFC, element, catId, axisInfo, offsetTransform); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisRep)) { 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)); string preDefinedType = "BEAM"; // Default predefined type for Beam preDefinedType = IFCValidateEntry.GetValidIFCType(element, preDefinedType); beam = IFCInstanceExporter.CreateBeam(file, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, instanceName, instanceDescription, instanceObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, instanceTag, preDefinedType); 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, null); 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(); return(beam); } }
/// <summary> /// Exports a generic element as an IfcSlab.</summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="floor">The floor element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="ifcEnumType">The string value represents the IFC type.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if the floor is exported successfully, false otherwise.</returns> public static void ExportGenericSlab(ExporterIFC exporterIFC, Element slabElement, GeometryElement geometryElement, string ifcEnumType, ProductWrapper productWrapper) { if (geometryElement == null) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCTransformSetter transformSetter = IFCTransformSetter.Create()) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, slabElement)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { bool exportParts = PartExporter.CanExportParts(slabElement); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle localPlacement = placementSetter.LocalPlacement; IFCAnyHandle prodDefHnd = null; bool isBRepSlabHnd = false; if (!exportParts) { ecData.SetLocalPlacement(localPlacement); ElementId catId = CategoryUtil.GetSafeCategoryId(slabElement); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium); BodyData bodyData; prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, slabElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd)) { ecData.ClearOpenings(); return; } isBRepSlabHnd = (bodyData.ShapeRepresentationType == ShapeRepresentationType.Brep); } // Create the slab from either the extrusion or the BRep information. string ifcGUID = GUIDUtil.CreateGUID(slabElement); string entityType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(slabElement, ifcEnumType, "FLOOR"); string ifcName = NamingUtil.GetNameOverride(slabElement, NamingUtil.GetIFCName(slabElement)); string ifcDescription = NamingUtil.GetDescriptionOverride(slabElement, null); string ifcObjectType = NamingUtil.GetObjectTypeOverride(slabElement, exporterIFC.GetFamilyName()); string ifcTag = NamingUtil.GetTagOverride(slabElement, NamingUtil.CreateIFCElementId(slabElement)); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, ifcGUID, ownerHistory, ifcName, ifcDescription, ifcObjectType, localPlacement, exportParts ? null : prodDefHnd, ifcTag, entityType); if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd)) { return; } if (exportParts) { PartExporter.ExportHostPart(exporterIFC, slabElement, slabHnd, productWrapper, placementSetter, localPlacement, null); } productWrapper.AddElement(slabElement, slabHnd, placementSetter, ecData, true); if (!exportParts) { if (slabElement is HostObject) { HostObject hostObject = slabElement as HostObject; HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, slabHnd, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, isBRepSlabHnd); } else if (slabElement is FamilyInstance) { ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, slabElement); Document doc = slabElement.Document; CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, matId); } OpeningUtil.CreateOpeningsIfNecessary(slabHnd, slabElement, ecData, null, exporterIFC, ecData.GetLocalPlacement(), placementSetter, productWrapper); } } } tr.Commit(); return; } } }
/// <summary> /// Exports an element as IFC railing. /// </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 IFCProductWrapper. /// </param> public static void ExportRailing(ExporterIFC exporterIFC, Element element, GeometryElement geomElem, string ifcEnumType, IFCProductWrapper productWrapper) { ElementType elemType = element.Document.GetElement(element.GetTypeId()) as ElementType; IFCFile file = exporterIFC.GetFile(); Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(setter.GetPlacement()); SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSolidMeshGeometry(geomElem, Transform.Identity); IList <Solid> solids = solidMeshInfo.GetSolids(); IList <Mesh> meshes = solidMeshInfo.GetMeshes(); Railing railingElem = element as Railing; IList <ElementId> subElementIds = CollectSubElements(railingElem); foreach (ElementId subElementId in subElementIds) { Element subElement = railingElem.Document.GetElement(subElementId); if (subElement != null) { GeometryElement subElementGeom = GeometryUtil.GetOneLevelGeometryElement(subElement.get_Geometry(geomOptions)); SolidMeshGeometryInfo subElementSolidMeshInfo = GeometryUtil.GetSolidMeshGeometry(subElementGeom, Transform.Identity); IList <Solid> subElementSolids = subElementSolidMeshInfo.GetSolids(); IList <Mesh> subElementMeshes = subElementSolidMeshInfo.GetMeshes(); foreach (Solid subElementSolid in subElementSolids) { solids.Add(subElementSolid); } foreach (Mesh subElementMesh in subElementMeshes) { meshes.Add(subElementMesh); } } } ElementId catId = CategoryUtil.GetSafeCategoryId(element); BodyData bodyData = null; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); //bodyExporterOptions.UseGroupsIfPossible = true; //bodyExporterOptions.UseMappedGeometriesIfPossible = true; bodyExporterOptions.TessellationLevel = BodyExporterOptions.BodyTessellationLevel.Coarse; if (solids.Count > 0 || meshes.Count > 0) { bodyData = BodyExporter.ExportBody(element.Document.Application, exporterIFC, element, catId, solids, meshes, bodyExporterOptions, ecData); } else { IList <GeometryObject> geomlist = new List <GeometryObject>(); geomlist.Add(geomElem); bodyData = BodyExporter.ExportBody(element.Document.Application, exporterIFC, element, catId, geomlist, bodyExporterOptions, ecData); } IFCAnyHandle bodyRep = bodyData.RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { if (ecData != null) { ecData.ClearOpenings(); } return; } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(bodyRep); IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string instanceGUID = ExporterIFCUtils.CreateGUID(element); string origInstanceName = exporterIFC.GetName(); string instanceName = NamingUtil.GetNameOverride(element, origInstanceName); string instanceDescription = NamingUtil.GetDescriptionOverride(element, null); string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string instanceElemId = NamingUtil.CreateIFCElementId(element); Toolkit.IFCRailingType railingType = GetIFCRailingType(element, ifcEnumType); IFCAnyHandle railing = IFCInstanceExporter.CreateRailing(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, ecData.GetLocalPlacement(), prodRep, instanceElemId, railingType); ElementId hostId = GetStairOrRampHostId(exporterIFC, element as Railing); bool associateToLevel = (hostId == ElementId.InvalidElementId) && LevelUtil.AssociateElementToLevel(element); productWrapper.AddElement(railing, setter, ecData, associateToLevel); OpeningUtil.CreateOpeningsIfNecessary(railing, element, ecData, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); CategoryUtil.CreateMaterialAssociations(element.Document, exporterIFC, railing, bodyData.MaterialIds); // Create multi-story duplicates of this railing. if (hostId != ElementId.InvalidElementId) { StairRampContainerInfo stairRampInfo = ExporterCacheManager.StairRampContainerInfoCache.GetStairRampContainerInfo(hostId); stairRampInfo.AddComponent(0, railing); List <IFCAnyHandle> stairHandles = stairRampInfo.StairOrRampHandles; for (int ii = 1; ii < stairHandles.Count; ii++) { IFCAnyHandle railingLocalPlacement = stairRampInfo.LocalPlacements[ii]; if (!IFCAnyHandleUtil.IsNullOrHasNoValue(railingLocalPlacement)) { IFCAnyHandle railingHndCopy = CopyRailingHandle(exporterIFC, element, catId, railingLocalPlacement, railing); stairRampInfo.AddComponent(ii, railingHndCopy); productWrapper.AddElement(railingHndCopy, (IFCLevelInfo)null, ecData, false); CategoryUtil.CreateMaterialAssociations(element.Document, exporterIFC, railingHndCopy, bodyData.MaterialIds); } } ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(hostId, stairRampInfo); } PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper); } transaction.Commit(); } } }