Backen Sie eine Textur-Map mit Python

Aug 15 2020

Ich benutze Blender 2.83. Für ein Addon (über die 3D-Ansicht zugänglich) möchte ich Texturkarten backen. Ich bin perfekt in der Lage, es ohne Skripte zu tun. Aber mit Python war ich nicht erfolgreich.

Um mein Problem auf ein Minimum zu reduzieren, beginne ich mit einem ausgewählten Objekt mit gültiger UV-Strahlung. Ich führe dann das folgende Python-Skript aus:

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)

Ich denke, was mir fehlt, ist die korrekte Verknüpfung des Bildes mit dem Texturknoten. Ich habe ähnliche Fragen wie konsultiert

Stellen Sie den aktiven Bildknoten mit Python ein

aber ihre Antworten haben nicht geholfen (Code für Blender 2.7, der nicht mehr kompatibel ist, denke ich).

Antworten

3 NoobCat Aug 22 2020 at 01:23

Ich denke, ich werde Ihnen einige grundlegende Schritte geben, dh einen Knoten vom Typ "TEX_IMAGE" hinzufügen und ihm Ihr Bild zuweisen. deshalb:

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)

Vermeiden Sie so viel wie möglich die Verwendung von bpy.ops. Wie Sie sehen, ist es in diesem Fall einfach, ein Bild mit den Methoden bpy.data.images.new () zu erstellen. Mit dieser Methode kann jedes Blender-Objekt erstellt werden.

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

bpy.ops es ist gut, es nur zu verwenden, wenn Sie keine Alternativen haben, wie in diesem Fall mit dem bpy.ops.object.bake()

Auf diese Weise können Sie etwas erstellen und es direkt einer Variablen zuweisen, wie im Beispiel von img = bpy.data.images.new()So müssen Sie nicht verrückt werden, um Zugriff darauf zu haben.