実用性の高いマテリアル関連のサンプルコードを紹介する。
Blenderの標準機能では弱い一括操作系を、コピペですぐ使えるように書き残しておく。
ここで紹介する機能は、自作アドオンの All Material List のために調べて作成したものである。
もくじ
マテリアルの置き換え
特定のマテリアルの割り当てを、一括して別のマテリアルに置き換える。
対象マテリアルを事前に指定しておく。
全オブジェクトの、
マテリアルスロットの、
マテリアルから該当するマテリアルを探して
置き換える 。
import bpy # "hoge"マテリアルを、"moga"マテリアルに置き換える old = bpy.data.materials["hoge"] new = bpy.data.materials["moga"] for o in bpy.data.objects: #全オブジェクトの for m in o.material_slots: #マテリアルスロットの if m.material == old: #マテリアルから該当するマテリアルを探して m.material = new #置き換える
空スロットを除去
選択オブジェクトの、
マテリアルスロット数の、
スロットの名前がない場合は、
除去する。
import bpy for obj in bpy.context.selected_objects: # 全選択オブジェクトを対象に bpy.context.view_layer.objects.active = obj # for文を繰り返すたびにActiveオブジェクトを変更する if not len(obj.material_slots) == 0: # マテリアルスロット数が0ではない場合 for slot in obj.material_slots: # 全マテリアルスロットを対象に if slot.name == "": # スロット名がない場合 bpy.ops.object.material_slot_remove() # スロットを除去する if obj.material_slots[0].name == "": # 処理後に残ったスロットに名前がない場合 bpy.ops.object.material_slot_remove() # スロットを除去する
.001,.002などの複製したマテリアルを結合する
hoge.001, hoge.002 などを、すべて hoge と名前の付いたマテリアルに置き換えることができる。
全オブジェクトの、
マテリアルスロットの、
001などの名前が付いているマテリアルが割り当てられたスロットを、
001などの名前が付いていないマテリアルに割り当てを置き換える。
rpartitionというのが重要。
"."で文字列を分割し、[前の部分, "." , 後の部分]という形の変数にすることができる。
import bpy for obj in bpy.data.objects: # 全オブジェクトの for slot in obj.material_slots: # マテリアルスロットの中の (base, sep, ext) = slot.name.rpartition(".") # rpartitionにより、"."で文字列を分割し、[前の部分, ., 後の部分]という形の変数を用意 if ext.isnumeric(): #isnumericにより、数値かどうかを判定する if base in bpy.data.materials: # マテリアルの中の、ベースの名前に該当するものを検索する # self.report({"INFO"}, "For object "%s" replace "%s" with "%s"" % (obj.name, slot.name, base)) 通知(コンソールでselfは使えないため注意) slot.material = bpy.data.materials.get(base) # ベースに置き換える
コメントなしバージョン
import bpy for obj in bpy.data.objects: for slot in obj.material_slots: (base, sep, ext) = slot.name.rpartition(".") if ext.isnumeric(): if base in bpy.data.materials: slot.material = bpy.data.materials.get(base)
特定マテリアルのみを結合する
"hoge"マテリアルのみを対象に結合する。
import bpy for obj in bpy.data.objects: for slot in obj.material_slots: if slot.name.startswith("hoge"): (base, sep, ext) = slot.name.rpartition(".") if ext.isnumeric(): if "hoge" in bpy.data.materials: # self.report({"INFO"}, "For object "%s" replace "%s" with "%s"" % (obj.name, slot.name, "hoge")) slot.material = bpy.data.materials.get("hoge")
マテリアル名を、割り当てたオブジェクトの名前にする
選択オブジェクトの、
マテリアルを設定できるオブジェクトの、
割り当てマテリアルがある場合、
マテリアル名をオブジェクト名にする。
import bpy for obj in bpy.context.selected_objects: # 選択オブジェクトの bpy.context.view_layer.objects.active = obj # アクティブオブジェクトをfor文で繰り返すたびに切り替える if obj.type in { 'MESH' , 'CURVE' , 'SURFACE' , 'META' , 'FONT' }: # マテリアルを設定できるオブジェクトに限定する if not bpy.context.object.active_material == None: # 割り当てマテリアルがある場合 bpy.context.object.active_material.name = obj.name # マテリアル名をオブジェクト名にする