iPhone の Reality Composer で作成した usdz ファイルの images の名前が一緒で、複数のモデルを同じシーンで扱いづらいので、ファイル名を変えたい
Blender の cli でリネーム対応と FBX 書き出しを試す
data.images の各 image のリネーム
一旦これでやりたいことはできた
import bpy
import os
# 事前に読み込みなどを済ませる
# 一旦保存して unpack して画像を取り出し、別名で保存した後 pack
# XXX: もっといいやり方があるかも
def rename_images(name):
bpy.ops.wm.save_as_mainfile(filepath = './tmp.blend')
bpy.ops.file.unpack_all(method='WRITE_LOCAL')
# XXX: bpy.data.images をそのままループで使ったらなぜか無限ループになってこれで解決したけどよくわかってない・・
images_name_list = [o.name for o in bpy.data.images if not o.filepath == '']
for i, image_name in enumerate(images_name_list):
image = bpy.data.images[image_name]
new_name = name + '_' + str(i + 1)
image.name = new_name
new_filepath = './' + new_name + '.png'
image.save(filepath=new_filepath)
image.filepath = new_filepath
image.reload()
image.pack()
os.remove(filepath)
print('image renamed: ' + image_name + ' => ' + new_name)
os.remove('./tmp.blend')
コード全体
rename.py
import bpy
import os
def import_usdz(path):
bpy.ops.wm.usd_import(filepath=path)
def rename(name):
rename_images(name)
rename_materials(name)
rename_objects(name)
def rename_images(name):
bpy.ops.wm.save_as_mainfile(filepath = './tmp.blend')
bpy.ops.file.unpack_all(method='WRITE_LOCAL')
images_name_list = [o.name for o in bpy.data.images if not o.filepath == '']
for i, image_name in enumerate(images_name_list):
image = bpy.data.images[image_name]
new_name = name + '_' + str(i + 1)
image.name = new_name
new_filepath = './' + new_name + '.png'
image.save(filepath=new_filepath)
image.filepath = new_filepath
image.reload()
image.pack()
os.remove(new_filepath)
os.remove('./tmp.blend')
def rename_materials(name):
materials = [o for o in bpy.data.materials if not o.name == 'Dots Stroke']
for i, material in enumerate(materials):
new_name = name + '_' + str(i + 1)
material.name = new_name
def rename_objects(name):
objects = [o for o in bpy.data.objects if o.type == "MESH"]
for i, object in enumerate(objects):
new_name = name + '_' + str(i + 1)
object.name = new_name
object.data.name = new_name + '_mesh'
def cleanup():
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
for block in bpy.data.meshes:
if block.users == 0:
bpy.data.meshes.remove(block)
for block in bpy.data.materials:
if block.users == 0:
bpy.data.materials.remove(block)
for block in bpy.data.textures:
if block.users == 0:
bpy.data.textures.remove(block)
for block in bpy.data.images:
if block.users == 0:
bpy.data.images.remove(block)
def save_blend(path):
bpy.ops.wm.save_as_mainfile(filepath=path)
bpy.ops.file.unpack_all(method='WRITE_LOCAL')
def export_fbx(path):
bpy.ops.export_scene.fbx(
filepath=path,
apply_scale_options='FBX_SCALE_ALL',
path_mode='COPY',
embed_textures=False,
)
cleanup()
import_usdz('./src/model1.usdz')
rename('model1')
save_blend('./output/model1.blend')
export_fbx('./output/model1.fbx')
cleanup()
import_usdz('./src/model2.usdz')
rename('model2')
save_blend('./output/model2.blend')
export_fbx('./output/model2.fbx')
実行
/Applications/Blender.app/Contents/MacOS/Blender --background --python rename.py