0
$\begingroup$

I'm fairly new to Blender and I've been looking for a way to bake an ao map using python with blender 3.0. I've been trying to adapt this code to the new version of blender, but I'm struggling

import bpy

ops = bpy.ops
scene = bpy.context.scene
mesh = bpy.ops.mesh

# Delete default scene objects
ops.object.select_all()
ops.object.select_all()
ops.object.delete()

# Import the model from our Three scene
ops.import_scene.obj(filepath="input.obj")

current_mesh = scene.objects[0]

# Set it to active and go into edit mode
scene.objects.active = current_mesh
ops.object.mode_set(mode='EDIT')

# Mesh cleanup step, since what's coming out of Three is mostly cubes laying side by side.

# Remove double verts...
mesh.select_mode(type="VERT")
mesh.remove_doubles()

# Merge tris into quads...
mesh.select_mode(type="FACE")
mesh.dissolve_limited()

# Remove interior faces
mesh.select_all()
mesh.select_interior_faces()
mesh.delete(type="FACE")

# Create a second UV layer for the ambient occlusion map
bpy.ops.mesh.uv_texture_add()
current_mesh.data.uv_layers[1].name = 'Shadows'

# Unwrap the mesh
mesh.select_all()
ops.uv.lightmap_pack(PREF_IMG_PX_SIZE=512)

# Create a new image to bake the lighting in to
bpy.ops.image.new(name="AO Map")
image = bpy.data.images['AO Map']

# Set the image to active (applies it to the object)
bpy.data.screens['UV Editing'].areas[1].spaces[0].image = image

# Bake the lightmap
bpy.data.scenes["Scene"].render.bake_margin = 4
bpy.data.worlds["World"].light_settings.use_ambient_occlusion = True
bpy.data.worlds["World"].light_settings.samples = 10
bpy.ops.object.bake_image()

# Save the baked image
image.filepath_raw = "output.png"
image.file_format = "PNG"
image.save()

# Save the new model with the new UV channel
ops.object.mode_set(mode='OBJECT')
bpy.ops.export.three(filepath="output.json")

For now, I replaced the 18th line by :

current_mesh = bpy.context.window.scene.objects[0]
bpy.context.view_layer.objects.active = current_mesh

there is also a problem with this line that i havent been able to solve

current_mesh.data.uv_layers[1].name = 'Shadows'
$\endgroup$

1 Answer 1

0
$\begingroup$

As you can see from bug report there is no attribute 'image' in 'SpaceOutliner'. So maybe it's more simple to use nodes? you can connect texture via node and start to bake. For node connection you can read example here. Connecting a texture node to a material node via the Blender Python API for Blender 2.82

Something like this

mat = current_mesh.active_material
mat.use_nodes = True
matnodes = mat.node_tree.nodes

tex = matnodes.new('ShaderNodeTexImage')
img = image
tex.image = img

disp = matnodes['Material Output'].inputs[2]
mat.node_tree.links.new(disp, tex.outputs[0])

Also maybe instead this

    # Bake the lightmap
bpy.data.scenes["Scene"].render.bake_margin = 4
bpy.data.worlds["World"].light_settings.use_ambient_occlusion = True
bpy.data.worlds["World"].light_settings.samples = 10
bpy.ops.object.bake_image()

Use this

bpy.context.scene.render.engine = 'CYCLES'
bpy.ops.object.bake(type='AO')
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .