public void SingleMaterialOverride(ElementId materialId, double materialWidth) { GenerateIFCObjectsIfNeeded(); Material material = m_Element.Document.GetElement(materialId) as Material; string layerName = "Layer"; if (material != null) { layerName = NamingUtil.GetMaterialLayerName(material); } MaterialInfo matInfo = new MaterialInfo(materialId, layerName, materialWidth, MaterialFunctionAssignment.None); MaterialIds.Add(matInfo); IFCAnyHandle singleMaterialOverrideHnd = IFCInstanceExporter.CreateMaterial(m_ExporterIFC.GetFile(), layerName, null, null); ExporterCacheManager.MaterialHandleCache.Register(MaterialIds[0].m_baseMatId, singleMaterialOverrideHnd); m_MaterialLayerSetHandle = singleMaterialOverrideHnd; }
/// <summary> /// Collect information about material layer. /// For IFC4RV Architectural exchange, it will generate IfcMatrialConstituentSet along with the relevant IfcShapeAspect and the width in the quantityset /// For IFC4RV Structural exchange, it will generate multiple components as IfcBuildingElementPart for each layer /// For others IfcMaterialLayer will be created /// </summary> private void CollectMaterialLayerSet() { ElementId typeElemId = m_Element.GetTypeId(); IFCAnyHandle materialLayerSet = ExporterCacheManager.MaterialSetCache.FindLayerSet(typeElemId); // Roofs with no components are only allowed one material. We will arbitrarily choose the thickest material. m_PrimaryMaterialHandle = ExporterCacheManager.MaterialSetCache.FindPrimaryMaterialHnd(typeElemId); bool materialHandleIsNotValid = IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet); if (IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet) || materialHandleIsNotValid) { if (materialHandleIsNotValid) { UnregisterIFCHandles(); } m_needToGenerateIFCObjects = true; List <double> widths = new List <double>(); List <MaterialFunctionAssignment> functions = new List <MaterialFunctionAssignment>(); HostObjAttributes hostObjAttr = m_Element.Document.GetElement(typeElemId) as HostObjAttributes; if (hostObjAttr == null) { // It does not have the HostObjAttribute (where we will get the compound structure for material layer set. // We will define a single material instead and create the material layer set of this single material if there is enough information (At least Material id and thickness) FamilyInstance familyInstance = m_Element as FamilyInstance; if (familyInstance == null) { return; } FamilySymbol familySymbol = familyInstance.Symbol; ICollection <ElementId> famMatIds = familySymbol.GetMaterialIds(false); if (famMatIds.Count == 0) { // For some reason Plate type may not return any Material id ElementId baseMatId = CategoryUtil.GetBaseMaterialIdForElement(m_Element); Material material = m_Element.Document.GetElement(baseMatId) as Material; if (material == null) { return; } string layerName = NamingUtil.GetMaterialLayerName(material); double matWidth = 0.0; Parameter thicknessPar = familySymbol.get_Parameter(BuiltInParameter.CURTAIN_WALL_SYSPANEL_THICKNESS); if (thicknessPar != null) { matWidth = thicknessPar.AsDouble(); } widths.Add(matWidth); if (baseMatId != ElementId.InvalidElementId) { MaterialIds.Add(new MaterialInfo(baseMatId, layerName, matWidth, MaterialFunctionAssignment.None)); } // How to get the thickness? For CurtainWall Panel (PanelType), there is a builtin parameter CURTAINWALL_SYSPANEL_THICKNESS functions.Add(MaterialFunctionAssignment.None); } else { foreach (ElementId matid in famMatIds) { // How to get the thickness? For CurtainWall Panel (PanelType), there is a builtin parameter CURTAINWALL_SYSPANEL_THICKNESS double matWidth = familySymbol.get_Parameter(BuiltInParameter.CURTAIN_WALL_SYSPANEL_THICKNESS)?.AsDouble() ?? ParameterUtil.GetSpecialThicknessParameter(familySymbol); if (MathUtil.IsAlmostZero(matWidth)) { continue; } widths.Add(matWidth); ElementId baseMatId = CategoryUtil.GetBaseMaterialIdForElement(m_Element); if (matid != ElementId.InvalidElementId) { Material material = m_Element.Document.GetElement(matid) as Material; if (material != null) { string layerName = NamingUtil.GetMaterialLayerName(material); MaterialIds.Add(new MaterialInfo(matid, layerName, matWidth, MaterialFunctionAssignment.None)); } } else { MaterialIds.Add(new MaterialInfo(baseMatId, null, matWidth, MaterialFunctionAssignment.None)); } functions.Add(MaterialFunctionAssignment.None); } } } else { ElementId baseMatId = CategoryUtil.GetBaseMaterialIdForElement(m_Element); CompoundStructure cs = hostObjAttr.GetCompoundStructure(); if (cs != null) { double scaledOffset = 0.0, scaledWallWidth = 0.0, wallHeight = 0.0; Wall wall = m_Element as Wall; if (wall != null) { scaledWallWidth = UnitUtil.ScaleLength(wall.Width); scaledOffset = -scaledWallWidth / 2.0; BoundingBoxXYZ boundingBox = wall.get_BoundingBox(null); if (boundingBox != null) { wallHeight = boundingBox.Max.Z - boundingBox.Min.Z; } } //TODO: Vertically compound structures are not yet supported by export. if (!cs.IsVerticallyHomogeneous() && !MathUtil.IsAlmostZero(wallHeight)) { cs = cs.GetSimpleCompoundStructure(wallHeight, wallHeight / 2.0); } for (int ii = 0; ii < cs.LayerCount; ++ii) { double matWidth = cs.GetLayerWidth(ii); ElementId matId = cs.GetMaterialId(ii); widths.Add(matWidth); // save layer function into ProductWrapper, // it's used while exporting "Function" of Pset_CoveringCommon functions.Add(cs.GetLayerFunction(ii)); if (matId != ElementId.InvalidElementId) { Material material = m_Element.Document.GetElement(matId) as Material; if (material != null) { string layerName = NamingUtil.GetMaterialLayerName(material); MaterialIds.Add(new MaterialInfo(matId, layerName, matWidth, functions.Last())); } } else { MaterialIds.Add(new MaterialInfo(baseMatId, null, matWidth, functions.Last())); } } } if (MaterialIds.Count == 0) { double matWidth = cs?.GetWidth() ?? 0.0; widths.Add(matWidth); if (baseMatId != ElementId.InvalidElementId) { Material material = m_Element.Document.GetElement(baseMatId) as Material; if (material != null) { string layerName = NamingUtil.GetMaterialLayerName(material); MaterialIds.Add(new MaterialInfo(baseMatId, layerName, matWidth, MaterialFunctionAssignment.None)); } } functions.Add(MaterialFunctionAssignment.None); } } } else { m_needToGenerateIFCObjects = false; m_MaterialLayerSetHandle = materialLayerSet; MaterialLayerSetInfo mlsInfo = ExporterCacheManager.MaterialSetCache.FindMaterialLayerSetInfo(typeElemId); if (mlsInfo != null) { MaterialIds = mlsInfo.MaterialIds; m_PrimaryMaterialHandle = mlsInfo.PrimaryMaterialHandle; m_LayerQuantityWidthHnd = mlsInfo.LayerQuantityWidthHnd; } } return; }