vvvvと私の博士課程

これは [vvvv Advent Calendar 2017](https://qiita.com/advent-calendar/2017/vvvv) の20日目の記事です。

---

こんにちは。高橋と申します。
つい先日、学位請求論文（いわゆる博士論文）を提出いたしました。これはつまり、博士学位に足る人間か否かを判定していただくための論文を大学に提出した、ということで、まだ手放しで喜べはしないけどとにもかくにも一区切りはついた、ということです。

さて、博士論文は「構造を書く」ことであるといわれています。
　参考：[博士論文とは「U字谷の旅」である](http://www.nakahara-lab.net/2013/07/u.html)
博士課程（あるいはそれ以前の課程）で重ねてきた研究にストーリーという構造を与えて、全体をひっくるめて自分のビジョンを示すといったところ。畢竟、私はこういうでっかいビジョンを示したいんや！そのためにコレとコレをやった！これらはこういうストーリーでつながるんです！と、そういう感じです（もちろんそんなに簡単ではありません）。
何はともあれ、僕の博士論文の中には、これまでにやってきた個々の研究内容が含まれているということです。そして、各研究ではその考え方を示すためにプロトタイプを実装しています。そのプロトタイプたちは、ほぼvvvvで実装されています。

今回は、その内容について書きたいと思います。あまり中身まで深く説明できないかもですが、技術的に参考になりそうなところをピックアップしつつ書くつもりです。

いいからパッチを寄越せ、という方にこちらを。
https://github.com/HarukiTakahashi/vvvv_Advent2017
内容物は、STLファイルの読み込みプラグイン、メッシュとカーソルのあたり判定、GUIについてさっくり、vvvvで実装したスライサです。個別の記事を書いた方が良い気も…



ご意見ご感想は以下へお願いします。
Twitter: [@kaede_tone](https://twitter.com/kaede_tone)
Email: ee97064(at)gmail.com
Web: http://haruki.xyz/

---
#はじめに
僕の博士論文のテーマは、熱溶解積層方式3Dプリンタの表現力拡張です。
「熱溶解積層方式」は3Dプリンタの方式の一つで、プラスチック樹脂を溶かして（熱溶解）ノズルから押し出して積み重ねる（積層）仕組みになります…という説明から始めるときりがないので、3Dプリンタに関する詳しい説明は、僕が2年ほど前に書いた記事やGoogle先生に委ねるとします。
　参考：[vvvvで3Dプリンタを動かす](https://qiita.com/HarukiTakahashi/items/e79a390b4071fe7a74a1)

とにかく重要なのは、**Gcodeと呼ばれる3Dプリンタの制御コードをどうやって作り出すか**です。
普通は、スライサと呼ばれるソフトウェアが3DモデルからこのGcodeを生成します（立体を高さ方向に薄く刻んでいくイメージ）。例えば、この変換中（あるいは変換後）にひと手間加えれば、3Dモデルで規定された形状とは異なるものが作れるかもしれません。Gcode自体を作れるシステムを作ってしまえば、そもそもこれまでの3Dプリンタが作りえなかったものを作れるようになるかもしれません。

こういった考え方を、熱溶解積層方式3Dプリンタの「表現力拡張」とし、一連の造形手法を構築した次第です。

#システムたち
ここでは3つのシステムを紹介します。
C#でがりがりと書いてしまうことが多いので中身はあまりvvvvライクではないのですが、各システムからいくつかの機能を抽出してパッチ化してみました。その部分に関しては、いろいろ応用ができるのではないかと思います。

本記事に関するパッチはこちらに置いてあります。
https://github.com/HarukiTakahashi/vvvv_Advent2017

##1　樹脂を溢れさせる
まずは、樹脂溢れを活用した造形手法です。
3Dプリンタはプラスチック樹脂を溶かしてノズルから押し出していくことを述べましたが、この造形の最中に3Dプリンタの動きをピタッと止めたらどうなるでしょうか？ステッピングモーターで制御されているノズルの移動は即座に停止しますが、ノズル内には樹脂を押し出すための圧力がかかっていますので、**停止中も樹脂が溢れてきてしまいます。**

表面にポコッと膨らみができてしまうので、こういう状況は可能な限り防がなければいけません。ここで、**じゃあ溢れ出す具合を制御出来たら表面のデザインに使えるじゃないか**と思ったのが僕です（そういうことばかり考えています）。以下のような具合になります。

<img src=https://qiita-image-store.s3.amazonaws.com/0/101596/0d2076a8-bc7a-0630-bd47-2c019b5f078e.png width="300">
樹脂を溢れさせた造形例

これをいろいろな造形に対してできるようにしたいなぁ、と思って実装したものが以下のシステムになります（Youtubeで字幕を付けています）。
このパッチには、**3Dモデル（STL）ファイルの読み込み**、外部のスライサで処理＆処理結果の受け取り、**3Dのドローイングシステム**、描かれた一時停止命令とスライサの処理結果とのマージが必要となります。しかし、これを全部説明しても恩恵を受ける人は少ないのではないか、と思うので、ここでは上でボールドした2点について。

[![オーバーエクストルージョン](http://img.youtube.com/vi/R-MlixZA-KE/0.jpg)](https://www.youtube.com/watch?v=R-MlixZA-KE&cc_load_policy=1)
(Youtubeで動画が開きます)

### 3Dモデルの読み込み
まずは、vvvvで3Dプリンタ用の3Dモデルフォーマットとして一般的なSTLファイルを読み込めるようなプラグインを書きます。STLにはバイナリ形式とアスキー形式があるのですが、一応どちらのファイルも読み込めるようにしてあります。
　参考：[STLファイルフォーマット](http://www.hiramine.com/programming/3dmodelfileformat/stlfileformat.html)
読み込まれた結果は、座標、法線、頂点の結合情報として出力されます。これを、VertexBufferとMesh(Join)入れてあげるとよい感じです。頂点をぐりぐりしたい（あとDX11がよくわからない）ので、DX9仕様になっております。あまり高速な処理は向かないです。誰か教えてください。

[![https://gyazo.com/865ed7629b4c26f997221f1aaa57be1e](https://i.gyazo.com/865ed7629b4c26f997221f1aaa57be1e.gif)](https://gyazo.com/865ed7629b4c26f997221f1aaa57be1e)
stlreader.v4pを実行した様子

### マウス座標とのあたり判定
あとは、この3Dモデルにマウスを乗っけた時に、どの位置に乗っているか、がわかれば簡単なドローイングシステムぐらいは作れそうです。これには、vvvvの**Intersect (EX9.Geometry Mesh)**を使います。このパッチは与えられた3Dモデル（メッシュ）とレイとが交差する点を求めるパッチですが、このレイをカメラ位置からマウスの方向に伸びている（それがメッシュにも突き抜けて行って…）という風にして交点を求めています。
なので、ViewとProjectionの行列をぐりぐりっと計算して座標系を変えてあげたりしています。気分的にLookAtとPerspectiveを使いましたが、お好みのCameraノードでもできるかと思います。

[![https://gyazo.com/49df855f1feef603b42b2d657ce4843a](https://i.gyazo.com/49df855f1feef603b42b2d657ce4843a.gif)](https://gyazo.com/49df855f1feef603b42b2d657ce4843a)
intersect.v4pを実行した様子

##2　空中に平面を作る
3Dプリンタには造形が困難な形状がいくつか存在します。例えば、オーバーハング（空中に突き出した部分）はわかりやすい例です。その部分を支えるような構造がなければ作ることができません。一方で、ぎりぎり作ることができる構造として「ブリッジ構造」があります。両端が固定されている「橋」のような形で、プラスチック樹脂がぶらんと垂れ落ちなければ、なんとか形状を維持できます。これを基礎に**造形パスを工夫して空中に平面を作ってやろう**、そして造形物をぎちぎちに詰めてまとめて造形してやろう、と考えたのが以下になります。

<img src="https://qiita-image-store.s3.amazonaws.com/0/101596/6e515a3e-a610-8b92-1378-831c58fc7af3.png" width="300">
水平面の造形と同時造形

これを活用するためのレイアウトデザインシステムが以下のシステムになります（Youtubeで字幕を付けています）。
このパッチには、3Dモデル（STL）ファイルの読み込み、レイアウト（BLF法で長方形詰め込み）、外部のスライサで処理＆処理結果の受け取り、スライサの処理結果とのマージが必要となります。しかし、これを全部説明しても恩恵を受ける人は少ないのではないか、と思うので、ここでは左側に出ている**GUI**について。
ごちゃっとしたパッチの中からどのBangだっけ…と探す作業を軽減できるというメリットもありますが、こういうメニューがあると論文中とかに乗せるときにそれっぽいので。時間があるときは簡単なものを作っています。

[![空中平面](http://img.youtube.com/vi/0SqVOh2bdys/0.jpg)](https://www.youtube.com/watch?v=0SqVOh2bdys&cc_load_policy=1)
(Youtubeで動画が開きます)

### 簡単なGUIを作る

まずは、プラグインを書く時と同様に**Template (GUI)**をクローンします。パッチ上に作られるノードを右クリックすると、デフォルトのGUIが表示されます。ボタンとチェックボックス、テキストエリア、スライダがあるものかと。それぞれを操作すると、先ほど作られたノードから操作した結果が出力されていることがわかります。

[![https://gyazo.com/09525011f9f2a0b6bb9bcf4fe4bc1bd2](https://i.gyazo.com/09525011f9f2a0b6bb9bcf4fe4bc1bd2.gif)](https://gyazo.com/09525011f9f2a0b6bb9bcf4fe4bc1bd2)
gui.v4pを実行した結果

さて、これらの中身は、**../(パッチのフォルダ)/plugins/クローンした名前/クローンした名前Node.cs**に書かれています。この.csファイルをとりあえずvvvvにドラッグアンドドロップしておいて、右クリックでエディタで開いて中身をいじります。ここからはC#（Windows.Forms）の話になります。
とはいえ、中身はそんなに難しくはないんじゃないかなぁ、と思います。InitializeComponent()でGUIコンポーネントを生成して、必要に応じてイベント用の関数を書いて（例えば、ButtonClicked()はボタンが押されたときの処理）、あとはEvaluationの中で出力につなげてあげるとパッチ上に出てきます。とても地味な作業になるので、ある程度パッチがまとまって、いくつかのボタンを押したりスライダで調整できるといいかな、ぐらいの段階になったら作ってみるとよいかもしれません。


##3　質感を制御する
3Dプリンタは「薄い」層を積み上げて造形を行っていきます。
具体的には、0.1～0.3mmぐらいの薄さになります。造形を行う際に押し出される樹脂もごくごくわずかで、それを薄っすらっと伸ばしているイメージです。では、もっと高い位置から、多めの樹脂を押し出すとどうなるでしょうか。細口のマヨネーズをぎゅぅっと押したときの状態がこれに近いのですが、「Liquid rope coiling」という現象が起こります。こうした**樹脂の振る舞いを制御しながら積層**したものが以下のくまさんになります。
　参考：[The Liquid Rope-Coil Effect (Youtube)](https://www.youtube.com/watch?v=rEkuhC9eJlM)

<img src="https://qiita-image-store.s3.amazonaws.com/0/101596/48292779-9144-f2a0-eefb-20f2405605a2.png" width="300">
もこもことした造形物をつくる
参考：[造形高さと樹脂量の設定による質感制御（Youtube）](https://www.youtube.com/watch?v=926KP1Z8-XQ)

このパラメータと造形結果の関係をひたすら調査し、それを結果を活用するためにvvvvでスライサを実装しました。
これにはvvvv的な工夫は何もありません。**ほぼ全部C#で書きました。**かなりガタガタした実装なのであらゆる3Dモデルに対応できるかは微妙なところです…

[![質感制御](http://img.youtube.com/vi/YqZMT0BIgQE/0.jpg)](https://www.youtube.com/watch?v=YqZMT0BIgQE&cc_load_policy=1)
(Youtubeで動画が開きます)

https://github.com/HarukiTakahashi/vvvv_Advent2017
には、このスライサを丸ごと突っ込みました。
基本的には、3Dモデルを読み込んで、初期化、スライスとボタンを押していくだけで大丈夫です。outputフォルダにGcodeが書き出されます。vvvvユーザでかつ3Dプリンタもいじれる方限定のニッチなプログラムですが、もし動かしていただけたら嬉しいです。

#おわりに

各システムについてしっぽり書き連ねたいところなのですが、簡単な説明とシステム（の中でもvvvv）を中心にまとめました。個人的なまとめになってしまった感がありますが、なにか情報提供できていれば幸いです。
（イベントとか大学でのゼミとか、いろいろ話せますのでなにかありましたらお誘いいただけると嬉しいです。こちらも積極的に動けるように頑張ります）

それでは。