要素のマテリアル

要素のマテリアル

1 つの要素は複数の要素とコンポーネントを持つことができます。たとえば、FamilyInstance は SubComponents を、Wall は(複数の CompoundStructureLayers を含めることができる) CompoundStructure を持つことができます(SubComponents の詳細には「ファミリ インスタンス」セクションを、CompoundStructure の詳細については「壁、床、屋根、開口部」を参照してください)。

Revit プラットフォーム API では、次のガイドラインを使用して、要素のマテリアルを取得します。

パラメータのマテリアル

要素オブジェクトに ParameterType が ParameterType.Material となっているパラメータがある場合、パラメータから要素のマテリアルを取得できます。たとえば、構造柱 FamilySymbol (カテゴリの FamilyInstance が BuiltInCategory.OST_StructuralColumns)は構造マテリアルを持ちます。ElementId を使用してマテリアルを取得します。次のサンプル コードは、コンポーネントを 1 つ持つ構造柱マテリアルの取得方法を表しています。

コード領域: パラメータから要素マテリアルを取得

public void GetMaterial(Document document, FamilyInstance familyInstance)
{
    foreach (Parameter parameter in familyInstance.Parameters)
    {
        Definition definition = parameter.Definition;
        // material is stored as element id
        if (parameter.StorageType == StorageType.ElementId)
        {
            if (definition.ParameterGroup == BuiltInParameterGroup.PG_MATERIALS &&
                    definition.ParameterType == ParameterType.Material)
            {
                Autodesk.Revit.DB.Material material = null;
                Autodesk.Revit.DB.ElementId materialId = parameter.AsElementId();
                if (-1 == materialId.IntegerValue)
                {
                    //Invalid ElementId, assume the material is "By Category"
                    if (null != familyInstance.Category)
                    {
                        material = familyInstance.Category.Material;
                    }
                }
                else
                {
                    material = document.GetElement(materialId) as Material;
                }

                TaskDialog.Show("Revit","Element material: " + material.Name);
                break;
            }
        }
    }
}
注: マテリアル プロパティを UI で[カテゴリ別]に設定した場合、マテリアルの ElementId は ElementId.InvalidElementId となり、サンプル コードにあるようにマテリアル オブジェクトを取得するのに使用することはできません。次のセクションで説明されている方法で、カテゴリからマテリアルを取得します。

他の複合パラメータに含まれる一部のマテリアル プロパティには API からはアクセスできません。次の図のシステム ファミリの例にあるように、手すり、手すりの構造パラメータの StorageType は StorageType.None になります。結果として、この状況ではマテリアルの情報を取得できません。

図 107: 手すりの構造プロパティ

マテリアルと FamilyInstance

梁、柱、基礎の FamilyInstances には、StructuralMaterialId プロパティを使用してマテリアルを取得するという別の方法があります。このプロパティは、インスタンスの構造解析プロパティを定義するマテリアルを特定する ElementId を返します。

コード領域: ファミリ インスタンスから要素のマテリアルを取得


public Material GetFamilyInstanceMaterial(Document document, FamilyInstance beam)
{
    Material material = document.GetElement(beam.StructuralMaterialId) as Material;

    return material;
}

マテリアルとカテゴリ

マテリアルを持つことができるのはモデル要素のみです。

[Revit Manage]タブから、[設定][オブジェクト スタイル]をクリックして、[オブジェクト スタイル]ダイアログ ボックスを表示します。[モデル オブジェクト]タブにリストされているカテゴリの要素はマテリアル情報を持ちます。

図 108: カテゴリ マテリアル

モデル要素にのみマテリアル プロパティを割り当てることができます。よって、モデル要素以外の要素(注釈や読み込み済みなど)に対応するカテゴリのマテリアルを照会する場合、結果は常に null となります。要素とカテゴリの分類の詳細については、「要素の基本」を参照してください。

要素に複数のコンポーネントがある場合、Category.Subcategories の一部が複数のコンポーネントに対応します。

前述の[オブジェクト スタイル]ダイアログ ボックスでは、窓カテゴリ、フレーム/マリオン、ガラス サブカテゴリは窓要素のコンポーネントにマップされます。次の図では、窓ペインのマテリアルを取得する方法は、窓記号のガラス ペイン マテリアル パラメータのみのように思われます。ただし、値は[カテゴリ別]であり、対応するパラメータは ElementId.InvalidElementId を返します。

この場合、ペインのマテリアルは null でなく、カテゴリ OST_WindowsFrameMullionProjection のマテリアル プロパティに依存します(これは窓のカテゴリ OST_Windows のサブカテゴリです)。null として返される場合、ペインのマテリアルは親カテゴリ OST_Windows によって決まります。詳細については、「ウォークスルー: 窓のマテリアルを取得す」を参照してください。

図 109: 窓のマテリアル

CompoundStructureLayer マテリアル

HostObjAttributes から CompoundStructureLayer オブジェクトを取得できます。詳細については、「壁、床、天井、屋根、開口部」を参照してください。

要素のマテリアルを取得する

次の図は、要素のマテリアルを取得するワークフローを表しています。

図 110: 要素のマテリアルを取得するワークフロー

このワークフローは次のプロセスを表しています。

  • ワークフローは、要素に属するマテリアル オブジェクト(Autodesk.Revit.DB.Structure.StructuralMaterialType 列挙型タイプ以外)を取得する方法を表しています。
  • マテリアルの取得の際には、次の 2 つの要素の分類があります。
    • HostObject with CompoundStructure - CompoundStructureLayer クラス MaterialId プロパティからマテリアル オブジェクトを取得します。
    • その他 - パラメータからマテリアルを取得します。
  • null マテリアル オブジェクトや、ElementId.InvalidElementId の値を持つ無効な ElementId を取得した場合は、対応するカテゴリのマテリアルを試してみます。FamilyInstance とその FamilySymbol は通常同じカテゴリを持つことに注意してください。
  • 要素オブジェクトについての理解が深まると、マテリアルの取得がより簡単になります。次に例を示します。
    • 要素が梁であることが分かっている場合は、インスタンス パラメータの構造マテリアルを取得することができます。
    • 要素が窓であることが分かっている場合は、それを FamilyInstance に投影して FamilySymbol を取得することができます。
  • その後、フレーム外部マテリアルやフレーム内部マテリアルなどのパラメータを取得して、マテリアル オブジェクトを取得できます。null を取得した場合は、FamilySymbol カテゴリからマテリアル オブジェクトの取得を試みます。
  • API ではすべての要素のマテリアルが使用できるわけではありません。

ウォークスルー: 窓マテリアルを取得

次のコードは、窓マテリアルの取得方法を表しています。

コード領域: 窓マテリアルを取得するウォークスルー

public void GetMaterial(Document document, FamilyInstance window)
{
    FamilySymbol windowSymbol = window.Symbol;
    Category category = windowSymbol.Category;
    Autodesk.Revit.DB.Material frameExteriorMaterial = null;
    Autodesk.Revit.DB.Material frameInteriorMaterial = null;
    Autodesk.Revit.DB.Material sashMaterial = null;
    // Check the parameters first
    foreach (Parameter parameter in windowSymbol.Parameters)
    {
        switch (parameter.Definition.Name)
        {
            case "Frame Exterior Material":
                frameExteriorMaterial = document.GetElement(parameter.AsElementId()) as Material;
                break;
            case "Frame Interior Material":
                frameInteriorMaterial = document.GetElement(parameter.AsElementId()) as Material;
                break;
            case "Sash":
                sashMaterial = document.GetElement(parameter.AsElementId()) as Material;
                break;
            default:
                break;
        }
    }
    // Try category if the material is set by category
    if (null == frameExteriorMaterial)
        frameExteriorMaterial = category.Material;
    if (null == frameInteriorMaterial)
        frameInteriorMaterial = category.Material;
    if (null == sashMaterial)
        sashMaterial = category.Material;
    // Show the result because the category may have a null Material,
    // the Material objects need to be checked.
    string materialsInfo = "Frame Exterior Material: " + (null != frameExteriorMaterial ? frameExteriorMaterial.Name : "null") + "\n";
    materialsInfo += "Frame Interior Material: " + (null != frameInteriorMaterial ? frameInteriorMaterial.Name : "null") + "\n";
    materialsInfo += "Sash: " + (null != sashMaterial ? sashMaterial.Name : "null") + "\n";
    TaskDialog.Show("Revit",materialsInfo);
}