2018年6月10日日曜日

【Grasshopper_08】GrasshopperとProcessingの連携方法

★OSCを使ったGrasshopperとProcessingの連携

今回のテーマはProcessing3との連携です。

Grasshopperで作成したパターンをCG的な表現で見せる場合、一旦Bakeして他の
CGソフトに渡す必要がありますが、もっとお手軽に、インタラクティブに操作ができる
方法としてProcessingと通信させる方法があります。

その際に使うのがgHowlというプラグインです。

★ウサギをGrasshopperのスライダーで動かすサンプル

試しにサンプルを作ってみました。スライダーでウサギの向きを変化させると、Processing上でウサギが追従して回転します。

Step.1 objデータの準備

・画面に表示するデータを用意します。

・データは何でも良いですが、今回はstanford bunnyと呼ばれている、CG環境のマテリアル情報の検証等で使われるデータを用意しました。
※Googleで検索するとダウンロードサイトにたどり着きます。

Step.2 ノードの作成


・上図のようなノードを組みます。

・ダウンロードしたobjデータを適当なフォルダに格納し、Rhinocerosにインポートした後、上図のMesh inputにアサインするとGrasshopperは動作します。

Step.3 Prosessingのスクリプトを組む

・スクリプトを下記のように作成します。

・各種、必要なライブラリを追加でインポートします。(やり方はGoogle検索で)

・objデータは今回作成したsketchフォルダ直下にbunny.objという名前で置きます。

以下、ソースです↓
import saito.objloader.*;
import processing.opengl.*;
import hypermedia.net.*;
import peasy.*;
PeasyCam cam;
UDP udp;
DRAW d;//DRAWクラスのインスタンスを宣言
PShape obj;
PImage img;
float angle = 0.0;
void setup() {
size(1280, 960, P3D);
noStroke();//線無し
smooth();//アンチエイリアス
/*通信の設定*/
udp = new UDP( this, 4000 );//4000番ポートで待ち状態 Grasshopper側もこれに合わせる
udp.listen( true );
d = new DRAW();//DRAWクラスのインスタンスを作成
/*カメラの設定*/
cam = new PeasyCam(this, 100);// カメラワーク操作オブジェクト。親オブジェクトと距離?を指定
cam.setMinimumDistance(10);// カメラの最小距離定義
cam.setMaximumDistance(10000);// カメラの最大距離定義
cam.setDistance(0);
frameRate(60);//フレームレートの設定
/*objファイルのインポート*/
obj = loadShape("bunny.obj");
/*原点を中心に、上向きに回転*/
obj.rotateX(radians(90));
/*objファイルの色設定*/
obj.setFill(color(200,200,200,255));//オブジェクトの色 R,G,B,α
obj.setSpecular(color(150));
obj.setShininess(20);
//obj1 = createShape(SPHERE, 200);
//obj1.setStroke(true);
//obj1.setStrokeWeight(6.0f);
}
void receive( byte[] data){ // <-- extended handler
//int time = millis();
String message = new String( data );
d.prepareData(message);//受信データを整理するメソッド
}
void draw() {
background(0);//背景を黒にリセット
/*光源の設定*/
ambientLight(20, 20, 20);//環境光(方向を持たないので陰影は付かない) R,G,B
lightSpecular(255, 255, 255);//光の鏡面反射色(ハイライト)を設定 directional lightの手前に書く
directionalLight(100, 100, 100, 0, 1, -1);//平行光(指向性がある)R,G,B,vx,vy,vz
lightFalloff(1,0,0);
translate(0,0,-1400);//初期の位置
rotateY(frameCount * 0.005);//Y軸周りに回転
/*objの描画*/
pushMatrix();//初期の位置をセット
noStroke();//線表示無し
d.rotateMesh();//回転動作
shape(obj);//objデータを表示
popMatrix();//初期位置に戻す
}
public class DRAW{
DRAW(){} //コンストラクタ
ArrayList<Vertex> v = new ArrayList<Vertex>();
/*受信データを仕分けするメソッド*/
public void prepareData(String udp_data){
ArrayList<Vertex> v_tmp = new ArrayList<Vertex>();//受信1回につき仮に格納するアレイリストのオブジェクトを作成
String lines[] = split(udp_data, '\n');//改行コードで分離して、lines配列にデータを格納
String tmpLine = "";
for(int i = 0; i < lines.length; i++){
tmpLine = lines[i];
String coords[] = tmpLine.split("x");//xで分離
Vertex vert = new Vertex(float(coords[0]), float(coords[1]), float(coords[2]), float(coords[3]));
v_tmp.add(vert);//v_temp配列にxで区切った数値を格納
}
if( v_tmp.size() == 0){v_tmp = null;}
v = v_tmp;
}
/*回転させるメソッド*/
void rotateMesh(){
//if( v == null) return;
for( Vertex vm : v ){
rotate(radians(vm.angle),vm.vx,vm.vy,vm.vz);
}
}
}
/*アレイリストで座標値を格納するためのユーザー定義のクラス*/
class Vertex{
float vx,vy,vz,angle;
Vertex(float vx, float vy, float vz, float angle){ //コンストラクタ
this.vx = vx;
this.vy = vy;
this.vz = vz;
this.angle = angle;
}
}

プログラムがエラーが発生せずに動作すると、Grasshopperのスライダーの位置に合わせてうさぎがグルグル回転します。

RhinocerosとProcessingでは座標系の向きが異なるので、合わせるのが結構面倒です・・・

0 件のコメント:

コメントを投稿

【Grasshopper_110】縦長長方形の範囲内で大きさを変化させる

今回は、縦長の四角形にひし形を配置し、真ん中より少し上の位置を基準に大きさを変化させるサンプルを作ってみました。 四角形の枠に近いところを同じ大きさに揃えるところが今回のポイントです。