iPhone の Reality Composer で作成した複数の usdz を Blender や Unity 上で扱いやすくする

iPhone の Reality Composer で作成した usdz ファイルの images の名前が一緒で、複数のモデルを同じシーンで扱いづらいので、ファイル名を変えたい
![Screenshot 2023-11-28 at 17.37.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191702/dbbbbf9f-72af-af35-b536-1993b09dff4c.png)

Blender の cli でリネーム対応と FBX 書き出しを試す

## data.images の各 image のリネーム
一旦これでやりたいことはできた
```python
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')
```


## コード全体
```python: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')
```

実行

```bash
/Applications/Blender.app/Contents/MacOS/Blender --background --python rename.py
```

実行すると、テクスチャの被りなく表示ができる
blender
![Screenshot 2023-11-29 at 15.17.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191702/ad918528-10c5-d67b-22c4-6d756ef8775b.png)

Unity
![Screenshot 2023-11-29 at 15.19.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191702/d0adf110-68f7-ce77-e028-165147f5eccf.png)