GrasshopperをGitする

Repository: git_rhino_ghxは 研究室内でgrasshopperのスパゲッティが量産されるのを解決したく始めた「grasshopperをGit/ Githubで管理しよう」というプロジェクトです。 grasshopperはsave asからxml形式の.ghxでも保存できるのですが、それをパースして、どうにかGitな管理ができないか試みています。

ざっくりと言えば、Grasshopperにて、外部のgrasshopper(.gh/ .ghx)を関数のように呼び出すことのできるhopsをgitで管理しつつ、そのサポートをgit_rhino_ghxに含まれるghx_diff.pyとghx_to_dot.pyで行うことを試行しています。hopsのみで良いのでは、と思うかもしれませんが:

  • .ghxではコンポーネント一つをざっくり50行くらい使って記述しているのでdiffがうまくとれない
  • 保存時のビューを変更しただけ、コンポーネントを移動しただけ、でも更新されてしまうので意味のある履歴が埋もれる

など、実は管理上の問題があります。git_rhino_ghxの二つのプログラムはこのあたりをなんとかしようと試作したものです。

なお、hopsを用いるとコンポーネントの集まり(モジュール)に対する入出力を整理するマインドが芽生えるように思います。スパゲッティに対してはそれだけで一定の効果がありそうです。

ghx_diff.py

ghx_diff.pyは、.ghxのdiffをとる目的で作られています。ファイル名(.ghx)と前(left)・後(right)のブランチ名を指定すると次図のような差分:diffの表現された.ghxを {target_file_name}({left_branch_name}_to_{right_branch_name})_diff.ghx として出力します。例えば、conflictした際に、これを使って採用版を作ったのち、 git checkout –ours target_file.ghx を発行すれば競合を解決できるかと思います。

実装としては、各コンポーネントのguidと、その定義のうち:

  • コンポーネントの通し番号の含まれる要素
  • コンポーネントの位置の含まれる要素

を除いた内容のhashのペアを作りそれを比較しています。左側にしかないguidはremoved、右側にしかなければadded、両方にあるがhashが違えばmodifiedとして、それぞれを色付きのグループでまとめ、最後に_diff.ghxとして書き出しています。grasshopperの場合、クラスターもバイナリ化されていますが文字列の状態でxmlの中に格納されていますし、GH_pythionの定義やinternalize、set valueした値もxmlの中に格納されています(当然といえば当然ですが…)のでhash化してしまうと扱いやすくて良いかと思います。このhashは下のghx_to_dot.pyでも使っています。

Test

ghx_to_dot.py

ghx_to_dot.pyはちょこっとした比較用に使うイメージで作られています。次図のようにコンポーネントの関係性をグラフとして表し、.pngで保存します。大凡どのような処理であったか、あるいは、add/stagingするべき変更なのか、など判断に使えると思っています。コンポーネントにはhashを付記できる(次図でいうpanelなどのコンポーネント名の左の「58b80…」など)ので、grasshopperでありがちな:

  • 同じ見た目のGH_pythionが複数存在してわからなくなる
  • internalizeやset valueした値が気づかないうちに更新されていた

などをチェックすることもできるかと思います。

Test

グラフとして表す処理には、pydotを使っています。dot言語はデータをグラフとして表現するために用いられる言語の一種で、Graphvizなどを使って可視化できます(pydotGraphvizを介さず直接可視化できます)。加戸は以前、伝統木造構法で設計された四脚門の部材関係をグラフ化するという研究でもdot言語/Graphvizを使ったのですが、ノードのレイアウトも自動的に行ってくれる点も楽しいです。便利で楽しいツールなので興味があればぜひ。

加戸はgrasshopper、Git/Githubともにnewbieなのでもう少し使いながらバージョンアップをしていくことを予定しています。

関連