Update lightmapper to Blender 2.9+
Finalized update to support Blender 2.9+ as well as new features, fixes and more stability
This commit is contained in:
parent
cbb8ee4bae
commit
ef8fb21536
|
@ -1 +1 @@
|
|||
__all__ = ('Operators', 'Properties', 'Utility', 'Keymap')
|
||||
__all__ = ('Operators', 'Panels', 'Properties', 'Preferences', 'Utility', 'Keymap')
|
BIN
blender/arm/lightmapper/assets/TLM_Overlay.png
Normal file
BIN
blender/arm/lightmapper/assets/TLM_Overlay.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
@ -1,7 +0,0 @@
|
|||
from . import keymap
|
||||
|
||||
def register():
|
||||
keymap.register()
|
||||
|
||||
def unregister():
|
||||
keymap.unregister()
|
|
@ -9,6 +9,8 @@ def register():
|
|||
winman = bpy.context.window_manager
|
||||
keyman = winman.keyconfigs.addon.keymaps.new(name='Window', space_type='EMPTY', region_type="WINDOW")
|
||||
|
||||
|
||||
#TODO - In Armory3D, merge with keymap.py
|
||||
keyman.keymap_items.new('tlm.build_lightmaps', type='F6', value='PRESS')
|
||||
keyman.keymap_items.new('tlm.clean_lightmaps', type='F7', value='PRESS')
|
||||
tlm_keymaps.append(keyman)
|
||||
|
|
|
@ -6,10 +6,11 @@ classes = [
|
|||
tlm.TLM_BuildLightmaps,
|
||||
tlm.TLM_CleanLightmaps,
|
||||
tlm.TLM_ExploreLightmaps,
|
||||
tlm.TLM_EnableSelection,
|
||||
tlm.TLM_EnableSet,
|
||||
tlm.TLM_DisableSelection,
|
||||
tlm.TLM_RemoveLightmapUV,
|
||||
tlm.TLM_SelectLightmapped,
|
||||
tlm.TLM_ToggleTexelDensity,
|
||||
installopencv.TLM_Install_OpenCV,
|
||||
tlm.TLM_AtlasListNewItem,
|
||||
tlm.TLM_AtlastListDeleteItem,
|
||||
|
@ -20,6 +21,8 @@ classes = [
|
|||
tlm.TLM_StartServer,
|
||||
tlm.TLM_BuildEnvironmentProbes,
|
||||
tlm.TLM_CleanBuildEnvironmentProbes,
|
||||
tlm.TLM_PrepareUVMaps,
|
||||
tlm.TLM_LoadLightmaps,
|
||||
imagetools.TLM_ImageUpscale,
|
||||
imagetools.TLM_ImageDownscale
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import bpy, os, time
|
||||
import bpy, os, time, importlib
|
||||
|
||||
class TLM_ImageUpscale(bpy.types.Operator):
|
||||
bl_idname = "tlm.image_upscale"
|
||||
|
@ -8,6 +8,69 @@ class TLM_ImageUpscale(bpy.types.Operator):
|
|||
|
||||
def invoke(self, context, event):
|
||||
|
||||
cv2 = importlib.util.find_spec("cv2")
|
||||
|
||||
if cv2 is None:
|
||||
print("CV2 not found - Ignoring filtering")
|
||||
return 0
|
||||
else:
|
||||
cv2 = importlib.__import__("cv2")
|
||||
|
||||
for area in bpy.context.screen.areas:
|
||||
if area.type == "IMAGE_EDITOR":
|
||||
active_image = area.spaces.active.image
|
||||
|
||||
if active_image.source == "FILE":
|
||||
img_path = active_image.filepath_raw
|
||||
filename = os.path.basename(img_path)
|
||||
|
||||
basename = os.path.splitext(filename)[0]
|
||||
extension = os.path.splitext(filename)[1]
|
||||
|
||||
size_x = active_image.size[0]
|
||||
size_y = active_image.size[1]
|
||||
|
||||
dir_path = os.path.dirname(os.path.realpath(img_path))
|
||||
|
||||
#newfile = os.path.join(dir_path, basename + "_" + str(size_x) + "_" + str(size_y) + extension)
|
||||
newfile = os.path.join(dir_path, basename + extension)
|
||||
os.rename(img_path, newfile)
|
||||
|
||||
basefile = cv2.imread(newfile, cv2.IMREAD_UNCHANGED)
|
||||
|
||||
scale_percent = 200 # percent of original size
|
||||
width = int(basefile.shape[1] * scale_percent / 100)
|
||||
height = int(basefile.shape[0] * scale_percent / 100)
|
||||
dim = (width, height)
|
||||
|
||||
if active_image.TLM_ImageProperties.tlm_image_scale_method == "Nearest":
|
||||
interp = cv2.INTER_NEAREST
|
||||
elif active_image.TLM_ImageProperties.tlm_image_scale_method == "Area":
|
||||
interp = cv2.INTER_AREA
|
||||
elif active_image.TLM_ImageProperties.tlm_image_scale_method == "Linear":
|
||||
interp = cv2.INTER_LINEAR
|
||||
elif active_image.TLM_ImageProperties.tlm_image_scale_method == "Cubic":
|
||||
interp = cv2.INTER_CUBIC
|
||||
elif active_image.TLM_ImageProperties.tlm_image_scale_method == "Lanczos":
|
||||
interp = cv2.INTER_LANCZOS4
|
||||
|
||||
resized = cv2.resize(basefile, dim, interpolation = interp)
|
||||
|
||||
#resizedFile = os.path.join(dir_path, basename + "_" + str(width) + "_" + str(height) + extension)
|
||||
resizedFile = os.path.join(dir_path, basename + extension)
|
||||
|
||||
cv2.imwrite(resizedFile, resized)
|
||||
|
||||
active_image.filepath_raw = resizedFile
|
||||
bpy.ops.image.reload()
|
||||
|
||||
print(newfile)
|
||||
print(img_path)
|
||||
|
||||
else:
|
||||
|
||||
print("Please save image")
|
||||
|
||||
print("Upscale")
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
|
@ -20,6 +83,111 @@ class TLM_ImageDownscale(bpy.types.Operator):
|
|||
|
||||
def invoke(self, context, event):
|
||||
|
||||
print("Downscale")
|
||||
cv2 = importlib.util.find_spec("cv2")
|
||||
|
||||
if cv2 is None:
|
||||
print("CV2 not found - Ignoring filtering")
|
||||
return 0
|
||||
else:
|
||||
cv2 = importlib.__import__("cv2")
|
||||
|
||||
for area in bpy.context.screen.areas:
|
||||
if area.type == "IMAGE_EDITOR":
|
||||
active_image = area.spaces.active.image
|
||||
|
||||
if active_image.source == "FILE":
|
||||
img_path = active_image.filepath_raw
|
||||
filename = os.path.basename(img_path)
|
||||
|
||||
basename = os.path.splitext(filename)[0]
|
||||
extension = os.path.splitext(filename)[1]
|
||||
|
||||
size_x = active_image.size[0]
|
||||
size_y = active_image.size[1]
|
||||
|
||||
dir_path = os.path.dirname(os.path.realpath(img_path))
|
||||
|
||||
#newfile = os.path.join(dir_path, basename + "_" + str(size_x) + "_" + str(size_y) + extension)
|
||||
newfile = os.path.join(dir_path, basename + extension)
|
||||
os.rename(img_path, newfile)
|
||||
|
||||
basefile = cv2.imread(newfile, cv2.IMREAD_UNCHANGED)
|
||||
|
||||
scale_percent = 50 # percent of original size
|
||||
width = int(basefile.shape[1] * scale_percent / 100)
|
||||
height = int(basefile.shape[0] * scale_percent / 100)
|
||||
dim = (width, height)
|
||||
|
||||
if dim[0] > 1 or dim[1] > 1:
|
||||
|
||||
if active_image.TLM_ImageProperties.tlm_image_scale_method == "Nearest":
|
||||
interp = cv2.INTER_NEAREST
|
||||
elif active_image.TLM_ImageProperties.tlm_image_scale_method == "Area":
|
||||
interp = cv2.INTER_AREA
|
||||
elif active_image.TLM_ImageProperties.tlm_image_scale_method == "Linear":
|
||||
interp = cv2.INTER_LINEAR
|
||||
elif active_image.TLM_ImageProperties.tlm_image_scale_method == "Cubic":
|
||||
interp = cv2.INTER_CUBIC
|
||||
elif active_image.TLM_ImageProperties.tlm_image_scale_method == "Lanczos":
|
||||
interp = cv2.INTER_LANCZOS4
|
||||
|
||||
resized = cv2.resize(basefile, dim, interpolation = interp)
|
||||
|
||||
#resizedFile = os.path.join(dir_path, basename + "_" + str(width) + "_" + str(height) + extension)
|
||||
resizedFile = os.path.join(dir_path, basename + extension)
|
||||
|
||||
cv2.imwrite(resizedFile, resized)
|
||||
|
||||
active_image.filepath_raw = resizedFile
|
||||
bpy.ops.image.reload()
|
||||
|
||||
print(newfile)
|
||||
print(img_path)
|
||||
|
||||
else:
|
||||
|
||||
print("Please save image")
|
||||
|
||||
print("Upscale")
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
class TLM_ImageSwitchUp(bpy.types.Operator):
|
||||
bl_idname = "tlm.image_switchup"
|
||||
bl_label = "Quickswitch Up"
|
||||
bl_description = "Switches to a cached upscaled image"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
|
||||
for area in bpy.context.screen.areas:
|
||||
if area.type == "IMAGE_EDITOR":
|
||||
active_image = area.spaces.active.image
|
||||
|
||||
if active_image.source == "FILE":
|
||||
img_path = active_image.filepath_raw
|
||||
filename = os.path.basename(img_path)
|
||||
|
||||
print("Switch up")
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
class TLM_ImageSwitchDown(bpy.types.Operator):
|
||||
bl_idname = "tlm.image_switchdown"
|
||||
bl_label = "Quickswitch Down"
|
||||
bl_description = "Switches to a cached downscaled image"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
|
||||
for area in bpy.context.screen.areas:
|
||||
if area.type == "IMAGE_EDITOR":
|
||||
active_image = area.spaces.active.image
|
||||
|
||||
if active_image.source == "FILE":
|
||||
img_path = active_image.filepath_raw
|
||||
filename = os.path.basename(img_path)
|
||||
|
||||
print("Switch Down")
|
||||
|
||||
return {'RUNNING_MODAL'}
|
|
@ -21,7 +21,10 @@ class TLM_Install_OpenCV(bpy.types.Operator):
|
|||
|
||||
print("Module OpenCV")
|
||||
|
||||
pythonbinpath = bpy.app.binary_path_python
|
||||
if (2, 91, 0) > bpy.app.version:
|
||||
pythonbinpath = bpy.app.binary_path_python
|
||||
else:
|
||||
pythonbinpath = sys.executable
|
||||
|
||||
if platform.system() == "Windows":
|
||||
pythonlibpath = os.path.join(os.path.dirname(os.path.dirname(pythonbinpath)), "lib")
|
||||
|
|
|
@ -1,9 +1,36 @@
|
|||
import bpy, os, time, blf, webbrowser, platform
|
||||
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"
|
||||
|
@ -52,13 +79,13 @@ class TLM_CleanLightmaps(bpy.types.Operator):
|
|||
for file in os.listdir(dirpath):
|
||||
os.remove(os.path.join(dirpath + "/" + file))
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == "MESH":
|
||||
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.data.objects:
|
||||
if obj.type == "MESH":
|
||||
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)
|
||||
|
||||
|
@ -75,8 +102,8 @@ class TLM_CleanLightmaps(bpy.types.Operator):
|
|||
if image.name.endswith("_baked"):
|
||||
bpy.data.images.remove(image, do_unlink=True)
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == "MESH":
|
||||
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:
|
||||
|
||||
|
@ -92,14 +119,17 @@ class TLM_CleanLightmaps(bpy.types.Operator):
|
|||
bpy.ops.object.select_all(action='DESELECT')
|
||||
obj.select_set(True)
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
#print(x)
|
||||
|
||||
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 == 'UVMap_Lightmap':
|
||||
if uv_layers[i].name == uv_channel:
|
||||
uv_layers.active_index = i
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Lightmap shift A")
|
||||
break
|
||||
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
|
@ -111,9 +141,11 @@ class TLM_CleanLightmaps(bpy.types.Operator):
|
|||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
#print(obj.name + ": Active UV: " + obj.data.uv_layers[obj.data.uv_layers.active_index].name)
|
||||
print("Resized for obj: " + obj.name)
|
||||
|
||||
if "Lightmap" in obj:
|
||||
del obj["Lightmap"]
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
class TLM_ExploreLightmaps(bpy.types.Operator):
|
||||
|
@ -153,63 +185,285 @@ class TLM_ExploreLightmaps(bpy.types.Operator):
|
|||
|
||||
return {'FINISHED'}
|
||||
|
||||
class TLM_EnableSelection(bpy.types.Operator):
|
||||
"""Enable for selection"""
|
||||
bl_idname = "tlm.enable_selection"
|
||||
bl_label = "Enable for selection"
|
||||
bl_description = "Enable for selection"
|
||||
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
|
||||
|
||||
for obj in bpy.context.selected_objects:
|
||||
obj.TLM_ObjectProperties.tlm_mesh_lightmap_use = True
|
||||
weightList = {} #ObjName : [Dimension,Weight]
|
||||
max = 0
|
||||
|
||||
if scene.TLM_SceneProperties.tlm_override_object_settings:
|
||||
obj.TLM_ObjectProperties.tlm_mesh_lightmap_resolution = scene.TLM_SceneProperties.tlm_mesh_lightmap_resolution
|
||||
obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode = scene.TLM_SceneProperties.tlm_mesh_lightmap_unwrap_mode
|
||||
obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin = scene.TLM_SceneProperties.tlm_mesh_unwrap_margin
|
||||
obj.TLM_ObjectProperties.tlm_postpack_object = scene.TLM_SceneProperties.tlm_postpack_object
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Scene":
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.type == "MESH":
|
||||
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
obj.TLM_ObjectProperties.tlm_atlas_pointer = scene.TLM_SceneProperties.tlm_atlas_pointer
|
||||
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
|
||||
|
||||
obj.TLM_ObjectProperties.tlm_postatlas_pointer = scene.TLM_SceneProperties.tlm_postatlas_pointer
|
||||
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 selection"""
|
||||
"""Disable for set"""
|
||||
bl_idname = "tlm.disable_selection"
|
||||
bl_label = "Disable for selection"
|
||||
bl_label = "Disable for set"
|
||||
bl_description = "Disable for selection"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
for obj in bpy.context.selected_objects:
|
||||
obj.TLM_ObjectProperties.tlm_mesh_lightmap_use = False
|
||||
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 selection"""
|
||||
"""Remove Lightmap UV for set"""
|
||||
bl_idname = "tlm.remove_uv_selection"
|
||||
bl_label = "Remove Lightmap UV"
|
||||
bl_description = "Remove Lightmap UV for selection"
|
||||
bl_description = "Remove Lightmap UV for set"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
for obj in bpy.context.selected_objects:
|
||||
if obj.type == "MESH":
|
||||
uv_layers = obj.data.uv_layers
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_utility_set == "Scene":
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.type == "MESH":
|
||||
|
||||
for uvlayer in uv_layers:
|
||||
if uvlayer.name == "UVMap_Lightmap":
|
||||
uv_layers.remove(uvlayer)
|
||||
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'}
|
||||
|
||||
|
@ -222,8 +476,8 @@ class TLM_SelectLightmapped(bpy.types.Operator):
|
|||
|
||||
def execute(self, context):
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == "MESH":
|
||||
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)
|
||||
|
@ -278,7 +532,7 @@ class TLM_AtlastListDeleteItem(bpy.types.Operator):
|
|||
list = scene.TLM_AtlasList
|
||||
index = scene.TLM_AtlasListItem
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
|
||||
atlasName = scene.TLM_AtlasList[index].name
|
||||
|
||||
|
@ -310,7 +564,7 @@ class TLM_PostAtlastListDeleteItem(bpy.types.Operator):
|
|||
list = scene.TLM_PostAtlasList
|
||||
index = scene.TLM_PostAtlasListItem
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
|
||||
atlasName = scene.TLM_PostAtlasList[index].name
|
||||
|
||||
|
@ -437,7 +691,7 @@ class TLM_BuildEnvironmentProbes(bpy.types.Operator):
|
|||
|
||||
def invoke(self, context, event):
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
|
||||
if obj.type == "LIGHT_PROBE":
|
||||
if obj.data.type == "CUBEMAP":
|
||||
|
@ -500,7 +754,7 @@ class TLM_BuildEnvironmentProbes(bpy.types.Operator):
|
|||
cam.rotation_euler = positions[val]
|
||||
|
||||
filename = os.path.join(directory, val) + "_" + camobj_name + ".hdr"
|
||||
bpy.data.scenes['Scene'].render.filepath = filename
|
||||
bpy.context.scene.render.filepath = filename
|
||||
print("Writing out: " + val)
|
||||
bpy.ops.render.render(write_still=True)
|
||||
|
||||
|
@ -642,7 +896,7 @@ class TLM_BuildEnvironmentProbes(bpy.types.Operator):
|
|||
|
||||
subprocess.call([envpipe3], shell=True)
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
obj.select_set(False)
|
||||
|
||||
cam_obj.select_set(True)
|
||||
|
@ -686,7 +940,92 @@ class TLM_MergeAdjacentActors(bpy.types.Operator):
|
|||
|
||||
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()
|
||||
|
||||
build.finish_assemble()
|
||||
|
||||
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'}
|
||||
|
||||
|
@ -698,7 +1037,4 @@ def TLM_HalfResolution():
|
|||
pass
|
||||
|
||||
def TLM_DivideLMGroups():
|
||||
pass
|
||||
|
||||
def TLM_LoadFromFolder():
|
||||
pass
|
0
blender/arm/lightmapper/panels/__init__.py
Normal file
0
blender/arm/lightmapper/panels/__init__.py
Normal file
66
blender/arm/lightmapper/panels/image.py
Normal file
66
blender/arm/lightmapper/panels/image.py
Normal file
|
@ -0,0 +1,66 @@
|
|||
import bpy, os, math, importlib
|
||||
|
||||
from bpy.types import Menu, Operator, Panel, UIList
|
||||
|
||||
from bpy.props import (
|
||||
StringProperty,
|
||||
BoolProperty,
|
||||
IntProperty,
|
||||
FloatProperty,
|
||||
FloatVectorProperty,
|
||||
EnumProperty,
|
||||
PointerProperty,
|
||||
)
|
||||
|
||||
class TLM_PT_Imagetools(bpy.types.Panel):
|
||||
bl_label = "TLM Imagetools"
|
||||
bl_space_type = "IMAGE_EDITOR"
|
||||
bl_region_type = 'UI'
|
||||
bl_category = "TLM Imagetools"
|
||||
|
||||
def draw_header(self, _):
|
||||
layout = self.layout
|
||||
row = layout.row(align=True)
|
||||
row.label(text ="Image Tools")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
activeImg = None
|
||||
|
||||
for area in bpy.context.screen.areas:
|
||||
if area.type == 'IMAGE_EDITOR':
|
||||
activeImg = area.spaces.active.image
|
||||
|
||||
if activeImg is not None and activeImg.name != "Render Result" and activeImg.name != "Viewer Node":
|
||||
|
||||
cv2 = importlib.util.find_spec("cv2")
|
||||
|
||||
if cv2 is None:
|
||||
row = layout.row(align=True)
|
||||
row.label(text ="OpenCV not installed.")
|
||||
else:
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text ="Method")
|
||||
row = layout.row(align=True)
|
||||
row.prop(activeImg.TLM_ImageProperties, "tlm_image_scale_engine")
|
||||
row = layout.row(align=True)
|
||||
row.prop(activeImg.TLM_ImageProperties, "tlm_image_cache_switch")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.image_upscale")
|
||||
if activeImg.TLM_ImageProperties.tlm_image_cache_switch:
|
||||
row = layout.row(align=True)
|
||||
row.label(text ="Switch up.")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.image_downscale")
|
||||
if activeImg.TLM_ImageProperties.tlm_image_cache_switch:
|
||||
row = layout.row(align=True)
|
||||
row.label(text ="Switch down.")
|
||||
if activeImg.TLM_ImageProperties.tlm_image_scale_engine == "OpenCV":
|
||||
row = layout.row(align=True)
|
||||
row.prop(activeImg.TLM_ImageProperties, "tlm_image_scale_method")
|
||||
|
||||
else:
|
||||
row = layout.row(align=True)
|
||||
row.label(text ="Select an image")
|
17
blender/arm/lightmapper/panels/light.py
Normal file
17
blender/arm/lightmapper/panels/light.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
import bpy
|
||||
from bpy.props import *
|
||||
from bpy.types import Menu, Panel
|
||||
|
||||
class TLM_PT_LightMenu(bpy.types.Panel):
|
||||
bl_label = "The Lightmapper"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "light"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
obj = bpy.context.object
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
118
blender/arm/lightmapper/panels/object.py
Normal file
118
blender/arm/lightmapper/panels/object.py
Normal file
|
@ -0,0 +1,118 @@
|
|||
import bpy
|
||||
from bpy.props import *
|
||||
from bpy.types import Menu, Panel
|
||||
|
||||
class TLM_PT_ObjectMenu(bpy.types.Panel):
|
||||
bl_label = "The Lightmapper"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "object"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
obj = bpy.context.object
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
if obj.type == "MESH":
|
||||
row = layout.row(align=True)
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_lightmap_use")
|
||||
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
|
||||
row = layout.row()
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_use_default_channel")
|
||||
|
||||
if not obj.TLM_ObjectProperties.tlm_use_default_channel:
|
||||
|
||||
row = layout.row()
|
||||
row.prop_search(obj.TLM_ObjectProperties, "tlm_uv_channel", obj.data, "uv_layers", text='UV Channel')
|
||||
|
||||
row = layout.row()
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_lightmap_resolution")
|
||||
if obj.TLM_ObjectProperties.tlm_use_default_channel:
|
||||
row = layout.row()
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_lightmap_unwrap_mode")
|
||||
row = layout.row()
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
|
||||
if scene.TLM_AtlasListItem >= 0 and len(scene.TLM_AtlasList) > 0:
|
||||
row = layout.row()
|
||||
item = scene.TLM_AtlasList[scene.TLM_AtlasListItem]
|
||||
row.prop_search(obj.TLM_ObjectProperties, "tlm_atlas_pointer", scene, "TLM_AtlasList", text='Atlas Group')
|
||||
row = layout.row()
|
||||
else:
|
||||
row = layout.label(text="Add Atlas Groups from the scene lightmapping settings.")
|
||||
row = layout.row()
|
||||
|
||||
else:
|
||||
row = layout.row()
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_postpack_object")
|
||||
row = layout.row()
|
||||
|
||||
|
||||
if obj.TLM_ObjectProperties.tlm_postpack_object and obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode != "AtlasGroupA":
|
||||
if scene.TLM_PostAtlasListItem >= 0 and len(scene.TLM_PostAtlasList) > 0:
|
||||
row = layout.row()
|
||||
item = scene.TLM_PostAtlasList[scene.TLM_PostAtlasListItem]
|
||||
row.prop_search(obj.TLM_ObjectProperties, "tlm_postatlas_pointer", scene, "TLM_PostAtlasList", text='Atlas Group')
|
||||
row = layout.row()
|
||||
|
||||
else:
|
||||
row = layout.label(text="Add Atlas Groups from the scene lightmapping settings.")
|
||||
row = layout.row()
|
||||
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_unwrap_margin")
|
||||
row = layout.row()
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_filter_override")
|
||||
row = layout.row()
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_filter_override:
|
||||
row = layout.row(align=True)
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_filtering_mode")
|
||||
row = layout.row(align=True)
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_filtering_mode == "Gaussian":
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_filtering_gaussian_strength")
|
||||
row = layout.row(align=True)
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_filtering_iterations")
|
||||
elif obj.TLM_ObjectProperties.tlm_mesh_filtering_mode == "Box":
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_filtering_box_strength")
|
||||
row = layout.row(align=True)
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_filtering_iterations")
|
||||
elif obj.TLM_ObjectProperties.tlm_mesh_filtering_mode == "Bilateral":
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_filtering_bilateral_diameter")
|
||||
row = layout.row(align=True)
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_filtering_bilateral_color_deviation")
|
||||
row = layout.row(align=True)
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_filtering_bilateral_coordinate_deviation")
|
||||
row = layout.row(align=True)
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_filtering_iterations")
|
||||
else:
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_filtering_median_kernel", expand=True)
|
||||
row = layout.row(align=True)
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_filtering_iterations")
|
||||
|
||||
|
||||
class TLM_PT_MaterialMenu(bpy.types.Panel):
|
||||
bl_label = "The Lightmapper"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "material"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
obj = bpy.context.object
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
mat = bpy.context.material
|
||||
if mat == None:
|
||||
return
|
||||
|
||||
if obj.type == "MESH":
|
||||
|
||||
row = layout.row()
|
||||
row.prop(mat, "TLM_ignore")
|
582
blender/arm/lightmapper/panels/scene.py
Normal file
582
blender/arm/lightmapper/panels/scene.py
Normal file
|
@ -0,0 +1,582 @@
|
|||
import bpy, importlib, math
|
||||
from bpy.props import *
|
||||
from bpy.types import Menu, Panel
|
||||
from .. utility import icon
|
||||
from .. properties.denoiser import oidn, optix
|
||||
|
||||
class TLM_PT_Settings(bpy.types.Panel):
|
||||
bl_label = "Settings"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "render"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_parent_id = "ARM_PT_BakePanel"
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
scene = context.scene
|
||||
return scene.arm_bakemode == "Lightmap"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
|
||||
row = layout.row(align=True)
|
||||
|
||||
#We list LuxCoreRender as available, by default we assume Cycles exists
|
||||
row.prop(sceneProperties, "tlm_lightmap_engine")
|
||||
|
||||
if sceneProperties.tlm_lightmap_engine == "Cycles":
|
||||
|
||||
#CYCLES SETTINGS HERE
|
||||
engineProperties = scene.TLM_EngineProperties
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="General Settings")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.build_lightmaps")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.clean_lightmaps")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.explore_lightmaps")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_apply_on_unwrap")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_headless")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_alert_on_finish")
|
||||
|
||||
if sceneProperties.tlm_alert_on_finish:
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_alert_sound")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_verbose")
|
||||
#row = layout.row(align=True)
|
||||
#row.prop(sceneProperties, "tlm_compile_statistics")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_override_bg_color")
|
||||
if sceneProperties.tlm_override_bg_color:
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_override_color")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_reset_uv")
|
||||
|
||||
row = layout.row(align=True)
|
||||
try:
|
||||
if bpy.context.scene["TLM_Buildstat"] is not None:
|
||||
row.label(text="Last build completed in: " + str(bpy.context.scene["TLM_Buildstat"][0]))
|
||||
except:
|
||||
pass
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Cycles Settings")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_mode")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_quality")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_resolution_scale")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_bake_mode")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_target")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_lighting_mode")
|
||||
# if scene.TLM_EngineProperties.tlm_lighting_mode == "combinedao" or scene.TLM_EngineProperties.tlm_lighting_mode == "indirectao":
|
||||
# row = layout.row(align=True)
|
||||
# row.prop(engineProperties, "tlm_premultiply_ao")
|
||||
if scene.TLM_EngineProperties.tlm_bake_mode == "Background":
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Warning! Background mode is currently unstable", icon_value=2)
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_network_render")
|
||||
if sceneProperties.tlm_network_render:
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_network_paths")
|
||||
#row = layout.row(align=True)
|
||||
#row.prop(sceneProperties, "tlm_network_dir")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_caching_mode")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_directional_mode")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_lightmap_savedir")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_dilation_margin")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_exposure_multiplier")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_setting_supersample")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_metallic_clamp")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_texture_interpolation")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_texture_extrapolation")
|
||||
|
||||
|
||||
|
||||
# elif sceneProperties.tlm_lightmap_engine == "LuxCoreRender":
|
||||
|
||||
# engineProperties = scene.TLM_Engine2Properties
|
||||
# row = layout.row(align=True)
|
||||
# row.prop(engineProperties, "tlm_luxcore_dir")
|
||||
# row = layout.row(align=True)
|
||||
# row.operator("tlm.build_lightmaps")
|
||||
# #LUXCORE SETTINGS HERE
|
||||
# #luxcore_available = False
|
||||
|
||||
# #Look for Luxcorerender in the renderengine classes
|
||||
# # for engine in bpy.types.RenderEngine.__subclasses__():
|
||||
# # if engine.bl_idname == "LUXCORE":
|
||||
# # luxcore_available = True
|
||||
# # break
|
||||
|
||||
# # row = layout.row(align=True)
|
||||
# # if not luxcore_available:
|
||||
# # row.label(text="Please install BlendLuxCore.")
|
||||
# # else:
|
||||
# # row.label(text="LuxCoreRender not yet available.")
|
||||
|
||||
elif sceneProperties.tlm_lightmap_engine == "OctaneRender":
|
||||
|
||||
engineProperties = scene.TLM_Engine3Properties
|
||||
|
||||
#LUXCORE SETTINGS HERE
|
||||
octane_available = True
|
||||
|
||||
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.build_lightmaps")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.clean_lightmaps")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.explore_lightmaps")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_verbose")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_lightmap_savedir")
|
||||
row = layout.row(align=True)
|
||||
|
||||
class TLM_PT_Denoise(bpy.types.Panel):
|
||||
bl_label = "Denoise"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "render"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_parent_id = "ARM_PT_BakePanel"
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
scene = context.scene
|
||||
return scene.arm_bakemode == "Lightmap"
|
||||
|
||||
def draw_header(self, context):
|
||||
scene = context.scene
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
self.layout.prop(sceneProperties, "tlm_denoise_use", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
layout.active = sceneProperties.tlm_denoise_use
|
||||
|
||||
row = layout.row(align=True)
|
||||
|
||||
#row.prop(sceneProperties, "tlm_denoiser", expand=True)
|
||||
#row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_denoise_engine", expand=True)
|
||||
row = layout.row(align=True)
|
||||
|
||||
if sceneProperties.tlm_denoise_engine == "Integrated":
|
||||
row.label(text="No options for Integrated.")
|
||||
elif sceneProperties.tlm_denoise_engine == "OIDN":
|
||||
denoiseProperties = scene.TLM_OIDNEngineProperties
|
||||
row.prop(denoiseProperties, "tlm_oidn_path")
|
||||
row = layout.row(align=True)
|
||||
row.prop(denoiseProperties, "tlm_oidn_verbose")
|
||||
row = layout.row(align=True)
|
||||
row.prop(denoiseProperties, "tlm_oidn_threads")
|
||||
row = layout.row(align=True)
|
||||
row.prop(denoiseProperties, "tlm_oidn_maxmem")
|
||||
row = layout.row(align=True)
|
||||
row.prop(denoiseProperties, "tlm_oidn_affinity")
|
||||
# row = layout.row(align=True)
|
||||
# row.prop(denoiseProperties, "tlm_denoise_ao")
|
||||
elif sceneProperties.tlm_denoise_engine == "Optix":
|
||||
denoiseProperties = scene.TLM_OptixEngineProperties
|
||||
row.prop(denoiseProperties, "tlm_optix_path")
|
||||
row = layout.row(align=True)
|
||||
row.prop(denoiseProperties, "tlm_optix_verbose")
|
||||
row = layout.row(align=True)
|
||||
row.prop(denoiseProperties, "tlm_optix_maxmem")
|
||||
#row = layout.row(align=True)
|
||||
#row.prop(denoiseProperties, "tlm_denoise_ao")
|
||||
|
||||
class TLM_PT_Filtering(bpy.types.Panel):
|
||||
bl_label = "Filtering"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "render"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_parent_id = "ARM_PT_BakePanel"
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
scene = context.scene
|
||||
return scene.arm_bakemode == "Lightmap"
|
||||
|
||||
def draw_header(self, context):
|
||||
scene = context.scene
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
self.layout.prop(sceneProperties, "tlm_filtering_use", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
layout.active = sceneProperties.tlm_filtering_use
|
||||
#row = layout.row(align=True)
|
||||
#row.label(text="TODO MAKE CHECK")
|
||||
#row = layout.row(align=True)
|
||||
#row.prop(sceneProperties, "tlm_filtering_engine", expand=True)
|
||||
row = layout.row(align=True)
|
||||
|
||||
if sceneProperties.tlm_filtering_engine == "OpenCV":
|
||||
|
||||
cv2 = importlib.util.find_spec("cv2")
|
||||
|
||||
if cv2 is None:
|
||||
row = layout.row(align=True)
|
||||
row.label(text="OpenCV is not installed. Install it through preferences.")
|
||||
else:
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_mode")
|
||||
row = layout.row(align=True)
|
||||
if scene.TLM_SceneProperties.tlm_filtering_mode == "Gaussian":
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_gaussian_strength")
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_iterations")
|
||||
elif scene.TLM_SceneProperties.tlm_filtering_mode == "Box":
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_box_strength")
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_iterations")
|
||||
|
||||
elif scene.TLM_SceneProperties.tlm_filtering_mode == "Bilateral":
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_bilateral_diameter")
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_bilateral_color_deviation")
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_bilateral_coordinate_deviation")
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_iterations")
|
||||
else:
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_median_kernel", expand=True)
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_iterations")
|
||||
else:
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_numpy_filtering_mode")
|
||||
|
||||
|
||||
class TLM_PT_Encoding(bpy.types.Panel):
|
||||
bl_label = "Encoding"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "render"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_parent_id = "ARM_PT_BakePanel"
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
scene = context.scene
|
||||
return scene.arm_bakemode == "Lightmap"
|
||||
|
||||
def draw_header(self, context):
|
||||
scene = context.scene
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
self.layout.prop(sceneProperties, "tlm_encoding_use", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
layout.active = sceneProperties.tlm_encoding_use
|
||||
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
row = layout.row(align=True)
|
||||
|
||||
if scene.TLM_EngineProperties.tlm_bake_mode == "Background":
|
||||
row.label(text="Encoding options disabled in background mode")
|
||||
row = layout.row(align=True)
|
||||
|
||||
else:
|
||||
|
||||
row.prop(sceneProperties, "tlm_encoding_device", expand=True)
|
||||
row = layout.row(align=True)
|
||||
|
||||
if sceneProperties.tlm_encoding_device == "CPU":
|
||||
row.prop(sceneProperties, "tlm_encoding_mode_a", expand=True)
|
||||
else:
|
||||
row.prop(sceneProperties, "tlm_encoding_mode_b", expand=True)
|
||||
|
||||
if sceneProperties.tlm_encoding_device == "CPU":
|
||||
if sceneProperties.tlm_encoding_mode_a == "RGBM":
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_encoding_range")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_decoder_setup")
|
||||
if sceneProperties.tlm_encoding_mode_a == "RGBD":
|
||||
pass
|
||||
if sceneProperties.tlm_encoding_mode_a == "HDR":
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_format")
|
||||
else:
|
||||
|
||||
if sceneProperties.tlm_encoding_mode_b == "RGBM":
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_encoding_range")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_decoder_setup")
|
||||
|
||||
if sceneProperties.tlm_encoding_mode_b == "LogLuv" and sceneProperties.tlm_encoding_device == "GPU":
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_decoder_setup")
|
||||
if sceneProperties.tlm_encoding_mode_b == "HDR":
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_format")
|
||||
|
||||
class TLM_PT_Utility(bpy.types.Panel):
|
||||
bl_label = "Utilities"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "render"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_parent_id = "ARM_PT_BakePanel"
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
scene = context.scene
|
||||
return scene.arm_bakemode == "Lightmap"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Enable Lightmaps for set")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.enable_set")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_utility_set")
|
||||
row = layout.row(align=True)
|
||||
#row.label(text="ABCD")
|
||||
row.prop(sceneProperties, "tlm_mesh_lightmap_unwrap_mode")
|
||||
|
||||
if sceneProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
|
||||
if scene.TLM_AtlasListItem >= 0 and len(scene.TLM_AtlasList) > 0:
|
||||
row = layout.row()
|
||||
item = scene.TLM_AtlasList[scene.TLM_AtlasListItem]
|
||||
row.prop_search(sceneProperties, "tlm_atlas_pointer", scene, "TLM_AtlasList", text='Atlas Group')
|
||||
else:
|
||||
row = layout.label(text="Add Atlas Groups from the scene lightmapping settings.")
|
||||
|
||||
else:
|
||||
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_postpack_object")
|
||||
row = layout.row()
|
||||
|
||||
if sceneProperties.tlm_postpack_object and sceneProperties.tlm_mesh_lightmap_unwrap_mode != "AtlasGroupA":
|
||||
|
||||
if scene.TLM_PostAtlasListItem >= 0 and len(scene.TLM_PostAtlasList) > 0:
|
||||
row = layout.row()
|
||||
item = scene.TLM_PostAtlasList[scene.TLM_PostAtlasListItem]
|
||||
row.prop_search(sceneProperties, "tlm_postatlas_pointer", scene, "TLM_PostAtlasList", text='Atlas Group')
|
||||
row = layout.row()
|
||||
|
||||
else:
|
||||
row = layout.label(text="Add Atlas Groups from the scene lightmapping settings.")
|
||||
row = layout.row()
|
||||
|
||||
row.prop(sceneProperties, "tlm_mesh_unwrap_margin")
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_resolution_weight")
|
||||
|
||||
if sceneProperties.tlm_resolution_weight == "Single":
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_mesh_lightmap_resolution")
|
||||
else:
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_resolution_min")
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_resolution_max")
|
||||
|
||||
row = layout.row()
|
||||
row.operator("tlm.disable_selection")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.select_lightmapped_objects")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.remove_uv_selection")
|
||||
row = layout.row(align=True)
|
||||
|
||||
|
||||
row.label(text="Environment Probes")
|
||||
row = layout.row()
|
||||
row.operator("tlm.build_environmentprobe")
|
||||
row = layout.row()
|
||||
row.operator("tlm.clean_environmentprobe")
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_environment_probe_engine")
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_cmft_path")
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_environment_probe_resolution")
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_create_spherical")
|
||||
|
||||
if sceneProperties.tlm_create_spherical:
|
||||
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_invert_direction")
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_write_sh")
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_write_radiance")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Load lightmaps")
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_load_folder")
|
||||
row = layout.row()
|
||||
row.operator("tlm.load_lightmaps")
|
||||
|
||||
class TLM_PT_Additional(bpy.types.Panel):
|
||||
bl_label = "Additional"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "render"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_parent_id = "ARM_PT_BakePanel"
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
scene = context.scene
|
||||
return scene.arm_bakemode == "Lightmap"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
atlasListItem = scene.TLM_AtlasListItem
|
||||
atlasList = scene.TLM_AtlasList
|
||||
postatlasListItem = scene.TLM_PostAtlasListItem
|
||||
postatlasList = scene.TLM_PostAtlasList
|
||||
|
||||
layout.label(text="Network Rendering")
|
||||
row = layout.row()
|
||||
row.operator("tlm.start_server")
|
||||
layout.label(text="Atlas Groups")
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_atlas_mode", expand=True)
|
||||
|
||||
if sceneProperties.tlm_atlas_mode == "Prepack":
|
||||
|
||||
rows = 2
|
||||
if len(atlasList) > 1:
|
||||
rows = 4
|
||||
row = layout.row()
|
||||
row.template_list("TLM_UL_AtlasList", "Atlas List", scene, "TLM_AtlasList", scene, "TLM_AtlasListItem", rows=rows)
|
||||
col = row.column(align=True)
|
||||
col.operator("tlm_atlaslist.new_item", icon='ADD', text="")
|
||||
col.operator("tlm_atlaslist.delete_item", icon='REMOVE', text="")
|
||||
|
||||
if atlasListItem >= 0 and len(atlasList) > 0:
|
||||
item = atlasList[atlasListItem]
|
||||
layout.prop(item, "tlm_atlas_lightmap_unwrap_mode")
|
||||
layout.prop(item, "tlm_atlas_lightmap_resolution")
|
||||
layout.prop(item, "tlm_atlas_unwrap_margin")
|
||||
|
||||
amount = 0
|
||||
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
if obj.TLM_ObjectProperties.tlm_atlas_pointer == item.name:
|
||||
amount = amount + 1
|
||||
|
||||
layout.label(text="Objects: " + str(amount))
|
||||
|
||||
else:
|
||||
|
||||
layout.label(text="Postpacking is unstable.")
|
||||
|
||||
cv2 = importlib.util.find_spec("cv2")
|
||||
|
||||
if cv2 is None:
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="OpenCV is not installed. Install it through preferences.")
|
||||
|
||||
else:
|
||||
|
||||
rows = 2
|
||||
if len(atlasList) > 1:
|
||||
rows = 4
|
||||
row = layout.row()
|
||||
row.template_list("TLM_UL_PostAtlasList", "PostList", scene, "TLM_PostAtlasList", scene, "TLM_PostAtlasListItem", rows=rows)
|
||||
col = row.column(align=True)
|
||||
col.operator("tlm_postatlaslist.new_item", icon='ADD', text="")
|
||||
col.operator("tlm_postatlaslist.delete_item", icon='REMOVE', text="")
|
||||
|
||||
if postatlasListItem >= 0 and len(postatlasList) > 0:
|
||||
item = postatlasList[postatlasListItem]
|
||||
layout.prop(item, "tlm_atlas_lightmap_resolution")
|
||||
|
||||
#Below list object counter
|
||||
amount = 0
|
||||
utilized = 0
|
||||
atlasUsedArea = 0
|
||||
atlasSize = item.tlm_atlas_lightmap_resolution
|
||||
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
if obj.TLM_ObjectProperties.tlm_postpack_object:
|
||||
if obj.TLM_ObjectProperties.tlm_postatlas_pointer == item.name:
|
||||
amount = amount + 1
|
||||
|
||||
atlasUsedArea += int(obj.TLM_ObjectProperties.tlm_mesh_lightmap_resolution) ** 2
|
||||
|
||||
row = layout.row()
|
||||
row.prop(item, "tlm_atlas_repack_on_cleanup")
|
||||
|
||||
#TODO SET A CHECK FOR THIS! ADD A CV2 CHECK TO UTILITY!
|
||||
cv2 = True
|
||||
|
||||
if cv2:
|
||||
row = layout.row()
|
||||
row.prop(item, "tlm_atlas_dilation")
|
||||
layout.label(text="Objects: " + str(amount))
|
||||
|
||||
utilized = atlasUsedArea / (int(atlasSize) ** 2)
|
||||
layout.label(text="Utilized: " + str(utilized * 100) + "%")
|
||||
|
||||
if (utilized * 100) > 100:
|
||||
layout.label(text="Warning! Overflow not yet supported")
|
17
blender/arm/lightmapper/panels/world.py
Normal file
17
blender/arm/lightmapper/panels/world.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
import bpy
|
||||
from bpy.props import *
|
||||
from bpy.types import Menu, Panel
|
||||
|
||||
class TLM_PT_WorldMenu(bpy.types.Panel):
|
||||
bl_label = "The Lightmapper"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "world"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
obj = bpy.context.object
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
16
blender/arm/lightmapper/preferences/__init__.py
Normal file
16
blender/arm/lightmapper/preferences/__init__.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
import bpy
|
||||
from bpy.utils import register_class, unregister_class
|
||||
from . import addon_preferences
|
||||
#from . import build, clean, explore, encode, installopencv
|
||||
|
||||
classes = [
|
||||
addon_preferences.TLM_AddonPreferences
|
||||
]
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
register_class(cls)
|
||||
|
||||
def unregister():
|
||||
for cls in classes:
|
||||
unregister_class(cls)
|
75
blender/arm/lightmapper/preferences/addon_preferences.py
Normal file
75
blender/arm/lightmapper/preferences/addon_preferences.py
Normal file
|
@ -0,0 +1,75 @@
|
|||
import bpy, platform
|
||||
from os.path import basename, dirname
|
||||
from bpy.types import AddonPreferences
|
||||
from .. operators import installopencv
|
||||
import importlib
|
||||
|
||||
class TLM_AddonPreferences(AddonPreferences):
|
||||
|
||||
bl_idname = "thelightmapper"
|
||||
|
||||
def draw(self, context):
|
||||
|
||||
layout = self.layout
|
||||
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.label(text="OpenCV")
|
||||
|
||||
cv2 = importlib.util.find_spec("cv2")
|
||||
|
||||
if cv2 is not None:
|
||||
row.label(text="OpenCV installed")
|
||||
else:
|
||||
if platform.system() == "Windows":
|
||||
row.label(text="OpenCV not found - Install as administrator!", icon_value=2)
|
||||
else:
|
||||
row.label(text="OpenCV not found - Click to install!", icon_value=2)
|
||||
row = box.row()
|
||||
row.operator("tlm.install_opencv_lightmaps", icon="PREFERENCES")
|
||||
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.label(text="Blender Xatlas")
|
||||
if "blender_xatlas" in bpy.context.preferences.addons.keys():
|
||||
row.label(text="Blender Xatlas installed and available")
|
||||
else:
|
||||
row.label(text="Blender Xatlas not installed", icon_value=2)
|
||||
row = box.row()
|
||||
row.label(text="Github: https://github.com/mattedicksoncom/blender-xatlas")
|
||||
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.label(text="RizomUV Bridge")
|
||||
row.label(text="Coming soon")
|
||||
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.label(text="UVPackmaster")
|
||||
row.label(text="Coming soon")
|
||||
|
||||
texel_density_addon = False
|
||||
for addon in bpy.context.preferences.addons.keys():
|
||||
if addon.startswith("Texel_Density"):
|
||||
texel_density_addon = True
|
||||
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.label(text="Texel Density Checker")
|
||||
if texel_density_addon:
|
||||
row.label(text="Texel Density Checker installed and available")
|
||||
else:
|
||||
row.label(text="Texel Density Checker", icon_value=2)
|
||||
row.label(text="Coming soon")
|
||||
row = box.row()
|
||||
row.label(text="Github: https://github.com/mrven/Blender-Texel-Density-Checker")
|
||||
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.label(text="LuxCoreRender")
|
||||
row.label(text="Coming soon")
|
||||
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.label(text="OctaneRender")
|
||||
row.label(text="Coming soon")
|
|
@ -1,7 +1,7 @@
|
|||
import bpy
|
||||
from bpy.utils import register_class, unregister_class
|
||||
from . import scene, object, atlas
|
||||
from . renderer import cycles, luxcorerender
|
||||
from . import scene, object, atlas, image
|
||||
from . renderer import cycles, luxcorerender, octanerender
|
||||
from . denoiser import oidn, optix
|
||||
|
||||
classes = [
|
||||
|
@ -9,12 +9,14 @@ classes = [
|
|||
object.TLM_ObjectProperties,
|
||||
cycles.TLM_CyclesSceneProperties,
|
||||
luxcorerender.TLM_LuxCoreSceneProperties,
|
||||
octanerender.TLM_OctanerenderSceneProperties,
|
||||
oidn.TLM_OIDNEngineProperties,
|
||||
optix.TLM_OptixEngineProperties,
|
||||
atlas.TLM_AtlasListItem,
|
||||
atlas.TLM_UL_AtlasList,
|
||||
atlas.TLM_PostAtlasListItem,
|
||||
atlas.TLM_UL_PostAtlasList
|
||||
atlas.TLM_UL_PostAtlasList,
|
||||
image.TLM_ImageProperties
|
||||
]
|
||||
|
||||
def register():
|
||||
|
@ -25,12 +27,14 @@ def register():
|
|||
bpy.types.Object.TLM_ObjectProperties = bpy.props.PointerProperty(type=object.TLM_ObjectProperties)
|
||||
bpy.types.Scene.TLM_EngineProperties = bpy.props.PointerProperty(type=cycles.TLM_CyclesSceneProperties)
|
||||
bpy.types.Scene.TLM_Engine2Properties = bpy.props.PointerProperty(type=luxcorerender.TLM_LuxCoreSceneProperties)
|
||||
bpy.types.Scene.TLM_Engine3Properties = bpy.props.PointerProperty(type=octanerender.TLM_OctanerenderSceneProperties)
|
||||
bpy.types.Scene.TLM_OIDNEngineProperties = bpy.props.PointerProperty(type=oidn.TLM_OIDNEngineProperties)
|
||||
bpy.types.Scene.TLM_OptixEngineProperties = bpy.props.PointerProperty(type=optix.TLM_OptixEngineProperties)
|
||||
bpy.types.Scene.TLM_AtlasListItem = bpy.props.IntProperty(name="Index for my_list", default=0)
|
||||
bpy.types.Scene.TLM_AtlasList = bpy.props.CollectionProperty(type=atlas.TLM_AtlasListItem)
|
||||
bpy.types.Scene.TLM_PostAtlasListItem = bpy.props.IntProperty(name="Index for my_list", default=0)
|
||||
bpy.types.Scene.TLM_PostAtlasList = bpy.props.CollectionProperty(type=atlas.TLM_PostAtlasListItem)
|
||||
bpy.types.Image.TLM_ImageProperties = bpy.props.PointerProperty(type=image.TLM_ImageProperties)
|
||||
|
||||
bpy.types.Material.TLM_ignore = bpy.props.BoolProperty(name="Skip material", description="Ignore material for lightmapped object", default=False)
|
||||
|
||||
|
@ -42,9 +46,11 @@ def unregister():
|
|||
del bpy.types.Object.TLM_ObjectProperties
|
||||
del bpy.types.Scene.TLM_EngineProperties
|
||||
del bpy.types.Scene.TLM_Engine2Properties
|
||||
del bpy.types.Scene.TLM_Engine3Properties
|
||||
del bpy.types.Scene.TLM_OIDNEngineProperties
|
||||
del bpy.types.Scene.TLM_OptixEngineProperties
|
||||
del bpy.types.Scene.TLM_AtlasListItem
|
||||
del bpy.types.Scene.TLM_AtlasList
|
||||
del bpy.types.Scene.TLM_PostAtlasListItem
|
||||
del bpy.types.Scene.TLM_PostAtlasList
|
||||
del bpy.types.Scene.TLM_PostAtlasList
|
||||
del bpy.types.Image.TLM_ImageProperties
|
|
@ -34,12 +34,16 @@ class TLM_PostAtlasListItem(bpy.types.PropertyGroup):
|
|||
max=1.0,
|
||||
subtype='FACTOR')
|
||||
|
||||
tlm_atlas_lightmap_unwrap_mode : EnumProperty(
|
||||
items = [('Lightmap', 'Lightmap', 'TODO'),
|
||||
('SmartProject', 'Smart Project', 'TODO'),
|
||||
('Xatlas', 'Xatlas', 'TODO')],
|
||||
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'))
|
||||
|
||||
tlm_postatlas_lightmap_unwrap_mode : EnumProperty(
|
||||
items = unwrap_modes,
|
||||
name = "Unwrap Mode",
|
||||
description="TODO",
|
||||
description="Atlas unwrapping method",
|
||||
default='SmartProject')
|
||||
|
||||
class TLM_UL_PostAtlasList(bpy.types.UIList):
|
||||
|
@ -51,7 +55,7 @@ class TLM_UL_PostAtlasList(bpy.types.UIList):
|
|||
#In list object counter
|
||||
amount = 0
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
if obj.TLM_ObjectProperties.tlm_postpack_object:
|
||||
if obj.TLM_ObjectProperties.tlm_postatlas_pointer == item.name:
|
||||
|
@ -69,9 +73,6 @@ class TLM_UL_PostAtlasList(bpy.types.UIList):
|
|||
layout.alignment = 'CENTER'
|
||||
layout.label(text="", icon = custom_icon)
|
||||
|
||||
|
||||
|
||||
|
||||
class TLM_AtlasListItem(bpy.types.PropertyGroup):
|
||||
obj: PointerProperty(type=bpy.types.Object, description="The object to bake")
|
||||
tlm_atlas_lightmap_resolution : EnumProperty(
|
||||
|
@ -95,12 +96,17 @@ class TLM_AtlasListItem(bpy.types.PropertyGroup):
|
|||
max=1.0,
|
||||
subtype='FACTOR')
|
||||
|
||||
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'))
|
||||
|
||||
tlm_atlas_lightmap_unwrap_mode : EnumProperty(
|
||||
items = [('Lightmap', 'Lightmap', 'TODO'),
|
||||
('SmartProject', 'Smart Project', 'TODO'),
|
||||
('Xatlas', 'Xatlas', 'TODO')],
|
||||
items = unwrap_modes,
|
||||
name = "Unwrap Mode",
|
||||
description="TODO",
|
||||
description="Atlas unwrapping method",
|
||||
default='SmartProject')
|
||||
|
||||
class TLM_UL_AtlasList(bpy.types.UIList):
|
||||
|
@ -111,7 +117,7 @@ class TLM_UL_AtlasList(bpy.types.UIList):
|
|||
|
||||
amount = 0
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
if obj.TLM_ObjectProperties.tlm_atlas_pointer == item.name:
|
||||
|
|
|
@ -1,10 +1,26 @@
|
|||
import bpy
|
||||
from bpy.props import *
|
||||
|
||||
class TLM_ObjectProperties(bpy.types.PropertyGroup):
|
||||
tlm_image_scale_method : EnumProperty(
|
||||
items = [('Native', 'Native', 'TODO'),
|
||||
('OpenCV', 'OpenCV', 'TODO')],
|
||||
class TLM_ImageProperties(bpy.types.PropertyGroup):
|
||||
tlm_image_scale_engine : EnumProperty(
|
||||
items = [('OpenCV', 'OpenCV', 'TODO')],
|
||||
name = "Scaling engine",
|
||||
description="TODO",
|
||||
default='Native')
|
||||
default='OpenCV')
|
||||
|
||||
#('Native', 'Native', 'TODO'),
|
||||
|
||||
tlm_image_scale_method : EnumProperty(
|
||||
items = [('Nearest', 'Nearest', 'TODO'),
|
||||
('Area', 'Area', 'TODO'),
|
||||
('Linear', 'Linear', 'TODO'),
|
||||
('Cubic', 'Cubic', 'TODO'),
|
||||
('Lanczos', 'Lanczos', 'TODO')],
|
||||
name = "Scaling method",
|
||||
description="TODO",
|
||||
default='Lanczos')
|
||||
|
||||
tlm_image_cache_switch : BoolProperty(
|
||||
name="Cache for quickswitch",
|
||||
description="Caches scaled images for quick switching",
|
||||
default=True)
|
|
@ -7,7 +7,7 @@ class TLM_ObjectProperties(bpy.types.PropertyGroup):
|
|||
|
||||
tlm_atlas_pointer : StringProperty(
|
||||
name = "Atlas Group",
|
||||
description = "Atlas Lightmap Group",
|
||||
description = "",
|
||||
default = "")
|
||||
|
||||
tlm_postatlas_pointer : StringProperty(
|
||||
|
@ -51,8 +51,7 @@ class TLM_ObjectProperties(bpy.types.PropertyGroup):
|
|||
|
||||
unwrap_modes = [('Lightmap', 'Lightmap', 'TODO'),
|
||||
('SmartProject', 'Smart Project', 'TODO'),
|
||||
('CopyExisting', 'Copy Existing', 'TODO'),
|
||||
('AtlasGroupA', 'Atlas Group (Prepack)', 'TODO')]
|
||||
('AtlasGroupA', 'Atlas Group (Prepack)', 'Attaches the object to a prepack Atlas group. Will overwrite UV map on build.')]
|
||||
|
||||
tlm_postpack_object : BoolProperty( #CHECK INSTEAD OF ATLASGROUPB
|
||||
name="Postpack object",
|
||||
|
@ -145,4 +144,14 @@ class TLM_ObjectProperties(bpy.types.PropertyGroup):
|
|||
name="Median kernel",
|
||||
default=3,
|
||||
min=1,
|
||||
max=5)
|
||||
max=5)
|
||||
|
||||
tlm_use_default_channel : BoolProperty(
|
||||
name="Use default UV channel",
|
||||
description="Will either use or create the default UV Channel 'UVMap_Lightmap' upon build.",
|
||||
default=True)
|
||||
|
||||
tlm_uv_channel : StringProperty(
|
||||
name = "UV Channel",
|
||||
description = "Use any custom UV Channel for the lightmap",
|
||||
default = "UVMap")
|
|
@ -21,6 +21,16 @@ class TLM_CyclesSceneProperties(bpy.types.PropertyGroup):
|
|||
description="Select baking quality",
|
||||
default="0")
|
||||
|
||||
targets = [('texture', 'Image texture', 'Build to image texture')]
|
||||
if (2, 92, 0) >= bpy.app.version:
|
||||
targets.append(('vertex', 'Vertex colors', 'Build to vertex colors'))
|
||||
|
||||
tlm_target : EnumProperty(
|
||||
items = targets,
|
||||
name = "Build Target",
|
||||
description="Select target to build to",
|
||||
default="texture")
|
||||
|
||||
tlm_resolution_scale : EnumProperty(
|
||||
items = [('1', '1/1', '1'),
|
||||
('2', '1/2', '2'),
|
||||
|
@ -45,10 +55,12 @@ class TLM_CyclesSceneProperties(bpy.types.PropertyGroup):
|
|||
description="Select bake mode",
|
||||
default="Foreground")
|
||||
|
||||
caching_modes = [('Copy', 'Copy', 'More overhead; allows for network.')]
|
||||
|
||||
#caching_modes.append(('Cache', 'Cache', 'Cache in separate blend'),('Node', 'Node restore', 'EXPERIMENTAL! Use with care'))
|
||||
|
||||
tlm_caching_mode : EnumProperty(
|
||||
items = [('Copy', 'Copy', 'More overhead; allows for network.'),
|
||||
('Cache', 'Cache', 'Cache in separate blend'),
|
||||
('Node', 'Node restore', 'EXPERIMENTAL! Use with care')],
|
||||
items = caching_modes,
|
||||
name = "Caching mode",
|
||||
description="Select cache mode",
|
||||
default="Copy")
|
||||
|
@ -88,8 +100,16 @@ class TLM_CyclesSceneProperties(bpy.types.PropertyGroup):
|
|||
|
||||
tlm_lighting_mode : EnumProperty(
|
||||
items = [('combined', 'Combined', 'Bake combined lighting'),
|
||||
('combinedao', 'Combined+AO', 'Bake combined lighting with Ambient Occlusion'),
|
||||
('indirect', 'Indirect', 'Bake indirect lighting'),
|
||||
('ao', 'AO', 'Bake only Ambient Occlusion')],
|
||||
# ('indirectao', 'Indirect+AO', 'Bake indirect lighting with Ambient Occlusion'),
|
||||
('ao', 'AO', 'Bake only Ambient Occlusion'),
|
||||
('complete', 'Complete', 'Bake complete map')],
|
||||
name = "Lighting mode",
|
||||
description="TODO.",
|
||||
default="combined")
|
||||
default="combined")
|
||||
|
||||
tlm_premultiply_ao : BoolProperty(
|
||||
name="Premultiply AO",
|
||||
description="Ambient Occlusion will be premultiplied together with lightmaps, requiring less textures.",
|
||||
default=True)
|
|
@ -0,0 +1,10 @@
|
|||
import bpy
|
||||
from bpy.props import *
|
||||
|
||||
class TLM_OctanerenderSceneProperties(bpy.types.PropertyGroup):
|
||||
|
||||
tlm_lightmap_savedir : StringProperty(
|
||||
name="Lightmap Directory",
|
||||
description="TODO",
|
||||
default="Lightmaps",
|
||||
subtype="FILE_PATH")
|
|
@ -1,11 +1,19 @@
|
|||
import bpy
|
||||
import bpy, os
|
||||
from bpy.props import *
|
||||
from .. utility import utility
|
||||
|
||||
def transfer_load():
|
||||
load_folder = bpy.context.scene.TLM_SceneProperties.tlm_load_folder
|
||||
lightmap_folder = os.path.join(os.path.dirname(bpy.data.filepath), bpy.context.scene.TLM_EngineProperties.tlm_lightmap_savedir)
|
||||
print(load_folder)
|
||||
print(lightmap_folder)
|
||||
#transfer_assets(True, load_folder, lightmap_folder)
|
||||
|
||||
class TLM_SceneProperties(bpy.types.PropertyGroup):
|
||||
|
||||
engines = [('Cycles', 'Cycles', 'Use Cycles for lightmapping')]
|
||||
|
||||
engines.append(('LuxCoreRender', 'LuxCoreRender', 'Use LuxCoreRender for lightmapping'))
|
||||
#engines.append(('LuxCoreRender', 'LuxCoreRender', 'Use LuxCoreRender for lightmapping'))
|
||||
#engines.append(('OctaneRender', 'Octane Render', 'Use Octane Render for lightmapping'))
|
||||
|
||||
tlm_atlas_pointer : StringProperty(
|
||||
|
@ -112,7 +120,7 @@ class TLM_SceneProperties(bpy.types.PropertyGroup):
|
|||
|
||||
#FILTERING SETTINGS GROUP
|
||||
tlm_filtering_use : BoolProperty(
|
||||
name="Enable Filtering",
|
||||
name="Enable denoising",
|
||||
description="Enable denoising for lightmaps",
|
||||
default=False)
|
||||
|
||||
|
@ -182,6 +190,17 @@ class TLM_SceneProperties(bpy.types.PropertyGroup):
|
|||
min=1,
|
||||
max=5)
|
||||
|
||||
tlm_clamp_hdr : BoolProperty(
|
||||
name="Enable HDR Clamp",
|
||||
description="Clamp HDR Value",
|
||||
default=False)
|
||||
|
||||
tlm_clamp_hdr_value : IntProperty(
|
||||
name="HDR Clamp value",
|
||||
default=10,
|
||||
min=0,
|
||||
max=20)
|
||||
|
||||
#Encoding properties
|
||||
tlm_encoding_use : BoolProperty(
|
||||
name="Enable encoding",
|
||||
|
@ -197,12 +216,13 @@ class TLM_SceneProperties(bpy.types.PropertyGroup):
|
|||
|
||||
encoding_modes_1 = [('RGBM', 'RGBM', '8-bit HDR encoding. Good for compatibility, good for memory but has banding issues.'),
|
||||
('RGBD', 'RGBD', '8-bit HDR encoding. Similar to RGBM.'),
|
||||
('HDR', 'HDR', '32-bit HDR encoding. Best quality, but high memory usage and not compatible with all devices.')]
|
||||
('HDR', 'HDR', '32-bit HDR encoding. Best quality, but high memory usage and not compatible with all devices.'),
|
||||
('SDR', 'SDR', '8-bit flat encoding.')]
|
||||
|
||||
encoding_modes_2 = [('RGBM', 'RGBM', '8-bit HDR encoding. Good for compatibility, good for memory but has banding issues.'),
|
||||
('RGBD', 'RGBD', '8-bit HDR encoding. Similar to RGBM.'),
|
||||
encoding_modes_2 = [('RGBD', 'RGBD', '8-bit HDR encoding. Similar to RGBM.'),
|
||||
('LogLuv', 'LogLuv', '8-bit HDR encoding. Different.'),
|
||||
('HDR', 'HDR', '32-bit HDR encoding. Best quality, but high memory usage and not compatible with all devices.')]
|
||||
('HDR', 'HDR', '32-bit HDR encoding. Best quality, but high memory usage and not compatible with all devices.'),
|
||||
('SDR', 'SDR', '8-bit flat encoding.')]
|
||||
|
||||
tlm_encoding_mode_a : EnumProperty(
|
||||
items = encoding_modes_1,
|
||||
|
@ -275,8 +295,7 @@ class TLM_SceneProperties(bpy.types.PropertyGroup):
|
|||
tlm_mesh_lightmap_unwrap_mode : EnumProperty(
|
||||
items = [('Lightmap', 'Lightmap', 'TODO'),
|
||||
('SmartProject', 'Smart Project', 'TODO'),
|
||||
('CopyExisting', 'Copy Existing', 'TODO'),
|
||||
('AtlasGroupA', 'Atlas Group (Prepack)', 'TODO'),
|
||||
('AtlasGroupA', 'Atlas Group (Prepack)', 'Attaches the object to a prepack Atlas group. Will overwrite UV map on build.'),
|
||||
('Xatlas', 'Xatlas', 'TODO')],
|
||||
name = "Unwrap Mode",
|
||||
description="TODO",
|
||||
|
@ -317,12 +336,30 @@ class TLM_SceneProperties(bpy.types.PropertyGroup):
|
|||
|
||||
tlm_metallic_clamp : EnumProperty(
|
||||
items = [('ignore', 'Ignore', 'Ignore clamping'),
|
||||
('skip', 'Skip', 'Skip baking metallic materials'),
|
||||
('zero', 'Zero', 'Set zero'),
|
||||
('limit', 'Limit', 'Clamp to 0.9')],
|
||||
name = "Metallic clamping",
|
||||
description="TODO.",
|
||||
default="ignore")
|
||||
|
||||
tlm_texture_interpolation : EnumProperty(
|
||||
items = [('Smart', 'Smart', 'Bicubic when magnifying.'),
|
||||
('Cubic', 'Cubic', 'Cubic interpolation'),
|
||||
('Closest', 'Closest', 'No interpolation'),
|
||||
('Linear', 'Linear', 'Linear')],
|
||||
name = "Texture interpolation",
|
||||
description="Texture interpolation.",
|
||||
default="Linear")
|
||||
|
||||
tlm_texture_extrapolation : EnumProperty(
|
||||
items = [('REPEAT', 'Repeat', 'Repeat in both direction.'),
|
||||
('EXTEND', 'Extend', 'Extend by repeating edge pixels.'),
|
||||
('CLIP', 'Clip', 'Clip to image size')],
|
||||
name = "Texture extrapolation",
|
||||
description="Texture extrapolation.",
|
||||
default="EXTEND")
|
||||
|
||||
tlm_verbose : BoolProperty(
|
||||
name="Verbose",
|
||||
description="Verbose console output",
|
||||
|
@ -409,4 +446,52 @@ class TLM_SceneProperties(bpy.types.PropertyGroup):
|
|||
('CYCLES', 'Cycles', 'TODO')],
|
||||
name = "Probe Render Engine",
|
||||
description="TODO",
|
||||
default='BLENDER_EEVEE')
|
||||
default='BLENDER_EEVEE')
|
||||
|
||||
tlm_load_folder : StringProperty(
|
||||
name="Load Folder",
|
||||
description="Load existing lightmaps from folder",
|
||||
subtype="DIR_PATH")
|
||||
|
||||
tlm_utility_set : EnumProperty(
|
||||
items = [('Scene', 'Scene', 'Set for all objects in the scene.'),
|
||||
('Selection', 'Selection', 'Set for selected objects.'),
|
||||
('Enabled', 'Enabled', 'Set for objects that has been enabled for lightmapping.')],
|
||||
name = "Set",
|
||||
description="Utility selection set",
|
||||
default='Scene')
|
||||
|
||||
tlm_resolution_weight : EnumProperty(
|
||||
items = [('Single', 'Single', 'Set a single resolution for all objects.'),
|
||||
('Dimension', 'Dimension', 'Distribute resolutions based on object dimensions.'),
|
||||
('Surface', 'Surface', 'Distribute resolutions based on mesh surface area.'),
|
||||
('Volume', 'Volume', 'Distribute resolutions based on mesh volume.')],
|
||||
name = "Resolution weight",
|
||||
description="Method for setting resolution value",
|
||||
default='Single')
|
||||
#Todo add vertex color option
|
||||
|
||||
tlm_resolution_min : 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')],
|
||||
name = "Minimum resolution",
|
||||
description="Minimum distributed resolution",
|
||||
default='32')
|
||||
|
||||
tlm_resolution_max : EnumProperty(
|
||||
items = [('64', '64', 'TODO'),
|
||||
('128', '128', 'TODO'),
|
||||
('256', '256', 'TODO'),
|
||||
('512', '512', 'TODO'),
|
||||
('1024', '1024', 'TODO'),
|
||||
('2048', '2048', 'TODO'),
|
||||
('4096', '4096', 'TODO')],
|
||||
name = "Maximum resolution",
|
||||
description="Maximum distributed resolution",
|
||||
default='256')
|
|
@ -1,17 +1,20 @@
|
|||
import bpy, os, subprocess, sys, platform, aud, json, datetime, socket
|
||||
import threading
|
||||
|
||||
from . import encoding, pack
|
||||
from . cycles import lightmap, prepare, nodes, cache
|
||||
from . luxcore import setup
|
||||
from . octane import configure, lightmap2
|
||||
from . denoiser import integrated, oidn, optix
|
||||
from . filtering import opencv
|
||||
from . gui import Viewport
|
||||
from .. network import client
|
||||
|
||||
from os import listdir
|
||||
from os.path import isfile, join
|
||||
from time import time, sleep
|
||||
from importlib import util
|
||||
|
||||
previous_settings = {}
|
||||
|
||||
postprocess_shutdown = False
|
||||
|
||||
def prepare_build(self=0, background_mode=False, shutdown_after_build=False):
|
||||
|
@ -21,15 +24,31 @@ def prepare_build(self=0, background_mode=False, shutdown_after_build=False):
|
|||
|
||||
print("Building lightmaps")
|
||||
|
||||
if bpy.context.scene.TLM_EngineProperties.tlm_lighting_mode == "combinedao":
|
||||
|
||||
scene = bpy.context.scene
|
||||
|
||||
if not "tlm_plus_mode" in bpy.app.driver_namespace or bpy.app.driver_namespace["tlm_plus_mode"] == 0:
|
||||
filepath = bpy.data.filepath
|
||||
dirpath = os.path.join(os.path.dirname(bpy.data.filepath), scene.TLM_EngineProperties.tlm_lightmap_savedir)
|
||||
if os.path.isdir(dirpath):
|
||||
for file in os.listdir(dirpath):
|
||||
os.remove(os.path.join(dirpath + "/" + file))
|
||||
bpy.app.driver_namespace["tlm_plus_mode"] = 1
|
||||
print("Plus Mode")
|
||||
|
||||
if bpy.context.scene.TLM_EngineProperties.tlm_bake_mode == "Foreground" or background_mode==True:
|
||||
|
||||
global start_time
|
||||
start_time = time()
|
||||
bpy.app.driver_namespace["tlm_start_time"] = time()
|
||||
|
||||
scene = bpy.context.scene
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
|
||||
#Timer start here bound to global
|
||||
if not background_mode and bpy.context.scene.TLM_EngineProperties.tlm_lighting_mode != "combinedao":
|
||||
#pass
|
||||
setGui(1)
|
||||
|
||||
if check_save():
|
||||
print("Please save your file first")
|
||||
|
@ -52,12 +71,6 @@ def prepare_build(self=0, background_mode=False, shutdown_after_build=False):
|
|||
self.report({'INFO'}, "Error:Filtering - OpenCV not installed")
|
||||
return{'FINISHED'}
|
||||
|
||||
#TODO DO some resolution change
|
||||
#if checkAtlasSize():
|
||||
# print("Error: AtlasGroup overflow")
|
||||
# self.report({'INFO'}, "Error: AtlasGroup overflow - Too many objects")
|
||||
# return{'FINISHED'}
|
||||
|
||||
setMode()
|
||||
|
||||
dirpath = os.path.join(os.path.dirname(bpy.data.filepath), bpy.context.scene.TLM_EngineProperties.tlm_lightmap_savedir)
|
||||
|
@ -67,19 +80,6 @@ def prepare_build(self=0, background_mode=False, shutdown_after_build=False):
|
|||
#Naming check
|
||||
naming_check()
|
||||
|
||||
# if sceneProperties.tlm_reset_uv or sceneProperties.tlm_atlas_mode == "Postpack":
|
||||
# for obj in bpy.data.objects:
|
||||
# if obj.type == "MESH":
|
||||
# uv_layers = obj.data.uv_layers
|
||||
|
||||
|
||||
|
||||
#for uvlayer in uv_layers:
|
||||
# if uvlayer.name == "UVMap_Lightmap":
|
||||
# uv_layers.remove(uvlayer)
|
||||
|
||||
## RENDER DEPENDENCY FROM HERE
|
||||
|
||||
if sceneProperties.tlm_lightmap_engine == "Cycles":
|
||||
|
||||
prepare.init(self, previous_settings)
|
||||
|
@ -90,18 +90,14 @@ def prepare_build(self=0, background_mode=False, shutdown_after_build=False):
|
|||
|
||||
if sceneProperties.tlm_lightmap_engine == "OctaneRender":
|
||||
|
||||
pass
|
||||
|
||||
#Renderer - Store settings
|
||||
|
||||
#Renderer - Set settings
|
||||
|
||||
#Renderer - Config objects, lights, world
|
||||
configure.init(self, previous_settings)
|
||||
|
||||
begin_build()
|
||||
|
||||
else:
|
||||
|
||||
print("Baking in background")
|
||||
|
||||
filepath = bpy.data.filepath
|
||||
|
||||
bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath)
|
||||
|
@ -111,22 +107,7 @@ def prepare_build(self=0, background_mode=False, shutdown_after_build=False):
|
|||
scene = bpy.context.scene
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
|
||||
#We dynamically load the renderer and denoiser, instead of loading something we don't use
|
||||
|
||||
if sceneProperties.tlm_lightmap_engine == "Cycles":
|
||||
|
||||
pass
|
||||
|
||||
if sceneProperties.tlm_lightmap_engine == "LuxCoreRender":
|
||||
|
||||
pass
|
||||
|
||||
if sceneProperties.tlm_lightmap_engine == "OctaneRender":
|
||||
|
||||
pass
|
||||
|
||||
#Timer start here bound to global
|
||||
|
||||
if check_save():
|
||||
print("Please save your file first")
|
||||
self.report({'INFO'}, "Please save your file first")
|
||||
|
@ -168,23 +149,12 @@ def prepare_build(self=0, background_mode=False, shutdown_after_build=False):
|
|||
|
||||
client.connect_client(HOST, PORT, bpy.data.filepath, 0)
|
||||
|
||||
# with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||
# s.connect((HOST, PORT))
|
||||
# message = {
|
||||
# "call" : 1,
|
||||
# "command" : 1,
|
||||
# "enquiry" : 0,
|
||||
# "args" : bpy.data.filepath
|
||||
# }
|
||||
|
||||
# s.sendall(json.dumps(message).encode())
|
||||
# data = s.recv(1024)
|
||||
# print(data.decode())
|
||||
|
||||
finish_assemble()
|
||||
|
||||
else:
|
||||
|
||||
print("Background driver process")
|
||||
|
||||
bpy.app.driver_namespace["alpha"] = 0
|
||||
|
||||
bpy.app.driver_namespace["tlm_process"] = False
|
||||
|
@ -196,6 +166,8 @@ def prepare_build(self=0, background_mode=False, shutdown_after_build=False):
|
|||
|
||||
def distribute_building():
|
||||
|
||||
print("Distributing lightmap building")
|
||||
|
||||
#CHECK IF THERE'S AN EXISTING SUBPROCESS
|
||||
|
||||
if not os.path.isfile(os.path.join(os.path.dirname(bpy.data.filepath), bpy.context.scene.TLM_EngineProperties.tlm_lightmap_savedir, "process.tlm")):
|
||||
|
@ -215,8 +187,16 @@ def distribute_building():
|
|||
with open(os.path.join(write_directory, "process.tlm"), 'w') as file:
|
||||
json.dump(process_status, file, indent=2)
|
||||
|
||||
bpy.app.driver_namespace["tlm_process"] = subprocess.Popen([sys.executable,"-b", blendPath,"--python-expr",'import bpy; import thelightmapper; thelightmapper.addon.utility.build.prepare_build(0, True);'], shell=False, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
|
||||
|
||||
if (2, 91, 0) > bpy.app.version:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
bpy.app.driver_namespace["tlm_process"] = subprocess.Popen([sys.executable,"-b", blendPath,"--python-expr",'import bpy; import thelightmapper; thelightmapper.addon.utility.build.prepare_build(0, True);'], shell=False, stdout=subprocess.PIPE)
|
||||
else:
|
||||
bpy.app.driver_namespace["tlm_process"] = subprocess.Popen([sys.executable,"-b", blendPath,"--python-expr",'import bpy; import thelightmapper; thelightmapper.addon.utility.build.prepare_build(0, True);'], shell=False, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
|
||||
else:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
bpy.app.driver_namespace["tlm_process"] = subprocess.Popen([bpy.app.binary_path,"-b", blendPath,"--python-expr",'import bpy; import thelightmapper; thelightmapper.addon.utility.build.prepare_build(0, True);'], shell=False, stdout=subprocess.PIPE)
|
||||
else:
|
||||
bpy.app.driver_namespace["tlm_process"] = subprocess.Popen([bpy.app.binary_path,"-b", blendPath,"--python-expr",'import bpy; import thelightmapper; thelightmapper.addon.utility.build.prepare_build(0, True);'], shell=False, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Started process: " + str(bpy.app.driver_namespace["tlm_process"]) + " at " + str(datetime.datetime.now()))
|
||||
|
||||
|
@ -269,6 +249,10 @@ def finish_assemble(self=0):
|
|||
if sceneProperties.tlm_lightmap_engine == "OctaneRender":
|
||||
pass
|
||||
|
||||
if not 'start_time' in globals():
|
||||
global start_time
|
||||
start_time = time()
|
||||
|
||||
manage_build(True)
|
||||
|
||||
def begin_build():
|
||||
|
@ -288,7 +272,8 @@ def begin_build():
|
|||
pass
|
||||
|
||||
if sceneProperties.tlm_lightmap_engine == "OctaneRender":
|
||||
pass
|
||||
|
||||
lightmap2.bake()
|
||||
|
||||
#Denoiser
|
||||
if sceneProperties.tlm_denoise_use:
|
||||
|
@ -429,7 +414,7 @@ def begin_build():
|
|||
print("Encoding:" + str(file))
|
||||
encoding.encodeImageRGBMCPU(img, sceneProperties.tlm_encoding_range, dirpath, 0)
|
||||
|
||||
if sceneProperties.tlm_encoding_mode_b == "RGBD":
|
||||
if sceneProperties.tlm_encoding_mode_a == "RGBD":
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("ENCODING RGBD")
|
||||
|
@ -455,6 +440,36 @@ def begin_build():
|
|||
print("Encoding:" + str(file))
|
||||
encoding.encodeImageRGBDCPU(img, sceneProperties.tlm_encoding_range, dirpath, 0)
|
||||
|
||||
if sceneProperties.tlm_encoding_mode_a == "SDR":
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("EXR Format")
|
||||
|
||||
ren = bpy.context.scene.render
|
||||
ren.image_settings.file_format = "PNG"
|
||||
#ren.image_settings.exr_codec = "scene.TLM_SceneProperties.tlm_exr_codec"
|
||||
|
||||
end = "_baked"
|
||||
|
||||
baked_image_array = []
|
||||
|
||||
if sceneProperties.tlm_denoise_use:
|
||||
|
||||
end = "_denoised"
|
||||
|
||||
if sceneProperties.tlm_filtering_use:
|
||||
|
||||
end = "_filtered"
|
||||
|
||||
#For each image in folder ending in denoised/filtered
|
||||
dirfiles = [f for f in listdir(dirpath) if isfile(join(dirpath, f))]
|
||||
|
||||
for file in dirfiles:
|
||||
if file.endswith(end + ".hdr"):
|
||||
|
||||
img = bpy.data.images.load(os.path.join(dirpath,file))
|
||||
img.save_render(img.filepath_raw[:-4] + ".png")
|
||||
|
||||
else:
|
||||
|
||||
if sceneProperties.tlm_encoding_mode_b == "HDR":
|
||||
|
@ -562,6 +577,33 @@ def begin_build():
|
|||
print("Encoding:" + str(file))
|
||||
encoding.encodeImageRGBDGPU(img, sceneProperties.tlm_encoding_range, dirpath, 0)
|
||||
|
||||
if sceneProperties.tlm_encoding_mode_b == "PNG":
|
||||
|
||||
ren = bpy.context.scene.render
|
||||
ren.image_settings.file_format = "PNG"
|
||||
#ren.image_settings.exr_codec = "scene.TLM_SceneProperties.tlm_exr_codec"
|
||||
|
||||
end = "_baked"
|
||||
|
||||
baked_image_array = []
|
||||
|
||||
if sceneProperties.tlm_denoise_use:
|
||||
|
||||
end = "_denoised"
|
||||
|
||||
if sceneProperties.tlm_filtering_use:
|
||||
|
||||
end = "_filtered"
|
||||
|
||||
#For each image in folder ending in denoised/filtered
|
||||
dirfiles = [f for f in listdir(dirpath) if isfile(join(dirpath, f))]
|
||||
|
||||
for file in dirfiles:
|
||||
if file.endswith(end + ".hdr"):
|
||||
|
||||
img = bpy.data.images.load(os.path.join(dirpath,file))
|
||||
img.save_render(img.filepath_raw[:-4] + ".png")
|
||||
|
||||
manage_build()
|
||||
|
||||
def manage_build(background_pass=False):
|
||||
|
@ -610,6 +652,10 @@ def manage_build(background_pass=False):
|
|||
|
||||
formatEnc = "_encoded.png"
|
||||
|
||||
if sceneProperties.tlm_encoding_mode_a == "SDR":
|
||||
|
||||
formatEnc = ".png"
|
||||
|
||||
else:
|
||||
|
||||
print("GPU Encoding")
|
||||
|
@ -632,6 +678,10 @@ def manage_build(background_pass=False):
|
|||
|
||||
formatEnc = "_encoded.png"
|
||||
|
||||
if sceneProperties.tlm_encoding_mode_b == "SDR":
|
||||
|
||||
formatEnc = ".png"
|
||||
|
||||
if not background_pass:
|
||||
nodes.exchangeLightmapsToPostfix("_baked", end, formatEnc)
|
||||
|
||||
|
@ -653,13 +703,13 @@ def manage_build(background_pass=False):
|
|||
filepath = bpy.data.filepath
|
||||
dirpath = os.path.join(os.path.dirname(bpy.data.filepath), scene.TLM_EngineProperties.tlm_lightmap_savedir)
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == "MESH":
|
||||
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.data.objects:
|
||||
if obj.type == "MESH":
|
||||
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)
|
||||
|
||||
|
@ -672,77 +722,181 @@ def manage_build(background_pass=False):
|
|||
if "_Original" in mat.name:
|
||||
bpy.data.materials.remove(mat)
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
|
||||
if obj.type == "MESH":
|
||||
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:
|
||||
img_name = obj.name + '_baked'
|
||||
Lightmapimage = bpy.data.images[img_name]
|
||||
obj["Lightmap"] = Lightmapimage.filepath_raw
|
||||
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
atlasName = obj.TLM_ObjectProperties.tlm_atlas_pointer
|
||||
img_name = atlasName + '_baked'
|
||||
Lightmapimage = bpy.data.images[img_name]
|
||||
obj["Lightmap"] = Lightmapimage.filepath_raw
|
||||
elif obj.TLM_ObjectProperties.tlm_postpack_object:
|
||||
atlasName = obj.TLM_ObjectProperties.tlm_postatlas_pointer
|
||||
img_name = atlasName + '_baked' + ".hdr"
|
||||
Lightmapimage = bpy.data.images[img_name]
|
||||
obj["Lightmap"] = Lightmapimage.filepath_raw
|
||||
else:
|
||||
img_name = obj.name + '_baked'
|
||||
Lightmapimage = bpy.data.images[img_name]
|
||||
obj["Lightmap"] = Lightmapimage.filepath_raw
|
||||
|
||||
for image in bpy.data.images:
|
||||
if image.name.endswith("_baked"):
|
||||
bpy.data.images.remove(image, do_unlink=True)
|
||||
|
||||
total_time = sec_to_hours((time() - start_time))
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print(total_time)
|
||||
if "tlm_plus_mode" in bpy.app.driver_namespace: #First DIR pass
|
||||
|
||||
bpy.context.scene["TLM_Buildstat"] = total_time
|
||||
if bpy.app.driver_namespace["tlm_plus_mode"] == 1: #First DIR pass
|
||||
|
||||
reset_settings(previous_settings["settings"])
|
||||
filepath = bpy.data.filepath
|
||||
dirpath = os.path.join(os.path.dirname(bpy.data.filepath), scene.TLM_EngineProperties.tlm_lightmap_savedir)
|
||||
|
||||
if sceneProperties.tlm_lightmap_engine == "LuxCoreRender":
|
||||
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)
|
||||
|
||||
pass
|
||||
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)
|
||||
|
||||
if sceneProperties.tlm_lightmap_engine == "OctaneRender":
|
||||
for mat in bpy.data.materials:
|
||||
if mat.users < 1:
|
||||
bpy.data.materials.remove(mat)
|
||||
|
||||
pass
|
||||
for mat in bpy.data.materials:
|
||||
if mat.name.startswith("."):
|
||||
if "_Original" in mat.name:
|
||||
bpy.data.materials.remove(mat)
|
||||
|
||||
if bpy.context.scene.TLM_EngineProperties.tlm_bake_mode == "Background":
|
||||
pass
|
||||
for image in bpy.data.images:
|
||||
if image.name.endswith("_baked"):
|
||||
bpy.data.images.remove(image, do_unlink=True)
|
||||
|
||||
if scene.TLM_SceneProperties.tlm_alert_on_finish:
|
||||
dirpath = os.path.join(os.path.dirname(bpy.data.filepath), bpy.context.scene.TLM_EngineProperties.tlm_lightmap_savedir)
|
||||
|
||||
alertSelect = scene.TLM_SceneProperties.tlm_alert_sound
|
||||
files = os.listdir(dirpath)
|
||||
|
||||
for index, file in enumerate(files):
|
||||
|
||||
filename = extension = os.path.splitext(file)[0]
|
||||
extension = os.path.splitext(file)[1]
|
||||
|
||||
os.rename(os.path.join(dirpath, file), os.path.join(dirpath, filename + "_dir" + extension))
|
||||
|
||||
print("First DIR pass complete")
|
||||
|
||||
bpy.app.driver_namespace["tlm_plus_mode"] = 2
|
||||
|
||||
prepare_build(self=0, background_mode=False, shutdown_after_build=False)
|
||||
|
||||
if not background_pass and bpy.context.scene.TLM_EngineProperties.tlm_lighting_mode != "combinedao":
|
||||
#pass
|
||||
setGui(0)
|
||||
|
||||
elif bpy.app.driver_namespace["tlm_plus_mode"] == 2:
|
||||
|
||||
filepath = bpy.data.filepath
|
||||
|
||||
dirpath = os.path.join(os.path.dirname(bpy.data.filepath), bpy.context.scene.TLM_EngineProperties.tlm_lightmap_savedir)
|
||||
|
||||
files = os.listdir(dirpath)
|
||||
|
||||
for index, file in enumerate(files):
|
||||
|
||||
filename = os.path.splitext(file)[0]
|
||||
extension = os.path.splitext(file)[1]
|
||||
|
||||
if not filename.endswith("_dir"):
|
||||
os.rename(os.path.join(dirpath, file), os.path.join(dirpath, filename + "_ao" + extension))
|
||||
|
||||
print("Second AO pass complete")
|
||||
|
||||
total_time = sec_to_hours((time() - start_time))
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print(total_time)
|
||||
|
||||
bpy.context.scene["TLM_Buildstat"] = total_time
|
||||
|
||||
reset_settings(previous_settings["settings"])
|
||||
|
||||
bpy.app.driver_namespace["tlm_plus_mode"] = 0
|
||||
|
||||
if not background_pass:
|
||||
|
||||
#TODO CHANGE!
|
||||
|
||||
nodes.exchangeLightmapsToPostfix(end, end + "_dir", formatEnc)
|
||||
|
||||
nodes.applyAOPass()
|
||||
|
||||
if alertSelect == "dash":
|
||||
soundfile = "dash.ogg"
|
||||
elif alertSelect == "pingping":
|
||||
soundfile = "pingping.ogg"
|
||||
elif alertSelect == "gentle":
|
||||
soundfile = "gentle.ogg"
|
||||
else:
|
||||
soundfile = "noot.ogg"
|
||||
|
||||
scriptDir = os.path.dirname(os.path.realpath(__file__))
|
||||
sound_path = os.path.abspath(os.path.join(scriptDir, '..', 'assets/'+soundfile))
|
||||
total_time = sec_to_hours((time() - start_time))
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print(total_time)
|
||||
|
||||
device = aud.Device()
|
||||
sound = aud.Sound.file(sound_path)
|
||||
device.play(sound)
|
||||
bpy.context.scene["TLM_Buildstat"] = total_time
|
||||
|
||||
print("Lightmap building finished")
|
||||
reset_settings(previous_settings["settings"])
|
||||
|
||||
if bpy.app.background:
|
||||
print("Lightmap building finished")
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Writing background process report")
|
||||
|
||||
write_directory = os.path.join(os.path.dirname(bpy.data.filepath), bpy.context.scene.TLM_EngineProperties.tlm_lightmap_savedir)
|
||||
if sceneProperties.tlm_lightmap_engine == "LuxCoreRender":
|
||||
|
||||
if os.path.exists(os.path.join(write_directory, "process.tlm")):
|
||||
pass
|
||||
|
||||
process_status = json.loads(open(os.path.join(write_directory, "process.tlm")).read())
|
||||
if sceneProperties.tlm_lightmap_engine == "OctaneRender":
|
||||
|
||||
process_status[1]["completed"] = True
|
||||
pass
|
||||
|
||||
with open(os.path.join(write_directory, "process.tlm"), 'w') as file:
|
||||
json.dump(process_status, file, indent=2)
|
||||
if bpy.context.scene.TLM_EngineProperties.tlm_bake_mode == "Background":
|
||||
pass
|
||||
|
||||
if postprocess_shutdown:
|
||||
sys.exit()
|
||||
if not background_pass and bpy.context.scene.TLM_EngineProperties.tlm_lighting_mode != "combinedao":
|
||||
#pass
|
||||
setGui(0)
|
||||
|
||||
if scene.TLM_SceneProperties.tlm_alert_on_finish:
|
||||
|
||||
alertSelect = scene.TLM_SceneProperties.tlm_alert_sound
|
||||
|
||||
if alertSelect == "dash":
|
||||
soundfile = "dash.ogg"
|
||||
elif alertSelect == "pingping":
|
||||
soundfile = "pingping.ogg"
|
||||
elif alertSelect == "gentle":
|
||||
soundfile = "gentle.ogg"
|
||||
else:
|
||||
soundfile = "noot.ogg"
|
||||
|
||||
scriptDir = os.path.dirname(os.path.realpath(__file__))
|
||||
sound_path = os.path.abspath(os.path.join(scriptDir, '..', 'assets/'+soundfile))
|
||||
|
||||
device = aud.Device()
|
||||
sound = aud.Sound.file(sound_path)
|
||||
device.play(sound)
|
||||
|
||||
if bpy.app.background:
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Writing background process report")
|
||||
|
||||
write_directory = os.path.join(os.path.dirname(bpy.data.filepath), bpy.context.scene.TLM_EngineProperties.tlm_lightmap_savedir)
|
||||
|
||||
if os.path.exists(os.path.join(write_directory, "process.tlm")):
|
||||
|
||||
process_status = json.loads(open(os.path.join(write_directory, "process.tlm")).read())
|
||||
|
||||
process_status[1]["completed"] = True
|
||||
|
||||
with open(os.path.join(write_directory, "process.tlm"), 'w') as file:
|
||||
json.dump(process_status, file, indent=2)
|
||||
|
||||
if postprocess_shutdown:
|
||||
sys.exit()
|
||||
|
||||
#TODO - SET BELOW TO UTILITY
|
||||
|
||||
|
@ -770,9 +924,8 @@ def reset_settings(prev_settings):
|
|||
|
||||
def naming_check():
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
|
||||
if obj.type == "MESH":
|
||||
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:
|
||||
|
||||
|
@ -829,6 +982,9 @@ def check_save():
|
|||
|
||||
def check_denoiser():
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Checking denoiser path")
|
||||
|
||||
scene = bpy.context.scene
|
||||
|
||||
if scene.TLM_SceneProperties.tlm_denoise_use:
|
||||
|
@ -847,8 +1003,8 @@ def check_denoiser():
|
|||
return 0
|
||||
|
||||
def check_materials():
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == "MESH":
|
||||
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 slot in obj.material_slots:
|
||||
mat = slot.material
|
||||
|
@ -868,15 +1024,39 @@ def check_materials():
|
|||
def sec_to_hours(seconds):
|
||||
a=str(seconds//3600)
|
||||
b=str((seconds%3600)//60)
|
||||
c=str((seconds%3600)%60)
|
||||
c=str(round((seconds%3600)%60,1))
|
||||
d=["{} hours {} mins {} seconds".format(a, b, c)]
|
||||
return d
|
||||
|
||||
def setMode():
|
||||
|
||||
obj = bpy.context.scene.objects[0]
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
obj.select_set(True)
|
||||
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
#TODO Make some checks that returns to previous selection
|
||||
|
||||
def setGui(mode):
|
||||
|
||||
if mode == 0:
|
||||
|
||||
context = bpy.context
|
||||
driver = bpy.app.driver_namespace
|
||||
|
||||
if "TLM_UI" in driver:
|
||||
driver["TLM_UI"].remove_handle()
|
||||
|
||||
if mode == 1:
|
||||
|
||||
#bpy.context.area.tag_redraw()
|
||||
context = bpy.context
|
||||
driver = bpy.app.driver_namespace
|
||||
driver["TLM_UI"] = Viewport.ViewportDraw(context, "Building Lightmaps")
|
||||
|
||||
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
|
||||
|
||||
def checkAtlasSize():
|
||||
|
||||
overflow = False
|
||||
|
@ -897,7 +1077,7 @@ def checkAtlasSize():
|
|||
utilized = 0
|
||||
atlasUsedArea = 0
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
if obj.TLM_ObjectProperties.tlm_postpack_object:
|
||||
if obj.TLM_ObjectProperties.tlm_postatlas_pointer == atlas.name:
|
||||
|
@ -912,4 +1092,5 @@ def checkAtlasSize():
|
|||
if overflow == True:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return False
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ import bpy
|
|||
|
||||
#Todo - Check if already exists, in case multiple objects has the same material
|
||||
|
||||
|
||||
def backup_material_copy(slot):
|
||||
material = slot.material
|
||||
dup = material.copy()
|
||||
|
@ -16,25 +15,49 @@ def backup_material_cache_restore(slot, path):
|
|||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Restore cache")
|
||||
|
||||
def backup_material_rename(obj):
|
||||
if "TLM_PrevMatArray" in obj:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Renaming material for: " + obj.name)
|
||||
# def backup_material_restore(obj): #??
|
||||
# if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
# print("Restoring material for: " + obj.name)
|
||||
|
||||
for slot in obj.material_slots:
|
||||
#Check if object has TLM_PrevMatArray
|
||||
# if yes
|
||||
# - check if array.len is bigger than 0:
|
||||
# if yes:
|
||||
# for slot in object:
|
||||
# originalMaterial = TLM_PrevMatArray[index]
|
||||
#
|
||||
#
|
||||
# if no:
|
||||
# - In which cases are these?
|
||||
|
||||
if slot.material is not None:
|
||||
if slot.material.name.endswith("_Original"):
|
||||
newname = slot.material.name[1:-9]
|
||||
if newname in bpy.data.materials:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Removing material: " + bpy.data.materials[newname].name)
|
||||
bpy.data.materials.remove(bpy.data.materials[newname])
|
||||
slot.material.name = newname
|
||||
# if no:
|
||||
# - In which cases are there not?
|
||||
# - If a lightmapped material was applied to a non-lightmap object?
|
||||
|
||||
del obj["TLM_PrevMatArray"]
|
||||
|
||||
def backup_material_restore(obj):
|
||||
# if bpy.data.materials[originalMaterial].users > 0: #TODO - Check if all lightmapped
|
||||
|
||||
# print("Material has multiple users")
|
||||
|
||||
# if originalMaterial in bpy.data.materials:
|
||||
# slot.material = bpy.data.materials[originalMaterial]
|
||||
# slot.material.use_fake_user = False
|
||||
# elif "." + originalMaterial + "_Original" in bpy.data.materials:
|
||||
# slot.material = bpy.data.materials["." + originalMaterial + "_Original"]
|
||||
# slot.material.use_fake_user = False
|
||||
|
||||
# else:
|
||||
|
||||
# print("Material has one user")
|
||||
|
||||
# if "." + originalMaterial + "_Original" in bpy.data.materials:
|
||||
# slot.material = bpy.data.materials["." + originalMaterial + "_Original"]
|
||||
# slot.material.use_fake_user = False
|
||||
# elif originalMaterial in bpy.data.materials:
|
||||
# slot.material = bpy.data.materials[originalMaterial]
|
||||
# slot.material.use_fake_user = False
|
||||
|
||||
def backup_material_restore(obj): #??
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Restoring material for: " + obj.name)
|
||||
|
||||
|
@ -59,9 +82,43 @@ def backup_material_restore(obj):
|
|||
originalMaterial = ""
|
||||
|
||||
if slot.material is not None:
|
||||
#slot.material.user_clear() Seems to be bad; See: https://developer.blender.org/T49837
|
||||
bpy.data.materials.remove(slot.material)
|
||||
#if slot.material.users < 2:
|
||||
#slot.material.user_clear() #Seems to be bad; See: https://developer.blender.org/T49837
|
||||
#bpy.data.materials.remove(slot.material)
|
||||
|
||||
if "." + originalMaterial + "_Original" in bpy.data.materials:
|
||||
slot.material = bpy.data.materials["." + originalMaterial + "_Original"]
|
||||
slot.material.use_fake_user = False
|
||||
slot.material.use_fake_user = False
|
||||
|
||||
else:
|
||||
|
||||
print("No previous material for " + obj.name)
|
||||
|
||||
else:
|
||||
|
||||
print("No previous material for " + obj.name)
|
||||
|
||||
def backup_material_rename(obj): #??
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Renaming material for: " + obj.name)
|
||||
|
||||
|
||||
if "TLM_PrevMatArray" in obj:
|
||||
|
||||
for slot in obj.material_slots:
|
||||
|
||||
if slot.material is not None:
|
||||
if slot.material.name.endswith("_Original"):
|
||||
newname = slot.material.name[1:-9]
|
||||
if newname in bpy.data.materials:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Removing material: " + bpy.data.materials[newname].name)
|
||||
#if bpy.data.materials[newname].users < 2:
|
||||
#bpy.data.materials.remove(bpy.data.materials[newname]) #TODO - Maybe remove this
|
||||
slot.material.name = newname
|
||||
|
||||
del obj["TLM_PrevMatArray"]
|
||||
|
||||
else:
|
||||
|
||||
print("No Previous material array for: " + obj.name)
|
|
@ -1,25 +1,26 @@
|
|||
import bpy, os
|
||||
from .. import build
|
||||
from time import time, sleep
|
||||
|
||||
def bake():
|
||||
def bake(plus_pass=0):
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
obj.select_set(False)
|
||||
|
||||
iterNum = 0
|
||||
currentIterNum = 0
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == "MESH":
|
||||
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:
|
||||
iterNum = iterNum + 1
|
||||
|
||||
if iterNum > 1:
|
||||
iterNum = iterNum - 1
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == 'MESH':
|
||||
|
||||
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:
|
||||
|
||||
scene = bpy.context.scene
|
||||
|
@ -32,19 +33,45 @@ def bake():
|
|||
obj.hide_render = False
|
||||
scene.render.bake.use_clear = False
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Baking " + str(currentIterNum) + "/" + str(iterNum) + " (" + str(round(currentIterNum/iterNum*100, 2)) + "%) : " + obj.name)
|
||||
#os.system("cls")
|
||||
|
||||
if scene.TLM_EngineProperties.tlm_lighting_mode == "combined" or scene.TLM_EngineProperties.tlm_lighting_mode == "combinedAO":
|
||||
#if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Baking " + str(currentIterNum) + "/" + str(iterNum) + " (" + str(round(currentIterNum/iterNum*100, 2)) + "%) : " + obj.name)
|
||||
#elapsed = build.sec_to_hours((time() - bpy.app.driver_namespace["tlm_start_time"]))
|
||||
#print("Baked: " + str(currentIterNum) + " | Left: " + str(iterNum-currentIterNum))
|
||||
elapsedSeconds = time() - bpy.app.driver_namespace["tlm_start_time"]
|
||||
bakedObjects = currentIterNum
|
||||
bakedLeft = iterNum-currentIterNum
|
||||
if bakedObjects == 0:
|
||||
bakedObjects = 1
|
||||
averagePrBake = elapsedSeconds / bakedObjects
|
||||
remaining = averagePrBake * bakedLeft
|
||||
#print(time() - bpy.app.driver_namespace["tlm_start_time"])
|
||||
print("Elapsed time: " + str(round(elapsedSeconds, 2)) + "s | ETA remaining: " + str(round(remaining, 2)) + "s") #str(elapsed[0])
|
||||
#print("Averaged: " + str(averagePrBake))
|
||||
#print("Remaining: " + str(remaining))
|
||||
|
||||
if scene.TLM_EngineProperties.tlm_target == "vertex":
|
||||
scene.render.bake_target = "VERTEX_COLORS"
|
||||
|
||||
if scene.TLM_EngineProperties.tlm_lighting_mode == "combined":
|
||||
bpy.ops.object.bake(type="DIFFUSE", pass_filter={"DIRECT","INDIRECT"}, margin=scene.TLM_EngineProperties.tlm_dilation_margin, use_clear=False)
|
||||
elif scene.TLM_EngineProperties.tlm_lighting_mode == "indirect" or scene.TLM_EngineProperties.tlm_lighting_mode == "indirectAO":
|
||||
elif scene.TLM_EngineProperties.tlm_lighting_mode == "indirect":
|
||||
bpy.ops.object.bake(type="DIFFUSE", pass_filter={"INDIRECT"}, margin=scene.TLM_EngineProperties.tlm_dilation_margin, use_clear=False)
|
||||
elif scene.TLM_EngineProperties.tlm_lighting_mode == "ao":
|
||||
bpy.ops.object.bake(type="AO", margin=scene.TLM_EngineProperties.tlm_dilation_margin, use_clear=False)
|
||||
elif scene.TLM_EngineProperties.tlm_lighting_mode == "combinedao":
|
||||
|
||||
if bpy.app.driver_namespace["tlm_plus_mode"] == 1:
|
||||
bpy.ops.object.bake(type="DIFFUSE", pass_filter={"DIRECT","INDIRECT"}, margin=scene.TLM_EngineProperties.tlm_dilation_margin, use_clear=False)
|
||||
elif bpy.app.driver_namespace["tlm_plus_mode"] == 2:
|
||||
bpy.ops.object.bake(type="AO", margin=scene.TLM_EngineProperties.tlm_dilation_margin, use_clear=False)
|
||||
|
||||
elif scene.TLM_EngineProperties.tlm_lighting_mode == "complete":
|
||||
bpy.ops.object.bake(type="COMBINED", margin=scene.TLM_EngineProperties.tlm_dilation_margin, use_clear=False)
|
||||
bpy.ops.object.bake(type="COMBINED", margin=scene.TLM_EngineProperties.tlm_dilation_margin, use_clear=False)
|
||||
else:
|
||||
bpy.ops.object.bake(type="DIFFUSE", pass_filter={"DIRECT","INDIRECT"}, margin=scene.TLM_EngineProperties.tlm_dilation_margin, use_clear=False)
|
||||
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
currentIterNum = currentIterNum + 1
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import bpy, os
|
||||
|
||||
def apply_lightmaps():
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == "MESH":
|
||||
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 slot in obj.material_slots:
|
||||
mat = slot.material
|
||||
|
@ -32,8 +32,12 @@ def apply_lightmaps():
|
|||
|
||||
|
||||
def apply_materials():
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == "MESH":
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Applying 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:
|
||||
|
||||
uv_layers = obj.data.uv_layers
|
||||
|
@ -90,7 +94,7 @@ def apply_materials():
|
|||
for node in nodes:
|
||||
if node.name == "Baked Image":
|
||||
lightmapNode = node
|
||||
lightmapNode.location = -800, 300
|
||||
lightmapNode.location = -1200, 300
|
||||
lightmapNode.name = "TLM_Lightmap"
|
||||
foundBakedNode = True
|
||||
|
||||
|
@ -98,9 +102,10 @@ def apply_materials():
|
|||
|
||||
if not foundBakedNode:
|
||||
lightmapNode = node_tree.nodes.new(type="ShaderNodeTexImage")
|
||||
lightmapNode.location = -300, 300
|
||||
lightmapNode.location = -1200, 300
|
||||
lightmapNode.name = "TLM_Lightmap"
|
||||
lightmapNode.interpolation = "Smart"
|
||||
lightmapNode.interpolation = bpy.context.scene.TLM_SceneProperties.tlm_texture_interpolation
|
||||
lightmapNode.extension = bpy.context.scene.TLM_SceneProperties.tlm_texture_extrapolation
|
||||
|
||||
if (obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA" and obj.TLM_ObjectProperties.tlm_atlas_pointer != ""):
|
||||
lightmapNode.image = bpy.data.images[obj.TLM_ObjectProperties.tlm_atlas_pointer + "_baked"]
|
||||
|
@ -118,37 +123,32 @@ def apply_materials():
|
|||
#Find mainnode
|
||||
mainNode = outputNode.inputs[0].links[0].from_node
|
||||
|
||||
#Clamp metallic
|
||||
|
||||
# if scene.TLM_SceneProperties.tlm_metallic_clamp != "ignore":
|
||||
# if mainNode.type == "BSDF_PRINCIPLED":
|
||||
|
||||
# if len(mainNode.inputs[4].links) == 0:
|
||||
|
||||
# if scene.TLM_SceneProperties.tlm_metallic_clamp == "zero":
|
||||
# mainNode.inputs[4].default_value = 0.0
|
||||
# else:
|
||||
# mainNode.inputs[4].default_value = 0.99
|
||||
|
||||
# else:
|
||||
|
||||
# pass
|
||||
|
||||
#Add all nodes first
|
||||
#Add lightmap multipliction texture
|
||||
mixNode = node_tree.nodes.new(type="ShaderNodeMixRGB")
|
||||
mixNode.name = "Lightmap_Multiplication"
|
||||
mixNode.location = -300, 300
|
||||
mixNode.location = -800, 300
|
||||
if scene.TLM_EngineProperties.tlm_lighting_mode == "indirect" or scene.TLM_EngineProperties.tlm_lighting_mode == "indirectAO":
|
||||
mixNode.blend_type = 'ADD'
|
||||
else:
|
||||
mixNode.blend_type = 'MULTIPLY'
|
||||
mixNode.inputs[0].default_value = 1.0
|
||||
|
||||
if scene.TLM_EngineProperties.tlm_lighting_mode == "complete":
|
||||
mixNode.inputs[0].default_value = 0.0
|
||||
else:
|
||||
mixNode.inputs[0].default_value = 1.0
|
||||
|
||||
UVLightmap = node_tree.nodes.new(type="ShaderNodeUVMap")
|
||||
UVLightmap.uv_map = "UVMap_Lightmap"
|
||||
|
||||
if not obj.TLM_ObjectProperties.tlm_use_default_channel:
|
||||
uv_channel = obj.TLM_ObjectProperties.tlm_uv_channel
|
||||
else:
|
||||
uv_channel = "UVMap_Lightmap"
|
||||
|
||||
UVLightmap.uv_map = uv_channel
|
||||
|
||||
UVLightmap.name = "Lightmap_UV"
|
||||
UVLightmap.location = -1000, 300
|
||||
UVLightmap.location = -1500, 300
|
||||
|
||||
if(scene.TLM_SceneProperties.tlm_decoder_setup):
|
||||
if scene.TLM_SceneProperties.tlm_encoding_device == "CPU":
|
||||
|
@ -196,7 +196,7 @@ def apply_materials():
|
|||
baseColorValue = mainNode.inputs[0].default_value
|
||||
baseColorNode = node_tree.nodes.new(type="ShaderNodeRGB")
|
||||
baseColorNode.outputs[0].default_value = baseColorValue
|
||||
baseColorNode.location = ((mainNode.location[0] - 500, mainNode.location[1] - 300))
|
||||
baseColorNode.location = ((mainNode.location[0] - 1100, mainNode.location[1] - 300))
|
||||
baseColorNode.name = "Lightmap_BasecolorNode_A"
|
||||
else:
|
||||
baseColorNode = mainNode.inputs[0].links[0].from_node
|
||||
|
@ -235,13 +235,19 @@ def apply_materials():
|
|||
mat.node_tree.links.new(mixNode.outputs[0], mainNode.inputs[0]) #Connect mixnode to pbr node
|
||||
mat.node_tree.links.new(UVLightmap.outputs[0], lightmapNode.inputs[0]) #Connect uvnode to lightmapnode
|
||||
|
||||
#If skip metallic
|
||||
if scene.TLM_SceneProperties.tlm_metallic_clamp == "skip":
|
||||
if mainNode.inputs[4].default_value > 0.1: #DELIMITER
|
||||
moutput = mainNode.inputs[0].links[0].from_node
|
||||
mat.node_tree.links.remove(moutput.outputs[0].links[0])
|
||||
|
||||
def exchangeLightmapsToPostfix(ext_postfix, new_postfix, formatHDR=".hdr"):
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print(ext_postfix, new_postfix, formatHDR)
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == "MESH":
|
||||
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 slot in obj.material_slots:
|
||||
mat = slot.material
|
||||
|
@ -267,6 +273,53 @@ def exchangeLightmapsToPostfix(ext_postfix, new_postfix, formatHDR=".hdr"):
|
|||
for image in bpy.data.images:
|
||||
image.reload()
|
||||
|
||||
def applyAOPass():
|
||||
|
||||
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 slot in obj.material_slots:
|
||||
mat = slot.material
|
||||
node_tree = mat.node_tree
|
||||
nodes = mat.node_tree.nodes
|
||||
|
||||
for node in nodes:
|
||||
if node.name == "Baked Image" or node.name == "TLM_Lightmap":
|
||||
|
||||
filepath = bpy.data.filepath
|
||||
dirpath = os.path.join(os.path.dirname(bpy.data.filepath), bpy.context.scene.TLM_EngineProperties.tlm_lightmap_savedir)
|
||||
|
||||
LightmapPath = node.image.filepath_raw
|
||||
|
||||
filebase = os.path.basename(LightmapPath)
|
||||
filename = os.path.splitext(filebase)[0]
|
||||
extension = os.path.splitext(filebase)[1]
|
||||
AOImagefile = filename[:-4] + "_ao"
|
||||
AOImagePath = os.path.join(dirpath, AOImagefile + extension)
|
||||
|
||||
AOMap = nodes.new('ShaderNodeTexImage')
|
||||
AOMap.name = "TLM_AOMap"
|
||||
AOImage = bpy.data.images.load(AOImagePath)
|
||||
AOMap.image = AOImage
|
||||
AOMap.location = -800, 0
|
||||
|
||||
AOMult = nodes.new(type="ShaderNodeMixRGB")
|
||||
AOMult.name = "TLM_AOMult"
|
||||
AOMult.blend_type = 'MULTIPLY'
|
||||
AOMult.inputs[0].default_value = 1.0
|
||||
AOMult.location = -300, 300
|
||||
|
||||
multyNode = nodes["Lightmap_Multiplication"]
|
||||
mainNode = nodes["Principled BSDF"]
|
||||
UVMapNode = nodes["Lightmap_UV"]
|
||||
|
||||
node_tree.links.remove(multyNode.outputs[0].links[0])
|
||||
|
||||
node_tree.links.new(multyNode.outputs[0], AOMult.inputs[1])
|
||||
node_tree.links.new(AOMap.outputs[0], AOMult.inputs[2])
|
||||
node_tree.links.new(AOMult.outputs[0], mainNode.inputs[0])
|
||||
node_tree.links.new(UVMapNode.outputs[0], AOMap.inputs[0])
|
||||
|
||||
def load_library(asset_name):
|
||||
|
||||
scriptDir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import bpy
|
||||
import bpy, math
|
||||
|
||||
from . import cache
|
||||
from .. utility import *
|
||||
|
@ -31,13 +31,16 @@ def configure_lights():
|
|||
|
||||
def configure_meshes(self):
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == "MESH":
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Configuring meshes")
|
||||
|
||||
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.data.objects:
|
||||
if obj.type == "MESH":
|
||||
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)
|
||||
|
||||
|
@ -59,9 +62,18 @@ def configure_meshes(self):
|
|||
|
||||
scene = bpy.context.scene
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == "MESH":
|
||||
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 scene.TLM_SceneProperties.tlm_apply_on_unwrap:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Applying transform to: " + 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.hide_select = False #Remember to toggle this back
|
||||
for slot in obj.material_slots:
|
||||
if "." + slot.name + '_Original' in bpy.data.materials:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
|
@ -77,33 +89,35 @@ def configure_meshes(self):
|
|||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
|
||||
uv_layers = obj.data.uv_layers
|
||||
if not "UVMap_Lightmap" in uv_layers:
|
||||
|
||||
if not obj.TLM_ObjectProperties.tlm_use_default_channel:
|
||||
uv_channel = obj.TLM_ObjectProperties.tlm_uv_channel
|
||||
else:
|
||||
uv_channel = "UVMap_Lightmap"
|
||||
|
||||
if not uv_channel in uv_layers:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("UVMap made A")
|
||||
uvmap = uv_layers.new(name="UVMap_Lightmap")
|
||||
print("UV map created for object: " + obj.name)
|
||||
uvmap = uv_layers.new(name=uv_channel)
|
||||
uv_layers.active_index = len(uv_layers) - 1
|
||||
else:
|
||||
print("Existing found...skipping")
|
||||
print("Existing UV map found for object: " + obj.name)
|
||||
for i in range(0, len(uv_layers)):
|
||||
if uv_layers[i].name == 'UVMap_Lightmap':
|
||||
uv_layers.active_index = i
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Lightmap shift A")
|
||||
break
|
||||
|
||||
atlas_items.append(obj)
|
||||
obj.select_set(True)
|
||||
|
||||
if scene.TLM_SceneProperties.tlm_apply_on_unwrap:
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
|
||||
if atlasgroup.tlm_atlas_lightmap_unwrap_mode == "SmartProject":
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Smart Project A for: " + str(atlas_items))
|
||||
print("Atlasgroup Smart Project for: " + str(atlas_items))
|
||||
for obj in atlas_items:
|
||||
print(obj.name + ": Active UV: " + obj.data.uv_layers[obj.data.uv_layers.active_index].name)
|
||||
|
||||
|
@ -112,7 +126,12 @@ def configure_meshes(self):
|
|||
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
bpy.ops.mesh.select_all(action='SELECT')
|
||||
bpy.ops.uv.smart_project(angle_limit=45.0, island_margin=atlasgroup.tlm_atlas_unwrap_margin, user_area_weight=1.0, use_aspect=True, stretch_to_bounds=False)
|
||||
#API changes in 2.91 causes errors:
|
||||
if (2, 91, 0) > bpy.app.version:
|
||||
bpy.ops.uv.smart_project(angle_limit=45.0, island_margin=obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin, user_area_weight=1.0, use_aspect=True, stretch_to_bounds=False)
|
||||
else:
|
||||
angle = math.radians(45.0)
|
||||
bpy.ops.uv.smart_project(angle_limit=angle, island_margin=obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin, area_weight=1.0, correct_aspect=True, scale_to_bounds=False)
|
||||
bpy.ops.mesh.select_all(action='DESELECT')
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
elif atlasgroup.tlm_atlas_lightmap_unwrap_mode == "Lightmap":
|
||||
|
@ -123,8 +142,9 @@ def configure_meshes(self):
|
|||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
elif atlasgroup.tlm_atlas_lightmap_unwrap_mode == "Xatlas":
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Temporary skip: COPYING SMART PROJECT")
|
||||
print("Using Xatlas on Atlas Group: " + atlas)
|
||||
|
||||
for obj in atlas_items:
|
||||
obj.select_set(True)
|
||||
|
@ -139,176 +159,213 @@ def configure_meshes(self):
|
|||
|
||||
else:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Copied Existing A")
|
||||
print("Copied Existing UV Map for Atlas Group: " + atlas)
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == "MESH":
|
||||
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:
|
||||
iterNum = iterNum + 1
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type == "MESH":
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.name in bpy.context.view_layer.objects: #Possible fix for view layer error
|
||||
if obj.type == 'MESH' and obj.name in bpy.context.view_layer.objects:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
|
||||
objWasHidden = False
|
||||
objWasHidden = False
|
||||
|
||||
#For some reason, a Blender bug might prevent invisible objects from being smart projected
|
||||
#We will turn the object temporarily visible
|
||||
obj.hide_viewport = False
|
||||
obj.hide_set(False)
|
||||
#For some reason, a Blender bug might prevent invisible objects from being smart projected
|
||||
#We will turn the object temporarily visible
|
||||
obj.hide_viewport = False
|
||||
obj.hide_set(False)
|
||||
|
||||
currentIterNum = currentIterNum + 1
|
||||
currentIterNum = currentIterNum + 1
|
||||
|
||||
#Configure selection
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
obj.select_set(True)
|
||||
obs = bpy.context.view_layer.objects
|
||||
active = obs.active
|
||||
#Configure selection
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
obj.select_set(True)
|
||||
|
||||
#Provide material if none exists
|
||||
preprocess_material(obj, scene)
|
||||
obs = bpy.context.view_layer.objects
|
||||
active = obs.active
|
||||
|
||||
#UV Layer management here
|
||||
if not obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
uv_layers = obj.data.uv_layers
|
||||
if not "UVMap_Lightmap" in uv_layers:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("UVMap made B")
|
||||
uvmap = uv_layers.new(name="UVMap_Lightmap")
|
||||
uv_layers.active_index = len(uv_layers) - 1
|
||||
#Provide material if none exists
|
||||
preprocess_material(obj, scene)
|
||||
|
||||
#If lightmap
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "Lightmap":
|
||||
if scene.TLM_SceneProperties.tlm_apply_on_unwrap:
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
bpy.ops.uv.lightmap_pack('EXEC_SCREEN', PREF_CONTEXT='ALL_FACES', PREF_MARGIN_DIV=obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin)
|
||||
|
||||
#If smart project
|
||||
elif obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "SmartProject":
|
||||
#UV Layer management here
|
||||
if not obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
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"
|
||||
|
||||
if not uv_channel in uv_layers:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Smart Project B")
|
||||
if scene.TLM_SceneProperties.tlm_apply_on_unwrap:
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
obj.select_set(True)
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
bpy.ops.mesh.select_all(action='DESELECT')
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
bpy.ops.uv.smart_project(angle_limit=45.0, island_margin=obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin, user_area_weight=1.0, use_aspect=True, stretch_to_bounds=False)
|
||||
|
||||
elif obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "Xatlas":
|
||||
print("UV map created for obj: " + obj.name)
|
||||
uvmap = uv_layers.new(name=uv_channel)
|
||||
uv_layers.active_index = len(uv_layers) - 1
|
||||
|
||||
if scene.TLM_SceneProperties.tlm_apply_on_unwrap:
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
#If lightmap
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "Lightmap":
|
||||
bpy.ops.uv.lightmap_pack('EXEC_SCREEN', PREF_CONTEXT='ALL_FACES', PREF_MARGIN_DIV=obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin)
|
||||
|
||||
#import blender_xatlas
|
||||
#blender_xatlas.Unwrap_Lightmap_Group_Xatlas_2(bpy.context)
|
||||
#If smart project
|
||||
elif obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "SmartProject":
|
||||
|
||||
#bpy.ops.object.setup_unwrap()
|
||||
Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj)
|
||||
|
||||
elif obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("ATLAS GROUP: " + obj.TLM_ObjectProperties.tlm_atlas_pointer)
|
||||
|
||||
else: #if copy existing
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Copied Existing B")
|
||||
|
||||
else:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Existing found...skipping")
|
||||
for i in range(0, len(uv_layers)):
|
||||
if uv_layers[i].name == 'UVMap_Lightmap':
|
||||
uv_layers.active_index = i
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Lightmap shift B")
|
||||
break
|
||||
print("Smart Project B")
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
obj.select_set(True)
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
bpy.ops.mesh.select_all(action='SELECT')
|
||||
#API changes in 2.91 causes errors:
|
||||
if (2, 91, 0) > bpy.app.version:
|
||||
bpy.ops.uv.smart_project(angle_limit=45.0, island_margin=obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin, user_area_weight=1.0, use_aspect=True, stretch_to_bounds=False)
|
||||
else:
|
||||
angle = math.radians(45.0)
|
||||
bpy.ops.uv.smart_project(angle_limit=angle, island_margin=obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin, area_weight=1.0, correct_aspect=True, scale_to_bounds=False)
|
||||
bpy.ops.mesh.select_all(action='DESELECT')
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
elif obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "Xatlas":
|
||||
|
||||
Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj)
|
||||
|
||||
#Sort out nodes
|
||||
for slot in obj.material_slots:
|
||||
elif obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
|
||||
nodetree = slot.material.node_tree
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("ATLAS GROUP: " + obj.TLM_ObjectProperties.tlm_atlas_pointer)
|
||||
|
||||
else: #if copy existing
|
||||
|
||||
outputNode = nodetree.nodes[0] #Presumed to be material output node
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Copied Existing UV Map for object: " + obj.name)
|
||||
|
||||
if(outputNode.type != "OUTPUT_MATERIAL"):
|
||||
else:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Existing UV map found for obj: " + obj.name)
|
||||
for i in range(0, len(uv_layers)):
|
||||
if uv_layers[i].name == uv_channel:
|
||||
uv_layers.active_index = i
|
||||
break
|
||||
|
||||
#print(x)
|
||||
|
||||
#Sort out nodes
|
||||
for slot in obj.material_slots:
|
||||
|
||||
nodetree = slot.material.node_tree
|
||||
|
||||
outputNode = nodetree.nodes[0] #Presumed to be material output node
|
||||
|
||||
if(outputNode.type != "OUTPUT_MATERIAL"):
|
||||
for node in nodetree.nodes:
|
||||
if node.type == "OUTPUT_MATERIAL":
|
||||
outputNode = node
|
||||
break
|
||||
|
||||
mainNode = outputNode.inputs[0].links[0].from_node
|
||||
|
||||
if mainNode.type not in ['BSDF_PRINCIPLED','BSDF_DIFFUSE','GROUP']:
|
||||
|
||||
#TODO! FIND THE PRINCIPLED PBR
|
||||
self.report({'INFO'}, "The primary material node is not supported. Seeking first principled.")
|
||||
|
||||
if len(find_node_by_type(nodetree.nodes, Node_Types.pbr_node)) > 0:
|
||||
mainNode = find_node_by_type(nodetree.nodes, Node_Types.pbr_node)[0]
|
||||
else:
|
||||
self.report({'INFO'}, "No principled found. Seeking diffuse")
|
||||
if len(find_node_by_type(nodetree.nodes, Node_Types.diffuse)) > 0:
|
||||
mainNode = find_node_by_type(nodetree.nodes, Node_Types.diffuse)[0]
|
||||
else:
|
||||
self.report({'INFO'}, "No supported nodes. Continuing anyway.")
|
||||
|
||||
if mainNode.type == 'GROUP':
|
||||
if mainNode.node_tree != "Armory PBR":
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("The material group is not supported!")
|
||||
|
||||
if (mainNode.type == "BSDF_PRINCIPLED"):
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("BSDF_Principled")
|
||||
if scene.TLM_EngineProperties.tlm_directional_mode == "None":
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Directional mode")
|
||||
if not len(mainNode.inputs[19].links) == 0:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("NOT LEN 0")
|
||||
ninput = mainNode.inputs[19].links[0]
|
||||
noutput = mainNode.inputs[19].links[0].from_node
|
||||
nodetree.links.remove(noutput.outputs[0].links[0])
|
||||
|
||||
#Clamp metallic
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_metallic_clamp == "limit":
|
||||
MainMetNodeSocket = mainNode.inputs[4]
|
||||
if not len(MainMetNodeSocket.links) == 0:
|
||||
nodes = nodetree.nodes
|
||||
MetClampNode = nodes.new('ShaderNodeClamp')
|
||||
MetClampNode.location = (-200,150)
|
||||
MetClampNode.inputs[2].default_value = 0.9
|
||||
minput = mainNode.inputs[4].links[0] #Metal input socket
|
||||
moutput = mainNode.inputs[4].links[0].from_node #Metal output node
|
||||
nodetree.links.remove(moutput.outputs[0].links[0]) #Works
|
||||
nodetree.links.new(moutput.outputs[0], MetClampNode.inputs[0]) #minput node to clamp node
|
||||
nodetree.links.new(MetClampNode.outputs[0],MainMetNodeSocket) #clamp node to metinput
|
||||
else:
|
||||
if mainNode.inputs[4].default_value > 0.9:
|
||||
mainNode.inputs[4].default_value = 0.9
|
||||
elif bpy.context.scene.TLM_SceneProperties.tlm_metallic_clamp == "zero":
|
||||
MainMetNodeSocket = mainNode.inputs[4]
|
||||
if not len(MainMetNodeSocket.links) == 0:
|
||||
nodes = nodetree.nodes
|
||||
MetClampNode = nodes.new('ShaderNodeClamp')
|
||||
MetClampNode.location = (-200,150)
|
||||
MetClampNode.inputs[2].default_value = 0.0
|
||||
minput = mainNode.inputs[4].links[0] #Metal input socket
|
||||
moutput = mainNode.inputs[4].links[0].from_node #Metal output node
|
||||
nodetree.links.remove(moutput.outputs[0].links[0]) #Works
|
||||
nodetree.links.new(moutput.outputs[0], MetClampNode.inputs[0]) #minput node to clamp node
|
||||
nodetree.links.new(MetClampNode.outputs[0],MainMetNodeSocket) #clamp node to metinput
|
||||
else:
|
||||
mainNode.inputs[4].default_value = 0.0
|
||||
|
||||
if (mainNode.type == "BSDF_DIFFUSE"):
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("BSDF_Diffuse")
|
||||
|
||||
# if (mainNode.type == "BSDF_DIFFUSE"):
|
||||
# if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
# print("BSDF_Diffuse")
|
||||
|
||||
#TODO FIX THIS PART!
|
||||
#THIS IS USED IN CASES WHERE FOR SOME REASON THE USER FORGETS TO CONNECT SOMETHING INTO THE OUTPUT MATERIAL
|
||||
for slot in obj.material_slots:
|
||||
|
||||
nodetree = bpy.data.materials[slot.name].node_tree
|
||||
nodes = nodetree.nodes
|
||||
|
||||
#First search to get the first output material type
|
||||
for node in nodetree.nodes:
|
||||
if node.type == "OUTPUT_MATERIAL":
|
||||
outputNode = node
|
||||
mainNode = node
|
||||
break
|
||||
|
||||
mainNode = outputNode.inputs[0].links[0].from_node
|
||||
#Fallback to get search
|
||||
if not mainNode.type == "OUTPUT_MATERIAL":
|
||||
mainNode = nodetree.nodes.get("Material Output")
|
||||
|
||||
if mainNode.type not in ['BSDF_PRINCIPLED','BSDF_DIFFUSE','GROUP']:
|
||||
#Last resort to first node in list
|
||||
if not mainNode.type == "OUTPUT_MATERIAL":
|
||||
mainNode = nodetree.nodes[0].inputs[0].links[0].from_node
|
||||
|
||||
#TODO! FIND THE PRINCIPLED PBR
|
||||
self.report({'INFO'}, "The primary material node is not supported. Seeking first principled.")
|
||||
# for node in nodes:
|
||||
# if "LM" in node.name:
|
||||
# nodetree.links.new(node.outputs[0], mainNode.inputs[0])
|
||||
|
||||
if len(find_node_by_type(nodetree.nodes, Node_Types.pbr_node)) > 0:
|
||||
mainNode = find_node_by_type(nodetree.nodes, Node_Types.pbr_node)[0]
|
||||
else:
|
||||
self.report({'INFO'}, "No principled found. Seeking diffuse")
|
||||
if len(find_node_by_type(nodetree.nodes, Node_Types.diffuse)) > 0:
|
||||
mainNode = find_node_by_type(nodetree.nodes, Node_Types.diffuse)[0]
|
||||
else:
|
||||
self.report({'INFO'}, "No supported nodes. Continuing anyway.")
|
||||
|
||||
if mainNode.type == 'GROUP':
|
||||
if mainNode.node_tree != "Armory PBR":
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("The material group is not supported!")
|
||||
|
||||
if (mainNode.type == "BSDF_PRINCIPLED"):
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("BSDF_Principled")
|
||||
if scene.TLM_EngineProperties.tlm_directional_mode == "None":
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Directional mode")
|
||||
if not len(mainNode.inputs[19].links) == 0:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("NOT LEN 0")
|
||||
ninput = mainNode.inputs[19].links[0]
|
||||
noutput = mainNode.inputs[19].links[0].from_node
|
||||
nodetree.links.remove(noutput.outputs[0].links[0])
|
||||
|
||||
#Clamp metallic
|
||||
if(mainNode.inputs[4].default_value == 1):
|
||||
mainNode.inputs[4].default_value = 0.0
|
||||
|
||||
if (mainNode.type == "BSDF_DIFFUSE"):
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("BSDF_Diffuse")
|
||||
|
||||
for slot in obj.material_slots:
|
||||
|
||||
nodetree = bpy.data.materials[slot.name].node_tree
|
||||
nodes = nodetree.nodes
|
||||
|
||||
#First search to get the first output material type
|
||||
for node in nodetree.nodes:
|
||||
if node.type == "OUTPUT_MATERIAL":
|
||||
mainNode = node
|
||||
break
|
||||
|
||||
#Fallback to get search
|
||||
if not mainNode.type == "OUTPUT_MATERIAL":
|
||||
mainNode = nodetree.nodes.get("Material Output")
|
||||
|
||||
#Last resort to first node in list
|
||||
if not mainNode.type == "OUTPUT_MATERIAL":
|
||||
mainNode = nodetree.nodes[0].inputs[0].links[0].from_node
|
||||
|
||||
for node in nodes:
|
||||
if "LM" in node.name:
|
||||
nodetree.links.new(node.outputs[0], mainNode.inputs[0])
|
||||
|
||||
for node in nodes:
|
||||
if "Lightmap" in node.name:
|
||||
nodes.remove(node)
|
||||
# for node in nodes:
|
||||
# if "Lightmap" in node.name:
|
||||
# nodes.remove(node)
|
||||
|
||||
def preprocess_material(obj, scene):
|
||||
if len(obj.material_slots) == 0:
|
||||
|
@ -537,7 +594,7 @@ def store_existing(prev_container):
|
|||
|
||||
selected = []
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.select_get():
|
||||
selected.append(obj.name)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class TLM_Integrated_Denoise:
|
|||
bpy.ops.object.camera_add()
|
||||
|
||||
#Just select the first camera we find, needed for the compositor
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.type == "CAMERA":
|
||||
bpy.context.scene.camera = obj
|
||||
return
|
||||
|
|
|
@ -332,6 +332,205 @@ def encodeImageRGBDGPU(image, maxRange, outDir, quality):
|
|||
#Todo - Find a way to save
|
||||
#bpy.ops.image.save_all_modified()
|
||||
|
||||
#TODO - FINISH THIS
|
||||
def encodeImageRGBMGPU(image, maxRange, outDir, quality):
|
||||
input_image = bpy.data.images[image.name]
|
||||
image_name = input_image.name
|
||||
|
||||
offscreen = gpu.types.GPUOffScreen(input_image.size[0], input_image.size[1])
|
||||
|
||||
image = input_image
|
||||
|
||||
vertex_shader = '''
|
||||
|
||||
uniform mat4 ModelViewProjectionMatrix;
|
||||
|
||||
in vec2 texCoord;
|
||||
in vec2 pos;
|
||||
out vec2 texCoord_interp;
|
||||
|
||||
void main()
|
||||
{
|
||||
//gl_Position = ModelViewProjectionMatrix * vec4(pos.xy, 0.0f, 1.0f);
|
||||
//gl_Position.z = 1.0;
|
||||
gl_Position = vec4(pos.xy, 100, 100);
|
||||
texCoord_interp = texCoord;
|
||||
}
|
||||
|
||||
'''
|
||||
fragment_shader = '''
|
||||
in vec2 texCoord_interp;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D image;
|
||||
|
||||
//Code from here: https://github.com/BabylonJS/Babylon.js/blob/master/src/Shaders/ShadersInclude/helperFunctions.fx
|
||||
|
||||
const float PI = 3.1415926535897932384626433832795;
|
||||
const float HALF_MIN = 5.96046448e-08; // Smallest positive half.
|
||||
|
||||
const float LinearEncodePowerApprox = 2.2;
|
||||
const float GammaEncodePowerApprox = 1.0 / LinearEncodePowerApprox;
|
||||
const vec3 LuminanceEncodeApprox = vec3(0.2126, 0.7152, 0.0722);
|
||||
|
||||
const float Epsilon = 0.0000001;
|
||||
#define saturate(x) clamp(x, 0.0, 1.0)
|
||||
|
||||
float maxEps(float x) {
|
||||
return max(x, Epsilon);
|
||||
}
|
||||
|
||||
float toLinearSpace(float color)
|
||||
{
|
||||
return pow(color, LinearEncodePowerApprox);
|
||||
}
|
||||
|
||||
vec3 toLinearSpace(vec3 color)
|
||||
{
|
||||
return pow(color, vec3(LinearEncodePowerApprox));
|
||||
}
|
||||
|
||||
vec4 toLinearSpace(vec4 color)
|
||||
{
|
||||
return vec4(pow(color.rgb, vec3(LinearEncodePowerApprox)), color.a);
|
||||
}
|
||||
|
||||
vec3 toGammaSpace(vec3 color)
|
||||
{
|
||||
return pow(color, vec3(GammaEncodePowerApprox));
|
||||
}
|
||||
|
||||
vec4 toGammaSpace(vec4 color)
|
||||
{
|
||||
return vec4(pow(color.rgb, vec3(GammaEncodePowerApprox)), color.a);
|
||||
}
|
||||
|
||||
float toGammaSpace(float color)
|
||||
{
|
||||
return pow(color, GammaEncodePowerApprox);
|
||||
}
|
||||
|
||||
float square(float value)
|
||||
{
|
||||
return value * value;
|
||||
}
|
||||
|
||||
// Check if configurable value is needed.
|
||||
const float rgbdMaxRange = 255.0;
|
||||
|
||||
vec4 toRGBM(vec3 color) {
|
||||
|
||||
vec4 rgbm;
|
||||
color *= 1.0/6.0;
|
||||
rgbm.a = saturate( max( max( color.r, color.g ), max( color.b, 1e-6 ) ) );
|
||||
rgbm.a = clamp(floor(D) / 255.0, 0., 1.);
|
||||
rgbm.rgb = color / rgbm.a;
|
||||
|
||||
return
|
||||
|
||||
float maxRGB = maxEps(max(color.r, max(color.g, color.b)));
|
||||
float D = max(rgbdMaxRange / maxRGB, 1.);
|
||||
D = clamp(floor(D) / 255.0, 0., 1.);
|
||||
vec3 rgb = color.rgb * D;
|
||||
|
||||
// Helps with png quantization.
|
||||
rgb = toGammaSpace(rgb);
|
||||
|
||||
return vec4(rgb, D);
|
||||
}
|
||||
|
||||
vec3 fromRGBD(vec4 rgbd) {
|
||||
// Helps with png quantization.
|
||||
rgbd.rgb = toLinearSpace(rgbd.rgb);
|
||||
|
||||
// return rgbd.rgb * ((rgbdMaxRange / 255.0) / rgbd.a);
|
||||
|
||||
return rgbd.rgb / rgbd.a;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
fragColor = toRGBM(texture(image, texCoord_interp).rgb);
|
||||
|
||||
}
|
||||
|
||||
'''
|
||||
|
||||
x_screen = 0
|
||||
off_x = -100
|
||||
off_y = -100
|
||||
y_screen_flip = 0
|
||||
sx = 200
|
||||
sy = 200
|
||||
|
||||
vertices = (
|
||||
(x_screen + off_x, y_screen_flip - off_y),
|
||||
(x_screen + off_x, y_screen_flip - sy - off_y),
|
||||
(x_screen + off_x + sx, y_screen_flip - sy - off_y),
|
||||
(x_screen + off_x + sx, y_screen_flip - off_x))
|
||||
|
||||
if input_image.colorspace_settings.name != 'Linear':
|
||||
input_image.colorspace_settings.name = 'Linear'
|
||||
|
||||
# Removing .exr or .hdr prefix
|
||||
if image_name[-4:] == '.exr' or image_name[-4:] == '.hdr':
|
||||
image_name = image_name[:-4]
|
||||
|
||||
target_image = bpy.data.images.get(image_name + '_encoded')
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print(image_name + '_encoded')
|
||||
if not target_image:
|
||||
target_image = bpy.data.images.new(
|
||||
name = image_name + '_encoded',
|
||||
width = input_image.size[0],
|
||||
height = input_image.size[1],
|
||||
alpha = True,
|
||||
float_buffer = False
|
||||
)
|
||||
|
||||
shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
|
||||
batch = batch_for_shader(
|
||||
shader, 'TRI_FAN',
|
||||
{
|
||||
"pos": vertices,
|
||||
"texCoord": ((0, 1), (0, 0), (1, 0), (1, 1)),
|
||||
},
|
||||
)
|
||||
|
||||
if image.gl_load():
|
||||
raise Exception()
|
||||
|
||||
with offscreen.bind():
|
||||
bgl.glActiveTexture(bgl.GL_TEXTURE0)
|
||||
bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode)
|
||||
|
||||
shader.bind()
|
||||
shader.uniform_int("image", 0)
|
||||
batch.draw(shader)
|
||||
|
||||
buffer = bgl.Buffer(bgl.GL_BYTE, input_image.size[0] * input_image.size[1] * 4)
|
||||
bgl.glReadBuffer(bgl.GL_BACK)
|
||||
bgl.glReadPixels(0, 0, input_image.size[0], input_image.size[1], bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer)
|
||||
|
||||
offscreen.free()
|
||||
|
||||
target_image.pixels = [v / 255 for v in buffer]
|
||||
input_image = target_image
|
||||
|
||||
#Save LogLuv
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print(input_image.name)
|
||||
input_image.filepath_raw = outDir + "/" + input_image.name + ".png"
|
||||
#input_image.filepath_raw = outDir + "_encoded.png"
|
||||
input_image.file_format = "PNG"
|
||||
bpy.context.scene.render.image_settings.quality = quality
|
||||
#input_image.save_render(filepath = input_image.filepath_raw, scene = bpy.context.scene)
|
||||
input_image.save()
|
||||
|
||||
#Todo - Find a way to save
|
||||
#bpy.ops.image.save_all_modified()
|
||||
|
||||
def encodeImageRGBMCPU(image, maxRange, outDir, quality):
|
||||
input_image = bpy.data.images[image.name]
|
||||
image_name = input_image.name
|
||||
|
@ -431,21 +630,6 @@ def encodeImageRGBDCPU(image, maxRange, outDir, quality):
|
|||
result_pixel[i+1] = math.pow(result_pixel[i+1] * D, 1/2.2)
|
||||
result_pixel[i+2] = math.pow(result_pixel[i+2] * D, 1/2.2)
|
||||
result_pixel[i+3] = D
|
||||
|
||||
|
||||
# for i in range(0,num_pixels,4):
|
||||
|
||||
# m = saturate(max(result_pixel[i], result_pixel[i+1], result_pixel[i+2], 1e-6))
|
||||
# d = max(maxRange / m, 1)
|
||||
# #d = saturate(math.floor(d) / 255.0)
|
||||
# d = np.clip((math.floor(d) / 255.0), 0.0, 1.0)
|
||||
|
||||
# #TODO TO GAMMA SPACE
|
||||
|
||||
# result_pixel[i] = math.pow(result_pixel[i] * d * 255 / maxRange, 1/2.2)
|
||||
# result_pixel[i+1] = math.pow(result_pixel[i+1] * d * 255 / maxRange, 1/2.2)
|
||||
# result_pixel[i+2] = math.pow(result_pixel[i+2] * d * 255 / maxRange, 1/2.2)
|
||||
# result_pixel[i+3] = d
|
||||
|
||||
target_image.pixels = result_pixel
|
||||
|
||||
|
@ -457,25 +641,4 @@ def encodeImageRGBDCPU(image, maxRange, outDir, quality):
|
|||
input_image.filepath_raw = outDir + "/" + input_image.name + ".png"
|
||||
input_image.file_format = "PNG"
|
||||
bpy.context.scene.render.image_settings.quality = quality
|
||||
input_image.save()
|
||||
|
||||
# const float rgbdMaxRange = 255.0;
|
||||
|
||||
# vec4 toRGBD(vec3 color) {
|
||||
# float maxRGB = maxEps(max(color.r, max(color.g, color.b)));
|
||||
# float D = max(rgbdMaxRange / maxRGB, 1.);
|
||||
# D = clamp(floor(D) / 255.0, 0., 1.);
|
||||
# vec3 rgb = color.rgb * D;
|
||||
|
||||
# // Helps with png quantization.
|
||||
# rgb = toGammaSpace(rgb);
|
||||
|
||||
# return vec4(rgb, D);
|
||||
# }
|
||||
|
||||
# const float Epsilon = 0.0000001;
|
||||
# #define saturate(x) clamp(x, 0.0, 1.0)
|
||||
|
||||
# float maxEps(float x) {
|
||||
# return max(x, Epsilon);
|
||||
# }
|
||||
input_image.save()
|
|
@ -62,7 +62,7 @@ class TLM_CV_Filtering:
|
|||
|
||||
#SEAM TESTING# #####################
|
||||
|
||||
if obj_name in bpy.data.objects:
|
||||
if obj_name in bpy.context.scene.objects:
|
||||
override = bpy.data.objects[obj_name].TLM_ObjectProperties.tlm_mesh_filter_override
|
||||
elif obj_name in scene.TLM_AtlasList:
|
||||
override = False
|
||||
|
|
67
blender/arm/lightmapper/utility/gui/Viewport.py
Normal file
67
blender/arm/lightmapper/utility/gui/Viewport.py
Normal file
|
@ -0,0 +1,67 @@
|
|||
import bpy, blf, bgl, os, gpu
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
|
||||
class ViewportDraw:
|
||||
|
||||
def __init__(self, context, text):
|
||||
|
||||
bakefile = "TLM_Overlay.png"
|
||||
scriptDir = os.path.dirname(os.path.realpath(__file__))
|
||||
bakefile_path = os.path.abspath(os.path.join(scriptDir, '..', '..', 'assets/' + bakefile))
|
||||
|
||||
image_name = "TLM_Overlay.png"
|
||||
|
||||
bpy.ops.image.open(filepath=bakefile_path)
|
||||
|
||||
print("Self path: " + bakefile_path)
|
||||
|
||||
image = bpy.data.images[image_name]
|
||||
|
||||
x = 15
|
||||
y = 15
|
||||
w = 400
|
||||
h = 200
|
||||
|
||||
self.shader = gpu.shader.from_builtin('2D_IMAGE')
|
||||
self.batch = batch_for_shader(
|
||||
self.shader, 'TRI_FAN',
|
||||
{
|
||||
"pos": ((x, y), (x+w, y), (x+w, y+h), (x, y+h)),
|
||||
"texCoord": ((0, 0), (1, 0), (1, 1), (0, 1)),
|
||||
},
|
||||
)
|
||||
|
||||
if image.gl_load():
|
||||
raise Exception()
|
||||
|
||||
self.text = text
|
||||
self.image = image
|
||||
#self.handle = bpy.types.SpaceView3D.draw_handler_add(self.draw_text_callback, (context,), 'WINDOW', 'POST_PIXEL')
|
||||
self.handle2 = bpy.types.SpaceView3D.draw_handler_add(self.draw_image_callback, (context,), 'WINDOW', 'POST_PIXEL')
|
||||
|
||||
def draw_text_callback(self, context):
|
||||
|
||||
font_id = 0
|
||||
blf.position(font_id, 15, 15, 0)
|
||||
blf.size(font_id, 20, 72)
|
||||
blf.draw(font_id, "%s" % (self.text))
|
||||
|
||||
def draw_image_callback(self, context):
|
||||
|
||||
if self.image:
|
||||
bgl.glEnable(bgl.GL_BLEND)
|
||||
bgl.glActiveTexture(bgl.GL_TEXTURE0)
|
||||
bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.image.bindcode)
|
||||
|
||||
self.shader.bind()
|
||||
self.shader.uniform_int("image", 0)
|
||||
self.batch.draw(self.shader)
|
||||
bgl.glDisable(bgl.GL_BLEND)
|
||||
|
||||
def update_text(self, text):
|
||||
|
||||
self.text = text
|
||||
|
||||
def remove_handle(self):
|
||||
#bpy.types.SpaceView3D.draw_handler_remove(self.handle, 'WINDOW')
|
||||
bpy.types.SpaceView3D.draw_handler_remove(self.handle2, 'WINDOW')
|
259
blender/arm/lightmapper/utility/luxcore/setup.py
Normal file
259
blender/arm/lightmapper/utility/luxcore/setup.py
Normal file
|
@ -0,0 +1,259 @@
|
|||
import bpy
|
||||
|
||||
from .. utility import *
|
||||
|
||||
def init(self, prev_container):
|
||||
|
||||
#TODO - JSON classes
|
||||
export.scene = """scene.camera.cliphither = 0.1
|
||||
scene.camera.clipyon = 100
|
||||
scene.camera.shutteropen = 0
|
||||
scene.camera.shutterclose = 1
|
||||
scene.camera.autovolume.enable = 1
|
||||
scene.camera.lookat.orig = 7.358891 -6.925791 4.958309
|
||||
scene.camera.lookat.target = 6.707333 -6.31162 4.513038
|
||||
scene.camera.up = -0.3240135 0.3054208 0.8953956
|
||||
scene.camera.screenwindow = -1 1 -0.5625 0.5625
|
||||
scene.camera.lensradius = 0
|
||||
scene.camera.focaldistance = 10
|
||||
scene.camera.autofocus.enable = 0
|
||||
scene.camera.type = "perspective"
|
||||
scene.camera.oculusrift.barrelpostpro.enable = 0
|
||||
scene.camera.fieldofview = 39.59776
|
||||
scene.camera.bokeh.blades = 0
|
||||
scene.camera.bokeh.power = 3
|
||||
scene.camera.bokeh.distribution.type = "NONE"
|
||||
scene.camera.bokeh.scale.x = 0.7071068
|
||||
scene.camera.bokeh.scale.y = 0.7071068
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.gain = 2e-05 2e-05 2e-05
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.transformation = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.id = 0
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.temperature = -1
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.temperature.normalize = 0
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.visibility.indirect.diffuse.enable = 1
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.visibility.indirect.glossy.enable = 1
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.visibility.indirect.specular.enable = 1
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.type = "sky2"
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.dir = 0 0 1
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.turbidity = 2.2
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.groundalbedo = 0.5 0.5 0.5
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.ground.enable = 0
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.ground.color = 0.5 0.5 0.5
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.ground.autoscale = 1
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.distribution.width = 512
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.distribution.height = 256
|
||||
scene.lights.__WORLD_BACKGROUND_LIGHT__.visibilitymapcache.enable = 0
|
||||
scene.lights.2382361116072.gain = 1 1 1
|
||||
scene.lights.2382361116072.transformation = -0.2908646 0.9551712 -0.05518906 0 -0.7711008 -0.1998834 0.6045247 0 0.5663932 0.2183912 0.7946723 0 4.076245 1.005454 5.903862 1
|
||||
scene.lights.2382361116072.id = 0
|
||||
scene.lights.2382361116072.temperature = -1
|
||||
scene.lights.2382361116072.temperature.normalize = 0
|
||||
scene.lights.2382361116072.type = "sphere"
|
||||
scene.lights.2382361116072.color = 1 1 1
|
||||
scene.lights.2382361116072.power = 0
|
||||
scene.lights.2382361116072.normalizebycolor = 0
|
||||
scene.lights.2382361116072.efficency = 0
|
||||
scene.lights.2382361116072.position = 0 0 0
|
||||
scene.lights.2382361116072.radius = 0.1
|
||||
scene.materials.Material2382357175256.type = "disney"
|
||||
scene.materials.Material2382357175256.basecolor = "0.7 0.7 0.7"
|
||||
scene.materials.Material2382357175256.subsurface = "0"
|
||||
scene.materials.Material2382357175256.roughness = "0.2"
|
||||
scene.materials.Material2382357175256.metallic = "0"
|
||||
scene.materials.Material2382357175256.specular = "0.5"
|
||||
scene.materials.Material2382357175256.speculartint = "0"
|
||||
scene.materials.Material2382357175256.clearcoat = "0"
|
||||
scene.materials.Material2382357175256.clearcoatgloss = "1"
|
||||
scene.materials.Material2382357175256.anisotropic = "0"
|
||||
scene.materials.Material2382357175256.sheen = "0"
|
||||
scene.materials.Material2382357175256.sheentint = "0"
|
||||
scene.materials.Material2382357175256.transparency.shadow = 0 0 0
|
||||
scene.materials.Material2382357175256.id = 3364224
|
||||
scene.materials.Material2382357175256.emission.gain = 1 1 1
|
||||
scene.materials.Material2382357175256.emission.power = 0
|
||||
scene.materials.Material2382357175256.emission.normalizebycolor = 1
|
||||
scene.materials.Material2382357175256.emission.efficency = 0
|
||||
scene.materials.Material2382357175256.emission.theta = 90
|
||||
scene.materials.Material2382357175256.emission.id = 0
|
||||
scene.materials.Material2382357175256.emission.importance = 1
|
||||
scene.materials.Material2382357175256.emission.temperature = -1
|
||||
scene.materials.Material2382357175256.emission.temperature.normalize = 0
|
||||
scene.materials.Material2382357175256.emission.directlightsampling.type = "AUTO"
|
||||
scene.materials.Material2382357175256.visibility.indirect.diffuse.enable = 1
|
||||
scene.materials.Material2382357175256.visibility.indirect.glossy.enable = 1
|
||||
scene.materials.Material2382357175256.visibility.indirect.specular.enable = 1
|
||||
scene.materials.Material2382357175256.shadowcatcher.enable = 0
|
||||
scene.materials.Material2382357175256.shadowcatcher.onlyinfinitelights = 0
|
||||
scene.materials.Material2382357175256.photongi.enable = 1
|
||||
scene.materials.Material2382357175256.holdout.enable = 0
|
||||
scene.materials.Material__0012382357172440.type = "disney"
|
||||
scene.materials.Material__0012382357172440.basecolor = "0.7 0.7 0.7"
|
||||
scene.materials.Material__0012382357172440.subsurface = "0"
|
||||
scene.materials.Material__0012382357172440.roughness = "0.2"
|
||||
scene.materials.Material__0012382357172440.metallic = "0"
|
||||
scene.materials.Material__0012382357172440.specular = "0.5"
|
||||
scene.materials.Material__0012382357172440.speculartint = "0"
|
||||
scene.materials.Material__0012382357172440.clearcoat = "0"
|
||||
scene.materials.Material__0012382357172440.clearcoatgloss = "1"
|
||||
scene.materials.Material__0012382357172440.anisotropic = "0"
|
||||
scene.materials.Material__0012382357172440.sheen = "0"
|
||||
scene.materials.Material__0012382357172440.sheentint = "0"
|
||||
scene.materials.Material__0012382357172440.transparency.shadow = 0 0 0
|
||||
scene.materials.Material__0012382357172440.id = 6728256
|
||||
scene.materials.Material__0012382357172440.emission.gain = 1 1 1
|
||||
scene.materials.Material__0012382357172440.emission.power = 0
|
||||
scene.materials.Material__0012382357172440.emission.normalizebycolor = 1
|
||||
scene.materials.Material__0012382357172440.emission.efficency = 0
|
||||
scene.materials.Material__0012382357172440.emission.theta = 90
|
||||
scene.materials.Material__0012382357172440.emission.id = 0
|
||||
scene.materials.Material__0012382357172440.emission.importance = 1
|
||||
scene.materials.Material__0012382357172440.emission.temperature = -1
|
||||
scene.materials.Material__0012382357172440.emission.temperature.normalize = 0
|
||||
scene.materials.Material__0012382357172440.emission.directlightsampling.type = "AUTO"
|
||||
scene.materials.Material__0012382357172440.visibility.indirect.diffuse.enable = 1
|
||||
scene.materials.Material__0012382357172440.visibility.indirect.glossy.enable = 1
|
||||
scene.materials.Material__0012382357172440.visibility.indirect.specular.enable = 1
|
||||
scene.materials.Material__0012382357172440.shadowcatcher.enable = 0
|
||||
scene.materials.Material__0012382357172440.shadowcatcher.onlyinfinitelights = 0
|
||||
scene.materials.Material__0012382357172440.photongi.enable = 1
|
||||
scene.materials.Material__0012382357172440.holdout.enable = 0
|
||||
scene.objects.23823611086320.material = "Material2382357175256"
|
||||
scene.objects.23823611086320.ply = "mesh-00000.ply"
|
||||
scene.objects.23823611086320.camerainvisible = 0
|
||||
scene.objects.23823611086320.id = 1326487202
|
||||
scene.objects.23823611086320.appliedtransformation = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 1
|
||||
scene.objects.23823611279760.material = "Material__0012382357172440"
|
||||
scene.objects.23823611279760.ply = "mesh-00001.ply"
|
||||
scene.objects.23823611279760.camerainvisible = 0
|
||||
scene.objects.23823611279760.id = 3772660237
|
||||
scene.objects.23823611279760.appliedtransformation = 5 0 0 0 0 5 0 0 0 0 5 0 0 0 0 1
|
||||
"""
|
||||
|
||||
export.config = """context.verbose = 1
|
||||
accelerator.type = "AUTO"
|
||||
accelerator.instances.enable = 1
|
||||
accelerator.motionblur.enable = 1
|
||||
accelerator.bvh.builder.type = "EMBREE_BINNED_SAH"
|
||||
accelerator.bvh.treetype = 4
|
||||
accelerator.bvh.costsamples = 0
|
||||
accelerator.bvh.isectcost = 80
|
||||
accelerator.bvh.travcost = 10
|
||||
accelerator.bvh.emptybonus = 0.5
|
||||
scene.epsilon.min = "1e-05"
|
||||
scene.epsilon.max = "0.1"
|
||||
scene.file = "scene.scn"
|
||||
images.scale = 1
|
||||
lightstrategy.type = "LOG_POWER"
|
||||
native.threads.count = 8
|
||||
renderengine.type = "BAKECPU"
|
||||
path.pathdepth.total = "7"
|
||||
path.pathdepth.diffuse = "5"
|
||||
path.pathdepth.glossy = "5"
|
||||
path.pathdepth.specular = "6"
|
||||
path.hybridbackforward.enable = "0"
|
||||
path.hybridbackforward.partition = "0.8"
|
||||
path.hybridbackforward.glossinessthreshold = "0.049"
|
||||
path.russianroulette.depth = 3
|
||||
path.russianroulette.cap = 0.5
|
||||
path.clamping.variance.maxvalue = 0
|
||||
path.forceblackbackground.enable = "0"
|
||||
sampler.type = "SOBOL"
|
||||
sampler.imagesamples.enable = 1
|
||||
sampler.sobol.adaptive.strength = "0.9"
|
||||
sampler.sobol.adaptive.userimportanceweight = 0.75
|
||||
sampler.sobol.bucketsize = "16"
|
||||
sampler.sobol.tilesize = "16"
|
||||
sampler.sobol.supersampling = "1"
|
||||
sampler.sobol.overlapping = "1"
|
||||
path.photongi.sampler.type = "METROPOLIS"
|
||||
path.photongi.photon.maxcount = 100000000
|
||||
path.photongi.photon.maxdepth = 4
|
||||
path.photongi.photon.time.start = 0
|
||||
path.photongi.photon.time.end = -1
|
||||
path.photongi.visibility.lookup.radius = 0
|
||||
path.photongi.visibility.lookup.normalangle = 10
|
||||
path.photongi.visibility.targethitrate = 0.99
|
||||
path.photongi.visibility.maxsamplecount = 1048576
|
||||
path.photongi.glossinessusagethreshold = 0.05
|
||||
path.photongi.indirect.enabled = 0
|
||||
path.photongi.indirect.maxsize = 0
|
||||
path.photongi.indirect.haltthreshold = 0.05
|
||||
path.photongi.indirect.lookup.radius = 0
|
||||
path.photongi.indirect.lookup.normalangle = 10
|
||||
path.photongi.indirect.usagethresholdscale = 8
|
||||
path.photongi.indirect.filter.radiusscale = 3
|
||||
path.photongi.caustic.enabled = 0
|
||||
path.photongi.caustic.maxsize = 100000
|
||||
path.photongi.caustic.updatespp = 8
|
||||
path.photongi.caustic.updatespp.radiusreduction = 0.96
|
||||
path.photongi.caustic.updatespp.minradius = 0.003
|
||||
path.photongi.caustic.lookup.radius = 0.15
|
||||
path.photongi.caustic.lookup.normalangle = 10
|
||||
path.photongi.debug.type = "none"
|
||||
path.photongi.persistent.file = ""
|
||||
path.photongi.persistent.safesave = 1
|
||||
film.filter.type = "BLACKMANHARRIS"
|
||||
film.filter.width = 2
|
||||
opencl.platform.index = -1
|
||||
film.width = 960
|
||||
film.height = 600
|
||||
film.safesave = 1
|
||||
film.noiseestimation.step = "32"
|
||||
film.noiseestimation.warmup = "8"
|
||||
film.noiseestimation.filter.scale = 4
|
||||
batch.haltnoisethreshold = 0.01
|
||||
batch.haltnoisethreshold.step = 64
|
||||
batch.haltnoisethreshold.warmup = 64
|
||||
batch.haltnoisethreshold.filter.enable = 1
|
||||
batch.haltnoisethreshold.stoprendering.enable = 1
|
||||
batch.halttime = "0"
|
||||
batch.haltspp = 32
|
||||
film.outputs.safesave = 1
|
||||
film.outputs.0.type = "RGB_IMAGEPIPELINE"
|
||||
film.outputs.0.filename = "RGB_IMAGEPIPELINE_0.png"
|
||||
film.outputs.0.index = "0"
|
||||
film.imagepipelines.000.0.type = "NOP"
|
||||
film.imagepipelines.000.1.type = "TONEMAP_LINEAR"
|
||||
film.imagepipelines.000.1.scale = "1"
|
||||
film.imagepipelines.000.2.type = "GAMMA_CORRECTION"
|
||||
film.imagepipelines.000.2.value = "2.2"
|
||||
film.imagepipelines.000.radiancescales.0.enabled = "1"
|
||||
film.imagepipelines.000.radiancescales.0.globalscale = "1"
|
||||
film.imagepipelines.000.radiancescales.0.rgbscale = "1" "1" "1"
|
||||
periodicsave.film.outputs.period = 0
|
||||
periodicsave.film.period = 0
|
||||
periodicsave.film.filename = "film.flm"
|
||||
periodicsave.resumerendering.period = 0
|
||||
periodicsave.resumerendering.filename = "rendering.rsm"
|
||||
resumerendering.filesafe = 1
|
||||
debug.renderconfig.parse.print = 0
|
||||
debug.scene.parse.print = 0
|
||||
screen.refresh.interval = 100
|
||||
screen.tool.type = "CAMERA_EDIT"
|
||||
screen.tiles.pending.show = 1
|
||||
screen.tiles.converged.show = 0
|
||||
screen.tiles.notconverged.show = 0
|
||||
screen.tiles.passcount.show = 0
|
||||
screen.tiles.error.show = 0
|
||||
bake.minmapautosize = 64
|
||||
bake.maxmapautosize = 1024
|
||||
bake.powerof2autosize.enable = 1
|
||||
bake.skipexistingmapfiles = 1
|
||||
film.imagepipelines.1.0.type = "NOP"
|
||||
bake.maps.0.type = "COMBINED"
|
||||
bake.maps.0.filename = "23823611086320.exr"
|
||||
bake.maps.0.imagepipelineindex = 1
|
||||
bake.maps.0.width = 512
|
||||
bake.maps.0.height = 512
|
||||
bake.maps.0.autosize.enabled = 1
|
||||
bake.maps.0.uvindex = 0
|
||||
bake.maps.0.objectnames = "23823611086320"
|
||||
bake.maps.1.type = "COMBINED"
|
||||
bake.maps.1.filename = "23823611279760.exr"
|
||||
bake.maps.1.imagepipelineindex = 1
|
||||
bake.maps.1.width = 512
|
||||
bake.maps.1.height = 512
|
||||
bake.maps.1.autosize.enabled = 1
|
||||
bake.maps.1.uvindex = 0
|
||||
bake.maps.1.objectnames = "23823611279760"
|
||||
"""
|
243
blender/arm/lightmapper/utility/octane/configure.py
Normal file
243
blender/arm/lightmapper/utility/octane/configure.py
Normal file
|
@ -0,0 +1,243 @@
|
|||
import bpy, math
|
||||
|
||||
#from . import cache
|
||||
from .. utility import *
|
||||
|
||||
def init(self, prev_container):
|
||||
|
||||
#store_existing(prev_container)
|
||||
|
||||
#set_settings()
|
||||
|
||||
configure_world()
|
||||
|
||||
configure_lights()
|
||||
|
||||
configure_meshes(self)
|
||||
|
||||
def configure_world():
|
||||
pass
|
||||
|
||||
def configure_lights():
|
||||
pass
|
||||
|
||||
def configure_meshes(self):
|
||||
|
||||
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)
|
||||
|
||||
iterNum = 1
|
||||
currentIterNum = 0
|
||||
|
||||
scene = bpy.context.scene
|
||||
|
||||
for obj in scene.objects:
|
||||
if obj.type == "MESH":
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
obj.hide_select = False #Remember to toggle this back
|
||||
|
||||
currentIterNum = currentIterNum + 1
|
||||
|
||||
obj.octane.baking_group_id = 1 + currentIterNum #0 doesn't exist, 1 is neutral and 2 is first baked object
|
||||
|
||||
print("Obj: " + obj.name + " set to baking group: " + str(obj.octane.baking_group_id))
|
||||
|
||||
for slot in obj.material_slots:
|
||||
if "." + slot.name + '_Original' in bpy.data.materials:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("The material: " + slot.name + " shifted to " + "." + slot.name + '_Original')
|
||||
slot.material = bpy.data.materials["." + slot.name + '_Original']
|
||||
|
||||
|
||||
objWasHidden = False
|
||||
|
||||
#For some reason, a Blender bug might prevent invisible objects from being smart projected
|
||||
#We will turn the object temporarily visible
|
||||
obj.hide_viewport = False
|
||||
obj.hide_set(False)
|
||||
|
||||
#Configure selection
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
obj.select_set(True)
|
||||
obs = bpy.context.view_layer.objects
|
||||
active = obs.active
|
||||
|
||||
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"
|
||||
|
||||
if not uv_channel in uv_layers:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("UV map created for obj: " + obj.name)
|
||||
uvmap = uv_layers.new(name=uv_channel)
|
||||
uv_layers.active_index = len(uv_layers) - 1
|
||||
print("Setting active UV to: " + uv_layers.active_index)
|
||||
|
||||
#If lightmap
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "Lightmap":
|
||||
bpy.ops.uv.lightmap_pack('EXEC_SCREEN', PREF_CONTEXT='ALL_FACES', PREF_MARGIN_DIV=obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin)
|
||||
|
||||
#If smart project
|
||||
elif obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "SmartProject":
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Smart Project B")
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
obj.select_set(True)
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
bpy.ops.mesh.select_all(action='SELECT')
|
||||
#API changes in 2.91 causes errors:
|
||||
if (2, 91, 0) > bpy.app.version:
|
||||
bpy.ops.uv.smart_project(angle_limit=45.0, island_margin=obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin, user_area_weight=1.0, use_aspect=True, stretch_to_bounds=False)
|
||||
else:
|
||||
angle = math.radians(45.0)
|
||||
bpy.ops.uv.smart_project(angle_limit=angle, island_margin=obj.TLM_ObjectProperties.tlm_mesh_unwrap_margin, area_weight=1.0, correct_aspect=True, scale_to_bounds=False)
|
||||
bpy.ops.mesh.select_all(action='DESELECT')
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
elif obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "Xatlas":
|
||||
|
||||
Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj)
|
||||
|
||||
elif obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("ATLAS GROUP: " + obj.TLM_ObjectProperties.tlm_atlas_pointer)
|
||||
|
||||
else: #if copy existing
|
||||
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Copied Existing UV Map for object: " + obj.name)
|
||||
|
||||
else:
|
||||
if bpy.context.scene.TLM_SceneProperties.tlm_verbose:
|
||||
print("Existing UV map found for obj: " + obj.name)
|
||||
for i in range(0, len(uv_layers)):
|
||||
if uv_layers[i].name == uv_channel:
|
||||
uv_layers.active_index = i
|
||||
break
|
||||
|
||||
set_camera()
|
||||
|
||||
def set_camera():
|
||||
|
||||
cam_name = "TLM-BakeCam"
|
||||
|
||||
if not cam_name in bpy.context.scene:
|
||||
camera = bpy.data.cameras.new(cam_name)
|
||||
camobj_name = "TLM-BakeCam-obj"
|
||||
cam_obj = bpy.data.objects.new(camobj_name, camera)
|
||||
bpy.context.collection.objects.link(cam_obj)
|
||||
cam_obj.location = ((0,0,0))
|
||||
|
||||
bpy.context.scene.camera = cam_obj
|
||||
|
||||
def set_settings():
|
||||
|
||||
scene = bpy.context.scene
|
||||
cycles = scene.cycles
|
||||
scene.render.engine = "CYCLES"
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
engineProperties = scene.TLM_EngineProperties
|
||||
cycles.device = scene.TLM_EngineProperties.tlm_mode
|
||||
|
||||
if cycles.device == "GPU":
|
||||
scene.render.tile_x = 256
|
||||
scene.render.tile_y = 256
|
||||
else:
|
||||
scene.render.tile_x = 32
|
||||
scene.render.tile_y = 32
|
||||
|
||||
if engineProperties.tlm_quality == "0":
|
||||
cycles.samples = 32
|
||||
cycles.max_bounces = 1
|
||||
cycles.diffuse_bounces = 1
|
||||
cycles.glossy_bounces = 1
|
||||
cycles.transparent_max_bounces = 1
|
||||
cycles.transmission_bounces = 1
|
||||
cycles.volume_bounces = 1
|
||||
cycles.caustics_reflective = False
|
||||
cycles.caustics_refractive = False
|
||||
elif engineProperties.tlm_quality == "1":
|
||||
cycles.samples = 64
|
||||
cycles.max_bounces = 2
|
||||
cycles.diffuse_bounces = 2
|
||||
cycles.glossy_bounces = 2
|
||||
cycles.transparent_max_bounces = 2
|
||||
cycles.transmission_bounces = 2
|
||||
cycles.volume_bounces = 2
|
||||
cycles.caustics_reflective = False
|
||||
cycles.caustics_refractive = False
|
||||
elif engineProperties.tlm_quality == "2":
|
||||
cycles.samples = 512
|
||||
cycles.max_bounces = 2
|
||||
cycles.diffuse_bounces = 2
|
||||
cycles.glossy_bounces = 2
|
||||
cycles.transparent_max_bounces = 2
|
||||
cycles.transmission_bounces = 2
|
||||
cycles.volume_bounces = 2
|
||||
cycles.caustics_reflective = False
|
||||
cycles.caustics_refractive = False
|
||||
elif engineProperties.tlm_quality == "3":
|
||||
cycles.samples = 1024
|
||||
cycles.max_bounces = 256
|
||||
cycles.diffuse_bounces = 256
|
||||
cycles.glossy_bounces = 256
|
||||
cycles.transparent_max_bounces = 256
|
||||
cycles.transmission_bounces = 256
|
||||
cycles.volume_bounces = 256
|
||||
cycles.caustics_reflective = False
|
||||
cycles.caustics_refractive = False
|
||||
elif engineProperties.tlm_quality == "4":
|
||||
cycles.samples = 2048
|
||||
cycles.max_bounces = 512
|
||||
cycles.diffuse_bounces = 512
|
||||
cycles.glossy_bounces = 512
|
||||
cycles.transparent_max_bounces = 512
|
||||
cycles.transmission_bounces = 512
|
||||
cycles.volume_bounces = 512
|
||||
cycles.caustics_reflective = True
|
||||
cycles.caustics_refractive = True
|
||||
else: #Custom
|
||||
pass
|
||||
|
||||
def store_existing(prev_container):
|
||||
|
||||
scene = bpy.context.scene
|
||||
cycles = scene.cycles
|
||||
|
||||
selected = []
|
||||
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.select_get():
|
||||
selected.append(obj.name)
|
||||
|
||||
prev_container["settings"] = [
|
||||
cycles.samples,
|
||||
cycles.max_bounces,
|
||||
cycles.diffuse_bounces,
|
||||
cycles.glossy_bounces,
|
||||
cycles.transparent_max_bounces,
|
||||
cycles.transmission_bounces,
|
||||
cycles.volume_bounces,
|
||||
cycles.caustics_reflective,
|
||||
cycles.caustics_refractive,
|
||||
cycles.device,
|
||||
scene.render.engine,
|
||||
bpy.context.view_layer.objects.active,
|
||||
selected,
|
||||
[scene.render.resolution_x, scene.render.resolution_y]
|
||||
]
|
71
blender/arm/lightmapper/utility/octane/lightmap2.py
Normal file
71
blender/arm/lightmapper/utility/octane/lightmap2.py
Normal file
|
@ -0,0 +1,71 @@
|
|||
import bpy, os
|
||||
|
||||
def bake():
|
||||
|
||||
cam_name = "TLM-BakeCam-obj"
|
||||
|
||||
if cam_name in bpy.context.scene.objects:
|
||||
|
||||
print("Camera found...")
|
||||
|
||||
camera = bpy.context.scene.objects[cam_name]
|
||||
|
||||
camera.data.octane.baking_camera = True
|
||||
|
||||
for obj in bpy.context.scene.objects:
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
obj.select_set(False)
|
||||
|
||||
iterNum = 2
|
||||
currentIterNum = 1
|
||||
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.type == "MESH":
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
iterNum = iterNum + 1
|
||||
|
||||
if iterNum > 1:
|
||||
iterNum = iterNum - 1
|
||||
|
||||
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:
|
||||
|
||||
currentIterNum = currentIterNum + 1
|
||||
|
||||
scene = bpy.context.scene
|
||||
|
||||
print("Baking obj: " + obj.name)
|
||||
|
||||
print("Baking ID: " + str(currentIterNum) + " out of " + str(iterNum))
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
camera.data.octane.baking_group_id = currentIterNum
|
||||
|
||||
savedir = os.path.dirname(bpy.data.filepath)
|
||||
user_dir = scene.TLM_Engine3Properties.tlm_lightmap_savedir
|
||||
directory = os.path.join(savedir, user_dir)
|
||||
|
||||
image_settings = bpy.context.scene.render.image_settings
|
||||
image_settings.file_format = "HDR"
|
||||
image_settings.color_depth = '32'
|
||||
|
||||
filename = os.path.join(directory, "LM") + "_" + obj.name + ".hdr"
|
||||
bpy.context.scene.render.filepath = filename
|
||||
|
||||
resolution = int(obj.TLM_ObjectProperties.tlm_mesh_lightmap_resolution)
|
||||
|
||||
bpy.context.scene.render.resolution_x = resolution
|
||||
bpy.context.scene.render.resolution_y = resolution
|
||||
|
||||
bpy.ops.render.render(write_still=True)
|
||||
|
||||
else:
|
||||
|
||||
print("No baking camera found")
|
||||
|
||||
|
||||
|
||||
|
||||
print("Baking in Octane!")
|
|
@ -106,7 +106,7 @@ def postpack():
|
|||
rect = []
|
||||
|
||||
#For each object that targets the atlas
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
if obj.TLM_ObjectProperties.tlm_postpack_object:
|
||||
if obj.TLM_ObjectProperties.tlm_postatlas_pointer == atlas.name:
|
||||
|
@ -156,7 +156,13 @@ def postpack():
|
|||
obj = bpy.data.objects[aob]
|
||||
|
||||
for idx, layer in enumerate(obj.data.uv_layers):
|
||||
if layer.name == "UVMap_Lightmap":
|
||||
|
||||
if not obj.TLM_ObjectProperties.tlm_use_default_channel:
|
||||
uv_channel = obj.TLM_ObjectProperties.tlm_uv_channel
|
||||
else:
|
||||
uv_channel = "UVMap_Lightmap"
|
||||
|
||||
if layer.name == uv_channel:
|
||||
obj.data.uv_layers.active_index = idx
|
||||
|
||||
print("UVLayer set to: " + str(obj.data.uv_layers.active_index))
|
||||
|
@ -194,7 +200,7 @@ def postpack():
|
|||
print("Written: " + str(os.path.join(lightmap_directory, atlas.name + end + formatEnc)))
|
||||
|
||||
#Change the material for each material, slot
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
if obj.TLM_ObjectProperties.tlm_postpack_object:
|
||||
if obj.TLM_ObjectProperties.tlm_postatlas_pointer == atlas.name:
|
||||
|
@ -219,7 +225,7 @@ def postpack():
|
|||
existing_image.user_clear()
|
||||
|
||||
#Add dilation map here...
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
if obj.TLM_ObjectProperties.tlm_postpack_object:
|
||||
if obj.TLM_ObjectProperties.tlm_postatlas_pointer == atlas.name:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import bpy.ops as O
|
||||
import bpy, os, re, sys, importlib, struct, platform, subprocess, threading, string, bmesh
|
||||
import bpy, os, re, sys, importlib, struct, platform, subprocess, threading, string, bmesh, shutil, glob, uuid
|
||||
from io import StringIO
|
||||
from threading import Thread
|
||||
from queue import Queue, Empty
|
||||
|
@ -81,15 +81,8 @@ def save_image(image):
|
|||
|
||||
image.filepath_raw = savepath
|
||||
|
||||
# if "Normal" in image.name:
|
||||
# bpy.context.scene.render.image_settings.quality = 90
|
||||
# image.save_render( filepath = image.filepath_raw, scene = bpy.context.scene )
|
||||
# else:
|
||||
image.save()
|
||||
|
||||
|
||||
|
||||
|
||||
def get_file_size(filepath):
|
||||
size = "Unpack Files"
|
||||
try:
|
||||
|
@ -141,7 +134,7 @@ def check_is_org_material(self,material):
|
|||
|
||||
|
||||
def clean_empty_materials(self):
|
||||
for obj in bpy.data.objects:
|
||||
for obj in bpy.context.scene.objects:
|
||||
for slot in obj.material_slots:
|
||||
mat = slot.material
|
||||
if mat is None:
|
||||
|
@ -319,6 +312,11 @@ def lightmap_to_ao(material,lightmap_node):
|
|||
# https://github.com/mattedicksoncom/blender-xatlas/
|
||||
###########################################################
|
||||
|
||||
def gen_safe_name():
|
||||
genId = uuid.uuid4().hex
|
||||
# genId = "u_" + genId.replace("-","_")
|
||||
return "u_" + genId
|
||||
|
||||
def Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj):
|
||||
|
||||
blender_xatlas = importlib.util.find_spec("blender_xatlas")
|
||||
|
@ -330,32 +328,54 @@ def Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj):
|
|||
|
||||
packOptions = bpy.context.scene.pack_tool
|
||||
chartOptions = bpy.context.scene.chart_tool
|
||||
|
||||
sharedProperties = bpy.context.scene.shared_properties
|
||||
#sharedProperties.unwrapSelection
|
||||
|
||||
context = bpy.context
|
||||
|
||||
if obj.type == 'MESH':
|
||||
context.view_layer.objects.active = obj
|
||||
if obj.data.users > 1:
|
||||
obj.data = obj.data.copy() #make single user copy
|
||||
uv_layers = obj.data.uv_layers
|
||||
|
||||
#setup the lightmap uvs
|
||||
uvName = "UVMap_Lightmap"
|
||||
if sharedProperties.lightmapUVChoiceType == "NAME":
|
||||
uvName = sharedProperties.lightmapUVName
|
||||
elif sharedProperties.lightmapUVChoiceType == "INDEX":
|
||||
if sharedProperties.lightmapUVIndex < len(uv_layers):
|
||||
uvName = uv_layers[sharedProperties.lightmapUVIndex].name
|
||||
#save whatever mode the user was in
|
||||
startingMode = bpy.context.object.mode
|
||||
selected_objects = bpy.context.selected_objects
|
||||
|
||||
if not uvName in uv_layers:
|
||||
uvmap = uv_layers.new(name=uvName)
|
||||
uv_layers.active_index = len(uv_layers) - 1
|
||||
else:
|
||||
for i in range(0, len(uv_layers)):
|
||||
if uv_layers[i].name == uvName:
|
||||
uv_layers.active_index = i
|
||||
obj.select_set(True)
|
||||
#check something is actually selected
|
||||
#external function/operator will select them
|
||||
if len(selected_objects) == 0:
|
||||
print("Nothing Selected")
|
||||
self.report({"WARNING"}, "Nothing Selected, please select Something")
|
||||
return {'FINISHED'}
|
||||
|
||||
#store the names of objects to be lightmapped
|
||||
rename_dict = dict()
|
||||
safe_dict = dict()
|
||||
|
||||
#make sure all the objects have ligthmap uvs
|
||||
for obj in selected_objects:
|
||||
if obj.type == 'MESH':
|
||||
safe_name = gen_safe_name();
|
||||
rename_dict[obj.name] = (obj.name,safe_name)
|
||||
safe_dict[safe_name] = obj.name
|
||||
context.view_layer.objects.active = obj
|
||||
if obj.data.users > 1:
|
||||
obj.data = obj.data.copy() #make single user copy
|
||||
uv_layers = obj.data.uv_layers
|
||||
|
||||
#setup the lightmap uvs
|
||||
uvName = "UVMap_Lightmap"
|
||||
if sharedProperties.lightmapUVChoiceType == "NAME":
|
||||
uvName = sharedProperties.lightmapUVName
|
||||
elif sharedProperties.lightmapUVChoiceType == "INDEX":
|
||||
if sharedProperties.lightmapUVIndex < len(uv_layers):
|
||||
uvName = uv_layers[sharedProperties.lightmapUVIndex].name
|
||||
|
||||
if not uvName in uv_layers:
|
||||
uvmap = uv_layers.new(name=uvName)
|
||||
uv_layers.active_index = len(uv_layers) - 1
|
||||
else:
|
||||
for i in range(0, len(uv_layers)):
|
||||
if uv_layers[i].name == uvName:
|
||||
uv_layers.active_index = i
|
||||
obj.select_set(True)
|
||||
|
||||
#save all the current edges
|
||||
if sharedProperties.packOnly:
|
||||
|
@ -381,8 +401,11 @@ def Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj):
|
|||
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
#Create a fake obj export to a string
|
||||
#Will strip this down further later
|
||||
fakeFile = StringIO()
|
||||
blender_xatlas.export_obj_simple.save(
|
||||
rename_dict=rename_dict,
|
||||
context=bpy.context,
|
||||
filepath=fakeFile,
|
||||
mainUVChoiceType=sharedProperties.mainUVChoiceType,
|
||||
|
@ -393,20 +416,26 @@ def Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj):
|
|||
use_mesh_modifiers=True,
|
||||
use_edges=True,
|
||||
use_smooth_groups=False,
|
||||
use_smooth_groups_bitflags=False,
|
||||
use_smooth_groups_bitflags=False,
|
||||
use_normals=True,
|
||||
use_uvs=True,
|
||||
use_materials=False,
|
||||
use_triangles=False,
|
||||
use_nurbs=False,
|
||||
use_vertex_groups=False,
|
||||
use_nurbs=False,
|
||||
use_vertex_groups=False,
|
||||
use_blen_objects=True,
|
||||
group_by_object=False,
|
||||
group_by_material=False,
|
||||
keep_vertex_order=False,
|
||||
)
|
||||
|
||||
file_path = os.path.dirname(os.path.abspath(blender_xatlas.__file__))
|
||||
#print just for reference
|
||||
# print(fakeFile.getvalue())
|
||||
|
||||
#get the path to xatlas
|
||||
#file_path = os.path.dirname(os.path.abspath(__file__))
|
||||
scriptsDir = bpy.utils.user_resource('SCRIPTS', "addons")
|
||||
file_path = os.path.join(scriptsDir, "blender_xatlas")
|
||||
if platform.system() == "Windows":
|
||||
xatlas_path = os.path.join(file_path, "xatlas", "xatlas-blender.exe")
|
||||
elif platform.system() == "Linux":
|
||||
|
@ -458,6 +487,8 @@ def Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj):
|
|||
shell=True
|
||||
)
|
||||
|
||||
print(xatlas_path)
|
||||
|
||||
#shove the fake file in stdin
|
||||
stdin = xatlas_process.stdin
|
||||
value = bytes(fakeFile.getvalue() + "\n", 'UTF-8') #The \n is needed to end the input properly
|
||||
|
@ -482,17 +513,17 @@ def Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj):
|
|||
obName: string = ""
|
||||
uvArray: List[float] = field(default_factory=list)
|
||||
faceArray: List[int] = field(default_factory=list)
|
||||
|
||||
|
||||
convertedObjects = []
|
||||
uvArrayComplete = []
|
||||
|
||||
|
||||
|
||||
#search through the out put for STARTOBJ
|
||||
#then start reading the objects
|
||||
obTest = None
|
||||
startRead = False
|
||||
for line in outObj.splitlines():
|
||||
|
||||
|
||||
line_split = line.split()
|
||||
|
||||
if not line_split:
|
||||
|
@ -504,14 +535,14 @@ def Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj):
|
|||
print("Start reading the objects----------------------------------------")
|
||||
startRead = True
|
||||
# obTest = uvObject()
|
||||
|
||||
|
||||
if startRead:
|
||||
#if it's a new obj
|
||||
if line_start == 'o':
|
||||
#if there is already an object append it
|
||||
if obTest is not None:
|
||||
convertedObjects.append(obTest)
|
||||
|
||||
|
||||
obTest = uvObject() #create new uv object
|
||||
obTest.obName = line_split[1]
|
||||
|
||||
|
@ -536,9 +567,9 @@ def Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj):
|
|||
|
||||
#append the final object
|
||||
convertedObjects.append(obTest)
|
||||
# print(convertedObjects)
|
||||
|
||||
|
||||
print(convertedObjects)
|
||||
|
||||
|
||||
#apply the output-------------------------------------------------------------
|
||||
#copy the uvs to the original objects
|
||||
# objIndex = 0
|
||||
|
@ -548,7 +579,7 @@ def Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj):
|
|||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
obTest = importObject
|
||||
|
||||
obTest.obName = safe_dict[obTest.obName] #probably shouldn't just replace it
|
||||
bpy.context.scene.objects[obTest.obName].select_set(True)
|
||||
context.view_layer.objects.active = bpy.context.scene.objects[obTest.obName]
|
||||
bpy.ops.object.mode_set(mode = 'OBJECT')
|
||||
|
@ -563,7 +594,7 @@ def Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj):
|
|||
|
||||
nFaces = len(bm.faces)
|
||||
#need to ensure lookup table for some reason?
|
||||
if hasattr(bm.faces, "ensure_lookup_table"):
|
||||
if hasattr(bm.faces, "ensure_lookup_table"):
|
||||
bm.faces.ensure_lookup_table()
|
||||
|
||||
#loop through the faces
|
||||
|
@ -601,7 +632,7 @@ def Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj):
|
|||
currentObject = bpy.context.scene.objects[edgeList['object']]
|
||||
bm = bmesh.new()
|
||||
bm.from_mesh(currentObject.data)
|
||||
if hasattr(bm.edges, "ensure_lookup_table"):
|
||||
if hasattr(bm.edges, "ensure_lookup_table"):
|
||||
bm.edges.ensure_lookup_table()
|
||||
|
||||
#assume that all the triangulated edges come after the original edges
|
||||
|
@ -617,6 +648,27 @@ def Unwrap_Lightmap_Group_Xatlas_2_headless_call(obj):
|
|||
bm.free()
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
|
||||
#End setting the quads back again------------------------------------------------------------
|
||||
#End setting the quads back again-------------------------------------------------------------
|
||||
|
||||
print("Finished Xatlas----------------------------------------")
|
||||
#select the original objects that were selected
|
||||
for objectName in rename_dict:
|
||||
if objectName[0] in bpy.context.scene.objects:
|
||||
current_object = bpy.context.scene.objects[objectName[0]]
|
||||
current_object.select_set(True)
|
||||
context.view_layer.objects.active = current_object
|
||||
|
||||
bpy.ops.object.mode_set(mode=startingMode)
|
||||
|
||||
print("Finished Xatlas----------------------------------------")
|
||||
return {'FINISHED'}
|
||||
|
||||
def transfer_assets(copy, source, destination):
|
||||
for filename in glob.glob(os.path.join(source, '*.*')):
|
||||
shutil.copy(filename, destination)
|
||||
|
||||
def transfer_load():
|
||||
load_folder = bpy.path.abspath(os.path.join(os.path.dirname(bpy.data.filepath), bpy.context.scene.TLM_SceneProperties.tlm_load_folder))
|
||||
lightmap_folder = os.path.join(os.path.dirname(bpy.data.filepath), bpy.context.scene.TLM_EngineProperties.tlm_lightmap_savedir)
|
||||
print(load_folder)
|
||||
print(lightmap_folder)
|
||||
transfer_assets(True, load_folder, lightmap_folder)
|
|
@ -3,7 +3,7 @@ import arm.assets
|
|||
import bpy
|
||||
from bpy.types import Menu, Panel, UIList
|
||||
from bpy.props import *
|
||||
from arm.lightmapper import operators, properties, utility, keymap
|
||||
from arm.lightmapper import operators, properties, utility
|
||||
|
||||
class ArmBakeListItem(bpy.types.PropertyGroup):
|
||||
obj: PointerProperty(type=bpy.types.Object, description="The object to bake")
|
||||
|
@ -361,7 +361,6 @@ def register():
|
|||
|
||||
operators.register()
|
||||
properties.register()
|
||||
keymap.register()
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(ArmBakeListItem)
|
||||
|
@ -380,5 +379,4 @@ def unregister():
|
|||
#Unregister lightmapper
|
||||
|
||||
operators.unregister()
|
||||
properties.unregister()
|
||||
keymap.unregister()
|
||||
properties.unregister()
|
|
@ -20,6 +20,7 @@ import arm.utils
|
|||
|
||||
from arm.lightmapper.utility import icon
|
||||
from arm.lightmapper.properties.denoiser import oidn, optix
|
||||
from arm.lightmapper.panels import scene
|
||||
import importlib
|
||||
|
||||
|
||||
|
@ -73,9 +74,18 @@ class ARM_PT_ObjectPropsPanel(bpy.types.Panel):
|
|||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
|
||||
row = layout.row()
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_lightmap_resolution")
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_use_default_channel")
|
||||
|
||||
if not obj.TLM_ObjectProperties.tlm_use_default_channel:
|
||||
|
||||
row = layout.row()
|
||||
row.prop_search(obj.TLM_ObjectProperties, "tlm_uv_channel", obj.data, "uv_layers", text='UV Channel')
|
||||
|
||||
row = layout.row()
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_lightmap_unwrap_mode")
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_lightmap_resolution")
|
||||
if obj.TLM_ObjectProperties.tlm_use_default_channel:
|
||||
row = layout.row()
|
||||
row.prop(obj.TLM_ObjectProperties, "tlm_mesh_lightmap_unwrap_mode")
|
||||
row = layout.row()
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
|
||||
|
@ -93,7 +103,6 @@ class ARM_PT_ObjectPropsPanel(bpy.types.Panel):
|
|||
row.prop(obj.TLM_ObjectProperties, "tlm_postpack_object")
|
||||
row = layout.row()
|
||||
|
||||
|
||||
if obj.TLM_ObjectProperties.tlm_postpack_object and obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode != "AtlasGroupA":
|
||||
if scene.TLM_PostAtlasListItem >= 0 and len(scene.TLM_PostAtlasList) > 0:
|
||||
row = layout.row()
|
||||
|
@ -1482,423 +1491,6 @@ class ARM_PT_BakePanel(bpy.types.Panel):
|
|||
layout.prop(item, "res_x")
|
||||
layout.prop(item, "res_y")
|
||||
|
||||
else:
|
||||
|
||||
scene = context.scene
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
row = layout.row(align=True)
|
||||
|
||||
row = layout.row(align=True)
|
||||
|
||||
#We list LuxCoreRender as available, by default we assume Cycles exists
|
||||
row.prop(sceneProperties, "tlm_lightmap_engine")
|
||||
|
||||
if sceneProperties.tlm_lightmap_engine == "Cycles":
|
||||
|
||||
#CYCLES SETTINGS HERE
|
||||
engineProperties = scene.TLM_EngineProperties
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="General Settings")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.build_lightmaps")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.clean_lightmaps")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.explore_lightmaps")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_apply_on_unwrap")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_headless")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_alert_on_finish")
|
||||
|
||||
if sceneProperties.tlm_alert_on_finish:
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_alert_sound")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_verbose")
|
||||
#row = layout.row(align=True)
|
||||
#row.prop(sceneProperties, "tlm_compile_statistics")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_override_bg_color")
|
||||
if sceneProperties.tlm_override_bg_color:
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_override_color")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_reset_uv")
|
||||
|
||||
row = layout.row(align=True)
|
||||
try:
|
||||
if bpy.context.scene["TLM_Buildstat"] is not None:
|
||||
row.label(text="Last build completed in: " + str(bpy.context.scene["TLM_Buildstat"][0]))
|
||||
except:
|
||||
pass
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Cycles Settings")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_mode")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_quality")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_resolution_scale")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_bake_mode")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_lighting_mode")
|
||||
|
||||
if scene.TLM_EngineProperties.tlm_bake_mode == "Background":
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Warning! Background mode is currently unstable", icon_value=2)
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_network_render")
|
||||
if sceneProperties.tlm_network_render:
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_network_paths")
|
||||
#row = layout.row(align=True)
|
||||
#row.prop(sceneProperties, "tlm_network_dir")
|
||||
row = layout.row(align=True)
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_caching_mode")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_directional_mode")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_lightmap_savedir")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_dilation_margin")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_exposure_multiplier")
|
||||
row = layout.row(align=True)
|
||||
row.prop(engineProperties, "tlm_setting_supersample")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_metallic_clamp")
|
||||
|
||||
elif sceneProperties.tlm_lightmap_engine == "LuxCoreRender":
|
||||
|
||||
#LUXCORE SETTINGS HERE
|
||||
luxcore_available = False
|
||||
|
||||
#Look for Luxcorerender in the renderengine classes
|
||||
for engine in bpy.types.RenderEngine.__subclasses__():
|
||||
if engine.bl_idname == "LUXCORE":
|
||||
luxcore_available = True
|
||||
break
|
||||
|
||||
row = layout.row(align=True)
|
||||
if not luxcore_available:
|
||||
row.label(text="Please install BlendLuxCore.")
|
||||
else:
|
||||
row.label(text="LuxCoreRender not yet available.")
|
||||
|
||||
elif sceneProperties.tlm_lightmap_engine == "OctaneRender":
|
||||
|
||||
#LUXCORE SETTINGS HERE
|
||||
octane_available = False
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Octane Render not yet available.")
|
||||
|
||||
|
||||
##################
|
||||
#DENOISE SETTINGS!
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Denoise Settings")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_denoise_use")
|
||||
row = layout.row(align=True)
|
||||
|
||||
if sceneProperties.tlm_denoise_use:
|
||||
row.prop(sceneProperties, "tlm_denoise_engine", expand=True)
|
||||
row = layout.row(align=True)
|
||||
|
||||
if sceneProperties.tlm_denoise_engine == "Integrated":
|
||||
row.label(text="No options for Integrated.")
|
||||
elif sceneProperties.tlm_denoise_engine == "OIDN":
|
||||
denoiseProperties = scene.TLM_OIDNEngineProperties
|
||||
row.prop(denoiseProperties, "tlm_oidn_path")
|
||||
row = layout.row(align=True)
|
||||
row.prop(denoiseProperties, "tlm_oidn_verbose")
|
||||
row = layout.row(align=True)
|
||||
row.prop(denoiseProperties, "tlm_oidn_threads")
|
||||
row = layout.row(align=True)
|
||||
row.prop(denoiseProperties, "tlm_oidn_maxmem")
|
||||
row = layout.row(align=True)
|
||||
row.prop(denoiseProperties, "tlm_oidn_affinity")
|
||||
# row = layout.row(align=True)
|
||||
# row.prop(denoiseProperties, "tlm_denoise_ao")
|
||||
elif sceneProperties.tlm_denoise_engine == "Optix":
|
||||
denoiseProperties = scene.TLM_OptixEngineProperties
|
||||
row.prop(denoiseProperties, "tlm_optix_path")
|
||||
row = layout.row(align=True)
|
||||
row.prop(denoiseProperties, "tlm_optix_verbose")
|
||||
row = layout.row(align=True)
|
||||
row.prop(denoiseProperties, "tlm_optix_maxmem")
|
||||
|
||||
|
||||
##################
|
||||
#FILTERING SETTINGS!
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Filtering Settings")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_filtering_use")
|
||||
row = layout.row(align=True)
|
||||
|
||||
if sceneProperties.tlm_filtering_use:
|
||||
|
||||
if sceneProperties.tlm_filtering_engine == "OpenCV":
|
||||
|
||||
cv2 = importlib.util.find_spec("cv2")
|
||||
|
||||
if cv2 is None:
|
||||
row = layout.row(align=True)
|
||||
row.label(text="OpenCV is not installed. Install it below.")
|
||||
row = layout.row(align=True)
|
||||
row.label(text="It is recommended to install as administrator.")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.install_opencv_lightmaps")
|
||||
else:
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_mode")
|
||||
row = layout.row(align=True)
|
||||
if scene.TLM_SceneProperties.tlm_filtering_mode == "Gaussian":
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_gaussian_strength")
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_iterations")
|
||||
elif scene.TLM_SceneProperties.tlm_filtering_mode == "Box":
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_box_strength")
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_iterations")
|
||||
|
||||
elif scene.TLM_SceneProperties.tlm_filtering_mode == "Bilateral":
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_bilateral_diameter")
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_bilateral_color_deviation")
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_bilateral_coordinate_deviation")
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_iterations")
|
||||
else:
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_median_kernel", expand=True)
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_filtering_iterations")
|
||||
else:
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene.TLM_SceneProperties, "tlm_numpy_filtering_mode")
|
||||
|
||||
|
||||
##################
|
||||
#ENCODING SETTINGS!
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Encoding Settings")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_encoding_use")
|
||||
row = layout.row(align=True)
|
||||
|
||||
if sceneProperties.tlm_encoding_use:
|
||||
|
||||
|
||||
if scene.TLM_EngineProperties.tlm_bake_mode == "Background":
|
||||
row.label(text="Encoding options disabled in background mode")
|
||||
row = layout.row(align=True)
|
||||
|
||||
row.prop(sceneProperties, "tlm_encoding_device", expand=True)
|
||||
row = layout.row(align=True)
|
||||
|
||||
if sceneProperties.tlm_encoding_device == "CPU":
|
||||
row.prop(sceneProperties, "tlm_encoding_mode_a", expand=True)
|
||||
else:
|
||||
row.prop(sceneProperties, "tlm_encoding_mode_b", expand=True)
|
||||
|
||||
if sceneProperties.tlm_encoding_device == "CPU":
|
||||
if sceneProperties.tlm_encoding_mode_a == "RGBM":
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_encoding_range")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_decoder_setup")
|
||||
if sceneProperties.tlm_encoding_mode_a == "RGBD":
|
||||
pass
|
||||
if sceneProperties.tlm_encoding_mode_a == "HDR":
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_format")
|
||||
else:
|
||||
|
||||
if sceneProperties.tlm_encoding_mode_b == "RGBM":
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_encoding_range")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_decoder_setup")
|
||||
|
||||
if sceneProperties.tlm_encoding_mode_b == "LogLuv" and sceneProperties.tlm_encoding_device == "GPU":
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_decoder_setup")
|
||||
if sceneProperties.tlm_encoding_mode_b == "HDR":
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_format")
|
||||
|
||||
##################
|
||||
#SELECTION OPERATORS!
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Selection Operators")
|
||||
row = layout.row(align=True)
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.enable_selection")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.disable_selection")
|
||||
row = layout.row(align=True)
|
||||
row.prop(sceneProperties, "tlm_override_object_settings")
|
||||
|
||||
if sceneProperties.tlm_override_object_settings:
|
||||
|
||||
row = layout.row(align=True)
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_mesh_lightmap_unwrap_mode")
|
||||
row = layout.row()
|
||||
|
||||
if sceneProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
|
||||
if scene.TLM_AtlasListItem >= 0 and len(scene.TLM_AtlasList) > 0:
|
||||
row = layout.row()
|
||||
item = scene.TLM_AtlasList[scene.TLM_AtlasListItem]
|
||||
row.prop_search(sceneProperties, "tlm_atlas_pointer", scene, "TLM_AtlasList", text='Atlas Group')
|
||||
else:
|
||||
row = layout.label(text="Add Atlas Groups from the scene lightmapping settings.")
|
||||
|
||||
else:
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_postpack_object")
|
||||
row = layout.row()
|
||||
|
||||
if sceneProperties.tlm_postpack_object and sceneProperties.tlm_mesh_lightmap_unwrap_mode != "AtlasGroupA":
|
||||
if scene.TLM_PostAtlasListItem >= 0 and len(scene.TLM_PostAtlasList) > 0:
|
||||
row = layout.row()
|
||||
item = scene.TLM_PostAtlasList[scene.TLM_PostAtlasListItem]
|
||||
row.prop_search(sceneProperties, "tlm_postatlas_pointer", scene, "TLM_PostAtlasList", text='Atlas Group')
|
||||
row = layout.row()
|
||||
|
||||
else:
|
||||
row = layout.label(text="Add Atlas Groups from the scene lightmapping settings.")
|
||||
row = layout.row()
|
||||
|
||||
if sceneProperties.tlm_mesh_lightmap_unwrap_mode != "AtlasGroupA":
|
||||
row.prop(sceneProperties, "tlm_mesh_lightmap_resolution")
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_mesh_unwrap_margin")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.remove_uv_selection")
|
||||
row = layout.row(align=True)
|
||||
row.operator("tlm.select_lightmapped_objects")
|
||||
row = layout.row(align=True)
|
||||
|
||||
##################
|
||||
#Additional settings
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Additional options")
|
||||
sceneProperties = scene.TLM_SceneProperties
|
||||
atlasListItem = scene.TLM_AtlasListItem
|
||||
atlasList = scene.TLM_AtlasList
|
||||
postatlasListItem = scene.TLM_PostAtlasListItem
|
||||
postatlasList = scene.TLM_PostAtlasList
|
||||
|
||||
layout.label(text="Atlas Groups")
|
||||
row = layout.row()
|
||||
row.prop(sceneProperties, "tlm_atlas_mode", expand=True)
|
||||
|
||||
if sceneProperties.tlm_atlas_mode == "Prepack":
|
||||
|
||||
rows = 2
|
||||
if len(atlasList) > 1:
|
||||
rows = 4
|
||||
row = layout.row()
|
||||
row.template_list("TLM_UL_AtlasList", "Atlas List", scene, "TLM_AtlasList", scene, "TLM_AtlasListItem", rows=rows)
|
||||
col = row.column(align=True)
|
||||
col.operator("tlm_atlaslist.new_item", icon='ADD', text="")
|
||||
col.operator("tlm_atlaslist.delete_item", icon='REMOVE', text="")
|
||||
#col.menu("ARM_MT_BakeListSpecials", icon='DOWNARROW_HLT', text="")
|
||||
|
||||
# if len(scene.TLM_AtlasList) > 1:
|
||||
# col.separator()
|
||||
# op = col.operator("arm_bakelist.move_item", icon='TRIA_UP', text="")
|
||||
# op.direction = 'UP'
|
||||
# op = col.operator("arm_bakelist.move_item", icon='TRIA_DOWN', text="")
|
||||
# op.direction = 'DOWN'
|
||||
|
||||
if atlasListItem >= 0 and len(atlasList) > 0:
|
||||
item = atlasList[atlasListItem]
|
||||
#layout.prop_search(item, "obj", bpy.data, "objects", text="Object")
|
||||
#layout.prop(item, "res_x")
|
||||
layout.prop(item, "tlm_atlas_lightmap_unwrap_mode")
|
||||
layout.prop(item, "tlm_atlas_lightmap_resolution")
|
||||
layout.prop(item, "tlm_atlas_unwrap_margin")
|
||||
|
||||
amount = 0
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_unwrap_mode == "AtlasGroupA":
|
||||
if obj.TLM_ObjectProperties.tlm_atlas_pointer == item.name:
|
||||
amount = amount + 1
|
||||
|
||||
layout.label(text="Objects: " + str(amount))
|
||||
|
||||
# layout.use_property_split = True
|
||||
# layout.use_property_decorate = False
|
||||
# layout.label(text="Enable for selection")
|
||||
# layout.label(text="Disable for selection")
|
||||
# layout.label(text="Something...")
|
||||
|
||||
else:
|
||||
|
||||
layout.label(text="Postpacking is unstable.")
|
||||
rows = 2
|
||||
if len(atlasList) > 1:
|
||||
rows = 4
|
||||
row = layout.row()
|
||||
row.template_list("TLM_UL_PostAtlasList", "PostList", scene, "TLM_PostAtlasList", scene, "TLM_PostAtlasListItem", rows=rows)
|
||||
col = row.column(align=True)
|
||||
col.operator("tlm_postatlaslist.new_item", icon='ADD', text="")
|
||||
col.operator("tlm_postatlaslist.delete_item", icon='REMOVE', text="")
|
||||
|
||||
if postatlasListItem >= 0 and len(postatlasList) > 0:
|
||||
item = postatlasList[postatlasListItem]
|
||||
layout.prop(item, "tlm_atlas_lightmap_resolution")
|
||||
|
||||
#Below list object counter
|
||||
amount = 0
|
||||
utilized = 0
|
||||
atlasUsedArea = 0
|
||||
atlasSize = item.tlm_atlas_lightmap_resolution
|
||||
|
||||
for obj in bpy.data.objects:
|
||||
if obj.TLM_ObjectProperties.tlm_mesh_lightmap_use:
|
||||
if obj.TLM_ObjectProperties.tlm_postpack_object:
|
||||
if obj.TLM_ObjectProperties.tlm_postatlas_pointer == item.name:
|
||||
amount = amount + 1
|
||||
|
||||
atlasUsedArea += int(obj.TLM_ObjectProperties.tlm_mesh_lightmap_resolution) ** 2
|
||||
|
||||
row = layout.row()
|
||||
row.prop(item, "tlm_atlas_repack_on_cleanup")
|
||||
|
||||
#TODO SET A CHECK FOR THIS! ADD A CV2 CHECK TO UTILITY!
|
||||
cv2 = True
|
||||
|
||||
if cv2:
|
||||
row = layout.row()
|
||||
row.prop(item, "tlm_atlas_dilation")
|
||||
layout.label(text="Objects: " + str(amount))
|
||||
|
||||
utilized = atlasUsedArea / (int(atlasSize) ** 2)
|
||||
layout.label(text="Utilized: " + str(utilized * 100) + "%")
|
||||
|
||||
if (utilized * 100) > 100:
|
||||
layout.label(text="Warning! Overflow not yet supported")
|
||||
|
||||
class ArmGenLodButton(bpy.types.Operator):
|
||||
"""Automatically generate LoD levels."""
|
||||
bl_idname = 'arm.generate_lod'
|
||||
|
@ -2671,6 +2263,13 @@ def register():
|
|||
bpy.utils.register_class(ArmoryUpdateListAndroidEmulatorRunButton)
|
||||
bpy.utils.register_class(ArmoryUpdateListInstalledVSButton)
|
||||
|
||||
bpy.utils.register_class(scene.TLM_PT_Settings)
|
||||
bpy.utils.register_class(scene.TLM_PT_Denoise)
|
||||
bpy.utils.register_class(scene.TLM_PT_Filtering)
|
||||
bpy.utils.register_class(scene.TLM_PT_Encoding)
|
||||
bpy.utils.register_class(scene.TLM_PT_Utility)
|
||||
bpy.utils.register_class(scene.TLM_PT_Additional)
|
||||
|
||||
bpy.types.VIEW3D_HT_header.append(draw_view3d_header)
|
||||
bpy.types.VIEW3D_MT_object.append(draw_view3d_object_menu)
|
||||
bpy.types.NODE_MT_context_menu.append(draw_custom_node_menu)
|
||||
|
@ -2743,3 +2342,10 @@ def unregister():
|
|||
bpy.utils.unregister_class(ArmSyncProxyButton)
|
||||
bpy.utils.unregister_class(ArmPrintTraitsButton)
|
||||
bpy.utils.unregister_class(ARM_PT_MaterialNodePanel)
|
||||
|
||||
bpy.utils.unregister_class(scene.TLM_PT_Settings)
|
||||
bpy.utils.unregister_class(scene.TLM_PT_Denoise)
|
||||
bpy.utils.unregister_class(scene.TLM_PT_Filtering)
|
||||
bpy.utils.unregister_class(scene.TLM_PT_Encoding)
|
||||
bpy.utils.unregister_class(scene.TLM_PT_Utility)
|
||||
bpy.utils.unregister_class(scene.TLM_PT_Additional)
|
Loading…
Reference in a new issue