ZBrushからエクスポートした.objファイル調べてみた+ブーリアンやってみた

この記事は、以下のようなものを含んでいます

  • ZBrushから書き出した.objファイルの調査
  • ポリグループを保存したままブーリアン計算
はじめに

私個人はもともと3D関係の研究者なのですが、最近ZBrushを触ることが多くなり(主に触っているのはZBrushの姉妹ソフトのZBrush Coreです)、さらに、ZBrushアーティストの方とお話させて頂くこともちらほら増えてきました。なので、せっかくなら私の持っている知識で何かアーティストの人の役に立てればなぁ、ということでZBrushから書き出した.objファイルについて調べてみました。

今回調べようと思ったきっかけは、ZBrush上で形状を.objにエクスポートしたあと、そのファイルを再度ZBrushでインポートすると、ポリグループが保存されたままインポートできていたのが少し不思議だったからです。.objファイルは、基本的にはジオメトリを保存する形式ですが、ポリゴン単位でグループ分けすることができるのでそれを使って実現しているのかな?とは思いましたが実際にどうしているかは確認してみないとわかりません。そこで、今回、どのようにしてポリグループが保存されているのかということに重点を置いて調べてみました。

あと、もし.objファイルの標準機能であるグループ機能で実現されているなら外部ツールでポリグループを保存したまま処理するみたいな夢が広がりますし。

ファイルの歴史や、一般的な説明はwikipediaをどうぞ。

ZBrushから書き出した.objファイルの調査

早速、ZBrushから.obj形式でエクスポートを行ってみます。今回は記事公開時点で最新版のZBrush 2018.1を利用しています。

まずはZBrushからエクスポートされる.objファイルの構造を知るために、極限までシンプルなメッシュを作成して書き出します。というわけで、サクッと立方体を用意してエクスポート。

※ポリフレーム表示です。6面しか無いのであまり意味はないですが…

書き出したあとの.objファイルを一般的なテキストエディタで開いて中身を確認してみます。.objファイルはテキスト形式なので楽でいいですね。(plyやstlだとバイナリで保存することもできるので中身を確認するのが面倒なことがあります)

予想通り、 g ZBrush_default_group という、グループに関する記述がありますね。では、続いて、複数ポリグループが存在するものを用意してみます。今回は立方体2つが(バラバラのメッシュとして)突き刺さっているものを用意しました。

こちらも同様に、テキストエディタで開いて確認してみます。

予想的中です。2つの立方体が g Group29455 と g Group29470 という2つのグループに分けられています。

最後に、dynameshを使って一つに融合したあともきちんとポリグループが別れているのかを確認してみます。

ポリグループの色が変わっていますが、深い意味は無いので無視してください

dynamesh解像度を最低に設定したのですが、メッシュ数が増えすぎてしまったので、.objファイルをテキストファイルで開いて目で確認するのはちょっとつらいです。なので、サクッとコマンドでグループを確認することにします。

こちらもやはり、 g Group29455 と g Group29470 という2つのグループに分けられていることがわかりました。

ということは、.objファイルのグループを適切に保持してあげれば、外部ツールでポリグループの状態を保持したまま編集ができるということになります。これは、

  1. ZBrushでエクスポート
  2. 外部ツールで.objのグループを保持したまま編集
  3. ZBrushにインポート

という手順で作業することで、ZBrushに無い様々な処理ができるようになるということを意味していて、非常に夢が広がります。

ZBrushだけでブーリアンを計算する (dynamesh)

ZBrushで作成した作品を3Dプリントする場合は、3Dプリント時のスライス処理が失敗しないようにすべてのサブツールを1つのメッシュに融合するということが多々あります。そして、その際には、dynameshで融合するのが一般的なようです。しかし、これにはどうしても避けられない問題が残っています。例えば、以下のようなサブツール2つのメッシュを1つに融合することを考えてみます。

この際、普通にdynameshで融合すると、境界部分が以下のように鈍い感じになってしまいます。本当はシャープにパリッと融合してほしいのですが…。

このような問題に対応するために、投影という機能をONにしてdynameshを計算するという対処法があります。投影をONにして、サブ投影のパラメタを1にした場合は以下のように、シャープにパリッとした仕上がりになります。(ポリグループの境界線は何故かガタガタになってしまっていますが)

しかし、投影を利用した場合は、メッシュ数が爆発的に増えるという欠点があります。更に、投影を使う場合は計算が非常に重たいという欠点まであります。

ポリグループを保存したままブーリアンを計算

というわけで、今回はポリグループを保存したままブーリアンを計算してみました。dynameshでの融合と比較すると下記の表のようになります。

dynamesh dynamesh(投影あり) 今回の方法
元の形状に忠実? 忠実ではない ほぼ忠実 完璧に忠実
メッシュの重さ(ポリゴン数) 軽い 重い 軽い
処理時間 短い 長い 長い

今回行った方法は、元の形状を完璧に保存します。dynamesh(投影あり)は少しだけ形が変わったりしますが、今回の方法では(浮動小数点の精度で)完璧に同一です。更に、dynameshで問題となることが多い、メッシュの重さ(ポリゴン数)に関しても(元の特徴を完璧の保持した上で、)できうる限り軽くなります。反面、計算の処理時間はそれ相応に時間がかかることになります。(投影ありの場合との処理時間の優劣は検証していないのでわからないですが…)

(3Dプリント用に書き出すときはポリグループ保存してなくていいという気もしますが、もし書き出してる最中に少しだけ修正したくなったりしたらポリグループが残っている方が嬉しいですしね。)

技術的には、2016年に発表された論文”Mesh arrangements for solid geometry”(web)に記載されている手法を利用してメッシュのブーリアンを計算して融合しています。より具体的には、libigl(github)に実装されているブーリアン操作を直接利用しています。

計算結果を再度ZBrushにインポートした結果が以下の画像です。

結果は一目瞭然で、境界部分の形状はパリッとシャープに接続している上に、ポリグループの境界も意図通りのものになっています。

次に、同じくらいの見た目の場合にどのくらいポリゴン数が変わってくるのかを確認してみます。dynamesh解像度はシーンに対して設定するものであるので、解像度が同じでもメッシュのサイズが違うとメッシュの密度が変わってきてしまいます。そこで、(私の主観ですが、)だいたい同じ位のメッシュ密度になるdynamesh解像度を探して、ポリゴン数の比較をしてみます。今回は大体、dynamesh解像度64くらいで投影なしの場合が同じような見た目になりました。(解像度が同じでも、投影の有無でメッシュの密度って変わるんですね。知りませんでした。)

dynamesh(解像度64) dynamesh(投影あり・解像度64) 今回の方法
ポリゴン数 7048 38343 5297

投影ありの場合のポリゴン数の増え方がえげつないです…。今回の方法はポリゴン数が一番少ないので、3Dプリントする際に、スライス計算がすごく早くなることが予想されます。(あと、何より、ファイルサイズが小さいので取扱がしやすいです。)

今回行った方法は、「元の形状に忠実で軽いメッシュを生成できる」ことに加えて、「ローポリゴンの場所はできる限りローポリゴンのまま保持する」という強みも持っています。その検証のため、以下のようなメッシュを融合することを試してみます。

みんな大好きスタンフォードバニー on 立方体

dynamesh, dynamesh(投影あり), 今回の方法の結果と、ポリゴン数の比較は以下のとおりです。

dynamesh dynamesh(投影あり) 今回の方法
ポリゴン数 24983 76661 43108

この例では今回の方法がdynameshよりも多いポリゴン数になっていますが、バニーに相当する部分だけで42616ポリゴンあるので、できる限り元の形状に忠実という前提条件のもとでは、できうる限り軽いメッシュになっていると言えます。更に、一番右のメッシュだけ、立方体がローポリゴンのまま保存されています。

おわりに

ZBrushからエクスポートした.objファイルの中身を調べたところ、.objファイルの標準機能である、グループ機能を利用してZBrushのポリグループが保存されているということがわかりました。

.objファイルに保存されているポリグループの情報を活用する一例として、3DCG研究の分野で一般的に利用されているメッシュの融合処理を実際に行ってみました。これはdynameshと異なり、元の形状を完璧に保持する一方、できうる限り軽いメッシュを生成するものであるため、「できる限り元の形状を保持しつつ、できる限り軽いメッシュになるよう融合したい」という要求がある場合にピッタリの方法だと言えます(例えば3Dプリントのためにサブツールを融合するときなど)。

今回の計算方法については、GUIもすでに作成済みなので、もし需要が大きいようなら適切に調整をしたあと公開する予定です。(もし公開するのならば、ダウンロードしてきてダブルクリックしたらすぐに動くっていう状態で公開したい)