3Dモデルをいろいろ作ってみたい

3Dモデルをいろいろ作ろうとがんばっています。苦労した点、役に立ちそうな情報を発信していきます。

ロボット骨格を修正、さらにアーマーを装着

試作を繰り返しながらひさびさにアーマー装着の段階までたどりついたロボットのモデルです。

Adventurer3で出力したロボット3Dモデル

ロボット骨格にアーマーを装着した状態

骨格は前回投稿したときのものを変更、強度と関節の可動域を改善しています。

Adventurer3で出力したロボット骨格とアーマー装着後

左:骨格 中:アーマー装着後(正面) 右:アーマー装着後(背面)

 

AIにロボットの顔を描いてもらう

最近、テキストを入力するとその内容にあったもっともらしい画像を生成してくれるスマホアプリやサービスが話題になってますよね。核となっている画像生成AIはStable Diffusionといわれるものでプログラムと学習済のネットワーク重みデータが公開されています。VRAM 10Gバイト以上のGPUがあれば動くということなので私のPCに導入してみました。

うまくテキストを入力してやると、意図した構図(馬に乗っている、剣を持っている)や画風(ピカソ風、鳥山明風)どおりの画像を生成できるようです。

単純に「closeup robot」と入力していみたら以下のような画像が生成されました(複数回試した中から選んでいます)。

AI(Stable Diffusion)で生成したロボットの頭部の画像

AIが出力したロボット頭部の画像

角(つの)またはアンテナを付けたような頭部が作れるかと思い「closeup robot with horn」と入力したら以下のようになりました。

AI(Stable Diffusion)で生成した「角」がついてロボットの頭部の画像

「角」つきのロボット頭部の画像

なんか「らしい」画像ができてる!

同様の原理でテキストから画像ではなくて3Dモデルデータを生成するなんていう論文もでているそうです。なかなかかっこいいロボットのデザインができないという私の悩みは近い将来AIによって解決されるかもしれません。

 

 

またまた長いお休みのあとのロボット骨格新バージョン

1年以上お休みしていたロボット骨格の作成をこの夏から再開しています。

手足の関節回りのパーツを何種類か用意しDプリントしてから、それらを組み合わせて骨格を作っています。完成形までFusion360の上で組み合わせていくよりがイメージがつきやすいかな。

Fusion360上で作成したロボット骨格の関節パーツ

関節用のパーツ

手足の末端部分は以前から使っていたものを流用、ネジは使わずシリコンチューブとPLA素材との摩擦で関節のポーズ固定を行っています。

PLAで出力したロボット骨格部品を組み立てたもの

作成したロボット骨格

赤いのは関節可動部の緩衝材に使っているシリコンチューブです。

 

Blenderを使って愛犬をモデリング

3Dプリンタを買ったときから家人からは、うちのワンコを作ってよと言われていました。プリンタを買ってからだいぶ時間もたっているしそろそろ最初の試作にチャレンジすることにしました。でもロボットや宇宙船などのメカ系と比べて動物ってより造形センスが要求される気がするんですよね。

苦肉の策でThingervirseでダックスフンドSTLデータを探してきて、それをなぞるようなかたちでローポリの3Dモデルを作成しました。

ダックスフンドの3DモデルをBlenderで作成

ダックスフンドの3Dモデル

モデリングツールはBlender Ver3.2、初めて使ってみました。将来的にZBrushで行っていたような作業はBlenderに移行しようかと迷っています。

PETGで3Dプリントしてみるとこんな感じです。

Adventure3で出力したダックスフンド

3D出力したダックス(側面から)

Adventure3で出力したダックスフンド

3D出力したダックス(斜め前から)




 

3DモデルのViewerにIM-NETのモデル生成機能を組み込む

前回のブログで「次の目標はこのViewerにIM-NETのモデル生成機能を組み込むことになります。」と書いてから早や3か月、やっとコーディングが終わりました。副業(?)のJavaScriptの仕事がちょっと忙しくなってしまい、Vue.jsとかおじさんの知らないフレームワークの勉強などしているうちに1か月ぐらいたっていたんです。副業が落ち着いたあとは1日1,2時間作業していたのですが、そのうち4分の3ぐらいは前の日にやったことを思い出すのに費やす感じで...

何はともあれ現状を報告すると、Viewerに3DモデルデータのLoad(下図の青枠ボタン)とSave(下図の赤枠ボタン)の機能を追加しいろんなフォーマットの3Dモデルの変換ができるようになりました。下図のAはMagicaVoxelのvox形式を読み込んでレゴブロック形式(水平と垂直な面だけで表現されている)もの、BはAをIN-NETのAuto Encooderで256次元ベクトルにエンコードしてから再度復元したもの、CはさらにMarching Cubeアルゴリズムで標準的なOBJ形式に変換したものです。

3Dモデルのフォーマット変換例

このBのところのLoad/SaveがこのViewerの特徴でして、64x64x64の3D形状をファイルサイズ1Kバイト(下図参照)のIM-NETエンコード結果として保存、読み込んで元の形状を復元することができます。

エンコード情報(256次元の浮動小数点数)の読み取り

さらにViewerに数式入力用のフィールド(下図の赤枠部分)を追加して形状を表現する256次元のベクトルに好みの演算を行ったうえで3Dの形状に変換できるようにしました。

エンコード結果を用いた形状のモーフィング(1)

自由な数式の入力ができるので、2つの形状間のモーフィングだけでなく以下のように3つの形状を足して3で割るといったことも可能です。デザインとして面白い形状になるかどうかは別の問題ですが...

エンコード結果を用いた形状のモーフィング(2)

新しい形状を作るのに必要なViewerとしての機能は最低限整ったと思うので、次は学習用3Dデータを増やしていくことを考えています。

 

3DモデルのViewerに機能を追加してみた

前回作成した3DモデルViewerにモデルデータのセーブの機能を追加しました。

f:id:ichidaya:20220220210448j:plain

セーブ機能つきのViewer画面

 

大きな変更点は読み込んだ3Dモデルの間でメッシュ<=>ボクセル の相互変換をできるようにして、ボクセルに変換したデータをvox形式で読み書きできるようにしたことです。メッシュ(サーフェス)からボクセルの変換はIM-NETで処理するデータを作成するのに必須の処理です。なんですが、今まで使っていたBinVoxはコマンドラインベースのツールで勝手にウィンドウを開いて処理状況を表示したりするので他のツールと組み合わせて使うのがやりにくい。vedoにもライブラリがあったのですがどうもうまく動いてくれなかったので今回はいちから実装しました。ボクセルからメッシュへの変換はVedoのライブラリの機能(おそらくMarching Cubeアルゴリズム)を利用しました。

vox形式というのはボクセルデータを扱う3DモデリングツールMagicaVoxelのファイル形式です。githubでvox形式の読み書きを行うPythonのコードを見つけて利用させていただきました(MagicaVoxelの最新版には対応してないのがちょっと残念ですが)。

f:id:ichidaya:20220221204238j:plain

MagicaVoxel画面

IM-NETで生成した3DモデルをVox形式で出力しMagicaVoxelで編集、それをIM-NETの学習に利用して新たな3Dモデルを生成する、といったワークフローを目論んでいます。

というわけで、次の目標はこのViewerにIM-NETのモデル生成機能を組み込むことになります。

 

 

vedo libraryを使って3DのViewerを作ってみた

IM-NETを使った3Dモデルの生成の可能性が確認できたところで、さらに手法をいろいろ試すためにはGUIを持ったテストベッドを用意したいと思うようになりました。まず欲しい機能としては以下の2種類の3Dデータ:

  1. ボクセルデータ(NxNxNの格子の点の有無で形を表現する、Pixelの3D版)
  2. サーフェスデータ(頂点と面の集合で形を表現する)

の表示機能です。

ボクセルデータは今までmatplotlibを使った自作プログラムで表示していたのですが、Nが大きくなると「重い」、「遅い」で非常に使いにくい。サーフェスデータの表示はMeshLabなどの既存のツールを使って表示していたのですが、複数のモデルを同時に表示しての比較がやりにくい等細かい点で自分の使い方に合わないところがあります。

じゃあ、ちょっとしたViewerを自分で作ろうか、3Dゲーム用のライブラリのPygletを使えばすぐにできるんじゃないか、と思ったのですが試してみると意外と難しい。こちらが期待するとおりの見え方にするためには投影変換(レンズの選定に相当)とビューイング変換(カメラの位置に相当)の設定を(どちらかというと低レベルの)OpenGLの機能を呼び出して行わなければならない。さらにサーフェスデータの表示(レンダリング)のためには頂点と面の情報だけでなく、各頂点ごとの法線ベクトルを呼び出し側で計算して供給してあげないといけない(無しで表示すると影がなく同じ色で塗りつぶされた全く立体感のない表示になる)。法線ベクトルの計算はやればできるけど、objやplyといったファイルフォーマットごとに頂点と面の情報を抜き出して法線を計算するコードを書くのはいかにもめんどくさい。

結局、解答として見つけたのはvedoというライブラリです。EMBL(European Molecular Biology Laboratory)という欧州19か国の出資で1974に創設された分子生物学の研究所が公開しているライブラリです。" python module for scientific analysis and visualization of эd objects"ということで研究者が自分たちで使うために作ったのではないかと推察しています。Anacondaとpipの両方でインストールできることになっていますが、私の環境ではconda installコマンドではインストールに失敗するためpipでインストールしました。

日本語のドキュメントは見つけられなかったけどapiのマニュアルと豊富なサンプルプログラムが提供されているので見よう見まねで何となくやりたいことをプログラムすることができました。PyQTと組み合わせることもできるので、ボタンや表示用のウィジェットを配置して以下のような簡易viewerを作ってみました。

f:id:ichidaya:20220118224923j:plain

vedoを使った簡易viewerの画面

ボクセルデータはnumpyファイルを読み込み後、legosurface()というメソッドでレゴブロックが並んだような形状のサーフェスデータを作って表示しています。