Fusion360の3DオブジェクトをopenFrameworksへ
お久しぶりです。
今回は、Fusion 360で作成した実寸大の3Dモデルを寸法を保ったままopenFrameworksに取り込む方法を取り上げたいと思います。
3Dオブジェクトを気軽に作成できるツールとして、Fusion 360があり、特に学生などの教育関係者や、フリーランサーは無料でライセンスを取得できることもあり、重宝しているツールの一つです。
Unityなどで3Dオブジェクトを作成する場合も多いですが、Unityなどと違ってCADソフトなので、実寸台でオブジェクトをしっかり作り込むことができます。自分が所属しているMUDSでもUnityを使って3Dオブジェクトを作っている学生が多いですが、個人的にFusion 360を推しています。
で、本題としては、そのFusion 360で作成したオブジェクトをいい感じにopenFrameworksに寸法通りに取り込みたい、ということです。
ただ、普通に取り込もうとしても取り込めません。理由として2つほど挙げられ、1つめはopenFrameworks上で勝手にスケーリングされること、2つめはFusion 360では何mmや何cmなどの単位でやり取りされていたものを何pxに変換しなければならないことです。
と、その前に基本動作のおさらいです。Fusion 360上でオブジェクトを作成し、.obj
形式で出力してあげます。その.obj
ファイルをopenFrameworksのプロジェクトフォルダ内、bin/data
フォルダに格納します。
サンプルとして、GitHub上にFusion 360アーカイブファイルと.obj
ファイルを掲載しているので、参考までにどうぞ。
そしたら、ヘッダーファイル (ofApp.h
)内に3Dオブジェクトを取り込むための拡張機能、ofxAssimpModelLoader
をインポートし、別途宣言も書いてあげます。適宜カメラに関しても宣言を書きましょう。
#include "ofxAssimpModelLoader.h"
// 中略
ofEasyCam cam;
ofxAssimpModelLoader cubes_model;
そしたら、次にメインのファイルであるofApp.cpp
にモデルを読み込んで可視化するコードを記入します。ついでにわかりやすいように、10px幅のグリッドも描画しておきましょう。
void ofApp::setup(){
cubes_model.loadModel("cubes.obj");
}
// 中略
void ofApp::draw(){
cam.begin();
ofDrawGrid(10, 20, true);
cubes_model.drawWireframe();
cam.end();
}
そうすると3Dオブジェクトが描画されたと思います。そしたらまず1点目の問題である、勝手にスケーリングされる問題について。
今回GitHub上に掲載しているサンプルオブジェクトでは、1辺1mの立方体を4x4で並べたものですが、上の画像をよく見るとわかるように、グリッドとオブジェクトがあってませんね。これは、openFrameworks側で自動でスケーリングをかけているからです。cubes_model.getNormalizedScale()
の出力をプリントしてあげると0.128
と出力されていることからわかるように、勝手にスケーリングされています。このスケーリングを止めるために、下記のようにファイルを書き換えます。
void ofApp::setup(){
cubes_model.loadModel("cubes.obj");
// 追記ここから
cubes_model.setScaleNormalization(false);
// 追記ここまで
}
setScaleNormalization
をfalse
に設定してあげることによって、自動でスケーリングされるのを防止します。すると超巨大になったかと思います。そこで2点目の問題であるメートル法 to pixelをどうするのか、という問題を解消していきます。
Fusion 360のサンプルデータでは、1mm1pxで.obj
ファイルに変換されています。これは詳しく検証したわけではありませんが、Fusion 360ファイル内の標準単位の1単位分が1pxになっているようです。スケーリングを厳密に確認したい際には、適当な大きさの立方体を作成したものを.obj
に出力して、確認するようにしてください。今回は1mmが1px、つまり1mは1000pxになっています。これは巨大すぎるので、1mを10pxの縮尺、つまり1/100に変換していきたいと思います。
void ofApp::setup(){
cubes_model.loadModel("cubes.obj");
cubes_model.setScaleNormalization(false);
// 追記ここから
cubes_model.setScale(.01, .01, .01);
// 追記ここまで
}
このようにすると、x, y, z軸全て1/100に変換したことになり、実際の画面でも10pxに四角がおさまっているのがわかりますね。
このような形でFusion 360からopenFrameworksに寸法を保ったままオブジェクトを挿入できました。この方法でARやVRの作品をFusion 360とopenFrameworksで制作する際、かんたんにFusion 360でモデルを作成してopenFrameworksに取り込むことができるようになります。
今回のプロジェクト用GitHubレポジトリはこちらに掲載しています。GitHub上では、openFrameworksとmax/mspを連携させてカメラを操作できるようにするデモ用のソースコードも含まれていますので参考までに。
Discussion