Backen Sie eine Textur-Map mit Python
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
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.