Update leenkx/blender/lnx/material/cycles.py

This commit is contained in:
2025-11-14 17:41:39 +00:00
parent 4f4f28d62f
commit 3bee97a560

View File

@ -69,9 +69,12 @@ def resize_texture_if_needed(image: bpy.types.Image, filepath: str, max_size: in
if image.size[0] <= max_size and image.size[1] <= max_size: if image.size[0] <= max_size and image.size[1] <= max_size:
return filepath return filepath
cache_key = (filepath, max_size, os.path.getmtime(filepath) if os.path.exists(filepath) else 0) wrd = bpy.data.worlds['Lnx']
if cache_key in texture_resize_cache: texture_quality = wrd.lnx_texture_quality
cached_path = texture_resize_cache[cache_key]
cache_key = (filepath, max_size, texture_quality, os.path.getmtime(filepath) if os.path.exists(filepath) else 0)
if cache_key in _texture_resize_cache:
cached_path = _texture_resize_cache[cache_key]
if os.path.exists(cached_path): if os.path.exists(cached_path):
return cached_path return cached_path
@ -84,38 +87,78 @@ def resize_texture_if_needed(image: bpy.types.Image, filepath: str, max_size: in
new_width = int((width / height) * max_size) new_width = int((width / height) * max_size)
build_dir = lnx.utils.get_fp_build() build_dir = lnx.utils.get_fp_build()
resized_dir = os.path.join(build_dir, 'compiled', 'Assets', 'resized_textures') resized_dir = os.path.join(build_dir, 'compiled', 'Assets', 'unpacked')
os.makedirs(resized_dir, exist_ok=True) os.makedirs(resized_dir, exist_ok=True)
basename = os.path.basename(filepath) basename = os.path.basename(filepath)
name, ext = os.path.splitext(basename) name, ext = os.path.splitext(basename)
resized_path = os.path.join(resized_dir, f"{name}_{max_size}px{ext}") quality_suffix = f"q{int(texture_quality * 100)}"
resized_path = os.path.join(resized_dir, f"{name}_{max_size}px_{quality_suffix}{ext}")
if os.path.exists(resized_path): if os.path.exists(resized_path):
src_mtime = os.path.getmtime(filepath) src_mtime = os.path.getmtime(filepath)
dst_mtime = os.path.getmtime(resized_path) dst_mtime = os.path.getmtime(resized_path)
if dst_mtime >= src_mtime: if dst_mtime >= src_mtime:
print(f"Using cached: {basename} -> {new_width}x{new_height}") _texture_resize_cache[cache_key] = resized_path
texture_resize_cache[cache_key] = resized_path
return resized_path return resized_path
try: try:
from PIL import Image as PILImage ffmpeg_path = lnx.utils.get_ffmpeg_path()
img = PILImage.open(filepath)
img_resized = img.resize((new_width, new_height), PILImage.Resampling.LANCZOS) if ffmpeg_path is None or ffmpeg_path == '':
img_resized.save(resized_path, quality=95, optimize=True) print(f"[Texture Optimizer] WARNING: FFmpeg not found. Please set FFmpeg path in addon preferences.")
print(f"Resized: {basename} {width}x{height} -> {new_width}x{new_height}") print(f"[Texture Optimizer] Skipping resize for: {basename}")
texture_resize_cache[cache_key] = resized_path return filepath
file_ext = os.path.splitext(filepath)[1].lower().lstrip('.')
cmd = [
ffmpeg_path,
'-y',
'-i', filepath,
'-vf', f'scale={new_width}:{new_height}:flags=lanczos',
]
if file_ext in ('png', 'tga', 'bmp'):
compression_level = round((1.0 - texture_quality) * 9)
cmd.extend(['-compression_level', str(compression_level)])
else:
qscale = round(2 + (1.0 - texture_quality) * 29)
cmd.extend(['-q:v', str(qscale)])
cmd.append(resized_path)
startupinfo = None
if os.name == 'nt':
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
result = subprocess.run(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
startupinfo=startupinfo,
timeout=60
)
if result.returncode == 0 and os.path.exists(resized_path):
print(f"[Texture Optimizer] Resized: {basename} {width}x{height} -> {new_width}x{new_height}")
_texture_resize_cache[cache_key] = resized_path
return resized_path return resized_path
except ImportError: else:
print(f"WARNING: PIL/Pillow not installed. Install with: pip install Pillow") error_msg = result.stderr.decode('utf-8', errors='ignore') if result.stderr else 'Unknown error'
print(f"Skipping resize for: {basename}") print(f"[Texture Optimizer] WARNING: FFmpeg failed to resize {basename}: {error_msg}")
return filepath
except subprocess.TimeoutExpired:
print(f"[Texture Optimizer] WARNING: FFmpeg timeout while resizing {basename}")
return filepath return filepath
except Exception as e: except Exception as e:
print(f"WARNING: Failed to resize {basename}: {e}") print(f"[Texture Optimizer] WARNING: Failed to resize {basename}: {e}")
return filepath return filepath
def parse(nodes, con: ShaderContext, def parse(nodes, con: ShaderContext,
vert: Shader, frag: Shader, geom: Shader, tesc: Shader, tese: Shader, vert: Shader, frag: Shader, geom: Shader, tesc: Shader, tese: Shader,
parse_surface=True, parse_opacity=True, parse_displacement=True, basecol_only=False): parse_surface=True, parse_opacity=True, parse_displacement=True, basecol_only=False):