皆様こんにちは。
AMDlabの齋藤です。
今回はGrasshopperで以下のように複数のコンポーネントを入力できるようにしたいと思います。
これでGrasshopperでよく構成するコンポーネント群をすぐに作ることができます。
コンポーネント複数配置がちょっと使い勝手悪かったので修正
置いたものが選択されている状態にしてみた pic.twitter.com/wRLeEzmnMp— K. SAITO (@Saito40k) May 30, 2024
それでは始めましょう。
今回のデータはこちらに挙げております。
https://github.com/AMDlab/TechBlog-Multiple-Components-At-Once
登録したい複数のコンポーネントの情報を得る
今回はこちらのコンポーネントを複数登録したいと思います。
まず、登録したい複数のコンポーネントの情報を読み取ります。
読み取る情報はコンポーネントの名前、GUID、位置です。
読み取る方法はいくつかありますが、今回は
MetaHopperのGet Selected Objectsでコンポーネント情報を、
そこからGhPython(Rhino8のScriptでも可)で読み取りたい情報を読み取ります。
まず、登録したい複数のコンポーネントをキャンバスの原点(左上の隅)に移動させます。
それらを選択し、Get Selected ObjectsのSelectを押します。
次にGhPythonを追加し、Inputをx、OutputをName、ComponentGuid、BPivotとします。
Get Selected ObjectsのComponentとParamを繋ぎます。(順不同)
そしてGhPythonに以下を入力します。
1 2 3 4 5 |
Name = x.Name ComponentGuid = x.ComponentGuid.ToString() Bounds = x.Attributes.Bounds BPivot = str(Bounds.X + Bounds.Width/2) + ", " \ + str(Bounds.Y + Bounds.Height/2) |
これで読み取ることができました。
複数のコンポーネントの情報からデータを構成する
次に複数のコンポーネントの情報からGhPython Pythonでデータを構成します。
このデータから一気に複数のコンポーネントを配置することができるようになります。
まず、GhPython(Rhino8のScriptでも可)を追加します。
次に、GhPythonが動作しないようDisableにします。
その後以下のプログラムを入力します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
"""Slider, Digit Multiplication Inputs: Output: """ from Grasshopper import Instances from System.Drawing import PointF from System import Guid put_data = [ # ここに入力していく ] recompute_doc_obj_id = [] def ParamInput(base_param, p_data): if type(p_data[1]) == list: child_param = getattr(base_param, p_data[0]) for p_d in p_data[1]: ParamInput(child_param, p_d) return setattr(base_param, p_data[0], p_data[1]) def SetPersistentData(Param, Data): Param.SetPersistentData(Data) def Callback(doc): for id in recompute_doc_obj_id: put_data[id][6].ExpireSolution(True) def main(): doc = ghenv.Component.OnPingDocument() u_server = doc.UndoServer u_server.RemoveRecord(u_server.UndoGuids[0]) pivot = ghenv.Component.Attributes.Pivot for c in put_data: c_pivot = PointF(c[2][0] + pivot.X, c[2][1] + pivot.Y) if not (Instances .ActiveCanvas .Validator .CanCreateObject(Guid(c[1]), c_pivot) ): raise Exception("ERROR: Can Create Object.") Instances.ActiveCanvas.InstantiateNewObject(Guid(c[1]), c_pivot, False) c[6] = doc.Objects[doc.Objects.Count - 1] if c[0] == "Param": if c[3]: SetPersistentData(c[6], c[3]) if c[4]: for c_params in c[4]: ParamInput(c[6], c_params) elif c[0] == "Component": if c[3]: for c_param in c[3]: ParamInput(c[6], c_param) if c[4]: for i, c_input in enumerate(c[4]): if c_input[0]: SetPersistentData(c[6].Params.Input[i], c_input[0]) if c_input[1]: for c_i in c_input[1]: ParamInput(c[6].Params.Input[i], c_i) if c[5]: for i, c_output in enumerate(c[5]): if c_output[0]: for c_o in c_output[0]: ParamInput(c[6].Params.Output[i], c_o) doc.DeselectAll() for c in put_data: c[6].Attributes.Selected = True if c[0] == "Param": if c[5]: for sid in c[5]: if put_data[sid[0]][0] == "Param": rid = put_data[sid[0]][6] elif put_data[sid[0]][0] == "Component": rid = put_data[sid[0]][6].Params.Input[sid[1]] rid.AddSource(c[6]) elif c[0] == "Component": for c_output in c[5]: sids = c_output[1] if sids: for i, sid in enumerate(sids): if put_data[sid[0]][0] == "Param": rid = put_data[sid[0]][6] elif put_data[sid[0]][0] == "Component": rid = put_data[sid[0]][6].Params.Input[sid[1]] rid.AddSource(c[6].Params.Output[i]) doc.ScheduleSolution(1, Callback) doc.UndoUtil.MergeRecords(len(put_data)) doc.RemoveObject(ghenv.Component, False) if True: main() |
そして put_data の # ここに入力していく に中身を入力していきます。
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
put_data = [ [ "Component", "ce46b74e-00c9-43c4-805a-193b69ea4a11", [60., 0.], None, [], [], None ], [ "Param", "33bcf975-a0b2-4b54-99fd-585c893b9e88", [-155., 10.], None, None, [[0, 1]], None ], [ "Param", "57da07bd-ecab-415d-9d86-af36d7073abc", [-110., -10.], None, None, [[0, 0]], None ] ] |
これで入力できました。
入力した内容はコンポーネント、パラメーターごとに多次元配列で入力していきます。
例えば今回は以下の順番で配列を構成しています。
そしてその中身は以下のようにしています。
0.
"Param" か
"Component" か
1. ComponentGuid(読み取った情報)
2. コンポーネントの場所(読み取った情報) 例)
[0., 10.]
3.
"Param" の場合:パラメーター内のデータ
"Component" の場合:コンポーネントのPropertiesを入力 例)
[["ComponentFlag", True], ["ComponentNum", 1.1], ...]
4.
"Param" の場合:パラメーターのPropertiesを入力 例)
[["ParamFlag", True], ["ParamNum", 1.1], ...]
"Component" の場合:コンポーネントのInput側のパラメーターをInputの数分入力
例)
[[3のパラメーター内のデータ, 4のパラメーターのPropertiesを入力], [3のパラメーター内のデータ, 4のパラメーターのPropertiesを入力], ...]
5.
"Param" の場合:次につながるコンポーネントを指す 例)
[[コンポーネントの番号, コンポーネントのInputの番号], [パラメーターの番号, 0], ...]
"Component" の場合:コンポーネントのOutput側のパラメーターをOutputの数分入力
例)
[[4のパラメーターのPropertiesを入力, 5の次につながるコンポーネントを指す], [4のパラメーターのPropertiesを入力, 5の次につながるコンポーネントを指す], ...]
6.
None
これで入力できました。実際に動くか試してみましょう。
できたGhPythonを複製してEnableにします。
Enableにした瞬間にコンポーネントが出てきたらOKです。
※ここでUndoをするとエラーを吐くので注意してください。
構成したGhPythonをUserObjectへ登録する
最後に構成したGhPythonをUserObjectへ登録して、Grasshopper上へ一気に入力できるようにします。
まず先に、コンポーネントの情報を入れます。
コンポーネントのNameを入力します。
次にUserObjectへ登録します。
まず、動作してしまってデータが消えると困るので、GhPythonをコピーしておきます。
次に動作しないようにDisable Solverをします。マウスホイールクリックからできます。
そしてGhPythonをEnableにします。
GhPythonを選択してFile>Create User Object…をクリックします。
フォームに入力していきます。
できたらOKを押しましょう。
その後はGhPythonをDisableにして、Enable Solverにします。
これで登録は完了です。
最後にちゃんと入力できるかテストしてみます。
うまくできました!
おわりに
いかがでしたでしょうか、
今回は複数のコンポーネントを1度に入力する方法紹介しました。
これである程度の効率化を図れます。
さらにもう数歩先を考えると生成AIがこの多次元配列を作成できれば、Grasshopperの自動生成ができるかもしれませんね。
皆さんもいろいろな複数のコンポーネントを一度に入れられるようにしてみましょう!
COMMENTS