忘却まとめ

Blenderの中級者・上級者向けの踏み込んだ情報や、アドオン・3DCGに関する情報を記事にします

Python

【Python】実用性の高いマテリアル関連のサンプルコード【Blender】- マテリアルの一括置き換え・001などの結合・空スロットを削除など

更新日:

実用性の高いマテリアル関連のサンプルコードを紹介する。
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 # マテリアル名をオブジェクト名にする

-Python
-, , , , , ,

Copyright© 忘却まとめ , 2019 All Rights Reserved Powered by STINGER.