407 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			407 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| 
								 | 
							
								import bpy
							 | 
						||
| 
								 | 
							
								from bpy.types import Menu, Panel, UIList
							 | 
						||
| 
								 | 
							
								from bpy.props import *
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								from lnx.lightmapper import operators, properties, utility
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import lnx.assets
							 | 
						||
| 
								 | 
							
								import lnx.utils
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if lnx.is_reload(__name__):
							 | 
						||
| 
								 | 
							
								    lnx.assets = lnx.reload_module(lnx.assets)
							 | 
						||
| 
								 | 
							
								    lnx.utils = lnx.reload_module(lnx.utils)
							 | 
						||
| 
								 | 
							
								else:
							 | 
						||
| 
								 | 
							
								    lnx.enable_reload(__name__)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LnxBakeListItem(bpy.types.PropertyGroup):
							 | 
						||
| 
								 | 
							
								    obj: PointerProperty(type=bpy.types.Object, description="The object to bake")
							 | 
						||
| 
								 | 
							
								    res_x: IntProperty(name="X", description="Texture resolution", default=1024)
							 | 
						||
| 
								 | 
							
								    res_y: IntProperty(name="Y", description="Texture resolution", default=1024)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LNX_UL_BakeList(bpy.types.UIList):
							 | 
						||
| 
								 | 
							
								    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
							 | 
						||
| 
								 | 
							
								        # We could write some code to decide which icon to use here...
							 | 
						||
| 
								 | 
							
								        custom_icon = 'OBJECT_DATAMODE'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Make sure your code supports all 3 layout types
							 | 
						||
| 
								 | 
							
								        if self.layout_type in {'DEFAULT', 'COMPACT'}:
							 | 
						||
| 
								 | 
							
								            row = layout.row()
							 | 
						||
| 
								 | 
							
								            row.prop(item, "obj", text="", emboss=False, icon=custom_icon)
							 | 
						||
| 
								 | 
							
								            col = row.column()
							 | 
						||
| 
								 | 
							
								            col.alignment = 'RIGHT'
							 | 
						||
| 
								 | 
							
								            col.label(text=str(item.res_x) + 'x' + str(item.res_y))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        elif self.layout_type in {'GRID'}:
							 | 
						||
| 
								 | 
							
								            layout.alignment = 'CENTER'
							 | 
						||
| 
								 | 
							
								            layout.label(text="", icon=custom_icon)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LnxBakeListNewItem(bpy.types.Operator):
							 | 
						||
| 
								 | 
							
								    # Add a new item to the list
							 | 
						||
| 
								 | 
							
								    bl_idname = "lnx_bakelist.new_item"
							 | 
						||
| 
								 | 
							
								    bl_label = "Add a new item"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def execute(self, context):
							 | 
						||
| 
								 | 
							
								        scn = context.scene
							 | 
						||
| 
								 | 
							
								        scn.lnx_bakelist.add()
							 | 
						||
| 
								 | 
							
								        scn.lnx_bakelist_index = len(scn.lnx_bakelist) - 1
							 | 
						||
| 
								 | 
							
								        return{'FINISHED'}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LnxBakeListDeleteItem(bpy.types.Operator):
							 | 
						||
| 
								 | 
							
								    # Delete the selected item from the list
							 | 
						||
| 
								 | 
							
								    bl_idname = "lnx_bakelist.delete_item"
							 | 
						||
| 
								 | 
							
								    bl_label = "Deletes an item"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    @classmethod
							 | 
						||
| 
								 | 
							
								    def poll(self, context):
							 | 
						||
| 
								 | 
							
								        """ Enable if there's something in the list """
							 | 
						||
| 
								 | 
							
								        scn = context.scene
							 | 
						||
| 
								 | 
							
								        return len(scn.lnx_bakelist) > 0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def execute(self, context):
							 | 
						||
| 
								 | 
							
								        scn = context.scene
							 | 
						||
| 
								 | 
							
								        list = scn.lnx_bakelist
							 | 
						||
| 
								 | 
							
								        index = scn.lnx_bakelist_index
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        list.remove(index)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if index > 0:
							 | 
						||
| 
								 | 
							
								            index = index - 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        scn.lnx_bakelist_index = index
							 | 
						||
| 
								 | 
							
								        return{'FINISHED'}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LnxBakeListMoveItem(bpy.types.Operator):
							 | 
						||
| 
								 | 
							
								    # Move an item in the list
							 | 
						||
| 
								 | 
							
								    bl_idname = "lnx_bakelist.move_item"
							 | 
						||
| 
								 | 
							
								    bl_label = "Move an item in the list"
							 | 
						||
| 
								 | 
							
								    direction: EnumProperty(
							 | 
						||
| 
								 | 
							
								                items=(
							 | 
						||
| 
								 | 
							
								                    ('UP', 'Up', ""),
							 | 
						||
| 
								 | 
							
								                    ('DOWN', 'Down', ""),))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def move_index(self):
							 | 
						||
| 
								 | 
							
								        # Move index of an item render queue while clamping it
							 | 
						||
| 
								 | 
							
								        obj = bpy.context.scene
							 | 
						||
| 
								 | 
							
								        index = obj.lnx_bakelist_index
							 | 
						||
| 
								 | 
							
								        list_length = len(obj.lnx_bakelist) - 1
							 | 
						||
| 
								 | 
							
								        new_index = 0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if self.direction == 'UP':
							 | 
						||
| 
								 | 
							
								            new_index = index - 1
							 | 
						||
| 
								 | 
							
								        elif self.direction == 'DOWN':
							 | 
						||
| 
								 | 
							
								            new_index = index + 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        new_index = max(0, min(new_index, list_length))
							 | 
						||
| 
								 | 
							
								        obj.lnx_bakelist.move(index, new_index)
							 | 
						||
| 
								 | 
							
								        obj.lnx_bakelist_index = new_index
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def execute(self, context):
							 | 
						||
| 
								 | 
							
								        obj = bpy.context.scene
							 | 
						||
| 
								 | 
							
								        list = obj.lnx_bakelist
							 | 
						||
| 
								 | 
							
								        index = obj.lnx_bakelist_index
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if self.direction == 'DOWN':
							 | 
						||
| 
								 | 
							
								            neighbor = index + 1
							 | 
						||
| 
								 | 
							
								            self.move_index()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        elif self.direction == 'UP':
							 | 
						||
| 
								 | 
							
								            neighbor = index - 1
							 | 
						||
| 
								 | 
							
								            self.move_index()
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            return{'CANCELLED'}
							 | 
						||
| 
								 | 
							
								        return{'FINISHED'}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LnxBakeButton(bpy.types.Operator):
							 | 
						||
| 
								 | 
							
								    '''Bake textures for listed objects'''
							 | 
						||
| 
								 | 
							
								    bl_idname = 'lnx.bake_textures'
							 | 
						||
| 
								 | 
							
								    bl_label = 'Bake'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def execute(self, context):
							 | 
						||
| 
								 | 
							
								        scn = context.scene
							 | 
						||
| 
								 | 
							
								        if len(scn.lnx_bakelist) == 0:
							 | 
						||
| 
								 | 
							
								            return{'FINISHED'}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        self.report({'INFO'}, "Once baked, hit 'Leenkx Bake - Apply' to pack lightmaps")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # At least one material required for now..
							 | 
						||
| 
								 | 
							
								        for o in scn.lnx_bakelist:
							 | 
						||
| 
								 | 
							
								            ob = o.obj
							 | 
						||
| 
								 | 
							
								            if len(ob.material_slots) == 0:
							 | 
						||
| 
								 | 
							
								                if not 'MaterialDefault' in bpy.data.materials:
							 | 
						||
| 
								 | 
							
								                    mat = bpy.data.materials.new(name='MaterialDefault')
							 | 
						||
| 
								 | 
							
								                    mat.use_nodes = True
							 | 
						||
| 
								 | 
							
								                else:
							 | 
						||
| 
								 | 
							
								                    mat = bpy.data.materials['MaterialDefault']
							 | 
						||
| 
								 | 
							
								                ob.data.materials.append(mat)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Single user materials
							 | 
						||
| 
								 | 
							
								        for o in scn.lnx_bakelist:
							 | 
						||
| 
								 | 
							
								            ob = o.obj
							 | 
						||
| 
								 | 
							
								            for slot in ob.material_slots:
							 | 
						||
| 
								 | 
							
								                # Temp material already exists
							 | 
						||
| 
								 | 
							
								                if slot.material.name.endswith('_temp'):
							 | 
						||
| 
								 | 
							
								                    continue
							 | 
						||
| 
								 | 
							
								                n = slot.material.name + '_' + ob.name + '_temp'
							 | 
						||
| 
								 | 
							
								                if not n in bpy.data.materials:
							 | 
						||
| 
								 | 
							
								                    slot.material = slot.material.copy()
							 | 
						||
| 
								 | 
							
								                    slot.material.name = n
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Images for baking
							 | 
						||
| 
								 | 
							
								        for o in scn.lnx_bakelist:
							 | 
						||
| 
								 | 
							
								            ob = o.obj
							 | 
						||
| 
								 | 
							
								            img_name = ob.name + '_baked'
							 | 
						||
| 
								 | 
							
								            sc = scn.lnx_bakelist_scale / 100
							 | 
						||
| 
								 | 
							
								            rx = o.res_x * sc
							 | 
						||
| 
								 | 
							
								            ry = o.res_y * sc
							 | 
						||
| 
								 | 
							
								            # Get image
							 | 
						||
| 
								 | 
							
								            if img_name not in bpy.data.images or bpy.data.images[img_name].size[0] != rx or bpy.data.images[img_name].size[1] != ry:
							 | 
						||
| 
								 | 
							
								                img = bpy.data.images.new(img_name, int(rx), int(ry))
							 | 
						||
| 
								 | 
							
								                img.name = img_name # Force img_name (in case Blender picked img_name.001)
							 | 
						||
| 
								 | 
							
								            else:
							 | 
						||
| 
								 | 
							
								                img = bpy.data.images[img_name]
							 | 
						||
| 
								 | 
							
								            for slot in ob.material_slots:
							 | 
						||
| 
								 | 
							
								                # Add image nodes
							 | 
						||
| 
								 | 
							
								                mat = slot.material
							 | 
						||
| 
								 | 
							
								                mat.use_nodes = True
							 | 
						||
| 
								 | 
							
								                nodes = mat.node_tree.nodes
							 | 
						||
| 
								 | 
							
								                if 'Baked Image' in nodes:
							 | 
						||
| 
								 | 
							
								                    img_node = nodes['Baked Image']
							 | 
						||
| 
								 | 
							
								                else:
							 | 
						||
| 
								 | 
							
								                    img_node = nodes.new('ShaderNodeTexImage')
							 | 
						||
| 
								 | 
							
								                    img_node.name = 'Baked Image'
							 | 
						||
| 
								 | 
							
								                    img_node.location = (100, 100)
							 | 
						||
| 
								 | 
							
								                    img_node.image = img
							 | 
						||
| 
								 | 
							
								                img_node.select = True
							 | 
						||
| 
								 | 
							
								                nodes.active = img_node
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        obs = bpy.context.view_layer.objects
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Unwrap
							 | 
						||
| 
								 | 
							
								        active = obs.active
							 | 
						||
| 
								 | 
							
								        for o in scn.lnx_bakelist:
							 | 
						||
| 
								 | 
							
								            ob = o.obj
							 | 
						||
| 
								 | 
							
								            uv_layers = ob.data.uv_layers
							 | 
						||
| 
								 | 
							
								            if not 'UVMap_baked' in uv_layers:
							 | 
						||
| 
								 | 
							
								                uvmap = uv_layers.new(name='UVMap_baked')
							 | 
						||
| 
								 | 
							
								                uv_layers.active_index = len(uv_layers) - 1
							 | 
						||
| 
								 | 
							
								                obs.active = ob
							 | 
						||
| 
								 | 
							
								                if scn.lnx_bakelist_unwrap == 'Lightmap Pack':
							 | 
						||
| 
								 | 
							
								                    bpy.context.view_layer.objects.active = ob
							 | 
						||
| 
								 | 
							
								                    ob.select_set(True)
							 | 
						||
| 
								 | 
							
								                    bpy.ops.uv.lightmap_pack(PREF_CONTEXT='ALL_FACES')
							 | 
						||
| 
								 | 
							
								                else:
							 | 
						||
| 
								 | 
							
								                    bpy.ops.object.mode_set(mode='OBJECT')
							 | 
						||
| 
								 | 
							
								                    bpy.ops.object.select_all(action='DESELECT')
							 | 
						||
| 
								 | 
							
								                    bpy.context.view_layer.objects.active = ob
							 | 
						||
| 
								 | 
							
								                    ob.select_set(True)
							 | 
						||
| 
								 | 
							
								                    bpy.ops.object.mode_set(mode='EDIT')
							 | 
						||
| 
								 | 
							
								                    bpy.ops.mesh.select_all(action='SELECT')
							 | 
						||
| 
								 | 
							
								                    bpy.ops.uv.smart_project()
							 | 
						||
| 
								 | 
							
								                    bpy.ops.mesh.select_all(action='DESELECT')
							 | 
						||
| 
								 | 
							
								                    bpy.ops.object.mode_set(mode='OBJECT')
							 | 
						||
| 
								 | 
							
								            else:
							 | 
						||
| 
								 | 
							
								                for i in range(0, len(uv_layers)):
							 | 
						||
| 
								 | 
							
								                    if uv_layers[i].name == 'UVMap_baked':
							 | 
						||
| 
								 | 
							
								                        uv_layers.active_index = i
							 | 
						||
| 
								 | 
							
								                        break
							 | 
						||
| 
								 | 
							
								        obs.active = active
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Materials for runtime
							 | 
						||
| 
								 | 
							
								        # TODO: use single mat per object
							 | 
						||
| 
								 | 
							
								        for o in scn.lnx_bakelist:
							 | 
						||
| 
								 | 
							
								            ob = o.obj
							 | 
						||
| 
								 | 
							
								            img_name = ob.name + '_baked'
							 | 
						||
| 
								 | 
							
								            for slot in ob.material_slots:
							 | 
						||
| 
								 | 
							
								                n = slot.material.name[:-5] + '_baked'
							 | 
						||
| 
								 | 
							
								                if not n in bpy.data.materials:
							 | 
						||
| 
								 | 
							
								                    mat = bpy.data.materials.new(name=n)
							 | 
						||
| 
								 | 
							
								                    mat.use_nodes = True
							 | 
						||
| 
								 | 
							
								                    mat.use_fake_user = True
							 | 
						||
| 
								 | 
							
								                    nodes = mat.node_tree.nodes
							 | 
						||
| 
								 | 
							
								                    img_node = nodes.new('ShaderNodeTexImage')
							 | 
						||
| 
								 | 
							
								                    img_node.name = 'Baked Image'
							 | 
						||
| 
								 | 
							
								                    img_node.location = (100, 100)
							 | 
						||
| 
								 | 
							
								                    img_node.image = bpy.data.images[img_name]
							 | 
						||
| 
								 | 
							
								                    mat.node_tree.links.new(img_node.outputs[0], nodes['Principled BSDF'].inputs[0])
							 | 
						||
| 
								 | 
							
								                else:
							 | 
						||
| 
								 | 
							
								                    mat = bpy.data.materials[n]
							 | 
						||
| 
								 | 
							
								                    nodes = mat.node_tree.nodes
							 | 
						||
| 
								 | 
							
								                    nodes['Baked Image'].image = bpy.data.images[img_name]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Bake
							 | 
						||
| 
								 | 
							
								        bpy.ops.object.select_all(action='DESELECT')
							 | 
						||
| 
								 | 
							
								        for o in scn.lnx_bakelist:
							 | 
						||
| 
								 | 
							
								            o.obj.select_set(True)
							 | 
						||
| 
								 | 
							
								        obs.active = scn.lnx_bakelist[0].obj
							 | 
						||
| 
								 | 
							
								        bpy.ops.object.bake('INVOKE_DEFAULT', type='COMBINED')
							 | 
						||
| 
								 | 
							
								        bpy.ops.object.select_all(action='DESELECT')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return{'FINISHED'}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LnxBakeApplyButton(bpy.types.Operator):
							 | 
						||
| 
								 | 
							
								    '''Pack baked textures and restore materials'''
							 | 
						||
| 
								 | 
							
								    bl_idname = 'lnx.bake_apply'
							 | 
						||
| 
								 | 
							
								    bl_label = 'Apply'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def execute(self, context):
							 | 
						||
| 
								 | 
							
								        scn = context.scene
							 | 
						||
| 
								 | 
							
								        if len(scn.lnx_bakelist) == 0:
							 | 
						||
| 
								 | 
							
								            return{'FINISHED'}
							 | 
						||
| 
								 | 
							
								        for material in bpy.data.materials:
							 | 
						||
| 
								 | 
							
								            if not material.users:
							 | 
						||
| 
								 | 
							
								                bpy.data.materials.remove(material)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # Remove leftover _baked materials for removed objects
							 | 
						||
| 
								 | 
							
								        for mat in bpy.data.materials:
							 | 
						||
| 
								 | 
							
								            if mat.name.endswith('_baked'):
							 | 
						||
| 
								 | 
							
								                has_user = False
							 | 
						||
| 
								 | 
							
								                for ob in bpy.data.objects:
							 | 
						||
| 
								 | 
							
								                    if ob.type == 'MESH' and mat.name.endswith('_' + ob.name + '_baked'):
							 | 
						||
| 
								 | 
							
								                        has_user = True
							 | 
						||
| 
								 | 
							
								                        break
							 | 
						||
| 
								 | 
							
								                if not has_user:
							 | 
						||
| 
								 | 
							
								                    bpy.data.materials.remove(mat, do_unlink=True)
							 | 
						||
| 
								 | 
							
								        # Recache lightmaps
							 | 
						||
| 
								 | 
							
								        lnx.assets.invalidate_unpacked_data(None, None)
							 | 
						||
| 
								 | 
							
								        for o in scn.lnx_bakelist:
							 | 
						||
| 
								 | 
							
								            ob = o.obj
							 | 
						||
| 
								 | 
							
								            img_name = ob.name + '_baked'
							 | 
						||
| 
								 | 
							
								            # Save images
							 | 
						||
| 
								 | 
							
								            bpy.data.images[img_name].pack()
							 | 
						||
| 
								 | 
							
								            #bpy.data.images[img_name].save()
							 | 
						||
| 
								 | 
							
								            for slot in ob.material_slots:
							 | 
						||
| 
								 | 
							
								                mat = slot.material
							 | 
						||
| 
								 | 
							
								                # Remove temp material
							 | 
						||
| 
								 | 
							
								                if mat.name.endswith('_temp'):
							 | 
						||
| 
								 | 
							
								                    old = slot.material
							 | 
						||
| 
								 | 
							
								                    slot.material = bpy.data.materials[old.name.split('_' + ob.name)[0] + "_" + ob.name + "_baked"]
							 | 
						||
| 
								 | 
							
								                    bpy.data.materials.remove(old, do_unlink=True)
							 | 
						||
| 
								 | 
							
								        # Restore uv slots
							 | 
						||
| 
								 | 
							
								        for o in scn.lnx_bakelist:
							 | 
						||
| 
								 | 
							
								            ob = o.obj
							 | 
						||
| 
								 | 
							
								            uv_layers = ob.data.uv_layers
							 | 
						||
| 
								 | 
							
								            uv_layers.active_index = 0
							 | 
						||
| 
								 | 
							
								            uv_layers["UVMap_baked"].active_render = True
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return{'FINISHED'}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LnxBakeSpecialsMenu(bpy.types.Menu):
							 | 
						||
| 
								 | 
							
								    bl_label = "Bake"
							 | 
						||
| 
								 | 
							
								    bl_idname = "LNX_MT_BakeListSpecials"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def draw(self, context):
							 | 
						||
| 
								 | 
							
								        layout = self.layout
							 | 
						||
| 
								 | 
							
								        layout.operator("lnx.bake_add_all")
							 | 
						||
| 
								 | 
							
								        layout.operator("lnx.bake_add_selected")
							 | 
						||
| 
								 | 
							
								        layout.operator("lnx.bake_clear_all")
							 | 
						||
| 
								 | 
							
								        layout.operator("lnx.bake_remove_baked_materials")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LnxBakeAddAllButton(bpy.types.Operator):
							 | 
						||
| 
								 | 
							
								    '''Fill the list with scene objects'''
							 | 
						||
| 
								 | 
							
								    bl_idname = 'lnx.bake_add_all'
							 | 
						||
| 
								 | 
							
								    bl_label = 'Add All'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def execute(self, context):
							 | 
						||
| 
								 | 
							
								        scn = context.scene
							 | 
						||
| 
								 | 
							
								        scn.lnx_bakelist.clear()
							 | 
						||
| 
								 | 
							
								        for ob in scn.objects:
							 | 
						||
| 
								 | 
							
								            if ob.type == 'MESH':
							 | 
						||
| 
								 | 
							
								                scn.lnx_bakelist.add().obj = ob
							 | 
						||
| 
								 | 
							
								        return{'FINISHED'}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LnxBakeAddSelectedButton(bpy.types.Operator):
							 | 
						||
| 
								 | 
							
								    '''Add selected objects to the list'''
							 | 
						||
| 
								 | 
							
								    bl_idname = 'lnx.bake_add_selected'
							 | 
						||
| 
								 | 
							
								    bl_label = 'Add Selected'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def contains(self, scn, ob):
							 | 
						||
| 
								 | 
							
								        for o in scn.lnx_bakelist:
							 | 
						||
| 
								 | 
							
								            if o == ob:
							 | 
						||
| 
								 | 
							
								                return True
							 | 
						||
| 
								 | 
							
								        return False
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def execute(self, context):
							 | 
						||
| 
								 | 
							
								        scn = context.scene
							 | 
						||
| 
								 | 
							
								        for ob in context.selected_objects:
							 | 
						||
| 
								 | 
							
								            if ob.type == 'MESH' and not self.contains(scn, ob):
							 | 
						||
| 
								 | 
							
								                scn.lnx_bakelist.add().obj = ob
							 | 
						||
| 
								 | 
							
								        return{'FINISHED'}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LnxBakeClearAllButton(bpy.types.Operator):
							 | 
						||
| 
								 | 
							
								    '''Clear the list'''
							 | 
						||
| 
								 | 
							
								    bl_idname = 'lnx.bake_clear_all'
							 | 
						||
| 
								 | 
							
								    bl_label = 'Clear'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def execute(self, context):
							 | 
						||
| 
								 | 
							
								        scn = context.scene
							 | 
						||
| 
								 | 
							
								        scn.lnx_bakelist.clear()
							 | 
						||
| 
								 | 
							
								        return{'FINISHED'}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class LnxBakeRemoveBakedMaterialsButton(bpy.types.Operator):
							 | 
						||
| 
								 | 
							
								    '''Clear the list'''
							 | 
						||
| 
								 | 
							
								    bl_idname = 'lnx.bake_remove_baked_materials'
							 | 
						||
| 
								 | 
							
								    bl_label = 'Remove Baked Materials'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def execute(self, context):
							 | 
						||
| 
								 | 
							
								        for mat in bpy.data.materials:
							 | 
						||
| 
								 | 
							
								            if mat.name.endswith('_baked'):
							 | 
						||
| 
								 | 
							
								                bpy.data.materials.remove(mat, do_unlink=True)
							 | 
						||
| 
								 | 
							
								        return{'FINISHED'}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								__REG_CLASSES = (
							 | 
						||
| 
								 | 
							
								    LnxBakeListItem,
							 | 
						||
| 
								 | 
							
								    LNX_UL_BakeList,
							 | 
						||
| 
								 | 
							
								    LnxBakeListNewItem,
							 | 
						||
| 
								 | 
							
								    LnxBakeListDeleteItem,
							 | 
						||
| 
								 | 
							
								    LnxBakeListMoveItem,
							 | 
						||
| 
								 | 
							
								    LnxBakeButton,
							 | 
						||
| 
								 | 
							
								    LnxBakeApplyButton,
							 | 
						||
| 
								 | 
							
								    LnxBakeSpecialsMenu,
							 | 
						||
| 
								 | 
							
								    LnxBakeAddAllButton,
							 | 
						||
| 
								 | 
							
								    LnxBakeAddSelectedButton,
							 | 
						||
| 
								 | 
							
								    LnxBakeClearAllButton,
							 | 
						||
| 
								 | 
							
								    LnxBakeRemoveBakedMaterialsButton
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								__reg_classes, __unreg_classes = bpy.utils.register_classes_factory(__REG_CLASSES)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def register():
							 | 
						||
| 
								 | 
							
								    __reg_classes()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    bpy.types.Scene.lnx_bakelist_scale = FloatProperty(
							 | 
						||
| 
								 | 
							
								        name="Resolution", description="Resolution scale", subtype='PERCENTAGE',
							 | 
						||
| 
								 | 
							
								        default=100.0, min=1, max=1000, soft_min=1, soft_max=100.0
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								    bpy.types.Scene.lnx_bakelist = CollectionProperty(type=LnxBakeListItem)
							 | 
						||
| 
								 | 
							
								    bpy.types.Scene.lnx_bakelist_index = IntProperty(name="Index for my_list", default=0)
							 | 
						||
| 
								 | 
							
								    bpy.types.Scene.lnx_bakelist_unwrap = EnumProperty(
							 | 
						||
| 
								 | 
							
								        name="UV Unwrap", default='Smart UV Project',
							 | 
						||
| 
								 | 
							
								        items=[
							 | 
						||
| 
								 | 
							
								            ('Lightmap Pack', 'Lightmap Pack', 'Lightmap Pack'),
							 | 
						||
| 
								 | 
							
								            ('Smart UV Project', 'Smart UV Project', 'Smart UV Project')
							 | 
						||
| 
								 | 
							
								        ]
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # Register lightmapper
							 | 
						||
| 
								 | 
							
								    bpy.types.Scene.lnx_bakemode = EnumProperty(
							 | 
						||
| 
								 | 
							
								        name="Bake mode", default='Static Map',
							 | 
						||
| 
								 | 
							
								        items=[
							 | 
						||
| 
								 | 
							
								            ('Static Map', 'Static Map', 'Static Map'),
							 | 
						||
| 
								 | 
							
								            ('Lightmap', 'Lightmap', 'Lightmap')
							 | 
						||
| 
								 | 
							
								        ]
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    operators.register()
							 | 
						||
| 
								 | 
							
								    properties.register()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def unregister():
							 | 
						||
| 
								 | 
							
								    __unreg_classes()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    # Unregister lightmapper
							 | 
						||
| 
								 | 
							
								    operators.unregister()
							 | 
						||
| 
								 | 
							
								    properties.unregister()
							 |