public static int GetNextCounter(IFCEntityType type) { int nextValue; if (!m_DoorWindowPanelCounters.TryGetValue(type, out nextValue)) nextValue = 0; m_DoorWindowPanelCounters[type] = ++nextValue; return nextValue; }
private static bool HasPredefinedType(IFCEntityType type) { // These entities have no predefined type field. if (m_sNoPredefinedType == null) { m_sNoPredefinedType = new HashSet<IFCEntityType>(); m_sNoPredefinedType.Add(IFCEntityType.IfcProject); m_sNoPredefinedType.Add(IFCEntityType.IfcSite); m_sNoPredefinedType.Add(IFCEntityType.IfcBuilding); m_sNoPredefinedType.Add(IFCEntityType.IfcBuildingStorey); m_sNoPredefinedType.Add(IFCEntityType.IfcGroup); m_sNoPredefinedType.Add(IFCEntityType.IfcSystem); } if (m_sNoPredefinedType.Contains(type)) return false; if (IFCImportFile.TheFile.SchemaVersion < IFCSchemaVersion.IFC4) { // Before IFC4, these are the only objects that have a predefined type that we support. // Note that this is just a list of entity types that are dealt with generically; other types may override the base function. if (m_sPredefinedTypePreIFC4 == null) { m_sPredefinedTypePreIFC4 = new HashSet<IFCEntityType>(); m_sPredefinedTypePreIFC4.Add(IFCEntityType.IfcCovering); m_sPredefinedTypePreIFC4.Add(IFCEntityType.IfcDistributionPort); m_sPredefinedTypePreIFC4.Add(IFCEntityType.IfcFooting); m_sPredefinedTypePreIFC4.Add(IFCEntityType.IfcPile); m_sPredefinedTypePreIFC4.Add(IFCEntityType.IfcRailing); m_sPredefinedTypePreIFC4.Add(IFCEntityType.IfcRamp); m_sPredefinedTypePreIFC4.Add(IFCEntityType.IfcRoof); m_sPredefinedTypePreIFC4.Add(IFCEntityType.IfcSlab); m_sPredefinedTypePreIFC4.Add(IFCEntityType.IfcStair); m_sPredefinedTypePreIFC4.Add(IFCEntityType.IfcTendon); } if (!m_sPredefinedTypePreIFC4.Contains(type)) return false; } return true; }
/// <summary> /// Removes invalid handles from the cache. /// </summary> /// <param name="elementIds">The element ids.</param> /// <param name="expectedType">The expected type of the handles.</param> public void RemoveInvalidHandles(ISet<ElementId> elementIds, IFCEntityType expectedType) { foreach (ElementId elementId in elementIds) { IFCAnyHandle handle; if (m_ElementIdToHandleDictionary.TryGetValue(elementId, out handle)) { try { bool isType = IFCAnyHandleUtil.IsSubTypeOf(handle, expectedType); if (!isType) m_ElementIdToHandleDictionary.Remove(elementId); } catch { m_ElementIdToHandleDictionary.Remove(elementId); } } } }
private static bool HasPredefinedType(IFCEntityType type) { if (IFCImportFile.TheFile.SchemaVersion < IFCSchemaVersion.IFC4) { // Before IFC4, these are the only objects that have a predefined type that we support. // Note that this is just a list of entity types that are dealt with generically; other types may override the base function. if (m_sNoPredefinedTypePreIFC4 == null) { m_sNoPredefinedTypePreIFC4 = new HashSet<IFCEntityType>(); m_sNoPredefinedTypePreIFC4.Add(IFCEntityType.IfcDiscreteAccessoryType); m_sNoPredefinedTypePreIFC4.Add(IFCEntityType.IfcDoorStyle); m_sNoPredefinedTypePreIFC4.Add(IFCEntityType.IfcFastenerType); m_sNoPredefinedTypePreIFC4.Add(IFCEntityType.IfcFurnishingElementType); m_sNoPredefinedTypePreIFC4.Add(IFCEntityType.IfcFurnitureType); m_sNoPredefinedTypePreIFC4.Add(IFCEntityType.IfcWindowStyle); } if (m_sNoPredefinedTypePreIFC4.Contains(type)) return false; } return true; }
/// <summary> /// Gets instances of an entity type from an IFC file. /// </summary> /// <param name="type">The type.</param> /// <param name="includeSubTypes">True to retrieve instances of sub types.</param> /// <returns>The instance handles.</returns> public IList<IFCAnyHandle> GetInstances(IFCEntityType type, bool includeSubTypes) { return m_IfcFile.GetInstances(IFCAnyHandleUtil.GetIFCEntityTypeName(type), includeSubTypes); }
private static void AddToCaches(int stepId, IFCEntityType entityType, XYZ xyz) { if (xyz != null) IFCImportFile.TheFile.XYZMap[stepId] = xyz; Importer.TheLog.AddProcessedEntity(entityType); }
/// <summary> /// This is a generic create method for all IFC Type Objects, mainly for MEP objects /// </summary> /// <param name="typeEntityToCreate">Type entity to create</param> /// <param name="file">The IFC file</param> /// <param name="guid">GUID</param> /// <param name="ownerHistory">Owner History</param> /// <param name="name">name attribute</param> /// <param name="description">Description</param> /// <param name="applicableOccurrence">Applicable Occurence attribute</param> /// <param name="propertySets">Preperty Sets</param> /// <param name="representationMaps">RepresentationMap for geometry</param> /// <param name="elementTag">Element Tag</param> /// <param name="elementType">Element Type</param> /// <param name="predefinedType">preDefinedType</param> /// <returns></returns> public static IFCAnyHandle CreateGenericIFCType(IFCEntityType typeEntityToCreate, IFCFile file, string guid, IFCAnyHandle ownerHistory, string name, string description, string applicableOccurrence, HashSet<IFCAnyHandle> propertySets, IList<IFCAnyHandle> representationMaps, string elementTag, string elementType, string predefinedType) { ValidateElementType(guid, ownerHistory, name, description, applicableOccurrence, propertySets, representationMaps, elementTag, elementType); if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { Revit.IFC.Common.Enums.IFC4.IFCEntityType IFC4ValidTypeEnum; // check existence of the entity in IFC4 if (Enum.TryParse(typeEntityToCreate.ToString(), true, out IFC4ValidTypeEnum)) { IFCAnyHandle genericIFCType = CreateInstance(file, typeEntityToCreate); IFCAnyHandleUtil.SetAttribute(genericIFCType, "PredefinedType", predefinedType, true); SetElementType(genericIFCType, guid, ownerHistory, name, description, applicableOccurrence, propertySets, representationMaps, elementTag, elementType); return genericIFCType; } } else { Revit.IFC.Common.Enums.IFC2x.IFCEntityType IFC2xValidTypeEnum; // check existence of the entity in IFC2x- if (Enum.TryParse(typeEntityToCreate.ToString(), true, out IFC2xValidTypeEnum)) { // Special IFC2x2 checks to avoid creating a completely new enum. if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2) { // Not supported: IfcBuildingElementProxyType in IFC2x2. if (typeEntityToCreate == IFCEntityType.IfcBuildingElementProxyType) return null; } IFCAnyHandle genericMEPType = CreateInstance(file, typeEntityToCreate); IFCAnyHandleUtil.SetAttribute(genericMEPType, "PredefinedType", predefinedType, true); SetElementType(genericMEPType, guid, ownerHistory, name, description, applicableOccurrence, propertySets, representationMaps, elementTag, elementType); return genericMEPType; } } return null; //type is unknown in both IFC4 and prior to IFC4 }
/// <summary> /// Processes IfcRepresentation attributes. /// </summary> /// <param name="ifcRepresentation">The IfcRepresentation handle.</param> override protected void Process(IFCAnyHandle ifcRepresentation) { base.Process(ifcRepresentation); IFCAnyHandle representationContext = IFCImportHandleUtil.GetRequiredInstanceAttribute(ifcRepresentation, "ContextOfItems", false); if (representationContext != null) { Context = IFCRepresentationContext.ProcessIFCRepresentationContext(representationContext); } string identifier = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentation, "RepresentationIdentifier", null); Identifier = GetRepresentationIdentifier(identifier, ifcRepresentation); Type = IFCImportHandleUtil.GetOptionalStringAttribute(ifcRepresentation, "RepresentationType", null); HashSet <IFCAnyHandle> items = IFCAnyHandleUtil.GetAggregateInstanceAttribute <HashSet <IFCAnyHandle> >(ifcRepresentation, "Items"); LayerAssignment = IFCPresentationLayerAssignment.GetTheLayerAssignment(ifcRepresentation, true); foreach (IFCAnyHandle item in items) { IFCRepresentationItem repItem = null; try { if (NotAllowedInRepresentation(item)) { IFCEntityType entityType = IFCAnyHandleUtil.GetEntityType(item); Importer.TheLog.LogWarning(item.StepId, "Ignoring unhandled representation item of type " + entityType.ToString() + " in " + Identifier.ToString() + " representation.", true); continue; } // Special processing for bounding boxes - only IfcBoundingBox allowed. if (IFCAnyHandleUtil.IsSubTypeOf(item, IFCEntityType.IfcBoundingBox)) { // Don't read in Box represenation unless options allow it. if (IFCImportFile.TheFile.Options.ProcessBoundingBoxGeometry == IFCProcessBBoxOptions.Never) { Importer.TheLog.LogWarning(item.StepId, "BoundingBox not imported with ProcessBoundingBoxGeometry=Never", false); } else { if (BoundingBox != null) { Importer.TheLog.LogWarning(item.StepId, "Found second IfcBoundingBox representation item, ignoring.", false); continue; } BoundingBox = ProcessBoundingBox(item); } } else { repItem = IFCRepresentationItem.ProcessIFCRepresentationItem(item); } } catch (Exception ex) { Importer.TheLog.LogError(item.StepId, ex.Message, false); } if (repItem != null) { RepresentationItems.Add(repItem); } } }
/// <summary> /// Get valid IFC entity type by using the official IFC schema (using the XML schema). It checks the non-abstract valid entity. /// If it is found to be abstract, it will try to find its supertype until it finds a non-abstract type. /// </summary> /// <param name="entityType">the IFC Entity type enum</param> /// <returns>return the appropriate entity type or Unknown</returns> public static IFCEntityType GetValidIFCEntityType(IFCEntityType entityType) { return(GetValidIFCEntityType(entityType.ToString())); }
/// <summary> /// Gets instances of an entity type from an IFC file. /// </summary> /// <param name="type">The type.</param> /// <param name="includeSubTypes">True to retrieve instances of sub types.</param> /// <returns>The instance handles.</returns> public IList <IFCAnyHandle> GetInstances(IFCEntityType type, bool includeSubTypes) { return(m_IfcFile.GetInstances(IFCAnyHandleUtil.GetIFCEntityTypeName(type), includeSubTypes)); }
/// <summary> /// Set the pair information using only either the entity or the type /// </summary> /// <param name="entityType">the entity or type</param> /// <param name="predefineType">predefinedtype string</param> public void SetValueWithPair(IFCEntityType entityType, string predefineType = null) { SetValueWithPair(entityType.ToString(), predefineType); }
/// <summary> /// Add an error message to the log file indicating an unhandled subtype of a known type. /// </summary> /// <param name="handle">The unhandled entity handle.</param> /// <param name="mainType">The base type of the handle.</param> /// <param name="throwError">throw an InvalidOperationException if true.</param> public void LogUnhandledSubTypeError(IFCAnyHandle handle, IFCEntityType mainType, bool throwError) { LogUnhandledSubTypeErrorBase(handle, mainType.ToString(), throwError); }
/// <summary> /// Add an error message to the log file indicating an incorrect type. /// </summary> /// <param name="handle">The unhandled entity handle.</param> /// <param name="expectedType">The expected base type of the handle.</param> /// <param name="throwError">throw an InvalidOperationException if true.</param> public void LogUnexpectedTypeError(IFCAnyHandle handle, IFCEntityType expectedType, bool throwError) { LogError(handle.StepId, "Expected handle of type " + expectedType.ToString() + ", found: " + IFCAnyHandleUtil.GetEntityType(handle).ToString(), throwError); }
/// <summary> /// Add an error message to the log file indicating a missing handle of an expected type. /// </summary> /// <param name="expectedType">The expected type of the handle.</param> public void LogNullError(IFCEntityType expectedType) { WriteLine("ERROR: " + expectedType.ToString() + " is null or has no value."); }
/// <summary> /// Exports a curve element to IFC curve annotation. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="curveElement"> /// The curve element to be exported. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="productWrapper"> /// The ProductWrapper. /// </param> public static void ExportCurveElement(ExporterIFC exporterIFC, CurveElement curveElement, GeometryElement geometryElement, ProductWrapper productWrapper) { if (geometryElement == null || !ShouldCurveElementBeExported(curveElement)) { return; } SketchPlane sketchPlane = curveElement.SketchPlane; if (sketchPlane == null) { return; } // Check the intended IFC entity or type name is in the exclude list specified in the UI IFCEntityType elementClassTypeEnum = IFCEntityType.IfcAnnotation; if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum)) { return; } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction transaction = new IFCTransaction(file)) { // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, curveElement, out overrideContainerHnd); using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, curveElement, null, null, overrideContainerId, overrideContainerHnd)) { IFCAnyHandle localPlacement = setter.LocalPlacement; IFCAnyHandle axisPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement); Plane planeSK = sketchPlane.GetPlane(); XYZ projDir = planeSK.Normal; XYZ origin = planeSK.Origin; bool useOffsetTrf = false; if (projDir.IsAlmostEqualTo(XYZ.BasisZ)) { XYZ offset = XYZ.BasisZ * setter.Offset; origin -= offset; } else { useOffsetTrf = true; } Transform curveLCS = GeometryUtil.CreateTransformFromPlane(planeSK); curveLCS.Origin = origin; IList <IFCAnyHandle> curves = null; if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView) { Transform trf = null; if (useOffsetTrf) { XYZ offsetOrig = -XYZ.BasisZ * setter.Offset; trf = Transform.CreateTranslation(offsetOrig); } curves = new List <IFCAnyHandle>(); //Curve curve = (geometryElement as GeometryObject) as Curve; List <Curve> curvesFromGeomElem = GeometryUtil.GetCurvesFromGeometryElement(geometryElement); foreach (Curve curve in curvesFromGeomElem) { IFCAnyHandle curveHnd = GeometryUtil.CreatePolyCurveFromCurve(exporterIFC, curve, trf); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveHnd)) { curves.Add(curveHnd); } } } else { IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, curveLCS, projDir, false); if (useOffsetTrf) { XYZ offsetOrig = -XYZ.BasisZ * setter.Offset; Transform trf = Transform.CreateTranslation(offsetOrig); ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false, trf); } else { ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geometryElement, XYZ.Zero, false); } curves = info.GetCurves(); } if (curves.Count != 1) { throw new Exception("IFC: expected 1 curve when export curve element."); } HashSet <IFCAnyHandle> curveSet = new HashSet <IFCAnyHandle>(curves); IFCAnyHandle repItemHnd = IFCInstanceExporter.CreateGeometricCurveSet(file, curveSet); IFCAnyHandle curveStyle = file.CreateStyle(exporterIFC, repItemHnd); CurveAnnotationCache annotationCache = ExporterCacheManager.CurveAnnotationCache; IFCAnyHandle curveAnno = annotationCache.GetAnnotation(sketchPlane.Id, curveStyle); if (!IFCAnyHandleUtil.IsNullOrHasNoValue(curveAnno)) { AddCurvesToAnnotation(curveAnno, curves); } else { curveAnno = CreateCurveAnnotation(exporterIFC, curveElement, curveElement.Category.Id, sketchPlane.Id, curveLCS, curveStyle, setter, localPlacement, repItemHnd); productWrapper.AddAnnotation(curveAnno, setter.LevelInfo, true); annotationCache.AddAnnotation(sketchPlane.Id, curveStyle, curveAnno); } } transaction.Commit(); } }
/// <summary> /// Exports a roof or floor as a container of multiple roof slabs. Returns the handle, if successful. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="element">The roof or floor element.</param> /// <param name="geometry">The geometry of the element.</param> /// <param name="productWrapper">The product wrapper.</param> /// <returns>The roof handle.</returns> /// <remarks>For floors, if there is only one component, return null, as we do not want to create a container.</remarks> public static IFCAnyHandle ExportRoofOrFloorAsContainer(ExporterIFC exporterIFC, Element element, GeometryElement geometry, ProductWrapper productWrapper) { IFCFile file = exporterIFC.GetFile(); // We support ExtrusionRoofs, FootPrintRoofs, and Floors only. bool elementIsRoof = (element is ExtrusionRoof) || (element is FootPrintRoof); bool elementIsFloor = (element is Floor); if (!elementIsRoof && !elementIsFloor) { return(null); } string subSlabType = null; IFCExportInfoPair roofExportType = ExporterUtil.GetProductExportType(exporterIFC, element, out _); if (roofExportType.IsUnKnown) { IFCEntityType elementClassTypeEnum = elementIsFloor ? IFCEntityType.IfcSlab: IFCEntityType.IfcRoof; roofExportType = new IFCExportInfoPair(elementClassTypeEnum, ""); } else { if (elementIsFloor) { subSlabType = "FLOOR"; } else if (elementIsRoof) { subSlabType = "ROOF"; } } // Check the intended IFC entity or type name is in the exclude list specified in the UI if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(roofExportType.ExportType)) { return(null); } Document doc = element.Document; using (SubTransaction tempPartTransaction = new SubTransaction(doc)) { using (IFCTransaction transaction = new IFCTransaction(file)) { MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, element, productWrapper); bool hasLayers = false; if (layersetInfo.MaterialIds.Count > 1) { hasLayers = true; } bool exportByComponents = ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && hasLayers; // Check for containment override IFCAnyHandle overrideContainerHnd = null; ElementId overrideContainerId = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd); // We want to delay creating entity handles until as late as possible, so that if we abort the IFC transaction, // we don't have to delete elements. This is both for performance reasons and to potentially extend the number // of projects that can be exported by reducing (a small amount) of waste. IList <HostObjectSubcomponentInfo> hostObjectSubcomponents = null; try { hostObjectSubcomponents = ExporterIFCUtils.ComputeSubcomponents(element as HostObject); } catch { return(null); } if (hostObjectSubcomponents == null) { return(null); } int numSubcomponents = hostObjectSubcomponents.Count; if (numSubcomponents == 0 || (elementIsFloor && numSubcomponents == 1)) { return(null); } using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd)) { IFCAnyHandle localPlacement = setter.LocalPlacement; IFCAnyHandle hostObjectHandle = null; try { using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData()) { IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle; extrusionCreationData.SetLocalPlacement(localPlacement); extrusionCreationData.ReuseLocalPlacement = true; using (TransformSetter trfSetter = TransformSetter.Create()) { IList <GeometryObject> geometryList = new List <GeometryObject>(); geometryList.Add(geometry); trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, extrusionCreationData); IFCAnyHandle prodRepHnd = null; string elementGUID = GUIDUtil.CreateGUID(element); hostObjectHandle = IFCInstanceExporter.CreateGenericIFCEntity( roofExportType, exporterIFC, element, elementGUID, ownerHistory, localPlacement, prodRepHnd); if (IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjectHandle)) { return(null); } IList <IFCAnyHandle> elementHandles = new List <IFCAnyHandle>(); elementHandles.Add(hostObjectHandle); // If element is floor, then the profile curve loop of hostObjectSubComponent is computed from the top face of the floor // else if element is roof, then the profile curve loop is taken from the bottom face of the roof instead XYZ extrusionDir = elementIsFloor ? new XYZ(0, 0, -1) : new XYZ(0, 0, 1); ElementId catId = CategoryUtil.GetSafeCategoryId(element); IList <IFCAnyHandle> slabHandles = new List <IFCAnyHandle>(); IList <CurveLoop> hostObjectOpeningLoops = new List <CurveLoop>(); double maximumScaledDepth = 0.0; using (IFCExtrusionCreationData slabExtrusionCreationData = new IFCExtrusionCreationData()) { slabExtrusionCreationData.SetLocalPlacement(extrusionCreationData.GetLocalPlacement()); slabExtrusionCreationData.ReuseLocalPlacement = false; slabExtrusionCreationData.ForceOffset = true; int loopNum = 0; int subElementStart = elementIsRoof ? (int)IFCRoofSubElements.RoofSlabStart : (int)IFCSlabSubElements.SubSlabStart; foreach (HostObjectSubcomponentInfo hostObjectSubcomponent in hostObjectSubcomponents) { trfSetter.InitializeFromBoundingBox(exporterIFC, geometryList, slabExtrusionCreationData); Plane plane = hostObjectSubcomponent.GetPlane(); Transform lcs = GeometryUtil.CreateTransformFromPlane(plane); IList <CurveLoop> curveLoops = new List <CurveLoop>(); CurveLoop slabCurveLoop = hostObjectSubcomponent.GetCurveLoop(); curveLoops.Add(slabCurveLoop); double slope = Math.Abs(plane.Normal.Z); double scaledDepth = UnitUtil.ScaleLength(hostObjectSubcomponent.Depth); double scaledExtrusionDepth = scaledDepth * slope; IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>(); IFCAnyHandle prodDefShape = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps); IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body"); string representationType = ShapeRepresentationType.SweptSolid.ToString(); // Create representation items based on the layers // Because in this case, the Roof components are not derived from Parts, but by "splitting" geometry part that can be extruded, // the creation of the Items for IFC4RV will be different by using "manual" split based on the layer thickness HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>(); if (!exportByComponents) { IFCAnyHandle itemShapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, scaledExtrusionDepth, false); if (IFCAnyHandleUtil.IsNullOrHasNoValue(itemShapeRep)) { productWrapper.ClearInternalHandleWrapperData(element); return(null); } ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(element as HostObject); BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, false, itemShapeRep, matId); bodyItems.Add(itemShapeRep); } else { List <MaterialLayerSetInfo.MaterialInfo> MaterialIds = layersetInfo.MaterialIds; ElementId typeElemId = element.GetTypeId(); // From CollectMaterialLayerSet() Roofs with no components are only allowed one material. It arbitrarily chooses the thickest material. // To be consistant with Roof(as Slab), we will reverse the order. IFCAnyHandle materialLayerSet = ExporterCacheManager.MaterialSetCache.FindLayerSet(typeElemId); bool materialHandleIsNotValid = IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet); if (IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet) || materialHandleIsNotValid) { MaterialIds.Reverse(); } double scaleProj = extrusionDir.DotProduct(plane.Normal); foreach (MaterialLayerSetInfo.MaterialInfo matLayerInfo in MaterialIds) { double itemExtrDepth = matLayerInfo.m_matWidth; double scaledItemExtrDepth = UnitUtil.ScaleLength(itemExtrDepth) * slope; IFCAnyHandle itemShapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, lcs, extrusionDir, scaledItemExtrDepth, false); if (IFCAnyHandleUtil.IsNullOrHasNoValue(itemShapeRep)) { productWrapper.ClearInternalHandleWrapperData(element); return(null); } BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, element.Document, false, itemShapeRep, matLayerInfo.m_baseMatId); bodyItems.Add(itemShapeRep); RepresentationUtil.CreateRepForShapeAspect(exporterIFC, element, prodDefShape, representationType, matLayerInfo.m_layerName, itemShapeRep); XYZ offset = new XYZ(0, 0, itemExtrDepth / scaleProj); // offset is calculated as extent in the direction of extrusion lcs.Origin += offset; } } IFCAnyHandle shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, contextOfItems, bodyItems, null); shapeReps.Add(shapeRep); IFCAnyHandleUtil.SetAttribute(prodDefShape, "Representations", shapeReps); // We could replace the code below to just use the newer, and better, // GenerateIFCGuidFrom. The code below maintains compatibility with older // versions while generating a stable GUID for all slabs (in the unlikely // case that we have more than 255 of them). string slabGUID = (loopNum < 256) ? GUIDUtil.CreateSubElementGUID(element, subElementStart + loopNum) : GUIDUtil.GenerateIFCGuidFrom(element, "Slab: " + loopNum.ToString()); IFCAnyHandle slabPlacement = ExporterUtil.CreateLocalPlacement(file, slabExtrusionCreationData.GetLocalPlacement(), null); IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(exporterIFC, element, slabGUID, ownerHistory, slabPlacement, prodDefShape, subSlabType); IFCExportInfoPair exportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, subSlabType); //slab quantities slabExtrusionCreationData.ScaledLength = scaledExtrusionDepth; slabExtrusionCreationData.ScaledArea = UnitUtil.ScaleArea(UnitUtil.ScaleArea(hostObjectSubcomponent.AreaOfCurveLoop)); slabExtrusionCreationData.ScaledOuterPerimeter = UnitUtil.ScaleLength(curveLoops[0].GetExactLength()); slabExtrusionCreationData.Slope = UnitUtil.ScaleAngle(MathUtil.SafeAcos(Math.Abs(slope))); IFCExportInfoPair slabRoofExportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, subSlabType); productWrapper.AddElement(null, slabHnd, setter, slabExtrusionCreationData, false, slabRoofExportType); // Create type IFCAnyHandle slabRoofTypeHnd = ExporterUtil.CreateGenericTypeFromElement(element, slabRoofExportType, exporterIFC.GetFile(), ownerHistory, subSlabType, productWrapper); ExporterCacheManager.TypeRelationsCache.Add(slabRoofTypeHnd, slabHnd); elementHandles.Add(slabHnd); slabHandles.Add(slabHnd); hostObjectOpeningLoops.Add(slabCurveLoop); maximumScaledDepth = Math.Max(maximumScaledDepth, scaledDepth); loopNum++; ExporterUtil.AddIntoComplexPropertyCache(slabHnd, layersetInfo); // Create material association here if (layersetInfo != null && !IFCAnyHandleUtil.IsNullOrHasNoValue(layersetInfo.MaterialLayerSetHandle)) { CategoryUtil.CreateMaterialAssociation(slabHnd, layersetInfo.MaterialLayerSetHandle); } } } productWrapper.AddElement(element, hostObjectHandle, setter, extrusionCreationData, true, roofExportType); ExporterUtil.RelateObjects(exporterIFC, null, hostObjectHandle, slabHandles); OpeningUtil.AddOpeningsToElement(exporterIFC, elementHandles, hostObjectOpeningLoops, element, null, maximumScaledDepth, null, setter, localPlacement, productWrapper); transaction.Commit(); return(hostObjectHandle); } } } catch { // SOmething wrong with the above process, unable to create the extrusion data. Reset any internal handles that may have been partially created since they are not committed productWrapper.ClearInternalHandleWrapperData(element); return(null); } finally { exporterIFC.ClearFaceWithElementHandleMap(); } } } } }
///////////////////////////////////////////////////////////////// // SetXXX method is to set base entities' attributes. // Every SetXXX method has a corresponding ValidateXXX method. // ValidateXXX is to validate the parameters for the attributes. // ValidateXXX should not be called in SetXXX. It must be called in CreateXXX method. // This is to make sure all arguments are valid BEFORE create an instance. // So we have below layout for these methods: // ValidateABCBaseEntity(...) { ... } // SetABCBaseEntity(...) { ... } // CreateABCEntity(...) // { // //Code to validate ABC entity's own parameters goes here. // ValidateABCBaseEntity(...); // //Code to create ABC instance goes here. // //Code to set ABC entity's own attributes goes here. // SetABCBaseEntity(...); // } /////////////////////////////////////////////////////////////// private static IFCAnyHandle CreateInstance(IFCFile file, IFCEntityType type) { IFCAnyHandle hnd = file.CreateInstance(type.ToString()); ExporterCacheManager.HandleTypeCache[hnd] = type; return hnd; }
/// <summary> /// Get the top-level Built-in category id for an IFC entity. /// </summary> /// <param name="doc">The doument.</param> /// <param name="entity">The entity.</param> /// <param name="gstyleId">The graphics style, if the returned category is not top level. This allows shapes to have their visibility controlled by the sub-category.</param> /// <returns>The element id for the built-in category.</returns> public static ElementId GetCategoryIdForEntity(Document doc, IFCObjectDefinition entity, out ElementId gstyleId) { gstyleId = ElementId.InvalidElementId; IFCEntityType entityType = entity.EntityType; IFCEntityType?typeEntityType = null; string typeShapeType = null; GetAssociatedTypeEntityInfo(entity, out typeEntityType, out typeShapeType); // Use the IfcTypeObject shape type if the IfcElement shape type is either null, empty, white space, or not defined. string shapeType = entity.ShapeType; if ((string.IsNullOrWhiteSpace(shapeType) || (string.Compare(shapeType, "NOTDEFINED", true) == 0)) && !string.IsNullOrWhiteSpace(typeShapeType)) { shapeType = typeShapeType; } // Set "special" shape types switch (entityType) { case IFCEntityType.IfcColumn: case IFCEntityType.IfcColumnType: if (IsColumnLoadBearing(entity)) { shapeType = "[LoadBearing]"; } break; } ElementId catElemId = GetCategoryElementId(entityType, shapeType); // If we didn't find a category, or if we found the generic model category, try again with the IfcTypeObject, if there is one. if (catElemId == ElementId.InvalidElementId || catElemId.IntegerValue == (int)BuiltInCategory.OST_GenericModel) { if (typeEntityType.HasValue) { catElemId = GetCategoryElementId(typeEntityType.Value, shapeType); } } Category subCategory = null; if (catElemId.IntegerValue == (int)BuiltInCategory.OST_GenericModel) { string subCategoryName = GetCustomCategoryName(entity); if (!string.IsNullOrWhiteSpace(subCategoryName)) { IDictionary <string, Category> createdSubcategories = Importer.TheCache.CreatedSubcategories; if (!createdSubcategories.TryGetValue(subCategoryName, out subCategory)) { // Category may have been created by a previous action (probably a previous import). Look first. try { CategoryNameMap subCategories = Importer.TheCache.GenericModelsCategory.SubCategories; subCategory = subCategories.get_Item(subCategoryName); } catch { subCategory = null; } if (subCategory == null) { subCategory = Importer.TheCache.DocumentCategories.NewSubcategory(Importer.TheCache.GenericModelsCategory, subCategoryName); SetMaterialForSpacesAndOpenings(doc, entity.Id, subCategory, subCategoryName); } createdSubcategories[subCategoryName] = subCategory; } GraphicsStyle graphicsStyle = subCategory.GetGraphicsStyle(GraphicsStyleType.Projection); if (graphicsStyle != null) { gstyleId = graphicsStyle.Id; } } } else if (catElemId == ElementId.InvalidElementId) { catElemId = new ElementId(BuiltInCategory.OST_GenericModel); // Top level entities that are OK to be here. if (entityType != IFCEntityType.IfcProject && entityType != IFCEntityType.IfcBuilding && entityType != IFCEntityType.IfcBuildingStorey && entityType != IFCEntityType.IfcElementAssembly) { string msg = "Setting IFC entity "; if (string.IsNullOrWhiteSpace(shapeType)) { msg = entityType.ToString(); } else { msg = entityType.ToString() + "." + shapeType; } if (typeEntityType.HasValue) { msg += " (" + typeEntityType.Value.ToString() + ")"; } msg += " to Generic Models."; IFCImportFile.TheLog.LogWarning(entity.Id, msg, true); } } Category categoryToCheck = null; if (catElemId.IntegerValue < 0) { categoryToCheck = Importer.TheCache.DocumentCategories.get_Item((BuiltInCategory)catElemId.IntegerValue); } else { categoryToCheck = subCategory; } if (categoryToCheck != null) { // We'll assume that a negative value means a built-in category. It may still be a sub-category, in which case we need to get the parent category and assign the gstyle. // We could optimize this, but this is safer. Category parentCategory = categoryToCheck.Parent; if (parentCategory != null) { catElemId = parentCategory.Id; } // Not already set by subcategory. if (gstyleId == ElementId.InvalidElementId) { GraphicsStyle graphicsStyle = categoryToCheck.GetGraphicsStyle(GraphicsStyleType.Projection); if (graphicsStyle != null) { gstyleId = graphicsStyle.Id; } } } return(catElemId); }
/// <summary> /// Keep track of entities that have been processed, for later summary count. /// </summary> /// <param name="type">The entity type of the handle.</param> public void AddProcessedEntity(IFCEntityType type) { if (m_ProcessedEntities.ContainsKey(type)) m_ProcessedEntities[type]++; else m_ProcessedEntities.Add(new KeyValuePair<IFCEntityType, int>(type, 1)); m_TotalProcessedEntities++; if (m_TotalProcessedEntities % 500 == 0) Importer.TheCache.StatusBar.Set(String.Format(Resources.IFCProcessedEntities, m_TotalProcessedEntities)); }
/// <summary> /// Check compatible type (supertype) when the entity is exported prior to IFC4 schema version /// </summary> /// <param name="typeToCheck">IFC Entity Type Enum</param> /// <param name="typeToUse">IFC Entity Type Enum for compatibility</param> /// <returns></returns> public static bool checkCompatibleType(IFCEntityType typeToCheck, out IFCEntityType typeToUse) { if (m_initialized == false) Initialize(); typeToUse = typeToCheck; if (m_SuperTypeCompatibility.ContainsKey(typeToCheck)) { typeToUse = m_SuperTypeCompatibility[typeToCheck]; return true; } return false; }
// Properties private static ISet<IFCEntityType> GetListOfRelatedEntities(IFCEntityType entityType) { // This is currently only for extending IfcElementType for schemas before IFC4, but could be expanded in the future. // TODO: add types for elements that didn't have types in IFC2x3 for IFC4 support. if (ExporterCacheManager.ExportOptionsCache.ExportAs4) return null; // Check IfcElementType and its parent types. if (entityType == IFCEntityType.IfcElementType || entityType == IFCEntityType.IfcTypeProduct || entityType == IFCEntityType.IfcTypeObject) { ISet<IFCEntityType> relatedEntities = new HashSet<IFCEntityType>(); relatedEntities.Add(IFCEntityType.IfcFooting); relatedEntities.Add(IFCEntityType.IfcPile); relatedEntities.Add(IFCEntityType.IfcRamp); relatedEntities.Add(IFCEntityType.IfcRoof); relatedEntities.Add(IFCEntityType.IfcStair); return relatedEntities; } return null; }
/// <summary> /// To check whether a specified IFC Entity is listed in the Exclude Filter (from configuration) /// </summary> /// <param name="entity">IFCEntityType enumeration representing the IFC entity concerned</param> /// <returns>true if the entity found in the set</returns> public bool IsElementInExcludeList(IFCEntityType entity) { return(ExcludeElementSet.Contains(entity.ToString())); }
/// <summary> /// Gets the first handle of a particular type, or null if none exists. /// </summary> /// <param name="type">The entity type.</param> /// <returns>The handle, or null.</returns> public IFCAnyHandle GetElementOfType(IFCEntityType type) { foreach (IFCAnyHandle handle in m_createdHandles) { if (IFCAnyHandleUtil.IsSubTypeOf(handle, type)) return handle; } ICollection<IFCAnyHandle> internalObjects = m_InternalWrapper.GetAllObjects(); foreach (IFCAnyHandle handle in internalObjects) { if (IFCAnyHandleUtil.IsSubTypeOf(handle, type)) return handle; } return null; }
/// <summary> /// Add an error message to the log file indicating a missing handle of an expected type. /// </summary> /// <param name="expectedType">The expected type of the handle.</param> public void LogNullError(IFCEntityType expectedType) { if (LoggingEnabled && m_LogFile != null) WriteLine("ERROR: " + expectedType.ToString() + " is null or has no value."); }
/// <summary> /// Get the entity type and predefined type for the IfcTypeObject of the entity. /// </summary> /// <param name="entity">The entity.</param> /// <param name="typeEntityType">The IfcTypeObject entity type, if it exists.</param> /// <param name="typePredefinedType">The IfcTypeObject predefined type, if it exists.</param> private static void GetAssociatedTypeEntityInfo(IFCObjectDefinition entity, out IFCEntityType? typeEntityType, out string typePredefinedType) { typeEntityType = null; typePredefinedType = null; if (entity is IFCObject) { IFCObject ifcObject = entity as IFCObject; if (ifcObject.TypeObjects != null && ifcObject.TypeObjects.Count > 0) { IFCTypeObject typeObject = ifcObject.TypeObjects.First(); typeEntityType = typeObject.EntityType; typePredefinedType = typeObject.PredefinedType; } } }
private static ElementId GetCategoryElementId(IFCEntityType entityType, string predefinedType) { BuiltInCategory catId; // Check to see if the entity type and predefined type have a known mapping. // Otherwise special cases follow that could be cached later. if (EntityPredefinedTypeToCategory.TryGetValue(new KeyValuePair<IFCEntityType, string>(entityType, predefinedType), out catId)) return new ElementId(catId); IFCEntityType key; if (EntityTypeKey.TryGetValue(entityType, out key) && EntityPredefinedTypeToCategory.TryGetValue(new KeyValuePair<IFCEntityType, string>(key, predefinedType), out catId)) return new ElementId(catId); // Check if there is a simple entity type to category mapping, and return if found. if (EntityTypeToCategory.TryGetValue(entityType, out catId)) return new ElementId(catId); return ElementId.InvalidElementId; }
/// <summary> /// Creation of Generic IFC object, mainly used for MEP Objects as most of MEP objects are identical /// </summary> /// <param name="entityToCreate">The specific Entity (Enum) to create</param> /// <param name="file">The IFC file</param> /// <param name="guid">GUID</param> /// <param name="ownerHistory">Owner History</param> /// <param name="name">Name attribute</param> /// <param name="description">Description</param> /// <param name="objectType">ObjectType attribute</param> /// <param name="objectPlacement">Placement</param> /// <param name="representation">Geometry representation</param> /// <param name="elementTag">Element Tag attribue</param> /// <returns></returns> public static IFCAnyHandle CreateGenericIFCEntity(IFCEntityType entityToCreate, IFCFile file, string guid, IFCAnyHandle ownerHistory, string name, string description, string objectType, IFCAnyHandle objectPlacement, IFCAnyHandle representation, string elementTag) { ValidateElement(guid, ownerHistory, name, description, objectType, objectPlacement, representation, elementTag); IFCAnyHandle genericIFCEntity; if (ExporterCacheManager.ExportOptionsCache.ExportAs4) { genericIFCEntity = CreateInstance(file, entityToCreate); SetElement(genericIFCEntity, guid, ownerHistory, name, description, objectType, objectPlacement, representation, elementTag); } else { // check for valid IFC2x- entity type Revit.IFC.Common.Enums.IFC2x.IFCEntityType IFC2xValidTypeEnum; if (!Enum.TryParse(entityToCreate.ToString(), true, out IFC2xValidTypeEnum)) { IFCEntityType actualEntity; if (IFCCompatibilityType.checkCompatibleType(entityToCreate, out actualEntity)) { genericIFCEntity = CreateInstance(file, actualEntity); SetElement(genericIFCEntity, guid, ownerHistory, name, description, objectType, objectPlacement, representation, elementTag); return genericIFCEntity; } else { // compatible type not found and it is not a valid 2x- entity type, create proxy genericIFCEntity = CreateInstance(file, IFCEntityType.IfcBuildingElementProxy); SetElement(genericIFCEntity, guid, ownerHistory, name, description, objectType, objectPlacement, representation, elementTag); } } else { // valid 2x- entity genericIFCEntity = CreateInstance(file, entityToCreate); SetElement(genericIFCEntity, guid, ownerHistory, name, description, objectType, objectPlacement, representation, elementTag); } } return genericIFCEntity; }
/// <summary> /// Determines if a entity, with an optional predefined type, should be imported. /// </summary> /// <param name="type">The entity type.</param> /// <param name="predefinedType">The predefined type.</param> /// <returns>True if it is being imported, false otherwise.</returns> public static bool CanImport(IFCEntityType type, string predefinedType) { if (EntityDontImport.Contains(type)) return false; if (!string.IsNullOrWhiteSpace(predefinedType) && EntityDontImportPredefinedType.Contains(new KeyValuePair<IFCEntityType, string>(type, predefinedType))) return false; return true; }
///////////////////////////////////////////////////////////////// // SetXXX method is to set base entities' attributes. // Every SetXXX method has a corresponding ValidateXXX method. // ValidateXXX is to validate the parameters for the attributes. // ValidateXXX should not be called in SetXXX. It must be called in CreateXXX method. // This is to make sure all arguments are valid BEFORE create an instance. // So we have below layout for these methods: // ValidateABCBaseEntity(...) { ... } // SetABCBaseEntity(...) { ... } // CreateABCEntity(...) // { // //Code to validate ABC entity's own parameters goes here. // ValidateABCBaseEntity(...); // //Code to create ABC instance goes here. // //Code to set ABC entity's own attributes goes here. // SetABCBaseEntity(...); // } /////////////////////////////////////////////////////////////// private static IFCAnyHandle CreateInstance(IFCFile file, IFCEntityType type) { IFCAnyHandle hnd = IFCAnyHandleUtil.CreateInstance(file, type); return hnd; }
/// <summary> /// Set the pair information using only either the entity or the type /// </summary> /// <param name="entityTypeStr">the entity or type string</param> /// <param name="predefineType">predefinedtype string</param> public void SetValueWithPair(string entityTypeStr, string predefineType = null) { IFCVersion ifcVersion = ExporterCacheManager.ExportOptionsCache.FileVersion; IfcSchemaEntityTree theTree = IfcSchemaEntityTree.GetEntityDictFor(ifcVersion); int typeLen = 4; bool isType = entityTypeStr.Substring(entityTypeStr.Length - 4, 4).Equals("Type", StringComparison.CurrentCultureIgnoreCase); if (!isType) { if (entityTypeStr.Equals("IfcDoorStyle", StringComparison.InvariantCultureIgnoreCase) || entityTypeStr.Equals("IfcWindowStyle", StringComparison.InvariantCultureIgnoreCase)) { isType = true; typeLen = 5; } } if (isType) { // Get the instance string instName = entityTypeStr.Substring(0, entityTypeStr.Length - typeLen); IfcSchemaEntityNode node = theTree.Find(instName); if (node != null && !node.isAbstract) { IFCEntityType instType = IFCEntityType.UnKnown; if (IFCEntityType.TryParse(instName, true, out instType)) { m_ExportInstance = instType; } } else { // If not found, try non-abstract supertype derived from the type node = IfcSchemaEntityTree.FindNonAbsInstanceSuperType(ifcVersion, instName); if (node != null) { IFCEntityType instType = IFCEntityType.UnKnown; if (IFCEntityType.TryParse(node.Name, true, out instType)) { m_ExportInstance = instType; } } } // set the type IFCEntityType entityType = ElementFilteringUtil.GetValidIFCEntityType(entityTypeStr); if (entityType != IFCEntityType.UnKnown) { m_ExportType = entityType; } else { node = IfcSchemaEntityTree.FindNonAbsInstanceSuperType(ifcVersion, entityTypeStr); if (node != null) { IFCEntityType instType = IFCEntityType.UnKnown; if (IFCEntityType.TryParse(node.Name, true, out instType)) { m_ExportType = instType; } } } } else { // set the instance IFCEntityType instType = ElementFilteringUtil.GetValidIFCEntityType(entityTypeStr); if (instType != IFCEntityType.UnKnown) { m_ExportInstance = instType; } else { // If not found, try non-abstract supertype derived from the type IfcSchemaEntityNode node = IfcSchemaEntityTree.FindNonAbsInstanceSuperType(ifcVersion, entityTypeStr); if (node != null) { instType = IFCEntityType.UnKnown; if (IFCEntityType.TryParse(node.Name, true, out instType)) { m_ExportInstance = instType; } } } // set the type pair string typeName = entityTypeStr; if (ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4 && (entityTypeStr.Equals("IfcDoor", StringComparison.InvariantCultureIgnoreCase) || entityTypeStr.Equals("IfcWindow", StringComparison.InvariantCultureIgnoreCase))) { typeName += "Style"; } else { typeName += "Type"; } IFCEntityType entityType = ElementFilteringUtil.GetValidIFCEntityType(typeName); if (entityType != IFCEntityType.UnKnown) { m_ExportType = entityType; } else { // If the type name is not found, likely it does not have the pair at this level, needs to get the supertype of the instance to get the type pair IList <IfcSchemaEntityNode> instNodes = IfcSchemaEntityTree.FindAllSuperTypes(ifcVersion, entityTypeStr, "IfcProduct", "IfcGroup"); foreach (IfcSchemaEntityNode instNode in instNodes) { typeName = instNode.Name + "Type"; IfcSchemaEntityNode node = theTree.Find(typeName); if (node == null) { node = IfcSchemaEntityTree.FindNonAbsInstanceSuperType(ifcVersion, typeName); } if (node != null && !node.isAbstract) { instType = IFCEntityType.UnKnown; if (IFCEntityType.TryParse(node.Name, true, out instType)) { m_ExportType = instType; break; } } } } } ValidatedPredefinedType = predefineType; }