本日はモデリング枠です。
ZBrushなどのソフトウェアで作られた3Dモデルは内部の画像フォーマットがtagが用いられていることがあります。 こういった場合は一度Blenderなどを使用してテクスチャをpngなどに書き換えなければApple製品でのAR体験時にエラーが出る可能性があります。
しかしながら、数が多い場合などはかなり面倒な作業になります。
今回はこれを自動化していきます。
〇環境
・Windows11PC
・Blender4.1
〇BlenderでUSDZモデルを読み込み出力する。
今回はusdzファイルを指定したパスからインポート→一度マテリアルのtag画像をtmpフォルダに出力、リネーム、→新しいマテリアルとして読み込み→outputフォルダに出力という形をとりました。
コードは以下です。
import bpy
import os
# --- 入力と出力のパス設定 ---
input_usdz_path = "C:~~~~○○.usdz"
output_usdz_path = "C:/~~~~○○/output_converted.usdz"
temp_folder_path = "C:/~~~~○○/tmp"
# 一時フォルダが存在しない場合は作成
if not os.path.exists(temp_folder_path):
os.makedirs(temp_folder_path)
# ログ出力
print("USDZファイルのインポートを開始: {}".format(input_usdz_path))
# USDZファイルのインポート
bpy.ops.wm.usd_import(filepath=input_usdz_path)
# マテリアルで使用されている画像を一時フォルダに保存し、pngに変換
for mat in bpy.data.materials:
if mat.use_nodes:
for node in mat.node_tree.nodes:
if node.type == 'TEX_IMAGE':
image = node.image
if image:
# 保存するファイルパス
png_image_path = os.path.join(temp_folder_path, image.name.replace('.tga', '.png'))
# 既に同じ名前のファイルが存在する場合は削除
if os.path.exists(png_image_path):
os.remove(png_image_path)
print(f"既存のファイルを削除しました: {png_image_path}")
print(f"画像保存パス: {png_image_path}")
# PNG形式で保存
try:
image.filepath_raw = png_image_path
image.file_format = 'PNG' # PNG形式で保存
image.save()
print(f"画像をPNG形式で保存しました: {png_image_path}")
except Exception as e:
print(f"画像保存中にエラーが発生しました: {e}")
continue
# 画像ファイルを再読み込み
try:
# PNGファイルを再読み込み
image = bpy.data.images.load(png_image_path) # 画像を新しく読み込む
node.image = image # ノードのテクスチャを新しく読み込んだ画像に置き換える
print(f"ノードのテクスチャをPNGに置き換えました: {png_image_path}")
except Exception as e:
print(f"画像再読み込み中にエラーが発生しました: {e}")
continue
# カメラとライトを削除
print("カメラとライトの削除を開始...")
for obj in bpy.data.objects:
if obj.type in {'CAMERA', 'LIGHT'}:
bpy.data.objects.remove(obj, do_unlink=True)
# USDZファイルのエクスポート
print("USDZファイルのエクスポートを開始: {}".format(output_usdz_path))
bpy.ops.wm.usd_export(filepath=output_usdz_path)
print("USDZファイルの画像拡張子変換とエクスポートが完了しました。")
このコードでは前述の通り処理を自動化しています。
USDZのインポートは以下のように実装しています。
bpy.ops.wm.usd_import(filepath=input_usdz_path)
これはBlenderに組み込まれているusdの機能を用いています。
https://docs.blender.org/api/current/bpy.ops.wm.html
次にマテリアルを取得し、tempフォルダに使用している画像をPNG形式で保存し再読み込みしています。
for mat in bpy.data.materials:
if mat.use_nodes:
for node in mat.node_tree.nodes:
if node.type == 'TEX_IMAGE':
image = node.image
if image:
# 保存するファイルパス
png_image_path = os.path.join(temp_folder_path, image.name.replace('.tga', '.png'))
# 既に同じ名前のファイルが存在する場合は削除
if os.path.exists(png_image_path):
os.remove(png_image_path)
print(f"既存のファイルを削除しました: {png_image_path}")
print(f"画像保存パス: {png_image_path}")
# PNG形式で保存
try:
image.filepath_raw = png_image_path
image.file_format = 'PNG' # PNG形式で保存
image.save()
print(f"画像をPNG形式で保存しました: {png_image_path}")
except Exception as e:
print(f"画像保存中にエラーが発生しました: {e}")
continue
# 画像ファイルを再読み込み
try:
# PNGファイルを再読み込み
image = bpy.data.images.load(png_image_path) # 画像を新しく読み込む
node.image = image # ノードのテクスチャを新しく読み込んだ画像に置き換える
print(f"ノードのテクスチャをPNGに置き換えました: {png_image_path}")
except Exception as e:
print(f"画像再読み込み中にエラーが発生しました: {e}")
continue
これによってtag画像が組み込まれないusdzファイルが出力されます。
以上でusdzモデルに含まれているtag画像をpng画像に書き換えることができました。