Blender Batch Lightmap Baking Script

I am currently working out a series of scripts that will allow someone to setup uv layers, and bake various map types for a large number of objects instead of doing everything by hand.

This is currently a three step process for each set of images you would like to bake.

  1. Select all meshes and run the bakesetup script. This will create the new UV layer, and a new image of the size you want. Then it will unwrap the mesh within the object.

  2. Then you will bake the selected meshes with which ever bake you are trying for. AO, full, shadow, etc.

  3. Use the imagesave script to save the images you just baked.

  4. Repeat 1-3 for each set of bakes you wanted to do. I have been baking a AO bake and a shadow bake, which I combine later.

Please pay attention to the Options at the top of each page, be sure that they are consistent between the Setup and Save script. These scripts are by no means polished or finished, but they are serviceable and do their job as this point. Hopefully, they could be useful to someone else.

Let me know if you have any questions or comments.
These scripts are not bullet proof but fairly reliable, so please save to a new file before trying. The worst that could happen is your texture maps get cleared or messed up.

I would love to have a little help figuring out the logic and error checking parts of this script to help make it a little more error proof and reliable.

import Blender
from Blender import Draw,Image,Material,Mesh,Object,Texture,Types
import bpy
import uvcalc_smart_project

######## Options to Change #########
LIGHTMAP_SIZE=1024
FILE_SUFFIX='LM'
FILE_PREFIX='A_'
UVLAYER_NAME='Lightmap'
CLEAR_UVLAYERS=0
CLEAR_IMAGES=0
####################################


BLEND_FILE=Blender.Get('filename')

print BLEND_FILE
#Get all selected objects
ob_list = Blender.Object.GetSelected()

#CLEANING THE IMAGE FILES
if CLEAR_IMAGES == 1:
    for m in ob_list:
        for f in m.getData(mesh=1).faces:
            image = None
            try: image = f.image
            except: pass
            if image:
                bImageReplacePointer = []
                replaceImage = bImageReplacePointer
                f.image = None
            
        

#Go through every object
for i in ob_list:
    mesh_data = i.getData(mesh=1)
    has_image = mesh_data.faceUV
    print '____________Working on %s ____________' % mesh_data.name
    
    #Delete all UVLayers if required
    if CLEAR_UVLAYERS==1 and mesh_data.getUVLayerNames():
        print "Cleaning out old UV layers"
        for layer in mesh_data.getUVLayerNames():
            mesh_data.removeUVLayer(layer)
            print "Deleted UVLayer: %s" % layer
    
    #Test to see if uvlayer already exists
    lm_exists = [o for o in mesh_data.getUVLayerNames() if o == UVLAYER_NAME]
    if not lm_exists:
        mesh_data.addUVLayer(UVLAYER_NAME)
        
    #Make Lightmap the active UVLayer
    mesh_data.activeUVLayer=UVLAYER_NAME
    
    #Create a new image for the faces in the object
    #See if image with name already exists
    lmimg_exists = [o.name for o in Blender.Image.Get() if o.name == FILE_PREFIX+i.name+"_"+FILE_SUFFIX ]
    print "Testing to see if image %s exists..." % lmimg_exists
    
    if lmimg_exists:
        print "Image %s alredy exists. Renaming, unlinking, and creating new image..." % (FILE_PREFIX+mesh_data.name+"_"+FILE_SUFFIX)
        Image.Get(FILE_PREFIX+i.name+"_"+FILE_SUFFIX).setName("Purged")
        
        blankImg = None
        blankImg=Image.New(FILE_PREFIX+i.name+"_"+FILE_SUFFIX,LIGHTMAP_SIZE,LIGHTMAP_SIZE,24)
        for f in mesh_data.faces:
            f.sel=1
            f.image=blankImg
        
    if not lmimg_exists:
        print "Image %s does not exist. Creating..." % (FILE_PREFIX+i.name+"_"+FILE_SUFFIX)
        blankImg=None
        blankImg=Image.New(FILE_PREFIX+i.name+"_"+FILE_SUFFIX,LIGHTMAP_SIZE,LIGHTMAP_SIZE,24)
        for f in mesh_data.faces:
            f.sel=1
            f.image=blankImg
    mesh_data.update()
    
# In uvcalc_smart_project.py, if the active object is NOT selected,
# it would be the only one processed, replacing all currently selected objects.
# Here is the stupid code :
#        ob = objects.active
#        if ob and ob.sel == 0 and ob.type == 'Mesh':
#            # Add to the list
#            obList =[ob]   <---- WT* ? "Add to the list" it says ? LOL
# So, just clear unselected active object before proceed.
objs=bpy.data.scenes.active.objects
activeObj=objs.active
if activeObj and activeObj.sel==0:
    objs.active=None
# unwrap UV, use the smart one, to minimize overlapping faces
uvcalc_smart_project.main()
####### Image Save Script ########
import Blender
from Blender import Draw,Image,Material,Mesh,Object,Texture,Types
import bpy
import uvcalc_smart_project

######## Options to Change #########
FILE_SUFFIX='AO'
FILE_PREFIX='A_'
UVLAYER_NAME='AO'
SAVE_DIR='C:\Users\Ryan\Desktop\Unity_a\Assets\Textures\\'
####################################


BLEND_FILE=Blender.Get('filename')

print BLEND_FILE
#Get all selected objects
ob_list = Blender.Object.GetSelected()

for m in ob_list:
    saved = 0
    for f in m.getData(mesh=1).faces:
        if saved == 0:
            image = f.image
            save_name = SAVE_DIR+image.name+'.tga'
            print save_name
            
            lmimg_exists = [o.name for o in Blender.Image.Get() if o.name == save_name ]
            
            if lmimg_exists:
                for h in m.getData(mesh=1).faces:
                    Image.Get(save_name).setName("Purged")
                image.setFilename(save_name)
                image.save()
                img = Image.Load(save_name)
                
            if not lmimg_exists:
                image.setFilename(save_name)
                image.save()
                img = Image.Load(save_name)

            saved = saved+1
        print img
        f.image=img
####### Image Unlinker #######

import Blender
from Blender import Draw,Image,Material,Mesh,Object,Texture,Types
import bpy
import uvcalc_smart_project


#Get all selected objects
ob_list = Blender.Object.GetSelected()

for m in ob_list:
    for f in m.getData(mesh=1).faces:
        image = None
        try: image = f.image
        except: pass
        if image:
            bImageReplacePointer = []
            replaceImage = bImageReplacePointer
            f.image = None
1 Like

Great!!! Is it compatible with blender 2.49b?Any tutorials on how use it?

So if I understand you correctly, what these scripts do is allow us to bake more than one object to a single texture? If so, I’m assuming we have to position each object’s UV’s in a separate area or does it reposition the UV maps as well? In either case this is something I might be able to use.

Can batch change shader??

Why do you need a script when Blender does it already from the render panel?