diff --git a/Texturing/MergeTextures2/build/merge_textures/Analysis-00.toc b/Texturing/MergeTextures2/build/merge_textures/Analysis-00.toc index 0933ce6..996bb31 100644 --- a/Texturing/MergeTextures2/build/merge_textures/Analysis-00.toc +++ b/Texturing/MergeTextures2/build/merge_textures/Analysis-00.toc @@ -2266,14 +2266,14 @@ 'C:\\Program ' 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\_py_abc.py', 'PYMODULE'), - ('tracemalloc', - 'C:\\Program ' - 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\tracemalloc.py', - 'PYMODULE'), ('stringprep', 'C:\\Program ' 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\stringprep.py', 'PYMODULE'), + ('tracemalloc', + 'C:\\Program ' + 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\tracemalloc.py', + 'PYMODULE'), ('PIL.Image', 'C:\\Users\\Niklas\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python310\\site-packages\\PIL\\Image.py', 'PYMODULE'), @@ -3232,29 +3232,29 @@ 'E:\\Arma Reforger ' 'Work\\1960-utils\\Texturing\\MergeTextures2\\build\\merge_textures\\base_library.zip', 'DATA'), - ('setuptools-65.5.0.dist-info\\LICENSE', + ('setuptools-65.5.0.dist-info\\METADATA', 'C:\\Program ' - 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\LICENSE', + 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\METADATA', + 'DATA'), + ('setuptools-65.5.0.dist-info\\top_level.txt', + 'C:\\Program ' + 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\top_level.txt', 'DATA'), ('setuptools-65.5.0.dist-info\\RECORD', 'C:\\Program ' 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\RECORD', 'DATA'), - ('setuptools-65.5.0.dist-info\\METADATA', + ('setuptools-65.5.0.dist-info\\LICENSE', 'C:\\Program ' - 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\METADATA', - 'DATA'), - ('setuptools-65.5.0.dist-info\\INSTALLER', - 'C:\\Program ' - 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\INSTALLER', + 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\LICENSE', 'DATA'), ('setuptools-65.5.0.dist-info\\WHEEL', 'C:\\Program ' 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\WHEEL', 'DATA'), - ('setuptools-65.5.0.dist-info\\top_level.txt', + ('setuptools-65.5.0.dist-info\\INSTALLER', 'C:\\Program ' - 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\top_level.txt', + 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\INSTALLER', 'DATA'), ('setuptools-65.5.0.dist-info\\entry_points.txt', 'C:\\Program ' diff --git a/Texturing/MergeTextures2/build/merge_textures/EXE-00.toc b/Texturing/MergeTextures2/build/merge_textures/EXE-00.toc index cc5420d..ed4f28f 100644 --- a/Texturing/MergeTextures2/build/merge_textures/EXE-00.toc +++ b/Texturing/MergeTextures2/build/merge_textures/EXE-00.toc @@ -277,29 +277,29 @@ 'E:\\Arma Reforger ' 'Work\\1960-utils\\Texturing\\MergeTextures2\\build\\merge_textures\\base_library.zip', 'DATA'), - ('setuptools-65.5.0.dist-info\\LICENSE', + ('setuptools-65.5.0.dist-info\\METADATA', 'C:\\Program ' - 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\LICENSE', + 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\METADATA', + 'DATA'), + ('setuptools-65.5.0.dist-info\\top_level.txt', + 'C:\\Program ' + 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\top_level.txt', 'DATA'), ('setuptools-65.5.0.dist-info\\RECORD', 'C:\\Program ' 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\RECORD', 'DATA'), - ('setuptools-65.5.0.dist-info\\METADATA', + ('setuptools-65.5.0.dist-info\\LICENSE', 'C:\\Program ' - 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\METADATA', - 'DATA'), - ('setuptools-65.5.0.dist-info\\INSTALLER', - 'C:\\Program ' - 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\INSTALLER', + 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\LICENSE', 'DATA'), ('setuptools-65.5.0.dist-info\\WHEEL', 'C:\\Program ' 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\WHEEL', 'DATA'), - ('setuptools-65.5.0.dist-info\\top_level.txt', + ('setuptools-65.5.0.dist-info\\INSTALLER', 'C:\\Program ' - 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\top_level.txt', + 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\INSTALLER', 'DATA'), ('setuptools-65.5.0.dist-info\\entry_points.txt', 'C:\\Program ' @@ -312,7 +312,7 @@ [], False, False, - 1729259223, + 1729345827, [('run.exe', 'C:\\Users\\Niklas\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python310\\site-packages\\PyInstaller\\bootloader\\Windows-64bit-intel\\run.exe', 'EXECUTABLE')], diff --git a/Texturing/MergeTextures2/build/merge_textures/PKG-00.toc b/Texturing/MergeTextures2/build/merge_textures/PKG-00.toc index 41e2da6..0e9b167 100644 --- a/Texturing/MergeTextures2/build/merge_textures/PKG-00.toc +++ b/Texturing/MergeTextures2/build/merge_textures/PKG-00.toc @@ -253,29 +253,29 @@ 'E:\\Arma Reforger ' 'Work\\1960-utils\\Texturing\\MergeTextures2\\build\\merge_textures\\base_library.zip', 'DATA'), - ('setuptools-65.5.0.dist-info\\LICENSE', + ('setuptools-65.5.0.dist-info\\METADATA', 'C:\\Program ' - 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\LICENSE', + 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\METADATA', + 'DATA'), + ('setuptools-65.5.0.dist-info\\top_level.txt', + 'C:\\Program ' + 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\top_level.txt', 'DATA'), ('setuptools-65.5.0.dist-info\\RECORD', 'C:\\Program ' 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\RECORD', 'DATA'), - ('setuptools-65.5.0.dist-info\\METADATA', + ('setuptools-65.5.0.dist-info\\LICENSE', 'C:\\Program ' - 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\METADATA', - 'DATA'), - ('setuptools-65.5.0.dist-info\\INSTALLER', - 'C:\\Program ' - 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\INSTALLER', + 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\LICENSE', 'DATA'), ('setuptools-65.5.0.dist-info\\WHEEL', 'C:\\Program ' 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\WHEEL', 'DATA'), - ('setuptools-65.5.0.dist-info\\top_level.txt', + ('setuptools-65.5.0.dist-info\\INSTALLER', 'C:\\Program ' - 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\top_level.txt', + 'Files\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\\lib\\site-packages\\setuptools-65.5.0.dist-info\\INSTALLER', 'DATA'), ('setuptools-65.5.0.dist-info\\entry_points.txt', 'C:\\Program ' diff --git a/Texturing/MergeTextures2/build/merge_textures/base_library.zip b/Texturing/MergeTextures2/build/merge_textures/base_library.zip index a6b9d38..2c5d5de 100644 Binary files a/Texturing/MergeTextures2/build/merge_textures/base_library.zip and b/Texturing/MergeTextures2/build/merge_textures/base_library.zip differ diff --git a/Texturing/MergeTextures2/build/merge_textures/merge_textures.pkg b/Texturing/MergeTextures2/build/merge_textures/merge_textures.pkg index 0edd352..135caeb 100644 Binary files a/Texturing/MergeTextures2/build/merge_textures/merge_textures.pkg and b/Texturing/MergeTextures2/build/merge_textures/merge_textures.pkg differ diff --git a/Texturing/MergeTextures2/dist/merge_textures.exe b/Texturing/MergeTextures2/dist/merge_textures.exe index f5ec2c2..ba5b732 100644 Binary files a/Texturing/MergeTextures2/dist/merge_textures.exe and b/Texturing/MergeTextures2/dist/merge_textures.exe differ diff --git a/Texturing/MergeTextures2/merge_textures.py b/Texturing/MergeTextures2/merge_textures.py index 49ee317..a1f545c 100644 --- a/Texturing/MergeTextures2/merge_textures.py +++ b/Texturing/MergeTextures2/merge_textures.py @@ -1,15 +1,16 @@ import os import sys -from PIL import Image +from PIL import Image # type: ignore import time # Define suffix lists for BaseColor, Normal, RMA/ORM -BASECOLOR_SUFFIXES = ['_alb', '_albedo', '_bc', '_basecolor', '_b'] -NORMAL_SUFFIXES = ['_nrm', '_normal', '_n'] -RMA_SUFFIXES = ['_rma'] -ORM_SUFFIXES = ['_orm'] -EMISSIVE_SUFFIXES = ['_emissive'] -OPACITY_SUFFIXES = ['_opacity'] +BASECOLOR_SUFFIXES = ['_alb.', '_albedo.', '_bc.', '_basecolor.', '_b.'] +NORMAL_SUFFIXES = ['_nrm.', '_normal.', '_n.'] +RMA_SUFFIXES = ['_rma.'] +ORM_SUFFIXES = ['_orm.'] +EMISSIVE_SUFFIXES = ['_emissive.'] +OPACITY_SUFFIXES = ['_opacity.'] +MASK_SUFFIXES = ['_mask.','_m.'] def detect_texture_type(filename): """ Detects the type of texture based on its suffix """ @@ -25,16 +26,23 @@ def detect_texture_type(filename): return 'Emissive' elif any(suffix in filename.lower() for suffix in OPACITY_SUFFIXES): return 'Opacity' + elif any(suffix in filename.lower() for suffix in MASK_SUFFIXES): + return 'Mask' return None def get_material_name(filename): - """ Strips the 'T_' or 'TX_' prefix and returns the material name """ + """ Strips the 'T_' or 'TX_' prefix but keeps the suffix for texture type detection. + Returns the full material name without the suffix for output file naming. """ base_name = os.path.basename(filename) + + # Remove the 'T_' or 'TX_' prefix if base_name.startswith('T_'): - return base_name[2:].split('_')[0] # Assumes 'T_Material_Suffix' + base_name = base_name[2:] elif base_name.startswith('TX_'): - return base_name[3:].split('_')[0] # Assumes 'TX_Material_Suffix' - return base_name.split('_')[0] + base_name = base_name[3:] + + # Return the base_name without the suffix for output naming + return base_name.rsplit('_', 1)[0] # Split only at the last underscore def process_textures(input_files): """ Main function to process all textures in a folder and convert to BCR/NMO """ @@ -54,27 +62,44 @@ def process_textures(input_files): base_path = os.path.dirname(input_files[0]) output_folder = os.path.join(base_path, 'merged') os.makedirs(output_folder, exist_ok=True) - + + material_count = len(textures) + print(f"Detected {material_count} Materials to process.") + # Process each material group - for material, files in textures.items(): + for index, (material, files) in enumerate(textures.items()): basecolor_file = files.get('BaseColor') normal_file = files.get('Normal') rma_file = files.get('RMA') orm_file = files.get('ORM') emissive_file = files.get('Emissive') opacity_file = files.get('Opacity') - - if basecolor_file and normal_file and (rma_file or orm_file): - # Convert to BCR/NMO format - convert_to_bcr_nmo(material, basecolor_file, normal_file, rma_file, orm_file, emissive_file, opacity_file, output_folder) - print(f"{material}: Successfully converted.") + mask_file = files.get('Mask') + + missing_files = [] + failed_converts = 0 + + # Check for required textures + if not basecolor_file: + missing_files.append('BaseColor') + if not normal_file: + missing_files.append('Normal') + if not (rma_file or orm_file): + missing_files.append('RMA or ORM') + + # Report missing files if any + if missing_files: + print(f"({index+1}/{material_count}) Skipping {material}: missing {', '.join(missing_files)}") + failed_converts += 1 else: - print(f"Skipping {material}: missing necessary files") + # Convert to BCR/NMO format + convert_to_bcr_nmo(material, basecolor_file, normal_file, rma_file, orm_file, emissive_file, opacity_file, mask_file, output_folder) + print(f"({index+1}/{material_count}) {material}: Successfully converted.") - print("+++All materials successfully converted+++") + print(f"+++{material_count - failed_converts} of {material_count} materials successfully converted+++") time.sleep(3) -def convert_to_bcr_nmo(material, basecolor_file, normal_file, rma_file, orm_file, emissive_file, opacity_file, output_folder): +def convert_to_bcr_nmo(material, basecolor_file, normal_file, rma_file, orm_file, emissive_file, opacity_file, mask_file, output_folder): """ Converts given textures to BCR and NMO formats """ basecolor_img = Image.open(basecolor_file).convert('RGBA') normal_img = Image.open(normal_file).convert('RGBA') @@ -103,6 +128,10 @@ def convert_to_bcr_nmo(material, basecolor_file, normal_file, rma_file, orm_file if opacity_file: opacity_img = Image.open(opacity_file).convert('L') opacity_img.save(os.path.join(output_folder, f"{material}_OP.png")) + + if mask_file: + mask_img = Image.open(mask_file).convert('L') + mask_img.save(os.path.join(output_folder, f"{material}_MASK.png")) if __name__ == "__main__": if len(sys.argv) < 2: print("Usage: drag and drop texture files onto the script")