0

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'

1 Answers1

0

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')
Juri Alb
  • 1
  • 2