MRが楽しい

MRやVRについて学習したことを書き残す

Blenderで利用可能なpythonスクリプトを作る その28(マテリアルスロットのソートと重複削除)

本日は Blender の技術調査枠です。
Blenderで利用可能なpythonスクリプトを作ります。
bluebirdofoz.hatenablog.com

マテリアルスロットのソート

オブジェクトのマテリアルスロットの順序を名前でソートします。
sort_materialslot.py

# bpyインポート
import bpy

# マテリアルスロットをソートする
# 引数   arg_objectname:指定オブジェクト名
# 戻り値
def sort_materialslot_bubble(arg_objectname='Default'):
   # 指定オブジェクトを取得する
   targetob = bpy.data.objects[arg_objectname]
   # 比較フラグ
   change_flg=True
   # 並び替えが完了するまでループ
   while change_flg:
     change_flg=False
     # マテリアルスロットを走査する
     for num in range(len(targetob.material_slots)-1):
       # マテリアル名を取得する
       checkmatname=targetob.material_slots[num].material.name
       compmatname=targetob.material_slots[num+1].material.name
       # マテリアル名を比較する
       if checkmatname > compmatname:
         # 位置を入れ替える
         targetob.active_material_index=num
         bpy.ops.object.material_slot_move(direction='DOWN')
         # 比較を継続する
         change_flg=True
   return


# 関数実行例
sort_materialslot_bubble('Cube')

f:id:bluebirdofoz:20190724092704j:plain
f:id:bluebirdofoz:20190724092716j:plain

マテリアルスロットの重複を削除

オブジェクトに同じマテリアルを参照するマテリアルスロットがあれば削除します。
マテリアルスロットは削除すると、直上のマテリアルに割り当てが統合されるので、隣り合ったマテリアルにのみ重複チェックを実施しています。
前述のマテリアルスロットのソートと組み合わせて利用すると、全ての重複が削除されます。
delate_materialslot.py

# bpyインポート
import bpy

# マテリアルスロットの重複を削除する
# 引数   arg_objectname:指定オブジェクト名
# 戻り値
def delate_materialslot_duplicate(arg_objectname='Default'):
   # 指定オブジェクトを取得する
   targetob = bpy.data.objects[arg_objectname]
   # 重複しているマテリアルスロットを削除する
   for num in range(len(targetob.material_slots)-1)[::-1]:
     # 削除処理を行うので逆順に要素を追う
     checkmatname=targetob.material_slots[num].material.name
     compmatname=targetob.material_slots[num+1].material.name
     # マテリアル名を比較する
     if checkmatname == compmatname:
       # マテリアル名が同じならば削除する
       targetob.active_material_index=num+1
       bpy.ops.object.material_slot_remove()
   return


# 関数実行例
delate_materialslot_duplicate('Cube')

f:id:bluebirdofoz:20190724092727j:plain
f:id:bluebirdofoz:20190724092736j:plain