open3dはテクスチャ付きglTFの出力に未対応?
とある案件で、open3dでglTF(glb)を出力したくなったときがあったのですが、
# テクスチャ付きメッシュ生成 mesh_textured = ... # glb形式で書き出し o3d.io.write_triangle_mesh("./output/hogehoge.glb", mesh_textured)
のようなコードでglTFを出力しようとしたときに、
[Open3D WARNING] This file format does not support writing textures and uv coordinates. Consider using .obj
のような警告が出力されてテクスチャを出力できませんでした。そんなぁ~…
(試した時のバージョンはopen3d 0.16.0)
言われた通り.obj形式で試したところ、無事テクスチャ付きのデータを出力できるようです。
でも今回出力したいのはglTFのデータ。さてどうしたものか。
trimeshを使ってみる
PythonでglTFを扱えそうなライブラリを探してみたところ、trimeshというライブラリが見つかりました。これは便利そうです!
出来上がったソースコードは以下の通り。
いったんobjファイルを出力して、それを読み込んで...ってやっているのでパフォーマンス的にはあまりよろしくありません。
(今回の私のケースではそれほど問題にならなかったのでこのままとしました)
import tempfile import os import open3d as o3d import trimesh def export_via_trimesh( o3d_mesh: o3d.geometry.TriangleMesh, file_type: str, file_path: str) -> trimesh.Trimesh: """ o3d.geometry.TriangleMeshをtrimesh経由でエクスポート """ with tempfile.TemporaryDirectory() as dname: # 1. TriangleMeshをobj形式で出力 obj_path = os.path.join(dname, "temp.obj") o3d.io.write_triangle_mesh(obj_path, o3d_mesh) # 2. 1をtrimeshで読み込み tri_mesh = trimesh.load(obj_path) # 3. 2を指定の形式で出力 tri_mesh.export(file_type=file_type, file_obj=file_path)
このように使います。
# テクスチャ付きメッシュ生成(open3d) mesh_textured = ... # glb形式で書き出し export_via_trimesh(mesh_textured, "glb", "./output/test.glb")
参考にした記事
この記事の投稿者さんのコードを参考にさせてもらいました。
(元記事の方はなぜかこのコードではうまくテクスチャ出力できなかったようですが、私のケースでは正常に動作しました)
※the incredibly ugly solutionって書きたくなるときの気持ち、すごくわかるなあ。。