/// <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, GeometryElement geometryElement, ProductWrapper productWrapper) { if (geometryElement == null) { return; } // export parts or not bool exportParts = PartExporter.CanExportParts(floorElement); if (exportParts && !PartExporter.CanExportElementInPartExport(floorElement, floorElement.LevelId, false)) { return; } string ifcEnumType; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, floorElement, out ifcEnumType); IFCFile file = exporterIFC.GetFile(); IList <IFCAnyHandle> slabHnds = new List <IFCAnyHandle>(); IList <IFCAnyHandle> brepSlabHnds = new List <IFCAnyHandle>(); IList <IFCAnyHandle> nonBrepSlabHnds = new List <IFCAnyHandle>(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCTransformSetter transformSetter = IFCTransformSetter.Create()) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, floorElement)) { IFCAnyHandle localPlacement = placementSetter.LocalPlacement; IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); 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(); IList <IFCAnyHandle> localPlacements = new List <IFCAnyHandle>(); if (!exportParts && (floorElement is Floor)) { Floor floor = floorElement as Floor; // First, 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(); if (solids.Count == 1 && meshes.Count == 0) { bool completelyClipped; 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 thruough te Revit model orgigin. 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 extrusionAnalyzerFloorPlane = new Plane(floorDir, floorOrigin); HandleAndData floorAndProperties = ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, floorElement, catId, solids[0], extrusionAnalyzerFloorPlane, floorExtrusionDirection, null, out completelyClipped); if (completelyClipped) { return; } if (floorAndProperties.Handle != null) { IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(floorAndProperties.Handle); IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); prodReps.Add(prodRep); repTypes.Add(ShapeRepresentationType.SweptSolid); if (floorAndProperties.Data != null) { loopExtraParams.Add(floorAndProperties.Data); } } } } } // Use internal routine as backup that handles openings. if (prodReps.Count == 0) { exportedAsInternalExtrusion = ExporterIFCUtils.ExportSlabAsExtrusion(exporterIFC, floorElement, geometryElement, transformSetter, localPlacement, out localPlacements, out prodReps, out extrusionLoops, out loopExtraParams, floorPlane); for (int ii = 0; ii < prodReps.Count; ii++) { // all are extrusions repTypes.Add(ShapeRepresentationType.SweptSolid); } } if (prodReps.Count == 0) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); bodyExporterOptions.TessellationLevel = BodyExporter.GetTessellationLevel(); BodyData bodyData; IFCAnyHandle 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; string entityType = null; switch (exportType) { case IFCExportType.IfcFooting: if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { entityType = IFCValidateEntry.GetValidIFCType <Revit.IFC.Export.Toolkit.IFC4.IFCFootingType>(floorElement, ifcEnumType, null); } else { entityType = IFCValidateEntry.GetValidIFCType <IFCFootingType>(floorElement, ifcEnumType, null); } break; case IFCExportType.IfcCovering: entityType = IFCValidateEntry.GetValidIFCType <IFCCoveringType>(floorElement, ifcEnumType, "FLOORING"); break; case IFCExportType.IfcRamp: if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { entityType = IFCValidateEntry.GetValidIFCType <Revit.IFC.Export.Toolkit.IFC4.IFCRampType>(floorElement, ifcEnumType, null); } else { entityType = IFCValidateEntry.GetValidIFCType <IFCRampType>(floorElement, ifcEnumType, null); } break; default: bool isBaseSlab = false; AnalyticalModel analyticalModel = floorElement.GetAnalyticalModel(); if (analyticalModel != null) { AnalyzeAs slabFoundationType = analyticalModel.GetAnalyzeAs(); isBaseSlab = (slabFoundationType == AnalyzeAs.SlabOnGrade) || (slabFoundationType == AnalyzeAs.Mat); } entityType = 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 ifcDescription = NamingUtil.GetDescriptionOverride(floorElement, null); string ifcObjectType = NamingUtil.GetObjectTypeOverride(floorElement, exporterIFC.GetFamilyName()); string ifcTag = NamingUtil.GetTagOverride(floorElement, NamingUtil.CreateIFCElementId(floorElement)); string currentGUID = (ii == 0) ? ifcGUID : GUIDUtil.CreateGUID(); IFCAnyHandle localPlacementHnd = exportedAsInternalExtrusion ? localPlacements[ii] : localPlacement; IFCAnyHandle slabHnd = null; // TODO: replace with CreateGenericBuildingElement. switch (exportType) { case IFCExportType.IfcFooting: slabHnd = IFCInstanceExporter.CreateFooting(file, currentGUID, ownerHistory, ifcName, ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii], ifcTag, entityType); break; case IFCExportType.IfcCovering: slabHnd = IFCInstanceExporter.CreateCovering(file, currentGUID, ownerHistory, ifcName, ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii], ifcTag, entityType); break; case IFCExportType.IfcRamp: slabHnd = IFCInstanceExporter.CreateRamp(file, currentGUID, ownerHistory, ifcName, ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii], ifcTag, entityType); break; default: slabHnd = IFCInstanceExporter.CreateSlab(file, currentGUID, ownerHistory, ifcName, ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii], ifcTag, entityType); break; } if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd)) { return; } if (exportParts) { PartExporter.ExportHostPart(exporterIFC, floorElement, slabHnd, productWrapper, placementSetter, localPlacementHnd, null); } slabHnds.Add(slabHnd); if (!exportParts) { if (repTypes[ii] == ShapeRepresentationType.Brep) { brepSlabHnds.Add(slabHnd); } else { nonBrepSlabHnds.Add(slabHnd); } } } for (int ii = 0; ii < numReps; ii++) { IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null; productWrapper.AddElement(floorElement, slabHnds[ii], placementSetter, loopExtraParam, true); } if (exportedAsInternalExtrusion) { ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, floorElement, placementSetter.LevelInfo, localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative()); } } if (!exportParts) { if (nonBrepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, nonBrepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false); } if (brepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, brepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, true); } } } tr.Commit(); return; } }
/// <summary> /// Exports a generic family instance as IFC instance. /// </summary> /// <param name="type">The export type.</param> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="familyInstance">The element.</param> /// <param name="wrapper">The ProductWrapper.</param> /// <param name="setter">The PlacementSetter.</param> /// <param name="extraParams">The extrusion creation data.</param> /// <param name="instanceGUID">The guid.</param> /// <param name="ownerHistory">The owner history handle.</param> /// <param name="instanceName">The name.</param> /// <param name="instanceDescription">The description.</param> /// <param name="instanceObjectType">The object type.</param> /// <param name="productRepresentation">The representation handle.</param> /// <param name="instanceTag">The tag for the entity, usually based on the element id.</param> /// <param name="ifcEnumType">The predefined type/shape type, if any, for the object.</param> /// <param name="overrideLocalPlacement">The local placement to use instead of the one in the placement setter, if appropriate.</param> /// <returns>The handle.</returns> public static IFCAnyHandle ExportGenericInstance(IFCExportInfoPair type, ExporterIFC exporterIFC, Element familyInstance, ProductWrapper wrapper, PlacementSetter setter, IFCExtrusionCreationData extraParams, string instanceGUID, IFCAnyHandle ownerHistory, IFCAnyHandle productRepresentation, string ifcEnumType, IFCAnyHandle overrideLocalPlacement) { IFCFile file = exporterIFC.GetFile(); Document doc = familyInstance.Document; bool isRoomRelated = IsRoomRelated(type); bool isChildInContainer = familyInstance.AssemblyInstanceId != ElementId.InvalidElementId; IFCAnyHandle localPlacementToUse = setter.LocalPlacement; ElementId roomId = ElementId.InvalidElementId; if (isRoomRelated) { roomId = setter.UpdateRoomRelativeCoordinates(familyInstance, out localPlacementToUse); } //should remove the create method where there is no use of this handle for API methods //some places uses the return value of ExportGenericInstance as input parameter for API methods IFCAnyHandle instanceHandle = null; switch (type.ExportInstance) { case IFCEntityType.IfcBeam: { string preDefinedType = string.IsNullOrWhiteSpace(ifcEnumType) ? "BEAM" : ifcEnumType; instanceHandle = IFCInstanceExporter.CreateBeam(exporterIFC, familyInstance, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation, preDefinedType); break; } case IFCEntityType.IfcColumn: { string preDefinedType = string.IsNullOrWhiteSpace(ifcEnumType) ? "COLUMN" : ifcEnumType; instanceHandle = IFCInstanceExporter.CreateColumn(exporterIFC, familyInstance, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation, preDefinedType); break; } case IFCEntityType.IfcCurtainWall: { instanceHandle = IFCInstanceExporter.CreateCurtainWall(exporterIFC, familyInstance, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation, ifcEnumType); break; } case IFCEntityType.IfcMember: { string preDefinedType = string.IsNullOrWhiteSpace(ifcEnumType) ? "BRACE" : ifcEnumType; instanceHandle = IFCInstanceExporter.CreateMember(exporterIFC, familyInstance, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation, preDefinedType); // Register the members's IFC handle for later use by truss export. ExporterCacheManager.ElementToHandleCache.Register(familyInstance.Id, instanceHandle); break; } case IFCEntityType.IfcPlate: { IFCAnyHandle localPlacement = localPlacementToUse; if (overrideLocalPlacement != null) { isChildInContainer = true; localPlacement = overrideLocalPlacement; } string preDefinedType = string.IsNullOrWhiteSpace(ifcEnumType) ? "NOTDEFINED" : ifcEnumType; instanceHandle = IFCInstanceExporter.CreatePlate(exporterIFC, familyInstance, instanceGUID, ownerHistory, localPlacement, productRepresentation, preDefinedType); break; } case IFCEntityType.IfcMechanicalFastener: { double?nominalDiameter = null; double?nominalLength = null; double nominalDiameterVal, nominalLengthVal; if (ParameterUtil.GetDoubleValueFromElementOrSymbol(familyInstance, "NominalDiameter", out nominalDiameterVal) != null) { nominalDiameter = UnitUtil.ScaleLength(nominalDiameterVal); } if (ParameterUtil.GetDoubleValueFromElementOrSymbol(familyInstance, "NominalLength", out nominalLengthVal) != null) { nominalLength = UnitUtil.ScaleLength(nominalLengthVal); } string preDefinedType = string.IsNullOrWhiteSpace(ifcEnumType) ? "NOTDEFINED" : ifcEnumType; instanceHandle = IFCInstanceExporter.CreateMechanicalFastener(exporterIFC, familyInstance, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation, nominalDiameter, nominalLength, preDefinedType); break; } case IFCEntityType.IfcRailing: { string strEnumType; IFCExportInfoPair exportAs = ExporterUtil.GetExportType(exporterIFC, familyInstance, out strEnumType); if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { instanceHandle = IFCInstanceExporter.CreateRailing(exporterIFC, familyInstance, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation, GetPreDefinedType <Toolkit.IFC4.IFCRailingType>(familyInstance, strEnumType).ToString()); } else { instanceHandle = IFCInstanceExporter.CreateRailing(exporterIFC, familyInstance, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation, GetPreDefinedType <Toolkit.IFCRailingType>(familyInstance, strEnumType).ToString()); } break; } case IFCEntityType.IfcSpace: { IFCInternalOrExternal internalOrExternal = CategoryUtil.IsElementExternal(familyInstance) ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal; instanceHandle = IFCInstanceExporter.CreateSpace(exporterIFC, familyInstance, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation, IFCElementComposition.Element, internalOrExternal, null); break; } default: { // !!! These entities are deprecated in IFC4 and will be made abstract in the next version. // It is still kept as it is because if we generate an IfcBuildingElementProxy, teh connectivity will be lost if (ExporterCacheManager.ExportOptionsCache.ExportAs4 && (type.ExportInstance == IFCEntityType.IfcDistributionElement || type.ExportInstance == IFCEntityType.IfcEnergyConversionDevice || type.ExportInstance == IFCEntityType.IfcFlowController || type.ExportInstance == IFCEntityType.IfcFlowFitting || type.ExportInstance == IFCEntityType.IfcFlowMovingDevice || type.ExportInstance == IFCEntityType.IfcFlowSegment || type.ExportInstance == IFCEntityType.IfcFlowStorageDevice || type.ExportInstance == IFCEntityType.IfcFlowTerminal || type.ExportInstance == IFCEntityType.IfcFlowTreatmentDevice)) { // for IFC4, there are several entities that are valid in IFC2x3 but now have been made abstract or deprecated, so cannot be created. Create proxy instead. //instanceHandle = IFCInstanceExporter.CreateBuildingElementProxy(file, instanceGUID, ownerHistory, // instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag, // Toolkit.IFC4.IFCBuildingElementProxyType.USERDEFINED.ToString()); instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(type, exporterIFC, familyInstance, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation); } else { if (type.ExportInstance != IFCEntityType.UnKnown) { instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(type, exporterIFC, familyInstance, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation); } } break; } } if (!IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle)) { bool containedInSpace = (roomId != ElementId.InvalidElementId); bool associateToLevel = containedInSpace ? false : !isChildInContainer; wrapper.AddElement(familyInstance, instanceHandle, setter, extraParams, associateToLevel); if (containedInSpace) { ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle); } } return(instanceHandle); }
/// <summary> /// Exports an element as building element proxy. /// </summary> /// <remarks> /// This function is called from the Export function, but can also be called directly if you do not /// want CreateInternalPropertySets to be called. /// </remarks> /// <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> /// <returns>The handle if created, null otherwise.</returns> public static IFCAnyHandle ExportBuildingElementProxy(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { if (element == null || geometryElement == null) { return(null); } // 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>("IfcBuildingElementProxy", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return(null); } } IFCFile file = exporterIFC.GetFile(); IFCAnyHandle buildingElementProxy = null; using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(placementSetter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, categoryId, geometryElement, bodyExporterOptions, null, ecData, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) { ecData.ClearOpenings(); return(null); } string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string revitObjectType = exporterIFC.GetFamilyName(); string name = NamingUtil.GetNameOverride(element, revitObjectType); string description = NamingUtil.GetDescriptionOverride(element, null); string objectType = NamingUtil.GetObjectTypeOverride(element, revitObjectType); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); string elementTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); buildingElementProxy = IFCInstanceExporter.CreateBuildingElementProxy(file, guid, ownerHistory, name, description, objectType, localPlacement, representation, elementTag, null); productWrapper.AddElement(element, buildingElementProxy, placementSetter.LevelInfo, ecData, true); } tr.Commit(); } } return(buildingElementProxy); }
/// <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(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; } IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; 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> /// 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); IFCAnyHandle ifcPart = null; if (!asBuildingElement) { ifcPart = IFCInstanceExporter.CreateBuildingElementPart(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep); } 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(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; case IFCExportType.IfcCovering: ifcPart = IFCInstanceExporter.CreateCovering(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; case IFCExportType.IfcFooting: ifcPart = IFCInstanceExporter.CreateFooting(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; case IFCExportType.IfcPile: ifcPart = IFCInstanceExporter.CreatePile(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType, null); break; case IFCExportType.IfcRoof: ifcPart = IFCInstanceExporter.CreateRoof(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; case IFCExportType.IfcSlab: ifcPart = IFCInstanceExporter.CreateSlab(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; case IFCExportType.IfcWall: ifcPart = IFCInstanceExporter.CreateWall(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; default: ifcPart = IFCInstanceExporter.CreateBuildingElementProxy(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, 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 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="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(); } } } }
private static bool ExportStandardFabricSheet(FabricSheetExportConfig cfg) { if (cfg.Equals(null)) { return(false); } string guid = GUIDUtil.CreateGUID(cfg.Sheet); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; int ii = 0; do { WireDistributionDirection dir = (WireDistributionDirection)ii; IList <Curve> wireCenterlines = cfg.Sheet?.GetWireCenterlines(dir); for (int jj = 0; jj < wireCenterlines.Count; jj++) { double wireDiam = 0.0; Element wireTypeElem = (dir == WireDistributionDirection.Major) ? cfg.Doc?.GetElement(cfg.SheetType?.MajorDirectionWireType) : cfg.Doc?.GetElement(cfg.SheetType?.MinorDirectionWireType); if (wireTypeElem is FabricWireType wireType) { wireDiam = UnitUtil.ScaleLength(wireType.WireDiameter); } IFCAnyHandle bodyItem = GeometryUtil.CreateSweptDiskSolid(cfg.ExporterIFC, cfg.File, wireCenterlines[jj], wireDiam / 2.0, null); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItem)) { cfg.BodyItems?.Add(bodyItem); } } ii++; }while (ii < 2); IFCAnyHandle shapeRep = null; if (cfg.BodyItems.Count > 0) { shapeRep = RepresentationUtil.CreateAdvancedSweptSolidRep(cfg.ExporterIFC, cfg.Sheet, cfg.CategoryId, cfg.ExporterIFC.Get3DContextHandle("Body"), cfg.BodyItems, null); } IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); if (shapeRep != null) { shapeReps.Add(shapeRep); } IFCAnyHandle prodRep = (shapeReps != null) ? IFCInstanceExporter.CreateProductDefinitionShape(cfg.File, null, null, shapeReps) : null; GetFabricSheetParams(cfg.Sheet, out string steelGrade, out double meshLength, out double meshWidth, out double longitudinalBarNominalDiameter, out double transverseBarNominalDiameter, out double longitudinalBarCrossSectionArea, out double transverseBarCrossSectionArea, out double longitudinalBarSpacing, out double transverseBarSpacing); IFCAnyHandle handle = IFCInstanceExporter.CreateReinforcingMesh(cfg.ExporterIFC, cfg.Sheet, guid, ownerHistory, cfg.EcData.GetLocalPlacement(), prodRep, steelGrade, meshLength, meshWidth, longitudinalBarNominalDiameter, transverseBarNominalDiameter, longitudinalBarCrossSectionArea, transverseBarCrossSectionArea, longitudinalBarSpacing, transverseBarSpacing); IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcReinforcingMesh); ElementId fabricAreaId = cfg.Sheet?.FabricAreaOwnerId; if (fabricAreaId != ElementId.InvalidElementId) { if (!ExporterCacheManager.FabricAreaHandleCache.TryGetValue(fabricAreaId, out HashSet <IFCAnyHandle> fabricSheets)) { fabricSheets = new HashSet <IFCAnyHandle>(); ExporterCacheManager.FabricAreaHandleCache[fabricAreaId] = fabricSheets; } fabricSheets.Add(handle); } cfg.ProductWrapper.AddElement(cfg.Sheet, handle, cfg.PlacementSetter?.LevelInfo, cfg.EcData, true, exportInfo); CategoryUtil.CreateMaterialAssociation(cfg.ExporterIFC, handle, cfg.MaterialId); return(true); }
/// <summary> /// Exports the top stories of a multistory ramp. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="ramp">The ramp element.</param> /// <param name="numFlights">The number of flights for a multistory ramp.</param> /// <param name="rampHnd">The stairs container handle.</param> /// <param name="components">The components handles.</param> /// <param name="ecData">The extrusion creation data.</param> /// <param name="componentECData">The extrusion creation data for the components.</param> /// <param name="placementSetter">The placement setter.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportMultistoryRamp(ExporterIFC exporterIFC, Element ramp, int numFlights, IFCAnyHandle rampHnd, IList <IFCAnyHandle> components, IList <IFCExtrusionCreationData> componentECData, PlacementSetter placementSetter, ProductWrapper productWrapper) { if (numFlights < 2) { return; } double heightNonScaled = GetRampHeight(exporterIFC, ramp); if (heightNonScaled < MathUtil.Eps()) { return; } if (IFCAnyHandleUtil.IsNullOrHasNoValue(rampHnd)) { return; } IFCAnyHandle localPlacement = IFCAnyHandleUtil.GetObjectPlacement(rampHnd); if (IFCAnyHandleUtil.IsNullOrHasNoValue(localPlacement)) { return; } IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCFile file = exporterIFC.GetFile(); IFCAnyHandle relPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement); IFCAnyHandle ptHnd = IFCAnyHandleUtil.GetLocation(relPlacement); IList <double> origCoords = IFCAnyHandleUtil.GetCoordinates(ptHnd); IList <IFCAnyHandle> rampLocalPlacementHnds = new List <IFCAnyHandle>(); IList <IFCLevelInfo> levelInfos = new List <IFCLevelInfo>(); for (int ii = 0; ii < numFlights - 1; ii++) { IFCAnyHandle newLevelHnd = null; // We are going to avoid internal scaling routines, and instead scale in .NET. double newOffsetUnscaled = 0.0; IFCLevelInfo currLevelInfo = placementSetter.GetOffsetLevelInfoAndHandle(heightNonScaled * (ii + 1), 1.0, ramp.Document, out newLevelHnd, out newOffsetUnscaled); double newOffsetScaled = UnitUtil.ScaleLength(newOffsetUnscaled); if (currLevelInfo != null) { levelInfos.Add(currLevelInfo); } else { levelInfos.Add(placementSetter.LevelInfo); } XYZ orig; if (ptHnd.HasValue) { orig = new XYZ(origCoords[0], origCoords[1], newOffsetScaled); } else { orig = new XYZ(0.0, 0.0, newOffsetScaled); } rampLocalPlacementHnds.Add(ExporterUtil.CreateLocalPlacement(file, newLevelHnd, orig, null, null)); } IList <List <IFCAnyHandle> > newComponents = new List <List <IFCAnyHandle> >(); for (int ii = 0; ii < numFlights - 1; ii++) { newComponents.Add(new List <IFCAnyHandle>()); } int compIdx = 0; ElementId catId = CategoryUtil.GetSafeCategoryId(ramp); foreach (IFCAnyHandle component in components) { string componentName = IFCAnyHandleUtil.GetStringAttribute(component, "Name"); string componentDescription = IFCAnyHandleUtil.GetStringAttribute(component, "Description"); string componentObjectType = IFCAnyHandleUtil.GetStringAttribute(component, "ObjectType"); string componentElementTag = IFCAnyHandleUtil.GetStringAttribute(component, "Tag"); IFCAnyHandle componentProdRep = IFCAnyHandleUtil.GetInstanceAttribute(component, "Representation"); IList <string> localComponentNames = new List <string>(); IList <IFCAnyHandle> componentPlacementHnds = new List <IFCAnyHandle>(); IFCAnyHandle localLocalPlacement = IFCAnyHandleUtil.GetObjectPlacement(component); IFCAnyHandle localRelativePlacement = (localLocalPlacement == null) ? null : IFCAnyHandleUtil.GetInstanceAttribute(localLocalPlacement, "RelativePlacement"); bool isSubRamp = component.IsSubTypeOf(IFCEntityType.IfcRamp.ToString()); for (int ii = 0; ii < numFlights - 1; ii++) { localComponentNames.Add((componentName == null) ? (ii + 2).ToString() : (componentName + ":" + (ii + 2))); if (isSubRamp) { componentPlacementHnds.Add(ExporterUtil.CopyLocalPlacement(file, rampLocalPlacementHnds[ii])); } else { componentPlacementHnds.Add(IFCInstanceExporter.CreateLocalPlacement(file, rampLocalPlacementHnds[ii], localRelativePlacement)); } } IList <IFCAnyHandle> localComponentHnds = new List <IFCAnyHandle>(); if (isSubRamp) { string componentType = IFCAnyHandleUtil.GetEnumerationAttribute(component, ExporterCacheManager.ExportOptionsCache.ExportAs4 ? "PredefinedType" : "ShapeType"); string localRampType = GetIFCRampType(componentType); for (int ii = 0; ii < numFlights - 1; ii++) { IFCAnyHandle representationCopy = ExporterUtil.CopyProductDefinitionShape(exporterIFC, ramp, catId, componentProdRep); localComponentHnds.Add(IFCInstanceExporter.CreateRamp(file, GUIDUtil.CreateGUID(), ownerHistory, localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy, componentElementTag, localRampType)); } } else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcRampFlight)) { for (int ii = 0; ii < numFlights - 1; ii++) { IFCAnyHandle representationCopy = ExporterUtil.CopyProductDefinitionShape(exporterIFC, ramp, catId, componentProdRep); localComponentHnds.Add(IFCInstanceExporter.CreateRampFlight(file, GUIDUtil.CreateGUID(), ownerHistory, localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy, componentElementTag, "NOTDEFINED")); } } else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcSlab)) { string componentType = IFCAnyHandleUtil.GetEnumerationAttribute(component, "PredefinedType"); IFCSlabType localLandingType = FloorExporter.GetIFCSlabType(componentType); for (int ii = 0; ii < numFlights - 1; ii++) { IFCAnyHandle representationCopy = ExporterUtil.CopyProductDefinitionShape(exporterIFC, ramp, catId, componentProdRep); localComponentHnds.Add(IFCInstanceExporter.CreateSlab(file, GUIDUtil.CreateGUID(), ownerHistory, localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy, componentElementTag, localLandingType.ToString())); } } else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcMember)) { for (int ii = 0; ii < numFlights - 1; ii++) { IFCAnyHandle representationCopy = ExporterUtil.CopyProductDefinitionShape(exporterIFC, ramp, catId, componentProdRep); localComponentHnds.Add(IFCInstanceExporter.CreateMember(file, GUIDUtil.CreateGUID(), ownerHistory, localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy, componentElementTag, "STRINGER")); } } for (int ii = 0; ii < numFlights - 1; ii++) { if (localComponentHnds[ii] != null) { newComponents[ii].Add(localComponentHnds[ii]); productWrapper.AddElement(null, localComponentHnds[ii], levelInfos[ii], componentECData[compIdx], false); } } compIdx++; } // finally add a copy of the container. IList <IFCAnyHandle> rampCopyHnds = new List <IFCAnyHandle>(); for (int ii = 0; ii < numFlights - 1; ii++) { string rampName = IFCAnyHandleUtil.GetStringAttribute(rampHnd, "Name"); string rampObjectType = IFCAnyHandleUtil.GetStringAttribute(rampHnd, "ObjectType"); string rampDescription = IFCAnyHandleUtil.GetStringAttribute(rampHnd, "Description"); string rampElementTag = IFCAnyHandleUtil.GetStringAttribute(rampHnd, "Tag"); string rampTypeAsString = null; if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { rampTypeAsString = IFCAnyHandleUtil.GetEnumerationAttribute(rampHnd, "PredefinedType"); } else { rampTypeAsString = IFCAnyHandleUtil.GetEnumerationAttribute(rampHnd, "ShapeType"); } string rampType = GetIFCRampType(rampTypeAsString); string containerRampName = rampName + ":" + (ii + 2); rampCopyHnds.Add(IFCInstanceExporter.CreateRamp(file, GUIDUtil.CreateGUID(), ownerHistory, containerRampName, rampDescription, rampObjectType, rampLocalPlacementHnds[ii], null, rampElementTag, rampType)); productWrapper.AddElement(ramp, rampCopyHnds[ii], levelInfos[ii], null, true); } for (int ii = 0; ii < numFlights - 1; ii++) { StairRampContainerInfo stairRampInfo = new StairRampContainerInfo(rampCopyHnds[ii], newComponents[ii], rampLocalPlacementHnds[ii]); ExporterCacheManager.StairRampContainerInfoCache.AppendStairRampContainerInfo(ramp.Id, stairRampInfo); } }
/// <summary> /// Exports an element as an IfcReinforcingMesh. /// </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> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportFabricSheet(ExporterIFC exporterIFC, FabricSheet sheet, GeometryElement geometryElement, ProductWrapper productWrapper) { if (sheet == null || geometryElement == null) { return(false); } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { // Check for containment override ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, sheet, out IFCAnyHandle overrideContainerHnd); if (!(sheet.Document?.GetElement(sheet.GetTypeId()) is FabricSheetType fsType)) { return(false); } using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, sheet, null, null, overrideContainerId, overrideContainerHnd)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(placementSetter.LocalPlacement); FabricSheetExportConfig config = new FabricSheetExportConfig() { BodyItems = new HashSet <IFCAnyHandle>(), CategoryId = CategoryUtil.GetSafeCategoryId(sheet), Doc = sheet.Document, Sheet = sheet, EcData = ecData, ExporterIFC = exporterIFC, File = file, PlacementSetter = placementSetter, ProductWrapper = productWrapper, SheetType = fsType }; ParameterUtil.GetElementIdValueFromElementOrSymbol(config.Sheet, BuiltInParameter.MATERIAL_ID_PARAM, out ElementId materialId); config.MaterialId = materialId; bool status = true; if (config.SheetType.IsCustom()) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(IFCEntityType.IfcElementAssembly)) { return(false); } else { status = ExportCustomFabricSheet(config); } } else { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(IFCEntityType.IfcReinforcingMesh)) { return(false); } else { status = ExportStandardFabricSheet(config); } } if (!status) { tr.RollBack(); return(false); } } } tr.Commit(); return(true); } }
private static bool ExportCustomFabricSheet(FabricSheetExportConfig cfg) { if (cfg.Equals(null) || cfg.Sheet.IsBent) { return(false); } string guid = GUIDUtil.CreateGUID(cfg.Sheet); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; HashSet <IFCAnyHandle> rebarHandles = new HashSet <IFCAnyHandle>(); string matName = (cfg.Doc.GetElement(cfg.MaterialId) as Material)?.Name; int ii = 0; do { WireDistributionDirection dir = (WireDistributionDirection)ii; IList <Curve> wireCenterlines = cfg.Sheet.GetWireCenterlines(dir); for (int jj = 0; jj < wireCenterlines.Count; jj++) { double wireDiam = 0.0; FabricWireItem wire = cfg.SheetType.GetWireItem(jj, dir); if (cfg.Doc.GetElement(wire.WireType) is FabricWireType wireType) { wireDiam = UnitUtil.ScaleLength(wireType.WireDiameter); } IFCAnyHandle bodyItem = GeometryUtil.CreateSweptDiskSolid(cfg.ExporterIFC, cfg.File, wireCenterlines[jj], wireDiam / 2.0, null); ISet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle> { bodyItem }; IFCAnyHandle shapeRep = null; if (bodyItems.Count > 0) { shapeRep = RepresentationUtil.CreateAdvancedSweptSolidRep(cfg.ExporterIFC, cfg.Sheet, cfg.CategoryId, cfg.ExporterIFC.Get3DContextHandle("Body"), bodyItems, null); } IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); if (shapeRep != null) { shapeReps.Add(shapeRep); } IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(cfg.File, null, null, shapeReps); IFCAnyHandle handle = IFCInstanceExporter.CreateReinforcingBar(cfg.ExporterIFC, cfg.Sheet, guid, ExporterCacheManager.OwnerHistoryHandle, cfg.PlacementSetter.LocalPlacement, prodRep, matName, wireDiam, 0, 0, IFCReinforcingBarRole.NotDefined, null); IFCAnyHandleUtil.SetAttribute(handle, "ObjectType", "Generic"); CategoryUtil.CreateMaterialAssociation(cfg.ExporterIFC, handle, cfg.MaterialId); rebarHandles.Add(handle); } ii++; }while (ii < 2); IFCAnyHandle assemblyInstanceHnd = IFCInstanceExporter.CreateElementAssembly(cfg.ExporterIFC, cfg.Sheet, guid, ownerHistory, cfg.PlacementSetter.LocalPlacement, null, IFCAssemblyPlace.NotDefined, IFCElementAssemblyType.UserDefined); IFCExportInfoPair assemblyExportInfo = new IFCExportInfoPair(IFCEntityType.IfcElementAssembly); cfg.ProductWrapper.AddElement(cfg.Sheet, assemblyInstanceHnd, cfg.PlacementSetter.LevelInfo, null, true, assemblyExportInfo); ExporterCacheManager.AssemblyInstanceCache.RegisterAssemblyInstance(cfg.Sheet.Id, assemblyInstanceHnd); IFCInstanceExporter.CreateRelAggregates(cfg.File, guid, ownerHistory, null, null, assemblyInstanceHnd, rebarHandles); return(true); }
/// <summary> /// Exports materials for host object. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="hostObject"> /// The host object. /// </param> /// <param name="elemHnds"> /// The host IFC handles. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The IFCProductWrapper. /// </param> /// <param name="levelId"> /// The level id. /// </param> /// <param name="direction"> /// The IFCLayerSetDirection. /// </param> /// <returns> /// True if exported successfully, false otherwise. /// </returns> public static bool ExportHostObjectMaterials(ExporterIFC exporterIFC, HostObject hostObject, IList <IFCAnyHandle> elemHnds, GeometryElement geometryElement, IFCProductWrapper productWrapper, ElementId levelId, Toolkit.IFCLayerSetDirection direction) { if (hostObject == null) { return(true); //nothing to do } if (elemHnds == null || (elemHnds.Count == 0)) { return(true); //nothing to do } IFCFile file = exporterIFC.GetFile(); // Roofs with no components are only allowed one material. We will arbitrarily choose the thickest material. IFCAnyHandle primaryMaterialHnd = null; using (IFCTransaction tr = new IFCTransaction(file)) { if (productWrapper != null) { productWrapper.ClearFinishMaterials(); } double scale = exporterIFC.LinearScale; double scaledOffset = 0.0, scaledWallWidth = 0.0, wallHeight = 0.0; Wall wall = hostObject as Wall; if (wall != null) { scaledWallWidth = wall.Width * scale; scaledOffset = -scaledWallWidth / 2.0; BoundingBoxXYZ boundingBox = wall.get_BoundingBox(null); if (boundingBox != null) { wallHeight = boundingBox.Max.Z - boundingBox.Min.Z; } } ElementId typeElemId = hostObject.GetTypeId(); IFCAnyHandle materialLayerSet = ExporterCacheManager.MaterialLayerSetCache.Find(typeElemId); if (IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet)) { HostObjAttributes hostObjAttr = hostObject.Document.GetElement(typeElemId) as HostObjAttributes; if (hostObjAttr == null) { return(true); //nothing to do } List <ElementId> matIds = new List <ElementId>(); List <double> widths = new List <double>(); List <MaterialFunctionAssignment> functions = new List <MaterialFunctionAssignment>(); ElementId baseMatId = CategoryUtil.GetBaseMaterialIdForElement(hostObject); CompoundStructure cs = hostObjAttr.GetCompoundStructure(); if (cs != null) { //TODO: Vertically compound structures are not yet supported by export. if (!cs.IsVerticallyHomogeneous() && !MathUtil.IsAlmostZero(wallHeight)) { cs = cs.GetSimpleCompoundStructure(wallHeight, wallHeight / 2.0); } for (int i = 0; i < cs.LayerCount; ++i) { ElementId matId = cs.GetMaterialId(i); if (matId != ElementId.InvalidElementId) { matIds.Add(matId); } else { matIds.Add(baseMatId); } widths.Add(cs.GetLayerWidth(i)); // save layer function into IFCProductWrapper, // it's used while exporting "Function" of Pset_CoveringCommon functions.Add(cs.GetLayerFunction(i)); } } if (matIds.Count == 0) { matIds.Add(baseMatId); widths.Add(cs != null ? cs.GetWidth() : 0); functions.Add(MaterialFunctionAssignment.None); } List <IFCAnyHandle> layers = new List <IFCAnyHandle>(); double thickestLayer = 0.0; for (int i = 0; i < matIds.Count; ++i) { if (widths[i] < MathUtil.Eps()) { continue; } IFCAnyHandle materialHnd = CategoryUtil.GetOrCreateMaterialHandle(hostObjAttr.Document, exporterIFC, matIds[i]); if (primaryMaterialHnd == null || (widths[i] > thickestLayer)) { primaryMaterialHnd = materialHnd; thickestLayer = widths[i]; } double scaledWidth = widths[i] * scale; IFCAnyHandle materialLayer = IFCInstanceExporter.CreateMaterialLayer(file, materialHnd, scaledWidth, null); layers.Add(materialLayer); if ((productWrapper != null) && (functions[i] == MaterialFunctionAssignment.Finish1 || functions[i] == MaterialFunctionAssignment.Finish2)) { productWrapper.AddFinishMaterial(materialHnd); } } if (layers.Count == 0) { return(false); } string layerSetName = NamingUtil.CreateIFCFamilyName(exporterIFC, -1); materialLayerSet = IFCInstanceExporter.CreateMaterialLayerSet(file, layers, layerSetName); ExporterCacheManager.MaterialLayerSetCache.Register(typeElemId, materialLayerSet); } // IfcMaterialLayerSetUsage is not supported for IfcWall, only IfcWallStandardCase. IFCAnyHandle layerSetUsage = null; for (int ii = 0; ii < elemHnds.Count; ii++) { IFCAnyHandle elemHnd = elemHnds[ii]; if (IFCAnyHandleUtil.IsNullOrHasNoValue(elemHnd)) { continue; } HashSet <IFCAnyHandle> relDecomposesSet = IFCAnyHandleUtil.GetRelDecomposes(elemHnd); IList <IFCAnyHandle> subElemHnds = new List <IFCAnyHandle>(); if (relDecomposesSet != null && relDecomposesSet.Count == 1) { IFCAnyHandle relAggregates = relDecomposesSet.First(); if (IFCAnyHandleUtil.IsTypeOf(relAggregates, IFCEntityType.IfcRelAggregates)) { IFCData ifcData = relAggregates.GetAttribute("RelatedObjects"); if (ifcData.PrimitiveType == IFCDataPrimitiveType.Aggregate) { IFCAggregate aggregate = ifcData.AsAggregate(); if (aggregate != null && aggregate.Count > 0) { foreach (IFCData val in aggregate) { if (val.PrimitiveType == IFCDataPrimitiveType.Instance) { subElemHnds.Add(val.AsInstance()); } } } } } } bool hasSubElems = !(subElemHnds.Count == 0); bool isRoof = IFCAnyHandleUtil.IsTypeOf(elemHnd, IFCEntityType.IfcRoof); if (!hasSubElems && !isRoof && !IFCAnyHandleUtil.IsTypeOf(elemHnd, IFCEntityType.IfcWall)) { if (layerSetUsage == null) { bool flipDirSense = true; if (wall != null) { // if we have flipped the center curve on export, we need to take that into account here. // We flip the center curve on export if it is an arc and it has a negative Z direction. LocationCurve locCurve = wall.Location as LocationCurve; if (locCurve != null) { Curve curve = locCurve.Curve; Plane defPlane = new Plane(XYZ.BasisX, XYZ.BasisY, XYZ.Zero); bool curveFlipped = GeometryUtil.MustFlipCurve(defPlane, curve); flipDirSense = !(wall.Flipped ^ curveFlipped); } } else if (hostObject is Floor) { flipDirSense = false; } double offsetFromReferenceLine = flipDirSense ? -scaledOffset : scaledOffset; IFCDirectionSense sense = flipDirSense ? IFCDirectionSense.Negative : IFCDirectionSense.Positive; layerSetUsage = IFCInstanceExporter.CreateMaterialLayerSetUsage(file, materialLayerSet, direction, sense, offsetFromReferenceLine); } ExporterCacheManager.MaterialLayerRelationsCache.Add(layerSetUsage, elemHnd); } else { if (hasSubElems) { foreach (IFCAnyHandle subElemHnd in subElemHnds) { if (!IFCAnyHandleUtil.IsNullOrHasNoValue(subElemHnd)) { ExporterCacheManager.MaterialLayerRelationsCache.Add(materialLayerSet, subElemHnd); } } } else if (!isRoof) { ExporterCacheManager.MaterialLayerRelationsCache.Add(materialLayerSet, elemHnd); } else if (primaryMaterialHnd != null) { ExporterCacheManager.MaterialLayerRelationsCache.Add(primaryMaterialHnd, elemHnd); } } exporterIFC.RegisterSpaceBoundingElementHandle(elemHnd, hostObject.Id, levelId); } tr.Commit(); return(true); } }
/// <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 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 pileType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType); IFCAnyHandle pile = IFCInstanceExporter.CreatePile(file, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, instanceName, instanceDescription, instanceObjectType, ecData.GetLocalPlacement(), prodRep, instanceTag, pileType, 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 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; } bool exportParts = PartExporter.CanExportParts(slabElement); IFCFile file = exporterIFC.GetFile(); IList <IFCAnyHandle> slabHnds = new List <IFCAnyHandle>(); IList <IFCAnyHandle> brepSlabHnds = new List <IFCAnyHandle>(); IList <IFCAnyHandle> nonBrepSlabHnds = new List <IFCAnyHandle>(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCTransformSetter transformSetter = IFCTransformSetter.Create()) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, slabElement)) { IFCAnyHandle localPlacement = placementSetter.LocalPlacement; IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); bool exportedAsInternalExtrusion = false; ElementId catId = CategoryUtil.GetSafeCategoryId(slabElement); 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(); IList <IFCAnyHandle> localPlacements = new List <IFCAnyHandle>(); using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); bodyExporterOptions.TessellationLevel = BodyExporter.GetTessellationLevel(); BodyData bodyData; IFCAnyHandle prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, slabElement, 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(slabElement); int numReps = exportParts ? 1 : prodReps.Count; string entityType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(slabElement, ifcEnumType, "FLOOR"); for (int ii = 0; ii < numReps; ii++) { string ifcName = NamingUtil.GetNameOverride(slabElement, NamingUtil.GetIFCNamePlusIndex(slabElement, ii == 0 ? -1 : ii + 1)); string ifcDescription = NamingUtil.GetDescriptionOverride(slabElement, null); string ifcObjectType = NamingUtil.GetObjectTypeOverride(slabElement, exporterIFC.GetFamilyName()); string ifcTag = NamingUtil.GetTagOverride(slabElement, NamingUtil.CreateIFCElementId(slabElement)); string currentGUID = (ii == 0) ? ifcGUID : GUIDUtil.CreateGUID(); IFCAnyHandle localPlacementHnd = exportedAsInternalExtrusion ? localPlacements[ii] : localPlacement; IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, currentGUID, ownerHistory, ifcName, ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii], ifcTag, entityType); if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd)) { return; } if (exportParts) { PartExporter.ExportHostPart(exporterIFC, slabElement, slabHnd, productWrapper, placementSetter, localPlacementHnd, null); } slabHnds.Add(slabHnd); if (!exportParts) { if (repTypes[ii] == ShapeRepresentationType.Brep) { brepSlabHnds.Add(slabHnd); } else { nonBrepSlabHnds.Add(slabHnd); } } } for (int ii = 0; ii < numReps; ii++) { IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null; productWrapper.AddElement(slabElement, slabHnds[ii], placementSetter, loopExtraParam, true); } if (exportedAsInternalExtrusion) { ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, slabElement, placementSetter.LevelInfo, localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative()); } } if (!exportParts) { if (slabElement is HostObject) { HostObject hostObject = slabElement as HostObject; if (nonBrepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, nonBrepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false); } if (brepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, brepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, true); } } else if (slabElement is FamilyInstance && slabHnds.Count > 0) { ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, slabElement); Document doc = slabElement.Document; foreach (IFCAnyHandle slabHnd in slabHnds) { CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, matId); } } } } tr.Commit(); return; } }
/// <summary> /// Calculates load bearing value for a column. /// </summary> /// <remarks> /// True for structural columns, and false for architectural ones. /// </remarks> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="extrusionCreationData"> /// The IFCExtrusionCreationData. /// </param> /// <param name="element"> /// The element to calculate the value. /// </param> /// <param name="elementType"> /// The element type. /// </param> /// <returns> /// True if the operation succeed, false otherwise. /// </returns> public override bool Calculate(ExporterIFC exporterIFC, IFCExtrusionCreationData extrusionCreationData, Element element, ElementType elementType) { m_LoadBearing = CategoryUtil.GetSafeCategoryId(element) == new ElementId(BuiltInCategory.OST_StructuralColumns); return(true); }
/// <summary> /// Exports a ramp to IfcRamp, without decomposing into separate runs and landings. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="ifcEnumType">The ramp type.</param> /// <param name="ramp">The ramp element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="numFlights">The number of flights for a multistory ramp.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportRamp(ExporterIFC exporterIFC, string ifcEnumType, Element ramp, GeometryElement geometryElement, int numFlights, ProductWrapper productWrapper) { if (ramp == null || geometryElement == null) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, ramp)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(placementSetter.LocalPlacement); ecData.ReuseLocalPlacement = false; GeometryElement rampGeom = GeometryUtil.GetOneLevelGeometryElement(geometryElement, numFlights); BodyData bodyData; ElementId categoryId = CategoryUtil.GetSafeCategoryId(ramp); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, ramp, categoryId, rampGeom, bodyExporterOptions, null, ecData, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation)) { ecData.ClearOpenings(); return; } string containedRampGuid = GUIDUtil.CreateSubElementGUID(ramp, (int)IFCRampSubElements.ContainedRamp); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string rampName = NamingUtil.GetNameOverride(ramp, NamingUtil.GetIFCName(ramp)); string rampDescription = NamingUtil.GetDescriptionOverride(ramp, null); string rampObjectType = NamingUtil.GetObjectTypeOverride(ramp, NamingUtil.CreateIFCObjectName(exporterIFC, ramp)); IFCAnyHandle containedRampLocalPlacement = ExporterUtil.CreateLocalPlacement(file, ecData.GetLocalPlacement(), null); string elementTag = NamingUtil.GetTagOverride(ramp, NamingUtil.CreateIFCElementId(ramp)); string rampType = GetIFCRampType(ifcEnumType); List <IFCAnyHandle> components = new List <IFCAnyHandle>(); IList <IFCExtrusionCreationData> componentExtrusionData = new List <IFCExtrusionCreationData>(); IFCAnyHandle containedRampHnd = IFCInstanceExporter.CreateRamp(file, containedRampGuid, ownerHistory, rampName, rampDescription, rampObjectType, containedRampLocalPlacement, representation, elementTag, rampType); components.Add(containedRampHnd); componentExtrusionData.Add(ecData); //productWrapper.AddElement(containedRampHnd, placementSetter.LevelInfo, ecData, false); CategoryUtil.CreateMaterialAssociation(exporterIFC, containedRampHnd, bodyData.MaterialIds); string guid = GUIDUtil.CreateGUID(ramp); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); IFCAnyHandle rampHnd = IFCInstanceExporter.CreateRamp(file, guid, ownerHistory, rampName, rampDescription, rampObjectType, localPlacement, null, elementTag, rampType); productWrapper.AddElement(ramp, rampHnd, placementSetter.LevelInfo, ecData, true); StairRampContainerInfo stairRampInfo = new StairRampContainerInfo(rampHnd, components, localPlacement); ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(ramp.Id, stairRampInfo); ExportMultistoryRamp(exporterIFC, ramp, numFlights, rampHnd, components, componentExtrusionData, placementSetter, 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(); 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.GetEndPoint(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 (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, canExportAxis ? orientTrf : null)) { IFCAnyHandle localPlacement = setter.LocalPlacement; 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 = -UnitUtil.UnscaleLength(offsetTransform.Origin); } else { // Note that we do not have to have any scaling adjustment here, since the curve origin is in the // same internal coordinate system as the curve. curveOffset = -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)); string preDefinedType = "BEAM"; // Default predefined type for Beam preDefinedType = IFCValidateEntry.GetValidIFCType(element, preDefinedType); IFCAnyHandle beam = IFCInstanceExporter.CreateBeam(file, instanceGUID, exporterIFC.GetOwnerHistoryHandle(), 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(); } }
/// <summary> /// Checks if exporting an element of Ramp category. /// </summary> /// <param name="element">The element.</param> /// <returns>True if element is of category OST_Ramps.</returns> static public bool IsRamp(Element element) { // FaceWall should be exported as IfcWall. return(CategoryUtil.GetSafeCategoryId(element) == new ElementId(BuiltInCategory.OST_Ramps)); }
/// <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 an annotation. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="filledRegion">The filled region element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void Export(ExporterIFC exporterIFC, FilledRegion filledRegion, GeometryElement geometryElement, ProductWrapper productWrapper) { if (filledRegion == null || geometryElement == null) { return; } // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>("IfcAnnotation", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { IList <CurveLoop> boundaries = filledRegion.GetBoundaries(); if (boundaries.Count == 0) { return; } Plane plane = null; try { plane = boundaries[0].GetPlane(); } catch { return; } Transform orientTrf = GeometryUtil.CreateTransformFromPlane(plane); XYZ projectionDirection = plane.Normal; IList <IList <CurveLoop> > sortedLoops = ExporterIFCUtils.SortCurveLoops(boundaries); if (sortedLoops.Count == 0) { return; } FilledRegionType filledRegionType = filledRegion.Document.GetElement(filledRegion.GetTypeId()) as FilledRegionType; Color color = filledRegionType != null?CategoryUtil.GetSafeColor(filledRegionType.Color) : new Color(0, 0, 0); ElementId fillPatternId = filledRegionType != null ? filledRegionType.FillPatternId : ElementId.InvalidElementId; ElementId categoryId = CategoryUtil.GetSafeCategoryId(filledRegion); using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, filledRegion, null, orientTrf)) { foreach (IList <CurveLoop> curveLoopList in sortedLoops) { IFCAnyHandle outerCurve = null; HashSet <IFCAnyHandle> innerCurves = null; for (int ii = 0; ii < curveLoopList.Count; ii++) { IFCAnyHandle ifcCurve = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, curveLoopList[ii], orientTrf, projectionDirection); if (ii == 0) { outerCurve = ifcCurve; } else { if (innerCurves == null) { innerCurves = new HashSet <IFCAnyHandle>(); } innerCurves.Add(ifcCurve); } } IFCAnyHandle representItem = IFCInstanceExporter.CreateAnnotationFillArea(file, outerCurve, innerCurves); file.CreateStyle(exporterIFC, representItem, color, fillPatternId); HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); bodyItems.Add(representItem); IFCAnyHandle bodyRepHnd = RepresentationUtil.CreateAnnotationSetRep(exporterIFC, filledRegion, categoryId, exporterIFC.Get2DContextHandle(), bodyItems); if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepHnd)) { return; } List <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(bodyRepHnd); IFCAnyHandle productShape = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); IFCAnyHandle annotation = IFCInstanceExporter.CreateAnnotation(exporterIFC, filledRegion, GUIDUtil.CreateGUID(), ExporterCacheManager.OwnerHistoryHandle, setter.LocalPlacement, productShape); productWrapper.AddAnnotation(annotation, setter.LevelInfo, true); } } transaction.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; } // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcFooting; 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.GetValidIFCPredefinedType(element, footingType, "IfcFootingType"); 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> /// Export one IFCGrid in one level. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="levelId">The level ID.</param> /// <param name="sameDirectionAxesU">The U axes of grids.</param> /// <param name="sameDirectionAxesV">The V axes of grids.</param> /// <param name="sameDirectionAxesW">The W axes of grids.</param> public static void ExportGrid(ExporterIFC exporterIFC, ElementId levelId, List <Grid> sameDirectionAxesU, List <Grid> sameDirectionAxesV, List <Grid> sameDirectionAxesW) { List <IFCAnyHandle> axesU = null; List <IFCAnyHandle> axesV = null; List <IFCAnyHandle> axesW = null; List <IFCAnyHandle> representations = new List <IFCAnyHandle>(); using (ProductWrapper productWrapper = ProductWrapper.Create(exporterIFC, true)) { IFCFile ifcFile = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(ifcFile)) { GridRepresentationData gridRepresentationData = new GridRepresentationData(); axesU = CreateIFCGridAxisAndRepresentations(exporterIFC, productWrapper, sameDirectionAxesU, representations, gridRepresentationData); axesV = CreateIFCGridAxisAndRepresentations(exporterIFC, productWrapper, sameDirectionAxesV, representations, gridRepresentationData); if (sameDirectionAxesW != null) { axesW = CreateIFCGridAxisAndRepresentations(exporterIFC, productWrapper, sameDirectionAxesW, representations, gridRepresentationData); } IFCAnyHandle contextOfItemsFootPrint = exporterIFC.Get3DContextHandle("FootPrint"); string identifierOpt = "FootPrint"; string representationTypeOpt = "GeometricCurveSet"; int numGridsToExport = gridRepresentationData.m_Grids.Count; if (numGridsToExport == 0) { return; } bool useIFCCADLayer = !string.IsNullOrWhiteSpace(gridRepresentationData.m_IFCCADLayer); IFCAnyHandle shapeRepresentation = null; HashSet <IFCAnyHandle> allCurves = new HashSet <IFCAnyHandle>(); for (int ii = 0; ii < numGridsToExport; ii++) { allCurves.UnionWith(gridRepresentationData.m_curveSets[ii]); } if (useIFCCADLayer) { shapeRepresentation = RepresentationUtil.CreateShapeRepresentation(exporterIFC, contextOfItemsFootPrint, identifierOpt, representationTypeOpt, allCurves, gridRepresentationData.m_IFCCADLayer); } else { ElementId catId = CategoryUtil.GetSafeCategoryId(gridRepresentationData.m_Grids[0]); shapeRepresentation = RepresentationUtil.CreateShapeRepresentation(exporterIFC, gridRepresentationData.m_Grids[0], catId, contextOfItemsFootPrint, identifierOpt, representationTypeOpt, allCurves); } representations.Add(shapeRepresentation); IFCAnyHandle productRep = IFCInstanceExporter.CreateProductDefinitionShape(ifcFile, null, null, representations); // We will associate the grid with its level, unless there are no levels in the file, in which case we'll associate it with the building. IFCLevelInfo levelInfo = ExporterCacheManager.LevelInfoCache.GetLevelInfo(exporterIFC, levelId); bool useLevelInfo = (levelInfo != null); string gridGUID = GUIDUtil.CreateGUID(); // Get the first grid's override name, if cannot find it, use null. string gridName = GetGridName(sameDirectionAxesU, sameDirectionAxesV, sameDirectionAxesW); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle gridLevelHandle = useLevelInfo ? levelInfo.GetBuildingStorey() : ExporterCacheManager.BuildingHandle; IFCAnyHandle levelObjectPlacement = IFCAnyHandleUtil.GetObjectPlacement(gridLevelHandle); double elev = useLevelInfo ? levelInfo.Elevation : 0.0; double elevation = UnitUtil.ScaleLength(elev); XYZ orig = new XYZ(0.0, 0.0, elevation); IFCAnyHandle copyLevelPlacement = ExporterUtil.CopyLocalPlacement(ifcFile, levelObjectPlacement); IFCAnyHandle ifcGrid = IFCInstanceExporter.CreateGrid(ifcFile, gridGUID, ownerHistory, gridName, null, null, copyLevelPlacement, productRep, axesU, axesV, axesW); productWrapper.AddElement(null, ifcGrid, levelInfo, null, true); transaction.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(); 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; 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); 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); string preDefinedType = "BEAM"; // Default predefined type for Beam preDefinedType = IFCValidateEntry.GetValidIFCType(element, preDefinedType); beam = IFCInstanceExporter.CreateBeam(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, extrusionCreationData.GetLocalPlacement(), prodRep, preDefinedType); IFCAnyHandle mpSetUsage; if (materialProfileSet != null) { mpSetUsage = IFCInstanceExporter.CreateMaterialProfileSetUsage(file, materialProfileSet, null, null); } productWrapper.AddElement(element, beam, setter, extrusionCreationData, true); ExportBeamType(exporterIFC, productWrapper, beam, element, preDefinedType); 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); } } transaction.Commit(); return(beam); } }
/// <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, GeometryElement geometryElement, ProductWrapper productWrapper) { if (geometryElement == null) { return; } // export parts or not bool exportParts = PartExporter.CanExportParts(floorElement); if (exportParts && !PartExporter.CanExportElementInPartExport(floorElement, floorElement.LevelId, false)) { return; } IFCFile file = exporterIFC.GetFile(); string ifcEnumType; IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, floorElement, out ifcEnumType); IFCAnyHandle type = null; // 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.ExportInstance.ToString(), out elementClassTypeEnum) || Enum.TryParse <Common.Enums.IFCEntityType>(exportType.ExportType.ToString(), out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } //string predefinedType = null; 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, ifcEnumType, 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; 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; 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(); IList <IFCAnyHandle> localPlacements = new List <IFCAnyHandle>(); 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) { bool completelyClipped; // 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 = ExporterCacheManager.ExportOptionsCache.ExportAs4 ? GenerateAdditionalInfo.GenerateFootprint : GenerateAdditionalInfo.None; HandleAndData floorAndProperties = ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, floorElement, catId, solids[0], extrusionAnalyzerFloorBasePlane, floorOrigin, floorExtrusionDirection, null, out completelyClipped, addInfo: additionalInfo); if (completelyClipped) { return; } if (floorAndProperties.Handle != null) { IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(floorAndProperties.Handle); // Footprint representation will only be exported in export to IFC4 if (((additionalInfo & GenerateAdditionalInfo.GenerateFootprint) != 0) && (floorAndProperties.FootprintInfo != null)) { if (!(IFCAnyHandleUtil.IsNullOrHasNoValue(floorAndProperties.FootprintInfo.FootPrintHandle))) { representations.Add(floorAndProperties.FootprintInfo.FootPrintHandle); } } IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); prodReps.Add(prodRep); repTypes.Add(ShapeRepresentationType.SweptSolid); if (floorAndProperties.Data != null) { loopExtraParams.Add(floorAndProperties.Data); } } } } } // Use internal routine as backup that handles openings. if (prodReps.Count == 0 && canExportAsInternalExtrusion && !ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { //IList<IFCAnyHandle> prodRepsTmp = new List<IFCAnyHandle>(); exportedAsInternalExtrusion = ExporterIFCUtils.ExportSlabAsExtrusion(exporterIFC, floorElement, geometryElement, transformSetter, localPlacement, out localPlacements, out prodReps, out extrusionLoops, out loopExtraParams, floorPlane); 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); //representations.Add(footprintShapeRepresentation); IList <IFCAnyHandle> reps = new List <IFCAnyHandle>(); reps.Add(footprintShapeRepresentation); IFCAnyHandleUtil.AddRepresentations(prodReps[ii], reps); } } } } } if (prodReps.Count == 0) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { // Brep representation using tesellation after ExportSlabAsExtrusion does not return prodReps BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium); BodyData bodyData; IFCAnyHandle 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; switch (exportType.ExportInstance) { case IFCEntityType.IfcFooting: if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType <Revit.IFC.Export.Toolkit.IFC4.IFCFootingType>(floorElement, ifcEnumType, null); } else { exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType <IFCFootingType>(floorElement, ifcEnumType, null); } break; case IFCEntityType.IfcCovering: exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType <IFCCoveringType>(floorElement, ifcEnumType, "FLOORING"); break; case IFCEntityType.IfcRamp: if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType <Revit.IFC.Export.Toolkit.IFC4.IFCRampType>(floorElement, ifcEnumType, null); } else { exportType.ValidatedPredefinedType = IFCValidateEntry.GetValidIFCType <IFCRampType>(floorElement, ifcEnumType, null); } break; default: bool isBaseSlab = false; AnalyticalModel analyticalModel = floorElement.GetAnalyticalModel(); if (analyticalModel != null) { AnalyzeAs slabFoundationType = analyticalModel.GetAnalyzeAs(); isBaseSlab = (slabFoundationType == AnalyzeAs.SlabOnGrade) || (slabFoundationType == 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.CreateGUID(); 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); } slabHnds.Add(slabHnd); if (!exportParts) { if (repTypes[ii] == ShapeRepresentationType.Brep || repTypes[ii] == ShapeRepresentationType.Tessellation) { brepSlabHnds.Add(slabHnd); } else { nonBrepSlabHnds.Add(slabHnd); } } } for (int ii = 0; ii < numReps; ii++) { IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null; productWrapper.AddElement(floorElement, slabHnds[ii], placementSetter, loopExtraParam, true, exportType); type = ExporterUtil.CreateGenericTypeFromElement(floorElement, exportType, file, ownerHistory, exportType.ValidatedPredefinedType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(type, slabHnds[ii]); } // 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) { ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, floorElement, placementSetter.LevelInfo, localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative()); } } if (!exportParts) { if (nonBrepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, nonBrepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false, type); } if (brepSlabHnds.Count > 0) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, brepSlabHnds, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, true, type); } } } tr.Commit(); return; } }
/// <summary> /// Exports a geometry element to boundary representation. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="exportBoundaryRep">True if to export boundary representation.</param> /// <param name="exportAsFacetation">True if to export the geometry as facetation.</param> /// <param name="bodyRep">Body representation.</param> /// <param name="boundaryRep">Boundary representation.</param> /// <returns>True if success, false if fail.</returns> public static bool ExportSurface(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, bool exportBoundaryRep, bool exportAsFacetation, ref IFCAnyHandle bodyRep, ref IFCAnyHandle boundaryRep) { if (geometryElement == null) { return(false); } IFCGeometryInfo ifcGeomInfo = null; Document doc = element.Document; Plane plane = GeometryUtil.CreateDefaultPlane(); XYZ projDir = new XYZ(0, 0, 1); double eps = doc.Application.VertexTolerance * exporterIFC.LinearScale; ifcGeomInfo = IFCGeometryInfo.CreateFaceGeometryInfo(exporterIFC, plane, projDir, eps, exportBoundaryRep); ExporterIFCUtils.CollectGeometryInfo(exporterIFC, ifcGeomInfo, geometryElement, XYZ.Zero, true); IFCFile file = exporterIFC.GetFile(); HashSet <IFCAnyHandle> faceSets = new HashSet <IFCAnyHandle>(); IList <ICollection <IFCAnyHandle> > faceList = ifcGeomInfo.GetFaces(); foreach (ICollection <IFCAnyHandle> faces in faceList) { // no faces, don't complain. if (faces.Count == 0) { continue; } HashSet <IFCAnyHandle> faceSet = new HashSet <IFCAnyHandle>(faces); faceSets.Add(IFCInstanceExporter.CreateConnectedFaceSet(file, faceSet)); } if (faceSets.Count == 0) { return(false); } IFCAnyHandle surface = IFCInstanceExporter.CreateFaceBasedSurfaceModel(file, faceSets); BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, doc, surface, BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element)); IList <IFCAnyHandle> surfaceItems = new List <IFCAnyHandle>(); surfaceItems.Add(surface); ElementId catId = CategoryUtil.GetSafeCategoryId(element); bodyRep = RepresentationUtil.CreateSurfaceRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), surfaceItems, exportAsFacetation, bodyRep); if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { return(false); } ICollection <IFCAnyHandle> boundaryRepresentations = ifcGeomInfo.GetRepresentations(); if (exportBoundaryRep && boundaryRepresentations.Count > 0) { boundaryRep = RepresentationUtil.CreateBoundaryRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("FootPrint"), boundaryRepresentations, boundaryRep); } return(true); }
/// <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()) { // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, slabElement, out overrideContainerHnd); using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, slabElement, null, null, overrideContainerId, overrideContainerHnd)) { 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 || bodyData.ShapeRepresentationType == ShapeRepresentationType.Tessellation); } // Create the slab from either the extrusion or the BRep information. string ifcGUID = GUIDUtil.CreateGUID(slabElement); string entityType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(slabElement, ifcEnumType, "FLOOR"); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(exporterIFC, slabElement, ifcGUID, ownerHistory, localPlacement, exportParts ? null : prodDefHnd, entityType); IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcSlab, entityType); if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd)) { return; } if (exportParts) { PartExporter.ExportHostPart(exporterIFC, slabElement, slabHnd, productWrapper, placementSetter, localPlacement, null); } productWrapper.AddElement(slabElement, slabHnd, placementSetter, ecData, true, exportInfo); if (!exportParts) { IFCAnyHandle typeHnd = ExporterUtil.CreateGenericTypeFromElement(slabElement, exportInfo, file, ownerHistory, entityType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(typeHnd, slabHnd); if (slabElement is HostObject) { HostObject hostObject = slabElement as HostObject; HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, slabHnd, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, isBRepSlabHnd, typeHnd); } else if (slabElement is FamilyInstance) { ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, slabElement); //Document doc = slabElement.Document; if (typeHnd != null) { CategoryUtil.CreateMaterialAssociation(exporterIFC, typeHnd, matId); } else { CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, matId); } } OpeningUtil.CreateOpeningsIfNecessary(slabHnd, slabElement, ecData, null, exporterIFC, ecData.GetLocalPlacement(), placementSetter, productWrapper); } } } tr.Commit(); return; } } }
/// <summary> /// Exports a generic family instance as IFC instance. /// </summary> /// <param name="type">The export type.</param> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="familyInstance">The element.</param> /// <param name="wrapper">The ProductWrapper.</param> /// <param name="setter">The PlacementSetter.</param> /// <param name="extraParams">The extrusion creation data.</param> /// <param name="instanceGUID">The guid.</param> /// <param name="ownerHistory">The owner history handle.</param> /// <param name="instanceName">The name.</param> /// <param name="instanceDescription">The description.</param> /// <param name="instanceObjectType">The object type.</param> /// <param name="productRepresentation">The representation handle.</param> /// <param name="instanceTag">The tag for the entity, usually based on the element id.</param> /// <param name="ifcEnumType">The predefined type/shape type, if any, for the object.</param> /// <param name="overrideLocalPlacement">The local placement to use instead of the one in the placement setter, if appropriate.</param> /// <returns>The handle.</returns> public static IFCAnyHandle ExportGenericInstance(IFCExportType type, ExporterIFC exporterIFC, Element familyInstance, ProductWrapper wrapper, PlacementSetter setter, IFCExtrusionCreationData extraParams, string instanceGUID, IFCAnyHandle ownerHistory, string instanceName, string instanceDescription, string instanceObjectType, IFCAnyHandle productRepresentation, string instanceTag, string ifcEnumType, IFCAnyHandle overrideLocalPlacement) { IFCFile file = exporterIFC.GetFile(); Document doc = familyInstance.Document; bool isRoomRelated = IsRoomRelated(type); bool isChildInContainer = familyInstance.AssemblyInstanceId != ElementId.InvalidElementId; IFCAnyHandle localPlacementToUse = setter.LocalPlacement; ElementId roomId = ElementId.InvalidElementId; if (isRoomRelated) { roomId = setter.UpdateRoomRelativeCoordinates(familyInstance, out localPlacementToUse); } //should remove the create method where there is no use of this handle for API methods //some places uses the return value of ExportGenericInstance as input parameter for API methods IFCAnyHandle instanceHandle = null; switch (type) { case IFCExportType.IfcBeam: case IFCExportType.IfcBeamType: { string preDefinedType = string.IsNullOrWhiteSpace(ifcEnumType) ? "BEAM" : ifcEnumType; instanceHandle = IFCInstanceExporter.CreateBeam(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag, preDefinedType); break; } case IFCExportType.IfcColumn: case IFCExportType.IfcColumnType: { string preDefinedType = string.IsNullOrWhiteSpace(ifcEnumType) ? "COLUMN" : ifcEnumType; instanceHandle = IFCInstanceExporter.CreateColumn(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag, preDefinedType); break; } case IFCExportType.IfcCurtainWall: case IFCExportType.IfcCurtainWallType: { instanceHandle = IFCInstanceExporter.CreateCurtainWall(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag); break; } case IFCExportType.IfcMember: case IFCExportType.IfcMemberType: { string preDefinedType = string.IsNullOrWhiteSpace(ifcEnumType) ? "BRACE" : ifcEnumType; instanceHandle = IFCInstanceExporter.CreateMember(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag, preDefinedType); // Register the members's IFC handle for later use by truss export. ExporterCacheManager.ElementToHandleCache.Register(familyInstance.Id, instanceHandle); break; } case IFCExportType.IfcPlate: case IFCExportType.IfcPlateType: { IFCAnyHandle localPlacement = localPlacementToUse; if (overrideLocalPlacement != null) { isChildInContainer = true; localPlacement = overrideLocalPlacement; } string preDefinedType = string.IsNullOrWhiteSpace(ifcEnumType) ? "NOTDEFINED" : ifcEnumType; instanceHandle = IFCInstanceExporter.CreatePlate(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacement, productRepresentation, instanceTag, preDefinedType); break; } case IFCExportType.IfcDiscreteAccessoryType: { instanceHandle = IFCInstanceExporter.CreateDiscreteAccessory(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag); break; } case IFCExportType.IfcDistributionControlElement: { instanceHandle = IFCInstanceExporter.CreateDistributionControlElement(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag, null); break; } case IFCExportType.IfcDistributionFlowElement: { instanceHandle = IFCInstanceExporter.CreateDistributionFlowElement(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag); break; } case IFCExportType.IfcDistributionChamberElement: case IFCExportType.IfcDistributionChamberElementType: { instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(Common.Enums.IFCEntityType.IfcDistributionChamberElement, file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag); break; } case IFCExportType.IfcFastenerType: { instanceHandle = IFCInstanceExporter.CreateFastener(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag); break; } case IFCExportType.IfcMechanicalFastenerType: { double?nominalDiameter = null; double?nominalLength = null; double nominalDiameterVal, nominalLengthVal; if (ParameterUtil.GetDoubleValueFromElementOrSymbol(familyInstance, "NominalDiameter", out nominalDiameterVal) != null) { nominalDiameter = UnitUtil.ScaleLength(nominalDiameterVal); } if (ParameterUtil.GetDoubleValueFromElementOrSymbol(familyInstance, "NominalLength", out nominalLengthVal) != null) { nominalLength = UnitUtil.ScaleLength(nominalLengthVal); } string preDefinedType = string.IsNullOrWhiteSpace(ifcEnumType) ? "NOTDEFINED" : ifcEnumType; instanceHandle = IFCInstanceExporter.CreateMechanicalFastener(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag, nominalDiameter, nominalLength, preDefinedType); break; } case IFCExportType.IfcRailingType: { string strEnumType; IFCExportType exportAs = ExporterUtil.GetExportType(exporterIFC, familyInstance, out strEnumType); if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { instanceHandle = IFCInstanceExporter.CreateRailing(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag, GetPreDefinedType <Toolkit.IFC4.IFCRailingType>(familyInstance, strEnumType).ToString()); } else { instanceHandle = IFCInstanceExporter.CreateRailing(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag, GetPreDefinedType <Toolkit.IFCRailingType>(familyInstance, strEnumType).ToString()); } break; } case IFCExportType.IfcSpace: { string instanceLongName = NamingUtil.GetLongNameOverride(familyInstance, NamingUtil.GetLongNameOverride(familyInstance, instanceName)); IFCInternalOrExternal internalOrExternal = CategoryUtil.IsElementExternal(familyInstance) ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal; instanceHandle = IFCInstanceExporter.CreateSpace(file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceLongName, IFCElementComposition.Element, internalOrExternal, null); break; } default: { if (ExporterCacheManager.ExportOptionsCache.ExportAs4 && (type == IFCExportType.IfcDistributionElement || type == IFCExportType.IfcEnergyConversionDevice || type == IFCExportType.IfcFlowController || type == IFCExportType.IfcFlowFitting || type == IFCExportType.IfcFlowMovingDevice || type == IFCExportType.IfcFlowSegment || type == IFCExportType.IfcFlowStorageDevice || type == IFCExportType.IfcFlowTerminal || type == IFCExportType.IfcFlowTreatmentDevice)) { // for IFC4, there are several entities that are valid in IFC2x3 but now have been made abstract or deprecated, so cannot be created. Create proxy instead. //instanceHandle = IFCInstanceExporter.CreateBuildingElementProxy(file, instanceGUID, ownerHistory, // instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag, // Toolkit.IFC4.IFCBuildingElementProxyType.USERDEFINED.ToString()); Common.Enums.IFCEntityType exportEntity = Common.Enums.IFCEntityType.UnKnown; if (Enum.TryParse(type.ToString(), out exportEntity)) { instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportEntity, file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag); } } else if ((type == IFCExportType.IfcPile) || (type == IFCExportType.IfcFurnishingElement) || IsFurnishingElementSubType(type) || (type == IFCExportType.IfcEnergyConversionDevice) || IsEnergyConversionDeviceSubType(type) || (type == IFCExportType.IfcFlowFitting) || IsFlowFittingSubType(type) || (type == IFCExportType.IfcFlowMovingDevice) || IsFlowMovingDeviceSubType(type) || (type == IFCExportType.IfcFlowSegment) || IsFlowSegmentSubType(type) || (type == IFCExportType.IfcFlowStorageDevice) || IsFlowStorageDeviceSubType(type) || (type == IFCExportType.IfcFlowTerminal) || IsFlowTerminalSubType(type) || (type == IFCExportType.IfcFlowTreatmentDevice) || IsFlowTreatmentDeviceSubType(type) || (type == IFCExportType.IfcFlowController) || IsFlowControllerSubType(type) || (type == IFCExportType.IfcDistributionFlowElement) || IsDistributionFlowElementSubType(type) || (type == IFCExportType.IfcDistributionControlElement) || IsDistributionControlElementSubType(type) || (type == IFCExportType.IfcBuildingElementProxy) || (type == IFCExportType.IfcBuildingElementProxyType)) { string exportEntityStr = type.ToString(); Common.Enums.IFCEntityType exportEntity = Common.Enums.IFCEntityType.UnKnown; if (String.Compare(exportEntityStr.Substring(exportEntityStr.Length - 4), "Type", true) == 0) { exportEntityStr = exportEntityStr.Substring(0, (exportEntityStr.Length - 4)); } if (!Enum.TryParse(exportEntityStr, out exportEntity)) { // This is a special case. IFC2x3 has IfcFlowElement for the instance, and both IfcElectricHeaterType and IfcSpaceHeaterType. // IFC4 has IfcSpaceHeater and IfcSpaceHeaterType. // Since IfcElectricHeater doesn't exist in IFC4, TryParse will fail. For the instance only, we will map it to IfcSpaceHeater, // which will in turn be redirected to IfcFlowElement for IFC2x3, if necessary. if (type == IFCExportType.IfcElectricHeaterType) { exportEntity = Common.Enums.IFCEntityType.IfcSpaceHeater; } else { exportEntity = Common.Enums.IFCEntityType.UnKnown; } } if (exportEntity != Common.Enums.IFCEntityType.UnKnown) { instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportEntity, file, instanceGUID, ownerHistory, instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag); } } break; } } if (!IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle)) { bool containedInSpace = (roomId != ElementId.InvalidElementId); bool associateToLevel = containedInSpace ? false : !isChildInContainer; wrapper.AddElement(familyInstance, instanceHandle, setter, extraParams, associateToLevel); if (containedInSpace) { ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle); } } return(instanceHandle); }
/// <summary> /// Exports a Rebar to IFC ReinforcingBar. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="rebarItem">The rebar to be exported. This might be an element or a sub-element.</param> /// <param name="rebarElement">The element that contains the rebar to be exported. This may be the same as rebarItem.</param> /// <param name="itemIndex">If greater than 0, the index of the first rebar in the rebarItem in the rebarElement, used for naming and GUID creation.</param> /// <param name="productWrapper">The ProductWrapper object.</param> /// <returns>The set of handles created, to add to the ProductWrapper in the calling function.</returns> private static ISet <DelayedProductWrapper> ExportRebar(ExporterIFC exporterIFC, object rebarItem, Element rebarElement, int itemIndex, 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.IfcReinforcingBar; if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return(null); } IFCFile file = exporterIFC.GetFile(); HashSet <DelayedProductWrapper> createdRebars = new HashSet <DelayedProductWrapper>(); int rebarQuantity = GetRebarQuantity(rebarItem); if (rebarQuantity == 0) { return(null); } using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, rebarElement)) { bool cannotExportRebar = false; IFCAnyHandle rebarHandle = ExportRebarAsProxyElementInView(exporterIFC, rebarElement, productWrapper, out cannotExportRebar); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(rebarHandle) || cannotExportRebar) { if (!cannotExportRebar) { transaction.Commit(); } return(null); // Rebar doesn't create a group. } IFCAnyHandle prodRep = null; double totalBarLengthUnscale = GetRebarTotalLength(rebarItem); double volumeUnscale = GetRebarVolume(rebarItem); double totalBarLength = UnitUtil.ScaleLength(totalBarLengthUnscale); if (MathUtil.IsAlmostZero(totalBarLength)) { return(null); } ElementId materialId = ElementId.InvalidElementId; ParameterUtil.GetElementIdValueFromElementOrSymbol(rebarElement, BuiltInParameter.MATERIAL_ID_PARAM, out materialId); double diameter = GetBarDiameter(rebarItem); double radius = diameter / 2.0; double longitudinalBarNominalDiameter = diameter; double longitudinalBarCrossSectionArea = UnitUtil.ScaleArea(volumeUnscale / totalBarLengthUnscale); int numberOfBarPositions = GetNumberOfBarPositions(rebarItem); string steelGrade = NamingUtil.GetOverrideStringValue(rebarElement, "SteelGrade", null); // Allow use of IFC2x3 or IFC4 naming. string predefinedType = NamingUtil.GetOverrideStringValue(rebarElement, "BarRole", null); if (string.IsNullOrWhiteSpace(predefinedType)) { predefinedType = NamingUtil.GetOverrideStringValue(rebarElement, "PredefinedType", null); } IFCReinforcingBarRole role = GetReinforcingBarRole(predefinedType); string origRebarName = NamingUtil.GetNameOverride(rebarElement, NamingUtil.GetIFCName(rebarElement)); const int maxBarGUIDS = IFCReinforcingBarSubElements.BarEnd - IFCReinforcingBarSubElements.BarStart + 1; ElementId categoryId = CategoryUtil.GetSafeCategoryId(rebarElement); IFCAnyHandle originalPlacement = setter.LocalPlacement; // Potential issue : totalBarLength has a rounded value but individual lengths (from centerlines) do not have rounded values. // Also dividing a rounded totalBarLength does not result in barLength rounded by the same round value. double barLength = totalBarLength / rebarQuantity; IList <Curve> baseCurves = GetRebarCenterlineCurves(rebarItem, true, false, false); ElementId barLengthParamId = new ElementId(BuiltInParameter.REBAR_ELEM_LENGTH); ParameterSet rebarElementParams = rebarElement.Parameters; for (int ii = 0; ii < numberOfBarPositions; ii++) { if (!DoesBarExistAtPosition(rebarItem, ii)) { continue; } Rebar rebar = rebarElement as Rebar; if ((rebar != null) && (rebar.DistributionType == DistributionType.VaryingLength || rebar.IsRebarFreeForm())) { baseCurves = GetRebarCenterlineCurves(rebar, true, false, false, MultiplanarOption.IncludeOnlyPlanarCurves, ii); DoubleParameterValue barLengthParamVal = rebar.GetParameterValueAtIndex(barLengthParamId, ii) as DoubleParameterValue; if (barLengthParamVal != null) { barLength = barLengthParamVal.Value; } } string rebarNameFormated = origRebarName; int indexForNamingAndGUID = (itemIndex > 0) ? ii + itemIndex : ii + 1; string rebarName = NamingUtil.GetNameOverride(rebarElement, rebarNameFormated + ": " + indexForNamingAndGUID); Transform barTrf = GetBarPositionTransform(rebarItem, ii); IList <Curve> curves = new List <Curve>(); double endParam = 0.0; foreach (Curve baseCurve in baseCurves) { if (baseCurve is Arc || baseCurve is Ellipse) { if (baseCurve.IsBound) { endParam += UnitUtil.ScaleAngle(baseCurve.GetEndParameter(1) - baseCurve.GetEndParameter(0)); } else { endParam += UnitUtil.ScaleAngle(2 * Math.PI); } } else { endParam += 1.0; } curves.Add(baseCurve.CreateTransformed(barTrf)); } IFCAnyHandle compositeCurve = GeometryUtil.CreateCompositeCurve(exporterIFC, curves); IFCAnyHandle sweptDiskSolid = IFCInstanceExporter.CreateSweptDiskSolid(file, compositeCurve, radius, null, 0, endParam); HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); bodyItems.Add(sweptDiskSolid); IFCAnyHandle shapeRep = RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC, rebarElement, categoryId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null); IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(shapeRep); prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); IFCAnyHandle copyLevelPlacement = (ii == 0) ? originalPlacement : ExporterUtil.CopyLocalPlacement(file, originalPlacement); string rebarGUID = (indexForNamingAndGUID < maxBarGUIDS) ? GUIDUtil.CreateSubElementGUID(rebarElement, indexForNamingAndGUID + (int)IFCReinforcingBarSubElements.BarStart - 1) : GUIDUtil.CreateGUID(); IFCAnyHandle elemHnd = IFCInstanceExporter.CreateReinforcingBar(exporterIFC, rebarElement, rebarGUID, ExporterCacheManager.OwnerHistoryHandle, copyLevelPlacement, prodRep, steelGrade, longitudinalBarNominalDiameter, longitudinalBarCrossSectionArea, barLength, role, null); IFCAnyHandleUtil.OverrideNameAttribute(elemHnd, rebarName); // We will not add the element ot the productWrapper here, but instead in the function that calls // ExportRebar. The reason for this is that we don't currently know if the handles such be associated // to the level or not, depending on whether they will or won't be grouped. createdRebars.Add(new DelayedProductWrapper(rebarElement, elemHnd, setter.LevelInfo)); CacheSubelementParameterValues(rebarElement, rebarElementParams, ii, elemHnd); ExporterCacheManager.HandleToElementCache.Register(elemHnd, rebarElement.Id); CategoryUtil.CreateMaterialAssociation(exporterIFC, elemHnd, materialId); } } transaction.Commit(); } return(createdRebars); }
/// <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(); 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, plane, 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 as an IfcReinforcingMesh. /// </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> /// <returns>True if exported successfully, false otherwise.</returns> public static bool ExportFabricSheet(ExporterIFC exporterIFC, FabricSheet sheet, GeometryElement geometryElement, ProductWrapper productWrapper) { if (sheet == null || geometryElement == null) { return(false); } Document doc = sheet.Document; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, sheet)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(placementSetter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(sheet); ElementId materialId = ElementId.InvalidElementId; ParameterUtil.GetElementIdValueFromElementOrSymbol(sheet, BuiltInParameter.MATERIAL_ID_PARAM, out materialId); string guid = GUIDUtil.CreateGUID(sheet); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string revitObjectType = exporterIFC.GetFamilyName(); string name = NamingUtil.GetNameOverride(sheet, revitObjectType); string description = NamingUtil.GetDescriptionOverride(sheet, null); string objectType = NamingUtil.GetObjectTypeOverride(sheet, revitObjectType); IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); string elementTag = NamingUtil.CreateIFCElementId(sheet); string steelGrade = NamingUtil.GetOverrideStringValue(sheet, "SteelGrade", null); double?meshLength = sheet.CutOverallLength; double?meshWidth = sheet.CutOverallWidth; Element fabricSheetTypeElem = doc.GetElement(sheet.GetTypeId()); FabricSheetType fabricSheetType = (fabricSheetTypeElem == null) ? null : (fabricSheetTypeElem as FabricSheetType); double longitudinalBarNominalDiameter = 0.0; double transverseBarNominalDiameter = 0.0; double longitudinalBarCrossSectionArea = 0.0; double transverseBarCrossSectionArea = 0.0; double longitudinalBarSpacing = 0.0; double transverseBarSpacing = 0.0; if (fabricSheetType != null) { Element majorFabricWireTypeElem = doc.GetElement(fabricSheetType.MajorDirectionWireType); FabricWireType majorFabricWireType = (majorFabricWireTypeElem == null) ? null : (majorFabricWireTypeElem as FabricWireType); if (majorFabricWireType != null) { longitudinalBarNominalDiameter = UnitUtil.ScaleLength(majorFabricWireType.WireDiameter); double localRadius = longitudinalBarNominalDiameter / 2.0; longitudinalBarCrossSectionArea = localRadius * localRadius * Math.PI; } Element minorFabricWireTypeElem = doc.GetElement(fabricSheetType.MinorDirectionWireType); FabricWireType minorFabricWireType = (minorFabricWireTypeElem == null) ? null : (minorFabricWireTypeElem as FabricWireType); if (minorFabricWireType != null) { transverseBarNominalDiameter = UnitUtil.ScaleLength(minorFabricWireType.WireDiameter); double localRadius = transverseBarNominalDiameter / 2.0; transverseBarCrossSectionArea = localRadius * localRadius * Math.PI; } longitudinalBarSpacing = UnitUtil.ScaleLength(fabricSheetType.MajorSpacing); transverseBarSpacing = UnitUtil.ScaleLength(fabricSheetType.MinorSpacing); } ISet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); IList <Curve> wireCenterlines = sheet.GetWireCenterlines(WireDistributionDirection.Major); foreach (Curve wireCenterline in wireCenterlines) { IFCAnyHandle bodyItem = CreateSweptDiskSolid(exporterIFC, file, wireCenterline, longitudinalBarNominalDiameter); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItem)) { bodyItems.Add(bodyItem); } } wireCenterlines = sheet.GetWireCenterlines(WireDistributionDirection.Minor); foreach (Curve wireCenterline in wireCenterlines) { IFCAnyHandle bodyItem = CreateSweptDiskSolid(exporterIFC, file, wireCenterline, transverseBarNominalDiameter); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItem)) { bodyItems.Add(bodyItem); } } IFCAnyHandle shapeRep = (bodyItems.Count > 0) ? RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC, sheet, categoryId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null) : null; IList <IFCAnyHandle> shapeReps = null; if (shapeRep != null) { shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(shapeRep); } IFCAnyHandle prodRep = (shapeReps != null) ? IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps) : null; IFCAnyHandle fabricSheet = IFCInstanceExporter.CreateReinforcingMesh(file, guid, ownerHistory, name, description, objectType, localPlacement, prodRep, elementTag, steelGrade, meshLength, meshWidth, longitudinalBarNominalDiameter, transverseBarNominalDiameter, longitudinalBarCrossSectionArea, transverseBarCrossSectionArea, longitudinalBarSpacing, transverseBarSpacing); ElementId fabricAreaId = sheet.FabricAreaOwnerId; if (fabricAreaId != ElementId.InvalidElementId) { HashSet <IFCAnyHandle> fabricSheets = null; if (!ExporterCacheManager.FabricAreaHandleCache.TryGetValue(fabricAreaId, out fabricSheets)) { fabricSheets = new HashSet <IFCAnyHandle>(); ExporterCacheManager.FabricAreaHandleCache[fabricAreaId] = fabricSheets; } fabricSheets.Add(fabricSheet); } productWrapper.AddElement(sheet, fabricSheet, placementSetter.LevelInfo, ecData, true); CategoryUtil.CreateMaterialAssociation(exporterIFC, fabricSheet, materialId); } } tr.Commit(); return(true); } }