Запекать текстурную карту с питоном
Я использую Blender 2.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 больше не совместим).
Ответы
Думаю, я дам вам несколько основных шагов, то есть добавлю узел типа «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 () С помощью этого метода можно создать любой объект блендера.
bpy.data.objects.new()
bpy.data.materials.new()
bpy.data.scenes.new()
...
...
bpy.ops его хорошо использовать только тогда, когда у вас нет альтернатив, как в этом случае с bpy.ops.object.bake()
это позволяет вам создавать что-то и напрямую присваивать это переменной, как в примере img = bpy.data.images.new()
Итак, вам не нужно сходить с ума, чтобы получить к нему доступ.