/// <summary> /// Creates openings if there is necessary. /// </summary> /// <param name="elementHandle">The element handle to create openings.</param> /// <param name="element">The element to create openings.</param> /// <param name="info">The extrusion data.</param> /// <param name="extraParams">The extrusion creation data.</param> /// <param name="offsetTransform">The offset transform from ExportBody, or the identity transform.</param> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="originalPlacement">The original placement handle.</param> /// <param name="setter">The PlacementSetter.</param> /// <param name="wrapper">The ProductWrapper.</param> private static void CreateOpeningsIfNecessaryBase(IFCAnyHandle elementHandle, Element element, IList<IFCExtrusionData> info, IFCExtrusionCreationData extraParams, Transform offsetTransform, ExporterIFC exporterIFC, IFCAnyHandle originalPlacement, PlacementSetter setter, ProductWrapper wrapper) { if (IFCAnyHandleUtil.IsNullOrHasNoValue(elementHandle)) return; int sz = info.Count; if (sz == 0) return; using (TransformSetter transformSetter = TransformSetter.Create()) { if (offsetTransform != null) transformSetter.Initialize(exporterIFC, offsetTransform.Inverse); IFCFile file = exporterIFC.GetFile(); ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); Document document = element.Document; string openingObjectType = "Opening"; int openingNumber = 1; for (int curr = info.Count - 1; curr >= 0; curr--) { Transform extrusionTrf = Transform.Identity; IFCAnyHandle extrusionHandle = ExtrusionExporter.CreateExtrudedSolidFromExtrusionData(exporterIFC, element, info[curr]); if (IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionHandle)) continue; BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, extrusionHandle, ElementId.InvalidElementId); HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>(); bodyItems.Add(extrusionHandle); IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body"); IFCAnyHandle bodyRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItems, null); IList<IFCAnyHandle> representations = new List<IFCAnyHandle>(); representations.Add(bodyRep); IFCAnyHandle openingRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); IFCAnyHandle openingPlacement = ExporterUtil.CopyLocalPlacement(file, originalPlacement); string guid = GUIDUtil.CreateGUID(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string openingName = NamingUtil.GetIFCNamePlusIndex(element, openingNumber++); IFCAnyHandle openingElement = IFCInstanceExporter.CreateOpeningElement(exporterIFC, element, guid, ownerHistory, openingPlacement, openingRep); IFCAnyHandleUtil.OverrideNameAttribute(openingElement, openingName); IFCAnyHandleUtil.SetAttribute(openingElement, "ObjectType", openingObjectType); IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcOpeningElement); wrapper.AddElement(null, openingElement, setter, extraParams, true, exportInfo); if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities && (extraParams != null)) PropertyUtil.CreateOpeningQuantities(exporterIFC, openingElement, extraParams); string voidGuid = GUIDUtil.CreateGUID(); IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, elementHandle, openingElement); } } }
public static void TryToCreateMaterialAssocation(ExporterIFC exporterIFC, BodyData bodyData, Element elementType, Element element, GeometryElement exportGeometry, IFCAnyHandle typeStyle, FamilyTypeInfo typeInfo) { if (bodyData != null && bodyData.RepresentationItemInfo != null && bodyData.RepresentationItemInfo.Count > 0) { CreateMaterialAssociationWithShapeAspect(exporterIFC, elementType, typeStyle, bodyData.RepresentationItemInfo); return; } bool addedMaterialAssociation = false; IList <ElementId> matIds = BodyExporter.GetMaterialIdsFromGeometryOrParameters(exportGeometry, elementType, element); if (matIds.Count > 0) { CreateMaterialAssociation(exporterIFC, typeStyle, matIds); addedMaterialAssociation = true; if (typeInfo.MaterialIdList.Count == 0) { typeInfo.MaterialIdList = matIds; } } if (!addedMaterialAssociation) { CreateMaterialAssociation(exporterIFC, typeStyle, typeInfo.MaterialIdList); } return; }
/// <summary> /// Creates an IfcFacetedBrep handle. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="shell">The closed shell handle.</param> /// <returns>The handle.</returns> public static IFCAnyHandle CreateFacetedBRep(ExporterIFC exporterIFC, Document document, IFCAnyHandle shell, ElementId overrideMaterialId) { IFCFile file = exporterIFC.GetFile(); IFCAnyHandle brep = IFCInstanceExporter.CreateFacetedBrep(file, shell); BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, brep, overrideMaterialId); return brep; }
/// <summary> /// Exports an element as a covering of type insulation. /// </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 ExportDuctLining(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { if (element == null || geometryElement == null) { return(false); } // 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(false); } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { // Check for containment override IFCAnyHandle overrideContainer = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainer); using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainer)) { 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(false); } string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle localPlacement = ecData.GetLocalPlacement(); IFCAnyHandle ductLining = IFCInstanceExporter.CreateCovering(exporterIFC, element, guid, ownerHistory, localPlacement, representation, "Wrapping"); ExporterCacheManager.ElementToHandleCache.Register(element.Id, ductLining); productWrapper.AddElement(element, ductLining, placementSetter.LevelInfo, ecData, true); ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element); CategoryUtil.CreateMaterialAssociation(exporterIFC, ductLining, matId); } } tr.Commit(); return(true); } }
/// <summary> /// Exports an element as a covering of type insulation. /// </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 ExportDuctLining(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { if (element == null || geometryElement == null) { return(false); } IFCFile file = exporterIFC.GetFile(); 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(false); } string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); 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)); IFCAnyHandle ductLining = IFCInstanceExporter.CreateCovering(file, guid, ownerHistory, name, description, objectType, localPlacement, representation, elementTag, "Wrapping"); ExporterCacheManager.ElementToHandleCache.Register(element.Id, ductLining); productWrapper.AddElement(element, ductLining, placementSetter.LevelInfo, ecData, true); ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element); CategoryUtil.CreateMaterialAssociation(exporterIFC, ductLining, matId); } } tr.Commit(); return(true); } }
/// <summary> /// Creates a SweptSolid, Brep, SolidModel or SurfaceModel product definition shape representation, based on the geometry and IFC version. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="categoryId">The category id.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="bodyExporterOptions">The body exporter options.</param> /// <param name="extraReps">Extra representations (e.g. Axis, Boundary). May be null.</param> /// <param name="extrusionCreationData">The extrusion creation data.</param> /// <param name="bodyData">The body data.</param> /// <returns>The handle.</returns> public static IFCAnyHandle CreateAppropriateProductDefinitionShape(ExporterIFC exporterIFC, Element element, ElementId categoryId, GeometryElement geometryElement, BodyExporterOptions bodyExporterOptions, IList<IFCAnyHandle> extraReps, IFCExtrusionCreationData extrusionCreationData, out BodyData bodyData) { bodyData = null; SolidMeshGeometryInfo info = null; IList<GeometryObject> geometryList = new List<GeometryObject>(); if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { info = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement, Transform.Identity); IList<Mesh> meshes = info.GetMeshes(); if (meshes.Count == 0) { IList<Solid> solidList = info.GetSolids(); foreach (Solid solid in solidList) { geometryList.Add(solid); } } } if (geometryList.Count == 0) geometryList.Add(geometryElement); else bodyExporterOptions.TryToExportAsExtrusion = true; bodyData = BodyExporter.ExportBody(exporterIFC, element, categoryId, ElementId.InvalidElementId, geometryList, bodyExporterOptions, extrusionCreationData); IFCAnyHandle bodyRep = bodyData.RepresentationHnd; List<IFCAnyHandle> bodyReps = new List<IFCAnyHandle>(); if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { if (extrusionCreationData != null) extrusionCreationData.ClearOpenings(); } else bodyReps.Add(bodyRep); if (extraReps != null) { foreach (IFCAnyHandle hnd in extraReps) bodyReps.Add(hnd); } IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); if (boundingBoxRep != null) bodyReps.Add(boundingBoxRep); if (bodyReps.Count == 0) return null; return IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, bodyReps); }
/// <summary> /// Creates an IfcFacetedBrep handle. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="shell"> /// The closed shell handle. /// </param> /// <returns> /// The handle. /// </returns> public static IFCAnyHandle CreateFacetedBRep(ExporterIFC exporterIFC, Document document, IFCAnyHandle shell, ElementId overrideMaterialId) { IFCFile file = exporterIFC.GetFile(); IFCAnyHandle brep = IFCInstanceExporter.CreateFacetedBrep(file, shell); // Coordination View V2 does not support styled items by default. IFC2x2 does, even if it isn't widely used, so we can't use ExportAnnotations. if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x3CoordinationView2) { BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, brep, overrideMaterialId); } return(brep); }
/// <summary> /// Create the "Body" IfcRepresentation for a beam if it is representable by an extrusion, possibly with clippings and openings. /// </summary> /// <param name="exporterIFC">The exporterIFC class.</param> /// <param name="element">The beam element.T</param> /// <param name="catId">The category id.</param> /// <param name="geomObjects">The list of solids and meshes representing the beam's geometry. /// <param name="axisInfo">The beam axis information.</param> /// <returns>The BeamBodyAsExtrusionInfo class which contains the created handle (if any) and other information, or null.</returns> private static BeamBodyAsExtrusionInfo CreateBeamGeometryAsExtrusion(ExporterIFC exporterIFC, Element element, ElementId catId, IList <GeometryObject> geomObjects, BeamAxisInfo axisInfo) { // If we have a beam with a Linear location line that only has one solid geometry, // we will try to use the ExtrusionAnalyzer to generate an extrusion with 0 or more clippings. // This code is currently limited in that it will not process beams with openings, so we // use other methods below if this one fails. if (geomObjects == null || geomObjects.Count != 1 || (!(geomObjects[0] is Solid)) || axisInfo == null || !(axisInfo.Axis is Line)) { return(null); } BeamBodyAsExtrusionInfo info = new BeamBodyAsExtrusionInfo(); info.DontExport = false; info.Materials = new HashSet <ElementId>(); info.Slope = 0.0; Transform orientTrf = axisInfo.LCSAsTransform; Solid solid = geomObjects[0] as Solid; bool completelyClipped; XYZ beamDirection = orientTrf.BasisX; XYZ planeXVec = orientTrf.BasisY.Normalize(); XYZ planeYVec = orientTrf.BasisZ.Normalize(); Plane beamExtrusionBasePlane = GeometryUtil.CreatePlaneByXYVectorsAtOrigin(planeXVec, planeYVec); info.RepresentationHandle = ExtrusionExporter.CreateExtrusionWithClipping(exporterIFC, element, catId, solid, beamExtrusionBasePlane, orientTrf.Origin, beamDirection, null, out completelyClipped); if (completelyClipped) { info.DontExport = true; return(null); } if (!IFCAnyHandleUtil.IsNullOrHasNoValue(info.RepresentationHandle)) { // This is used by the BeamSlopeCalculator. This should probably be generated automatically by // CreateExtrusionWithClipping. IFCExtrusionBasis bestAxis = (Math.Abs(beamDirection[0]) > Math.Abs(beamDirection[1])) ? IFCExtrusionBasis.BasisX : IFCExtrusionBasis.BasisY; info.Slope = GeometryUtil.GetSimpleExtrusionSlope(beamDirection, bestAxis); ElementId materialId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(solid, exporterIFC, element); if (materialId != ElementId.InvalidElementId) { info.Materials.Add(materialId); } } return(info); }
/// <summary> /// Exports mullion. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="mullion"> /// The mullion object. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="localPlacement"> /// The local placement handle. /// </param> /// <param name="setter"> /// The IFCPlacementSetter. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void Export(ExporterIFC exporterIFC, Mullion mullion, GeometryElement geometryElement, IFCAnyHandle localPlacement, IFCPlacementSetter setter, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (IFCPlacementSetter mullionSetter = IFCPlacementSetter.Create(exporterIFC, mullion, null, null, ExporterUtil.GetBaseLevelIdForElement(mullion))) { using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData()) { IFCAnyHandle mullionPlacement = mullionSetter.GetPlacement(); Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(localPlacement, mullionPlacement); Transform inverseTrf = relTrf.Inverse; IFCAnyHandle mullionRelativePlacement = ExporterUtil.CreateAxis2Placement3D(file, inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX); IFCAnyHandle mullionLocalPlacement = IFCInstanceExporter.CreateLocalPlacement(file, localPlacement, mullionRelativePlacement); extraParams.SetLocalPlacement(mullionLocalPlacement); ElementId catId = CategoryUtil.GetSafeCategoryId(mullion); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); IFCAnyHandle repHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, mullion, catId, geometryElement, bodyExporterOptions, null, extraParams, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd)) { extraParams.ClearOpenings(); return; } string elemGUID = GUIDUtil.CreateGUID(mullion); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); string elemObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, mullion); string name = NamingUtil.GetNameOverride(mullion, elemObjectType); string description = NamingUtil.GetDescriptionOverride(mullion, null); string objectType = NamingUtil.GetObjectTypeOverride(mullion, elemObjectType); string elemTag = NamingUtil.GetTagOverride(mullion, NamingUtil.CreateIFCElementId(mullion)); IFCAnyHandle mullionHnd = IFCInstanceExporter.CreateMember(file, elemGUID, ownerHistory, name, description, objectType, mullionLocalPlacement, repHnd, elemTag); ExporterCacheManager.HandleToElementCache.Register(mullionHnd, mullion.Id); productWrapper.AddElement(mullion, mullionHnd, mullionSetter, extraParams, false); ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, mullion); CategoryUtil.CreateMaterialAssociation(exporterIFC, mullionHnd, matId); } } }
/// <summary> /// Creates a Brep product definition shape representation. /// </summary> /// <param name="application">The Revit application object.</param> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="categoryId">The category id.</param> /// <param name="geometryObject">The geometry object.</param> /// <param name="extraReps">Extra representations (e.g. Axis, Footprint). May be null.</param> /// <param name="options">The settings for how to export the body.</param> /// <param name="extrusionCreationData">The extrusion creation data.</param> /// <param name="bodyData">The body data.</param> /// <returns>The handle.</returns> public static IFCAnyHandle CreateBRepProductDefinitionShape(Autodesk.Revit.ApplicationServices.Application application, ExporterIFC exporterIFC, Element element, ElementId categoryId, IList <GeometryObject> geometryObjectIn, IList <IFCAnyHandle> extraReps, BodyExporterOptions bodyExporterOptions, IFCExtrusionCreationData extrusionCreationData, out BodyData bodyData) { bodyData = BodyExporter.ExportBody(application, exporterIFC, element, categoryId, geometryObjectIn, bodyExporterOptions, extrusionCreationData); IFCAnyHandle bodyRep = bodyData.RepresentationHnd; List <IFCAnyHandle> bodyReps = new List <IFCAnyHandle>(); if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { if (extrusionCreationData != null) { extrusionCreationData.ClearOpenings(); } } else { bodyReps.Add(bodyRep); } if (extraReps != null) { foreach (IFCAnyHandle hnd in extraReps) { bodyReps.Add(hnd); } } if (bodyReps.Count == 0) { return(null); } return(IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, bodyReps)); }
/// <summary> /// Exports curtain object as one Brep. /// </summary> /// <param name="allSubElements"> /// Collection of elements contained in the host curtain element. /// </param> /// <param name="wallElement"> /// The curtain wall element. /// </param> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="setter"> /// The PlacementSetter object. /// </param> /// <param name="localPlacement"> /// The local placement handle. /// </param> /// <returns> /// The handle. /// </returns> public static IFCAnyHandle ExportCurtainObjectCommonAsOneBRep(ICollection <ElementId> allSubElements, Element wallElement, ExporterIFC exporterIFC, PlacementSetter setter, IFCAnyHandle localPlacement) { IFCAnyHandle prodDefRep = null; Document document = wallElement.Document; double eps = UnitUtil.ScaleLength(document.Application.VertexTolerance); IFCFile file = exporterIFC.GetFile(); IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body"); IFCGeometryInfo info = IFCGeometryInfo.CreateFaceGeometryInfo(eps); ISet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); // Want to make sure we don't accidentally add a mullion or curtain line more than once. HashSet <ElementId> alreadyVisited = new HashSet <ElementId>(); bool useFallbackBREP = true; Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions(); foreach (ElementId subElemId in allSubElements) { Element subElem = wallElement.Document.GetElement(subElemId); GeometryElement geomElem = subElem.get_Geometry(geomOptions); if (geomElem == null) { continue; } if (alreadyVisited.Contains(subElem.Id)) { continue; } alreadyVisited.Add(subElem.Id); // Export tessellated geometry when IFC4 Reference View is selected if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(false, ExportOptionsCache.ExportTessellationLevel.ExtraLow); IFCAnyHandle triFaceSet = BodyExporter.ExportBodyAsTessellatedFaceSet(exporterIFC, subElem, bodyExporterOptions, geomElem); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triFaceSet)) { bodyItems.Add(triFaceSet); useFallbackBREP = false; // no need to do Brep since it is successful } } // Export AdvancedFace before use fallback BREP else if (ExporterCacheManager.ExportOptionsCache.ExportAs4DesignTransferView) { BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(false, ExportOptionsCache.ExportTessellationLevel.ExtraLow); IFCAnyHandle advancedBRep = BodyExporter.ExportBodyAsAdvancedBrep(exporterIFC, subElem, bodyExporterOptions, geomElem); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(advancedBRep)) { bodyItems.Add(advancedBRep); useFallbackBREP = false; // no need to do Brep since it is successful } } if (useFallbackBREP) { ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geomElem, XYZ.Zero, false); HashSet <IFCAnyHandle> faces = new HashSet <IFCAnyHandle>(info.GetSurfaces()); IFCAnyHandle outer = IFCInstanceExporter.CreateClosedShell(file, faces); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(outer)) { bodyItems.Add(RepresentationUtil.CreateFacetedBRep(exporterIFC, document, outer, ElementId.InvalidElementId)); } } } if (bodyItems.Count == 0) { return(prodDefRep); } ElementId catId = CategoryUtil.GetSafeCategoryId(wallElement); IFCAnyHandle shapeRep; // Use tessellated geometry in Reference View if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && !useFallbackBREP) { shapeRep = RepresentationUtil.CreateTessellatedRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems, null); } else if (ExporterCacheManager.ExportOptionsCache.ExportAs4DesignTransferView && !useFallbackBREP) { shapeRep = RepresentationUtil.CreateAdvancedBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems, null); } else { shapeRep = RepresentationUtil.CreateBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep)) { return(prodDefRep); } IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(shapeRep); IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, wallElement.get_Geometry(geomOptions), Transform.Identity); if (boundingBoxRep != null) { shapeReps.Add(boundingBoxRep); } prodDefRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); return(prodDefRep); }
/// <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 = UnitUtil.ScaleLength(doc.Application.VertexTolerance); ifcGeomInfo = IFCGeometryInfo.CreateFaceGeometryInfo(exporterIFC, plane, projDir, eps, exportBoundaryRep); ExporterIFCUtils.CollectGeometryInfo(exporterIFC, ifcGeomInfo, geometryElement, XYZ.Zero, true); IFCFile file = exporterIFC.GetFile(); IFCAnyHandle surface; // Use tessellated geometry for surface in IFC Reference View if (ExporterUtil.IsReferenceView()) { BodyExporterOptions options = new BodyExporterOptions(false); surface = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, element, options, geometryElement); } else { 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); } surface = IFCInstanceExporter.CreateFaceBasedSurfaceModel(file, faceSets); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(surface)) { return(false); } BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, doc, surface, BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element)); ISet <IFCAnyHandle> surfaceItems = new HashSet <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) { HashSet <IFCAnyHandle> boundaryRepresentationSet = new HashSet <IFCAnyHandle>(); boundaryRepresentationSet.UnionWith(boundaryRepresentations); boundaryRep = RepresentationUtil.CreateBoundaryRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("FootPrint"), boundaryRepresentationSet, boundaryRep); } return(true); }
/// <summary> /// Exports a Rebar Coupler, /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="coupler">The RebarCoupler element.</param> /// <param name="productWrapper">The product wrapper.</param> public static void ExportCoupler(ExporterIFC exporterIFC, RebarCoupler coupler, ProductWrapper productWrapper) { if (coupler == null) { return; } FamilySymbol familySymbol = ExporterCacheManager.Document.GetElement(coupler.GetTypeId()) as FamilySymbol; if (familySymbol == 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>("IfcMechanicalFastener", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } ElementId categoryId = CategoryUtil.GetSafeCategoryId(coupler); IFCFile file = exporterIFC.GetFile(); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; Options options = GeometryUtil.GetIFCExportGeometryOptions();; string ifcEnumType; IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, coupler, out ifcEnumType); using (IFCTransaction tr = new IFCTransaction(file)) { FamilyTypeInfo currentTypeInfo = ExporterCacheManager.FamilySymbolToTypeInfoCache.Find(coupler.GetTypeId(), false, exportType.ExportType); bool found = currentTypeInfo.IsValid(); if (!found) { string typeObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, familySymbol); HashSet <IFCAnyHandle> propertySetsOpt = new HashSet <IFCAnyHandle>(); GeometryElement exportGeometry = familySymbol.get_Geometry(options); BodyData bodyData = null; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); bodyData = BodyExporter.ExportBody(exporterIFC, coupler, categoryId, ElementId.InvalidElementId, exportGeometry, bodyExporterOptions, null); List <IFCAnyHandle> repMap = new List <IFCAnyHandle>(); IFCAnyHandle origin = ExporterUtil.CreateAxis2Placement3D(file);; repMap.Add(IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyData.RepresentationHnd)); IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, propertySetsOpt, repMap, coupler, familySymbol); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) { string applicableOccurrence = NamingUtil.GetObjectTypeOverride(familySymbol, typeObjectType); if (!string.IsNullOrEmpty(applicableOccurrence)) { IFCAnyHandleUtil.SetAttribute(styleHandle, "ApplicableOccurrence", applicableOccurrence); } currentTypeInfo.Style = styleHandle; ExporterCacheManager.FamilySymbolToTypeInfoCache.Register(coupler.GetTypeId(), false, exportType.ExportType, currentTypeInfo); } } int nCouplerQuantity = coupler.GetCouplerQuantity(); if (nCouplerQuantity <= 0) { return; } ISet <IFCAnyHandle> createdRebarCouplerHandles = new HashSet <IFCAnyHandle>(); string origInstanceName = NamingUtil.GetNameOverride(coupler, NamingUtil.GetIFCName(coupler)); for (int idx = 0; idx < nCouplerQuantity; idx++) { string instanceGUID = GUIDUtil.CreateSubElementGUID(coupler, idx); IFCAnyHandle style = currentTypeInfo.Style; if (IFCAnyHandleUtil.IsNullOrHasNoValue(style)) { return; } IList <IFCAnyHandle> repMapList = GeometryUtil.GetRepresentationMaps(style); if (repMapList == null) { return; } if (repMapList.Count == 0) { return; } IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); IFCAnyHandle contextOfItems3d = exporterIFC.Get3DContextHandle("Body"); ISet <IFCAnyHandle> representations = new HashSet <IFCAnyHandle>(); representations.Add(ExporterUtil.CreateDefaultMappedItem(file, repMapList[0], XYZ.Zero)); IFCAnyHandle shapeRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, coupler, categoryId, contextOfItems3d, representations); shapeReps.Add(shapeRep); IFCAnyHandle productRepresentation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, shapeReps); Transform trf = coupler.GetCouplerPositionTransform(idx); using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, coupler, trf, null)) { IFCAnyHandle instanceHandle = null; IFCExportInfoPair exportMechFastener = new IFCExportInfoPair(); exportMechFastener.SetValueWithPair(IFCEntityType.IfcMechanicalFastener); instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportMechFastener, exporterIFC, coupler, instanceGUID, ownerHistory, setter.LocalPlacement, productRepresentation); string instanceName = NamingUtil.GetNameOverride(instanceHandle, coupler, origInstanceName + ": " + idx); IFCAnyHandleUtil.SetAttribute(instanceHandle, "Name", instanceName); if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { // In IFC4 NominalDiameter and NominalLength attributes have been deprecated. PredefinedType attribute was added. IFCAnyHandleUtil.SetAttribute(instanceHandle, "PredefinedType", Revit.IFC.Export.Toolkit.IFC4.IFCMechanicalFastenerType.USERDEFINED); } else { IFCAnyHandleUtil.SetAttribute(instanceHandle, "NominalDiameter", familySymbol.get_Parameter(BuiltInParameter.COUPLER_WIDTH).AsDouble()); IFCAnyHandleUtil.SetAttribute(instanceHandle, "NominalLength", familySymbol.get_Parameter(BuiltInParameter.COUPLER_LENGTH).AsDouble()); } createdRebarCouplerHandles.Add(instanceHandle); productWrapper.AddElement(coupler, instanceHandle, setter, null, true); } } string couplerGUID = GUIDUtil.CreateGUID(coupler); if (nCouplerQuantity > 1) { // Create a group to hold all of the created IFC entities, if the coupler aren't already in an assembly. // We want to avoid nested groups of groups of couplers. if (coupler.AssemblyInstanceId == ElementId.InvalidElementId) { string revitObjectType = exporterIFC.GetFamilyName(); string name = NamingUtil.GetNameOverride(coupler, revitObjectType); string description = NamingUtil.GetDescriptionOverride(coupler, null); string objectType = NamingUtil.GetObjectTypeOverride(coupler, revitObjectType); IFCAnyHandle rebarGroup = IFCInstanceExporter.CreateGroup(file, couplerGUID, ownerHistory, name, description, objectType); productWrapper.AddElement(coupler, rebarGroup); IFCInstanceExporter.CreateRelAssignsToGroup(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, createdRebarCouplerHandles, null, rebarGroup); } } else { // We will update the GUID of the one created element to be the element GUID. // This will allow the IfcGUID parameter to be use/set if appropriate. ExporterUtil.SetGlobalId(createdRebarCouplerHandles.ElementAt(0), couplerGUID); } tr.Commit(); } }
/// <summary> /// Exports a roof or floor as a container of multiple roof slabs. Returns the handle, if successful. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="ifcEnumType">The roof type.</param> /// <param name="element">The roof or floor element.</param> /// <param name="geometry">The geometry of the element.</param> /// <param name="productWrapper">The product wrapper.</param> /// <returns>The roof handle.</returns> /// <remarks>For floors, if there is only one component, return null, as we do not want to create a container.</remarks> public static IFCAnyHandle ExportRoofOrFloorAsContainer(ExporterIFC exporterIFC, string ifcEnumType, Element element, GeometryElement geometry, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); // We support ExtrusionRoofs, FootPrintRoofs, and Floors only. bool elementIsRoof = (element is ExtrusionRoof) || (element is FootPrintRoof); bool elementIsFloor = (element is Floor); if (!elementIsRoof && !elementIsFloor) { return(null); } using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { IFCAnyHandle localPlacement = setter.LocalPlacement; IList <HostObjectSubcomponentInfo> hostObjectSubcomponents = null; try { hostObjectSubcomponents = ExporterIFCUtils.ComputeSubcomponents(element as HostObject); } catch { return(null); } if (hostObjectSubcomponents == null) { return(null); } int numSubcomponents = hostObjectSubcomponents.Count; if (numSubcomponents == 0 || (elementIsFloor && numSubcomponents == 1)) { return(null); } try { using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; extrusionCreationData.SetLocalPlacement(localPlacement); extrusionCreationData.ReuseLocalPlacement = true; using (TransformSetter trfSetter = TransformSetter.Create()) { IList <GeometryObject> geometryList = new List <GeometryObject>(); geometryList.Add(geometry); trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, extrusionCreationData); IFCAnyHandle prodRepHnd = null; string elementGUID = GUIDUtil.CreateGUID(element); string elementName = NamingUtil.GetIFCName(element); string elementDescription = NamingUtil.GetDescriptionOverride(element, null); string elementObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string elementId = NamingUtil.CreateIFCElementId(element); string hostObjectType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType); IFCAnyHandle hostObjectHandle = null; if (elementIsRoof) { hostObjectHandle = IFCInstanceExporter.CreateRoof(file, elementGUID, ownerHistory, elementName, elementDescription, elementObjectType, localPlacement, prodRepHnd, elementId, hostObjectType); } else { hostObjectHandle = IFCInstanceExporter.CreateSlab(file, elementGUID, ownerHistory, elementName, elementDescription, elementObjectType, localPlacement, prodRepHnd, elementId, hostObjectType); } if (IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjectHandle)) { return(null); } IList <IFCAnyHandle> elementHandles = new List <IFCAnyHandle>(); elementHandles.Add(hostObjectHandle); // If element is floor, then the profile curve loop of hostObjectSubComponent is computed from the top face of the floor // else if element is roof, then the profile curve loop is taken from the bottom face of the roof instead XYZ extrusionDir = elementIsFloor ? new XYZ(0, 0, -1) : new XYZ(0, 0, 1); ElementId catId = CategoryUtil.GetSafeCategoryId(element); IList <IFCAnyHandle> slabHandles = new List <IFCAnyHandle>(); IList <CurveLoop> hostObjectOpeningLoops = new List <CurveLoop>(); double maximumScaledDepth = 0.0; using (IFCExtrusionCreationData slabExtrusionCreationData = new IFCExtrusionCreationData()) { slabExtrusionCreationData.SetLocalPlacement(extrusionCreationData.GetLocalPlacement()); slabExtrusionCreationData.ReuseLocalPlacement = false; slabExtrusionCreationData.ForceOffset = true; int loopNum = 0; int subElementStart = elementIsRoof ? (int)IFCRoofSubElements.RoofSlabStart : (int)IFCSlabSubElements.SubSlabStart; string subSlabType = elementIsRoof ? "ROOF" : hostObjectType; foreach (HostObjectSubcomponentInfo hostObjectSubcomponent in hostObjectSubcomponents) { trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, slabExtrusionCreationData); Plane plane = hostObjectSubcomponent.GetPlane(); Transform lcs = GeometryUtil.CreateTransformFromPlane(plane); IList <CurveLoop> curveLoops = new List <CurveLoop>(); CurveLoop slabCurveLoop = hostObjectSubcomponent.GetCurveLoop(); curveLoops.Add(slabCurveLoop); double slope = Math.Abs(plane.Normal.Z); double scaledDepth = UnitUtil.ScaleLength(hostObjectSubcomponent.Depth); double scaledExtrusionDepth = scaledDepth * slope; IFCAnyHandle shapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, scaledExtrusionDepth, false); if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep)) { return(null); } ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(element as HostObject); BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, shapeRep, matId); HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); bodyItems.Add(shapeRep); shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null); IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(shapeRep); IFCAnyHandle repHnd = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); // Allow support for up to 256 named IfcSlab components, as defined in IFCSubElementEnums.cs. string slabGUID = (loopNum < 256) ? GUIDUtil.CreateSubElementGUID(element, subElementStart + loopNum) : GUIDUtil.CreateGUID(); IFCAnyHandle slabPlacement = ExporterUtil.CreateLocalPlacement(file, slabExtrusionCreationData.GetLocalPlacement(), null); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, slabGUID, ownerHistory, elementName, elementDescription, elementObjectType, slabPlacement, repHnd, elementId, subSlabType); //slab quantities slabExtrusionCreationData.ScaledLength = scaledExtrusionDepth; slabExtrusionCreationData.ScaledArea = UnitUtil.ScaleArea(UnitUtil.ScaleArea(hostObjectSubcomponent.AreaOfCurveLoop)); slabExtrusionCreationData.ScaledOuterPerimeter = UnitUtil.ScaleLength(curveLoops[0].GetExactLength()); slabExtrusionCreationData.Slope = UnitUtil.ScaleAngle(MathUtil.SafeAcos(Math.Abs(slope))); productWrapper.AddElement(null, slabHnd, setter, slabExtrusionCreationData, false); elementHandles.Add(slabHnd); slabHandles.Add(slabHnd); hostObjectOpeningLoops.Add(slabCurveLoop); maximumScaledDepth = Math.Max(maximumScaledDepth, scaledDepth); loopNum++; } } productWrapper.AddElement(element, hostObjectHandle, setter, extrusionCreationData, true); ExporterUtil.RelateObjects(exporterIFC, null, hostObjectHandle, slabHandles); OpeningUtil.AddOpeningsToElement(exporterIFC, elementHandles, hostObjectOpeningLoops, element, null, maximumScaledDepth, null, setter, localPlacement, productWrapper); transaction.Commit(); return(hostObjectHandle); } } } finally { exporterIFC.ClearFaceWithElementHandleMap(); } } } }
/// <summary> /// Exports an element as IFC covering. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element to be exported.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportCovering(ExporterIFC exporterIFC, Element element, GeometryElement geomElem, string ifcEnumType, ProductWrapper productWrapper) { bool exportParts = PartExporter.CanExportParts(element); if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false)) { return; } // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>("IfcCovering", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } ElementType elemType = element.Document.GetElement(element.GetTypeId()) as ElementType; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); IFCAnyHandle prodRep = null; if (!exportParts) { ecData.SetLocalPlacement(setter.LocalPlacement); ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, categoryId, geomElem, bodyExporterOptions, null, ecData, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) { ecData.ClearOpenings(); return; } } // We will use the category of the element to set a default value for the covering. string defaultCoveringEnumType = null; if (categoryId == new ElementId(BuiltInCategory.OST_Ceilings)) { defaultCoveringEnumType = "CEILING"; } else if (categoryId == new ElementId(BuiltInCategory.OST_Floors)) { defaultCoveringEnumType = "FLOORING"; } else if (categoryId == new ElementId(BuiltInCategory.OST_Roofs)) { defaultCoveringEnumType = "ROOFING"; } string instanceGUID = GUIDUtil.CreateGUID(element); string instanceName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string instanceDescription = NamingUtil.GetDescriptionOverride(element, null); string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string instanceTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); string coveringType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType, defaultCoveringEnumType); IFCAnyHandle covering = IFCInstanceExporter.CreateCovering(file, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, instanceName, instanceDescription, instanceObjectType, setter.LocalPlacement, prodRep, instanceTag, coveringType); if (exportParts) { PartExporter.ExportHostPart(exporterIFC, element, covering, productWrapper, setter, setter.LocalPlacement, null); } bool containInSpace = false; IFCAnyHandle localPlacementToUse = setter.LocalPlacement; // Ceiling containment in Space is generally required and not specific to any view if (ExporterCacheManager.CeilingSpaceRelCache.ContainsKey(element.Id)) { IList <ElementId> roomlist = ExporterCacheManager.CeilingSpaceRelCache[element.Id]; // Process Ceiling to be contained in a Space only when it is exactly bounding one Space if (roomlist.Count == 1) { productWrapper.AddElement(element, covering, setter, null, false); // Modify the Ceiling placement to be relative to the Space that it bounds IFCAnyHandle roomPlacement = IFCAnyHandleUtil.GetObjectPlacement(ExporterCacheManager.SpaceInfoCache.FindSpaceHandle(roomlist[0])); Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(roomPlacement, localPlacementToUse); Transform inverseTrf = relTrf.Inverse; IFCAnyHandle relLocalPlacement = ExporterUtil.CreateAxis2Placement3D(file, inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX); IFCAnyHandleUtil.SetAttribute(localPlacementToUse, "PlacementRelTo", roomPlacement); GeometryUtil.SetRelativePlacement(localPlacementToUse, relLocalPlacement); ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomlist[0], covering); containInSpace = true; } } // if not contained in Space, assign it to default containment in Level if (!containInSpace) { productWrapper.AddElement(element, covering, setter, null, true); } if (!exportParts) { Ceiling ceiling = element as Ceiling; if (ceiling != null) { HostObjectExporter.ExportHostObjectMaterials(exporterIFC, ceiling, covering, geomElem, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, null); } else { ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geomElem, exporterIFC, element); CategoryUtil.CreateMaterialAssociation(exporterIFC, covering, matId); } } OpeningUtil.CreateOpeningsIfNecessary(covering, element, ecData, null, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); } } transaction.Commit(); } }
/// <summary> /// Exports a gutter element. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> public static void ExportGutter(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper) { // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcPipeSegmentType; if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd); using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(setter.LocalPlacement); ElementId categoryId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); IFCAnyHandle bodyRep = BodyExporter.ExportBody(exporterIFC, element, categoryId, ElementId.InvalidElementId, geometryElement, bodyExporterOptions, ecData).RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { if (ecData != null) { ecData.ClearOpenings(); } return; } string originalTag = NamingUtil.CreateIFCElementId(element); // In Revit, we don't have a corresponding type, so we create one for every gutter. IFCAnyHandle origin = ExporterUtil.CreateAxis2Placement3D(file); IFCAnyHandle repMap3dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyRep); List <IFCAnyHandle> repMapList = new List <IFCAnyHandle>(); repMapList.Add(repMap3dHnd); string elementTypeName = NamingUtil.CreateIFCObjectName(exporterIFC, element); string typeGuid = GUIDUtil.CreateSubElementGUID(element, (int)IFCHostedSweepSubElements.PipeSegmentType); IFCAnyHandle style = IFCInstanceExporter.CreatePipeSegmentType(file, null, null, repMapList, IFCPipeSegmentType.Gutter); IFCAnyHandleUtil.OverrideNameAttribute(style, elementTypeName); IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcPipeSegmentType, IFCPipeSegmentType.Gutter.ToString()); IFCAnyHandleUtil.SetAttribute(style, "Tag", originalTag); ExporterUtil.SetGlobalId(style, typeGuid); IFCAnyHandleUtil.SetAttribute(style, "ElementType", elementTypeName); List <IFCAnyHandle> representationMaps = GeometryUtil.GetRepresentationMaps(style); IFCAnyHandle mappedItem = ExporterUtil.CreateDefaultMappedItem(file, representationMaps[0]); ISet <IFCAnyHandle> representations = new HashSet <IFCAnyHandle>(); representations.Add(mappedItem); IFCAnyHandle bodyMappedItemRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, element, categoryId, exporterIFC.Get3DContextHandle("Body"), representations); if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyMappedItemRep)) { return; } List <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(bodyMappedItemRep); IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); if (boundingBoxRep != null) { shapeReps.Add(boundingBoxRep); } IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); IFCAnyHandle localPlacementToUse; ElementId roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse); if (roomId == ElementId.InvalidElementId) { localPlacementToUse = ecData.GetLocalPlacement(); } string guid = GUIDUtil.CreateGUID(element); IFCAnyHandle elemHnd = IFCInstanceExporter.CreateFlowSegment(exporterIFC, element, guid, ExporterCacheManager.OwnerHistoryHandle, localPlacementToUse, prodRep); bool containedInSpace = (roomId != ElementId.InvalidElementId); productWrapper.AddElement(element, elemHnd, setter.LevelInfo, ecData, !containedInSpace, exportInfo); if (containedInSpace) { ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, elemHnd); } // Associate segment with type. ExporterCacheManager.TypeRelationsCache.Add(style, elemHnd); OpeningUtil.CreateOpeningsIfNecessary(elemHnd, element, ecData, null, exporterIFC, localPlacementToUse, setter, productWrapper); } tr.Commit(); } } }
/// <summary> /// Exports an element to IFC footing. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="element"> /// The element. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="ifcEnumType"> /// The string value represents the IFC type. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportFooting(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, string ifcEnumType, ProductWrapper productWrapper) { // export parts or not bool exportParts = PartExporter.CanExportParts(element); if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false)) { return; } // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>("IfcFooting", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(setter.LocalPlacement); IFCAnyHandle prodRep = null; ElementId matId = ElementId.InvalidElementId; if (!exportParts) { ElementId catId = CategoryUtil.GetSafeCategoryId(element); matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, ecData, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) { ecData.ClearOpenings(); return; } } string instanceGUID = GUIDUtil.CreateGUID(element); string footingType = GetIFCFootingType(ifcEnumType); // need to keep it for legacy support when original data follows slightly diff naming footingType = IFCValidateEntry.GetValidIFCType(element, footingType); IFCAnyHandle footing = IFCInstanceExporter.CreateFooting(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, ecData.GetLocalPlacement(), prodRep, footingType); if (exportParts) { PartExporter.ExportHostPart(exporterIFC, element, footing, productWrapper, setter, setter.LocalPlacement, null); } else { if (matId != ElementId.InvalidElementId) { CategoryUtil.CreateMaterialAssociation(exporterIFC, footing, matId); } } productWrapper.AddElement(element, footing, setter, ecData, true); OpeningUtil.CreateOpeningsIfNecessary(footing, element, ecData, null, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); } } tr.Commit(); } }
/// <summary> /// Exports a roof as a container of multiple roof slabs. Returns the handle, if successful. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="ifcEnumType">The roof type.</param> /// <param name="element">The roof element.</param> /// <param name="geometry">The geometry of the element.</param> /// <param name="productWrapper">The product wrapper.</param> /// <returns>The roof handle.</returns> public static IFCAnyHandle ExportRoofAsContainer(ExporterIFC exporterIFC, string ifcEnumType, Element element, GeometryElement geometry, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); if (!(element is ExtrusionRoof) && !(element is FootPrintRoof)) { return(null); } using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { IFCAnyHandle localPlacement = setter.LocalPlacement; RoofComponents roofComponents = null; try { roofComponents = ExporterIFCUtils.GetRoofComponents(exporterIFC, element as RoofBase); } catch { return(null); } if (roofComponents == null) { return(null); } try { using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); extrusionCreationData.SetLocalPlacement(localPlacement); extrusionCreationData.ReuseLocalPlacement = true; using (TransformSetter trfSetter = TransformSetter.Create()) { IList <GeometryObject> geometryList = new List <GeometryObject>(); geometryList.Add(geometry); trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, extrusionCreationData); IFCAnyHandle prodRepHnd = null; string elementGUID = GUIDUtil.CreateGUID(element); string elementName = NamingUtil.GetIFCName(element); string elementDescription = NamingUtil.GetDescriptionOverride(element, null); string elementObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string elementId = NamingUtil.CreateIFCElementId(element); string roofType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType); IFCAnyHandle roofHandle = IFCInstanceExporter.CreateRoof(file, elementGUID, ownerHistory, elementName, elementDescription, elementObjectType, localPlacement, prodRepHnd, elementId, roofType); IList <IFCAnyHandle> elementHandles = new List <IFCAnyHandle>(); elementHandles.Add(roofHandle); //only thing supported right now. XYZ extrusionDir = new XYZ(0, 0, 1); ElementId catId = CategoryUtil.GetSafeCategoryId(element); IList <CurveLoop> roofCurveloops = roofComponents.GetCurveLoops(); IList <XYZ> planeDirs = roofComponents.GetPlaneDirections(); IList <XYZ> planeOrigins = roofComponents.GetPlaneOrigins(); IList <Face> loopFaces = roofComponents.GetLoopFaces(); double scaledDepth = roofComponents.ScaledDepth; IList <double> areas = roofComponents.GetAreasOfCurveLoops(); IList <IFCAnyHandle> slabHandles = new List <IFCAnyHandle>(); using (IFCExtrusionCreationData slabExtrusionCreationData = new IFCExtrusionCreationData()) { slabExtrusionCreationData.SetLocalPlacement(extrusionCreationData.GetLocalPlacement()); slabExtrusionCreationData.ReuseLocalPlacement = false; slabExtrusionCreationData.ForceOffset = true; for (int numLoop = 0; numLoop < roofCurveloops.Count; numLoop++) { trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, slabExtrusionCreationData); Plane plane = new Plane(planeDirs[numLoop], planeOrigins[numLoop]); IList <CurveLoop> curveLoops = new List <CurveLoop>(); curveLoops.Add(roofCurveloops[numLoop]); double slope = Math.Abs(planeDirs[numLoop].Z); double scaledExtrusionDepth = scaledDepth * slope; IFCAnyHandle shapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, plane, extrusionDir, scaledExtrusionDepth); if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep)) { return(null); } ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(element as HostObject); BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, shapeRep, matId); HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); bodyItems.Add(shapeRep); shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null); IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); shapeReps.Add(shapeRep); IFCAnyHandle repHnd = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); // Allow support for up to 256 named IfcSlab components, as defined in IFCSubElementEnums.cs. string slabGUID = (numLoop < 256) ? GUIDUtil.CreateSubElementGUID(element, (int)IFCRoofSubElements.RoofSlabStart + numLoop) : GUIDUtil.CreateGUID(); IFCAnyHandle slabPlacement = ExporterUtil.CreateLocalPlacement(file, slabExtrusionCreationData.GetLocalPlacement(), null); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, slabGUID, ownerHistory, elementName, elementDescription, elementObjectType, slabPlacement, repHnd, elementId, "ROOF"); //slab quantities slabExtrusionCreationData.ScaledLength = scaledExtrusionDepth; slabExtrusionCreationData.ScaledArea = UnitUtil.ScaleArea(areas[numLoop]); slabExtrusionCreationData.ScaledOuterPerimeter = UnitUtil.ScaleLength(curveLoops[0].GetExactLength()); slabExtrusionCreationData.Slope = UnitUtil.ScaleAngle(Math.Acos(Math.Abs(planeDirs[numLoop].Z))); productWrapper.AddElement(null, slabHnd, setter, slabExtrusionCreationData, false); elementHandles.Add(slabHnd); slabHandles.Add(slabHnd); } } productWrapper.AddElement(element, roofHandle, setter, extrusionCreationData, true); ExporterUtil.RelateObjects(exporterIFC, null, roofHandle, slabHandles); OpeningUtil.AddOpeningsToElement(exporterIFC, elementHandles, roofCurveloops, element, null, roofComponents.ScaledDepth, null, setter, localPlacement, productWrapper); transaction.Commit(); return(roofHandle); } } } finally { exporterIFC.ClearFaceWithElementHandleMap(); } } } }
/// <summary> /// Exports a beam to IFC beam if it has an axis representation and only one Solid as its geometry, ideally as an extrusion, potentially with clippings and openings. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element to be exported.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <param name="dontExport">An output value that says that the element shouldn't be exported at all.</param> /// <returns>The created handle.</returns> /// <remarks>In the original implementation, the ExportBeam function would export each beam as its own individual geometry (that is, not use representation maps). /// For non-standard beams, this could result in massive IFC files. Now, we use the ExportBeamAsStandardElement function and limit its scope, and instead /// resort to the standard FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem for more complicated objects categorized as beams. This has the following pros and cons: /// Pro: possiblity for massively reduced file sizes for files containing repeated complex beam families /// Con: some beams that may have had an "Axis" representation before will no longer have them, although this possibility is minimized. /// Con: some beams that have 1 Solid and an axis, but that Solid will be heavily faceted, won't be helped by this improvement. /// It is intended that we phase out this routine entirely and instead teach ExportFamilyInstanceAsMappedItem how to sometimes export the Axis representation for beams.</remarks> public static IFCAnyHandle ExportBeamAsStandardElement(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper, out bool dontExport) { dontExport = true; IList <GeometryObject> geomObjects = BeamGeometryToExport(exporterIFC, element, geometryElement, out dontExport); if (dontExport) { return(null); } IFCAnyHandle beam = null; IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { BeamAxisInfo axisInfo = GetBeamAxisTransform(element); bool canExportAxis = (axisInfo != null); Curve curve = canExportAxis ? axisInfo.Axis : null; XYZ beamDirection = canExportAxis ? axisInfo.AxisDirection : null; Transform orientTrf = canExportAxis ? axisInfo.LCSAsTransform : null; using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, orientTrf)) { IFCAnyHandle localPlacement = setter.LocalPlacement; using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { extrusionCreationData.SetLocalPlacement(localPlacement); if (canExportAxis && (orientTrf.BasisX != null)) { extrusionCreationData.CustomAxis = beamDirection; extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom; } else { extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryXY; } ElementId catId = CategoryUtil.GetSafeCategoryId(element); // There may be an offset to make the local coordinate system // be near the origin. This offset will be used to move the axis to the new LCS. Transform offsetTransform = null; // The list of materials in the solids or meshes. ICollection <ElementId> materialIds = null; // The representation handle generated from one of the methods below. BeamBodyAsExtrusionInfo extrusionInfo = CreateBeamGeometryAsExtrusion(exporterIFC, element, catId, geomObjects, axisInfo); if (extrusionInfo != null && extrusionInfo.DontExport) { dontExport = true; return(null); } IFCAnyHandle repHnd = (extrusionInfo != null) ? extrusionInfo.RepresentationHandle : null; if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd)) { materialIds = extrusionInfo.Materials; extrusionCreationData.Slope = extrusionInfo.Slope; } else { // Here is where we limit the scope of how complex a case we will still try to export as a standard element. // This is explicitly added so that many curved beams that can be represented by a reasonable facetation because of the // SweptSolidExporter can still have an Axis representation. BodyData bodyData = null; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); if (geomObjects != null && geomObjects.Count == 1 && geomObjects[0] is Solid) { bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, geomObjects[0], bodyExporterOptions, extrusionCreationData); repHnd = bodyData.RepresentationHnd; materialIds = bodyData.MaterialIds; offsetTransform = bodyData.OffsetTransform; } } if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd)) { extrusionCreationData.ClearOpenings(); return(null); } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); IFCAnyHandle axisRep = CreateBeamAxis(exporterIFC, element, catId, axisInfo, offsetTransform); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisRep)) { representations.Add(axisRep); } representations.Add(repHnd); Transform boundingBoxTrf = (offsetTransform == null) ? Transform.Identity : offsetTransform.Inverse; IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, boundingBoxTrf); if (boundingBoxRep != null) { representations.Add(boundingBoxRep); } IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); string instanceGUID = GUIDUtil.CreateGUID(element); string instanceName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string instanceDescription = NamingUtil.GetDescriptionOverride(element, null); string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element)); string instanceTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); string preDefinedType = "BEAM"; // Default predefined type for Beam preDefinedType = IFCValidateEntry.GetValidIFCType(element, preDefinedType); beam = IFCInstanceExporter.CreateBeam(file, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, instanceName, instanceDescription, instanceObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, instanceTag, preDefinedType); productWrapper.AddElement(element, beam, setter, extrusionCreationData, true); OpeningUtil.CreateOpeningsIfNecessary(beam, element, extrusionCreationData, offsetTransform, exporterIFC, extrusionCreationData.GetLocalPlacement(), setter, productWrapper); FamilyTypeInfo typeInfo = new FamilyTypeInfo(); typeInfo.ScaledDepth = extrusionCreationData.ScaledLength; typeInfo.ScaledArea = extrusionCreationData.ScaledArea; typeInfo.ScaledInnerPerimeter = extrusionCreationData.ScaledInnerPerimeter; typeInfo.ScaledOuterPerimeter = extrusionCreationData.ScaledOuterPerimeter; PropertyUtil.CreateBeamColumnBaseQuantities(exporterIFC, beam, element, typeInfo, null); if (materialIds.Count != 0) { CategoryUtil.CreateMaterialAssociations(exporterIFC, beam, materialIds); } // Register the beam's IFC handle for later use by truss and beam system export. ExporterCacheManager.ElementToHandleCache.Register(element.Id, beam); } } transaction.Commit(); return(beam); } }
/// <summary> /// Exports a generic element as an IfcSlab.</summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="floor">The floor element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="ifcEnumType">The string value represents the IFC type.</param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if the floor is exported successfully, false otherwise.</returns> public static void ExportGenericSlab(ExporterIFC exporterIFC, Element slabElement, GeometryElement geometryElement, string ifcEnumType, ProductWrapper productWrapper) { if (geometryElement == null) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (IFCTransformSetter transformSetter = IFCTransformSetter.Create()) { using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, slabElement)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { bool exportParts = PartExporter.CanExportParts(slabElement); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; IFCAnyHandle localPlacement = placementSetter.LocalPlacement; IFCAnyHandle prodDefHnd = null; bool isBRepSlabHnd = false; if (!exportParts) { ecData.SetLocalPlacement(localPlacement); ElementId catId = CategoryUtil.GetSafeCategoryId(slabElement); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium); BodyData bodyData; prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, slabElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd)) { ecData.ClearOpenings(); return; } isBRepSlabHnd = (bodyData.ShapeRepresentationType == ShapeRepresentationType.Brep); } // Create the slab from either the extrusion or the BRep information. string ifcGUID = GUIDUtil.CreateGUID(slabElement); string entityType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(slabElement, ifcEnumType, "FLOOR"); string ifcName = NamingUtil.GetNameOverride(slabElement, NamingUtil.GetIFCName(slabElement)); string ifcDescription = NamingUtil.GetDescriptionOverride(slabElement, null); string ifcObjectType = NamingUtil.GetObjectTypeOverride(slabElement, exporterIFC.GetFamilyName()); string ifcTag = NamingUtil.GetTagOverride(slabElement, NamingUtil.CreateIFCElementId(slabElement)); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, ifcGUID, ownerHistory, ifcName, ifcDescription, ifcObjectType, localPlacement, exportParts ? null : prodDefHnd, ifcTag, entityType); if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd)) { return; } if (exportParts) { PartExporter.ExportHostPart(exporterIFC, slabElement, slabHnd, productWrapper, placementSetter, localPlacement, null); } productWrapper.AddElement(slabElement, slabHnd, placementSetter, ecData, true); if (!exportParts) { if (slabElement is HostObject) { HostObject hostObject = slabElement as HostObject; HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, slabHnd, geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, isBRepSlabHnd); } else if (slabElement is FamilyInstance) { ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, slabElement); Document doc = slabElement.Document; CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, matId); } OpeningUtil.CreateOpeningsIfNecessary(slabHnd, slabElement, ecData, null, exporterIFC, ecData.GetLocalPlacement(), placementSetter, productWrapper); } } } tr.Commit(); return; } } }
/// <summary> /// Export the individual part (IfcBuildingElementPart). /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="partElement">The part element to export.</param> /// <param name="geometryElement">The geometry of part.</param> /// <param name="productWrapper">The ProductWrapper object.</param> public static void ExportPart(ExporterIFC exporterIFC, Element partElement, ProductWrapper productWrapper, PlacementSetter placementSetter, IFCAnyHandle originalPlacement, IFCRange range, IFCExtrusionAxes ifcExtrusionAxes, Element hostElement, ElementId overrideLevelId, bool asBuildingElement) { if (!ElementFilteringUtil.IsElementVisible(partElement)) { return; } Part part = partElement as Part; if (part == null) { return; } if (!asBuildingElement) { // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>("IfcBuildingElementPart", out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } } else { string ifcEnumType = null; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType); // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>(exportType.ToString(), out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } } PlacementSetter standalonePlacementSetter = null; bool standaloneExport = hostElement == null && !asBuildingElement; ElementId partExportLevel = null; if (standaloneExport || asBuildingElement) { partExportLevel = partElement.LevelId; } else { if (part.OriginalCategoryId != hostElement.Category.Id) { return; } partExportLevel = hostElement.LevelId; } if (overrideLevelId != null) { partExportLevel = overrideLevelId; } if (ExporterCacheManager.PartExportedCache.HasExported(partElement.Id, partExportLevel)) { return; } Options options = GeometryUtil.GetIFCExportGeometryOptions(); View ownerView = partElement.Document.GetElement(partElement.OwnerViewId) as View; if (ownerView != null) { options.View = ownerView; } GeometryElement geometryElement = partElement.get_Geometry(options); if (geometryElement == null) { return; } try { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { IFCAnyHandle partPlacement = null; if (standaloneExport || asBuildingElement) { Transform orientationTrf = Transform.Identity; standalonePlacementSetter = PlacementSetter.Create(exporterIFC, partElement, null, orientationTrf, partExportLevel); partPlacement = standalonePlacementSetter.LocalPlacement; } else { partPlacement = ExporterUtil.CreateLocalPlacement(file, originalPlacement, null); } bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End)); SolidMeshGeometryInfo solidMeshInfo; if (validRange) { solidMeshInfo = GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range); if (solidMeshInfo.GetSolids().Count == 0 && solidMeshInfo.GetMeshes().Count == 0) { return; } } else { solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement); } using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { extrusionCreationData.SetLocalPlacement(partPlacement); extrusionCreationData.ReuseLocalPlacement = false; extrusionCreationData.PossibleExtrusionAxes = ifcExtrusionAxes; IList <Solid> solids = solidMeshInfo.GetSolids(); IList <Mesh> meshes = solidMeshInfo.GetMeshes(); ElementId catId = CategoryUtil.GetSafeCategoryId(partElement); ElementId hostCatId = CategoryUtil.GetSafeCategoryId(hostElement); BodyData bodyData = null; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); if (solids.Count > 0 || meshes.Count > 0) { bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, solids, meshes, bodyExporterOptions, extrusionCreationData); } else { IList <GeometryObject> geomlist = new List <GeometryObject>(); geomlist.Add(geometryElement); bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, geomlist, bodyExporterOptions, extrusionCreationData); } IFCAnyHandle bodyRep = bodyData.RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { extrusionCreationData.ClearOpenings(); return; } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(bodyRep); IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); if (boundingBoxRep != null) { representations.Add(boundingBoxRep); } IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string partGUID = GUIDUtil.CreateGUID(partElement); string partName = NamingUtil.GetNameOverride(partElement, NamingUtil.GetIFCName(partElement)); string partDescription = NamingUtil.GetDescriptionOverride(partElement, null); string partObjectType = NamingUtil.GetObjectTypeOverride(partElement, NamingUtil.CreateIFCObjectName(exporterIFC, partElement)); string partTag = NamingUtil.GetTagOverride(partElement, NamingUtil.CreateIFCElementId(partElement)); IFCAnyHandle ifcPart = null; if (!asBuildingElement) { ifcPart = IFCInstanceExporter.CreateBuildingElementPart(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag); } else { string ifcEnumType = null; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType); string defaultValue = null; // This replicates old functionality before IFC4 addition, where the default for slab was "FLOOR". // Really the export layer table should be fixed for this case. if (string.IsNullOrWhiteSpace(ifcEnumType) && hostCatId == new ElementId(BuiltInCategory.OST_Floors)) { ifcEnumType = "FLOOR"; } ifcEnumType = IFCValidateEntry.GetValidIFCType(hostElement, ifcEnumType, defaultValue); switch (exportType) { case IFCExportType.IfcColumnType: ifcPart = IFCInstanceExporter.CreateColumn(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcCovering: ifcPart = IFCInstanceExporter.CreateCovering(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcFooting: ifcPart = IFCInstanceExporter.CreateFooting(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcPile: ifcPart = IFCInstanceExporter.CreatePile(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType, null); break; case IFCExportType.IfcRoof: ifcPart = IFCInstanceExporter.CreateRoof(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcSlab: ifcPart = IFCInstanceExporter.CreateSlab(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; case IFCExportType.IfcWall: ifcPart = IFCInstanceExporter.CreateWall(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType); break; default: ifcPart = IFCInstanceExporter.CreateBuildingElementProxy(file, partGUID, ownerHistory, partName, partDescription, partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, null); break; } } bool containedInLevel = (standaloneExport || asBuildingElement); PlacementSetter whichPlacementSetter = containedInLevel ? standalonePlacementSetter : placementSetter; productWrapper.AddElement(partElement, ifcPart, whichPlacementSetter, extrusionCreationData, containedInLevel); OpeningUtil.CreateOpeningsIfNecessary(ifcPart, partElement, extrusionCreationData, bodyData.OffsetTransform, exporterIFC, extrusionCreationData.GetLocalPlacement(), whichPlacementSetter, productWrapper); //Add the exported part to exported cache. TraceExportedParts(partElement, partExportLevel, standaloneExport || asBuildingElement ? ElementId.InvalidElementId : hostElement.Id); CategoryUtil.CreateMaterialAssociation(exporterIFC, ifcPart, bodyData.MaterialIds); transaction.Commit(); } } } finally { if (standalonePlacementSetter != null) { standalonePlacementSetter.Dispose(); } } }
/// <summary> /// Export the individual part (IfcBuildingElementPart). /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="partElement">The part element to export.</param> /// <param name="geometryElement">The geometry of part.</param> /// <param name="productWrapper">The ProductWrapper object.</param> /// <param name="placementSetter"></param> /// <param name="originalPlacement"></param> /// <param name="range"></param> /// <param name="ifcExtrusionAxes"></param> /// <param name="hostElement">The host of the part. This can be null.</param> /// <param name="overrideLevelId">The id of the level that the part is one, overridding other sources.</param> /// <param name="asBuildingElement">If true, export the Part as a building element instead of an IfcElementPart.</param> public static void ExportPart(ExporterIFC exporterIFC, Element partElement, ProductWrapper productWrapper, PlacementSetter placementSetter, IFCAnyHandle originalPlacement, IFCRange range, IFCExtrusionAxes ifcExtrusionAxes, Element hostElement, ElementId overrideLevelId, bool asBuildingElement) { if (!ElementFilteringUtil.IsElementVisible(partElement)) { return; } Part part = partElement as Part; if (part == null) { return; } // We don't know how to export a part as a building element if we don't know it's host. if (asBuildingElement && (hostElement == null)) { return; } if (!asBuildingElement) { // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcBuildingElementPart; if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } else { string ifcEnumType = null; IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType); // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum; if (Enum.TryParse <Common.Enums.IFCEntityType>(exportType.ToString(), out elementClassTypeEnum)) { if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } } } PlacementSetter standalonePlacementSetter = null; bool standaloneExport = hostElement == null || asBuildingElement; ElementId partExportLevelId = (overrideLevelId != null) ? overrideLevelId : null; if (partExportLevelId == null && standaloneExport) { partExportLevelId = partElement.LevelId; } if (partExportLevelId == null) { if (hostElement == null || (part.OriginalCategoryId != hostElement.Category.Id)) { return; } partExportLevelId = hostElement.LevelId; } if (ExporterCacheManager.PartExportedCache.HasExported(partElement.Id, partExportLevelId)) { return; } Options options = GeometryUtil.GetIFCExportGeometryOptions(); View ownerView = partElement.Document.GetElement(partElement.OwnerViewId) as View; if (ownerView != null) { options.View = ownerView; } GeometryElement geometryElement = partElement.get_Geometry(options); if (geometryElement == null) { return; } try { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { IFCAnyHandle partPlacement = null; if (standaloneExport) { Transform orientationTrf = Transform.Identity; IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, partElement, out overrideContainerHnd); if (overrideContainerId != ElementId.InvalidElementId && (partExportLevelId == null || partExportLevelId == ElementId.InvalidElementId)) { partExportLevelId = overrideContainerId; } standalonePlacementSetter = PlacementSetter.Create(exporterIFC, partElement, null, orientationTrf, partExportLevelId, overrideContainerHnd); partPlacement = standalonePlacementSetter.LocalPlacement; } else { //partPlacement = ExporterUtil.CreateLocalPlacement(file, null, null); partPlacement = ExporterUtil.CreateLocalPlacement(file, originalPlacement, null); } bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End)); SolidMeshGeometryInfo solidMeshInfo; if (validRange) { solidMeshInfo = GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range); if (solidMeshInfo.GetSolids().Count == 0 && solidMeshInfo.GetMeshes().Count == 0) { return; } } else { solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement); } using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { extrusionCreationData.SetLocalPlacement(partPlacement); extrusionCreationData.ReuseLocalPlacement = false; extrusionCreationData.PossibleExtrusionAxes = ifcExtrusionAxes; IList <Solid> solids = new List <Solid>();; IList <Mesh> meshes = new List <Mesh>(); IList <GeometryObject> gObjs = FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(partElement.Document, exporterIFC, solidMeshInfo.GetSolids(), solidMeshInfo.GetMeshes()); foreach (GeometryObject gObj in gObjs) { if (gObj is Solid) { solids.Add(gObj as Solid); } else if (gObj is Mesh) { meshes.Add(gObj as Mesh); } } ElementId catId = CategoryUtil.GetSafeCategoryId(partElement); ElementId hostCatId = CategoryUtil.GetSafeCategoryId(hostElement); BodyData bodyData = null; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); if (solids.Count > 0 || meshes.Count > 0) { bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, solids, meshes, bodyExporterOptions, extrusionCreationData); } else { IList <GeometryObject> geomlist = new List <GeometryObject>(); geomlist.Add(geometryElement); bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, geomlist, bodyExporterOptions, extrusionCreationData); } IFCAnyHandle bodyRep = bodyData.RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { extrusionCreationData.ClearOpenings(); return; } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(bodyRep); IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); if (boundingBoxRep != null) { representations.Add(boundingBoxRep); } IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string partGUID = GUIDUtil.CreateGUID(partElement); string ifcEnumType = null; IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType); IFCAnyHandle ifcPart = null; if (!asBuildingElement) { ifcPart = IFCInstanceExporter.CreateBuildingElementPart(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep); } else { switch (exportType.ExportInstance) { case IFCEntityType.IfcColumn: ifcPart = IFCInstanceExporter.CreateColumn(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; case IFCEntityType.IfcCovering: ifcPart = IFCInstanceExporter.CreateCovering(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; case IFCEntityType.IfcFooting: ifcPart = IFCInstanceExporter.CreateFooting(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; case IFCEntityType.IfcPile: ifcPart = IFCInstanceExporter.CreatePile(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType, null); break; case IFCEntityType.IfcRoof: ifcPart = IFCInstanceExporter.CreateRoof(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; case IFCEntityType.IfcSlab: { // TODO: fix this elsewhere. if (ExporterUtil.IsNotDefined(ifcEnumType)) { if (hostCatId == new ElementId(BuiltInCategory.OST_Floors)) { ifcEnumType = "FLOOR"; } else if (hostCatId == new ElementId(BuiltInCategory.OST_Roofs)) { ifcEnumType = "ROOF"; } } ifcPart = IFCInstanceExporter.CreateSlab(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); } break; case IFCEntityType.IfcWall: ifcPart = IFCInstanceExporter.CreateWall(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType); break; default: ifcPart = IFCInstanceExporter.CreateBuildingElementProxy(exporterIFC, partElement, partGUID, ownerHistory, extrusionCreationData.GetLocalPlacement(), prodRep, exportType.ValidatedPredefinedType); break; } } bool containedInLevel = standaloneExport; PlacementSetter whichPlacementSetter = containedInLevel ? standalonePlacementSetter : placementSetter; productWrapper.AddElement(partElement, ifcPart, whichPlacementSetter, extrusionCreationData, containedInLevel, exportType); OpeningUtil.CreateOpeningsIfNecessary(ifcPart, partElement, extrusionCreationData, bodyData.OffsetTransform, exporterIFC, extrusionCreationData.GetLocalPlacement(), whichPlacementSetter, productWrapper); //Add the exported part to exported cache. TraceExportedParts(partElement, partExportLevelId, standaloneExport ? ElementId.InvalidElementId : hostElement.Id); CategoryUtil.CreateMaterialAssociation(exporterIFC, ifcPart, bodyData.MaterialIds); transaction.Commit(); } } } finally { if (standalonePlacementSetter != null) { standalonePlacementSetter.Dispose(); } } }
private static void ExportAsMappedItem(ExporterIFC exporterIFC, Element element, IFCFile file, IFCExportInfoPair exportType, string ifcEnumType, IFCExtrusionCreationData extraParams, PlacementSetter setter, IFCAnyHandle localPlacementToUse, IFCAnyHandle productRepresentation, ProductWrapper productWrapper) { IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; ElementId typeId = element.GetTypeId(); ElementType type = element.Document.GetElement(typeId) as ElementType; IFCAnyHandle styleHandle = null; ElementId matId = ElementId.InvalidElementId; Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions(); bool hasMaterialAssociatedToType = false; if (type != null) { FamilyTypeInfo currentTypeInfo = ExporterCacheManager.FamilySymbolToTypeInfoCache.Find(typeId, false, exportType); if (!currentTypeInfo.IsValid()) { string typeObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, type); HashSet <IFCAnyHandle> propertySetsOpt = new HashSet <IFCAnyHandle>(); IList <IFCAnyHandle> repMapListOpt = new List <IFCAnyHandle>(); styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, propertySetsOpt, repMapListOpt, element, type); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) { propertySetsOpt = ExporterUtil.ExtractElementTypeProperties(exporterIFC, type, styleHandle); productWrapper.RegisterHandleWithElementType(type, exportType, styleHandle, propertySetsOpt); currentTypeInfo.Style = styleHandle; ExporterCacheManager.FamilySymbolToTypeInfoCache.Register(typeId, false, exportType, currentTypeInfo); Element elementType = element.Document.GetElement(element.GetTypeId()); matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(element.get_Geometry(geomOptions), exporterIFC, elementType); if (matId == ElementId.InvalidElementId) { matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(element.get_Geometry(geomOptions), exporterIFC, element); } if (matId != ElementId.InvalidElementId) { currentTypeInfo.MaterialIdList = new List <ElementId>() { matId }; hasMaterialAssociatedToType = true; CategoryUtil.CreateMaterialAssociation(exporterIFC, styleHandle, matId); } } } else { styleHandle = currentTypeInfo.Style; if (currentTypeInfo.MaterialIdList != null && currentTypeInfo.MaterialIdList.Count > 0) { hasMaterialAssociatedToType = true; } } } string instanceGUID = GUIDUtil.CreateGUID(element); bool roomRelated = !FamilyExporterUtil.IsDistributionFlowElementSubType(exportType); ElementId roomId = ElementId.InvalidElementId; if (roomRelated) { roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse); } IFCAnyHandle instanceHandle = null; // For MEP objects //string exportEntityStr = exportType.ToString(); //Common.Enums.IFCEntityType exportEntity; //if (String.Compare(exportEntityStr.Substring(exportEntityStr.Length - 4), "Type", true) == 0) // exportEntityStr = exportEntityStr.Substring(0, (exportEntityStr.Length - 4)); //if (Enum.TryParse(exportEntityStr, out exportEntity)) //{ // For MEP object creation instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportType, exporterIFC, element, instanceGUID, ownerHistory, localPlacementToUse, productRepresentation); //} if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle)) { return; } if (matId == ElementId.InvalidElementId && !hasMaterialAssociatedToType) { matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(element.get_Geometry(geomOptions), exporterIFC, element); if (matId != ElementId.InvalidElementId) { CategoryUtil.CreateMaterialAssociation(exporterIFC, instanceHandle, matId); } } if (roomId != ElementId.InvalidElementId) { //exporterIFC.RelateSpatialElement(roomId, instanceHandle); ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle); productWrapper.AddElement(element, instanceHandle, setter, extraParams, false, exportType); } else { productWrapper.AddElement(element, instanceHandle, setter, extraParams, true, exportType); } OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, element, extraParams, null, exporterIFC, localPlacementToUse, setter, productWrapper); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle)) { ExporterCacheManager.TypeRelationsCache.Add(styleHandle, instanceHandle); } PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper.GetAllObjects()); ExporterCacheManager.MEPCache.Register(element, instanceHandle); // add to system export cache // SystemExporter.ExportSystem(exporterIFC, element, instanceHandle); }
/// <summary> /// Exports a MEP family instance. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="exportType">The export type of the element. /// <param name="ifcEnumType">The sub-type of the element.</param></param> /// <param name="productWrapper">The ProductWrapper.</param> /// <returns>True if an entity was created, false otherwise.</returns> public static bool Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, IFCExportInfoPair exportType, string ifcEnumType, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { // CQ_TODO: Clean up this code by at least factoring it out. // If we are exporting a duct segment, we may need to split it into parts by level. Create a list of ranges. IList <ElementId> levels = new List <ElementId>(); IList <IFCRange> ranges = new List <IFCRange>(); // We will not split duct segments if the assemblyId is set, as we would like to keep the original duct segment // associated with the assembly, on the level of the assembly. if ((exportType.ExportType == IFCEntityType.IfcDuctSegmentType) && (ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting) && (element.AssemblyInstanceId == ElementId.InvalidElementId)) { LevelUtil.CreateSplitLevelRangesForElement(exporterIFC, exportType, element, out levels, out ranges); } int numPartsToExport = ranges.Count; { ElementId catId = CategoryUtil.GetSafeCategoryId(element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow); if (0 == numPartsToExport) { // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd); using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd)) { IFCAnyHandle localPlacementToUse = setter.LocalPlacement; BodyData bodyData = null; using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData()) { extraParams.SetLocalPlacement(localPlacementToUse); IFCAnyHandle productRepresentation = RepresentationUtil.CreateAppropriateProductDefinitionShape( exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, extraParams, out bodyData); if (IFCAnyHandleUtil.IsNullOrHasNoValue(productRepresentation)) { extraParams.ClearOpenings(); return(false); } ExportAsMappedItem(exporterIFC, element, file, exportType, ifcEnumType, extraParams, setter, localPlacementToUse, productRepresentation, productWrapper); } } } else { for (int ii = 0; ii < numPartsToExport; ii++) { // Check for containment override IFCAnyHandle overrideContainerHnd = null; ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd); using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, levels[ii], overrideContainerHnd)) { IFCAnyHandle localPlacementToUse = setter.LocalPlacement; using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData()) { SolidMeshGeometryInfo solidMeshCapsule = GeometryUtil.GetClippedSolidMeshGeometry(geometryElement, ranges[ii]); IList <Solid> solids = solidMeshCapsule.GetSolids(); IList <Mesh> polyMeshes = solidMeshCapsule.GetMeshes(); IList <GeometryObject> geomObjects = FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(element.Document, exporterIFC, ref solids, ref polyMeshes); if (geomObjects.Count == 0 && (solids.Count > 0 || polyMeshes.Count > 0)) { return(false); } bool tryToExportAsExtrusion = (!exporterIFC.ExportAs2x2 || (exportType.ExportInstance == IFCEntityType.IfcColumn)); if (exportType.ExportInstance == IFCEntityType.IfcColumn) { extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ; } else { extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryXYZ; } BodyData bodyData = null; if (geomObjects.Count > 0) { bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, geomObjects, bodyExporterOptions, extraParams); } else { IList <GeometryObject> exportedGeometries = new List <GeometryObject>(); exportedGeometries.Add(geometryElement); bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, exportedGeometries, bodyExporterOptions, extraParams); } List <IFCAnyHandle> bodyReps = new List <IFCAnyHandle>(); bodyReps.Add(bodyData.RepresentationHnd); IFCAnyHandle productRepresentation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, bodyReps); if (IFCAnyHandleUtil.IsNullOrHasNoValue(productRepresentation)) { extraParams.ClearOpenings(); return(false); } ExportAsMappedItem(exporterIFC, element, file, exportType, ifcEnumType, extraParams, setter, localPlacementToUse, productRepresentation, productWrapper); } } } } } tr.Commit(); } return(true); }
/// <summary> /// Exports an element to IFC footing. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="element"> /// The element. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="ifcEnumType"> /// The string value represents the IFC type. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportFooting(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, string ifcEnumType, ProductWrapper productWrapper) { // export parts or not bool exportParts = PartExporter.CanExportParts(element); if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false)) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { ecData.SetLocalPlacement(setter.LocalPlacement); IFCAnyHandle prodRep = null; ElementId matId = ElementId.InvalidElementId; if (!exportParts) { ElementId catId = CategoryUtil.GetSafeCategoryId(element); matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element); BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, ecData, true); if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep)) { ecData.ClearOpenings(); return; } } string instanceGUID = GUIDUtil.CreateGUID(element); string instanceName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string instanceDescription = NamingUtil.GetDescriptionOverride(element, null); string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName()); string instanceTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); string footingType = GetIFCFootingType(ifcEnumType); // need to keep it for legacy support when original data follows slightly diff naming footingType = IFCValidateEntry.GetValidIFCType(element, footingType); IFCAnyHandle footing = IFCInstanceExporter.CreateFooting(file, instanceGUID, exporterIFC.GetOwnerHistoryHandle(), instanceName, instanceDescription, instanceObjectType, ecData.GetLocalPlacement(), prodRep, instanceTag, footingType); if (exportParts) { PartExporter.ExportHostPart(exporterIFC, element, footing, productWrapper, setter, setter.LocalPlacement, null); } else { if (matId != ElementId.InvalidElementId) { CategoryUtil.CreateMaterialAssociation(exporterIFC, footing, matId); } } productWrapper.AddElement(element, footing, setter, ecData, true); OpeningUtil.CreateOpeningsIfNecessary(footing, element, ecData, null, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); } } tr.Commit(); } }
/// <summary> /// Creates a SweptSolidExporter. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="element">The element.</param> /// <param name="solid">The solid.</param> /// <param name="normal">The normal of the plane that the path lies on.</param> /// <returns>The SweptSolidExporter.</returns> public static SweptSolidExporter Create(ExporterIFC exporterIFC, Element element, SimpleSweptSolidAnalyzer sweptAnalyzer, GeometryObject geomObject) { try { if (sweptAnalyzer == null) { return(null); } SweptSolidExporter sweptSolidExporter = null; IList <Revit.IFC.Export.Utility.GeometryUtil.FaceBoundaryType> faceBoundaryTypes; IList <CurveLoop> faceBoundaries = GeometryUtil.GetFaceBoundaries(sweptAnalyzer.ProfileFace, null, out faceBoundaryTypes); string profileName = null; if (element != null) { ElementType type = element.Document.GetElement(element.GetTypeId()) as ElementType; if (type != null) { profileName = type.Name; } } // Is it really an extrusion? if (sweptAnalyzer.PathCurve is Line) { Line line = sweptAnalyzer.PathCurve as Line; // invalid case if (MathUtil.VectorsAreOrthogonal(line.Direction, sweptAnalyzer.ProfileFace.FaceNormal)) { return(null); } sweptSolidExporter = new SweptSolidExporter(); sweptSolidExporter.RepresentationType = ShapeRepresentationType.SweptSolid; Plane plane = new Plane(sweptAnalyzer.ProfileFace.FaceNormal, sweptAnalyzer.ProfileFace.Origin); sweptSolidExporter.RepresentationItem = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, profileName, faceBoundaries, plane, line.Direction, UnitUtil.ScaleLength(line.Length), false); } else { sweptSolidExporter = new SweptSolidExporter(); if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { // Use tessellated geometry in IFC Reference View if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { // TODO: Create CreateSimpleSweptSolidAsTessellation routine that takes advantage of the superior tessellation of this class. BodyExporterOptions options = new BodyExporterOptions(false, ExportOptionsCache.ExportTessellationLevel.ExtraLow); sweptSolidExporter.RepresentationItem = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, element, options, geomObject); sweptSolidExporter.RepresentationType = ShapeRepresentationType.Tessellation; } else { sweptSolidExporter.RepresentationItem = CreateSimpleSweptSolid(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve); sweptSolidExporter.RepresentationType = ShapeRepresentationType.AdvancedSweptSolid; } } else { sweptSolidExporter.Facets = CreateSimpleSweptSolidAsBRep(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve); sweptSolidExporter.RepresentationType = ShapeRepresentationType.Brep; } } return(sweptSolidExporter); } catch (Exception) { return(null); } }
/// <summary> /// Get the handles of Grid Axes. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="sameDirectionAxes">The grid axes in the same direction of one level.</param> /// <param name="representations">The representation of grid axis.</param> /// <returns>The list of handles of grid axes.</returns> private static List <IFCAnyHandle> CreateIFCGridAxisAndRepresentations(ExporterIFC exporterIFC, ProductWrapper productWrapper, IList <Grid> sameDirectionAxes, IList <IFCAnyHandle> representations, GridRepresentationData gridRepresentationData) { if (sameDirectionAxes.Count == 0) { return(null); } IDictionary <ElementId, List <IFCAnyHandle> > gridAxisMap = new Dictionary <ElementId, List <IFCAnyHandle> >(); IDictionary <ElementId, List <IFCAnyHandle> > gridRepMap = new Dictionary <ElementId, List <IFCAnyHandle> >(); IFCFile ifcFile = exporterIFC.GetFile(); Grid baseGrid = sameDirectionAxes[0]; Transform lcs = Transform.Identity; List <IFCAnyHandle> ifcGridAxes = new List <IFCAnyHandle>(); foreach (Grid grid in sameDirectionAxes) { // Because the IfcGrid is a collection of Revit Grids, any one of them can override the IFC CAD Layer. // We will take the first name, and not do too much checking. if (string.IsNullOrWhiteSpace(gridRepresentationData.m_IFCCADLayer)) { ParameterUtil.GetStringValueFromElementOrSymbol(grid, "IFCCadLayer", out gridRepresentationData.m_IFCCADLayer); } // Get the handle of curve. XYZ projectionDirection = lcs.BasisZ; IFCAnyHandle axisCurve; if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { axisCurve = GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, grid.Curve, lcs, projectionDirection); } else { IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, lcs, projectionDirection, false); ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, grid.Curve, XYZ.Zero, false); IList <IFCAnyHandle> curves = info.GetCurves(); if (curves.Count != 1) { throw new Exception("IFC: expected 1 curve when export curve element."); } axisCurve = curves[0]; } bool sameSense = true; if (baseGrid.Curve is Line) { Line baseLine = baseGrid.Curve as Line; Line axisLine = grid.Curve as Line; sameSense = (axisLine.Direction.IsAlmostEqualTo(baseLine.Direction)); } IFCAnyHandle ifcGridAxis = IFCInstanceExporter.CreateGridAxis(ifcFile, grid.Name, axisCurve, sameSense); ifcGridAxes.Add(ifcGridAxis); HashSet <IFCAnyHandle> AxisCurves = new HashSet <IFCAnyHandle>(); AxisCurves.Add(axisCurve); IFCAnyHandle repItemHnd = IFCInstanceExporter.CreateGeometricCurveSet(ifcFile, AxisCurves); // get the weight and color from the GridType to create the curve style. GridType gridType = grid.Document.GetElement(grid.GetTypeId()) as GridType; IFCData curveWidth = null; if (ExporterCacheManager.ExportOptionsCache.ExportAnnotations) { int outWidth; double width = (ParameterUtil.GetIntValueFromElement(gridType, BuiltInParameter.GRID_END_SEGMENT_WEIGHT, out outWidth) != null) ? outWidth : 1; curveWidth = IFCDataUtil.CreateAsPositiveLengthMeasure(width); } if (!ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { int outColor; int color = (ParameterUtil.GetIntValueFromElement(gridType, BuiltInParameter.GRID_END_SEGMENT_COLOR, out outColor) != null) ? outColor : 0; double blueVal = 0.0; double greenVal = 0.0; double redVal = 0.0; GeometryUtil.GetRGBFromIntValue(color, out blueVal, out greenVal, out redVal); IFCAnyHandle colorHnd = IFCInstanceExporter.CreateColourRgb(ifcFile, null, redVal, greenVal, blueVal); BodyExporter.CreateCurveStyleForRepItem(exporterIFC, repItemHnd, curveWidth, colorHnd); } HashSet <IFCAnyHandle> curveSet = new HashSet <IFCAnyHandle>(); curveSet.Add(repItemHnd); gridRepresentationData.m_Grids.Add(grid); gridRepresentationData.m_curveSets.Add(curveSet); } return(ifcGridAxes); }
/// <summary> /// Creates a facetation of a simple swept solid from a list of curve loops. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="profileName">The profile name.</param> /// <param name="profileCurveLoops">The profile curve loops.</param> /// <param name="normal">The normal of the plane that the path lies on.</param> /// <param name="directrix">The path curve.</param> /// <returns>The list of facet handles.</returns> public static HashSet <IFCAnyHandle> CreateSimpleSweptSolidAsBRep(ExporterIFC exporterIFC, string profileName, IList <CurveLoop> profileCurveLoops, XYZ normal, Curve directrix) { // see definition of IfcSurfaceCurveSweptAreaSolid from // http://www.buildingsmart-tech.org/ifc/IFC2x4/rc4/html/schema/ifcgeometricmodelresource/lexical/ifcsurfacecurvesweptareasolid.htm HashSet <IFCAnyHandle> facetHnds = null; if (!CanCreateSimpleSweptSolid(profileCurveLoops, normal, directrix)) { return(facetHnds); } // An extra requirement, as we can't tessellate an unbound curve. if (!directrix.IsBound) { return(facetHnds); } double originalStartParam = directrix.GetEndParameter(0); Plane axisPlane, profilePlane; CreateAxisAndProfileCurvePlanes(directrix, originalStartParam, out axisPlane, out profilePlane); IList <CurveLoop> curveLoops = null; try { // Check that curve loops are valid. curveLoops = ExporterIFCUtils.ValidateCurveLoops(profileCurveLoops, profilePlane.Normal); } catch (Exception) { return(null); } if (curveLoops == null || curveLoops.Count == 0) { return(facetHnds); } // Tessellate the curve loops. We don't add the last point, as these should all be closed curves. IList <IList <XYZ> > tessellatedOutline = new List <IList <XYZ> >(); foreach (CurveLoop curveLoop in curveLoops) { List <XYZ> tessellatedCurve = new List <XYZ>(); foreach (Curve curve in curveLoop) { if (curve is Line) { AddScaledPointToList(exporterIFC, tessellatedCurve, curve.GetEndPoint(0)); } else { IList <XYZ> curveTessellation = CreateRoughTessellation(exporterIFC, curve); tessellatedCurve.AddRange(curveTessellation); } } if (tessellatedCurve.Count != 0) { tessellatedOutline.Add(tessellatedCurve); } } IFCFile file = exporterIFC.GetFile(); IList <IList <IList <IFCAnyHandle> > > facetVertexHandles = new List <IList <IList <IFCAnyHandle> > >(); IList <IList <IFCAnyHandle> > tessellatedOutlineHandles = new List <IList <IFCAnyHandle> >(); foreach (IList <XYZ> tessellatedOutlinePolygon in tessellatedOutline) { IList <IFCAnyHandle> tessellatedOutlinePolygonHandles = new List <IFCAnyHandle>(); foreach (XYZ tessellatedOutlineXYZ in tessellatedOutlinePolygon) { tessellatedOutlinePolygonHandles.Add(ExporterUtil.CreateCartesianPoint(file, tessellatedOutlineXYZ)); } tessellatedOutlineHandles.Add(tessellatedOutlinePolygonHandles); } facetVertexHandles.Add(tessellatedOutlineHandles); // Tessellate the Directrix. This only works for bound Directrix curves. Unfortunately, we get XYZ values, which we will have to convert // back to parameter values to get the local transform. IList <double> tessellatedDirectrixParameters = CreateRoughParametricTessellation(directrix); // Create all of the other outlines by transformng the first tessellated outline to the current transform. Transform profilePlaneTrf = Transform.CreateTranslation(ExporterIFCUtils.TransformAndScalePoint(exporterIFC, profilePlane.Origin)); profilePlaneTrf.BasisX = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, profilePlane.XVec); profilePlaneTrf.BasisY = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, profilePlane.YVec); profilePlaneTrf.BasisZ = ExporterIFCUtils.TransformAndScaleVector(exporterIFC, profilePlane.Normal); // The inverse transform will be applied to generate the delta transform for the profile curves from the start of the directrix // to the current location. This could be optimized in the case of a Line, but current usage is really only for a single arc. // If that changes, we should revisit optimization possibilities. Transform profilePlaneTrfInverse = profilePlaneTrf.Inverse; // Create the delta transforms and the offset tessellated profiles. foreach (double parameter in tessellatedDirectrixParameters) { Transform directrixDirs = CreateProfileCurveTransform(exporterIFC, directrix, parameter); Transform deltaTransform = directrixDirs.Multiply(profilePlaneTrfInverse); IList <IList <IFCAnyHandle> > currTessellatedOutline = new List <IList <IFCAnyHandle> >(); foreach (IList <XYZ> pointLoop in tessellatedOutline) { IList <IFCAnyHandle> currTessellatedPoinLoop = new List <IFCAnyHandle>(); foreach (XYZ point in pointLoop) { XYZ transformedPoint = deltaTransform.OfPoint(point); IFCAnyHandle transformedPointHandle = ExporterUtil.CreateCartesianPoint(file, transformedPoint); currTessellatedPoinLoop.Add(transformedPointHandle); } currTessellatedOutline.Add(currTessellatedPoinLoop); } facetVertexHandles.Add(currTessellatedOutline); } // Create the side facets. facetHnds = new HashSet <IFCAnyHandle>(); int numFacets = facetVertexHandles.Count - 1; for (int ii = 0; ii < numFacets; ii++) { IList <IList <IFCAnyHandle> > firstOutline = facetVertexHandles[ii]; IList <IList <IFCAnyHandle> > secondOutline = facetVertexHandles[ii + 1]; int numLoops = firstOutline.Count; for (int jj = 0; jj < numLoops; jj++) { IList <IFCAnyHandle> firstLoop = firstOutline[jj]; IList <IFCAnyHandle> secondLoop = secondOutline[jj]; int numVertices = firstLoop.Count; for (int kk = 0; kk < numVertices; kk++) { IList <IFCAnyHandle> polyLoopHandles = new List <IFCAnyHandle>(4); polyLoopHandles.Add(secondLoop[kk]); polyLoopHandles.Add(secondLoop[(kk + 1) % numVertices]); polyLoopHandles.Add(firstLoop[(kk + 1) % numVertices]); polyLoopHandles.Add(firstLoop[kk]); IFCAnyHandle face = BodyExporter.CreateFaceFromVertexList(file, polyLoopHandles); facetHnds.Add(face); } } } // Create the end facets. for (int ii = 0; ii < 2; ii++) { int faceIndex = (ii == 0) ? 0 : facetVertexHandles.Count - 1; int numLoops = facetVertexHandles[faceIndex].Count; HashSet <IFCAnyHandle> faceBounds = new HashSet <IFCAnyHandle>(); for (int jj = 0; jj < numLoops; jj++) { IList <IFCAnyHandle> polyLoopHandles = null; if (ii == 0) { polyLoopHandles = facetVertexHandles[faceIndex][jj]; } else { int numHandles = facetVertexHandles[faceIndex][jj].Count; polyLoopHandles = new List <IFCAnyHandle>(numHandles); for (int kk = numHandles - 1; kk >= 0; kk--) { polyLoopHandles.Add(facetVertexHandles[faceIndex][jj][kk]); } } IFCAnyHandle polyLoop = IFCInstanceExporter.CreatePolyLoop(file, polyLoopHandles); IFCAnyHandle faceBound = (jj == 0) ? IFCInstanceExporter.CreateFaceOuterBound(file, polyLoop, true) : IFCInstanceExporter.CreateFaceBound(file, polyLoop, true); faceBounds.Add(faceBound); } IFCAnyHandle face = IFCInstanceExporter.CreateFace(file, faceBounds); facetHnds.Add(face); } return(facetHnds); }
/// <summary> /// Creates an opening from a solid. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="hostObjHnd">The host object handle.</param> /// <param name="hostElement">The host element.</param> /// <param name="insertElement">The insert element.</param> /// <param name="openingGUID">The GUID for the opening, depending on how the opening is created.</param> /// <param name="solid">The solid.</param> /// <param name="scaledHostWidth">The scaled host width.</param> /// <param name="isRecess">True if it is recess.</param> /// <param name="extrusionCreationData">The extrusion creation data.</param> /// <param name="setter">The placement setter.</param> /// <param name="localWrapper">The product wrapper.</param> /// <returns>The created opening handle.</returns> static public IFCAnyHandle CreateOpening(ExporterIFC exporterIFC, IFCAnyHandle hostObjHnd, Element hostElement, Element insertElement, string openingGUID, Solid solid, double scaledHostWidth, bool isRecess, IFCExtrusionCreationData extrusionCreationData, PlacementSetter setter, ProductWrapper localWrapper) { IFCFile file = exporterIFC.GetFile(); ElementId catId = CategoryUtil.GetSafeCategoryId(insertElement); XYZ prepToWall; bool isLinearWall = GetOpeningDirection(hostElement, out prepToWall); if (isLinearWall) { extrusionCreationData.CustomAxis = prepToWall; extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom; } BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); BodyData bodyData = BodyExporter.ExportBody(exporterIFC, insertElement, catId, ElementId.InvalidElementId, solid, bodyExporterOptions, extrusionCreationData); IFCAnyHandle openingRepHnd = bodyData.RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(openingRepHnd)) { extrusionCreationData.ClearOpenings(); return(null); } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(openingRepHnd); IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); IFCAnyHandle openingPlacement = extrusionCreationData.GetLocalPlacement(); IFCAnyHandle hostObjPlacementHnd = IFCAnyHandleUtil.GetObjectPlacement(hostObjHnd); Transform relTransform = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(openingPlacement, hostObjPlacementHnd); openingPlacement = ExporterUtil.CreateLocalPlacement(file, hostObjPlacementHnd, relTransform.Origin, relTransform.BasisZ, relTransform.BasisX); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); double scaledOpeningLength = extrusionCreationData.ScaledLength; string openingObjectType = "Opening"; if (!MathUtil.IsAlmostZero(scaledHostWidth) && !MathUtil.IsAlmostZero(scaledOpeningLength)) { openingObjectType = scaledOpeningLength < (scaledHostWidth - MathUtil.Eps()) ? "Recess" : "Opening"; } else { openingObjectType = isRecess ? "Recess" : "Opening"; } string openingName = NamingUtil.GetNameOverride(insertElement, null); if (string.IsNullOrEmpty(openingName)) { if (!IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjHnd)) { openingName = IFCAnyHandleUtil.GetStringAttribute(hostObjHnd, "Name"); } else { openingName = NamingUtil.GetNameOverride(hostElement, NamingUtil.CreateIFCObjectName(exporterIFC, hostElement)); } } IFCAnyHandle openingHnd = IFCInstanceExporter.CreateOpeningElement(file, openingGUID, ownerHistory, openingName, null, openingObjectType, openingPlacement, prodRep, null); if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities) { PropertyUtil.CreateOpeningQuantities(exporterIFC, openingHnd, extrusionCreationData); } if (localWrapper != null) { Element elementForProperties = null; if (GUIDUtil.IsGUIDFor(insertElement, openingGUID)) { elementForProperties = insertElement; } localWrapper.AddElement(insertElement, openingHnd, setter, extrusionCreationData, true); } string voidGuid = GUIDUtil.CreateGUID(); IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, hostObjHnd, openingHnd); return(openingHnd); }
/// <summary> /// Exports an element as IFC railing. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="element"> /// The element to be exported. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportRailing(ExporterIFC exporterIFC, Element element, GeometryElement geomElem, string ifcEnumType, ProductWrapper productWrapper) { // Check the intended IFC entity or type name is in the exclude list specified in the UI Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcRailing; if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } ElementType elemType = element.Document.GetElement(element.GetTypeId()) as ElementType; IFCFile file = exporterIFC.GetFile(); Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions(); using (IFCTransaction transaction = new IFCTransaction(file)) { using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element)) { using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData()) { IFCAnyHandle localPlacement = setter.LocalPlacement; StairRampContainerInfo stairRampInfo = null; ElementId hostId = GetStairOrRampHostId(exporterIFC, element as Railing); Transform inverseTrf = Transform.Identity; if (hostId != ElementId.InvalidElementId) { stairRampInfo = ExporterCacheManager.StairRampContainerInfoCache.GetStairRampContainerInfo(hostId); IFCAnyHandle stairRampLocalPlacement = stairRampInfo.LocalPlacements[0]; Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(stairRampLocalPlacement, localPlacement); inverseTrf = relTrf.Inverse; IFCAnyHandle railingLocalPlacement = ExporterUtil.CreateLocalPlacement(file, stairRampLocalPlacement, inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX); localPlacement = railingLocalPlacement; } ecData.SetLocalPlacement(localPlacement); SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geomElem); IList <Solid> solids = solidMeshInfo.GetSolids(); IList <Mesh> meshes = solidMeshInfo.GetMeshes(); Railing railingElem = element as Railing; IList <ElementId> subElementIds = CollectSubElements(railingElem); foreach (ElementId subElementId in subElementIds) { Element subElement = railingElem.Document.GetElement(subElementId); if (subElement != null) { GeometryElement subElementGeom = GeometryUtil.GetOneLevelGeometryElement(subElement.get_Geometry(geomOptions), 0); SolidMeshGeometryInfo subElementSolidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(subElementGeom); IList <Solid> subElementSolids = subElementSolidMeshInfo.GetSolids(); IList <Mesh> subElementMeshes = subElementSolidMeshInfo.GetMeshes(); foreach (Solid subElementSolid in subElementSolids) { solids.Add(subElementSolid); } foreach (Mesh subElementMesh in subElementMeshes) { meshes.Add(subElementMesh); } } } ElementId catId = CategoryUtil.GetSafeCategoryId(element); BodyData bodyData = null; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium); //bodyExporterOptions.UseGroupsIfPossible = true; //bodyExporterOptions.UseMappedGeometriesIfPossible = true; if (solids.Count > 0 || meshes.Count > 0) { bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, solids, meshes, bodyExporterOptions, ecData); } else { IList <GeometryObject> geomlist = new List <GeometryObject>(); geomlist.Add(geomElem); bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, geomlist, bodyExporterOptions, ecData); } IFCAnyHandle bodyRep = bodyData.RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { if (ecData != null) { ecData.ClearOpenings(); } return; } IList <IFCAnyHandle> representations = new List <IFCAnyHandle>(); representations.Add(bodyRep); IList <GeometryObject> geomObjects = new List <GeometryObject>(); foreach (Solid solid in solids) { geomObjects.Add(solid); } foreach (Mesh mesh in meshes) { geomObjects.Add(mesh); } Transform boundingBoxTrf = (bodyData.OffsetTransform != null) ? bodyData.OffsetTransform.Inverse : Transform.Identity; boundingBoxTrf = inverseTrf.Multiply(boundingBoxTrf); IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geomObjects, boundingBoxTrf); if (boundingBoxRep != null) { representations.Add(boundingBoxRep); } IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; string instanceGUID = GUIDUtil.CreateGUID(element); //string railingType = IFCValidateEntry.GetValidIFCPredefinedType(element, ifcEnumType); IFCAnyHandle railing = IFCInstanceExporter.CreateRailing(exporterIFC, element, instanceGUID, ownerHistory, ecData.GetLocalPlacement(), prodRep, ifcEnumType); bool associateToLevel = (hostId == ElementId.InvalidElementId); productWrapper.AddElement(element, railing, setter, ecData, associateToLevel); OpeningUtil.CreateOpeningsIfNecessary(railing, element, ecData, bodyData.OffsetTransform, exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper); CategoryUtil.CreateMaterialAssociation(exporterIFC, railing, bodyData.MaterialIds); // Create multi-story duplicates of this railing. if (stairRampInfo != null) { stairRampInfo.AddComponent(0, railing); List <IFCAnyHandle> stairHandles = stairRampInfo.StairOrRampHandles; for (int ii = 1; ii < stairHandles.Count; ii++) { IFCAnyHandle railingLocalPlacement = stairRampInfo.LocalPlacements[ii]; if (!IFCAnyHandleUtil.IsNullOrHasNoValue(railingLocalPlacement)) { IFCAnyHandle railingHndCopy = CopyRailingHandle(exporterIFC, element, catId, railingLocalPlacement, railing); stairRampInfo.AddComponent(ii, railingHndCopy); productWrapper.AddElement(element, railingHndCopy, (IFCLevelInfo)null, ecData, false); CategoryUtil.CreateMaterialAssociation(exporterIFC, railingHndCopy, bodyData.MaterialIds); } } ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(hostId, stairRampInfo); } } transaction.Commit(); } } }