ファミリ タイプとパラメータを管理する

ファミリ タイプとパラメータを管理する

ファミリ ドキュメントからは FamilyManager プロパティにアクセスできます。FamilyManager クラスからはファミリ タイプとパラメータにアクセスできます。このクラスを使用すると、タイプの追加と削除、ファミリと共有パラメータの追加と削除、異なるファミリ タイプのパラメータ値の設定、パラメータ値を決定するための式の定義といった操作が可能になります。

ファミリ内のタイプを取得する

次の例に示すように、FamilyManager を使用するとファミリ内のタイプに繰り返し処理を行うことができます。

コード領域 13-11: ファミリ内のタイプを取得

public void GetFamilyTypesInFamily(Document familyDoc)
{
    if (familyDoc.IsFamilyDocument)
    {
        FamilyManager familyManager = familyDoc.FamilyManager;

        // get types in family
        string types = "Family Types: ";
        FamilyTypeSet familyTypes = familyManager.Types;
        FamilyTypeSetIterator familyTypesItor = familyTypes.ForwardIterator();
        familyTypesItor.Reset();
        while (familyTypesItor.MoveNext())
        {
            FamilyType familyType = familyTypesItor.Current as FamilyType;
            types += "\n" + familyType.Name;
        }
        TaskDialog.Show("Revit",types);
    }
}

図 53: コンクリート-長方形-柱ファミリのファミリ タイプ

FamilyTypes を編集する

FamilyManager には、ファミリ内の既存のタイプに繰り返し処理を行い、タイプとそのパラメータを追加、修正する機能があります。

次の例は、新しいタイプを追加し、パラメータを設定して、FamilyInstance に新しいタイプを追加する方法を表しています。タイプの編集は Set()関数を使用して現在のタイプに対して実行します。現在のタイプは CurrentType プロパティから判断できます。CurrentType プロパティを使用して編集前に現在のタイプを設定することもできますし、NewType()関数を使用して新しいタイプを作成し、編集用に現在のタイプとして設定することもできます。

新しいタイプを作成して修正した後、新しいタイプを使用可能にするために、Document.LoadFamily()を使用してファミリを Revit プロジェクトにロードして戻します。

コード領域 13-12: ファミリ タイプを編集

public void EditFamilyTypes(Document document, FamilyInstance familyInstance)
{
    // example works best when familyInstance is a rectangular concrete element

    if ((null == document) || (null == familyInstance.Symbol))
    {
        return;   // invalid arguments
    }

    // Get family associated with this
    Family family = familyInstance.Symbol.Family;
    if (null == family)
    {
        return;    // could not get the family
    }

    // Get Family document for family
    Document familyDoc = document.EditFamily(family);
    if (null == familyDoc)
    {
        return;    // could not open a family for edit
    }

    FamilyManager familyManager = familyDoc.FamilyManager;
    if (null == familyManager)
    {
        return;  // cuould not get a family manager
    }

    // Start transaction for the family document
    using (Transaction newFamilyTypeTransaction = new Transaction(familyDoc, "Add Type to Family"))
    {
        int changesMade = 0;
        newFamilyTypeTransaction.Start();

        // add a new type and edit its parameters
        FamilyType newFamilyType = familyManager.NewType("2X2");

        if (newFamilyType != null)
        {
            // look for 'b' and 'h' parameters and set them to 2 feet
            FamilyParameter familyParam = familyManager.get_Parameter("b");
            if (null != familyParam)
            {
                familyManager.Set(familyParam, 2.0);
                changesMade += 1;
            }

            familyParam = familyManager.get_Parameter("h");
            if (null != familyParam)
            {
                familyManager.Set(familyParam, 2.0);
                changesMade += 1;
            }
        }

        if (2 == changesMade)   // set both paramaters?
        {
            newFamilyTypeTransaction.Commit();
        }
        else   // could not make the change -> should roll back 
        {
            newFamilyTypeTransaction.RollBack();
        }

        // if could not make the change or could not commit it, we return
        if (newFamilyTypeTransaction.GetStatus() != TransactionStatus.Committed)
        {
            return;
        }
    }

    // now update the Revit project with Family which has a new type
    LoadOpts loadOptions = new LoadOpts();

    // This overload is necessary for reloading an edited family
    // back into the source document from which it was extracted
    family = familyDoc.LoadFamily(document, loadOptions);
    if (null != family)
    {
        // find the new type and assign it to FamilyInstance
        ISet<ElementId> familySymbolIds = family.GetFamilySymbolIds();
        foreach (ElementId id in familySymbolIds)
        {
            FamilySymbol familySymbol = family.Document.GetElement(id) as FamilySymbol;
            if ((null != familySymbol) && familySymbol.Name == "2X2")
            {
                using (Transaction changeSymbol = new Transaction(document, "Change Symbol Assignment"))
                {
                    changeSymbol.Start();
                    familyInstance.Symbol = familySymbol;
                    changeSymbol.Commit();
                }
                break;
            }
        }
    }
}

class LoadOpts : IFamilyLoadOptions
{
    public bool OnFamilyFound(bool familyInUse, out bool overwriteParameterValues)
    {
        overwriteParameterValues = true;
        return true;
    }

    public bool OnSharedFamilyFound(Family sharedFamily, bool familyInUse, out FamilySource source, out bool overwriteParameterValues)
    {
        source = FamilySource.Family;
        overwriteParameterValues = true;
        return true;
    }
}
FamilyManager クラスを使用すると、すべてのファミリ パラメータにアクセスできます。これには、ファミリの組み込みパラメータ、カテゴリの組み込みパラメータ、ファミリ タイプに関連付けられている共有パラメータが含まれます。ファミリ パラメータを取得するには 2 つの方法があります。
  • パラメータ プロパティ - ファミリ内のすべてのパラメータを取得する
  • GetParameters() - ファミリ内のすべてのパラメータを、Revit UI に表示される順序で取得する

GetParameters()メソッドを使用した場合、Revit UI の順番は最初にグループごとで指定され、次に個々のパラメータの順番で指定されます。

ファミリ パラメータは、指定したファミリについて、API から(グループ内で)並べ替えることができます(パラメータの並べ替えをサポートしない、鉄筋形状ファミリを除く)。これにより、最も論理的な順序で、パラメータをユーザに表示できます。並べ替えは、同じパラメータ グループ内に表示されるパラメータにのみ影響します。異なるグループに属するパラメータは区別され、順序は影響を受けません。

パラメータを並べ替えるための最も簡単な方法が FamilyManager.SortParameters()メソッドを使用する方法であり、目的の並べ替え順序を指定するパラメータがあります。以下のサンプルでは、パラメータを昇順で並べ替えます。
コード領域: ファミリ パラメータを並べ替える
private void DisplayParametersInAscendingOrder(Document familyDoc)
{
    FamilyManager familyManager = familyDoc.FamilyManager;
    familyManager.SortParameters(ParametersOrder.Ascending);
}
注: 並べ替えは、1 回のみの操作です。新しいパラメータを追加しても、自動的に並べ替えられるわけではありません。

パラメータの並べ替え順序を詳細にコントロールするには、ファミリ パラメータの新しい順番のリストを指定する FamilyManager.ReorderParameters()メソッドを使用します。このリストには、表示されないパラメータを含む、GetParameters()メソッドが返すすべてのパラメータを含める必要があります。含まれてない場合は、例外がスローされます。