Fusion360の3DオブジェクトをopenFrameworksへ

2022/08/22に公開

お久しぶりです。

今回は、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をインポートし、別途宣言も書いてあげます。適宜カメラに関しても宣言を書きましょう。

ofApp.h
#include "ofxAssimpModelLoader.h"

// 中略

ofEasyCam cam;
ofxAssimpModelLoader cubes_model;

ソースコード

そしたら、次にメインのファイルであるofApp.cppにモデルを読み込んで可視化するコードを記入します。ついでにわかりやすいように、10px幅のグリッドも描画しておきましょう。

ofApp.cpp
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と出力されていることからわかるように、勝手にスケーリングされています。このスケーリングを止めるために、下記のようにファイルを書き換えます。

ofApp.cpp
void ofApp::setup(){
    cubes_model.loadModel("cubes.obj");
    // 追記ここから
    cubes_model.setScaleNormalization(false);
    // 追記ここまで
}

ソースコード

setScaleNormalizationfalseに設定してあげることによって、自動でスケーリングされるのを防止します。すると超巨大になったかと思います。そこで2点目の問題であるメートル法 to pixelをどうするのか、という問題を解消していきます。

Fusion 360のサンプルデータでは、1mm1pxで.objファイルに変換されています。これは詳しく検証したわけではありませんが、Fusion 360ファイル内の標準単位の1単位分が1pxになっているようです。スケーリングを厳密に確認したい際には、適当な大きさの立方体を作成したものを.objに出力して、確認するようにしてください。今回は1mmが1px、つまり1mは1000pxになっています。これは巨大すぎるので、1mを10pxの縮尺、つまり1/100に変換していきたいと思います。

ofApp.cpp
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 x openFrameworks x max/msp 3D Object Mapping in scale

このような形でFusion 360からopenFrameworksに寸法を保ったままオブジェクトを挿入できました。この方法でARやVRの作品をFusion 360とopenFrameworksで制作する際、かんたんにFusion 360でモデルを作成してopenFrameworksに取り込むことができるようになります。

今回のプロジェクト用GitHubレポジトリはこちらに掲載しています。GitHub上では、openFrameworksとmax/mspを連携させてカメラを操作できるようにするデモ用のソースコードも含まれていますので参考までに。

Discussion