Pythonでテクスチャマップをベイクします

Aug 15 2020

私はBlender2.83を使用しています。アドオン(3D-Viewからアクセス可能)の場合、テクスチャマップをベイク処理したいと思います。私はスクリプトなしでそれを完全に行うことができます。しかし、Pythonでは私は成功しませんでした。

問題を最小限に抑えるために、有効なUVを持つ選択されたオブジェクトから始めます。次に、次のPythonスクリプトを実行します。

import bpy

obj = bpy.context.active_object

# Creating a texture node, linked with a new image
mat = obj.data.materials[0]
mat.use_nodes = True
texImage = mat.node_tree.nodes.new('ShaderNodeTexImage')
img = bpy.ops.image.new(name= obj.name + '_BakedTexture')
texImage = img

# !!! No image is linked to the texture node !!!

# Baking to the newly created image
# The following part works if I create the texture node and the assigning of the image by hand
bpy.context.view_layer.objects.active = obj
bpy.ops.object.bake(type='DIFFUSE', save_mode='EXTERNAL', filepath='C:\\TEMP\\baked.png', use_automatic_name=True, width=512, height=512)

私が見逃しているのは、画像とテクスチャノードの正しいリンクだと思います。私は次のような同様の質問を参考にしました

Pythonでアクティブな画像ノードを設定する

しかし、彼らの答えは役に立ちませんでした(互換性がなくなったBlender 2.7のコードだと思います)。

回答

3 NoobCat Aug 22 2020 at 01:23

基本的な手順をいくつか紹介します。つまり、「TEX_IMAGE」タイプのノードを追加し、それに画像を割り当てます。したがって:

obj = bpy.context.active_object
# You can choose your texture size (This will be the de bake image)
image_name = obj.name + '_BakedTexture'
img = bpy.data.images.new(image_name,1024,1024)

   
#Due to the presence of any multiple materials, it seems necessary to iterate on all the materials, and assign them a node + the image to bake.
for mat in obj.data.materials:

    mat.use_nodes = True #Here it is assumed that the materials have been created with nodes, otherwise it would not be possible to assign a node for the Bake, so this step is a bit useless
    nodes = mat.node_tree.nodes
    texture_node =nodes.new('ShaderNodeTexImage')
    texture_node.name = 'Bake_node'
    texture_node.select = True
    nodes.active = texture_node
    texture_node.image = img #Assign the image to the node
    
bpy.context.view_layer.objects.active = obj
bpy.ops.object.bake(type='DIFFUSE', save_mode='EXTERNAL')

img.save_render(filepath='C:\\TEMP\\baked.png')
    
#In the last step, we are going to delete the nodes we created earlier
for mat in obj.data.materials:
    for n in mat.node_tree.nodes:
        if n.name == 'Bake_node':
            mat.node_tree.nodes.remove(n)

bpy.opsの使用はできるだけ避けてください。この場合、ご覧のとおり、bpy.data.images.new()メソッドを使用して画像を簡単に作成できます。このメソッドを使用して任意のBlenderオブジェクトを作成できます。

bpy.data.objects.new()
bpy.data.materials.new()
bpy.data.scenes.new()
...
...

bpy.opsこの場合のように、代替手段がない場合にのみ使用することをお勧めします。 bpy.ops.object.bake()

これにより、次の例のように、何かを作成して変数に直接割り当てることimg = bpy.data.images.new()ができます。そのため、アクセスするために夢中になる必要はありません。