【集中講座】Grasshopper API – DataTree関係について

  • Grasshopperでスクリプトを記述したい方へ
  • GrasshopperのDataTree型のAPIの理解をより深めたい人
  • Grasshopper応用
  • VisualStudioでGHAを作成する際にも使用可能
  • DataTreeのAPIについてC#で扱う際の方法について

このページは、Grasshopperでスクリプトを記述する際、階層を持ったデータを扱うことができるGrasshopperのDataTreeのAPIについてC#で扱う際の方法について記述しています。VisualStudioでGHAを作成する際にも使用できますので、興味がある方は確認いただけたらと思います。
※このページで使用している.ghファイルはこちらからダウンロード可能です。⇒ ghファイルをダウンロード

またこのページは、下記の3つのリンクのitem、List、Treeの各入力方法・Grasshopperでの処理方法の違いについて理解している前提で書かれています。このページを読む前に下記リンクを確認頂けたらと思います。

[データの働き方 – 基礎] https://www.applicraft.com/tips/rhinoceros/data1/
[データの働き方 – 応用] https://www.applicraft.com/tips/rhinoceros/data2/
[データの働き方 – 応用の続き] https://www.applicraft.com/tips/rhinoceros/data3/


Grasshopperではデータを扱う際、DataTreeという階層構造でデータを扱います。C#コンポーネントの入力端子にItem,List,Treeをそれぞれ設定し(型はすべてPoint3dに設定)、コンポーネント内にどうやって入力されているか確認してみます。

C#Scriptコンポーネントをダブルクリックし、中の引数にあたる箇所の記述を確認すると、RunScriptの引数にそれぞれ
・Point3d
・List<Point3d>
・DataTree<Point3d>
型として、読み込まれているのが分かります。

Point3d型とList<>型は、通常のC#で使用する形式と同じです。DataTree<>型はGrasshopperのAPIにより定義された階層構造を持ったデータ型となります。


ではDataTree型が、どういう形でデータを扱っているか確認してみます。

まずList内のItemをそれぞれ取得するのは、通常のforeachで行うことできます。DataTree型ではBranchesプロパティを使うことで、DataTree内の階層ごとのListを取得できます。なので、取得したListに対して再度foreachを行うことで、DataTree型のそれぞれのItemに対して処理を行うことができます。
下の例で行っている処理は、Printメソッドを使用して、入力した点の座標を出力しています。

Branchesプロパティについては下記を参照。
https://developer.rhino3d.com/api/grasshopper/html/P_Grasshopper_DataTree_1_Branches.htm


次にDataTree型にデータを追加する方法を確認してみます。

ListではAddメソッドで単数のデータを、AddRangeメソッドで複数のデータを追加できます。DataTreeでも同じメソッドでデータを追加できますが、入力する階層もGH_Path型で指定する必要があります。階層値を指定しない場合は、{0}の階層にデータが入ることになります。

記述としては、DataTree型変数.Add(入力するデータ,GH_Path型); といった形です。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_DataTree_1_Add_1.htm

またGH_Path型は、戻り値 GH_Path型 = new GH_Path(int  ないし int[]); といった形でコンストラクタから作成可能です。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_Kernel_Data_GH_Path__ctor_2.htm
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_Kernel_Data_GH_Path__ctor_3.htm


GH_Path型に入力する値をランダムにすることで、ランダムな階層に追加することも可能です。

AddRangeも同様に DataTree型変数.AddRange(複数入力データ,GH_Path型); といった形で使用可能。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_DataTree_1_AddRange_1.htm

ここまで理解できていれば、データを取得・追加することはできるかと思います。次にDataTree型の各種プロパティやメソッドを確認してみたいと思います。

またDataTree型のプロパティ・メソッドにはstatic(静的 型名.~といった形で記述)なものはないので、
・DataTree型の変数.プロパティ
・DataTree型の変数.メソッド名(任意の引数) 
と言った記述で使用可能です。


以下は、各種プロパティを順不同で紹介していきます。

BranchCountプロパティ。階層の数を求める。ここでは3。
https://developer.rhino3d.com/api/grasshopper/html/P_Grasshopper_DataTree_1_BranchCount.htm

DataCountプロパティ。階層を無視してアイテムの総数を求める。ここでは6。
https://developer.rhino3d.com/api/grasshopper/html/P_Grasshopper_DataTree_1_DataCount.htm

Pathsプロパティ。階層名をGH_Path型のList形式で返す。
https://developer.rhino3d.com/api/grasshopper/html/P_Grasshopper_DataTree_1_Paths.htm

Itemプロパティ。階層値(GH_Path型)とインデックス(int)でアイテムを指定する(GetもSetも可)。
戻り値 = DataTree型変数[GH_Path 求める階層, int インデックス]; と言った記述。
https://developer.rhino3d.com/api/grasshopper/html/P_Grasshopper_DataTree_1_Item.htm


次に各種メソッドを順不同で紹介していきます。

ToStringメソッド。通常のToStringをオーバーライドしている。階層ごとのアイテム数を tree {アイテム数;アイテム数} のような形で出力。戻り値 string型 = DataTree型変数.ToString(); のような記述。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_DataTree_1_ToString.htm

Clearメソッド。DataTree型変数.Clear();  階層ごとデータをすべて削除します。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_DataTree_1_Clear.htm

ClearDataメソッド。DataTree型変数.ClearData();  階層は残して、データのみ削除します。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_DataTree_1_ClearData.htm

Insertメソッド。DataTree型変数.Insert(挿入するデータ,GH_Path型 階層番号 ,int インデックス);
指定した階層値、インデックスにデータを挿入します。例では、1番目の階層の3番目のインデックスに100を挿入。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_DataTree_1_Insert.htm

Flattenメソッド。DataTree型変数.Flatten(GH_Path 階層値); データをすべて同じ階層に入れる。何も入力しない場合{0}に入力。GHのFlattenオプションと同様の働き。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_DataTree_1_Flatten.htm

Graftメソッド。DataTree型変数.Graft(Boolean  nullアイテムを含むか);
アイテムごとにそれぞれ階層を追加して、分岐するような処理。GHのGraftオプションと同様の働き。
https://developer.rhino3d.com/api/grasshopper/html/Overload_Grasshopper_DataTree_1_Graft.htm

SimplifyPathsメソッド。DataTree型変数.SimplifyPaths();
不必要な階層構造の分岐をなくす。GHのSimplifyオプションと同様の働き。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_DataTree_1_SimplifyPaths.htm

AllDataメソッド。戻り値 List = DataTree型変数.AllData(); 階層をなくしたデータを、List型で取得する。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_DataTree_1_AllData.htm

MergeTreeメソッド。DataTree型変数.MergeTree(DataTree 別のデータ); 同じ階層同士でデータをまとめる。
引数に指定したデータは変化しないので注意。GHのMergeコンポーネントと同様の働き。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_DataTree_1_MergeTree.htm

Branchメソッド。戻り値 List<T>= DataTree型変数.Branch(階層値);
階層値で指定したデータをList型で取得する。階層値に入れる引数の指定は int, int[] ,GH_Path など。
例では、出力端子の上から、int 0の階層、配列でint[]{0,0}の階層、GH_Pathで2番目の階層を指定。
https://developer.rhino3d.com/api/grasshopper/html/Overload_Grasshopper_DataTree_1_Branch.htm

Pathメソッド。戻り値 GH_Path= DataTree型変数.Path(int 階層のインデックス); 
指定したインデックスの階層値を、GH_Path型で取得する。
例では、0番(1番上)と2番(上から3番目)のGH_Path型を出力。またBranchCountプロパティと併せて階層数だけループし、奇数番目にあたる階層のデータのみResultsから出力した例。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_DataTree_1_Path.htm

EnsurePathメソッド。DataTree型変数.EnsurePath(階層値);
指定した階層を追加する。階層値の指定は、int[] ないしGH_Path。例では、{5],{10,0},{11;0;5}などの階層を追加している。
https://developer.rhino3d.com/api/grasshopper/html/Overload_Grasshopper_DataTree_1_EnsurePath.htm

RemovePathメソッド。DataTree型変数.RemovePath(階層値);
指定した階層をデータごと削除する。階層値の指定は、int[] ないしGH_Path。例では、{0},{0;2;0}にあたる階層を削除している。存在しない階層を指定した場合は、何も行わない。
https://developer.rhino3d.com/api/grasshopper/html/Overload_Grasshopper_DataTree_1_RemovePath.htm

PathExistsメソッド。戻り値 Boolean = DataTree型変数.PathExists(階層値);
指定した階層があるかないか判定する。入力する階層値は int[] , GH_Path。
例では、{0;1],{0}の階層があるか判定している。
https://developer.rhino3d.com/api/grasshopper/html/Overload_Grasshopper_DataTree_1_PathExists.htm

ItemExistsメソッド。戻り値 Boolean = DataTree型変数.ItemExists(GH_Path 階層値,int インデックス);
階層値とインデックスで指定したデータがあるかないかを判定する。例では、{0]の1番,{1}の2番にあたるアイテムがあるか判定している。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_DataTree_1_ItemExists.htm

RenumberPathsメソッド。DataTree型変数.RenumberPaths();
階層値を順番に{0}から付け直す。GHのPath Mapperコンポーネントの[Create Renumber Mapping]オプションと同等の機能。引数に文字列を入れて書式を設定することも可能。
https://developer.rhino3d.com/api/grasshopper/html/Overload_Grasshopper_DataTree_1_RenumberPaths.htm


下記、DataTreeに関係した補足のサンプルです。

GHのFlipMatrixコンポーネントを模したもの。階層のアイテム数の最大数分ループし、インデックス値を階層値としてデータを空のDataTreeに入れ直すような処理で実装可能。

GHのMatchTreeコンポーネントを模したもの。取得したGH_Path型をToStringメソッドで文字列に変え、該当する文字列の時のみ処理。例では{0;1}から始まる時のみ”_test”を末尾に付け足している。

GHのTrimTreeコンポーネントを模したもの。階層値の末尾を削除してデータをまとめ直している。Graftの反対の効果。GH_Path型のCullElementメソッドを使用。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_Kernel_Data_GH_Path_CullElement.htm

階層値の先頭を削除するGH_Path型のCullFirstElementを使うことで、GHのShift Pathsコンポーネントのような働きをすることも可能。
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_Kernel_Data_GH_Path_CullFirstElement.htm

※このページで使用している.ghファイルはこちらからダウンロード可能です。⇒ ghファイルをダウンロード