- 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ファイルをダウンロード