1732 lines
		
	
	
		
			66 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			1732 lines
		
	
	
		
			66 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import bpy, os, time, blf, webbrowser, platform, numpy, bmesh
 | 
						|
import math, subprocess, multiprocessing
 | 
						|
from .. utility import utility
 | 
						|
from .. utility import build
 | 
						|
from .. utility.cycles import cache
 | 
						|
from .. network import server
 | 
						|
 | 
						|
def setObjectLightmapByWeight(minimumRes, maximumRes, objWeight):
 | 
						|
        
 | 
						|
        availableResolutions = [32,64,128,256,512,1024,2048,4096,8192]
 | 
						|
        
 | 
						|
        minRes = minimumRes
 | 
						|
        minResIdx = availableResolutions.index(minRes)
 | 
						|
        maxRes = maximumRes
 | 
						|
        maxResIdx = availableResolutions.index(maxRes)
 | 
						|
        
 | 
						|
        exampleWeight = objWeight
 | 
						|
        
 | 
						|
        if minResIdx == maxResIdx:
 | 
						|
            pass
 | 
						|
        else:
 | 
						|
        
 | 
						|
            increment = 1.0/(maxResIdx-minResIdx)
 | 
						|
            
 | 
						|
            assortedRange = []
 | 
						|
            
 | 
						|
            for a in numpy.arange(0.0, 1.0, increment):
 | 
						|
                assortedRange.append(round(a, 2))
 | 
						|
                
 | 
						|
            assortedRange.append(1.0)
 | 
						|
            nearestWeight = min(assortedRange, key=lambda x:abs(x - exampleWeight))
 | 
						|
            return (availableResolutions[assortedRange.index(nearestWeight) + minResIdx])
 | 
						|
 | 
						|
class TLM_BuildLightmaps(bpy.types.Operator):
 | 
						|
    bl_idname = "tlm.build_lightmaps"
 | 
						|
    bl_label = "Build Lightmaps"
 | 
						|
    bl_description = "Build Lightmaps"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def modal(self, context, event):
 | 
						|
 | 
						|
        #Add progress bar from 0.15
 | 
						|
 | 
						|
        print("MODAL")
 | 
						|
 | 
						|
        return {'PASS_THROUGH'}
 | 
						|
 | 
						|
    def invoke(self, context, event):
 | 
						|
 | 
						|
        if not bpy.app.background:
 | 
						|
 | 
						|
            build.prepare_build(self, False)
 | 
						|
 | 
						|
        else:
 | 
						|
 | 
						|
            print("Running in background mode. Contextual operator not available. Use command 'thelightmapper.addon.build.prepare_build()'")
 | 
						|
 | 
						|
        return {'RUNNING_MODAL'}
 | 
						|
 | 
						|
    def cancel(self, context):
 | 
						|
        pass
 | 
						|
 | 
						|
    def draw_callback_px(self, context, event):
 | 
						|
        pass
 | 
						|
 | 
						|
class TLM_CleanLightmaps(bpy.types.Operator):
 | 
						|
    bl_idname = "tlm.clean_lightmaps"
 | 
						|
    bl_label = "Clean Lightmaps"
 | 
						|
    bl_description = "Clean Lightmaps"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        scene = context.scene
 | 
						|
 | 
						|
        filepath = bpy.data.filepath
 | 
						|
        dirpath = os.path.join(os.path.dirname(bpy.data.filepath), scene.TLM_EngineProperties.tlm_lightmap_savedir)
 | 
						|
 | 
						|
        if not bpy.context.scene.TLM_SceneProperties.tlm_keep_baked_files:
 | 
						|
            if os.path.isdir(dirpath):
 | 
						|
                for file in os.listdir(dirpath):
 | 
						|
                    os.remove(os.path.join(dirpath + "/" + file))
 | 
						|
 | 
						|
        for obj in bpy.context.scene.objects:
 | 
						|
            if obj.type == 'MESH' and obj.name in bpy.context.view_layer.objects:
 | 
						|
                if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
 | 
						|
                    cache.backup_material_restore(obj)
 | 
						|
 | 
						|
        for obj in bpy.context.scene.objects:
 | 
						|
            if obj.type == 'MESH' and obj.name in bpy.context.view_layer.objects:
 | 
						|
                if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
 | 
						|
                    cache.backup_material_rename(obj)
 | 
						|
 | 
						|
        for obj in bpy.context.scene.objects:
 | 
						|
            if obj.type == 'MESH' and obj.name in bpy.context.view_layer.objects:
 | 
						|
                if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
 | 
						|
                    for vertex_layer in obj.data.vertex_colors:
 | 
						|
                        if vertex_layer.name == "TLM":
 | 
						|
                            obj.data.vertex_colors.remove(vertex_layer)
 | 
						|
 | 
						|
        for mat in bpy.data.materials:
 | 
						|
            if mat.users < 1:
 | 
						|
                bpy.data.materials.remove(mat)
 | 
						|
 | 
						|
        for mat in bpy.data.materials:
 | 
						|
            if mat.name.startswith("."):
 | 
						|
                if "_Original" in mat.name:
 | 
						|
                    bpy.data.materials.remove(mat)
 | 
						|
 | 
						|
        for image in bpy.data.images:
 | 
						|
            if image.name.endswith("_baked"):
 | 
						|
                bpy.data.images.remove(image, do_unlink=True)
 | 
						|
 | 
						|
        for obj in bpy.context.scene.objects:
 | 
						|
            if obj.type == 'MESH' and obj.name in bpy.context.view_layer.objects:
 | 
						|
                if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
 | 
						|
                    if obj.TLM_ObjectProperties.tlm_postpack_object:
 | 
						|
 | 
						|
                        atlas = obj.TLM_ObjectProperties.tlm_postatlas_pointer
 | 
						|
                        atlas_resize = False
 | 
						|
 | 
						|
                        for atlasgroup in scene.TLM_PostAtlasList:
 | 
						|
                            if atlasgroup.name == atlas:
 | 
						|
                                atlas_resize = True
 | 
						|
 | 
						|
                        if atlas_resize:
 | 
						|
 | 
						|
                            bpy.ops.object.select_all(action='DESELECT')
 | 
						|
                            obj.select_set(True)
 | 
						|
                            bpy.context.view_layer.objects.active = obj
 | 
						|
 | 
						|
                            uv_layers = obj.data.uv_layers
 | 
						|
 | 
						|
                            if not obj.TLM_ObjectProperties.tlm_use_default_channel:
 | 
						|
                                uv_channel = obj.TLM_ObjectProperties.tlm_uv_channel
 | 
						|
                            else:
 | 
						|
                                uv_channel = "UVMap_Lightmap"
 | 
						|
                            
 | 
						|
                            for i in range(0, len(uv_layers)):
 | 
						|
                                if uv_layers[i].name == uv_channel:
 | 
						|
                                    uv_layers.active_index = i
 | 
						|
                                    break
 | 
						|
 | 
						|
                            bpy.ops.object.mode_set(mode='EDIT')
 | 
						|
                            bpy.ops.mesh.select_all(action='SELECT')
 | 
						|
                            bpy.ops.uv.select_all(action='SELECT')
 | 
						|
                            bpy.ops.uv.pack_islands(rotate=False, margin=0.001)
 | 
						|
                            bpy.ops.uv.select_all(action='DESELECT')
 | 
						|
                            bpy.ops.mesh.select_all(action='DESELECT')
 | 
						|
                            bpy.ops.object.mode_set(mode='OBJECT')
 | 
						|
 | 
						|
                            if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
 | 
						|
                                print("Resized for obj: " + obj.name)
 | 
						|
 | 
						|
                    if "Lightmap" in obj:
 | 
						|
                        del obj["Lightmap"]
 | 
						|
 | 
						|
        if bpy.context.scene.TLM_SceneProperties.tlm_repartition_on_clean:
 | 
						|
 | 
						|
            mats = bpy.data.materials
 | 
						|
            
 | 
						|
            for obj in bpy.context.scene.objects:
 | 
						|
                if obj.type == 'MESH' and obj.name in bpy.context.view_layer.objects:
 | 
						|
                    if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
 | 
						|
 | 
						|
                        print("Repartitioning materials")
 | 
						|
 | 
						|
                        for slt in obj.material_slots:
 | 
						|
                            print("Repartitioning material: " + str(slt.name))
 | 
						|
                            part = slt.name.rpartition('.')
 | 
						|
                            if part[2].isnumeric() and part[0] in mats:
 | 
						|
                                slt.material = mats.get(part[0])
 | 
						|
 | 
						|
                        for slt in obj.material_slots:
 | 
						|
                            if slt.name.endswith(tuple(["001","002","003","004","005","006","007","008","009"])): #Do regex instead
 | 
						|
                                if not slt.name[:-4] in mats:
 | 
						|
                                    slt.material.name = slt.name[:-4]
 | 
						|
 | 
						|
        return {'FINISHED'}
 | 
						|
 | 
						|
class TLM_ExploreLightmaps(bpy.types.Operator):
 | 
						|
    bl_idname = "tlm.explore_lightmaps"
 | 
						|
    bl_label = "Explore Lightmaps"
 | 
						|
    bl_description = "Explore Lightmaps"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        scene = context.scene
 | 
						|
        cycles = scene.cycles
 | 
						|
 | 
						|
        if not bpy.data.is_saved:
 | 
						|
            self.report({'INFO'}, "Please save your file first")
 | 
						|
            return {"CANCELLED"}
 | 
						|
 | 
						|
        filepath = bpy.data.filepath
 | 
						|
        dirpath = os.path.join(os.path.dirname(bpy.data.filepath), scene.TLM_EngineProperties.tlm_lightmap_savedir)
 | 
						|
        
 | 
						|
        if platform.system() != "Linux":
 | 
						|
 | 
						|
            if os.path.isdir(dirpath):
 | 
						|
                webbrowser.open('file://' + dirpath)
 | 
						|
            else:
 | 
						|
                os.mkdir(dirpath)
 | 
						|
                webbrowser.open('file://' + dirpath)
 | 
						|
        else:
 | 
						|
 | 
						|
            if os.path.isdir(dirpath):
 | 
						|
                os.system('xdg-open "%s"' % dirpath)
 | 
						|
                #webbrowser.open('file://' + dirpath)
 | 
						|
            else:
 | 
						|
                os.mkdir(dirpath)
 | 
						|
                os.system('xdg-open "%s"' % dirpath)
 | 
						|
                #webbrowser.open('file://' + dirpath)
 | 
						|
 | 
						|
        return {'FINISHED'}
 | 
						|
 | 
						|
class TLM_EnableSet(bpy.types.Operator):
 | 
						|
    """Enable for set"""
 | 
						|
    bl_idname = "tlm.enable_set"
 | 
						|
    bl_label = "Enable for set"
 | 
						|
    bl_description = "Enable for set"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        scene = context.scene
 | 
						|
 | 
						|
        weightList = {} #ObjName : [Dimension,Weight]
 | 
						|
        max = 0
 | 
						|
 | 
						|
        if bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Scene":
 | 
						|
            for obj in bpy.context.scene.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
 | 
						|
                    print("Enabling for scene: " + obj.name)
 | 
						|
                    
 | 
						|
                    bpy.context.view_layer.objects.active = obj
 | 
						|
                    obj.select_set(True)
 | 
						|
                    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)
 | 
						|
                    
 | 
						|
                    obj.TLM_ObjectProperties.tlm_mesh_lightmap_use = True
 | 
						|
                    
 | 
						|
                    obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode = bpy.context.scene.TLM_SceneProperties.tlm_mesh_lightmap_unwrap_mode
 | 
						|
                    obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin = bpy.context.scene.TLM_SceneProperties.tlm_mesh_unwrap_margin
 | 
						|
                    obj.TLM_ObjectProperties.tlm_postpack_object = bpy.context.scene.TLM_SceneProperties.tlm_postpack_object
 | 
						|
 | 
						|
                    if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
 | 
						|
                        obj.TLM_ObjectProperties.tlm_atlas_pointer = bpy.context.scene.TLM_SceneProperties.tlm_atlas_pointer
 | 
						|
 | 
						|
                    obj.TLM_ObjectProperties.tlm_postatlas_pointer = bpy.context.scene.TLM_SceneProperties.tlm_postatlas_pointer
 | 
						|
                    
 | 
						|
                    if bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight == "Single":
 | 
						|
                        obj.TLM_ObjectProperties.tlm_mesh_lightmap_resolution = scene.TLM_SceneProperties.tlm_mesh_lightmap_resolution
 | 
						|
                    elif bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight == "Dimension":
 | 
						|
                        obj_dimensions = obj.dimensions.x * obj.dimensions.y * obj.dimensions.z
 | 
						|
                        weightList[obj.name] = [obj_dimensions, 0]
 | 
						|
                        if obj_dimensions > max:
 | 
						|
                            max = obj_dimensions
 | 
						|
                    elif bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight == "Surface":
 | 
						|
                        bm = bmesh.new()
 | 
						|
                        bm.from_mesh(obj.data)
 | 
						|
                        area = sum(f.calc_area() for f in bm.faces)
 | 
						|
                        weightList[obj.name] = [area, 0]
 | 
						|
                        if area > max:
 | 
						|
                            max = area
 | 
						|
                    elif bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight == "Volume":
 | 
						|
                        bm = bmesh.new()
 | 
						|
                        bm.from_mesh(obj.data)
 | 
						|
                        volume = float( bm.calc_volume())
 | 
						|
                        weightList[obj.name] = [volume, 0]
 | 
						|
                        if volume > max:
 | 
						|
                            max = volume
 | 
						|
        
 | 
						|
        elif bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Selection":
 | 
						|
            for obj in bpy.context.selected_objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
                    
 | 
						|
                    print("Enabling for selection: " + obj.name)
 | 
						|
                    
 | 
						|
                    bpy.context.view_layer.objects.active = obj
 | 
						|
                    obj.select_set(True)
 | 
						|
                    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)
 | 
						|
                    
 | 
						|
                    obj.TLM_ObjectProperties.tlm_mesh_lightmap_use = True
 | 
						|
                    
 | 
						|
                    obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode = bpy.context.scene.TLM_SceneProperties.tlm_mesh_lightmap_unwrap_mode
 | 
						|
                    obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin = bpy.context.scene.TLM_SceneProperties.tlm_mesh_unwrap_margin
 | 
						|
                    obj.TLM_ObjectProperties.tlm_postpack_object = bpy.context.scene.TLM_SceneProperties.tlm_postpack_object
 | 
						|
 | 
						|
                    if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
 | 
						|
                        obj.TLM_ObjectProperties.tlm_atlas_pointer = bpy.context.scene.TLM_SceneProperties.tlm_atlas_pointer
 | 
						|
 | 
						|
                    obj.TLM_ObjectProperties.tlm_postatlas_pointer = bpy.context.scene.TLM_SceneProperties.tlm_postatlas_pointer
 | 
						|
                    
 | 
						|
                    if bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight == "Single":
 | 
						|
                        obj.TLM_ObjectProperties.tlm_mesh_lightmap_resolution = scene.TLM_SceneProperties.tlm_mesh_lightmap_resolution
 | 
						|
                    elif bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight == "Dimension":
 | 
						|
                        obj_dimensions = obj.dimensions.x * obj.dimensions.y * obj.dimensions.z
 | 
						|
                        weightList[obj.name] = [obj_dimensions, 0]
 | 
						|
                        if obj_dimensions > max:
 | 
						|
                            max = obj_dimensions
 | 
						|
                    elif bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight == "Surface":
 | 
						|
                        bm = bmesh.new()
 | 
						|
                        bm.from_mesh(obj.data)
 | 
						|
                        area = sum(f.calc_area() for f in bm.faces)
 | 
						|
                        weightList[obj.name] = [area, 0]
 | 
						|
                        if area > max:
 | 
						|
                            max = area
 | 
						|
                    elif bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight == "Volume":
 | 
						|
                        bm = bmesh.new()
 | 
						|
                        bm.from_mesh(obj.data)
 | 
						|
                        volume = float( bm.calc_volume())
 | 
						|
                        weightList[obj.name] = [volume, 0]
 | 
						|
                        if volume > max:
 | 
						|
                            max = volume
 | 
						|
        
 | 
						|
        else: #Enabled
 | 
						|
            for obj in bpy.context.scene.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
                    if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
 | 
						|
 | 
						|
                        print("Enabling for designated: " + obj.name)
 | 
						|
                        
 | 
						|
                        bpy.context.view_layer.objects.active = obj
 | 
						|
                        obj.select_set(True)
 | 
						|
                        bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)
 | 
						|
                        
 | 
						|
                        obj.TLM_ObjectProperties.tlm_mesh_lightmap_use = True
 | 
						|
                        
 | 
						|
                        obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode = bpy.context.scene.TLM_SceneProperties.tlm_mesh_lightmap_unwrap_mode
 | 
						|
                        obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin = bpy.context.scene.TLM_SceneProperties.tlm_mesh_unwrap_margin
 | 
						|
                        obj.TLM_ObjectProperties.tlm_postpack_object = bpy.context.scene.TLM_SceneProperties.tlm_postpack_object
 | 
						|
 | 
						|
                        if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
 | 
						|
                            obj.TLM_ObjectProperties.tlm_atlas_pointer = bpy.context.scene.TLM_SceneProperties.tlm_atlas_pointer
 | 
						|
 | 
						|
                        obj.TLM_ObjectProperties.tlm_postatlas_pointer = bpy.context.scene.TLM_SceneProperties.tlm_postatlas_pointer
 | 
						|
                        
 | 
						|
                        if bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight == "Single":
 | 
						|
                            obj.TLM_ObjectProperties.tlm_mesh_lightmap_resolution = scene.TLM_SceneProperties.tlm_mesh_lightmap_resolution
 | 
						|
                        elif bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight == "Dimension":
 | 
						|
                            obj_dimensions = obj.dimensions.x * obj.dimensions.y * obj.dimensions.z
 | 
						|
                            weightList[obj.name] = [obj_dimensions, 0]
 | 
						|
                            if obj_dimensions > max:
 | 
						|
                                max = obj_dimensions
 | 
						|
                        elif bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight == "Surface":
 | 
						|
                            bm = bmesh.new()
 | 
						|
                            bm.from_mesh(obj.data)
 | 
						|
                            area = sum(f.calc_area() for f in bm.faces)
 | 
						|
                            weightList[obj.name] = [area, 0]
 | 
						|
                            if area > max:
 | 
						|
                                max = area
 | 
						|
                        elif bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight == "Volume":
 | 
						|
                            bm = bmesh.new()
 | 
						|
                            bm.from_mesh(obj.data)
 | 
						|
                            volume = float( bm.calc_volume())
 | 
						|
                            weightList[obj.name] = [volume, 0]
 | 
						|
                            if volume > max:
 | 
						|
                                max = volume
 | 
						|
 | 
						|
        if bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Scene":
 | 
						|
            for obj in bpy.context.scene.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
        
 | 
						|
                    if bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight != "Single":
 | 
						|
                        for key in weightList:
 | 
						|
                            weightList[obj.name][1] = weightList[obj.name][0] / max
 | 
						|
                        a = setObjectLightmapByWeight(int(bpy.context.scene.TLM_SceneProperties.tlm_resolution_min), int(bpy.context.scene.TLM_SceneProperties.tlm_resolution_max), weightList[obj.name][1])
 | 
						|
                        print(str(a) + "/" + str(weightList[obj.name][1]))
 | 
						|
                        print("Scale: " + str(weightList[obj.name][0]))
 | 
						|
                        print("Obj: " + obj.name)
 | 
						|
                        obj.TLM_ObjectProperties.tlm_mesh_lightmap_resolution = str(a)
 | 
						|
 | 
						|
        elif bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Selection":
 | 
						|
            for obj in bpy.context.selected_objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
 | 
						|
                    if bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight != "Single":
 | 
						|
                        for key in weightList:
 | 
						|
                            weightList[obj.name][1] = weightList[obj.name][0] / max
 | 
						|
                        a = setObjectLightmapByWeight(int(bpy.context.scene.TLM_SceneProperties.tlm_resolution_min), int(bpy.context.scene.TLM_SceneProperties.tlm_resolution_max), weightList[obj.name][1])
 | 
						|
                        print(str(a) + "/" + str(weightList[obj.name][1]))
 | 
						|
                        print("Scale: " + str(weightList[obj.name][0]))
 | 
						|
                        print("Obj: " + obj.name)
 | 
						|
                        obj.TLM_ObjectProperties.tlm_mesh_lightmap_resolution = str(a)
 | 
						|
 | 
						|
 | 
						|
        else: #Enabled
 | 
						|
            for obj in bpy.context.scene.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
                    if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
 | 
						|
 | 
						|
                        if bpy.context.scene.TLM_SceneProperties.tlm_resolution_weight != "Single":
 | 
						|
                            for key in weightList:
 | 
						|
                                weightList[obj.name][1] = weightList[obj.name][0] / max
 | 
						|
                            a = setObjectLightmapByWeight(int(bpy.context.scene.TLM_SceneProperties.tlm_resolution_min), int(bpy.context.scene.TLM_SceneProperties.tlm_resolution_max), weightList[obj.name][1])
 | 
						|
                            print(str(a) + "/" + str(weightList[obj.name][1]))
 | 
						|
                            print("Scale: " + str(weightList[obj.name][0]))
 | 
						|
                            print("Obj: " + obj.name)
 | 
						|
                            print("")
 | 
						|
                            obj.TLM_ObjectProperties.tlm_mesh_lightmap_resolution = str(a)
 | 
						|
        
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
class TLM_DisableSelection(bpy.types.Operator):
 | 
						|
    """Disable for set"""
 | 
						|
    bl_idname = "tlm.disable_selection"
 | 
						|
    bl_label = "Disable for set"
 | 
						|
    bl_description = "Disable for selection"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        scene = context.scene
 | 
						|
 | 
						|
        weightList = {} #ObjName : [Dimension,Weight]
 | 
						|
        max = 0
 | 
						|
 | 
						|
        if bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Scene":
 | 
						|
            for obj in bpy.context.scene.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
 | 
						|
                    obj.TLM_ObjectProperties.tlm_mesh_lightmap_use = False
 | 
						|
 | 
						|
        elif bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Selection":
 | 
						|
            for obj in bpy.context.selected_objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
 | 
						|
                    obj.TLM_ObjectProperties.tlm_mesh_lightmap_use = False
 | 
						|
 | 
						|
 | 
						|
        else: #Enabled
 | 
						|
            for obj in bpy.context.scene.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
                    if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
 | 
						|
 | 
						|
                        obj.TLM_ObjectProperties.tlm_mesh_lightmap_use = False
 | 
						|
 | 
						|
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
class TLM_RemoveLightmapUV(bpy.types.Operator):
 | 
						|
    """Remove Lightmap UV for set"""
 | 
						|
    bl_idname = "tlm.remove_uv_selection"
 | 
						|
    bl_label = "Remove Lightmap UV"
 | 
						|
    bl_description = "Remove Lightmap UV for set"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        if bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Scene":
 | 
						|
            for obj in bpy.context.scene.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
 | 
						|
                    uv_layers = obj.data.uv_layers
 | 
						|
 | 
						|
                    if not obj.TLM_ObjectProperties.tlm_use_default_channel:
 | 
						|
                        uv_channel = obj.TLM_ObjectProperties.tlm_uv_channel
 | 
						|
                    else:
 | 
						|
                        uv_channel = "UVMap_Lightmap"
 | 
						|
 | 
						|
                    for uvlayer in uv_layers:
 | 
						|
                        if uvlayer.name == uv_channel:
 | 
						|
                            uv_layers.remove(uvlayer)
 | 
						|
 | 
						|
        elif bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Selection":
 | 
						|
            for obj in bpy.context.selected_objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
 | 
						|
                    uv_layers = obj.data.uv_layers
 | 
						|
 | 
						|
                    if not obj.TLM_ObjectProperties.tlm_use_default_channel:
 | 
						|
                        uv_channel = obj.TLM_ObjectProperties.tlm_uv_channel
 | 
						|
                    else:
 | 
						|
                        uv_channel = "UVMap_Lightmap"
 | 
						|
 | 
						|
                    for uvlayer in uv_layers:
 | 
						|
                        if uvlayer.name == uv_channel:
 | 
						|
                            uv_layers.remove(uvlayer)
 | 
						|
 | 
						|
        else: #Enabled
 | 
						|
            for obj in bpy.context.scene.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
                    if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
 | 
						|
 | 
						|
                        uv_layers = obj.data.uv_layers
 | 
						|
 | 
						|
                        if not obj.TLM_ObjectProperties.tlm_use_default_channel:
 | 
						|
                            uv_channel = obj.TLM_ObjectProperties.tlm_uv_channel
 | 
						|
                        else:
 | 
						|
                            uv_channel = "UVMap_Lightmap"
 | 
						|
 | 
						|
                        for uvlayer in uv_layers:
 | 
						|
                            if uvlayer.name == uv_channel:
 | 
						|
                                uv_layers.remove(uvlayer)
 | 
						|
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
class TLM_SelectLightmapped(bpy.types.Operator):
 | 
						|
    """Select all objects for lightmapping"""
 | 
						|
    bl_idname = "tlm.select_lightmapped_objects"
 | 
						|
    bl_label = "Select lightmap objects"
 | 
						|
    bl_description = "Remove Lightmap UV for selection"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        for obj in bpy.context.scene.objects:
 | 
						|
            if obj.type == 'MESH' and obj.name in bpy.context.view_layer.objects:
 | 
						|
                if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
 | 
						|
 | 
						|
                    obj.select_set(True)
 | 
						|
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
class TLM_GroupListNewItem(bpy.types.Operator):
 | 
						|
    # Add a new item to the list
 | 
						|
    bl_idname = "tlm_grouplist.new_item"
 | 
						|
    bl_label = "Add a new lightmap group"
 | 
						|
    bl_description = "Create a new lightmap group"
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
        scene = context.scene
 | 
						|
        scene.TLM_GroupList.add()
 | 
						|
        scene.TLM_GroupListItem = len(scene.TLM_GroupList) - 1
 | 
						|
 | 
						|
        scene.TLM_GroupList[len(scene.TLM_GroupList) - 1].name = "LightmapGroup"
 | 
						|
 | 
						|
class TLM_AtlasListNewItem(bpy.types.Operator):
 | 
						|
    # Add a new item to the list
 | 
						|
    bl_idname = "tlm_atlaslist.new_item"
 | 
						|
    bl_label = "Add a new item"
 | 
						|
    bl_description = "Create a new AtlasGroup"
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
        scene = context.scene
 | 
						|
        scene.TLM_AtlasList.add()
 | 
						|
        scene.TLM_AtlasListItem = len(scene.TLM_AtlasList) - 1
 | 
						|
 | 
						|
        scene.TLM_AtlasList[len(scene.TLM_AtlasList) - 1].name = "AtlasGroup"
 | 
						|
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
class TLM_PostAtlasListNewItem(bpy.types.Operator):
 | 
						|
    # Add a new item to the list
 | 
						|
    bl_idname = "tlm_postatlaslist.new_item"
 | 
						|
    bl_label = "Add a new item"
 | 
						|
    bl_description = "Create a new AtlasGroup"
 | 
						|
    bl_description = ""
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
        scene = context.scene
 | 
						|
        scene.TLM_PostAtlasList.add()
 | 
						|
        scene.TLM_PostAtlasListItem = len(scene.TLM_PostAtlasList) - 1
 | 
						|
 | 
						|
        scene.TLM_PostAtlasList[len(scene.TLM_PostAtlasList) - 1].name = "AtlasGroup"
 | 
						|
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
class TLM_AtlastListDeleteItem(bpy.types.Operator):
 | 
						|
    # Delete the selected item from the list
 | 
						|
    bl_idname = "tlm_atlaslist.delete_item"
 | 
						|
    bl_label = "Deletes an item"
 | 
						|
    bl_description = "Delete an AtlasGroup"
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def poll(self, context):
 | 
						|
        """ Enable if there's something in the list """
 | 
						|
        scene = context.scene
 | 
						|
        return len(scene.TLM_AtlasList) > 0
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
        scene = context.scene
 | 
						|
        list = scene.TLM_AtlasList
 | 
						|
        index = scene.TLM_AtlasListItem
 | 
						|
 | 
						|
        for obj in bpy.context.scene.objects:
 | 
						|
 | 
						|
            atlasName = scene.TLM_AtlasList[index].name
 | 
						|
 | 
						|
            if obj.TLM_ObjectProperties.tlm_atlas_pointer == atlasName:
 | 
						|
                obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode = "SmartProject"
 | 
						|
 | 
						|
        list.remove(index)
 | 
						|
 | 
						|
        if index > 0:
 | 
						|
            index = index - 1
 | 
						|
 | 
						|
        scene.TLM_AtlasListItem = index
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
class TLM_PostAtlastListDeleteItem(bpy.types.Operator):
 | 
						|
    # Delete the selected item from the list
 | 
						|
    bl_idname = "tlm_postatlaslist.delete_item"
 | 
						|
    bl_label = "Deletes an item"
 | 
						|
    bl_description = "Delete an AtlasGroup"
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def poll(self, context):
 | 
						|
        """ Enable if there's something in the list """
 | 
						|
        scene = context.scene
 | 
						|
        return len(scene.TLM_PostAtlasList) > 0
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
        scene = context.scene
 | 
						|
        list = scene.TLM_PostAtlasList
 | 
						|
        index = scene.TLM_PostAtlasListItem
 | 
						|
 | 
						|
        for obj in bpy.context.scene.objects:
 | 
						|
 | 
						|
            atlasName = scene.TLM_PostAtlasList[index].name
 | 
						|
 | 
						|
            if obj.TLM_ObjectProperties.tlm_atlas_pointer == atlasName:
 | 
						|
                obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode = "SmartProject"
 | 
						|
 | 
						|
        list.remove(index)
 | 
						|
 | 
						|
        if index > 0:
 | 
						|
            index = index - 1
 | 
						|
 | 
						|
        scene.TLM_PostAtlasListItem = index
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
class TLM_AtlasListMoveItem(bpy.types.Operator):
 | 
						|
    # Move an item in the list
 | 
						|
    bl_idname = "tlm_atlaslist.move_item"
 | 
						|
    bl_label = "Move an item in the list"
 | 
						|
    bl_description = "Move an item in the list"
 | 
						|
    direction: bpy.props.EnumProperty(
 | 
						|
                items=(
 | 
						|
                    ('UP', 'Up', ""),
 | 
						|
                    ('DOWN', 'Down', ""),))
 | 
						|
 | 
						|
    def move_index(self):
 | 
						|
        # Move index of an item render queue while clamping it
 | 
						|
        scene = context.scene
 | 
						|
        index = scene.TLM_AtlasListItem
 | 
						|
        list_length = len(scene.TLM_AtlasList) - 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))
 | 
						|
        scene.TLM_AtlasList.move(index, new_index)
 | 
						|
        scene.TLM_AtlasListItem = new_index
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
        scene = context.scene
 | 
						|
        list = scene.TLM_AtlasList
 | 
						|
        index = scene.TLM_AtlasListItem
 | 
						|
 | 
						|
        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 TLM_PostAtlasListMoveItem(bpy.types.Operator):
 | 
						|
    # Move an item in the list
 | 
						|
    bl_idname = "tlm_postatlaslist.move_item"
 | 
						|
    bl_label = "Move an item in the list"
 | 
						|
    bl_description = "Move an item in the list"
 | 
						|
    direction: bpy.props.EnumProperty(
 | 
						|
                items=(
 | 
						|
                    ('UP', 'Up', ""),
 | 
						|
                    ('DOWN', 'Down', ""),))
 | 
						|
 | 
						|
    def move_index(self):
 | 
						|
        # Move index of an item render queue while clamping it
 | 
						|
        scene = context.scene
 | 
						|
        index = scene.TLM_PostAtlasListItem
 | 
						|
        list_length = len(scene.TLM_PostAtlasList) - 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))
 | 
						|
        scene.TLM_PostAtlasList.move(index, new_index)
 | 
						|
        scene.TLM_PostAtlasListItem = new_index
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
        scene = context.scene
 | 
						|
        list = scene.TLM_PostAtlasList
 | 
						|
        index = scene.TLM_PostAtlasListItem
 | 
						|
 | 
						|
        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 TLM_StartServer(bpy.types.Operator):
 | 
						|
    bl_idname = "tlm.start_server"
 | 
						|
    bl_label = "Start Network Server"
 | 
						|
    bl_description = "Start Network Server"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def modal(self, context, event):
 | 
						|
 | 
						|
        #Add progress bar from 0.15
 | 
						|
 | 
						|
        print("MODAL")
 | 
						|
 | 
						|
        return {'PASS_THROUGH'}
 | 
						|
 | 
						|
    def invoke(self, context, event):
 | 
						|
 | 
						|
        server.startServer()
 | 
						|
 | 
						|
        return {'RUNNING_MODAL'}
 | 
						|
 | 
						|
class TLM_BuildEnvironmentProbes(bpy.types.Operator):
 | 
						|
    bl_idname = "tlm.build_environmentprobe"
 | 
						|
    bl_label = "Build Environment Probes"
 | 
						|
    bl_description = "Build all environment probes from reflection cubemaps"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def invoke(self, context, event):
 | 
						|
 | 
						|
        for obj in bpy.context.scene.objects:
 | 
						|
 | 
						|
            if obj.type == "LIGHT_PROBE":
 | 
						|
                if obj.data.type == "CUBEMAP":
 | 
						|
 | 
						|
                    cam_name = "EnvPCam_" + obj.name
 | 
						|
                    camera = bpy.data.cameras.new(cam_name)
 | 
						|
                    camobj_name = "EnvPCamera_" + obj.name
 | 
						|
                    cam_obj = bpy.data.objects.new(camobj_name, camera)
 | 
						|
                    bpy.context.collection.objects.link(cam_obj)
 | 
						|
                    cam_obj.location = obj.location
 | 
						|
                    camera.angle = math.radians(90)
 | 
						|
 | 
						|
                    prevResx = bpy.context.scene.render.resolution_x
 | 
						|
                    prevResy = bpy.context.scene.render.resolution_y
 | 
						|
                    prevCam = bpy.context.scene.camera
 | 
						|
                    prevEngine = bpy.context.scene.render.engine
 | 
						|
                    bpy.context.scene.camera = cam_obj
 | 
						|
 | 
						|
                    bpy.context.scene.render.engine = bpy.context.scene.TLM_SceneProperties.tlm_environment_probe_engine
 | 
						|
                    bpy.context.scene.render.resolution_x = int(bpy.context.scene.TLM_SceneProperties.tlm_environment_probe_resolution)
 | 
						|
                    bpy.context.scene.render.resolution_y = int(bpy.context.scene.TLM_SceneProperties.tlm_environment_probe_resolution)
 | 
						|
 | 
						|
                    savedir = os.path.dirname(bpy.data.filepath)
 | 
						|
                    directory = os.path.join(savedir, "Probes")
 | 
						|
 | 
						|
                    t = 90
 | 
						|
 | 
						|
                    inverted = bpy.context.scene.TLM_SceneProperties.tlm_invert_direction
 | 
						|
 | 
						|
                    if inverted:
 | 
						|
 | 
						|
                        positions = {
 | 
						|
                                "xp" : (math.radians(t), 0, math.radians(0)),
 | 
						|
                                "zp" : (math.radians(t), 0, math.radians(t)),
 | 
						|
                                "xm" : (math.radians(t), 0, math.radians(t*2)),
 | 
						|
                                "zm" : (math.radians(t), 0, math.radians(-t)),
 | 
						|
                                "yp" : (math.radians(t*2), 0, math.radians(t)),
 | 
						|
                                "ym" : (0, 0, math.radians(t))
 | 
						|
                        }
 | 
						|
 | 
						|
                    else:
 | 
						|
 | 
						|
                        positions = {
 | 
						|
                                "xp" : (math.radians(t), 0, math.radians(t*2)),
 | 
						|
                                "zp" : (math.radians(t), 0, math.radians(-t)),
 | 
						|
                                "xm" : (math.radians(t), 0, math.radians(0)),
 | 
						|
                                "zm" : (math.radians(t), 0, math.radians(t)),
 | 
						|
                                "yp" : (math.radians(t*2), 0, math.radians(-t)),
 | 
						|
                                "ym" : (0, 0, math.radians(-t))
 | 
						|
                        }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
                    cam = cam_obj
 | 
						|
                    image_settings = bpy.context.scene.render.image_settings
 | 
						|
                    image_settings.file_format = "HDR"
 | 
						|
                    image_settings.color_depth = '32'
 | 
						|
 | 
						|
                    for val in positions:
 | 
						|
                        cam.rotation_euler = positions[val]
 | 
						|
                        
 | 
						|
                        filename = os.path.join(directory, val) + "_" + camobj_name + ".hdr"
 | 
						|
                        bpy.context.scene.render.filepath = filename
 | 
						|
                        print("Writing out: " + val)
 | 
						|
                        bpy.ops.render.render(write_still=True)
 | 
						|
 | 
						|
                    cmft_path = bpy.path.abspath(os.path.join(os.path.dirname(bpy.data.filepath), bpy.context.scene.TLM_SceneProperties.tlm_cmft_path))
 | 
						|
 | 
						|
                    output_file_irr = camobj_name + ".hdr"
 | 
						|
 | 
						|
                    posx = directory + "/" + "xp_" + camobj_name + ".hdr"
 | 
						|
                    negx = directory + "/" + "xm_" + camobj_name + ".hdr"
 | 
						|
                    posy = directory + "/" + "yp_" + camobj_name + ".hdr"
 | 
						|
                    negy = directory + "/" + "ym_" + camobj_name + ".hdr"
 | 
						|
                    posz = directory + "/" + "zp_" + camobj_name + ".hdr"
 | 
						|
                    negz = directory + "/" + "zm_" + camobj_name + ".hdr"
 | 
						|
                    output = directory + "/" + camobj_name
 | 
						|
 | 
						|
                    if platform.system() == 'Windows':
 | 
						|
                        envpipe = [cmft_path, 
 | 
						|
                        '--inputFacePosX', posx, 
 | 
						|
                        '--inputFaceNegX', negx, 
 | 
						|
                        '--inputFacePosY', posy, 
 | 
						|
                        '--inputFaceNegY', negy, 
 | 
						|
                        '--inputFacePosZ', posz, 
 | 
						|
                        '--inputFaceNegZ', negz, 
 | 
						|
                        '--output0', output, 
 | 
						|
                        '--output0params', 
 | 
						|
                        'hdr,rgbe,latlong']
 | 
						|
                        
 | 
						|
                    else:
 | 
						|
                        envpipe = [cmft_path + '--inputFacePosX' + posx 
 | 
						|
                        + '--inputFaceNegX' + negx 
 | 
						|
                        + '--inputFacePosY' + posy 
 | 
						|
                        + '--inputFaceNegY' + negy 
 | 
						|
                        + '--inputFacePosZ' + posz 
 | 
						|
                        + '--inputFaceNegZ' + negz 
 | 
						|
                        + '--output0' + output 
 | 
						|
                        + '--output0params' + 'hdr,rgbe,latlong']
 | 
						|
 | 
						|
                    if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
 | 
						|
                        print("Calling CMFT with:" + str(envpipe))
 | 
						|
 | 
						|
                    if bpy.context.scene.TLM_SceneProperties.tlm_create_spherical:
 | 
						|
                        subprocess.call(envpipe, shell=True)
 | 
						|
 | 
						|
                    input2 = output + ".hdr"
 | 
						|
                    output2 = directory + "/" + camobj_name
 | 
						|
 | 
						|
                    if platform.system() == 'Windows':
 | 
						|
                        envpipe2 = [cmft_path, 
 | 
						|
                        '--input', input2, 
 | 
						|
                        '--filter', 'shcoeffs', 
 | 
						|
                        '--outputNum', '1', 
 | 
						|
                        '--output0', output2]
 | 
						|
                        
 | 
						|
                    else:
 | 
						|
                        envpipe2 = [cmft_path + 
 | 
						|
                        '--input' + input2
 | 
						|
                        + '-filter' + 'shcoeffs'
 | 
						|
                        + '--outputNum' + '1'
 | 
						|
                        + '--output0' + output2]
 | 
						|
                        
 | 
						|
                    if bpy.context.scene.TLM_SceneProperties.tlm_write_sh:
 | 
						|
                        subprocess.call(envpipe2, shell=True)
 | 
						|
 | 
						|
                    if bpy.context.scene.TLM_SceneProperties.tlm_write_radiance:
 | 
						|
 | 
						|
                        use_opencl = 'false'
 | 
						|
                        cpu_count = 2
 | 
						|
 | 
						|
                        # 4096 = 256 face
 | 
						|
                        # 2048 = 128 face
 | 
						|
                        # 1024 = 64 face
 | 
						|
                        target_w = int(512)
 | 
						|
                        face_size = target_w / 8
 | 
						|
                        if target_w == 2048:
 | 
						|
                            mip_count = 9
 | 
						|
                        elif target_w == 1024:
 | 
						|
                            mip_count = 8
 | 
						|
                        else:
 | 
						|
                            mip_count = 7
 | 
						|
 | 
						|
                        output_file_rad = directory + "/" + camobj_name + "_rad.hdr"
 | 
						|
                        
 | 
						|
                        if platform.system() == 'Windows':
 | 
						|
 | 
						|
                            envpipe3 = [
 | 
						|
                                cmft_path,
 | 
						|
                                '--input', input2,
 | 
						|
                                '--filter', 'radiance',
 | 
						|
                                '--dstFaceSize', str(face_size),
 | 
						|
                                '--srcFaceSize', str(face_size),
 | 
						|
                                '--excludeBase', 'false',
 | 
						|
                                # '--mipCount', str(mip_count),
 | 
						|
                                '--glossScale', '8',
 | 
						|
                                '--glossBias', '3',
 | 
						|
                                '--lightingModel', 'blinnbrdf',
 | 
						|
                                '--edgeFixup', 'none',
 | 
						|
                                '--numCpuProcessingThreads', str(cpu_count),
 | 
						|
                                '--useOpenCL', use_opencl,
 | 
						|
                                '--clVendor', 'anyGpuVendor',
 | 
						|
                                '--deviceType', 'gpu',
 | 
						|
                                '--deviceIndex', '0',
 | 
						|
                                '--generateMipChain', 'true',
 | 
						|
                                '--inputGammaNumerator', '1.0',
 | 
						|
                                '--inputGammaDenominator', '1.0',
 | 
						|
                                '--outputGammaNumerator', '1.0',
 | 
						|
                                '--outputGammaDenominator', '1.0',
 | 
						|
                                '--outputNum', '1',
 | 
						|
                                '--output0', output_file_rad,
 | 
						|
                                '--output0params', 'hdr,rgbe,latlong'
 | 
						|
                            ]
 | 
						|
 | 
						|
                            subprocess.call(envpipe3)
 | 
						|
 | 
						|
                        else:
 | 
						|
 | 
						|
                            envpipe3 = cmft_path + \
 | 
						|
                                ' --input "' + input2 + '"' + \
 | 
						|
                                ' --filter radiance' + \
 | 
						|
                                ' --dstFaceSize ' + str(face_size) + \
 | 
						|
                                ' --srcFaceSize ' + str(face_size) + \
 | 
						|
                                ' --excludeBase false' + \
 | 
						|
                                ' --glossScale 8' + \
 | 
						|
                                ' --glossBias 3' + \
 | 
						|
                                ' --lightingModel blinnbrdf' + \
 | 
						|
                                ' --edgeFixup none' + \
 | 
						|
                                ' --numCpuProcessingThreads ' + str(cpu_count) + \
 | 
						|
                                ' --useOpenCL ' + use_opencl + \
 | 
						|
                                ' --clVendor anyGpuVendor' + \
 | 
						|
                                ' --deviceType gpu' + \
 | 
						|
                                ' --deviceIndex 0' + \
 | 
						|
                                ' --generateMipChain true' + \
 | 
						|
                                ' --inputGammaNumerator ' + '1.0' + \
 | 
						|
                                ' --inputGammaDenominator 1.0' + \
 | 
						|
                                ' --outputGammaNumerator 1.0' + \
 | 
						|
                                ' --outputGammaDenominator 1.0' + \
 | 
						|
                                ' --outputNum 1' + \
 | 
						|
                                ' --output0 "' + output_file_rad + '"' + \
 | 
						|
                                ' --output0params hdr,rgbe,latlong'
 | 
						|
 | 
						|
                            subprocess.call([envpipe3], shell=True)
 | 
						|
 | 
						|
                    for obj in bpy.context.scene.objects:
 | 
						|
                        obj.select_set(False)
 | 
						|
 | 
						|
                    cam_obj.select_set(True)
 | 
						|
                    bpy.ops.object.delete()
 | 
						|
                    bpy.context.scene.render.resolution_x = prevResx
 | 
						|
                    bpy.context.scene.render.resolution_y = prevResy
 | 
						|
                    bpy.context.scene.camera = prevCam
 | 
						|
                    bpy.context.scene.render.engine = prevEngine
 | 
						|
 | 
						|
                    print("Finished building environment probes")
 | 
						|
 | 
						|
 | 
						|
        return {'RUNNING_MODAL'}
 | 
						|
 | 
						|
class TLM_CleanBuildEnvironmentProbes(bpy.types.Operator): 
 | 
						|
    bl_idname = "tlm.clean_environmentprobe"
 | 
						|
    bl_label = "Clean Environment Probes"
 | 
						|
    bl_description = "Clean Environment Probes"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        scene = context.scene
 | 
						|
 | 
						|
        savedir = os.path.dirname(bpy.data.filepath)
 | 
						|
        dirpath = os.path.join(savedir, "Probes")
 | 
						|
 | 
						|
        if os.path.isdir(dirpath):
 | 
						|
            for file in os.listdir(dirpath):
 | 
						|
                os.remove(os.path.join(dirpath + "/" + file))
 | 
						|
 | 
						|
        return {'FINISHED'}
 | 
						|
 | 
						|
class TLM_MergeAdjacentActors(bpy.types.Operator): 
 | 
						|
    bl_idname = "tlm.merge_adjacent_actors"
 | 
						|
    bl_label = "Merge adjacent actors"
 | 
						|
    bl_description = "Merges the adjacent faces/vertices of selected objects"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        scene = context.scene
 | 
						|
 | 
						|
        return {'FINISHED'}
 | 
						|
 | 
						|
class TLM_PrepareUVMaps(bpy.types.Operator): 
 | 
						|
    bl_idname = "tlm.prepare_uvmaps"
 | 
						|
    bl_label = "Prepare UV maps"
 | 
						|
    bl_description = "Prepare UV lightmaps for selected objects"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        scene = context.scene
 | 
						|
 | 
						|
        return {'FINISHED'}
 | 
						|
 | 
						|
class TLM_LoadLightmaps(bpy.types.Operator): 
 | 
						|
    bl_idname = "tlm.load_lightmaps"
 | 
						|
    bl_label = "Load Lightmaps"
 | 
						|
    bl_description = "Load lightmaps from selected folder"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        scene = context.scene
 | 
						|
 | 
						|
        utility.transfer_load()
 | 
						|
 | 
						|
        print("Transfer finished")
 | 
						|
 | 
						|
        build.finish_assemble(self, 1, 1)
 | 
						|
 | 
						|
        return {'FINISHED'}
 | 
						|
 | 
						|
class TLM_ToggleTexelDensity(bpy.types.Operator): 
 | 
						|
    bl_idname = "tlm.toggle_texel_density"
 | 
						|
    bl_label = "Toggle Texel Density"
 | 
						|
    bl_description = "Toggle visualize lightmap texel density for selected objects"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        scene = context.scene
 | 
						|
 | 
						|
        for obj in bpy.context.selected_objects:
 | 
						|
            if obj.type == "MESH":
 | 
						|
                uv_layers = obj.data.uv_layers
 | 
						|
 | 
						|
                #if the object has a td_vis in the uv maps, toggle off
 | 
						|
                #else toggle on
 | 
						|
 | 
						|
                if obj.TLM_ObjectProperties.tlm_use_default_channel:
 | 
						|
 | 
						|
                    for i in range(0, len(uv_layers)):
 | 
						|
                        if uv_layers[i].name == 'UVMap_Lightmap':
 | 
						|
                            uv_layers.active_index = i
 | 
						|
                            break
 | 
						|
                else:
 | 
						|
 | 
						|
                    for i in range(0, len(uv_layers)):
 | 
						|
                        if uv_layers[i].name == obj.TLM_ObjectProperties.tlm_uv_channel:
 | 
						|
                            uv_layers.active_index = i
 | 
						|
                            break
 | 
						|
 | 
						|
                #filepath = r"C:\path\to\image.png"
 | 
						|
 | 
						|
                #img = bpy.data.images.load(filepath)
 | 
						|
 | 
						|
                for area in bpy.context.screen.areas:
 | 
						|
                    if area.type == 'VIEW_3D':
 | 
						|
                        space_data = area.spaces.active
 | 
						|
                        bpy.ops.screen.area_dupli('INVOKE_DEFAULT')
 | 
						|
                        new_window = context.window_manager.windows[-1]
 | 
						|
 | 
						|
                        area = new_window.screen.areas[-1]
 | 
						|
                        area.type = 'VIEW_3D'
 | 
						|
                        #bg = space_data.background_images.new()
 | 
						|
                        print(bpy.context.object)
 | 
						|
                        bpy.ops.object.bake_td_uv_to_vc()
 | 
						|
 | 
						|
                        #bg.image = img
 | 
						|
                        break
 | 
						|
 | 
						|
                
 | 
						|
                #set active uv_layer to 
 | 
						|
                
 | 
						|
 | 
						|
        print("TLM_Viz_Toggle")
 | 
						|
 | 
						|
        return {'FINISHED'}
 | 
						|
 | 
						|
class TLM_DisableSpecularity(bpy.types.Operator): 
 | 
						|
    bl_idname = "tlm.disable_specularity"
 | 
						|
    bl_label = "Disable specularity"
 | 
						|
    bl_description = "Disables specularity from set"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        if bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Scene":
 | 
						|
            for obj in bpy.context.scene.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
 | 
						|
                    for slot in obj.material_slots:
 | 
						|
 | 
						|
                        mat = slot.material
 | 
						|
                        
 | 
						|
                        if mat.node_tree:
 | 
						|
 | 
						|
                            for node in mat.node_tree.nodes:
 | 
						|
 | 
						|
                                if node.type == "BSDF_PRINCIPLED":
 | 
						|
 | 
						|
                                    for inp in node.inputs:
 | 
						|
 | 
						|
                                        if inp.name == "Specular":
 | 
						|
 | 
						|
                                            inp.default_value = 0.0
 | 
						|
 | 
						|
                                            if inp.links and bpy.context.scene.TLM_SceneProperties.tlm_remove_met_spec_link:
 | 
						|
 | 
						|
                                                mat.node_tree.links.remove(inp.links[0])
 | 
						|
 | 
						|
        elif bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Selection":
 | 
						|
            for obj in bpy.context.selected_objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
 | 
						|
                    for slot in obj.material_slots:
 | 
						|
 | 
						|
                        mat = slot.material
 | 
						|
                        
 | 
						|
                        if mat.node_tree:
 | 
						|
 | 
						|
                            for node in mat.node_tree.nodes:
 | 
						|
 | 
						|
                                if node.type == "BSDF_PRINCIPLED":
 | 
						|
 | 
						|
                                    for inp in node.inputs:
 | 
						|
 | 
						|
                                        if inp.name == "Specular":
 | 
						|
 | 
						|
                                            inp.default_value = 0.0
 | 
						|
 | 
						|
                                            if inp.links and bpy.context.scene.TLM_SceneProperties.tlm_remove_met_spec_link:
 | 
						|
 | 
						|
                                                mat.node_tree.links.remove(inp.links[0])
 | 
						|
 | 
						|
        else: #Enabled
 | 
						|
            for obj in bpy.context.scene.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
                    if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
 | 
						|
 | 
						|
                        for slot in obj.material_slots:
 | 
						|
 | 
						|
                            mat = slot.material
 | 
						|
                            
 | 
						|
                            if mat.node_tree:
 | 
						|
 | 
						|
                                for node in mat.node_tree.nodes:
 | 
						|
 | 
						|
                                    if node.type == "BSDF_PRINCIPLED":
 | 
						|
 | 
						|
                                        for inp in node.inputs:
 | 
						|
 | 
						|
                                            if inp.name == "Specular":
 | 
						|
 | 
						|
                                                inp.default_value = 0.0
 | 
						|
 | 
						|
                                                if inp.links and bpy.context.scene.TLM_SceneProperties.tlm_remove_met_spec_link:
 | 
						|
 | 
						|
                                                    mat.node_tree.links.remove(inp.links[0])
 | 
						|
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
class TLM_DisableMetallic(bpy.types.Operator): 
 | 
						|
    bl_idname = "tlm.disable_metallic"
 | 
						|
    bl_label = "Disable metallic"
 | 
						|
    bl_description = "Disables metallic from set"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        if bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Scene":
 | 
						|
            for obj in bpy.context.scene.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
 | 
						|
                    for slot in obj.material_slots:
 | 
						|
 | 
						|
                        mat = slot.material
 | 
						|
 | 
						|
                        for node in mat.node_tree.nodes:
 | 
						|
 | 
						|
                            if node.type == "BSDF_PRINCIPLED":
 | 
						|
 | 
						|
                                for inp in node.inputs:
 | 
						|
 | 
						|
                                    if inp.name == "Metallic":
 | 
						|
 | 
						|
                                        inp.default_value = 0.0
 | 
						|
 | 
						|
                                        if inp.links and bpy.context.scene.TLM_SceneProperties.tlm_remove_met_spec_link:
 | 
						|
 | 
						|
                                            mat.node_tree.links.remove(inp.links[0])
 | 
						|
 | 
						|
        elif bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Selection":
 | 
						|
            for obj in bpy.context.selected_objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
 | 
						|
                    for slot in obj.material_slots:
 | 
						|
 | 
						|
                        mat = slot.material
 | 
						|
 | 
						|
                        for node in mat.node_tree.nodes:
 | 
						|
 | 
						|
                            if node.type == "BSDF_PRINCIPLED":
 | 
						|
 | 
						|
                                for inp in node.inputs:
 | 
						|
 | 
						|
                                    if inp.name == "Metallic":
 | 
						|
 | 
						|
                                        inp.default_value = 0.0
 | 
						|
 | 
						|
                                        if inp.links and bpy.context.scene.TLM_SceneProperties.tlm_remove_met_spec_link:
 | 
						|
 | 
						|
                                            mat.node_tree.links.remove(inp.links[0])
 | 
						|
 | 
						|
        else: #Enabled
 | 
						|
            for obj in bpy.context.scene.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
                    if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
 | 
						|
 | 
						|
                        for slot in obj.material_slots:
 | 
						|
 | 
						|
                            mat = slot.material
 | 
						|
 | 
						|
                            for node in mat.node_tree.nodes:
 | 
						|
 | 
						|
                                if node.type == "BSDF_PRINCIPLED":
 | 
						|
 | 
						|
                                    for inp in node.inputs:
 | 
						|
 | 
						|
                                        if inp.name == "Metallic":
 | 
						|
 | 
						|
                                            inp.default_value = 0.0
 | 
						|
 | 
						|
                                            if inp.links and bpy.context.scene.TLM_SceneProperties.tlm_remove_met_spec_link:
 | 
						|
 | 
						|
                                                mat.node_tree.links.remove(inp.links[0])
 | 
						|
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
class TLM_RemoveEmptyImages(bpy.types.Operator): 
 | 
						|
 | 
						|
    bl_idname = "tlm.remove_empty_images"
 | 
						|
    bl_label = "Remove Empty Images"
 | 
						|
    bl_description = "Removes empty images from scene materials"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        for mat in bpy.data.materials:
 | 
						|
 | 
						|
            nodetree = mat.node_tree
 | 
						|
 | 
						|
            if nodetree:
 | 
						|
 | 
						|
                for node in nodetree.nodes:
 | 
						|
 | 
						|
                    if node.name == "Baked Image":
 | 
						|
 | 
						|
                        print(node.name)
 | 
						|
 | 
						|
                        nodetree.nodes.remove(node)
 | 
						|
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
 | 
						|
class TLM_PostAtlasSpecialsMenu(bpy.types.Menu):
 | 
						|
    bl_label = "Lightmap"
 | 
						|
    bl_idname = "TLM_MT_PostAtlasListSpecials"
 | 
						|
 | 
						|
    def draw(self, context):
 | 
						|
        layout = self.layout
 | 
						|
        layout.operator("tlm.add_collections_post")
 | 
						|
        layout.operator("tlm.add_selected_collections_post")
 | 
						|
 | 
						|
class TLM_AddCollectionsPost(bpy.types.Operator): 
 | 
						|
    bl_idname = "tlm.add_collections_post"
 | 
						|
    bl_label = "Add collections"
 | 
						|
    bl_description = "Adds all collections to atlases"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    resolution : bpy.props.EnumProperty(
 | 
						|
            items = [('32', '32', 'TODO'),
 | 
						|
                    ('64', '64', 'TODO'),
 | 
						|
                    ('128', '128', 'TODO'),
 | 
						|
                    ('256', '256', 'TODO'),
 | 
						|
                    ('512', '512', 'TODO'),
 | 
						|
                    ('1024', '1024', 'TODO'),
 | 
						|
                    ('2048', '2048', 'TODO'),
 | 
						|
                    ('4096', '4096', 'TODO'),
 | 
						|
                    ('8192', '8192', 'TODO')],
 | 
						|
                    name = "Atlas Lightmap Resolution", 
 | 
						|
                    description="Atlas lightmap resolution",
 | 
						|
                    default='256')
 | 
						|
 | 
						|
    unwrap_modes = [('Lightmap', 'Lightmap', 'Use Blender Lightmap Pack algorithm'),
 | 
						|
                 ('SmartProject', 'Smart Project', 'Use Blender Smart Project algorithm')]
 | 
						|
 | 
						|
    if "blender_xatlas" in bpy.context.preferences.addons.keys():
 | 
						|
        unwrap_modes.append(('Xatlas', 'Xatlas', 'Use Xatlas addon packing algorithm'))
 | 
						|
 | 
						|
    unwrap : bpy.props.EnumProperty(
 | 
						|
        items = unwrap_modes,
 | 
						|
                name = "Unwrap Mode", 
 | 
						|
                description="Atlas unwrapping method", 
 | 
						|
                default='SmartProject')
 | 
						|
 | 
						|
    margin : bpy.props.FloatProperty(
 | 
						|
        name="Unwrap Margin", 
 | 
						|
        default=0.1, 
 | 
						|
        min=0.0, 
 | 
						|
        max=1.0, 
 | 
						|
        subtype='FACTOR')
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def poll(cls, context):
 | 
						|
        return True
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
        
 | 
						|
        for collection in bpy.context.scene.collection.children:
 | 
						|
            
 | 
						|
            #Add a new atlas with collection name
 | 
						|
            #Traverse before adding
 | 
						|
            scene = bpy.context.scene
 | 
						|
            scene.TLM_PostAtlasList.add()
 | 
						|
            scene.TLM_PostAtlasListItem = len(scene.TLM_PostAtlasList) - 1
 | 
						|
 | 
						|
            scene.TLM_PostAtlasList[len(scene.TLM_PostAtlasList) - 1].name = collection.name
 | 
						|
            scene.TLM_PostAtlasList[collection.name].tlm_atlas_lightmap_unwrap_mode = self.unwrap
 | 
						|
            scene.TLM_PostAtlasList[collection.name].tlm_atlas_lightmap_resolution = self.resolution
 | 
						|
            scene.TLM_PostAtlasList[collection.name].tlm_atlas_unwrap_margin = self.margin
 | 
						|
            
 | 
						|
            for obj in collection.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
                    obj.TLM_ObjectProperties.tlm_mesh_lightmap_use = True
 | 
						|
                    obj.TLM_ObjectProperties.tlm_postpack_object = True
 | 
						|
                    obj.TLM_ObjectProperties.tlm_postatlas_pointer = collection.name
 | 
						|
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
    def invoke(self, context, event):
 | 
						|
        return context.window_manager.invoke_props_dialog(self)
 | 
						|
 | 
						|
    def draw(self, context):
 | 
						|
        row = self.layout
 | 
						|
        row.prop(self, "unwrap", text="Unwrap mode")
 | 
						|
        row.prop(self, "resolution", text="Resolution")
 | 
						|
        row.prop(self, "margin", text="Margin")
 | 
						|
 | 
						|
class TLM_AddSelectedCollectionsPost(bpy.types.Operator): 
 | 
						|
    bl_idname = "tlm.add_selected_collections_post"
 | 
						|
    bl_label = "Add selected collections"
 | 
						|
    bl_description = "Add the collections of the selected objects"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    resolution : bpy.props.EnumProperty(
 | 
						|
            items = [('32', '32', 'TODO'),
 | 
						|
                    ('64', '64', 'TODO'),
 | 
						|
                    ('128', '128', 'TODO'),
 | 
						|
                    ('256', '256', 'TODO'),
 | 
						|
                    ('512', '512', 'TODO'),
 | 
						|
                    ('1024', '1024', 'TODO'),
 | 
						|
                    ('2048', '2048', 'TODO'),
 | 
						|
                    ('4096', '4096', 'TODO'),
 | 
						|
                    ('8192', '8192', 'TODO')],
 | 
						|
                    name = "Atlas Lightmap Resolution", 
 | 
						|
                    description="Atlas lightmap resolution",
 | 
						|
                    default='256')
 | 
						|
 | 
						|
    unwrap_modes = [('Lightmap', 'Lightmap', 'Use Blender Lightmap Pack algorithm'),
 | 
						|
                 ('SmartProject', 'Smart Project', 'Use Blender Smart Project algorithm')]
 | 
						|
 | 
						|
    if "blender_xatlas" in bpy.context.preferences.addons.keys():
 | 
						|
        unwrap_modes.append(('Xatlas', 'Xatlas', 'Use Xatlas addon packing algorithm'))
 | 
						|
 | 
						|
    unwrap : bpy.props.EnumProperty(
 | 
						|
        items = unwrap_modes,
 | 
						|
                name = "Unwrap Mode", 
 | 
						|
                description="Atlas unwrapping method", 
 | 
						|
                default='SmartProject')
 | 
						|
 | 
						|
    margin : bpy.props.FloatProperty(
 | 
						|
        name="Unwrap Margin", 
 | 
						|
        default=0.1, 
 | 
						|
        min=0.0, 
 | 
						|
        max=1.0, 
 | 
						|
        subtype='FACTOR')
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def poll(cls, context):
 | 
						|
        return True
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        collections = []
 | 
						|
 | 
						|
        for obj in bpy.context.selected_objects:
 | 
						|
 | 
						|
            obj_collection = obj.users_collection[0]
 | 
						|
 | 
						|
            if obj_collection.name not in collections:
 | 
						|
 | 
						|
                collections.append(obj_collection.name)
 | 
						|
 | 
						|
        print("Collections:" + str(collections))
 | 
						|
        
 | 
						|
        for collection in bpy.context.scene.collection.children:
 | 
						|
 | 
						|
            if collection.name in collections:
 | 
						|
                
 | 
						|
                #Add a new atlas with collection name
 | 
						|
                #Traverse before adding
 | 
						|
                scene = bpy.context.scene
 | 
						|
                scene.TLM_PostAtlasList.add()
 | 
						|
                scene.TLM_PostAtlasListItem = len(scene.TLM_PostAtlasList) - 1
 | 
						|
 | 
						|
                scene.TLM_PostAtlasList[len(scene.TLM_PostAtlasList) - 1].name = collection.name
 | 
						|
                scene.TLM_PostAtlasList[collection.name].tlm_atlas_lightmap_unwrap_mode = self.unwrap
 | 
						|
                scene.TLM_PostAtlasList[collection.name].tlm_atlas_lightmap_resolution = self.resolution
 | 
						|
                scene.TLM_PostAtlasList[collection.name].tlm_atlas_unwrap_margin = self.margin
 | 
						|
                
 | 
						|
                for obj in collection.objects:
 | 
						|
                    if obj.type == "MESH":
 | 
						|
                        obj.TLM_ObjectProperties.tlm_mesh_lightmap_use = True
 | 
						|
                        obj.TLM_ObjectProperties.tlm_postpack_object = True
 | 
						|
                        obj.TLM_ObjectProperties.tlm_postatlas_pointer = collection.name
 | 
						|
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
    def invoke(self, context, event):
 | 
						|
        return context.window_manager.invoke_props_dialog(self)
 | 
						|
 | 
						|
    def draw(self, context):
 | 
						|
        row = self.layout
 | 
						|
        row.prop(self, "unwrap", text="Unwrap mode")
 | 
						|
        row.prop(self, "resolution", text="Resolution")
 | 
						|
        row.prop(self, "margin", text="Margin")
 | 
						|
 | 
						|
class TLM_AtlasSpecialsMenu(bpy.types.Menu):
 | 
						|
    bl_label = "Lightmap"
 | 
						|
    bl_idname = "TLM_MT_AtlasListSpecials"
 | 
						|
 | 
						|
    def draw(self, context):
 | 
						|
        layout = self.layout
 | 
						|
        layout.operator("tlm.add_collections")
 | 
						|
        layout.operator("tlm.add_selected_collections")
 | 
						|
 | 
						|
class TLM_AddCollections(bpy.types.Operator): 
 | 
						|
    bl_idname = "tlm.add_collections"
 | 
						|
    bl_label = "Add all collections"
 | 
						|
    bl_description = "Adds all collections to atlases"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    resolution : bpy.props.EnumProperty(
 | 
						|
            items = [('32', '32', 'TODO'),
 | 
						|
                    ('64', '64', 'TODO'),
 | 
						|
                    ('128', '128', 'TODO'),
 | 
						|
                    ('256', '256', 'TODO'),
 | 
						|
                    ('512', '512', 'TODO'),
 | 
						|
                    ('1024', '1024', 'TODO'),
 | 
						|
                    ('2048', '2048', 'TODO'),
 | 
						|
                    ('4096', '4096', 'TODO'),
 | 
						|
                    ('8192', '8192', 'TODO')],
 | 
						|
                    name = "Atlas Lightmap Resolution", 
 | 
						|
                    description="Atlas lightmap resolution",
 | 
						|
                    default='256')
 | 
						|
 | 
						|
    unwrap_modes = [('Lightmap', 'Lightmap', 'Use Blender Lightmap Pack algorithm'),
 | 
						|
                 ('SmartProject', 'Smart Project', 'Use Blender Smart Project algorithm'),
 | 
						|
                 ('Copy', 'Copy existing', 'Use the existing UV channel')]
 | 
						|
 | 
						|
    if "blender_xatlas" in bpy.context.preferences.addons.keys():
 | 
						|
        unwrap_modes.append(('Xatlas', 'Xatlas', 'Use Xatlas addon packing algorithm'))
 | 
						|
 | 
						|
    unwrap : bpy.props.EnumProperty(
 | 
						|
        items = unwrap_modes,
 | 
						|
                name = "Unwrap Mode", 
 | 
						|
                description="Atlas unwrapping method", 
 | 
						|
                default='SmartProject')
 | 
						|
 | 
						|
    margin : bpy.props.FloatProperty(
 | 
						|
        name="Unwrap Margin", 
 | 
						|
        default=0.1, 
 | 
						|
        min=0.0, 
 | 
						|
        max=1.0, 
 | 
						|
        subtype='FACTOR')
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def poll(cls, context):
 | 
						|
        return True
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        for collection in bpy.context.scene.collection.children:
 | 
						|
            
 | 
						|
            #Add a new atlas with collection name
 | 
						|
            #Traverse before adding
 | 
						|
            scene = bpy.context.scene
 | 
						|
            scene.TLM_AtlasList.add()
 | 
						|
            scene.TLM_AtlasListItem = len(scene.TLM_AtlasList) - 1
 | 
						|
 | 
						|
            scene.TLM_AtlasList[len(scene.TLM_AtlasList) - 1].name = collection.name
 | 
						|
            scene.TLM_AtlasList[collection.name].tlm_atlas_lightmap_unwrap_mode = self.unwrap
 | 
						|
            scene.TLM_AtlasList[collection.name].tlm_atlas_lightmap_resolution = self.resolution
 | 
						|
            scene.TLM_AtlasList[collection.name].tlm_atlas_unwrap_margin = self.margin
 | 
						|
            
 | 
						|
            for obj in collection.objects:
 | 
						|
                if obj.type == "MESH":
 | 
						|
                    obj.TLM_ObjectProperties.tlm_mesh_lightmap_use = True
 | 
						|
                    obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode = "AtlasGroupA"
 | 
						|
                    obj.TLM_ObjectProperties.tlm_atlas_pointer = collection.name
 | 
						|
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
    def invoke(self, context, event):
 | 
						|
        return context.window_manager.invoke_props_dialog(self)
 | 
						|
 | 
						|
    def draw(self, context):
 | 
						|
        row = self.layout
 | 
						|
        row.prop(self, "unwrap", text="Unwrap mode")
 | 
						|
        row.prop(self, "resolution", text="Resolution")
 | 
						|
        row.prop(self, "margin", text="Margin")
 | 
						|
 | 
						|
class TLM_AddSelectedCollections(bpy.types.Operator): 
 | 
						|
    bl_idname = "tlm.add_selected_collections"
 | 
						|
    bl_label = "Add the collections of the selected objects"
 | 
						|
    bl_description = "Add the collections of the selected objects"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    resolution : bpy.props.EnumProperty(
 | 
						|
            items = [('32', '32', 'TODO'),
 | 
						|
                    ('64', '64', 'TODO'),
 | 
						|
                    ('128', '128', 'TODO'),
 | 
						|
                    ('256', '256', 'TODO'),
 | 
						|
                    ('512', '512', 'TODO'),
 | 
						|
                    ('1024', '1024', 'TODO'),
 | 
						|
                    ('2048', '2048', 'TODO'),
 | 
						|
                    ('4096', '4096', 'TODO'),
 | 
						|
                    ('8192', '8192', 'TODO')],
 | 
						|
                    name = "Atlas Lightmap Resolution", 
 | 
						|
                    description="Atlas lightmap resolution",
 | 
						|
                    default='256')
 | 
						|
 | 
						|
    unwrap_modes = [('Lightmap', 'Lightmap', 'Use Blender Lightmap Pack algorithm'),
 | 
						|
                 ('SmartProject', 'Smart Project', 'Use Blender Smart Project algorithm'),
 | 
						|
                 ('Copy', 'Copy existing', 'Use the existing UV channel')]
 | 
						|
 | 
						|
    if "blender_xatlas" in bpy.context.preferences.addons.keys():
 | 
						|
        unwrap_modes.append(('Xatlas', 'Xatlas', 'Use Xatlas addon packing algorithm'))
 | 
						|
 | 
						|
    unwrap : bpy.props.EnumProperty(
 | 
						|
        items = unwrap_modes,
 | 
						|
                name = "Unwrap Mode", 
 | 
						|
                description="Atlas unwrapping method", 
 | 
						|
                default='SmartProject')
 | 
						|
 | 
						|
    margin : bpy.props.FloatProperty(
 | 
						|
        name="Unwrap Margin", 
 | 
						|
        default=0.1, 
 | 
						|
        min=0.0, 
 | 
						|
        max=1.0, 
 | 
						|
        subtype='FACTOR')
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def poll(cls, context):
 | 
						|
        return True
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        collections = []
 | 
						|
 | 
						|
        for obj in bpy.context.selected_objects:
 | 
						|
 | 
						|
            obj_collection = obj.users_collection[0]
 | 
						|
 | 
						|
            if obj_collection.name not in collections:
 | 
						|
 | 
						|
                collections.append(obj_collection.name)
 | 
						|
 | 
						|
        print("Collections:" + str(collections))
 | 
						|
 | 
						|
        for collection in bpy.context.scene.collection.children:
 | 
						|
 | 
						|
            if collection.name in collections:
 | 
						|
                
 | 
						|
                #Add a new atlas with collection name
 | 
						|
                #Traverse before adding
 | 
						|
                scene = bpy.context.scene
 | 
						|
                scene.TLM_AtlasList.add()
 | 
						|
                scene.TLM_AtlasListItem = len(scene.TLM_AtlasList) - 1
 | 
						|
 | 
						|
                scene.TLM_AtlasList[len(scene.TLM_AtlasList) - 1].name = collection.name
 | 
						|
                scene.TLM_AtlasList[collection.name].tlm_atlas_lightmap_unwrap_mode = self.unwrap
 | 
						|
                scene.TLM_AtlasList[collection.name].tlm_atlas_lightmap_resolution = self.resolution
 | 
						|
                scene.TLM_AtlasList[collection.name].tlm_atlas_unwrap_margin = self.margin
 | 
						|
                
 | 
						|
                for obj in collection.objects:
 | 
						|
                    if obj.type == "MESH":
 | 
						|
                        obj.TLM_ObjectProperties.tlm_mesh_lightmap_use = True
 | 
						|
                        obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode = "AtlasGroupA"
 | 
						|
                        obj.TLM_ObjectProperties.tlm_atlas_pointer = collection.name
 | 
						|
 | 
						|
        return{'FINISHED'}
 | 
						|
 | 
						|
    def invoke(self, context, event):
 | 
						|
        return context.window_manager.invoke_props_dialog(self)
 | 
						|
 | 
						|
    def draw(self, context):
 | 
						|
        row = self.layout
 | 
						|
        row.prop(self, "unwrap", text="Unwrap mode")
 | 
						|
        row.prop(self, "resolution", text="Resolution")
 | 
						|
        row.prop(self, "margin", text="Margin")
 | 
						|
        
 | 
						|
#Atlas disable objects
 | 
						|
 | 
						|
class TLM_Reset(bpy.types.Operator):
 | 
						|
    bl_idname = "tlm.reset"
 | 
						|
    bl_label = "Resets all UI and settings"
 | 
						|
    bl_description = "Reset UI and objects"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def poll(cls, context):
 | 
						|
        return True
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
        self.report({'INFO'}, "YES!")
 | 
						|
        return {'FINISHED'}
 | 
						|
 | 
						|
    def invoke(self, context, event):
 | 
						|
        return context.window_manager.invoke_confirm(self, event)
 | 
						|
 | 
						|
# class TLM_Reset2(bpy.types.Operator):
 | 
						|
#     bl_idname = "tlm.reset2"
 | 
						|
#     bl_label = "Do you really want to do that?"
 | 
						|
#     bl_options = {'REGISTER', 'INTERNAL'}
 | 
						|
 | 
						|
#     prop1: bpy.props.BoolProperty()
 | 
						|
#     prop2: bpy.props.BoolProperty()
 | 
						|
 | 
						|
#     @classmethod
 | 
						|
#     def poll(cls, context):
 | 
						|
#         return True
 | 
						|
 | 
						|
#     def execute(self, context):
 | 
						|
#         self.report({'INFO'}, "YES!")
 | 
						|
#         return {'FINISHED'}
 | 
						|
 | 
						|
#     def invoke(self, context, event):
 | 
						|
#         return context.window_manager.invoke_props_dialog(self)
 | 
						|
 | 
						|
#     def draw(self, context):
 | 
						|
#         row = self.layout
 | 
						|
#         row.prop(self, "prop1", text="Property A")
 | 
						|
#         row.prop(self, "prop2", text="Property B")
 | 
						|
 | 
						|
def TLM_DoubleResolution():
 | 
						|
    pass
 | 
						|
 | 
						|
def TLM_HalfResolution():
 | 
						|
    pass
 | 
						|
 | 
						|
def TLM_DivideLMGroups():
 | 
						|
    pass
 | 
						|
 | 
						|
class TLM_CalcTexDex(bpy.types.Operator):
 | 
						|
    bl_idname = "tlm.calctexdex"
 | 
						|
    bl_label = "Calculate Texel Density"
 | 
						|
    bl_description = "Calculates Texel Density of selected object"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def poll(cls, context):
 | 
						|
        return True
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
        return {'FINISHED'}
 | 
						|
 | 
						|
class TLM_AddGLTFNode(bpy.types.Operator):
 | 
						|
    bl_idname = "tlm.add_gltf_node"
 | 
						|
    bl_label = "Add GLTF Node"
 | 
						|
    bl_description = "Add to GLTF node to active material and connect lightmap if present"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        scene = context.scene
 | 
						|
        cycles = scene.cycles
 | 
						|
        material = bpy.context.active_object.active_material
 | 
						|
 | 
						|
        nodes = material.node_tree.nodes
 | 
						|
        # create group data
 | 
						|
        gltf_settings = bpy.data.node_groups.get('glTF Settings')
 | 
						|
        if gltf_settings is None:
 | 
						|
            bpy.data.node_groups.new('glTF Settings', 'ShaderNodeTree')
 | 
						|
        
 | 
						|
        # add group to node tree
 | 
						|
        gltf_settings_node = nodes.get('glTF Settings')
 | 
						|
        if gltf_settings_node is None:
 | 
						|
            gltf_settings_node = nodes.new('ShaderNodeGroup')
 | 
						|
            gltf_settings_node.name = 'glTF Settings'
 | 
						|
            gltf_settings_node.node_tree = bpy.data.node_groups['glTF Settings']
 | 
						|
 | 
						|
        # create group inputs
 | 
						|
        if gltf_settings_node.inputs.get('Occlusion') is None:
 | 
						|
            gltf_settings_node.inputs.new('NodeSocketFloat','Occlusion')
 | 
						|
 | 
						|
        #return gltf_settings_node
 | 
						|
 | 
						|
        return {'FINISHED'}
 | 
						|
 | 
						|
class TLM_ShiftMultiplyLinks(bpy.types.Operator):
 | 
						|
    bl_idname = "tlm.shift_multiply_links"
 | 
						|
    bl_label = "Shift multiply links"
 | 
						|
    bl_description = "Shift multiply links for active material"
 | 
						|
    bl_options = {'REGISTER', 'UNDO'}
 | 
						|
 | 
						|
    def execute(self, context):
 | 
						|
 | 
						|
        scene = context.scene
 | 
						|
        cycles = scene.cycles
 | 
						|
        material = bpy.context.active_object.active_material
 | 
						|
 | 
						|
        nodes = material.node_tree.nodes
 | 
						|
 | 
						|
        LM_Node = nodes.get("TLM_Lightmap")
 | 
						|
        Multi_Node = nodes.get("Lightmap_Multiplication")
 | 
						|
        Base_Node = nodes.get("Lightmap_BasecolorNode_A")
 | 
						|
 | 
						|
        material.node_tree.links.remove(LM_Node.outputs[0].links[0])
 | 
						|
        material.node_tree.links.remove(Base_Node.outputs[0].links[0])
 | 
						|
 | 
						|
        material.node_tree.links.new(LM_Node.outputs[0], Multi_Node.inputs[2])
 | 
						|
        material.node_tree.links.new(Base_Node.outputs[0], Multi_Node.inputs[1])
 | 
						|
 | 
						|
        return {'FINISHED'}
 |