見出し画像

GrasshopperのUIを考える【Processing連携編】

少し空いてしまいました。

今回は、GrasshopperのUI(特に数値制御のSlider全般の操作)をわかりやすく構築できるかどうかについて書きたいと思います。
具体的にやったことは、ProcessingとGrasshopperを連携させ、Processing側からGrasshopperをいじる、というもの。いじるといっても数値の制御だけですが。
以下の動画のモデルを作成しました。

Grasshopperはパラメトリックなモデリングを得意としますが、
複雑なモデルなどを作っていくと、そのパラメーターが多いがためにキャンバス上のどこにどんなパラメーターがあるのかがわかりずらくなってしまうときがあります。

簡単な対処法としては、そのようなパラメーター(例えばnumber slider)が配置されているGrasshopperのキャンバスの画面を名前を付けて保存することが考えられます。
①保存したい画面の状態にして
②「目」のアイコンをクリックし、適当な名前を付けて保存
③保存したViewは「目」のアイコンの右にある小さな逆三角形から呼び出せます。

ただ、この方法ではコンポーネントを移動させた場合に、それに連動して保存したViewがついては来ないので、なかなか使いずらかったりもします。

そこで、NumberSliderなど数値を変化させるコンポーネントは、まとめて別のウィンドウから操作できれば便利?なのかもしれません。

じゃあ標準搭載の「Remote Panel」を使用すればいいじゃないか!という考えもあるかと思います。とてもとてもいいことだと思います。
しかし、もう少し自由度の高いスライダー(例えばスライダーの種類や配置する場所をカスタムすること)を作るために、ここではProcessingを使用してみたいと思います。

具体的には、Processingのライブラリである「ControlP5」を用いて、Processing上で作成したスライダーの数値をいじると、それがGrasshopperにとんでRhinoのビューポートのモデルが動くというものになります。

ここで、Grasshopperのプラグインとして必要となるものは、
gHowl」です。この中にUDP通信が可能なコンポーネントがあるので、こちらを用いてProcessingから送信したデータをGrasshopperで受信します

では、簡単に作成したものを説明します。別にProcessingと連携させる必要はないじゃん!と思う方もいるかもしれませんが、おおめに見てやってください。
①勾玉のような形状の床をRhino上で作成
②それをZ軸側に指定の数だけ複製
③各フロアの中心を基点にフロアを回転
④回転角度は各フロアの高さに比例して回転(Remapなどを用いて)
⑤最後に柱?を指定した数で作成。


下記の画像はがGrasshopperのキャンバス画面です。
左下の四角いピンク色のグループの箇所がgHowlを使用しているコンポーネントによってProcessingから数値のデータを受信し、それぞれの数値をListItemによって分けている部分です。
また、丸いピンクの部分はProcessingで受けた数値のデータがつながっているコンポーネントです。


Processingのコードです(Processing3.5.2使用)

import netP5.*;
import oscP5.*;
import controlP5.*; //ControlP5のライブラリのインポート

ControlP5 cp5;

//Slider, Knobを宣言
Slider floor_num;
Knob rotation;
Knob divide_num;

OscP5 oscP5;
NetAddress myRemoteLocation;

void setup(){
  size(600, 350);
  background(0);
  
  
  cp5 = new ControlP5(this); //ControlP5のインスタンスを作成
  
  floor_num = cp5.addSlider("floor_num") //
               .setRange(0, 15)
               .setValue(10)
               .setPosition(width/8, height/4)
               .setSize(200, 30)
               .setNumberOfTickMarks(16);
               
  rotation = cp5.addKnob("knobValue1") //
               .setLabel("rotation")
               .setRange(0, 360)
               .setValue(60)
               .setPosition(width/8, height/4*2)
               .setRadius(60);
               
  divide_num = cp5.addKnob("knobValue2") //
                .setLabel("divide_num")
                .setRange(0, 50)
                .setValue(20)
                .setPosition(width/8*5, height/4*2)
                .setRadius(60)
                .setTickMarkLength(1)
                .setNumberOfTickMarks(50)
                .snapToTickMarks(true);
   
  OscProperties oscProperties = new OscProperties();
  oscProperties.setListeningPort(12001);
  oscProperties.setDatagramSize(60000);
  oscP5 = new OscP5(this, oscProperties);
  
  myRemoteLocation = new NetAddress("127.0.0.1", 8000);
  
}

void draw() {
 
  OscMessage myMessage = new OscMessage("/test");
  
  float a = floor_num.getValue();
  float b = rotation.getValue();
  float c = divide_num.getValue();   

  myMessage.add(a)
           .add(b)
           .add(c); /* add an int to the osc message */
  oscP5.send(myMessage, myRemoteLocation); 
}

controlP5以外にも、
netP5,  oscP5のライブラリを使用します。

すみません、ひとまずここまで。
詳しいコードの説明など、
続きはまたこちらの記事上で更新するようにします。

この記事が気に入ったらサポートをしてみませんか?