3D Turtle Graphics

3Dプリンタは便利な道具である。好きなものが自由に作れる。3Dモデリングソフトを使いこなすことができれば、であるが。

使い始めの頃から123D Designというソフトを使っていたのだが、慣れるのに時間がかかり、慣れたと思ったところで提供が中止されてしまった。別のアプリを使え、ということなので推奨されたものを使ってみたものの、すんなりと使いこなせる感じではなく、習熟には多少の時間がかかりそうだった。

同じ頃、3Dプリンタを商っている知人がいて、子ども向けのワークショップもやっていた。時間の限られたワークショップで、3Dプリンタののんびりした出力を待つわけにもいかない。一部は当日出力し、参加者全員分の出力は後日という形をとったようだ。

そうなるとワークショップの中心は3Dモデリングになる。ゼロから自在に形状を作れるのがモデリングソフトの良いところだが、小学生ではなかなか操作が難しいらしく、教えるのも並大抵の苦労ではなかったという。

「モデリングソフトの習熟がボトルネックになっちゃいますね」と笑って言った。

3D Turtle Graphics

ふと思ったのは、流行りのブロック型のプログラミング環境で3Dモデリングはできないのだろうかということだった。タートルグラフィックスは、画面で(あるいは地面で)絵を描きながら幾何学について学ぶ。タートルグラフィックスの3D版があれば、三次元幾何学について学びながら自由に形状を作り上げることができるのではないか。

「3D Turtle Graphics」で検索すると、さまざまなサイトがヒットする。Python や Javascript を使ったものが良く見つかるし、おそらくProcessingを使っても似たようなことはできるだろう。とはいえ、実際のコードを見るとすぐに取り掛かりたくなるような代物ではないように見える。(個人的な偏見に聞こえるかもしれないが)

取り掛かりやすさでいえば「スクラッチのようなブロックで」と考えられるし、以前にtwitterでそのような例を見た気がするのだが、何度調べてみても到達できない。ブックマークを残さなかったことを今でも後悔している。(誰か知っていたら教えて欲しい)

そんなようなことを3Dプリンタを使い始めてしばらく後に考えていた。ブロック型の3Dモデリング環境があればいいな、なければ、作ってみようかなどと。

実際に作ってみた

コロナ禍のせいで外出制限や職場の開始時期の遅れもあり、まとまった時間ができたのでこのプロジェクトに取り掛かることにした。一番の課題は3Dの表示環境や3Dソリッドの表現方法である。OpenGL を使うつもりだったのが、どうやってもWodenがうまく使えず、何度やってもPharoごと落ちてしまうことを繰り返して挫折していた。

そこで、 OpenGL は当面あきらめてイチから3D表示環境を作ることにした。車輪の再発明である。きょうび、そこまで低レベルを詳しく解説している書籍は少ないので、書棚に埋もれていた古典的な本を掘り出して、勉強しながら改めて実装することにした。

ちなみに参考にした書籍は以下のものである。

アルゴリズムとプログラムによるコンピュータグラフィックス〈2〉 (COMPUTATION & SOFTWARE SCIENCE) (日本語) 単行本 – 1984/2
https://www.amazon.co.jp/gp/product/4895013014/

たしか学生の頃、3Dグラフィックスの学習用に買ったのだと思うが詳細は覚えていない。アルゴリズムはALGOLで書かれている。Boldの大文字プログラムに面食らうが、コードは程よく分割されていて読みやすく説明も詳しい。当時の雰囲気が感じられて読み物としても楽しい。

(当然)ALGOL ではなく Pharo Smalltalk で実装するため、説明を読んで理解して、コードを組んで確かめての繰り返しとなった。ブロック部分は今までのプロジェクトでかなりこなれてきたコードを再利用して比較的簡単に実装できた。3月中旬から3週間程度で実装したが、2週間を3Dグラフィックス部分、1週間をブロックプログラミング部分に費やした感じである。

Knead3D

これが出来上がったアプリ画面である。MicroWiz のスタイルを踏襲(コピペ)している。要はブロックで作ったコードにより作られた3Dモデルが表示される。ご覧の通りモデルはワイヤーフレームだし、陰線処理も行っていない。このあたりはいつか Woden で OpenGL が使えるようになったら置き換えればいいだろう。

スクリプトは下のようなものである。

まず2D平面上でタートルグラフィックスで線画を描き、それを版として立体を造形する。上のプログラムで作られる立体は以下のようなものだ。

このやり方でもっと複雑な形状も表現できる。例えば、造形の前に版の位置を変更して繰り返し造形すれば、回転図形も作れる。

これは10角形をベースに、少しずつ角度を変えて造形する。出来上がりはこんな感じ。

ビデオも作ってみた。

STLフォーマット

3Dプリンタで出力できるように、STL フォーマットに変換する機能を追加した。STL フォーマットにするには多角形を三角形の集合にしなければならない。複雑な形状の多角形に対応できるさまざまなアルゴリズムがあるが、ちゃんと理解できていないので、手っ取り早く凸多角形のみ対応するような実装を行った。それによって生成したSTLデータから出力したのが記事冒頭の写真である。

作ってみて

まだ複雑な形状をたくさん作ったわけではないし、自分以外の誰も使っていないので「使い勝手」的なことはよくわからない。ただ、うまくブロックを設計すれば少ないブロックで多様なものが作れそうな気がした。

一般的なモデリングツールに比べれば機能も貧弱だが、スクリプトで書かれているため何度でも作り直すことができるので失敗が怖くない。今まではうまくできた形状を維持しようと腐心していたが、試行錯誤を繰り返すのが苦でなくなった。

例のように1つのスクリプトに作り込むこともできるし、別のスクリプトにしておいて出力時に合わせることもできる。凹多角形の出力やブーリアン処理など課題は山積しているが、地道に発展させていこうと思う。

2020/8/12追記

単純多角形を三角形分割する簡単なアルゴリズムを実装したので、githubに公開した。リリースページにwindows向けバイナリを用意したのですぐに使うことができる。