Initial commit
This commit is contained in:
commit
30b5b7ec23
6
.lh/.lhignore
Normal file
6
.lh/.lhignore
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# list file to not track by the local-history extension. comment line starts with a '#' character
|
||||||
|
# each line describe a regular expression pattern (search for 'Javascript regex')
|
||||||
|
# it will relate to the workspace directory root. for example:
|
||||||
|
# '.*\.txt' ignores any file with 'txt' extension
|
||||||
|
# '/test/.*' ignores all the files under the 'test' directory
|
||||||
|
# '.*/test/.*' ignores all the files under any 'test' directory (even under sub-folders)
|
||||||
34
.lh/.vscode/settings.json.json
vendored
Normal file
34
.lh/.vscode/settings.json.json
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": ".vscode/settings.json",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 4,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745334456903,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745334464049,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -0,0 +1,10 @@\n+{\r\n+ \"files.exclude\": {\r\n+ \"**/.git\": true,\r\n+ \"**/.svn\": true,\r\n+ \"**/.hg\": true,\r\n+ \"**/.DS_Store\": true,\r\n+ \"**/Thumbs.db\": true,\r\n+ \".vscode\": true\r\n+ }\r\n+}\n\\ No newline at end of file\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745334472393,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -4,16 +4,9 @@\n \"**/.svn\": true,\r\n \"**/.hg\": true,\r\n \"**/.DS_Store\": true,\r\n \"**/Thumbs.db\": true,\r\n- \".vscode\": true\r\n+ \".vscode\": true,\r\n+ \".vs\": true,\r\n+ \".lh\": true\r\n }\r\n-}\n-{\r\n- \"files.exclude\": {\r\n- \"**/.git\": true,\r\n- \"**/.svn\": true,\r\n- \"**/.hg\": true,\r\n- \"**/.DS_Store\": true,\r\n- \"**/Thumbs.db\": true\r\n- }\r\n }\n\\ No newline at end of file\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745334478206,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -6,7 +6,9 @@\n \"**/.DS_Store\": true,\r\n \"**/Thumbs.db\": true,\r\n \".vscode\": true,\r\n \".vs\": true,\r\n- \".lh\": true\r\n+ \".lh\": true,\r\n+ \"__pycache__\": true,\r\n+ \"Deprecated-POC\": true\r\n }\r\n }\n\\ No newline at end of file\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745334493049,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -8,7 +8,9 @@\n \".vscode\": true,\r\n \".vs\": true,\r\n \".lh\": true,\r\n \"__pycache__\": true,\r\n- \"Deprecated-POC\": true\r\n+ \"Deprecated-POC\": true,\r\n+ \"BlenderDocumentation\": true,\r\n+ \"PythonCheatsheats\": true\r\n }\r\n }\n\\ No newline at end of file\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745334456903,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "{\r\n \"files.exclude\": {\r\n \"**/.git\": true,\r\n \"**/.svn\": true,\r\n \"**/.hg\": true,\r\n \"**/.DS_Store\": true,\r\n \"**/Thumbs.db\": true\r\n }\r\n}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
30
.lh/Documentation/00_Overview.md.json
Normal file
30
.lh/Documentation/00_Overview.md.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/00_Overview.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 3,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494293096,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745495189201,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -11,28 +11,28 @@\n This documentation strictly excludes details on environment setup, dependency installation, building the project, or deployment procedures, assuming familiarity with Python and the relevant libraries (OpenCV, NumPy, PySide6).\r\n \r\n ## Table of Contents\r\n \r\n-* [Overview](00_Overview.md)\r\n-* **User Guide**\r\n- * [Introduction](01_User_Guide/01_Introduction.md)\r\n- * [Features](01_User_Guide/02_Features.md)\r\n- * [Installation](01_User_Guide/03_Installation.md)\r\n- * [Configuration and Presets](01_User_Guide/04_Configuration_and_Presets.md)\r\n- * [Usage: GUI](01_User_Guide/05_Usage_GUI.md)\r\n- * [Usage: CLI](01_User_Guide/06_Usage_CLI.md)\r\n- * [Usage: Monitor](01_User_Guide/07_Usage_Monitor.md)\r\n- * [Usage: Blender Integration](01_User_Guide/08_Usage_Blender.md)\r\n- * [Output Structure](01_User_Guide/09_Output_Structure.md)\r\n- * [Docker](01_User_Guide/10_Docker.md)\r\n-* **Developer Guide**\r\n- * [Architecture](02_Developer_Guide/01_Architecture.md)\r\n- * [Codebase Structure](02_Developer_Guide/02_Codebase_Structure.md)\r\n- * [Key Components](02_Developer_Guide/03_Key_Components.md)\r\n- * [Configuration System and Presets](02_Developer_Guide/04_Configuration_System_and_Presets.md)\r\n- * [Processing Pipeline](02_Developer_Guide/05_Processing_Pipeline.md)\r\n- * [GUI Internals](02_Developer_Guide/06_GUI_Internals.md)\r\n- * [Monitor Internals](02_Developer_Guide/07_Monitor_Internals.md)\r\n- * [Blender Integration Internals](02_Developer_Guide/08_Blender_Integration_Internals.md)\r\n- * [Development Workflow](02_Developer_Guide/09_Development_Workflow.md)\r\n- * [Coding Conventions](02_Developer_Guide/10_Coding_Conventions.md)\r\n- * [Debugging Notes](02_Developer_Guide/11_Debugging_Notes.md)\n\\ No newline at end of file\n+* [Overview](00_Overview.md) - This document, providing a high-level summary and table of contents.\r\n+* **User Guide** - Information for end-users of the tool.\r\n+ * [Introduction](01_User_Guide/01_Introduction.md) - Purpose and scope of the tool for users.\r\n+ * [Features](01_User_Guide/02_Features.md) - Detailed list of the tool's capabilities.\r\n+ * [Installation](01_User_Guide/03_Installation.md) - Requirements and setup instructions.\r\n+ * [Configuration and Presets](01_User_Guide/04_Configuration_and_Presets.md) - How to configure the tool and use presets.\r\n+ * [Usage: GUI](01_User_Guide/05_Usage_GUI.md) - Guide to using the Graphical User Interface.\r\n+ * [Usage: CLI](01_User_Guide/06_Usage_CLI.md) - Guide to using the Command-Line Interface.\r\n+ * [Usage: Monitor](01_User_Guide/07_Usage_Monitor.md) - Guide to using the Directory Monitor for automated processing.\r\n+ * [Usage: Blender Integration](01_User_Guide/08_Usage_Blender.md) - How the optional Blender integration works for users.\r\n+ * [Output Structure](01_User_Guide/09_Output_Structure.md) - Description of the generated asset library structure.\r\n+ * [Docker](01_User_Guide/10_Docker.md) - Instructions for using the tool with Docker.\r\n+* **Developer Guide** - Technical information for developers contributing to the tool.\r\n+ * [Architecture](02_Developer_Guide/01_Architecture.md) - High-level system design and component overview.\r\n+ * [Codebase Structure](02_Developer_Guide/02_Codebase_Structure.md) - Detailed breakdown of project files and directories.\r\n+ * [Key Components](02_Developer_Guide/03_Key_Components.md) - In-depth explanation of major classes and modules.\r\n+ * [Configuration System and Presets](02_Developer_Guide/04_Configuration_System_and_Presets.md) - Technical details of configuration loading and preset structure.\r\n+ * [Processing Pipeline](02_Developer_Guide/05_Processing_Pipeline.md) - Step-by-step technical breakdown of the asset processing logic.\r\n+ * [GUI Internals](02_Developer_Guide/06_GUI_Internals.md) - Technical details of the GUI implementation (threading, signals, etc.).\r\n+ * [Monitor Internals](02_Developer_Guide/07_Monitor_Internals.md) - Technical details of the Directory Monitor implementation.\r\n+ * [Blender Integration Internals](02_Developer_Guide/08_Blender_Integration_Internals.md) - Technical details of Blender script execution and interaction.\r\n+ * [Development Workflow](02_Developer_Guide/09_Development_Workflow.md) - Guidance on contributing and modifying the codebase.\r\n+ * [Coding Conventions](02_Developer_Guide/10_Coding_Conventions.md) - Project's coding standards and practices.\r\n+ * [Debugging Notes](02_Developer_Guide/11_Debugging_Notes.md) - Advanced internal details, state management, error handling, and limitations.\n\\ No newline at end of file\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745506983704,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -3,9 +3,9 @@\n This documentation provides information about the Asset Processor Tool, covering both user-facing features and technical details for developers.\r\n \r\n ## Overview\r\n \r\n-This tool processes 3D asset source files (texture sets, models, etc., provided as ZIP archives or folders) into a standardized library format. It uses configurable presets to interpret different asset sources and automates tasks like file classification, image resizing, channel merging, and metadata generation.\r\n+This tool processes 3D asset source files (texture sets, models, etc., provided as ZIP, RAR, 7z archives, or folders) into a standardized library format. It uses configurable presets to interpret different asset sources and automates tasks like file classification, image resizing, channel merging, and metadata generation.\r\n \r\n The tool offers both a Graphical User Interface (GUI) for interactive use and a Command-Line Interface (CLI) for batch processing and scripting. It also includes a Directory Monitor for automated processing of assets dropped into a watched folder, and optional integration with Blender for automated material/nodegroup creation.\r\n \r\n This documentation strictly excludes details on environment setup, dependency installation, building the project, or deployment procedures, assuming familiarity with Python and the relevant libraries (OpenCV, NumPy, PySide6).\r\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745934668650,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -9,8 +9,14 @@\n The tool offers both a Graphical User Interface (GUI) for interactive use and a Command-Line Interface (CLI) for batch processing and scripting. It also includes a Directory Monitor for automated processing of assets dropped into a watched folder, and optional integration with Blender for automated material/nodegroup creation.\r\n \r\n This documentation strictly excludes details on environment setup, dependency installation, building the project, or deployment procedures, assuming familiarity with Python and the relevant libraries (OpenCV, NumPy, PySide6).\r\n \r\n+## Architecture and Codebase Summary\r\n+\r\n+For developers interested in contributing, the tool's architecture is designed around a **Core Processing Engine** (`asset_processor.py`) that handles the pipeline for single assets, supported by a **Configuration System** (`configuration.py` and `config.py` with `Presets/*.json`). Multiple interfaces are provided: a **Graphical User Interface** (`gui/`), a **Command-Line Interface** (`main.py`), and a **Directory Monitor** (`monitor.py`). Optional **Blender Integration** (`blenderscripts/`) is also included.\r\n+\r\n+The codebase is organized into key directories and files reflecting these components. The `gui/` directory contains all GUI-related code, `Presets/` holds configuration presets, and `blenderscripts/` contains scripts for Blender interaction. The core logic resides in files like `asset_processor.py`, `configuration.py`, `config.py`, `main.py`, and `monitor.py`. The processing pipeline involves steps such as file classification, map processing, channel merging, and metadata generation.\r\n+\r\n ## Table of Contents\r\n \r\n * [Overview](00_Overview.md) - This document, providing a high-level summary and table of contents.\r\n * **User Guide** - Information for end-users of the tool.\r\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494293096,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Asset Processor Tool Documentation\r\n\r\nThis documentation provides information about the Asset Processor Tool, covering both user-facing features and technical details for developers.\r\n\r\n## Overview\r\n\r\nThis tool processes 3D asset source files (texture sets, models, etc., provided as ZIP archives or folders) into a standardized library format. It uses configurable presets to interpret different asset sources and automates tasks like file classification, image resizing, channel merging, and metadata generation.\r\n\r\nThe tool offers both a Graphical User Interface (GUI) for interactive use and a Command-Line Interface (CLI) for batch processing and scripting. It also includes a Directory Monitor for automated processing of assets dropped into a watched folder, and optional integration with Blender for automated material/nodegroup creation.\r\n\r\nThis documentation strictly excludes details on environment setup, dependency installation, building the project, or deployment procedures, assuming familiarity with Python and the relevant libraries (OpenCV, NumPy, PySide6).\r\n\r\n## Table of Contents\r\n\r\n* [Overview](00_Overview.md)\r\n* **User Guide**\r\n * [Introduction](01_User_Guide/01_Introduction.md)\r\n * [Features](01_User_Guide/02_Features.md)\r\n * [Installation](01_User_Guide/03_Installation.md)\r\n * [Configuration and Presets](01_User_Guide/04_Configuration_and_Presets.md)\r\n * [Usage: GUI](01_User_Guide/05_Usage_GUI.md)\r\n * [Usage: CLI](01_User_Guide/06_Usage_CLI.md)\r\n * [Usage: Monitor](01_User_Guide/07_Usage_Monitor.md)\r\n * [Usage: Blender Integration](01_User_Guide/08_Usage_Blender.md)\r\n * [Output Structure](01_User_Guide/09_Output_Structure.md)\r\n * [Docker](01_User_Guide/10_Docker.md)\r\n* **Developer Guide**\r\n * [Architecture](02_Developer_Guide/01_Architecture.md)\r\n * [Codebase Structure](02_Developer_Guide/02_Codebase_Structure.md)\r\n * [Key Components](02_Developer_Guide/03_Key_Components.md)\r\n * [Configuration System and Presets](02_Developer_Guide/04_Configuration_System_and_Presets.md)\r\n * [Processing Pipeline](02_Developer_Guide/05_Processing_Pipeline.md)\r\n * [GUI Internals](02_Developer_Guide/06_GUI_Internals.md)\r\n * [Monitor Internals](02_Developer_Guide/07_Monitor_Internals.md)\r\n * [Blender Integration Internals](02_Developer_Guide/08_Blender_Integration_Internals.md)\r\n * [Development Workflow](02_Developer_Guide/09_Development_Workflow.md)\r\n * [Coding Conventions](02_Developer_Guide/10_Coding_Conventions.md)\r\n * [Debugging Notes](02_Developer_Guide/11_Debugging_Notes.md)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Documentation/01_User_Guide/01_Introduction.md.json
Normal file
18
.lh/Documentation/01_User_Guide/01_Introduction.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/01_User_Guide/01_Introduction.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494300926,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494300926,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# User Guide: Introduction\r\n\r\nThis document provides an introduction to the Asset Processor Tool for users.\r\n\r\n## Purpose\r\n\r\nThis tool processes 3D asset source files (texture sets, models, etc., provided as ZIP archives or folders) into a standardized library format. It uses configurable presets to interpret different asset sources and automates tasks like file classification, image resizing, channel merging, and metadata generation.\r\n\r\n## Interfaces\r\n\r\nThe tool offers both a Graphical User Interface (GUI) for interactive use and a Command-Line Interface (CLI) for batch processing and scripting. It also includes a Directory Monitor for automated processing of assets dropped into a watched folder, and optional integration with Blender for automated material/nodegroup creation.\r\n\r\n## Scope\r\n\r\nThis documentation focuses on how to use the Asset Processor Tool. It assumes familiarity with basic file system operations and the concepts of 3D assets like texture sets and models. Details on environment setup, dependency installation, building the project, or deployment procedures are covered in other sections or assume standard practices."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
26
.lh/Documentation/01_User_Guide/02_Features.md.json
Normal file
26
.lh/Documentation/01_User_Guide/02_Features.md.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/01_User_Guide/02_Features.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 2,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494307791,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745494347700,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -1,7 +1,7 @@\n # User Guide: Features\r\n \r\n-The Asset Processor Tool provides the following key features:\r\n+This document outlines the key features of the Asset Processor Tool.\r\n \r\n ## Core Processing & Classification\r\n \r\n * **Preset-Driven:** Uses JSON presets (`presets/`) to define rules for different asset suppliers (e.g., `Poliigon.json`).\r\n@@ -15,4 +15,30 @@\n * Applies bit-depth rules (`respect` source or `force_8bit`).\r\n * Saves maps in appropriate formats (JPG, PNG, EXR) based on complex rules involving map type (`FORCE_LOSSLESS_MAP_TYPES`), resolution (`RESOLUTION_THRESHOLD_FOR_JPG`), bit depth, and source format.\r\n * Calculates basic image statistics (Min/Max/Mean) for a reference resolution.\r\n * Calculates and stores the relative aspect ratio change string in metadata (e.g., `EVEN`, `X150`, `Y125`).\r\n+* **Channel Merging:** Combines channels from different maps into packed textures (e.g., NRMRGH) based on preset rules (`MAP_MERGE_RULES` in `config.py`).\r\n+* **Metadata Generation:** Creates a `metadata.json` file for each asset containing details about maps, category, archetype, aspect ratio change, processing settings, etc.\r\n+* **Output Organization:** Creates a clean, structured output directory (`<output_base>/<supplier>/<asset_name>/`).\r\n+* **Optimized Classification:** Pre-compiles regular expressions from presets for faster file identification.\r\n+\r\n+## Interface & Automation\r\n+\r\n+* **Dual Interface:** Provides both a user-friendly GUI and a powerful CLI.\r\n+* **Parallel Processing:** Utilizes multiple CPU cores for faster processing (configurable via `--workers` in CLI or GUI control).\r\n+* **Skip/Overwrite:** Can skip processing if the output already exists or force reprocessing (`--overwrite` flag / checkbox).\r\n+* **Directory Monitor:** Includes `monitor.py` script for automated processing of assets dropped into a watched folder.\r\n+* **Responsive GUI:** Uses background threads (`QThread`, `ProcessPoolExecutor`, `ThreadPoolExecutor`) to keep the UI responsive during intensive operations.\r\n+* **GUI Features:**\r\n+ * Drag-and-drop input (ZIPs / folders).\r\n+ * Integrated preset editor panel.\r\n+ * Configurable output directory field with browse button.\r\n+ * Enhanced live preview table showing predicted file status.\r\n+ * Toggleable preview mode (detailed file list vs simple asset list).\r\n+ * Toggleable log console panel.\r\n+ * Progress bar, cancellation button, clear queue button.\r\n+\r\n+## Integration\r\n+\r\n+* **Blender Integration:** Optionally runs Blender scripts (`create_nodegroups.py`, `create_materials.py`) after asset processing to automate node group and material creation in specified `.blend` files. Available via both CLI and GUI.\r\n+ * **GUI Controls:** Checkbox to enable/disable Blender integration and input fields with browse buttons for target `.blend` files.\r\n+* **Docker Support:** Includes a `Dockerfile` for containerized execution.\n\\ No newline at end of file\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745506993446,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -4,9 +4,9 @@\n \r\n ## Core Processing & Classification\r\n \r\n * **Preset-Driven:** Uses JSON presets (`presets/`) to define rules for different asset suppliers (e.g., `Poliigon.json`).\r\n-* **Multi-Asset Input Handling:** Correctly identifies and processes multiple distinct assets contained within a single input `.zip` or folder, creating separate outputs for each.\r\n+* **Multi-Asset Input Handling:** Correctly identifies and processes multiple distinct assets contained within a single input `.zip`, `.rar`, `.7z` archive, or folder, creating separate outputs for each.\r\n * **File Classification:** Automatically identifies map types (Color, Normal, Roughness, etc.), models, explicitly marked extra files, and unrecognised files based on preset rules.\r\n * **Variant Handling:** Map types listed in `RESPECT_VARIANT_MAP_TYPES` (in `config.py`, e.g., `\"COL\"`) always receive a numeric suffix (`-1`, `-2`, etc.). Numbering priority uses preset keyword order first, then alphabetical filename sorting as a tie-breaker. Other map types never receive a suffix.\r\n * **16-bit Prioritization:** Correctly identifies and prioritizes 16-bit variants defined in preset `bit_depth_variants` (e.g., `*_NRM16.tif`), ignoring the corresponding 8-bit version (marked as `Ignored` in GUI).\r\n * **Map Processing:**\r\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494307791,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# User Guide: Features\r\n\r\nThe Asset Processor Tool provides the following key features:\r\n\r\n## Core Processing & Classification\r\n\r\n* **Preset-Driven:** Uses JSON presets (`presets/`) to define rules for different asset suppliers (e.g., `Poliigon.json`).\r\n* **Multi-Asset Input Handling:** Correctly identifies and processes multiple distinct assets contained within a single input `.zip` or folder, creating separate outputs for each.\r\n* **File Classification:** Automatically identifies map types (Color, Normal, Roughness, etc.), models, explicitly marked extra files, and unrecognised files based on preset rules.\r\n * **Variant Handling:** Map types listed in `RESPECT_VARIANT_MAP_TYPES` (in `config.py`, e.g., `\"COL\"`) always receive a numeric suffix (`-1`, `-2`, etc.). Numbering priority uses preset keyword order first, then alphabetical filename sorting as a tie-breaker. Other map types never receive a suffix.\r\n * **16-bit Prioritization:** Correctly identifies and prioritizes 16-bit variants defined in preset `bit_depth_variants` (e.g., `*_NRM16.tif`), ignoring the corresponding 8-bit version (marked as `Ignored` in GUI).\r\n* **Map Processing:**\r\n * Resizes texture maps to configured resolutions (e.g., 4K, 2K, 1K), avoiding upscaling.\r\n * Handles Glossiness map inversion to Roughness.\r\n * Applies bit-depth rules (`respect` source or `force_8bit`).\r\n * Saves maps in appropriate formats (JPG, PNG, EXR) based on complex rules involving map type (`FORCE_LOSSLESS_MAP_TYPES`), resolution (`RESOLUTION_THRESHOLD_FOR_JPG`), bit depth, and source format.\r\n * Calculates basic image statistics (Min/Max/Mean) for a reference resolution.\r\n * Calculates and stores the relative aspect ratio change string in metadata (e.g., `EVEN`, `X150`, `Y125`).\r\n"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
22
.lh/Documentation/01_User_Guide/03_Installation.md.json
Normal file
22
.lh/Documentation/01_User_Guide/03_Installation.md.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/01_User_Guide/03_Installation.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 1,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494354036,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745507004268,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -7,8 +7,10 @@\n * Python 3.8 +\r\n * Required Python Packages (see `requirements.txt`):\r\n * `opencv-python` (image processing)\r\n * `numpy` (numerical operations)\r\n+ * `py7zr` (7z archive support)\r\n+ * `rarfile` (RAR archive support)\r\n * `PySide6` (for the GUI only)\r\n * `watchdog` (for the directory monitor)\r\n * Optional Python Packages:\r\n * `OpenEXR` (improved `.exr` handling, recommended if processing EXR sources)\r\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494354036,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# User Guide: Installation\r\n\r\nThis document details the requirements and steps for installing the Asset Processor Tool.\r\n\r\n## Requirements\r\n\r\n* Python 3.8 +\r\n* Required Python Packages (see `requirements.txt`):\r\n * `opencv-python` (image processing)\r\n * `numpy` (numerical operations)\r\n * `PySide6` (for the GUI only)\r\n * `watchdog` (for the directory monitor)\r\n* Optional Python Packages:\r\n * `OpenEXR` (improved `.exr` handling, recommended if processing EXR sources)\r\n* **Blender:** A working installation is required for optional Blender integration. Configure the path in `config.py` or ensure it's in the system PATH.\r\n\r\n## Installation Steps\r\n\r\n1. Navigate to the project root directory in your terminal.\r\n2. Install core dependencies using pip:\r\n\r\n ```bash\r\n pip install -r requirements.txt\r\n ```\r\n\r\n3. If you plan to use the GUI, ensure `PySide6` is installed. It might be included in `requirements.txt`, or install separately:\r\n\r\n ```bash\r\n pip install PySide6\r\n ```\r\n\r\n4. If you plan to use the directory monitor script, ensure `watchdog` is installed. It might be included in `requirements.txt`, or install separately:\r\n\r\n ```bash\r\n pip install watchdog"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/01_User_Guide/04_Configuration_and_Presets.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494363263,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494363263,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# User Guide: Configuration and Presets\r\n\r\nThis document explains how to configure the Asset Processor Tool and use presets.\r\n\r\n## Core Settings (`config.py`)\r\n\r\nThe tool's behavior is controlled by core settings defined in `config.py`. While primarily for developers, some settings are important for users to be aware of:\r\n\r\n* `OUTPUT_BASE_DIR`: The default root directory where processed assets will be saved.\r\n* `IMAGE_RESOULTIONS`: Defines the target resolutions for processed texture maps (e.g., 4K, 2K).\r\n* `BLENDER_EXECUTABLE_PATH`: The path to your Blender installation, required for optional Blender integration.\r\n* Other settings control aspects like default asset category, filename patterns, map merge rules, and output formats.\r\n\r\nThese settings can often be overridden via the GUI or CLI arguments.\r\n\r\n## Preset Files (`presets/*.json`)\r\n\r\nPreset files define supplier-specific rules for interpreting asset source files. They are crucial for the tool to correctly classify files and process assets from different sources.\r\n\r\n* Presets are located in the `presets/` directory.\r\n* Each preset is a JSON file named after the supplier (e.g., `Poliigon.json`).\r\n* Presets contain rules based on filename patterns and keywords to identify map types, models, and other files.\r\n* They also define how variants (like different resolutions or bit depths) are handled and how asset names and categories are determined from the source filename.\r\n\r\nWhen processing assets, you must specify which preset to use. The tool then loads the core settings from `config.py` and merges them with the rules from the selected preset to determine how to process the input.\r\n\r\nA template preset file (`presets/_template.json`) is provided as a base for creating new presets."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
42
.lh/Documentation/01_User_Guide/05_Usage_GUI.md.json
Normal file
42
.lh/Documentation/01_User_Guide/05_Usage_GUI.md.json
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/01_User_Guide/05_Usage_GUI.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 6,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494370671,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745502513671,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -21,9 +21,9 @@\n * **Preset Selector:** Choose the preset to use for *processing* the current queue.\r\n * **Output Directory:** Set the output path (defaults to `config.py`, use \"Browse...\")\r\n * **Drag and Drop Area:** Add asset `.zip` files or folders by dragging and dropping them here.\r\n * **Preview Table:** Shows queued assets. The mode depends on the \"View\" menu:\r\n- * **Detailed Preview (Default):** Lists all files, predicted status (`Mapped`, `Model`, `Extra`, `Unrecognised`, `Ignored`, `Error`), output name, etc., based on the selected *processing* preset. Rows are color-coded.\r\n+ * **Detailed Preview (Default):** Lists all files, predicted status (`Mapped`, `Model`, `Extra`, `Unrecognised`, `Ignored`, `Error`), output name, etc., based on the selected *processing* preset. Rows are color-coded by status and use alternating background colors per asset group for visual separation.\r\n * **Simple View (Preview Disabled):** Lists only top-level input asset paths.\r\n * **Progress Bar:** Shows overall processing progress.\r\n * **Blender Post-Processing:** Checkbox to enable Blender scripts. If enabled, shows fields and browse buttons for target `.blend` files (defaults from `config.py`).\r\n * **Options & Controls (Bottom):**\r\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745503625509,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -0,0 +1,35 @@\n+# User Guide: Usage - Graphical User Interface (GUI)\r\n+\r\n+This document explains how to use the Asset Processor Tool's Graphical User Interface.\r\n+\r\n+## Running the GUI\r\n+\r\n+From the project root directory, run the following command:\r\n+\r\n+```bash\r\n+python -m gui.main_window\r\n+```\r\n+\r\n+## Interface Overview\r\n+\r\n+* **Menu Bar:** The \"View\" menu allows you to toggle the visibility of the Log Console and the Detailed File Preview.\r\n+* **Preset Editor Panel (Left):**\r\n+ * **Optional Log Console:** Displays application logs (toggle via View menu).\r\n+ * **Preset List:** Create, delete, load, edit, and save presets. Select a preset here to edit its details below.\r\n+ * **Preset Editor Tabs:** Edit the details of the selected preset.\r\n+* **Processing Panel (Right):**\r\n+ * **Preset Selector:** Choose the preset to use for *processing* the current queue.\r\n+ * **Output Directory:** Set the output path (defaults to `config.py`, use \"Browse...\")\r\n+ * **Drag and Drop Area:** Add asset `.zip` files or folders by dragging and dropping them here.\r\n+ * **Preview Table:** Shows queued assets. The mode depends on the \"View\" menu:\r\n+ * **Detailed Preview (Default):** Lists all files, predicted status (`Mapped`, `Model`, `Extra`, `Unrecognised`, `Ignored`, `Error`), output name, etc., based on the selected *processing* preset. Text colors in the 'Status' and 'Additional Files' columns indicate the status of the individual file in that cell. Rows use alternating background colors per asset group for visual separation.\r\n+ * **Simple View (Preview Disabled):** Lists only top-level input asset paths.\r\n+* **Progress Bar:** Shows overall processing progress.\r\n+* **Blender Post-Processing:** Checkbox to enable Blender scripts. If enabled, shows fields and browse buttons for target `.blend` files (defaults from `config.py`).\r\n+ * **Options & Controls (Bottom):**\r\n+ * `Overwrite Existing`: Checkbox to force reprocessing.\r\n+ * `Workers`: Spinbox for concurrent processes.\r\n+ * `Clear Queue`: Button to clear the queue and preview.\r\n+ * `Start Processing`: Button to start processing the queue.\r\n+ * `Cancel`: Button to attempt stopping processing.\r\n+* **Status Bar:** Displays current status, errors, and completion messages.\n\\ No newline at end of file\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745505105261,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -21,9 +21,9 @@\n * **Preset Selector:** Choose the preset to use for *processing* the current queue.\r\n * **Output Directory:** Set the output path (defaults to `config.py`, use \"Browse...\")\r\n * **Drag and Drop Area:** Add asset `.zip` files or folders by dragging and dropping them here.\r\n * **Preview Table:** Shows queued assets. The mode depends on the \"View\" menu:\r\n- * **Detailed Preview (Default):** Lists all files, predicted status (`Mapped`, `Model`, `Extra`, `Unrecognised`, `Ignored`, `Error`), output name, etc., based on the selected *processing* preset. Text colors in the 'Status' and 'Additional Files' columns indicate the status of the individual file in that cell. Rows use alternating background colors per asset group for visual separation.\r\n+ * **Detailed Preview (Default):** Lists all files, predicted status (`Mapped`, `Model`, `Extra`, `Unrecognised`, `Ignored`, `Error`), output name, etc., based on the selected *processing* preset. Text colors are applied to cells based on the status of the individual file they represent. Rows use alternating background colors per asset group for visual separation.\r\n * **Simple View (Preview Disabled):** Lists only top-level input asset paths.\r\n * **Progress Bar:** Shows overall processing progress.\r\n * **Blender Post-Processing:** Checkbox to enable Blender scripts. If enabled, shows fields and browse buttons for target `.blend` files (defaults from `config.py`).\r\n * **Options & Controls (Bottom):**\r\n@@ -31,40 +31,5 @@\n * `Workers`: Spinbox for concurrent processes.\r\n * `Clear Queue`: Button to clear the queue and preview.\r\n * `Start Processing`: Button to start processing the queue.\r\n * `Cancel`: Button to attempt stopping processing.\r\n-* **Status Bar:** Displays current status, errors, and completion messages.\n-# User Guide: Usage - Graphical User Interface (GUI)\r\n-\r\n-This document explains how to use the Asset Processor Tool's Graphical User Interface.\r\n-\r\n-## Running the GUI\r\n-\r\n-From the project root directory, run the following command:\r\n-\r\n-```bash\r\n-python -m gui.main_window\r\n-```\r\n-\r\n-## Interface Overview\r\n-\r\n-* **Menu Bar:** The \"View\" menu allows you to toggle the visibility of the Log Console and the Detailed File Preview.\r\n-* **Preset Editor Panel (Left):**\r\n- * **Optional Log Console:** Displays application logs (toggle via View menu).\r\n- * **Preset List:** Create, delete, load, edit, and save presets. Select a preset here to edit its details below.\r\n- * **Preset Editor Tabs:** Edit the details of the selected preset.\r\n-* **Processing Panel (Right):**\r\n- * **Preset Selector:** Choose the preset to use for *processing* the current queue.\r\n- * **Output Directory:** Set the output path (defaults to `config.py`, use \"Browse...\")\r\n- * **Drag and Drop Area:** Add asset `.zip` files or folders by dragging and dropping them here.\r\n- * **Preview Table:** Shows queued assets. The mode depends on the \"View\" menu:\r\n- * **Detailed Preview (Default):** Lists all files, predicted status (`Mapped`, `Model`, `Extra`, `Unrecognised`, `Ignored`, `Error`), output name, etc., based on the selected *processing* preset. Rows are color-coded by status and use alternating background colors per asset group for visual separation.\r\n- * **Simple View (Preview Disabled):** Lists only top-level input asset paths.\r\n- * **Progress Bar:** Shows overall processing progress.\r\n- * **Blender Post-Processing:** Checkbox to enable Blender scripts. If enabled, shows fields and browse buttons for target `.blend` files (defaults from `config.py`).\r\n- * **Options & Controls (Bottom):**\r\n- * `Overwrite Existing`: Checkbox to force reprocessing.\r\n- * `Workers`: Spinbox for concurrent processes.\r\n- * `Clear Queue`: Button to clear the queue and preview.\r\n- * `Start Processing`: Button to start processing the queue.\r\n- * `Cancel`: Button to attempt stopping processing.\r\n * **Status Bar:** Displays current status, errors, and completion messages.\n\\ No newline at end of file\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745507709970,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -19,9 +19,9 @@\n * **Preset Editor Tabs:** Edit the details of the selected preset.\r\n * **Processing Panel (Right):**\r\n * **Preset Selector:** Choose the preset to use for *processing* the current queue.\r\n * **Output Directory:** Set the output path (defaults to `config.py`, use \"Browse...\")\r\n- * **Drag and Drop Area:** Add asset `.zip` files or folders by dragging and dropping them here.\r\n+ * **Drag and Drop Area:** Add asset `.zip`, `.rar`, `.7z` files, or folders by dragging and dropping them here.\r\n * **Preview Table:** Shows queued assets. The mode depends on the \"View\" menu:\r\n * **Detailed Preview (Default):** Lists all files, predicted status (`Mapped`, `Model`, `Extra`, `Unrecognised`, `Ignored`, `Error`), output name, etc., based on the selected *processing* preset. Text colors are applied to cells based on the status of the individual file they represent. Rows use alternating background colors per asset group for visual separation.\r\n * **Simple View (Preview Disabled):** Lists only top-level input asset paths.\r\n * **Progress Bar:** Shows overall processing progress.\r\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745511632131,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -14,15 +14,15 @@\n \r\n * **Menu Bar:** The \"View\" menu allows you to toggle the visibility of the Log Console and the Detailed File Preview.\r\n * **Preset Editor Panel (Left):**\r\n * **Optional Log Console:** Displays application logs (toggle via View menu).\r\n- * **Preset List:** Create, delete, load, edit, and save presets. Select a preset here to edit its details below.\r\n+ * **Preset List:** Create, delete, load, edit, and save presets. On startup, \"-- Select a Preset --\" is chosen by default. Select a specific preset from this list to load it into the editor below and enable the detailed file preview.\r\n * **Preset Editor Tabs:** Edit the details of the selected preset.\r\n * **Processing Panel (Right):**\r\n * **Preset Selector:** Choose the preset to use for *processing* the current queue.\r\n * **Output Directory:** Set the output path (defaults to `config.py`, use \"Browse...\")\r\n * **Drag and Drop Area:** Add asset `.zip`, `.rar`, `.7z` files, or folders by dragging and dropping them here.\r\n- * **Preview Table:** Shows queued assets. The mode depends on the \"View\" menu:\r\n+ * **Preview Table:** Shows queued assets. Initially, this area displays a message prompting you to select a preset. Once a preset is selected from the Preset List, the detailed file preview will load here. The mode of the preview depends on the \"View\" menu:\r\n * **Detailed Preview (Default):** Lists all files, predicted status (`Mapped`, `Model`, `Extra`, `Unrecognised`, `Ignored`, `Error`), output name, etc., based on the selected *processing* preset. Text colors are applied to cells based on the status of the individual file they represent. Rows use alternating background colors per asset group for visual separation.\r\n * **Simple View (Preview Disabled):** Lists only top-level input asset paths.\r\n * **Progress Bar:** Shows overall processing progress.\r\n * **Blender Post-Processing:** Checkbox to enable Blender scripts. If enabled, shows fields and browse buttons for target `.blend` files (defaults from `config.py`).\r\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745514273064,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -14,9 +14,9 @@\n \r\n * **Menu Bar:** The \"View\" menu allows you to toggle the visibility of the Log Console and the Detailed File Preview.\r\n * **Preset Editor Panel (Left):**\r\n * **Optional Log Console:** Displays application logs (toggle via View menu).\r\n- * **Preset List:** Create, delete, load, edit, and save presets. On startup, \"-- Select a Preset --\" is chosen by default. Select a specific preset from this list to load it into the editor below and enable the detailed file preview.\r\n+ * **Preset List:** Create, delete, load, edit, and save presets. On startup, the \"-- Select a Preset --\" item is explicitly selected. You must select a specific preset from this list to load it into the editor below, enable the detailed file preview, and enable the \"Start Processing\" button.\r\n * **Preset Editor Tabs:** Edit the details of the selected preset.\r\n * **Processing Panel (Right):**\r\n * **Preset Selector:** Choose the preset to use for *processing* the current queue.\r\n * **Output Directory:** Set the output path (defaults to `config.py`, use \"Browse...\")\r\n@@ -29,7 +29,7 @@\n * **Options & Controls (Bottom):**\r\n * `Overwrite Existing`: Checkbox to force reprocessing.\r\n * `Workers`: Spinbox for concurrent processes.\r\n * `Clear Queue`: Button to clear the queue and preview.\r\n- * `Start Processing`: Button to start processing the queue.\r\n+ * `Start Processing`: Button to start processing the queue. This button is disabled until a valid preset is selected from the Preset List.\r\n * `Cancel`: Button to attempt stopping processing.\r\n * **Status Bar:** Displays current status, errors, and completion messages.\n\\ No newline at end of file\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494370671,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# User Guide: Usage - Graphical User Interface (GUI)\r\n\r\nThis document explains how to use the Asset Processor Tool's Graphical User Interface.\r\n\r\n## Running the GUI\r\n\r\nFrom the project root directory, run the following command:\r\n\r\n```bash\r\npython -m gui.main_window\r\n```\r\n\r\n## Interface Overview\r\n\r\n* **Menu Bar:** The \"View\" menu allows you to toggle the visibility of the Log Console and the Detailed File Preview.\r\n* **Preset Editor Panel (Left):**\r\n * **Optional Log Console:** Displays application logs (toggle via View menu).\r\n * **Preset List:** Create, delete, load, edit, and save presets. Select a preset here to edit its details below.\r\n * **Preset Editor Tabs:** Edit the details of the selected preset.\r\n* **Processing Panel (Right):**\r\n * **Preset Selector:** Choose the preset to use for *processing* the current queue.\r\n * **Output Directory:** Set the output path (defaults to `config.py`, use \"Browse...\")\r\n * **Drag and Drop Area:** Add asset `.zip` files or folders by dragging and dropping them here.\r\n * **Preview Table:** Shows queued assets. The mode depends on the \"View\" menu:\r\n * **Detailed Preview (Default):** Lists all files, predicted status (`Mapped`, `Model`, `Extra`, `Unrecognised`, `Ignored`, `Error`), output name, etc., based on the selected *processing* preset. Rows are color-coded.\r\n * **Simple View (Preview Disabled):** Lists only top-level input asset paths.\r\n * **Progress Bar:** Shows overall processing progress.\r\n * **Blender Post-Processing:** Checkbox to enable Blender scripts. If enabled, shows fields and browse buttons for target `.blend` files (defaults from `config.py`).\r\n * **Options & Controls (Bottom):**\r\n * `Overwrite Existing`: Checkbox to force reprocessing.\r\n * `Workers`: Spinbox for concurrent processes.\r\n * `Clear Queue`: Button to clear the queue and preview.\r\n * `Start Processing`: Button to start processing the queue.\r\n * `Cancel`: Button to attempt stopping processing.\r\n* **Status Bar:** Displays current status, errors, and completion messages."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
22
.lh/Documentation/01_User_Guide/06_Usage_CLI.md.json
Normal file
22
.lh/Documentation/01_User_Guide/06_Usage_CLI.md.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/01_User_Guide/06_Usage_CLI.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 1,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494377557,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745507624965,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -11,9 +11,9 @@\n ```\r\n \r\n ## Arguments\r\n \r\n-* `INPUT_PATH`: One or more paths to input `.zip` files or folders.\r\n+* `INPUT_PATH`: One or more paths to input `.zip`, `.rar`, `.7z` files, or folders.\r\n \r\n ## Options\r\n \r\n * `-p PRESET`, `--preset PRESET`: **(Required)** Name of the preset (e.g., `Poliigon`).\r\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494377557,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# User Guide: Usage - Command-Line Interface (CLI)\r\n\r\nThis document explains how to use the Asset Processor Tool's Command-Line Interface.\r\n\r\n## Running the CLI\r\n\r\nFrom the project root directory, run the following command:\r\n\r\n```bash\r\npython main.py [OPTIONS] INPUT_PATH [INPUT_PATH ...]\r\n```\r\n\r\n## Arguments\r\n\r\n* `INPUT_PATH`: One or more paths to input `.zip` files or folders.\r\n\r\n## Options\r\n\r\n* `-p PRESET`, `--preset PRESET`: **(Required)** Name of the preset (e.g., `Poliigon`).\r\n* `-o OUTPUT_DIR`, `--output-dir OUTPUT_DIR`: Override `OUTPUT_BASE_DIR` from `config.py`.\r\n* `-w WORKERS`, `--workers WORKERS`: Number of parallel processes (default: auto).\r\n* `--overwrite`: Force reprocessing and overwrite existing output.\r\n* `-v`, `--verbose`: Enable detailed DEBUG level logging.\r\n* `--nodegroup-blend NODEGROUP_BLEND`: Path to `.blend` for node groups. Triggers script if provided. Overrides `config.py`.\r\n* `--materials-blend MATERIALS_BLEND`: Path to `.blend` for materials. Triggers script if provided. Overrides `config.py`.\r\n\r\n## Example\r\n\r\n```bash\r\npython main.py \"C:/Downloads/WoodFine001.zip\" -p Poliigon -o \"G:/Assets/Processed\" --workers 4 --overwrite --nodegroup-blend \"G:/Blender/Libraries/NodeGroups.blend\" --materials-blend \"G:/Blender/Libraries/Materials.blend\""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
22
.lh/Documentation/01_User_Guide/07_Usage_Monitor.md.json
Normal file
22
.lh/Documentation/01_User_Guide/07_Usage_Monitor.md.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/01_User_Guide/07_Usage_Monitor.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 1,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494384510,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745507755122,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -11,9 +11,9 @@\n ```\r\n \r\n ## Functionality\r\n \r\n-The monitor script uses the `watchdog` library to continuously monitor a specified input directory for new `.zip` files. When a new `.zip` file is detected, it expects the filename to follow the format `[preset]_filename.zip`. It extracts the preset name from the filename and automatically processes the asset using that preset. After processing, the source `.zip` file is moved to either a 'processed' directory (on success or skip) or an 'error' directory (on failure or invalid preset).\r\n+The monitor script uses the `watchdog` library to continuously monitor a specified input directory for new `.zip`, `.rar`, or `.7z` files. When a new supported archive file is detected, it expects the filename to follow the format `[preset]_filename.zip`, `[preset]_filename.rar`, or `[preset]_filename.7z`. It extracts the preset name from the filename and automatically processes the asset using that preset. After processing, the source archive file is moved to either a 'processed' directory (on success or skip) or an 'error' directory (on failure or invalid preset).\r\n \r\n **Note:** The directory monitor does *not* currently support optional Blender script execution (this is only available via the CLI or GUI).\r\n \r\n ## Configuration (Environment Variables)\r\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494384510,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# User Guide: Usage - Directory Monitor (Automated Processing)\r\n\r\nThis document explains how to use the Asset Processor Tool's Directory Monitor for automated processing.\r\n\r\n## Running the Monitor\r\n\r\nFrom the project root directory, run the following command:\r\n\r\n```bash\r\npython monitor.py\r\n```\r\n\r\n## Functionality\r\n\r\nThe monitor script uses the `watchdog` library to continuously monitor a specified input directory for new `.zip` files. When a new `.zip` file is detected, it expects the filename to follow the format `[preset]_filename.zip`. It extracts the preset name from the filename and automatically processes the asset using that preset. After processing, the source `.zip` file is moved to either a 'processed' directory (on success or skip) or an 'error' directory (on failure or invalid preset).\r\n\r\n**Note:** The directory monitor does *not* currently support optional Blender script execution (this is only available via the CLI or GUI).\r\n\r\n## Configuration (Environment Variables)\r\n\r\nThe monitor's behavior is configured using environment variables:\r\n\r\n* `INPUT_DIR`: The directory to monitor (default: `/data/input`).\r\n* `OUTPUT_DIR`: The base output directory (default: `/data/output`).\r\n* `PROCESSED_DIR`: Directory for successful source ZIPs (default: `/data/processed`).\r\n* `ERROR_DIR`: Directory for failed source ZIPs (default: `/data/error`).\r\n* `LOG_LEVEL`: Logging verbosity (`INFO`, `DEBUG`) (default: `INFO`).\r\n* `POLL_INTERVAL`: Check frequency (seconds) (default: `5`).\r\n* `PROCESS_DELAY`: Delay before processing detected file (seconds) (default: `2`).\r\n* `NUM_WORKERS`: Number of parallel workers (default: auto).\r\n\r\n## Output\r\n\r\nThe monitor logs messages to the console. It creates processed assets in the `OUTPUT_DIR` and moves the source `.zip` file as described above."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Documentation/01_User_Guide/08_Usage_Blender.md.json
Normal file
18
.lh/Documentation/01_User_Guide/08_Usage_Blender.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/01_User_Guide/08_Usage_Blender.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494392489,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494392489,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# User Guide: Usage - Blender Integration\r\n\r\nThis document explains how to use the optional Blender integration feature of the Asset Processor Tool.\r\n\r\n## Overview\r\n\r\nThe Asset Processor Tool can optionally run Blender scripts after processing assets. These scripts automate the creation of PBR node groups and materials in specified `.blend` files, linking to the processed textures. This feature is available when using the tool via the Command-Line Interface (CLI) or the Graphical User Interface (GUI).\r\n\r\n## How it Works (User Perspective)\r\n\r\nWhen the Blender integration is enabled and configured, the Asset Processor Tool will:\r\n\r\n1. Process the input assets and generate the output files, including the `metadata.json` file for each asset.\r\n2. Execute Blender in the background using the specified Blender executable path.\r\n3. Run the `blenderscripts/create_nodegroups.py` script within Blender, passing the path to the processed asset's output directory and the target `.blend` file for node groups. This script reads the `metadata.json` and creates/updates PBR node groups in the target `.blend` file.\r\n4. If configured, execute the `blenderscripts/create_materials.py` script within Blender, passing the path to the processed asset's output directory, the target `.blend` file for materials, and the `.blend` file containing the node groups. This script reads the `metadata.json`, creates/updates materials in the target materials `.blend` file, and links them to the node groups created in the node group `.blend` file.\r\n\r\n## Enabling and Configuring Blender Integration\r\n\r\n### In the GUI\r\n\r\n* Locate the \"Blender Post-Processing\" section in the Processing Panel.\r\n* Check the box to enable the Blender integration.\r\n* Input fields and browse buttons will appear for specifying the target `.blend` files for Node Groups and Materials. These fields will default to the paths configured in `config.py`.\r\n\r\n### In the CLI\r\n\r\n* Use the `--nodegroup-blend` option followed by the path to the target `.blend` file for node groups.\r\n* Use the `--materials-blend` option followed by the path to the target `.blend` file for materials.\r\n\r\nProviding either of these options in the CLI will trigger the respective Blender script execution after asset processing. These command-line options override the default paths set in `config.py`.\r\n\r\n## Requirements\r\n\r\n* A working installation of Blender.\r\n* The path to the Blender executable configured in `config.py` or accessible in your system's PATH.\r\n* For the material creation script, the target `.blend` file must contain a template material named `Template_PBRMaterial` with a Group node labeled `PLACEHOLDER_NODE_LABEL` (as defined in `blenderscripts/create_materials.py`)."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Documentation/01_User_Guide/09_Output_Structure.md.json
Normal file
18
.lh/Documentation/01_User_Guide/09_Output_Structure.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/01_User_Guide/09_Output_Structure.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494407593,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494407593,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# User Guide: Output Structure\r\n\r\nThis document describes the directory structure and contents of the processed assets generated by the Asset Processor Tool.\r\n\r\nProcessed assets are saved to: `<output_base_directory>/<supplier_name>/<asset_name>/`\r\n\r\n* `<output_base_directory>`: The base output directory configured in `config.py` or specified via CLI/GUI.\r\n* `<supplier_name>`: The name of the asset supplier, determined from the preset used.\r\n* `<asset_name>`: The name of the processed asset, determined from the source filename based on preset rules.\r\n\r\n## Contents of Each Asset Directory\r\n\r\nEach asset directory contains the following:\r\n\r\n* Processed texture maps (e.g., `AssetName_Color_4K.png`, `AssetName_NRM_2K.exr`). These are the resized, format-converted, and bit-depth adjusted texture files.\r\n* Merged texture maps (e.g., `AssetName_NRMRGH_4K.png`). These are maps created by combining channels from different source maps based on the configured merge rules.\r\n* Model files (if present in the source asset).\r\n* `metadata.json`: A JSON file containing detailed information about the asset and the processing that was performed. This includes details about the maps, resolutions, formats, bit depths, merged map details, calculated image statistics, aspect ratio change information, asset category and archetype, the source preset used, and a list of ignored source files. This file is intended for use by downstream tools or scripts (like the Blender integration scripts).\r\n* `Extra/` (subdirectory): Contains source files that were not classified as maps or models but were explicitly marked to be moved to the extra directory based on preset rules (e.g., previews, documentation files).\r\n* `Unrecognised/` (subdirectory): Contains source files that were not classified as maps, models, or explicitly marked as extra, and were not ignored.\r\n* `Ignored/` (subdirectory): Contains source files that were explicitly ignored during processing (e.g., an 8-bit Normal map when a 16-bit variant exists and is prioritized)."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Documentation/01_User_Guide/10_Docker.md.json
Normal file
18
.lh/Documentation/01_User_Guide/10_Docker.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/01_User_Guide/10_Docker.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494414023,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494414023,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# User Guide: Docker\r\n\r\nThis document explains how to use the Asset Processor Tool with Docker.\r\n\r\n## Overview\r\n\r\nA `Dockerfile` and `requirements-docker.txt` are provided to allow you to build and run the Asset Processor Tool in a containerized environment. This is primarily intended for CLI or monitor usage.\r\n\r\n## Building the Docker Image\r\n\r\nFrom the project root directory, run the following command to build the Docker image:\r\n\r\n```bash\r\ndocker build -t asset-processor-tool .\r\n```\r\n\r\nThis command builds a Docker image named `asset-processor-tool` using the `Dockerfile` in the current directory.\r\n\r\n## Running the Docker Container\r\n\r\nYou can run the Docker container using standard Docker commands. You will typically need to mount volumes to make your input assets and desired output directory accessible within the container.\r\n\r\nHere is an example run command (adjust volumes as needed):\r\n\r\n```bash\r\ndocker run -v /path/to/your/inputs:/data/input -v /path/to/your/outputs:/data/output asset-processor-tool python main.py /data/input/YourAsset.zip -p YourPreset\r\n```\r\n\r\n* `-v /path/to/your/inputs:/data/input`: This mounts your local input directory (`/path/to/your/inputs`) to the `/data/input` directory inside the container.\r\n* `-v /path/to/your/outputs:/data/output`: This mounts your local output directory (`/path/to/your/outputs`) to the `/data/output` directory inside the container.\r\n* `asset-processor-tool`: The name of the Docker image to run.\r\n* `python main.py /data/input/YourAsset.zip -p YourPreset`: The command to execute inside the container. This example runs the CLI with a specific input file and preset, using the mounted input and output directories.\r\n\r\nAdjust the input file path (`/data/input/YourAsset.zip`) and preset name (`YourPreset`) as needed for your specific use case. You can also adapt the command to run the `monitor.py` script within the container."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
34
.lh/Documentation/02_Developer_Guide/01_Architecture.md.json
Normal file
34
.lh/Documentation/02_Developer_Guide/01_Architecture.md.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/02_Developer_Guide/01_Architecture.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 4,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494423952,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745933699117,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -11,18 +11,19 @@\n 3. **Multiple Interfaces:** Provides different ways to interact with the tool:\r\n * Graphical User Interface (GUI)\r\n * Command-Line Interface (CLI)\r\n * Directory Monitor for automated processing.\r\n+These interfaces now exchange significantly more detailed data structures containing information about each file and asset set being processed.\r\n 4. **Optional Integration:** Includes scripts and logic for integrating with external software, specifically Blender, to automate material and node group creation.\r\n \r\n ## Core Components\r\n \r\n * `config.py`: Defines core, global settings and constants.\r\n * `Presets/*.json`: Supplier-specific JSON files defining rules for file interpretation and processing.\r\n * `configuration.py` (`Configuration` class): Loads `config.py` settings and merges them with a selected preset, pre-compiling regex patterns for efficiency.\r\n-* `asset_processor.py` (`AssetProcessor` class): Contains the core logic for processing a *single* asset through the defined pipeline steps.\r\n-* `main.py`: The entry point for the CLI, handling argument parsing, logging, parallel processing orchestration, and triggering Blender scripts.\r\n-* `gui/`: Directory containing modules for the GUI, built with PySide6.\r\n+* `asset_processor.py` (`AssetProcessor` class): Contains the core logic for processing a *single* asset through the defined pipeline steps. This component now works with enhanced data structures.\r\n+* `main.py`: The entry point for the CLI, handling argument parsing, logging, parallel processing orchestration, and triggering Blender scripts. It exchanges enhanced data structures with the core processor and GUI.\r\n+* `gui/`: Directory containing modules for the GUI, built with PySide6. These modules handle and utilize the richer data structures received from the core processing engine.\r\n * `monitor.py`: Implements the directory monitoring feature using `watchdog`.\r\n * `blenderscripts/`: Contains Python scripts designed to be executed *within* Blender for post-processing tasks.\r\n \r\n ## Processing Pipeline (Simplified)\r\n@@ -39,5 +40,5 @@\n 8. Organization of processed files into the final output structure.\r\n 9. Cleanup of the temporary workspace.\r\n 10. (Optional) Execution of Blender scripts for post-processing.\r\n \r\n-This architecture allows for a modular design, separating configuration, core processing logic, and different interfaces. Parallel processing is utilized for efficiency, and background threads keep the GUI responsive.\n\\ No newline at end of file\n+This architecture allows for a modular design, separating configuration, core processing logic, and different interfaces. The data structures flowing through this pipeline now carry significantly more detailed information about individual files and asset sets. Parallel processing is utilized for efficiency, and background threads keep the GUI responsive.\n\\ No newline at end of file\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745933964077,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -11,19 +11,19 @@\n 3. **Multiple Interfaces:** Provides different ways to interact with the tool:\r\n * Graphical User Interface (GUI)\r\n * Command-Line Interface (CLI)\r\n * Directory Monitor for automated processing.\r\n-These interfaces now exchange significantly more detailed data structures containing information about each file and asset set being processed.\r\n+These interfaces exchange data structures containing information about each file and asset set being processed.\r\n 4. **Optional Integration:** Includes scripts and logic for integrating with external software, specifically Blender, to automate material and node group creation.\r\n \r\n ## Core Components\r\n \r\n * `config.py`: Defines core, global settings and constants.\r\n * `Presets/*.json`: Supplier-specific JSON files defining rules for file interpretation and processing.\r\n * `configuration.py` (`Configuration` class): Loads `config.py` settings and merges them with a selected preset, pre-compiling regex patterns for efficiency.\r\n-* `asset_processor.py` (`AssetProcessor` class): Contains the core logic for processing a *single* asset through the defined pipeline steps. This component now works with enhanced data structures.\r\n-* `main.py`: The entry point for the CLI, handling argument parsing, logging, parallel processing orchestration, and triggering Blender scripts. It exchanges enhanced data structures with the core processor and GUI.\r\n-* `gui/`: Directory containing modules for the GUI, built with PySide6. These modules handle and utilize the richer data structures received from the core processing engine.\r\n+* `asset_processor.py` (`AssetProcessor` class): Contains the core logic for processing a *single* asset through the defined pipeline steps. This component works with data structures containing detailed information about the asset and its files.\r\n+* `main.py`: The entry point for the CLI, handling argument parsing, logging, parallel processing orchestration, and triggering Blender scripts. It exchanges data structures with the core processor and GUI.\r\n+* `gui/`: Directory containing modules for the GUI, built with PySide6. These modules handle and utilize the data structures received from the core processing engine.\r\n * `monitor.py`: Implements the directory monitoring feature using `watchdog`.\r\n * `blenderscripts/`: Contains Python scripts designed to be executed *within* Blender for post-processing tasks.\r\n \r\n ## Processing Pipeline (Simplified)\r\n@@ -40,5 +40,5 @@\n 8. Organization of processed files into the final output structure.\r\n 9. Cleanup of the temporary workspace.\r\n 10. (Optional) Execution of Blender scripts for post-processing.\r\n \r\n-This architecture allows for a modular design, separating configuration, core processing logic, and different interfaces. The data structures flowing through this pipeline now carry significantly more detailed information about individual files and asset sets. Parallel processing is utilized for efficiency, and background threads keep the GUI responsive.\n\\ No newline at end of file\n+This architecture allows for a modular design, separating configuration, core processing logic, and different interfaces. The data structures flowing through this pipeline carry detailed information about individual files and asset sets. Parallel processing is utilized for efficiency, and background threads keep the GUI responsive.\n\\ No newline at end of file\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745934361165,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -20,9 +20,9 @@\n * `config.py`: Defines core, global settings and constants.\r\n * `Presets/*.json`: Supplier-specific JSON files defining rules for file interpretation and processing.\r\n * `configuration.py` (`Configuration` class): Loads `config.py` settings and merges them with a selected preset, pre-compiling regex patterns for efficiency.\r\n * `asset_processor.py` (`AssetProcessor` class): Contains the core logic for processing a *single* asset through the defined pipeline steps. This component works with data structures containing detailed information about the asset and its files.\r\n-* `main.py`: The entry point for the CLI, handling argument parsing, logging, parallel processing orchestration, and triggering Blender scripts. It exchanges data structures with the core processor and GUI.\r\n+* `main.py`: The entry point for the Command-Line Interface (CLI). It handles argument parsing, logging, parallel processing orchestration, and triggering Blender scripts. It orchestrates the processing of multiple assets by interacting with the `AssetProcessor` for individual assets and manages the overall CLI execution flow.\r\n * `gui/`: Directory containing modules for the GUI, built with PySide6. These modules handle and utilize the data structures received from the core processing engine.\r\n * `monitor.py`: Implements the directory monitoring feature using `watchdog`.\r\n * `blenderscripts/`: Contains Python scripts designed to be executed *within* Blender for post-processing tasks.\r\n \r\n@@ -40,5 +40,7 @@\n 8. Organization of processed files into the final output structure.\r\n 9. Cleanup of the temporary workspace.\r\n 10. (Optional) Execution of Blender scripts for post-processing.\r\n \r\n-This architecture allows for a modular design, separating configuration, core processing logic, and different interfaces. The data structures flowing through this pipeline carry detailed information about individual files and asset sets. Parallel processing is utilized for efficiency, and background threads keep the GUI responsive.\n\\ No newline at end of file\n+This architecture allows for a modular design, separating configuration, core processing logic, and different interfaces. The data structures flowing through this pipeline carry detailed information about individual files and asset sets. Examples include lists of input file paths, configuration objects, dictionaries summarizing processing outcomes, and detailed lists of file predictions. Parallel processing is utilized for efficiency, and background threads keep the GUI responsive.\r\n+\r\n+**Note on Data Passing:** Major changes to the data passing mechanisms between the GUI, Main (CLI orchestration), and `AssetProcessor` modules are currently being planned. These changes are expected to involve new data structures and updated interaction patterns to convey detailed specifications for datasets/asset-sets and processing instructions for individual files. The documentation in this section, particularly regarding data flow, will require significant review and updates once the plan for these changes is finalized.\n\\ No newline at end of file\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745934375142,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -21,9 +21,9 @@\n * `Presets/*.json`: Supplier-specific JSON files defining rules for file interpretation and processing.\r\n * `configuration.py` (`Configuration` class): Loads `config.py` settings and merges them with a selected preset, pre-compiling regex patterns for efficiency.\r\n * `asset_processor.py` (`AssetProcessor` class): Contains the core logic for processing a *single* asset through the defined pipeline steps. This component works with data structures containing detailed information about the asset and its files.\r\n * `main.py`: The entry point for the Command-Line Interface (CLI). It handles argument parsing, logging, parallel processing orchestration, and triggering Blender scripts. It orchestrates the processing of multiple assets by interacting with the `AssetProcessor` for individual assets and manages the overall CLI execution flow.\r\n-* `gui/`: Directory containing modules for the GUI, built with PySide6. These modules handle and utilize the data structures received from the core processing engine.\r\n+* `gui/`: Directory containing modules for the Graphical User Interface (GUI), built with PySide6. The GUI interacts with the core processing logic indirectly via dedicated handler classes (`ProcessingHandler`, `PredictionHandler`) running in separate threads. Data structures, such as input paths, configuration details, processing progress updates, and file prediction results, are passed between the GUI, these handlers, and the `AssetProcessor` using thread-safe mechanisms like Qt signals and slots.\r\n * `monitor.py`: Implements the directory monitoring feature using `watchdog`.\r\n * `blenderscripts/`: Contains Python scripts designed to be executed *within* Blender for post-processing tasks.\r\n \r\n ## Processing Pipeline (Simplified)\r\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494423952,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Developer Guide: Architecture\r\n\r\nThis document provides a high-level overview of the Asset Processor Tool's architecture and core components for developers.\r\n\r\n## High-Level Architecture\r\n\r\nThe Asset Processor Tool is designed to process 3D asset source files into a standardized library format. Its high-level architecture consists of:\r\n\r\n1. **Core Processing Engine (`AssetProcessor`):** The central component responsible for orchestrating the asset processing pipeline for a single input asset.\r\n2. **Configuration System (`Configuration`):** Handles loading core settings and merging them with supplier-specific rules defined in JSON presets.\r\n3. **Multiple Interfaces:** Provides different ways to interact with the tool:\r\n * Graphical User Interface (GUI)\r\n * Command-Line Interface (CLI)\r\n * Directory Monitor for automated processing.\r\n4. **Optional Integration:** Includes scripts and logic for integrating with external software, specifically Blender, to automate material and node group creation.\r\n\r\n## Core Components\r\n\r\n* `config.py`: Defines core, global settings and constants.\r\n* `Presets/*.json`: Supplier-specific JSON files defining rules for file interpretation and processing.\r\n* `configuration.py` (`Configuration` class): Loads `config.py` settings and merges them with a selected preset, pre-compiling regex patterns for efficiency.\r\n* `asset_processor.py` (`AssetProcessor` class): Contains the core logic for processing a *single* asset through the defined pipeline steps.\r\n* `main.py`: The entry point for the CLI, handling argument parsing, logging, parallel processing orchestration, and triggering Blender scripts.\r\n* `gui/`: Directory containing modules for the GUI, built with PySide6.\r\n* `monitor.py`: Implements the directory monitoring feature using `watchdog`.\r\n* `blenderscripts/`: Contains Python scripts designed to be executed *within* Blender for post-processing tasks.\r\n\r\n## Processing Pipeline (Simplified)\r\n\r\nThe core processing engine (`AssetProcessor`) executes a series of steps for each asset:\r\n\r\n1. Extraction of input to a temporary workspace.\r\n2. Classification of files (map, model, extra, ignored, unrecognised) using preset rules.\r\n3. Determination of base metadata (asset name, category, archetype).\r\n4. Skip check if output exists and overwrite is not forced.\r\n5. Processing of maps (resize, format/bit depth conversion, inversion, stats calculation).\r\n6. Merging of channels based on rules.\r\n7. Generation of `metadata.json` file.\r\n8. Organization of processed files into the final output structure.\r\n9. Cleanup of the temporary workspace.\r\n10. (Optional) Execution of Blender scripts for post-processing.\r\n\r\nThis architecture allows for a modular design, separating configuration, core processing logic, and different interfaces. Parallel processing is utilized for efficiency, and background threads keep the GUI responsive."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/02_Developer_Guide/04_Configuration_System_and_Presets.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 1,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494552943,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745934423187,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -38,5 +38,7 @@\n * `source_naming_convention`: Rules for extracting the base asset name and potentially the archetype from source filenames or directory structures (e.g., using separators and indices).\r\n * `asset_category_rules`: Keywords or patterns used to determine the asset category (e.g., identifying `\"Decal\"` based on keywords).\r\n * `archetype_rules`: Keywords or patterns used to determine the asset archetype (e.g., identifying `\"Wood\"` or `\"Metal\"`).\r\n \r\n-Careful definition of these patterns and rules, especially the regex in `map_type_mapping`, `bit_depth_variants`, `model_patterns`, and `move_to_extra_patterns`, is essential for correct asset processing.\n\\ No newline at end of file\n+Careful definition of these patterns and rules, especially the regex in `map_type_mapping`, `bit_depth_variants`, `model_patterns`, and `move_to_extra_patterns`, is essential for correct asset processing.\r\n+\r\n+**Note on Data Passing:** As mentioned in the Architecture documentation, major changes to the data passing mechanisms between the GUI, Main (CLI orchestration), and `AssetProcessor` modules are currently being planned. The descriptions of how configuration data is handled and passed within this document reflect the current state and will require review and updates once the plan for these changes is finalized.\n\\ No newline at end of file\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494552943,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Developer Guide: Configuration System and Presets\r\n\r\nThis document provides technical details about the configuration system and the structure of preset files for developers working on the Asset Processor Tool.\r\n\r\n## Configuration Flow\r\n\r\nThe tool utilizes a two-tiered configuration system:\r\n\r\n1. **Core Settings (`config.py`):** This Python module defines global default settings, constants, and core rules that apply generally across different asset sources. Examples include default output paths, standard image resolutions, map merge rules, output format rules, Blender executable paths, and default map types.\r\n2. **Preset Files (`Presets/*.json`):** These JSON files define supplier-specific rules and overrides. They contain patterns (often regular expressions) to interpret filenames, classify map types, handle variants, define naming conventions, and specify other source-specific behaviors.\r\n\r\n## `Configuration` Class (`configuration.py`)\r\n\r\nThe `Configuration` class is responsible for loading, merging, and preparing the configuration settings for use by the `AssetProcessor`.\r\n\r\n* **Initialization:** An instance is created with a specific `preset_name`.\r\n* **Loading:**\r\n * It loads the core settings from `config.py` using `importlib.util`.\r\n * It loads the specified preset JSON file from the `Presets/` directory.\r\n* **Merging:** The loaded core settings and preset rules are merged into a single configuration object accessible via instance attributes. Preset values generally override core settings where applicable.\r\n* **Validation (`_validate_configs`):** Performs basic structural validation on the loaded settings, checking for the presence of required keys and basic data types (e.g., ensuring `map_type_mapping` is a list of dictionaries).\r\n* **Regex Compilation (`_compile_regex_patterns`):** A crucial step for performance. It iterates through the regex patterns defined in the preset (for extra files, models, bit depth variants, map keywords) and compiles them using `re.compile` (mostly case-insensitive). These compiled regex objects are stored as instance attributes (e.g., `self.compiled_map_keyword_regex`) for fast matching during file classification. It uses a helper (`_fnmatch_to_regex`) for basic wildcard (`*`, `?`) conversion in patterns.\r\n\r\nAn instance of `Configuration` is created within each worker process (`main.process_single_asset_wrapper`) to ensure that each concurrently processed asset uses the correct, isolated configuration based on the specified preset.\r\n\r\n## Preset File Structure (`Presets/*.json`)\r\n\r\nPreset files are the primary way to adapt the tool to new asset sources. Developers should use `Presets/_template.json` as a starting point. Key fields include:\r\n\r\n* `supplier_name`: The name of the asset source (e.g., `\"Poliigon\"`). Used for output directory naming.\r\n* `map_type_mapping`: A list of dictionaries, each mapping source filename patterns/keywords to a standard internal map type (defined in `config.py`).\r\n * `target_type`: The standard internal map type (e.g., `\"COL\"`, `\"NRM\"`).\r\n * `keywords`: A list of filename patterns (regex or fnmatch-style wildcards) used to identify this map type. The order of keywords within this list, and the order of dictionaries in the `map_type_mapping` list, determines the priority for assigning variant suffixes (`-1`, `-2`, etc.) when multiple files match the same `target_type`.\r\n* `bit_depth_variants`: A dictionary mapping standard map types (e.g., `\"NRM\"`) to a pattern identifying its high bit-depth variant (e.g., `\"*_NRM16*.tif\"`). Files matching these patterns are prioritized over their standard counterparts.\r\n* `map_bit_depth_rules`: Defines how to handle the bit depth of source maps. Can specify a default behavior (`\"respect\"` or `\"force_8bit\"`) and overrides for specific map types.\r\n* `model_patterns`: A list of regex patterns to identify model files (e.g., `\".*\\\\.fbx\"`, `\".*\\\\.obj\"`).\r\n* `move_to_extra_patterns`: A list of regex patterns for files that should be moved directly to the `Extra/` output subdirectory without further processing.\r\n* `source_naming_convention`: Rules for extracting the base asset name and potentially the archetype from source filenames or directory structures (e.g., using separators and indices).\r\n* `asset_category_rules`: Keywords or patterns used to determine the asset category (e.g., identifying `\"Decal\"` based on keywords).\r\n* `archetype_rules`: Keywords or patterns used to determine the asset archetype (e.g., identifying `\"Wood\"` or `\"Metal\"`).\r\n\r\nCareful definition of these patterns and rules, especially the regex in `map_type_mapping`, `bit_depth_variants`, `model_patterns`, and `move_to_extra_patterns`, is essential for correct asset processing."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/02_Developer_Guide/07_Monitor_Internals.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494857428,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494857428,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Developer Guide: Monitor Internals\r\n\r\nThis document provides technical details about the implementation of the Directory Monitor script (`monitor.py`) for developers.\r\n\r\n## Overview\r\n\r\nThe `monitor.py` script provides an automated way to process assets by monitoring a specified input directory for new ZIP files. It is built using the `watchdog` library.\r\n\r\n## Key Components\r\n\r\n* **`watchdog` Library:** The script relies on the `watchdog` library for monitoring file system events. Specifically, it uses a `PollingObserver` to watch the `INPUT_DIR` for changes.\r\n* **`ZipHandler` Class:** This is a custom event handler class defined within `monitor.py`. It inherits from a `watchdog` event handler class (likely `FileSystemEventHandler` or similar, though not explicitly stated in the source text, it's the standard pattern). Its primary method of interest is the one that handles file creation events (`on_created`).\r\n* **`main.run_processing`:** The monitor script triggers the main asset processing logic by calling the `run_processing` function from the `main.py` module.\r\n\r\n## Functionality Details\r\n\r\n1. **Watching:** A `PollingObserver` is set up to monitor the directory specified by the `INPUT_DIR` environment variable. Polling is used, checking for changes at a frequency defined by `POLL_INTERVAL`.\r\n2. **Event Handling:** The `ZipHandler` is attached to the observer. When a file is created in the monitored directory, the `on_created` method of the `ZipHandler` is triggered.\r\n3. **ZIP File Detection:** The `on_created` method checks if the newly created file is a `.zip` file.\r\n4. **Filename Parsing:** If it's a ZIP file, the script expects the filename to follow a specific format: `[preset]_filename.zip`. It uses a regular expression (`PRESET_FILENAME_REGEX`, likely defined in `config.py` or similar) to extract the `[preset]` part from the filename.\r\n5. **Preset Validation:** It validates whether the extracted `preset` name corresponds to an existing preset JSON file in the `Presets/` directory.\r\n6. **Triggering Processing:** If the preset is valid, the `monitor.py` script calls `main.run_processing`, passing the path to the detected ZIP file and the extracted preset name. This initiates the main asset processing pipeline for that single asset. A `PROCESS_DELAY` can be configured to wait before triggering processing, potentially allowing large files to finish copying.\r\n7. **Source ZIP Management:** After the processing initiated by `main.run_processing` completes, the original source `.zip` file is moved to either the `PROCESSED_DIR` (if processing was successful or skipped) or the `ERROR_DIR` (if processing failed or the preset was invalid).\r\n\r\n## Configuration\r\n\r\nThe monitor's behavior is primarily controlled by environment variables, which are read by the `monitor.py` script. These include `INPUT_DIR`, `OUTPUT_DIR`, `PROCESSED_DIR`, `ERROR_DIR`, `LOG_LEVEL`, `POLL_INTERVAL`, and `NUM_WORKERS`.\r\n\r\n## Limitations\r\n\r\n* The current implementation of the directory monitor does *not* support triggering the optional Blender script execution after processing. This post-processing step is only available when running the tool via the CLI or GUI.\r\n\r\nUnderstanding the interaction between `watchdog`, the `ZipHandler`, and the call to `main.run_processing` is key to debugging or modifying the directory monitoring functionality."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/02_Developer_Guide/09_Development_Workflow.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494882680,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494882680,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Developer Guide: Development Workflow\r\n\r\nThis document provides guidance for developers on the typical workflow for contributing to or modifying the Asset Processor Tool.\r\n\r\n## Modifying Core Processing Logic\r\n\r\nChanges to how assets are classified, maps are processed (resizing, format conversion, bit depth handling), channels are merged, or metadata is generated primarily involve editing the `AssetProcessor` class in `asset_processor.py`. Understanding the processing pipeline steps outlined in `05_Processing_Pipeline.md` is crucial here.\r\n\r\n## Changing Global Settings/Rules\r\n\r\nAdjustments to default output paths, standard image resolutions, default format rules, map merge definitions, Blender paths, or other global constants should be made in `config.py`.\r\n\r\n## Adding/Modifying Supplier Rules (Presets)\r\n\r\nTo add support for a new asset source or change how an existing one is interpreted, you need to create or edit the corresponding JSON file in the `Presets/` directory.\r\n\r\n* Use `Presets/_template.json` as a base for new presets.\r\n* Focus on defining accurate regex patterns and rules in fields like `map_type_mapping`, `bit_depth_variants`, `model_patterns`, `source_naming_convention`, etc.\r\n* Refer to `04_Configuration_System_and_Presets.md` for a detailed explanation of the preset file structure and the configuration loading process.\r\n\r\n## Adjusting CLI Behavior\r\n\r\nChanges to command-line arguments, argument parsing logic, or the overall CLI workflow are handled in `main.py`. This includes how arguments are parsed using `argparse`, how parallel processing is orchestrated, and how Blender scripts are triggered from the CLI.\r\n\r\n## Modifying the GUI\r\n\r\nWork on the Graphical User Interface involves the files within the `gui/` directory.\r\n\r\n* UI layout changes, adding new controls, or altering event handling are typically done in `main_window.py`.\r\n* Modifications to how background processing tasks are managed for the GUI are handled in `processing_handler.py`.\r\n* Changes to how file classification previews are generated and updated in the UI are in `prediction_handler.py`.\r\n* Understanding Qt's signals and slots mechanism and the use of `QThread` and `ProcessPoolExecutor` (as detailed in `06_GUI_Internals.md`) is essential for GUI development.\r\n\r\n## Enhancing Blender Integration\r\n\r\nImprovements or changes to how node groups or materials are created in Blender require editing the Python scripts within the `blenderscripts/` directory (`create_nodegroups.py`, `create_materials.py`).\r\n\r\n* These scripts are designed to be executed *within* Blender and interact with Blender's `bpy` API.\r\n* Consider how these scripts are invoked by the Asset Processor (via subprocess calls) and what data they expect (primarily from `metadata.json` and `sys.argv`).\r\n* Refer to `08_Blender_Integration_Internals.md` for details on the execution mechanism and script specifics.\r\n\r\n## General Development Practices\r\n\r\n* Adhere to the project's coding conventions (see `10_Coding_Conventions.md`).\r\n* Utilize the standard Python `logging` module for outputting information and debugging messages.\r\n* Use `try...except` blocks for error handling, and leverage the custom exceptions (`ConfigurationError`, `AssetProcessingError`) where appropriate.\r\n* When working with file paths, use `pathlib.Path` for consistency and robustness.\r\n* Be mindful of concurrency when working with the GUI or parallel processing in the CLI.\r\n\r\nThis workflow provides a general guide; specific tasks may require delving into multiple files and understanding the interactions between different components."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Documentation/02_Developer_Guide/10_Coding_Conventions.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745494891891,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745494891891,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Developer Guide: Coding Conventions\r\n\r\nThis document outlines the coding conventions and general practices followed within the Asset Processor Tool codebase. Adhering to these conventions helps maintain consistency and readability.\r\n\r\n## General Principles\r\n\r\n* **Readability:** Code should be easy to read and understand. Use clear variable and function names.\r\n* **Consistency:** Follow existing patterns and styles within the codebase.\r\n* **Maintainability:** Write code that is easy to modify and extend.\r\n* **Explicitness:** Be explicit rather than implicit.\r\n\r\n## Specific Conventions\r\n\r\n* **Object-Oriented Programming (OOP):** The codebase heavily utilizes classes to structure the application logic (e.g., `AssetProcessor`, `Configuration`, `MainWindow`, various Handlers). Follow standard OOP principles.\r\n* **Type Hinting:** Use Python type hints throughout the code to indicate the expected types of function arguments, return values, and variables. This improves code clarity and allows for static analysis.\r\n* **Logging:** Use the standard Python `logging` module for all output messages (information, warnings, errors, debug). Avoid using `print()` for application output. Configure log levels appropriately. The GUI uses a custom `QtLogHandler` to integrate logging with the UI.\r\n* **Error Handling:** Use standard `try...except` blocks to handle potential errors gracefully. Define and use custom exceptions (e.g., `ConfigurationError`, `AssetProcessingError`) for specific error conditions within the application logic. Log exceptions with `exc_info=True` to include traceback information.\r\n* **Parallelism:** When implementing CPU-bound tasks that can be run concurrently, use `concurrent.futures.ProcessPoolExecutor` as demonstrated in `main.py` and `gui/processing_handler.py`. Ensure that shared state is handled correctly (e.g., by instantiating necessary objects within worker processes).\r\n* **GUI Development (`PySide6`):**\r\n * Use Qt's signals and slots mechanism for communication between objects, especially across threads.\r\n * Run long-running or blocking tasks in separate `QThread`s to keep the main UI thread responsive.\r\n * Perform UI updates only from the main UI thread.\r\n* **Configuration:** Core settings are managed in `config.py` (Python module). Supplier-specific rules are managed in JSON files (`Presets/`). The `Configuration` class handles loading and merging these.\r\n* **File Paths:** Use `pathlib.Path` objects for handling file system paths. Avoid using string manipulation for path joining or parsing.\r\n* **Docstrings:** Write clear and concise docstrings for modules, classes, methods, and functions, explaining their purpose, arguments, and return values.\r\n* **Comments:** Use comments to explain complex logic or non-obvious parts of the code.\r\n* **Imports:** Organize imports at the top of the file, grouped by standard library, third-party libraries, and local modules.\r\n* **Naming:**\r\n * Use `snake_case` for function and variable names.\r\n * Use `PascalCase` for class names.\r\n * Use `UPPER_CASE` for constants.\r\n * Use a leading underscore (`_`) for internal or \"protected\" methods/attributes.\r\n\r\nAdhering to these conventions will make the codebase more consistent, easier to understand, and more maintainable for all contributors."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
18
.lh/Project Notes/BLENDER_INTEGRATION_PLAN.md.json
Normal file
18
.lh/Project Notes/BLENDER_INTEGRATION_PLAN.md.json
Normal file
File diff suppressed because one or more lines are too long
18
.lh/Project Notes/BLENDER_INTEGRATION_PLAN_v2.md.json
Normal file
18
.lh/Project Notes/BLENDER_INTEGRATION_PLAN_v2.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Project Notes/BLENDER_INTEGRATION_PLAN_v2.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745261903310,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745261903310,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Blender Integration Plan v2\r\n\r\n## Goal\r\n\r\nAdd an optional step to `main.py` to run `blenderscripts/create_nodegroups.py` and `blenderscripts/create_materials.py` on specified `.blend` files after asset processing is complete.\r\n\r\n## Proposed Plan\r\n\r\n1. **Update `config.py`:**\r\n * Add two new optional configuration variables: `DEFAULT_NODEGROUP_BLEND_PATH` and `DEFAULT_MATERIALS_BLEND_PATH`. These will store the default paths to the Blender files.\r\n\r\n2. **Update `main.py` Argument Parser:**\r\n * Add two new optional command-line arguments: `--nodegroup-blend` and `--materials-blend`.\r\n * These arguments will accept file paths to the respective `.blend` files.\r\n * If provided, these arguments will override the default paths specified in `config.py`.\r\n\r\n3. **Update `blenderscripts/create_nodegroups.py` and `blenderscripts/create_materials.py`:**\r\n * Modify both scripts to accept the processed asset library root path (`PROCESSED_ASSET_LIBRARY_ROOT`) as a command-line argument. This will be passed to the script when executed by Blender using the `--` separator.\r\n * Update the scripts to read this path from `sys.argv` instead of using the hardcoded variable.\r\n\r\n4. **Update `main.py` Execution Flow:**\r\n * After the main asset processing loop (`run_processing`) completes and the summary is reported, check if the `--nodegroup-blend` or `--materials-blend` arguments (or their fallbacks from `config.py`) were provided.\r\n * If a path for the nodegroup `.blend` file is available:\r\n * Construct a command to execute Blender in the background (`-b`), load the specified nodegroup `.blend` file, run the `create_nodegroups.py` script using `--python`, pass the processed asset root directory as an argument after `--`, and save the `.blend` file (`-S`).\r\n * Execute this command using the `execute_command` tool.\r\n * If a path for the materials `.blend` file is available:\r\n * Construct a similar command to execute Blender in the background, load the specified materials `.blend` file, run the `create_materials.py` script using `--python`, pass the processed asset root directory as an argument after `--`, and save the `.blend` file (`-S`).\r\n * Execute this command using the `execute_command` tool.\r\n * Include error handling for the execution of the Blender commands.\r\n\r\n## Execution Flow Diagram\r\n\r\n```mermaid\r\ngraph TD\r\n A[Asset Processing Complete] --> B[Report Summary];\r\n B --> C{Nodegroup Blend Path Specified?};\r\n C -- Yes --> D[Get Nodegroup Blend Path (Arg or Config)];\r\n D --> E[Construct Blender Command for Nodegroups];\r\n E --> F[Execute Command: blender -b nodegroup.blend --python create_nodegroups.py -- <asset_root> -S];\r\n F --> G{Command Successful?};\r\n G -- Yes --> H{Materials Blend Path Specified?};\r\n G -- No --> I[Log Nodegroup Error];\r\n I --> H;\r\n H -- Yes --> J[Get Materials Blend Path (Arg or Config)];\r\n J --> K[Construct Blender Command for Materials];\r\n K --> L[Execute Command: blender -b materials.blend --python create_materials.py -- <asset_root> -S];\r\n L --> M{Command Successful?};\r\n M -- Yes --> N[End main.py];\r\n M -- No --> O[Log Materials Error];\r\n O --> N;\r\n H -- No --> N;\r\n C -- No --> H;"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
26
.lh/Project Notes/BLENDER_MATERIAL_CREATION_PLAN.md.json
Normal file
26
.lh/Project Notes/BLENDER_MATERIAL_CREATION_PLAN.md.json
Normal file
File diff suppressed because one or more lines are too long
18
.lh/Project Notes/BLENDER_MATERIAL_MERGE_ADDON_PLAN.md.json
Normal file
18
.lh/Project Notes/BLENDER_MATERIAL_MERGE_ADDON_PLAN.md.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
18
.lh/Project Notes/FEAT-003_Implementation_Plan.md.json
Normal file
18
.lh/Project Notes/FEAT-003_Implementation_Plan.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Project Notes/FEAT-003_Implementation_Plan.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745309374613,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745309374613,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# FEAT-003: Selective Nodegroup Generation and Category Tagging - Implementation Plan\r\n\r\n**Objective:** Modify `blenderscripts/create_nodegroups.py` to read the asset category from `metadata.json`, conditionally create nodegroups for \"Surface\" and \"Decal\" assets, and add the category as a tag to the Blender asset.\r\n\r\n**Plan:**\r\n\r\n1. **Modify `blenderscripts/create_nodegroups.py`:**\r\n * Locate the main loop in `blenderscripts/create_nodegroups.py` that iterates through the processed assets.\r\n * Inside this loop, for each asset directory, construct the path to the `metadata.json` file.\r\n * Read the `metadata.json` file using Python's `json` module.\r\n * Extract the `category` value from the parsed JSON data.\r\n * Implement a conditional check: If the extracted `category` is *not* \"Surface\" and *not* \"Decal\", skip the existing nodegroup creation logic for this asset and proceed to the tagging step.\r\n * If the `category` *is* \"Surface\" or \"Decal\", execute the existing nodegroup creation logic.\r\n * After the conditional nodegroup creation (or skipping), use the Blender Python API (`bpy`) to find the corresponding Blender asset (likely the created node group, if applicable, or potentially the asset representation even if the nodegroup was skipped).\r\n * Add the extracted `category` string as a tag to the found Blender asset.\r\n\r\n2. **Testing:**\r\n * Prepare a test set of processed assets that includes examples of \"Surface\", \"Decal\", and \"Asset\" categories, each with a corresponding `metadata.json` file.\r\n * Run the modified `create_nodegroups.py` script within Blender, pointing it to the test asset library root.\r\n * Verify in Blender that:\r\n * Node groups were created only for the \"Surface\" and \"Decal\" assets.\r\n * No node groups were created for \"Asset\" category assets.\r\n * All processed assets (Surface, Decal, and Asset) have a tag corresponding to their category (\"Surface\", \"Decal\", or \"Asset\") in the Blender asset browser.\r\n\r\n```mermaid\r\ngraph TD\r\n A[Start Script] --> B{Iterate Assets};\r\n B --> C[Read metadata.json];\r\n C --> D[Get Category];\r\n D --> E{Category in [\"Surface\", \"Decal\"]?};\r\n E -- Yes --> F[Create Nodegroup];\r\n E -- No --> G[Skip Nodegroup];\r\n F --> H[Find Blender Asset];\r\n G --> H[Find Blender Asset];\r\n H --> I[Add Category Tag];\r\n I --> B;\r\n B -- No More Assets --> J[End Script];"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Project Notes/FEAT-rar-7z-support-plan.md.json
Normal file
18
.lh/Project Notes/FEAT-rar-7z-support-plan.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Project Notes/FEAT-rar-7z-support-plan.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745506880027,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745506880027,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Plan for Adding .rar and .7z Support\r\n\r\n**Goal:** Extend the Asset Processor Tool to accept `.rar` and `.7z` files as input sources, in addition to the currently supported `.zip` files and folders.\r\n\r\n**Plan:**\r\n\r\n1. **Add Required Libraries:**\r\n * Update the `requirements.txt` file to include `py7zr` and `rarfile` as dependencies. This will ensure these libraries are installed when setting up the project.\r\n\r\n2. **Modify Input Extraction Logic:**\r\n * Locate the `_extract_input` method within the `AssetProcessor` class in `asset_processor.py`.\r\n * Modify this method to check the file extension of the input source.\r\n * If the extension is `.zip`, retain the existing extraction logic using Python's built-in `zipfile` module.\r\n * If the extension is `.rar`, implement extraction using the `rarfile` library.\r\n * If the extension is `.7z`, implement extraction using the `py7zr` library.\r\n * Include error handling for cases where the archive might be corrupted, encrypted (since we are not implementing password support at this stage, these should likely be skipped or logged as errors), or uses an unsupported compression method. Log appropriate warnings or errors in such cases.\r\n * If the input is a directory, retain the existing logic to copy its contents to the temporary workspace.\r\n\r\n3. **Update CLI and Monitor Input Handling:**\r\n * Review `main.py` (CLI entry point) and `monitor.py` (Directory Monitor).\r\n * Ensure that the argument parsing in `main.py` can accept `.rar` and `.7z` file paths as valid inputs.\r\n * In `monitor.py`, modify the `ZipHandler` (or create a new handler) to watch for `.rar` and `.7z` file creation events in the watched directory, in addition to `.zip` files. The logic for triggering processing via `main.run_processing` should then be extended to handle these new file types.\r\n\r\n4. **Update Documentation:**\r\n * Edit `Documentation/00_Overview.md` to explicitly mention `.rar` and `.7z` as supported input formats in the overview section.\r\n * Update `Documentation/01_User_Guide/02_Features.md` to list `.rar` and `.7z` alongside `.zip` and folders in the features list.\r\n * Modify `Documentation/01_User_Guide/03_Installation.md` to include instructions for installing the new `py7zr` and `rarfile` dependencies (likely via `pip install -r requirements.txt`).\r\n * Revise `Documentation/02_Developer_Guide/05_Processing_Pipeline.md` to accurately describe the updated `_extract_input` method, detailing how `.zip`, `.rar`, `.7z`, and directories are handled.\r\n\r\n5. **Testing:**\r\n * Prepare sample `.rar` and `.7z` files (including nested directories and various file types) to test the extraction logic thoroughly.\r\n * Test processing of these new archive types via both the CLI and the Directory Monitor.\r\n * Verify that the subsequent processing steps (classification, map processing, metadata generation, etc.) work correctly with files extracted from `.rar` and `.7z` archives.\r\n\r\nHere is a simplified flow diagram illustrating the updated input handling:\r\n\r\n```mermaid\r\ngraph TD\r\n A[Input Source] --> B{Is it a file or directory?};\r\n B -- Directory --> C[Copy Contents to Workspace];\r\n B -- File --> D{What is the file extension?};\r\n D -- .zip --> E[Extract using zipfile];\r\n D -- .rar --> F[Extract using rarfile];\r\n D -- .7z --> G[Extract using py7zr];\r\n E --> H[Temporary Workspace];\r\n F --> H;\r\n G --> H;\r\n C --> H;\r\n H --> I[Processing Pipeline Starts];"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Project Notes/GUI_BLENDER_INTEGRATION_PLAN.md.json
Normal file
18
.lh/Project Notes/GUI_BLENDER_INTEGRATION_PLAN.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Project Notes/GUI_BLENDER_INTEGRATION_PLAN.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745262237766,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745262237766,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# GUI Blender Integration Plan\r\n\r\n## Goal\r\n\r\nAdd a checkbox and input fields to the GUI (`gui/main_window.py`) to enable/disable Blender script execution and specify the `.blend` file paths, defaulting to `config.py` values. Integrate this control into the processing logic (`gui/processing_handler.py`).\r\n\r\n## Proposed Plan\r\n\r\n1. **Modify `gui/main_window.py`:**\r\n * Add a `QCheckBox` (e.g., `self.blender_integration_checkbox`) to the processing panel layout.\r\n * Add two pairs of `QLineEdit` widgets and `QPushButton` browse buttons for the nodegroup `.blend` path (`self.nodegroup_blend_path_input`, `self.browse_nodegroup_blend_button`) and the materials `.blend` path (`self.materials_blend_path_input`, `self.browse_materials_blend_button`).\r\n * Initialize the text of the `QLineEdit` widgets by reading the `DEFAULT_NODEGROUP_BLEND_PATH` and `DEFAULT_MATERIALS_BLEND_PATH` values from `config.py` when the GUI starts.\r\n * Connect signals from the browse buttons to new methods that open a `QFileDialog` to select `.blend` files and update the corresponding input fields.\r\n * Modify the slot connected to the \"Start Processing\" button to:\r\n * Read the checked state of `self.blender_integration_checkbox`.\r\n * Read the text from `self.nodegroup_blend_path_input` and `self.materials_blend_path_input`.\r\n * Pass these three pieces of information (checkbox state, nodegroup path, materials path) to the `ProcessingHandler` when initiating the processing task.\r\n\r\n2. **Modify `gui/processing_handler.py`:**\r\n * Add parameters to the method that starts the processing (likely `start_processing`) to accept the Blender integration flag (boolean), the nodegroup `.blend` path (string), and the materials `.blend` path (string).\r\n * Implement the logic for finding the Blender executable (reading `BLENDER_EXECUTABLE_PATH` from `config.py` or checking PATH) within `processing_handler.py`.\r\n * Implement the logic for executing the Blender scripts using `subprocess.run` within `processing_handler.py`. This logic should be similar to the `run_blender_script` function added to `main.py` in the previous step.\r\n * Ensure this Blender script execution logic is conditional based on the received integration flag and runs *after* the main asset processing (handled by the worker pool) is complete.\r\n\r\n## Execution Flow Diagram (GUI)\r\n\r\n```mermaid\r\ngraph TD\r\n A[GUI: User Clicks Start Processing] --> B{Blender Integration Checkbox Checked?};\r\n B -- Yes --> C[Get Blend File Paths from Input Fields];\r\n C --> D[Pass Paths and Flag to ProcessingHandler];\r\n D --> E[ProcessingHandler: Start Asset Processing (Worker Pool)];\r\n E --> F[ProcessingHandler: Asset Processing Complete];\r\n F --> G{Blender Integration Flag True?};\r\n G -- Yes --> H[ProcessingHandler: Find Blender Executable];\r\n H --> I{Blender Executable Found?};\r\n I -- Yes --> J{Nodegroup Blend Path Valid?};\r\n J -- Yes --> K[ProcessingHandler: Run Nodegroup Script in Blender];\r\n K --> L{Script Successful?};\r\n L -- Yes --> M{Materials Blend Path Valid?};\r\n L -- No --> N[ProcessingHandler: Report Nodegroup Error];\r\n N --> M;\r\n M -- Yes --> O[ProcessingHandler: Run Materials Script in Blender];\r\n O --> P{Script Successful?};\r\n P -- Yes --> Q[ProcessingHandler: Report Completion];\r\n P -- No --> R[ProcessingHandler: Report Materials Error];\r\n R --> Q;\r\n M -- No --> Q;\r\n J -- No --> M[Skip Nodegroup Script];\r\n I -- No --> Q[Skip Blender Scripts];\r\n G -- No --> Q;\r\n B -- No --> E;"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Project Notes/GUI_Enhancement_Plan.md.json
Normal file
18
.lh/Project Notes/GUI_Enhancement_Plan.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Project Notes/GUI_Enhancement_Plan.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745269698564,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745269698564,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# GUI Enhancement Plan\r\n\r\n## Objective\r\n\r\nImplement two new features in the Graphical User Interface (GUI) of the Asset Processor Tool:\r\n1. Automatically switch the preview to \"simple view\" when more than 10 input files (ZIPs or folders) are added to the queue.\r\n2. Remove the specific visual area labeled \"Drag and drop folders here\" while keeping the drag-and-drop functionality active for the main processing panel.\r\n\r\n## Implementation Plan\r\n\r\nThe changes will be made in the `gui/main_window.py` file.\r\n\r\n1. **Implement automatic preview switch:**\r\n * Locate the `add_input_paths` method.\r\n * After adding the `newly_added_paths` to `self.current_asset_paths`, check the total number of items in `self.current_asset_paths`.\r\n * If the count is greater than 10, programmatically set the state of the \"Disable Detailed Preview\" menu action (`self.toggle_preview_action`) to `checked=True`. This will automatically trigger the `update_preview` method, which will then render the simple list view.\r\n\r\n2. **Remove the \"Drag and drop folders here\" visual area:**\r\n * Locate the `setup_main_panel_ui` method.\r\n * Find the creation of the `self.drag_drop_area` QFrame and its associated QLabel (`drag_drop_label`).\r\n * Add a line after the creation of `self.drag_drop_area` to hide this widget (`self.drag_drop_area.setVisible(False)`). This will remove the visual box and label while keeping the drag-and-drop functionality enabled for the main window.\r\n\r\n## Workflow Diagram\r\n\r\n```mermaid\r\ngraph TD\r\n A[User drops files/folders] --> B{Call add_input_paths}\r\n B --> C[Add paths to self.current_asset_paths]\r\n C --> D{Count items in self.current_asset_paths}\r\n D{Count > 10?} -->|Yes| E[Set toggle_preview_action.setChecked(True)]\r\n D{Count > 10?} -->|No| F[Keep current preview state]\r\n E --> G[update_preview triggered]\r\n F --> G[update_preview triggered]\r\n G --> H{Check toggle_preview_action state}\r\n H{Checked (Simple)?} -->|Yes| I[Display simple list in preview_table]\r\n H{Checked (Simple)?} -->|No| J[Run PredictionHandler for detailed preview]\r\n J --> K[Display detailed results in preview_table]\r\n\r\n L[GUI Initialization] --> M[Call setup_main_panel_ui]\r\n M --> N[Create drag_drop_area QFrame]\r\n N --> O[Hide drag_drop_area QFrame]\r\n O --> P[Main window accepts drops]\r\n P --> B"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Project Notes/GUI_FEATURE_PLAN.md.json
Normal file
18
.lh/Project Notes/GUI_FEATURE_PLAN.md.json
Normal file
File diff suppressed because one or more lines are too long
18
.lh/Project Notes/GUI_LOG_CONSOLE_PLAN.md.json
Normal file
18
.lh/Project Notes/GUI_LOG_CONSOLE_PLAN.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Project Notes/GUI_LOG_CONSOLE_PLAN.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745236923455,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745236923455,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# GUI Log Console Feature Plan\r\n\r\n**Overall Goal:** Add a log console panel to the GUI's editor panel, controlled by a \"View\" menu action. Move the \"Disable Detailed Preview\" control to the same \"View\" menu.\r\n\r\n**Detailed Plan:**\r\n\r\n1. **Create Custom Log Handler:**\r\n * **New File/Location:** Potentially add this to a new `gui/log_handler.py` or keep it within `gui/main_window.py` if simple enough.\r\n * **Implementation:**\r\n * Define a class `QtLogHandler(logging.Handler, QObject)` that inherits from both `logging.Handler` and `QObject` (for signals).\r\n * Add a Qt signal, e.g., `log_record_received = Signal(str)`.\r\n * Override the `emit(self, record)` method:\r\n * Format the log record using `self.format(record)`.\r\n * Emit the `log_record_received` signal with the formatted string.\r\n\r\n2. **Modify `gui/main_window.py`:**\r\n * **Imports:** Add `QMenuBar`, `QMenu`, `QAction` from `PySide6.QtWidgets`. Import the new `QtLogHandler`.\r\n * **UI Elements (`__init__` / `setup_editor_panel_ui`):**\r\n * **Menu Bar:**\r\n * Create `self.menu_bar = self.menuBar()`.\r\n * Create `view_menu = self.menu_bar.addMenu(\"&View\")`.\r\n * **Log Console:**\r\n * Create `self.log_console_output = QTextEdit()`. Set it to read-only (`self.log_console_output.setReadOnly(True)`).\r\n * Create a container widget, e.g., `self.log_console_widget = QWidget()`. Create a layout for it (e.g., `QVBoxLayout`) and add `self.log_console_output` to this layout.\r\n * In `setup_editor_panel_ui`, insert `self.log_console_widget` into the `editor_layout` *before* adding the `list_layout` (the preset list).\r\n * Initially hide the console: `self.log_console_widget.setVisible(False)`.\r\n * **Menu Actions:**\r\n * Create `self.toggle_log_action = QAction(\"Show Log Console\", self, checkable=True)`. Connect `self.toggle_log_action.toggled.connect(self._toggle_log_console_visibility)`. Add it to `view_menu`.\r\n * Create `self.toggle_preview_action = QAction(\"Disable Detailed Preview\", self, checkable=True)`. Connect `self.toggle_preview_action.toggled.connect(self.update_preview)`. Add it to `view_menu`.\r\n * **Remove Old Checkbox:** Delete the lines creating and adding `self.disable_preview_checkbox`.\r\n * **Logging Setup (`__init__`):**\r\n * Instantiate the custom handler: `self.log_handler = QtLogHandler()`.\r\n * Connect its signal: `self.log_handler.log_record_received.connect(self._append_log_message)`.\r\n * Add the handler to the logger: `log.addHandler(self.log_handler)`. Set an appropriate level if needed (e.g., `self.log_handler.setLevel(logging.INFO)`).\r\n * **New Slots:**\r\n * Implement `_toggle_log_console_visibility(self, checked)`: This slot will simply call `self.log_console_widget.setVisible(checked)`.\r\n * Implement `_append_log_message(self, message)`:\r\n * Append the `message` string to `self.log_console_output`.\r\n * Optional: Add logic to limit the number of lines in the text edit to prevent performance issues.\r\n * Optional: Add basic HTML formatting for colors based on log level.\r\n * **Modify `update_preview`:**\r\n * Replace the check for `self.disable_preview_checkbox.isChecked()` with `self.toggle_preview_action.isChecked()`.\r\n * Update the log messages within this method to reflect checking the action state.\r\n\r\n**Mermaid Diagram:**\r\n\r\n```mermaid\r\ngraph TD\r\n subgraph MainWindow\r\n A[Initialization] --> B(Create Menu Bar);\r\n B --> C(Add View Menu);\r\n C --> D(Add 'Show Log Console' Action);\r\n C --> E(Add 'Disable Detailed Preview' Action);\r\n A --> F(Create Log Console QTextEdit);\r\n F --> G(Place Log Console Widget in Layout [Hidden]);\r\n A --> H(Create & Add QtLogHandler);\r\n H --> I(Connect Log Handler Signal to _append_log_message);\r\n\r\n D -- Toggled --> J[_toggle_log_console_visibility];\r\n J --> K(Show/Hide Log Console Widget);\r\n\r\n E -- Toggled --> L[update_preview];\r\n\r\n M[update_preview] --> N{Is 'Disable Preview' Action Checked?};\r\n N -- Yes --> O[Show Simple List View];\r\n N -- No --> P[Start PredictionHandler];\r\n\r\n Q[Any Log Message] -- Emitted by Logger --> H;\r\n I --> R[_append_log_message];\r\n R --> S(Append Message to Log Console QTextEdit);\r\n end\r\n\r\n subgraph QtLogHandler\r\n style QtLogHandler fill:#lightgreen,stroke:#333,stroke-width:2px\r\n T1[emit(record)] --> T2(Format Record);\r\n T2 --> T3(Emit log_record_received Signal);\r\n T3 --> I;\r\n end"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
26
.lh/Project Notes/GUI_Preset_Selection_Plan.md.json
Normal file
26
.lh/Project Notes/GUI_Preset_Selection_Plan.md.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Project Notes/GUI_Preset_Selection_Plan.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 2,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745508237366,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745508648879,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -1,9 +1,9 @@\n-# GUI Preset Selection Change Plan\r\n+# GUI Preset Selection Plan\r\n \r\n ## Objective\r\n \r\n-Modify the GUI so that no preset is selected by default, and the preview table is only populated after the user explicitly selects a preset. This aims to prevent accidental processing with an unintended preset and clearly indicate to the user that a preset selection is required for preview.\r\n+Modify the GUI so that no preset is selected by default, and the preview table is only populated after the user explicitly selects a preset. This aims to prevent accidental processing with an unintended preset and clearly indicate to the user that a preset selection is required for preview generation.\r\n \r\n ## Plan\r\n \r\n 1. **Modify `gui/main_window.py`:**\r\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745508921820,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -1,9 +1,9 @@\n # GUI Preset Selection Plan\r\n \r\n ## Objective\r\n \r\n-Modify the GUI so that no preset is selected by default, and the preview table is only populated after the user explicitly selects a preset. This aims to prevent accidental processing with an unintended preset and clearly indicate to the user that a preset selection is required for preview generation.\r\n+Modify the GUI so that no preset is selected by default, and the preview table is only populated after the user explicitly selects a preset. This aims to prevent accidental processing with an unintended preset and clearly indicate to the user that a preset selection is required for preview.\r\n \r\n ## Plan\r\n \r\n 1. **Modify `gui/main_window.py`:**\r\n@@ -30,10 +30,8 @@\n \r\n The proposed data flow would be:\r\n Initialization -> No Preset Selected -> Preview Table Empty/Placeholder -> User Selects Preset -> Trigger PredictionHandler with Selected Preset -> Update Preview Table\r\n \r\n-Here's a simplified Mermaid diagram illustrating the change in the initial state:\r\n-\r\n ```mermaid\r\n graph TD\r\n A[GUI Initialization] --> B{Is a Preset Selected?};\r\n B -- Yes (Current) --> C[Load Default Preset];\r\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745508237366,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# GUI Preset Selection Change Plan\r\n\r\n## Objective\r\n\r\nModify the GUI so that no preset is selected by default, and the preview table is only populated after the user explicitly selects a preset. This aims to prevent accidental processing with an unintended preset and clearly indicate to the user that a preset selection is required for preview.\r\n\r\n## Plan\r\n\r\n1. **Modify `gui/main_window.py`:**\r\n * Remove the logic that selects a default preset during initialization.\r\n * Initialize the preview table to display the text \"please select a preset\".\r\n * Disable the mechanism that triggers the `PredictionHandler` for preview generation until a preset is selected.\r\n * Update the slot connected to the preset selection signal:\r\n * When a preset is selected, clear the placeholder text and enable the preview generation mechanism.\r\n * Pass the selected preset configuration to the `PredictionHandler`.\r\n * Trigger the `PredictionHandler` to generate and display the preview.\r\n * (Optional but recommended) Add logic to handle the deselection of a preset, which should clear the preview table and display the \"please select a preset\" text again, and disable preview generation.\r\n\r\n2. **Review `gui/prediction_handler.py`:**\r\n * Verify that the `PredictionHandler`'s methods that generate predictions (`get_detailed_file_predictions`) correctly handle being called only when a valid preset is provided. No major changes are expected here, but it's good practice to confirm.\r\n\r\n3. **Update Preview Table Handling (`gui/preview_table_model.py` and `gui/main_window.py`):**\r\n * Ensure the `PreviewTableModel` can gracefully handle having no data when no preset is selected.\r\n * In `gui/main_window.py`, configure the `QTableView` or its parent widget to display the placeholder text \"please select a preset\" when the model is empty or no preset is active.\r\n\r\n## Data Flow Change\r\n\r\nThe current data flow for preview generation is roughly:\r\nInitialization -> Default Preset Loaded -> Trigger PredictionHandler -> Update Preview Table\r\n\r\nThe proposed data flow would be:\r\nInitialization -> No Preset Selected -> Preview Table Empty/Placeholder -> User Selects Preset -> Trigger PredictionHandler with Selected Preset -> Update Preview Table\r\n\r\nHere's a simplified Mermaid diagram illustrating the change in the initial state:\r\n\r\n```mermaid\r\ngraph TD\r\n A[GUI Initialization] --> B{Is a Preset Selected?};\r\n B -- Yes (Current) --> C[Load Default Preset];\r\n B -- No (Proposed) --> D[Preview Table Empty/Placeholder];\r\n C --> E[Trigger PredictionHandler];\r\n D --> F[User Selects Preset];\r\n F --> E;\r\n E --> G[Update Preview Table];"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Project Notes/GUI_PreviewTable_AlternatingColors_Plan.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745498803515,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745498803515,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Plan: Implement Alternating Row Colors Per Asset Group in GUI Preview Table\r\n\r\n## Objective\r\n\r\nModify the GUI preview table to display alternating background colors for rows based on the asset group they belong to, rather than alternating colors for each individual row. The visual appearance should be similar to the default alternating row colors (dark greys, no border, no rounded corners).\r\n\r\n## Current State\r\n\r\nThe preview table in the GUI uses a `QTableView` with `setAlternatingRowColors(True)` enabled, which applies alternating background colors based on the row index. The `PreviewTableModel` groups file prediction data by `source_asset` in its internal `_table_rows` structure and provides data to the view.\r\n\r\n## Proposed Plan\r\n\r\nTo achieve alternating colors per asset group, we will implement custom coloring logic within the `PreviewTableModel`.\r\n\r\n1. **Disable Default Alternating Colors:**\r\n * In `gui/main_window.py`, locate the initialization of the `preview_table_view` (a `QTableView`).\r\n * Change `self.preview_table_view.setAlternatingRowColors(True)` to `self.preview_table_view.setAlternatingRowColors(False)`.\r\n\r\n2. **Modify `PreviewTableModel.data()`:**\r\n * Open `gui/preview_table_model.py`.\r\n * In the `data()` method, add a case to handle the `Qt.ItemDataRole.BackgroundRole`.\r\n * Inside this case, retrieve the `source_asset` for the current row from the `self._table_rows` structure.\r\n * Maintain a sorted list of unique `source_asset` values. This can be done when the data is set in `set_data()`.\r\n * Find the index of the current row's `source_asset` within this sorted list.\r\n * Based on whether the index is even or odd, return a `QColor` object representing one of the two desired grey colors.\r\n * Ensure that the `Qt.ItemDataRole.BackgroundRole` is handled correctly for all columns in the row.\r\n\r\n3. **Define Colors:**\r\n * Define two `QColor` objects within the `PreviewTableModel` class to represent the two grey colors for alternating groups. These should be chosen to be visually similar to the default alternating row colors.\r\n\r\n## Visual Representation of Data Flow with Custom Coloring\r\n\r\n```mermaid\r\ngraph TD\r\n A[QTableView] --> B{Requests Data for Row/Column};\r\n B --> C[PreviewSortFilterProxyModel];\r\n C --> D[PreviewTableModel];\r\n D -- data(index, role) --> E{Check Role};\r\n E -- Qt.ItemDataRole.BackgroundRole --> F{Get source_asset for row};\r\n F --> G{Determine Asset Group Index};\r\n G --> H{Assign Color based on Index Parity};\r\n H --> I[Return QColor];\r\n E -- Other Roles --> J[Return Display/Tooltip/Foreground Data};\r\n I --> C;\r\n J --> C;\r\n C --> A{Displays Data with Custom Background Color};\r\n\r\n style D fill:#f9f,stroke:#333,stroke-width:2px\r\n style H fill:#ccf,stroke:#333,stroke-width:1px\r\n style I fill:#ccf,stroke:#333,stroke-width:1px\r\n```\r\n\r\n## Implementation Steps (for Code Mode)\r\n\r\n1. Modify `gui/main_window.py` to disable default alternating row colors.\r\n2. Modify `gui/preview_table_model.py` to:\r\n * Define the two grey `QColor` objects.\r\n * Update `set_data()` to create and store a sorted list of unique asset groups.\r\n * Implement the `Qt.ItemDataRole.BackgroundRole` logic in the `data()` method to return alternating colors based on the asset group index."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Project Notes/GUI_PreviewTable_Coloring_Plan.md.json
Normal file
18
.lh/Project Notes/GUI_PreviewTable_Coloring_Plan.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Project Notes/GUI_PreviewTable_Coloring_Plan.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745504994360,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745504994360,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Plan: Enhance GUI Preview Table Coloring\r\n\r\n## Objective\r\n\r\nModify the GUI preview table to apply status-based text coloring to all relevant cells in a row, providing a more consistent visual indication of a file's status.\r\n\r\n## Current State\r\n\r\nThe `PreviewTableModel` in `gui/preview_table_model.py` currently applies status-based text colors only to the \"Status\" column (based on the main file's status) and the \"Additional Files\" column (based on the additional file's status). Other cells in the row do not have status-based coloring.\r\n\r\n## Proposed Change\r\n\r\nExtend the status-based text coloring logic in the `PreviewTableModel`'s `data()` method to apply the relevant status color to any cell that corresponds to either the main file or an additional file in that row.\r\n\r\n## Plan\r\n\r\n1. **Modify the `data()` method in `gui/preview_table_model.py`:**\r\n * Locate the section handling the `Qt.ItemDataRole.ForegroundRole`.\r\n * Currently, this section checks the column index (`col`) to decide which file's status to use for coloring (main file for `COL_STATUS`, additional file for `COL_ADDITIONAL_FILES`).\r\n * We will change this logic to determine which file (main or additional) the *current row and column* corresponds to, and then use that file's status to look up the color.\r\n * For columns related to the main file (`COL_STATUS`, `COL_PREDICTED_ASSET`, `COL_ORIGINAL_PATH`, `COL_PREDICTED_OUTPUT`, `COL_DETAILS`), if the row contains a `main_file`, use the `main_file`'s status for coloring.\r\n * For the `COL_ADDITIONAL_FILES` column, if the row contains `additional_file_details`, use the `additional_file_details`' status for coloring.\r\n * If a cell does not correspond to a file (e.g., a main file column in a row that only has an additional file), return `None` for the `ForegroundRole` to use the default text color.\r\n\r\n## Detailed Steps\r\n\r\n1. Open `gui/preview_table_model.py`.\r\n2. Navigate to the `data()` method.\r\n3. Find the `if role == Qt.ItemDataRole.ForegroundRole:` block.\r\n4. Inside this block, modify the logic to determine the `status` variable based on the current `col` and the presence of `main_file` or `additional_file_details` in `row_data`.\r\n5. Use the determined `status` to look up the color in `self.STATUS_COLORS`.\r\n6. Return the color if found, otherwise return `None`.\r\n\r\n## Modified Color Logic Flow\r\n\r\n```mermaid\r\ngraph TD\r\n A[data(index, role)] --> B{role == Qt.ItemDataRole.ForegroundRole?};\r\n B -- Yes --> C{Determine relevant file for cell (row, col)};\r\n C -- Cell corresponds to Main File --> D{Get main_file status};\r\n C -- Cell corresponds to Additional File --> E{Get additional_file_details status};\r\n C -- Cell is empty --> F[status = None];\r\n D --> G{Lookup color in STATUS_COLORS};\r\n E --> G;\r\n F --> H[Return None];\r\n G -- Color found --> I[Return Color];\r\n G -- No color found --> H;\r\n B -- No --> J[Handle other roles];\r\n J --> K[Return data based on role];"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Project Notes/GUI_Preview_Table_Restructure_Plan.md.json
Normal file
18
.lh/Project Notes/GUI_Preview_Table_Restructure_Plan.md.json
Normal file
File diff suppressed because one or more lines are too long
18
.lh/Project Notes/ISSUE-011-plan.md.json
Normal file
18
.lh/Project Notes/ISSUE-011-plan.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Project Notes/ISSUE-011-plan.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745348289645,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745348289645,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Plan to Resolve ISSUE-011: Blender nodegroup script creates empty assets for skipped items\r\n\r\n**Issue:** The Blender nodegroup creation script (`blenderscripts/create_nodegroups.py`) creates empty asset entries in the target .blend file for assets belonging to categories that the script is designed to skip, even though it correctly identifies them as skippable.\r\n\r\n**Root Cause:** The script creates the parent node group, marks it as an asset, and applies tags *before* checking if the asset category is one that should be skipped for full nodegroup generation.\r\n\r\n**Plan:**\r\n\r\n1. **Analyze `blenderscripts/create_nodegroups.py` (Completed):** Confirmed that parent group creation and asset marking occur before the asset category skip check.\r\n2. **Modify `blenderscripts/create_nodegroups.py`:**\r\n * Relocate the code block responsible for creating/updating the parent node group, marking it as an asset, and applying tags (currently lines 605-645) to *after* the conditional check `if asset_category not in CATEGORIES_FOR_NODEGROUP_GENERATION:` (line 646).\r\n * This ensures that if an asset's category is in the list of categories to be skipped, the `continue` statement will be hit before any actions are taken to create the parent asset entry in the Blender file.\r\n\r\n3. **Testing:**\r\n * Use test assets that represent both categories that *should* and *should not* result in full nodegroup generation based on the `CATEGORIES_FOR_NODEGROUP_GENERATION` list.\r\n * Run the asset processor with these test assets, ensuring the Blender script is executed.\r\n * Inspect the resulting `.blend` file to confirm:\r\n * No `PBRSET_` node groups are created for assets belonging to skipped categories.\r\n * `PBRSET_` node groups are correctly created and populated for assets belonging to categories in `CATEGORIES_FOR_NODEGROUP_GENERATION`.\r\n\r\n4. **Update Ticket Status:**\r\n * Once the fix is implemented and verified, update the `Status` field in `Tickets/ISSUE-011-blender-nodegroup-empty-assets.md` to `Resolved`.\r\n\r\n**Logic Flow:**\r\n\r\n```mermaid\r\ngraph TD\r\n A[create_nodegroups.py] --> B{Load Asset Metadata};\r\n B --> C{Determine Asset Category};\r\n C --> D{Is Category Skipped?};\r\n D -- Yes --> E[Exit Processing for Asset];\r\n D -- No --> F{Create/Update Parent Group};\r\n F --> G{Mark as Asset & Add Tags};\r\n G --> H{Proceed with Child Group Creation etc.};"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
22
.lh/Tickets/BUG-GUI-PreviewToggleCrash.md.json
Normal file
22
.lh/Tickets/BUG-GUI-PreviewToggleCrash.md.json
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/FEAT-003-selective-nodegroup-generation-tagging.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 1,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745307144919,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745309772733,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -1,8 +1,8 @@\n ---\r\n ID: FEAT-003\r\n Type: Feature\r\n-Status: Backlog\r\n+Status: Complete\r\n Priority: Medium\r\n Labels: [feature, blender, metadata]\r\n Created: 2025-04-22\r\n Updated: 2025-04-22\r\n@@ -26,7 +26,7 @@\n ## Implementation Notes (Optional)\r\n (This will require modifying `blenderscripts/create_nodegroups.py` to read the `metadata.json` file, check the `category` field, and use the Blender Python API (`bpy`) to add tags to the created asset.)\r\n \r\n ## Acceptance Criteria (Optional)\r\n-* [ ] Run the nodegroup generation script on a processed asset library containing assets of different categories (Surface, Decal, Asset).\r\n-* [ ] Verify that nodegroups are created only for Surface and Decal assets.\r\n-* [ ] Verify that assets in the Blender file (both those with generated nodegroups and those skipped) have a tag corresponding to their category from `metadata.json`.\n\\ No newline at end of file\n+* [x] Run the nodegroup generation script on a processed asset library containing assets of different categories (Surface, Decal, Asset).\r\n+* [x] Verify that nodegroups are created only for Surface and Decal assets.\r\n+* [x] Verify that assets in the Blender file (both those with generated nodegroups and those skipped) have a tag corresponding to their category from `metadata.json`.\n\\ No newline at end of file\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745307144919,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "---\r\nID: FEAT-003\r\nType: Feature\r\nStatus: Backlog\r\nPriority: Medium\r\nLabels: [feature, blender, metadata]\r\nCreated: 2025-04-22\r\nUpdated: 2025-04-22\r\nRelated:\r\n---\r\n\r\n# [FEAT-003]: Selective Nodegroup Generation and Category Tagging in Blender\r\n\r\n## Description\r\nEnhance the Blender nodegroup creation script (`blenderscripts/create_nodegroups.py`) to only generate nodegroups for assets classified as \"Surface\" or \"Decal\" based on the `category` field in their `metadata.json` file. Additionally, store the asset's category (Surface, Decal, or Asset) as a tag on the generated Blender asset for better organization and filtering within Blender.\r\n\r\n## Current Behavior\r\nThe current nodegroup generation script processes all assets found in the processed asset library root, regardless of their `category` specified in `metadata.json`. It does not add the asset's category as a tag in Blender.\r\n\r\n## Desired Behavior / Goals\r\n1. The script should read the `category` field from the `metadata.json` file for each processed asset.\r\n2. If the `category` is \"Surface\" or \"Decal\", the script should proceed with generating the nodegroup.\r\n3. If the `category` is \"Asset\" (or any other category), the script should skip nodegroup generation for that asset.\r\n4. The script should add the asset's `category` (e.g., \"Surface\", \"Decal\", \"Asset\") as a tag to the corresponding generated Blender asset.\r\n\r\n## Implementation Notes (Optional)\r\n(This will require modifying `blenderscripts/create_nodegroups.py` to read the `metadata.json` file, check the `category` field, and use the Blender Python API (`bpy`) to add tags to the created asset.)\r\n\r\n## Acceptance Criteria (Optional)\r\n* [ ] Run the nodegroup generation script on a processed asset library containing assets of different categories (Surface, Decal, Asset).\r\n* [ ] Verify that nodegroups are created only for Surface and Decal assets.\r\n* [ ] Verify that assets in the Blender file (both those with generated nodegroups and those skipped) have a tag corresponding to their category from `metadata.json`."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
22
.lh/Tickets/FEAT-004-handle-multi-asset-inputs.md.json
Normal file
22
.lh/Tickets/FEAT-004-handle-multi-asset-inputs.md.json
Normal file
File diff suppressed because one or more lines are too long
22
.lh/Tickets/FEAT-008-gui-preview-refinement.md.json
Normal file
22
.lh/Tickets/FEAT-008-gui-preview-refinement.md.json
Normal file
File diff suppressed because one or more lines are too long
22
.lh/Tickets/FEAT-009-gui-unify-preset-selection.md.json
Normal file
22
.lh/Tickets/FEAT-009-gui-unify-preset-selection.md.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/FEAT-009-gui-unify-preset-selection.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 1,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745326044000,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745326465662,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -1,7 +1,7 @@\n # FEAT-009: GUI - Unify Preset Editor Selection and Processing Preset\r\n \r\n-**Status:** Open\r\n+**Status:** Resolved\r\n **Priority:** Medium\r\n **Assigned:** TBD\r\n **Reporter:** Roo (Architect Mode)\r\n **Date:** 2025-04-22\r\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745326044000,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# FEAT-009: GUI - Unify Preset Editor Selection and Processing Preset\r\n\r\n**Status:** Open\r\n**Priority:** Medium\r\n**Assigned:** TBD\r\n**Reporter:** Roo (Architect Mode)\r\n**Date:** 2025-04-22\r\n\r\n## Description\r\n\r\nThis ticket proposes a GUI modification to streamline the preset handling workflow by unifying the preset selection mechanism. Currently, the preset selected for editing in the left panel can be different from the preset selected for processing/previewing in the right panel. This change aims to eliminate this duality, making the preset loaded in the editor the single source of truth for both editing and processing actions.\r\n\r\n## Current Behavior\r\n\r\n1. **Preset Editor Panel (Left):** Users select a preset from the 'Preset List'. This action loads the selected preset's details into the 'Preset Editor Tabs' for viewing or modification (See `readme.md` lines 257-260).\r\n2. **Processing Panel (Right):** A separate 'Preset Selector' dropdown exists. Users select a preset from this dropdown *specifically* for processing the queued assets and generating the file preview in the 'Preview Table' (See `readme.md` lines 262, 266).\r\n3. This allows for a scenario where the preset being edited is different from the preset used for previewing and processing, potentially causing confusion.\r\n\r\n## Proposed Behavior\r\n\r\n1. **Unified Selection:** Selecting a preset from the 'Preset List' in the left panel will immediately make it the active preset for *both* editing (loading its details into the 'Preset Editor Tabs') *and* processing/previewing.\r\n2. **Dropdown Removal:** The separate 'Preset Selector' dropdown in the right 'Processing Panel' will be removed.\r\n3. **Dynamic Updates:** The 'Preview Table' in the right panel will dynamically update based on the preset selected in the left panel's 'Preset List'.\r\n4. **Processing Logic:** The 'Start Processing' action will use the currently active preset (selected from the left panel's list).\r\n\r\n## Rationale\r\n\r\n* **Improved User Experience:** Simplifies the UI by removing a redundant control and creates a more intuitive workflow.\r\n* **Reduced Complexity:** Eliminates the need to manage two separate preset states (editing vs. processing).\r\n* **Consistency:** Ensures that the preview and processing actions always reflect the preset currently being viewed/edited.\r\n\r\n## Implementation Notes/Tasks\r\n\r\n* **UI Modification (`gui/main_window.py`):**\r\n * Remove the `QComboBox` (or similar widget) used for the 'Preset Selector' from the right 'Processing Panel' layout.\r\n* **Signal/Slot Connection (`gui/main_window.py`):**\r\n * Ensure the signal emitted when a preset is selected in the left panel's 'Preset List' (`QListWidget` or similar) is connected to slots responsible for:\r\n * Loading the preset into the editor tabs.\r\n * Updating the application's state to reflect the new active preset for processing.\r\n * Triggering an update of the 'Preview Table'.\r\n* **State Management:**\r\n * Modify how the currently active preset for processing is stored and accessed. It should now directly reference the preset selected in the left panel list.\r\n* **Handler Updates (`gui/prediction_handler.py`, `gui/processing_handler.py`):**\r\n * Ensure these handlers correctly retrieve and use the single, unified active preset state when generating previews or initiating processing.\r\n\r\n## Acceptance Criteria\r\n\r\n1. The 'Preset Selector' dropdown is no longer visible in the right 'Processing Panel'.\r\n2. Selecting a preset in the 'Preset List' (left panel) successfully loads its details into the 'Preset Editor Tabs'.\r\n3. Selecting a preset in the 'Preset List' (left panel) updates the 'Preview Table' (right panel) to reflect the rules of the newly selected preset.\r\n4. Initiating processing via the 'Start Processing' button uses the preset currently selected in the 'Preset List' (left panel).\r\n5. The application remains stable and performs processing correctly with the unified preset selection.\r\n\r\n## Workflow Diagram (Mermaid)\r\n\r\n```mermaid\r\ngraph TD\r\n subgraph \"Current GUI\"\r\n A[Preset List (Left Panel)] -- Selects --> B(Preset Editor Tabs);\r\n C[Preset Selector Dropdown (Right Panel)] -- Selects --> D(Active Processing Preset);\r\n D -- Affects --> E(Preview Table);\r\n D -- Used by --> F(Processing Logic);\r\n end\r\n\r\n subgraph \"Proposed GUI\"\r\n G[Preset List (Left Panel)] -- Selects --> H(Preset Editor Tabs);\r\n G -- Also Sets --> I(Active Preset for Editing & Processing);\r\n I -- Affects --> J(Preview Table);\r\n I -- Used by --> K(Processing Logic);\r\n L(Preset Selector Dropdown Removed);\r\n end\r\n\r\n A --> G;\r\n B --> H;\r\n E --> J;\r\n F --> K;"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Tickets/FEAT-011-pot-resizing.md.json
Normal file
18
.lh/Tickets/FEAT-011-pot-resizing.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/FEAT-011-pot-resizing.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745340344932,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745340344932,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Ticket: FEAT-011 - Implement Power-of-Two Texture Resizing\r\n\r\n**Status:** Open\r\n**Priority:** High\r\n**Assignee:** TBD\r\n**Reporter:** Roo (Architect Mode)\r\n\r\n## Description\r\n\r\nThe current asset processing pipeline resizes textures based on a target maximum dimension (e.g., 4K = 4096px) while maintaining the original aspect ratio. This results in non-power-of-two (NPOT) dimensions for non-square textures, which is suboptimal for rendering performance and compatibility with certain systems.\r\n\r\nThis feature implements a \"Stretch/Squash\" approach to ensure all output textures have power-of-two (POT) dimensions for each target resolution key.\r\n\r\n## Proposed Solution\r\n\r\n1. **Resizing Logic Change:**\r\n * Modify the `calculate_target_dimensions` helper function in `asset_processor.py`.\r\n * **Step 1:** Calculate intermediate dimensions (`scaled_w`, `scaled_h`) by scaling the original image (orig_w, orig_h) to fit within the target resolution key's maximum dimension (e.g., 4096 for \"4K\") while maintaining the original aspect ratio (using existing logic).\r\n * **Step 2:** Implement a new helper function `get_nearest_pot(value: int) -> int` to find the closest power-of-two value for a given integer.\r\n * **Step 3:** Apply `get_nearest_pot()` to `scaled_w` to get the final target power-of-two width (`pot_w`).\r\n * **Step 4:** Apply `get_nearest_pot()` to `scaled_h` to get the final target power-of-two height (`pot_h`).\r\n * **Step 5:** Return `(pot_w, pot_h)` from `calculate_target_dimensions`. The `_process_maps` function will then use these POT dimensions in `cv2.resize`.\r\n\r\n2. **Helper Function `get_nearest_pot`:**\r\n * This function will take an integer `value`.\r\n * It will find the powers of two immediately below (`lower_pot`) and above (`upper_pot`) the value.\r\n * It will return the power of two that is numerically closer to the original `value`. (e.g., `get_nearest_pot(1365)` would return 1024, as `1365 - 1024 = 341` and `2048 - 1365 = 683`).\r\n\r\n3. **Filename Convention:**\r\n * The original resolution tag (e.g., `_4K`, `_2K`) defined in `config.py` will be kept in the output filename, even though the final dimensions are POT. This maintains consistency with the processing target.\r\n\r\n4. **Metadata:**\r\n * The existing aspect ratio change metadata calculation (`_normalize_aspect_ratio_change`) will remain unchanged. This metadata can be used downstream to potentially correct the aspect ratio distortion introduced by the stretch/squash resizing.\r\n\r\n## Implementation Diagram\r\n\r\n```mermaid\r\ngraph TD\r\n A[Original Dimensions (W, H)] --> B{Target Resolution Key (e.g., \"4K\")};\r\n B --> C{Get Max Dimension (e.g., 4096)};\r\n A & C --> D[Calculate Scaled Dimensions (scaled_w, scaled_h) - Maintain Aspect Ratio];\r\n D --> E[scaled_w];\r\n D --> F[scaled_h];\r\n E --> G[Find Nearest POT(scaled_w) -> pot_w];\r\n F --> H[Find Nearest POT(scaled_h) -> pot_h];\r\n G & H --> I[Final POT Dimensions (pot_w, pot_h)];\r\n I --> J[Use (pot_w, pot_h) in cv2.resize];\r\n```\r\n\r\n## Acceptance Criteria\r\n\r\n* All textures output by the `_process_maps` function have power-of-two dimensions (width and height are both powers of 2).\r\n* The resizing uses the \"Stretch/Squash\" method based on the nearest POT value for each dimension calculated *after* initial aspect-preserving scaling.\r\n* The output filename retains the original resolution key (e.g., `_4K`).\r\n* The `get_nearest_pot` helper function correctly identifies the closest power of two.\r\n* The aspect ratio metadata calculation remains unchanged."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Tickets/FEAT-GUI-NoDefaultPreset.md.json
Normal file
18
.lh/Tickets/FEAT-GUI-NoDefaultPreset.md.json
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-001-source-naming-rules-not-respected.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745307127879,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745307127879,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "---\r\nID: ISSUE-001\r\nType: Issue\r\nStatus: Backlog\r\nPriority: Medium\r\nLabels: [bug, config, gui]\r\nCreated: 2025-04-22\r\nUpdated: 2025-04-22\r\nRelated:\r\n---\r\n\r\n# [ISSUE-001]: Source file naming rules from JSON are not respected\r\n\r\n## Description\r\nThe tool is not correctly applying the \"Source file naming rules\" defined in the JSON presets. Specifically, the \"base Name index\" and \"Map type index\" values within the `source_naming` section of the preset JSON are not being respected during file processing.\r\n\r\n## Current Behavior\r\nWhen processing assets, the tool (observed in the GUI) does not use the specified \"base Name index\" and \"Map type index\" from the active preset's `source_naming` rules to determine the asset's base name and individual map types from the source filenames.\r\n\r\n## Desired Behavior / Goals\r\nThe tool should accurately read and apply the \"base Name index\" and \"Map type index\" values from the selected preset's `source_naming` rules to correctly parse asset base names and map types from source filenames.\r\n\r\n## Implementation Notes (Optional)\r\n(Add any thoughts on how this could be implemented, technical challenges, relevant code sections, or ideas for a solution.)\r\n\r\n## Acceptance Criteria (Optional)\r\n(Define clear, testable criteria that must be met for the ticket to be considered complete.)\r\n* [ ] Processing an asset with a preset that uses specific `base_name_index` and `map_type_index` values results in the correct asset name and map types being identified according to those indices.\r\n* [ ] This behavior is consistent in both the GUI and CLI."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-002-incorrect-col-numbering-multiple-assets.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745307136334,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745307136334,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "---\r\nID: ISSUE-002\r\nType: Issue\r\nStatus: Backlog\r\nPriority: High\r\nLabels: [bug, core, file-classification]\r\nCreated: 2025-04-22\r\nUpdated: 2025-04-22\r\nRelated:\r\n---\r\n\r\n# [ISSUE-002]: Incorrect COL-# numbering with multiple assets in one directory\r\n\r\n## Description\r\nWhen processing a directory containing multiple distinct asset sets (e.g., `Assetname1` and `Assetname2`), the numbering for map types that require variant suffixes (like \"COL\") is incorrectly incremented across all assets in the directory rather than being reset for each individual asset.\r\n\r\n## Current Behavior\r\nIf an input directory contains files for `Assetname1` and `Assetname2`, and both have multiple \"COL\" maps, the numbering continues sequentially across both sets. For example, `Assetname1` might get `_COL-1`, `_COL-2`, while `Assetname2` incorrectly gets `_COL-3`, `_COL-4`, instead of starting its own sequence (`_COL-1`, `_COL-2`). The \"COL value accumulates across directory, not comparing names\".\r\n\r\n## Desired Behavior / Goals\r\nThe tool should correctly identify distinct asset sets within a single input directory and apply variant numbering (like \"COL-#\") independently for each asset set. The numbering should reset for each new asset encountered in the directory.\r\n\r\n## Implementation Notes (Optional)\r\n(This likely requires adjusting the file classification or inventory logic to group files by asset name before applying variant numbering rules.)\r\n\r\n## Acceptance Criteria (Optional)\r\n* [ ] Processing a directory containing multiple asset sets with variant map types results in correct, independent numbering for each asset set (e.g., `Assetname1_COL-1`, `Assetname1_COL-2`, `Assetname2_COL-1`, `Assetname2_COL-2`).\r\n* [ ] The numbering is based on the files belonging to a specific asset name, not the overall count of variant maps in the entire input directory."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
26
.lh/Tickets/ISSUE-004-color-channel-swapping.md.json
Normal file
26
.lh/Tickets/ISSUE-004-color-channel-swapping.md.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-004-color-channel-swapping.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 2,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745307154166,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745313700401,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -1,8 +1,8 @@\n ---\r\n ID: ISSUE-004\r\n Type: Issue\r\n-Status: Backlog\r\n+Status: Resolved\r\n Priority: High\r\n Labels: [bug, core, image-processing]\r\n Created: 2025-04-22\r\n Updated: 2025-04-22\r\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745335105823,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -25,5 +25,14 @@\n \r\n ## Acceptance Criteria (Optional)\r\n * [ ] Process an asset with a normal map and a map requiring channel packing (e.g., NRMRGH).\r\n * [ ] Verify that the channels in the output normal map and packed map are in the correct R, G, B order.\r\n-* [ ] Verify that the calculated image statistics (Min/Max/Mean) for Red and Blue channels accurately reflect the data in those specific channels, not the swapped data.\n\\ No newline at end of file\n+* [ ] Verify that the calculated image statistics (Min/Max/Mean) for Red and Blue channels accurately reflect the data in those specific channels, not the swapped data.\r\n+## Resolution\r\n+The root cause was identified as a mismatch between OpenCV's default BGR channel order upon image loading (`cv2.imread`) and subsequent code assuming an RGB channel order, particularly in channel indexing during map merging (`_merge_maps`) and potentially in statistics calculation (`_calculate_image_stats`).\r\n+\r\n+The fix involved the following changes in `asset_processor.py`:\r\n+1. **BGR to RGB Conversion:** Immediately after loading a 3-channel image using `cv2.imread` in the `_process_maps` function, the image is converted to RGB color space using `img_processed = cv2.cvtColor(img_loaded, cv2.COLOR_BGR2RGB)`. Grayscale or 4-channel images are handled appropriately without conversion.\r\n+2. **Updated Channel Indexing:** The channel indexing logic within the `_merge_maps` function was updated to reflect the RGB order (Red = index 0, Green = index 1, Blue = index 2) when extracting channels from the now-RGB source images for merging.\r\n+3. **Statistics Assumption Update:** Comments in `_calculate_image_stats` were updated to reflect that the input data is now expected in RGB order.\r\n+\r\n+This ensures consistent RGB channel ordering throughout the processing pipeline after the initial load.\n\\ No newline at end of file\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745307154166,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "---\r\nID: ISSUE-004\r\nType: Issue\r\nStatus: Backlog\r\nPriority: High\r\nLabels: [bug, core, image-processing]\r\nCreated: 2025-04-22\r\nUpdated: 2025-04-22\r\nRelated:\r\n---\r\n\r\n# [ISSUE-004]: Color channel swapping in image processing (Normal Maps, Stats)\r\n\r\n## Description\r\nThere appears to be a general issue with how color channels (specifically Red and Blue) are handled in several parts of the image processing pipeline. This has been observed in normal map channel packing and potentially in the calculation of image statistics per channel, where the Red and Blue channels seem to be swapped relative to their intended order.\r\n\r\n## Current Behavior\r\nWhen processing images where individual color channels are accessed or manipulated (e.g., during normal map channel packing or calculating per-channel image statistics), the Red and Blue channels appear to be swapped. For example, in normal map packing, the channel intended for Blue might contain Red data, and vice versa, while Green remains correct. This suggests a consistent R/B channel inversion issue in the underlying image processing logic.\r\n\r\n## Desired Behavior / Goals\r\nThe tool should correctly handle color channels according to standard RGB ordering in all image processing operations, including channel packing and image statistics calculation. The Red, Green, and Blue channels should consistently correspond to their intended data.\r\n\r\n## Implementation Notes (Optional)\r\n(This likely points to an issue in the image loading, channel splitting, merging, or processing functions, possibly related to the library used for image manipulation (e.g., OpenCV). Need to investigate how channels are accessed and ordered in relevant code sections like `_process_maps`, `_merge_maps`, and image statistics calculation.)\r\n\r\n## Acceptance Criteria (Optional)\r\n* [ ] Process an asset with a normal map and a map requiring channel packing (e.g., NRMRGH).\r\n* [ ] Verify that the channels in the output normal map and packed map are in the correct R, G, B order.\r\n* [ ] Verify that the calculated image statistics (Min/Max/Mean) for Red and Blue channels accurately reflect the data in those specific channels, not the swapped data."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
22
.lh/Tickets/ISSUE-005-alpha-mask-channel-incorrect.md.json
Normal file
22
.lh/Tickets/ISSUE-005-alpha-mask-channel-incorrect.md.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-005-alpha-mask-channel-incorrect.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 1,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745307162180,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745308662610,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -1,8 +1,8 @@\n ---\r\n ID: ISSUE-005\r\n Type: Issue\r\n-Status: Backlog\r\n+Status: Resolved\r\n Priority: High\r\n Labels: [bug, core, image-processing]\r\n Created: 2025-04-22\r\n Updated: 2025-04-22\r\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745307162180,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "---\r\nID: ISSUE-005\r\nType: Issue\r\nStatus: Backlog\r\nPriority: High\r\nLabels: [bug, core, image-processing]\r\nCreated: 2025-04-22\r\nUpdated: 2025-04-22\r\nRelated:\r\n---\r\n\r\n# [ISSUE-005]: Alpha Mask channel not processed correctly\r\n\r\n## Description\r\nWhen processing source images that contain an alpha channel intended for use as a MASK map, the tool's output for the MASK map is an RGBA image instead of a grayscale image derived solely from the alpha channel.\r\n\r\n## Current Behavior\r\nIf a source image (e.g., a PNG or TIF) has an alpha channel and is classified as a MASK map type, the resulting output MASK file retains the RGB channels (potentially with incorrect data or black/white values) in addition to the alpha channel, resulting in an RGBA output image.\r\n\r\n## Desired Behavior / Goals\r\nWhen processing a source image with an alpha channel for a MASK map type, the tool should extract only the alpha channel data and output a single-channel (grayscale) image representing the mask. The RGB channels from the source should be discarded for the MASK output.\r\n\r\n## Implementation Notes (Optional)\r\n(This requires modifying the image processing logic for MASK map types to specifically isolate and save only the alpha channel as a grayscale image. Need to check the relevant sections in `asset_processor.py` related to map processing and saving.)\r\n\r\n## Acceptance Criteria (Optional)\r\n* [ ] Process an asset containing a source image with an alpha channel intended as a MASK map.\r\n* [ ] Verify that the output MASK file is a grayscale image (single channel) and accurately represents the alpha channel data from the source.\r\n* [ ] Verify that the output MASK file does not contain redundant or incorrect RGB channel data."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Tickets/ISSUE-006-col-increment-multi-asset.md.json
Normal file
18
.lh/Tickets/ISSUE-006-col-increment-multi-asset.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-006-col-increment-multi-asset.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745318806220,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745318806220,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "---\r\nID: ISSUE-006 # e.g., FEAT-001, ISSUE-002\r\nType: Issue # Choose one: Issue or Feature\r\nStatus: Backlog # Choose one\r\nPriority: Medium # Choose one\r\nLabels: [core, bug, map_processing, multi_asset] # Add relevant labels from the list or define new ones\r\nCreated: 2025-04-22\r\nUpdated: 2025-04-22\r\nRelated: #FEAT-004-handle-multi-asset-inputs.md # Links to other tickets (e.g., #ISSUE-YYY), relevant files, or external URLs\r\n---\r\n\r\n# [ISSUE-006]: COL-# Suffixes Incorrectly Increment Across Multi-Asset Inputs\r\n\r\n## Description\r\nWhen processing an input (ZIP or folder) that contains files for multiple distinct assets, the numeric suffixes applied to map types listed in `RESPECT_VARIANT_MAP_TYPES` (such as \"COL\") are currently incremented globally across all files in the input, rather than being reset and incremented independently for each detected asset group.\r\n\r\n## Current Behavior\r\nIf an input contains files for AssetA (e.g., AssetA_COL.png, AssetA_COL_Variant.png) and AssetB (e.g., AssetB_COL.png), the output might incorrectly number them as AssetA_COL-1.png, AssetA_COL-2.png, and AssetB_COL-3.png. The expectation is that numbering should restart for each asset, resulting in AssetA_COL-1.png, AssetA_COL-2.png, and AssetB_COL-1.png.\r\n\r\n## Desired Behavior / Goals\r\nThe numeric suffix for map types in `RESPECT_VARIANT_MAP_TYPES` should be determined and applied independently for each distinct asset detected within a multi-asset input. The numbering should start from -1 for each asset group.\r\n\r\n## Implementation Notes (Optional)\r\n- The logic for assigning suffixes is primarily within `AssetProcessor._inventory_and_classify_files`.\r\n- This method currently classifies all files from the input together before determining asset groups.\r\n- The classification logic needs to be adjusted to perform suffix assignment *after* files have been grouped by their determined asset name.\r\n- This might require modifying the output of `_inventory_and_classify_files` or adding a new step after `_determine_base_metadata` to re-process or re-structure the classified files per asset for suffix assignment.\r\n\r\n## Acceptance Criteria (Optional)\r\n* [ ] Processing a multi-asset input containing multiple \"COL\" variants for different assets results in correct COL-# suffixes starting from -1 for each asset's output files.\r\n* [ ] The GUI preview accurately reflects the correct COL-# numbering for each file based on its predicted asset name.\r\n* [ ] The CLI processing output confirms the correct numbering in the generated filenames."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
22
.lh/Tickets/ISSUE-007-respect-variant-single-map.md.json
Normal file
22
.lh/Tickets/ISSUE-007-respect-variant-single-map.md.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-007-respect-variant-single-map.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 1,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745320213464,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745321266333,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -1,8 +1,8 @@\n ---\r\n ID: ISSUE-007 # e.g., FEAT-001, ISSUE-002\r\n Type: Issue # Choose one: Issue or Feature\r\n-Status: Backlog # Choose one\r\n+Status: Resolved # Choose one\r\n Priority: Medium # Choose one\r\n Labels: [core, bug, map_processing, suffix, regression] # Add relevant labels from the list or define new ones\r\n Created: 2025-04-22\r\n Updated: 2025-04-22\r\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745320213464,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "---\r\nID: ISSUE-007 # e.g., FEAT-001, ISSUE-002\r\nType: Issue # Choose one: Issue or Feature\r\nStatus: Backlog # Choose one\r\nPriority: Medium # Choose one\r\nLabels: [core, bug, map_processing, suffix, regression] # Add relevant labels from the list or define new ones\r\nCreated: 2025-04-22\r\nUpdated: 2025-04-22\r\nRelated: #ISSUE-006-col-increment-multi-asset.md # Links to other tickets (e.g., #ISSUE-YYY), relevant files, or external URLs\r\n---\r\n\r\n# [ISSUE-007]: Suffix Not Applied to Single Maps in RESPECT_VARIANT_MAP_TYPES\r\n\r\n## Description\r\nMap types listed in `config.py`'s `RESPECT_VARIANT_MAP_TYPES` (e.g., \"COL\") are expected to always receive a numeric suffix (e.g., \"-1\"), even if only one map of that type exists for a given asset. Following the fix for #ISSUE-006, this behavior is no longer occurring. Single maps of these types are now output without a suffix.\r\n\r\n## Current Behavior\r\nAn asset containing only one map file designated as \"COL\" (e.g., `AssetA_COL.png`) results in processed output files named like `AssetA_COL_4K.png`, without the `-1` suffix.\r\n\r\n## Desired Behavior / Goals\r\nAn asset containing only one map file designated as \"COL\" (or any other type listed in `RESPECT_VARIANT_MAP_TYPES`) should result in processed output files named like `AssetA_COL-1_4K.png`, correctly applying the numeric suffix even when it's the sole variant.\r\n\r\n## Implementation Notes (Optional)\r\n- The per-asset suffix assignment logic added in `AssetProcessor.process` (around line 233 in the previous diff) likely needs adjustment.\r\n- The condition `if respect_variants:` might need to be modified, or the loop/enumeration logic needs to explicitly handle the case where `len(maps_in_group) == 1` for types listed in `RESPECT_VARIANT_MAP_TYPES`.\r\n\r\n## Acceptance Criteria (Optional)\r\n* [ ] Processing an asset with a single \"COL\" map results in output files with the `COL-1` suffix.\r\n* [ ] Processing an asset with multiple \"COL\" maps still results in correctly incremented suffixes (`COL-1`, `COL-2`, etc.).\r\n* [ ] Map types *not* listed in `RESPECT_VARIANT_MAP_TYPES` continue to receive no suffix if only one exists."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
26
.lh/Tickets/ISSUE-010-color-channel-regression.md.json
Normal file
26
.lh/Tickets/ISSUE-010-color-channel-regression.md.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-010-color-channel-regression.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 2,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745335634854,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745335788240,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -41,5 +41,36 @@\n * [ ] Process an asset requiring map merging (e.g., ORM from Roughness, Metallic, AO). Verify the output merged map has correct RGB(A) channel order.\r\n * [ ] Verify image statistics in `metadata.json` remain correct (reflecting RGB values).\r\n * [ ] Verify grayscale maps are processed and saved correctly.\r\n * [ ] Verify normal maps are processed and saved correctly (as per ISSUE-004 fix).\r\n-* [ ] (Optional) Verify RGBA maps are processed and saved correctly.\n\\ No newline at end of file\n+* [ ] (Optional) Verify RGBA maps are processed and saved correctly.\r\n+---\r\n+\r\n+## Implementation Plan (Generated 2025-04-22)\r\n+\r\n+**Goal:** Correct the BGR/RGB channel order regression for saved color maps (introduced by the `ISSUE-004` fix) while maintaining the correct handling for statistics, grayscale maps, and EXR files.\r\n+\r\n+**Core Idea:** Convert the image data back from RGB to BGR *just before* saving with `cv2.imwrite`, but only for 3-channel images and formats where this conversion is necessary (e.g., PNG, JPG, TIF, but *not* EXR).\r\n+\r\n+**Plan Steps:**\r\n+\r\n+1. **Modify `_process_maps` Saving Logic (`asset_processor.py`):**\r\n+ * Before the primary `cv2.imwrite` call (around line 1182) and the fallback call (around line 1206), add logic to check if the image is 3-channel and the output format is *not* 'exr'. If true, convert the image from RGB to BGR using `cv2.cvtColor` and add a debug log message.\r\n+2. **Modify `_merge_maps` Saving Logic (`asset_processor.py`):**\r\n+ * Apply the same conditional RGB to BGR conversion logic before the primary `cv2.imwrite` call (around line 1505) and the fallback call (around line 1531), including a debug log message.\r\n+3. **Verification Strategy:**\r\n+ * Test with various 3-channel color maps (Albedo, Emission, etc.) and merged maps (NRMRGH, etc.) saved as PNG/JPG/TIF.\r\n+ * Verify correct RGB order in outputs.\r\n+ * Verify grayscale, EXR, and statistics calculation remain correct.\r\n+\r\n+**Mermaid Diagram:**\r\n+\r\n+```mermaid\r\n+graph TD\r\n+ subgraph \"_process_maps / _merge_maps Saving Step\"\r\n+ A[Prepare Final Image Data (in RGB)] --> B{Is it 3-Channel?};\r\n+ B -- Yes --> C{Output Format != 'exr'?};\r\n+ B -- No --> E[Save Image using cv2.imwrite];\r\n+ C -- Yes --> D(Convert Image RGB -> BGR);\r\n+ C -- No --> E;\r\n+ D --> E;\r\n+ end\n\\ No newline at end of file\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745339075067,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -1,10 +1,10 @@\n ---\r\n ID: ISSUE-010\r\n Type: Issue\r\n-Status: Backlog\r\n+Status: Resolved\r\n Priority: High\r\n-Labels: [bug, core, image-processing, regression]\r\n+Labels: [bug, core, image-processing, regression, resolved]\r\n Created: 2025-04-22\r\n Updated: 2025-04-22\r\n Related: #ISSUE-004, asset_processor.py\r\n ---\r\n@@ -36,16 +36,23 @@\n - Review `_merge_maps`: How are channels combined? Does the saving logic here also need adjustment?\r\n - Determine if the BGR->RGB conversion should be conditional or if a final RGB->BGR conversion is needed before saving specific map types.\r\n \r\n ## Acceptance Criteria (Optional)\r\n-* [ ] Process an asset containing standard RGB maps (e.g., Color/Albedo). Verify the output map has correct RGB channel order.\r\n-* [ ] Process an asset requiring map merging (e.g., ORM from Roughness, Metallic, AO). Verify the output merged map has correct RGB(A) channel order.\r\n-* [ ] Verify image statistics in `metadata.json` remain correct (reflecting RGB values).\r\n-* [ ] Verify grayscale maps are processed and saved correctly.\r\n-* [ ] Verify normal maps are processed and saved correctly (as per ISSUE-004 fix).\r\n+* [x] Process an asset containing standard RGB maps (e.g., Color/Albedo). Verify the output map has correct RGB channel order.\r\n+* [x] Process an asset requiring map merging (e.g., ORM from Roughness, Metallic, AO). Verify the output merged map has correct RGB(A) channel order.\r\n+* [x] Verify image statistics in `metadata.json` remain correct (reflecting RGB values).\r\n+* [x] Verify grayscale maps are processed and saved correctly.\r\n+* [x] Verify normal maps are processed and saved correctly (as per ISSUE-004 fix).\r\n * [ ] (Optional) Verify RGBA maps are processed and saved correctly.\r\n ---\r\n \r\n+## Resolution\r\n+The issue was resolved by implementing conditional RGB to BGR conversion immediately before saving images using `cv2.imwrite` within the `_process_maps` and `_merge_maps` methods in `asset_processor.py`.\r\n+\r\n+The logic checks if the image is 3-channel and if the target output format is *not* EXR. If both conditions are true, the image data is converted from the internal RGB representation back to BGR, which is the expected channel order for `cv2.imwrite` when saving formats like PNG, JPG, and TIF.\r\n+\r\n+This approach ensures that color maps are saved with the correct channel order in standard formats while leaving EXR files (which handle RGB correctly) and grayscale/single-channel images unaffected. It also preserves the internal RGB representation used for accurate image statistics calculation and channel merging, thus not reintroducing the issues fixed by `ISSUE-004`.\r\n+\r\n ## Implementation Plan (Generated 2025-04-22)\r\n \r\n **Goal:** Correct the BGR/RGB channel order regression for saved color maps (introduced by the `ISSUE-004` fix) while maintaining the correct handling for statistics, grayscale maps, and EXR files.\r\n \r\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745335634854,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "---\r\nID: ISSUE-010\r\nType: Issue\r\nStatus: Backlog\r\nPriority: High\r\nLabels: [bug, core, image-processing, regression]\r\nCreated: 2025-04-22\r\nUpdated: 2025-04-22\r\nRelated: #ISSUE-004, asset_processor.py\r\n---\r\n\r\n# [ISSUE-010]: Color Channel Swapping Regression for RGB/Merged Maps after ISSUE-004 Fix\r\n\r\n## Description\r\nThe resolution implemented for `ISSUE-004` successfully corrected the BGR/RGB channel handling for image statistics calculation and potentially normal map packing. However, this fix appears to have introduced a regression where standard RGB color maps and maps generated through merging operations are now being saved with swapped Blue and Red channels (BGR order) instead of the expected RGB order.\r\n\r\n## Current Behavior\r\n- Standard RGB texture maps (e.g., Diffuse, Albedo) loaded and processed are saved with BGR channel order.\r\n- Texture maps created by merging channels (e.g., ORM, NRMRGH) are saved with BGR channel order for their color components.\r\n- Image statistics (`metadata.json`) are calculated correctly based on RGB data.\r\n- Grayscale maps are handled correctly.\r\n- RGBA maps are assumed to be handled correctly (needs verification).\r\n\r\n## Desired Behavior / Goals\r\n- All processed color texture maps (both original RGB and merged maps) should be saved with the standard RGB channel order.\r\n- Image statistics should continue to be calculated correctly based on RGB data.\r\n- Grayscale and RGBA maps should retain their correct handling.\r\n- The fix should not reintroduce the problems solved by `ISSUE-004`.\r\n\r\n## Implementation Notes (Optional)\r\nThe issue likely stems from the universal application of `cv2.cvtColor(img_loaded, cv2.COLOR_BGR2RGB)` in `_process_maps` introduced in the `ISSUE-004` fix. While this ensures consistent RGB data for internal operations like statistics and merging (which now expects RGB), the final saving step (`cv2.imwrite`) might implicitly expect BGR data for color images, or the conversion needs to be selectively undone before saving certain map types.\r\n\r\nInvestigation needed in `asset_processor.py`:\r\n- Review `_process_maps`: Where is the BGR->RGB conversion happening? Is it applied to all 3-channel images?\r\n- Review `_process_maps` saving logic: How are different map types saved? Does `cv2.imwrite` expect RGB or BGR?\r\n- Review `_merge_maps`: How are channels combined? Does the saving logic here also need adjustment?\r\n- Determine if the BGR->RGB conversion should be conditional or if a final RGB->BGR conversion is needed before saving specific map types.\r\n\r\n## Acceptance Criteria (Optional)\r\n* [ ] Process an asset containing standard RGB maps (e.g., Color/Albedo). Verify the output map has correct RGB channel order.\r\n* [ ] Process an asset requiring map merging (e.g., ORM from Roughness, Metallic, AO). Verify the output merged map has correct RGB(A) channel order.\r\n* [ ] Verify image statistics in `metadata.json` remain correct (reflecting RGB values).\r\n* [ ] Verify grayscale maps are processed and saved correctly.\r\n* [ ] Verify normal maps are processed and saved correctly (as per ISSUE-004 fix).\r\n* [ ] (Optional) Verify RGBA maps are processed and saved correctly."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Tickets/ISSUE-011-blender-nodegroup-empty-assets.md.json
Normal file
18
.lh/Tickets/ISSUE-011-blender-nodegroup-empty-assets.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-011-blender-nodegroup-empty-assets.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745347846080,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745347846080,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "---\r\nID: ISSUE-011\r\nType: Issue\r\nStatus: Backlog\r\nPriority: Medium\r\nLabels: [blender, bug]\r\nCreated: 2025-04-22\r\nUpdated: 2025-04-22\r\nRelated:\r\n---\r\n\r\n# [ISSUE-011]: Blender nodegroup script creates empty assets for skipped items\r\n\r\n## Description\r\nThe Blender nodegroup creation script (`blenderscripts/create_nodegroups.py`) incorrectly generates empty asset entries in the target .blend file for assets that were skipped during the main processing pipeline. This occurs even though the main asset processor correctly identifies and skips these assets based on the overwrite flag.\r\n\r\n## Current Behavior\r\nWhen running the asset processor with the `--overwrite` flag set to false, if an asset's output directory and metadata.json already exist, the main processing pipeline correctly skips processing that asset. However, the subsequent Blender nodegroup creation script still attempts to create a nodegroup for this skipped asset, resulting in an empty or incomplete asset entry in the target .blend file.\r\n\r\n## Desired Behavior / Goals\r\nThe Blender nodegroup creation script should only attempt to create nodegroups for assets that were *actually processed* by the main asset processor, not those that were skipped. It should check if the asset was processed successfully before attempting nodegroup creation.\r\n\r\n## Implementation Notes (Optional)\r\nThe `main.py` script, which orchestrates the processing and calls the Blender scripts, needs to pass information about which assets were successfully processed to the Blender nodegroup script. The Blender script should then filter its operations based on this information.\r\n\r\n## Acceptance Criteria (Optional)\r\n* [ ] Running the asset processor with `--overwrite` false on inputs that already have processed outputs should result in the main processing skipping the asset.\r\n* [ ] The Blender nodegroup script, when run after a skipped processing run, should *not* create or update a nodegroup for the skipped asset.\r\n* [ ] Only assets that were fully processed should have corresponding nodegroups created/updated by the Blender script."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Tickets/ISSUE-012-mask-map-alpha-extraction.md.json
Normal file
18
.lh/Tickets/ISSUE-012-mask-map-alpha-extraction.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-012-mask-map-alpha-extraction.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745347937534,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745347937534,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "---\r\nID: ISSUE-012\r\nType: Issue\r\nStatus: Backlog\r\nPriority: High\r\nLabels: [core, bug, image processing]\r\nCreated: 2025-04-22\r\nUpdated: 2025-04-22\r\nRelated:\r\n---\r\n\r\n# [ISSUE-012]: MASK map processing fails to extract alpha channel from RGBA images\r\n\r\n## Description\r\nWhen processing texture sets that include MASK maps provided as RGBA images, the asset processor is expected to extract the alpha channel to represent the mask. However, the current implementation appears to be converting the RGBA image to grayscale instead of isolating the alpha channel. This results in incorrect MASK maps in the processed output.\r\n\r\n## Current Behavior\r\nThe asset processor, when encountering an RGBA image classified as a MASK map, converts the image to grayscale. The alpha channel information is lost or ignored during this process.\r\n\r\n## Desired Behavior / Goals\r\nFor RGBA images classified as MASK maps, the asset processor should extract the alpha channel and use it as the content for the output MASK map. The resulting MASK map should be a single-channel (grayscale) image representing the transparency or mask information from the original alpha channel.\r\n\r\n## Implementation Notes (Optional)\r\nThe image processing logic within `asset_processor.py` (likely in the `_process_maps` method or a related helper function) needs to be updated to specifically handle RGBA input images for MASK map types. It should identify the alpha channel and save it as a single-channel output image. Libraries like OpenCV or Pillow should provide functionality for accessing individual channels.\r\n\r\n## Acceptance Criteria (Optional)\r\n* [ ] Process an asset with an RGBA image designated as a MASK map according to the preset.\r\n* [ ] Verify that the output MASK map is a single-channel grayscale image.\r\n* [ ] Confirm that the grayscale values in the output MASK map correspond to the alpha values of the original RGBA input image."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Tickets/ISSUE-012-plan.md.json
Normal file
18
.lh/Tickets/ISSUE-012-plan.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-012-plan.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745348522990,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745348522990,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Plan for ISSUE-012: MASK map processing fails to extract alpha channel from RGBA images\r\n\r\n## Issue Description\r\nWhen processing texture sets that include MASK maps provided as RGBA images, the asset processor is expected to extract the alpha channel to represent the mask. However, the current implementation appears to be converting the RGBA image to grayscale instead of isolating the alpha channel, resulting in incorrect MASK maps. This issue affects all RGBA images classified as MASK, including plain 'MASK' and MASK variants (e.g., MASK-1).\r\n\r\n## Analysis\r\nBased on the code in `asset_processor.py`, specifically the `_load_and_transform_source` method, the issue likely stems from the order of operations. The current logic converts 4-channel BGRA images to 3-channel RGB *before* checking specifically for MASK types and attempting to extract the alpha channel. This means the alpha channel is lost before the code gets a chance to extract it. The condition `if map_type.upper() == 'MASK':` is too strict and does not cover MASK variants.\r\n\r\n## Detailed Plan\r\n\r\n1. **Analyze `_load_and_transform_source`:** Re-examine the `_load_and_transform_source` method in `asset_processor.py` to confirm the exact sequence of image loading, color space conversions, and MASK-specific handling. (Completed during initial analysis).\r\n2. **Modify MASK Handling Condition:** Change the current condition `if map_type.upper() == 'MASK':` to use the `_get_base_map_type` helper function, so it correctly identifies all MASK variants (e.g., 'MASK', 'MASK-1', 'MASK-2') and applies the special handling logic to them. The condition will become `if _get_base_map_type(map_type) == 'MASK':`.\r\n3. **Reorder and Refine Logic:**\r\n * The image will still be loaded with `cv2.IMREAD_UNCHANGED` for MASK types to ensure the alpha channel is initially present.\r\n * Immediately after loading, and *before* any general color space conversions (like BGR->RGB), check if the base map type is 'MASK' and if the loaded image is 4-channel (RGBA/BGRA).\r\n * If both conditions are true, extract the alpha channel (`img_loaded[:, :, 3]`) and use this single-channel data for subsequent processing steps (`img_prepared`).\r\n * If the base map type is 'MASK' but the loaded image is 3-channel (RGB/BGR), convert it to grayscale (`cv2.cvtColor(img_loaded, cv2.COLOR_BGR2GRAY)`) and use this for `img_prepared`.\r\n * If the base map type is 'MASK' and the loaded image is already 1-channel (grayscale), keep it as is.\r\n * If the base map type is *not* 'MASK', the existing BGR->RGB conversion logic for 3/4 channel images will be applied as before.\r\n4. **Review Subsequent Steps:** Verify that the rest of the `_load_and_transform_source` method (Gloss->Rough inversion, resizing, dtype conversion) correctly handles the single-channel image data that will now be produced for RGBA MASK inputs.\r\n5. **Testing:** Use the acceptance criteria outlined in `ISSUE-012` to ensure the fix works correctly.\r\n\r\n## Proposed Code Logic Flow\r\n\r\n```mermaid\r\ngraph TD\r\n A[Load Image (IMREAD_UNCHANGED for MASK)] --> B{Loading Successful?};\r\n B -- No --> C[Handle Load Error];\r\n B -- Yes --> D[Get Original Dtype & Shape];\r\n D --> E{Base Map Type is MASK?};\r\n E -- Yes --> F{Loaded Image is 4-Channel?};\r\n F -- Yes --> G[Extract Alpha Channel];\r\n F -- No --> H{Loaded Image is 3-Channel?};\r\n H -- Yes --> I[Convert BGR/RGB to Grayscale];\r\n H -- No --> J[Keep as is (Assume Grayscale)];\r\n G --> K[Set img_prepared to Mask Data];\r\n I --> K;\r\n J --> K;\r\n E -- No --> L{Loaded Image is 3 or 4-Channel?};\r\n L -- Yes --> M[Convert BGR/BGRA to RGB];\r\n L -- No --> N[Keep as is];\r\n M --> O[Set img_prepared to RGB Data];\r\n N --> O;\r\n K --> P[Proceed with other transformations (Gloss, Resize, etc.)];\r\n O --> P;\r\n P --> Q[Cache Result & Return];\r\n C --> Q;\r\n```\r\n\r\n## Acceptance Criteria (from ISSUE-012)\r\n* [ ] Process an asset with an RGBA image designated as a MASK map according to the preset.\r\n* [ ] Verify that the output MASK map is a single-channel grayscale image.\r\n* [ ] Confirm that the grayscale values in the output MASK map correspond to the alpha values of the original RGBA input image."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Tickets/ISSUE-013-merged-map-roughness-stats.md.json
Normal file
18
.lh/Tickets/ISSUE-013-merged-map-roughness-stats.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-013-merged-map-roughness-stats.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745348035401,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745348035401,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "---\r\nID: ISSUE-013\r\nType: Issue\r\nStatus: Backlog\r\nPriority: Medium\r\nLabels: [core, bug, refactor, image processing]\r\nCreated: 2025-04-22\r\nUpdated: 2025-04-22\r\nRelated: #REFACTOR-001-merge-from-source\r\n\r\n---\r\n\r\n# [ISSUE-013]: Image statistics calculation missing for roughness maps after merged map refactor\r\n\r\n## Description\r\nFollowing the recent refactor of the merged map processing logic, the calculation of image statistics (Min/Max/Mean) for roughness maps appears to have been omitted or broken. This data is valuable for quality control and metadata, and needs to be reimplemented for roughness maps, particularly when they are part of a merged texture like NRMRGH.\r\n\r\n## Current Behavior\r\nImage statistics (Min/Max/Mean) are not being calculated or stored for roughness maps after the merged map refactor.\r\n\r\n## Desired Behavior / Goals\r\nReimplement the image statistics calculation for roughness maps. Ensure that statistics are calculated correctly for standalone roughness maps and for roughness data when it is part of a merged map (e.g., the green channel in an NRMRGH map). The calculated statistics should be included in the `metadata.json` file for the asset.\r\n\r\n## Implementation Notes (Optional)\r\nReview the changes made during the merged map refactor (`REFACTOR-001-merge-from-source`). Identify where the image statistics calculation for roughness maps was previously handled and integrate it into the new merged map processing flow. Special consideration may be needed to extract the correct channel (green for NRMRGH) for calculation. The `_process_maps` and `_merge_maps` methods in `asset_processor.py` are likely relevant areas.\r\n\r\n## Acceptance Criteria (Optional)\r\n* [ ] Process an asset that includes a roughness map (standalone or as part of a merged map).\r\n* [ ] Verify that Min/Max/Mean statistics for the roughness data are calculated.\r\n* [ ] Confirm that the calculated roughness statistics are present and correct in the output `metadata.json` file."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Tickets/ISSUE-013-plan.md.json
Normal file
18
.lh/Tickets/ISSUE-013-plan.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-013-plan.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745348766875,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745348766875,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Plan to Resolve ISSUE-013: Merged Map Roughness Statistics\r\n\r\n**Objective:** Reimplement the calculation and inclusion of image statistics (Min/Max/Mean) for roughness data, covering both standalone roughness maps and roughness data used as a source channel in merged maps (specifically the green channel for NRMRGH), and ensure these statistics are present in the output `metadata.json` file.\r\n\r\n**Proposed Changes:**\r\n\r\n1. **Modify `_merge_maps_from_source`:**\r\n * Within the loop that processes each resolution for a merge rule, after successfully loading and transforming the source images into `loaded_inputs_data`, iterate through the `inputs_mapping` for the current rule.\r\n * Identify if any of the source map types in the `inputs_mapping` is 'ROUGH'.\r\n * If 'ROUGH' is used as a source, retrieve the corresponding loaded image data from `loaded_inputs_data`.\r\n * Calculate image statistics (Min/Max/Mean) for this ROUGH source image data using the existing `_calculate_image_stats` helper function.\r\n * Store these calculated statistics temporarily, associated with the output merged map type (e.g., 'NRMRGH') and the target channel it's mapped to (e.g., 'G').\r\n\r\n2. **Update Asset Metadata Structure:**\r\n * Introduce a new key in the asset's metadata dictionary (e.g., `merged_map_channel_stats`) to store statistics for specific channels within merged maps. This structure will hold the stats per merged map type, per channel, and per resolution (specifically the stats resolution defined in the config).\r\n\r\n3. **Modify `_generate_metadata_file`:**\r\n * When generating the final `metadata.json` file, retrieve the accumulated `merged_map_channel_stats` from the asset's metadata dictionary.\r\n * Include these statistics under a dedicated section in the output JSON, alongside the existing `image_stats_1k` for individual maps.\r\n\r\n**Data Flow for Statistics Calculation:**\r\n\r\n```mermaid\r\ngraph TD\r\n A[Source Image Files] --> B{_load_and_transform_source};\r\n B --> C[Resized/Transformed Image Data (float32)];\r\n C --> D{Is this source for a ROUGH map?};\r\n D -- Yes --> E{_calculate_image_stats};\r\n E --> F[Calculated Stats (Min/Max/Mean)];\r\n F --> G[Store in merged_map_channel_stats (in asset metadata)];\r\n C --> H{_merge_maps_from_source};\r\n H --> I[Merged Image Data];\r\n I --> J[_save_image];\r\n J --> K[Saved Merged Map File];\r\n G --> L[_generate_metadata_file];\r\n L --> M[metadata.json];\r\n\r\n subgraph Individual Map Processing\r\n A --> B;\r\n B --> C;\r\n C --> N{Is this an individual map?};\r\n N -- Yes --> E;\r\n E --> O[Store in image_stats_1k (in asset metadata)];\r\n C --> P[_save_image];\r\n P --> Q[Saved Individual Map File];\r\n O --> L;\r\n Q --> S[Organize Output Files];\r\n end\r\n\r\n subgraph Merged Map Processing\r\n A --> B;\r\n B --> C;\r\n C --> D;\r\n D -- Yes --> E;\r\n E --> G;\r\n C --> H;\r\n H --> I;\r\n I --> J;\r\n J --> K;\r\n K --> S;\r\n end\r\n\r\n L --> M;\r\n M --> S;\r\n```\r\n\r\nThis plan ensures that statistics are calculated for the roughness data at the appropriate stage (after loading and transformation, before merging) and correctly included in the metadata file, addressing the issue described in ISSUE-013."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-GUI-DisableDetailedPreview-Regression.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745332173688,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745332173688,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# ISSUE: GUI - \"Disable Detailed Preview\" feature regression\r\n\r\n**Ticket Type:** Issue\r\n**Priority:** Medium\r\n\r\n**Description:**\r\nThe \"Disable Detailed Preview\" feature in the GUI is currently not functioning correctly. When attempting to disable the detailed file preview (via the View menu), the GUI does not switch to the simpler asset list view. This regression prevents users from using the less detailed preview mode, which may impact performance or usability, especially when dealing with inputs containing a large number of files.\r\n\r\n**Steps to Reproduce:**\r\n1. Launch the GUI (`python -m gui.main_window`).\r\n2. Load an asset (ZIP or folder) into the drag and drop area. Observe the detailed preview table populating.\r\n3. Go to the \"View\" menu.\r\n4. Select/Deselect the \"Detailed File Preview\" option.\r\n\r\n**Expected Result:**\r\nThe preview table should switch between the detailed file list view and the simple asset list view when the menu option is toggled.\r\n\r\n**Actual Result:**\r\nThe preview table remains in the detailed file list view regardless of the \"Detailed File Preview\" menu option state.\r\n\r\n**Relevant Files/Components:**\r\n* `gui/main_window.py`: Likely contains the logic for the View menu and handling the toggle state.\r\n* `gui/prediction_handler.py`: Manages the background process that generates the detailed preview data. The GUI needs to be able to stop or not request this process when detailed preview is disabled.\r\n* `gui/preview_table_model.py`: Manages the data and display logic for the preview table. It should adapt its display based on whether detailed preview is enabled or disabled."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
22
.lh/Tickets/ISSUE-GUI-PreviewNotUpdatingOnDrop.md.json
Normal file
22
.lh/Tickets/ISSUE-GUI-PreviewNotUpdatingOnDrop.md.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/ISSUE-GUI-PreviewNotUpdatingOnDrop.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 1,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745858114191,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745858262336,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -29,5 +29,21 @@\n \r\n **Debugging Steps Taken:**\r\n - Confirmed `AssetProcessor.__init__` error was fixed.\r\n - Added logging to `PredictionHandler` and `MainWindow`.\r\n-- Logs confirmed `update_preview` is called on drop, but exits early due to no valid preset being selected via `currentItem()`.\n\\ No newline at end of file\n+- Logs confirmed `update_preview` is called on drop, but exits early due to no valid preset being selected via `currentItem()`.\r\n+## Related Changes (Session 2025-04-28)\r\n+\r\n+During a recent session, work was done to implement a feature allowing GUI editing of the file preview list, specifically the file status and predicted output name.\r\n+\r\n+This involved defining a data interface (`ProjectNotes/Data_Structures/Preview_Edit_Interface.md`) and modifying several GUI and backend components.\r\n+\r\n+Key files modified for this feature include:\r\n+- `gui/prediction_handler.py`\r\n+- `gui/preview_table_model.py`\r\n+- `gui/main_window.py`\r\n+- `gui/processing_handler.py`\r\n+- Core `asset_processor` logic\r\n+\r\n+The changes involved passing the editable `file_list` and `asset_properties` data structure through the prediction handler, to the preview table model, and finally to the processing handler. The preview table model was made editable to allow user interaction. The backend logic was updated to utilize this editable data.\r\n+\r\n+Debugging steps taken during this implementation included fixing indentation errors and resolving an `AssetProcessor` instantiation issue that occurred during the prediction phase.\n\\ No newline at end of file\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745858114191,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Issue: GUI Preview Not Updating on File Drop Without Preset Selection\r\n\r\n**ID:** ISSUE-GUI-PreviewNotUpdatingOnDrop\r\n**Date:** 2025-04-28\r\n**Status:** Open\r\n**Priority:** High\r\n\r\n**Description:**\r\nThe file preview list (`QTableView` in the main panel) does not populate when files or folders are dropped onto the application if a valid preset has not been explicitly selected *after* the application starts and *before* the drop event.\r\n\r\n**Root Cause:**\r\n- The `add_input_paths` method in `gui/main_window.py` correctly calls `update_preview` after files are added via drag-and-drop.\r\n- However, the `update_preview` method checks `self.editor_preset_list.currentItem()` to get the selected preset.\r\n- If no preset is selected, or if the placeholder \"--- Select a Preset ---\" is selected, `update_preview` correctly identifies this and returns *before* starting the `PredictionHandler` thread.\r\n- This prevents the file prediction from running and the preview table from being populated, even if assets have been added.\r\n\r\n**Expected Behavior:**\r\nDropping files should trigger a preview update based on the last valid preset selected by the user, or potentially prompt the user to select a preset if none has ever been selected. The preview should not remain empty simply because the user hasn't re-clicked the preset list immediately before dropping files.\r\n\r\n**Proposed Solution:**\r\n1. Modify `MainWindow` to store the last validly selected preset path.\r\n2. Update the `update_preview` method:\r\n - Instead of relying solely on `currentItem()`, use the stored last valid preset path if `currentItem()` is invalid or the placeholder.\r\n - If no valid preset has ever been selected, display a clear message in the status bar or a dialog box prompting the user to select a preset first.\r\n - Ensure the prediction handler is triggered with the correct preset name based on this updated logic.\r\n\r\n**Affected Files:**\r\n- `gui/main_window.py`\r\n\r\n**Debugging Steps Taken:**\r\n- Confirmed `AssetProcessor.__init__` error was fixed.\r\n- Added logging to `PredictionHandler` and `MainWindow`.\r\n- Logs confirmed `update_preview` is called on drop, but exits early due to no valid preset being selected via `currentItem()`."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
34
.lh/Tickets/README.md.json
Normal file
34
.lh/Tickets/README.md.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/README.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 4,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745305637426,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745305643051,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -0,0 +1,76 @@\n+# Issue and Feature Tracking\r\n+\r\n+This directory is used to track issues and feature ideas for the Asset Processor Tool using Markdown files.\r\n+\r\n+## Structure\r\n+\r\n+All ticket files are stored directly within the `Tickets/` directory.\r\n+\r\n+```mermaid\r\n+graph TD\r\n+ A[Asset_processor_tool] --> B(Tickets);\r\n+ A --> C(...other files/dirs...);\r\n+ B --> D(ISSUE-XXX-....md);\r\n+ B --> E(FEAT-XXX-....md);\r\n+ B --> F(_template.md);\r\n+```\r\n+\r\n+## File Naming Convention\r\n+\r\n+Ticket files should follow the convention: `TYPE-ID-short-description.md`\r\n+\r\n+* `TYPE`: `ISSUE` for bug reports or problems, `FEAT` for new features or enhancements.\r\n+* `ID`: A sequential three-digit number (e.g., `001`, `002`).\r\n+* `short-description`: A brief, hyphenated summary of the ticket's content.\r\n+\r\n+Examples:\r\n+* `ISSUE-001-gui-preview-bug.md`\r\n+* `FEAT-002-add-dark-mode.md`\r\n+\r\n+## Ticket Template (`_template.md`)\r\n+\r\n+Use the `_template.md` file as a starting point for creating new tickets. It includes YAML front matter for structured metadata and standard Markdown headings for the ticket content.\r\n+\r\n+```markdown\r\n+---\r\n+ID: TYPE-XXX # e.g., FEAT-001, ISSUE-002\r\n+Type: Issue | Feature # Choose one: Issue or Feature\r\n+Status: Backlog | Planned | In Progress | Blocked | Needs Review | Done | Won't Fix # Choose one\r\n+Priority: Low | Medium | High # Choose one\r\n+Labels: [gui, cli, core, blender, bug, feature, enhancement, docs, config] # Add relevant labels from the list or define new ones\r\n+Created: YYYY-MM-DD\r\n+Updated: YYYY-MM-DD\r\n+Related: # Links to other tickets (e.g., #ISSUE-YYY), relevant files, or external URLs\r\n+---\r\n+\r\n+# [TYPE-XXX]: Brief Title of Issue/Feature\r\n+\r\n+## Description\r\n+(Provide a detailed explanation of the issue or feature request. What is the problem you are trying to solve, or what is the new functionality you are proposing?)\r\n+\r\n+## Current Behavior\r\n+(Describe what happens currently. If reporting a bug, explain the steps to reproduce it. If proposing a feature, describe the current state without the feature.)\r\n+\r\n+## Desired Behavior / Goals\r\n+(Describe what *should* happen if the issue is resolved, or what the feature aims to achieve. Be specific about the desired outcome.)\r\n+\r\n+## Implementation Notes (Optional)\r\n+(Add any thoughts on how this could be implemented, potential technical challenges, relevant code sections, or ideas for a solution.)\r\n+\r\n+## Acceptance Criteria (Optional)\r\n+(Define clear, testable criteria that must be met for the ticket to be considered complete.)\r\n+* [ ] Criterion 1: The first condition that must be satisfied.\r\n+* [ ] Criterion 2: The second condition that must be satisfied.\r\n+* [ ] Add more criteria as needed.\r\n+\r\n+```\r\n+\r\n+## How to Use\r\n+\r\n+1. Create a new Markdown file in the `Tickets/` directory following the naming convention (`TYPE-ID-short-description.md`).\r\n+2. Copy the content from `_template.md` into your new file.\r\n+3. Fill in the YAML front matter and the Markdown sections with details about the issue or feature.\r\n+4. Update the `Status` and `Updated` fields as you work on the ticket.\r\n+5. Use the `Related` field to link to other relevant tickets or project files.\r\n+```\r\n+<line_count>78</line_count>\r\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745305674150,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -0,0 +1,76 @@\n+# Issue and Feature Tracking\r\n+\r\n+This directory is used to track issues and feature ideas for the Asset Processor Tool using Markdown files.\r\n+\r\n+## Structure\r\n+\r\n+All ticket files are stored directly within the `Tickets/` directory.\r\n+\r\n+```mermaid\r\n+graph TD\r\n+ A[Asset_processor_tool] --> B(Tickets);\r\n+ A --> C(...other files/dirs...);\r\n+ B --> D(ISSUE-XXX-....md);\r\n+ B --> E(FEAT-XXX-....md);\r\n+ B --> F(_template.md);\r\n+```\r\n+\r\n+## File Naming Convention\r\n+\r\n+Ticket files should follow the convention: `TYPE-ID-short-description.md`\r\n+\r\n+* `TYPE`: `ISSUE` for bug reports or problems, `FEAT` for new features or enhancements.\r\n+* `ID`: A sequential three-digit number (e.g., `001`, `002`).\r\n+* `short-description`: A brief, hyphenated summary of the ticket's content.\r\n+\r\n+Examples:\r\n+* `ISSUE-001-gui-preview-bug.md`\r\n+* `FEAT-002-add-dark-mode.md`\r\n+\r\n+## Ticket Template (`_template.md`)\r\n+\r\n+Use the `_template.md` file as a starting point for creating new tickets. It includes YAML front matter for structured metadata and standard Markdown headings for the ticket content.\r\n+\r\n+```markdown\r\n+---\r\n+ID: TYPE-XXX # e.g., FEAT-001, ISSUE-002\r\n+Type: Issue | Feature # Choose one: Issue or Feature\r\n+Status: Backlog | Planned | In Progress | Blocked | Needs Review | Done | Won't Fix # Choose one\r\n+Priority: Low | Medium | High # Choose one\r\n+Labels: [gui, cli, core, blender, bug, feature, enhancement, docs, config] # Add relevant labels from the list or define new ones\r\n+Created: YYYY-MM-DD\r\n+Updated: YYYY-MM-DD\r\n+Related: # Links to other tickets (e.g., #ISSUE-YYY), relevant files, or external URLs\r\n+---\r\n+\r\n+# [TYPE-XXX]: Brief Title of Issue/Feature\r\n+\r\n+## Description\r\n+(Provide a detailed explanation of the issue or feature request. What is the problem you are trying to solve, or what is the new functionality you are proposing?)\r\n+\r\n+## Current Behavior\r\n+(Describe what happens currently. If reporting a bug, explain the steps to reproduce it. If proposing a feature, describe the current state without the feature.)\r\n+\r\n+## Desired Behavior / Goals\r\n+(Describe what *should* happen if the issue is resolved, or what the feature aims to achieve. Be specific about the desired outcome.)\r\n+\r\n+## Implementation Notes (Optional)\r\n+(Add any thoughts on how this could be implemented, potential technical challenges, relevant code sections, or ideas for a solution.)\r\n+\r\n+## Acceptance Criteria (Optional)\r\n+(Define clear, testable criteria that must be met for the ticket to be considered complete.)\r\n+* [ ] Criterion 1: The first condition that must be satisfied.\r\n+* [ ] Criterion 2: The second condition that must be satisfied.\r\n+* [ ] Add more criteria as needed.\r\n+\r\n+```\r\n+\r\n+## How to Use\r\n+\r\n+1. Create a new Markdown file in the `Tickets/` directory following the naming convention (`TYPE-ID-short-description.md`).\r\n+2. Copy the content from `_template.md` into your new file.\r\n+3. Fill in the YAML front matter and the Markdown sections with details about the issue or feature.\r\n+4. Update the `Status` and `Updated` fields as you work on the ticket.\r\n+5. Use the `Related` field to link to other relevant tickets or project files.\r\n+```\r\n+<line_count>78</line_count>\r\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745307072622,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -0,0 +1,75 @@\n+# Issue and Feature Tracking\r\n+\r\n+This directory is used to track issues and feature ideas for the Asset Processor Tool using Markdown files.\r\n+\r\n+## Structure\r\n+\r\n+All ticket files are stored directly within the `Tickets/` directory.\r\n+\r\n+```mermaid\r\n+graph TD\r\n+ A[Asset_processor_tool] --> B(Tickets);\r\n+ A --> C(...other files/dirs...);\r\n+ B --> D(ISSUE-XXX-....md);\r\n+ B --> E(FEAT-XXX-....md);\r\n+ B --> F(_template.md);\r\n+```\r\n+\r\n+## File Naming Convention\r\n+\r\n+Ticket files should follow the convention: `TYPE-ID-short-description.md`\r\n+\r\n+* `TYPE`: `ISSUE` for bug reports or problems, `FEAT` for new features or enhancements.\r\n+* `ID`: A sequential three-digit number (e.g., `001`, `002`).\r\n+* `short-description`: A brief, hyphenated summary of the ticket's content.\r\n+\r\n+Examples:\r\n+* `ISSUE-001-gui-preview-bug.md`\r\n+* `FEAT-002-add-dark-mode.md`\r\n+\r\n+## Ticket Template (`_template.md`)\r\n+\r\n+Use the `_template.md` file as a starting point for creating new tickets. It includes YAML front matter for structured metadata and standard Markdown headings for the ticket content.\r\n+\r\n+```markdown\r\n+---\r\n+ID: TYPE-XXX # e.g., FEAT-001, ISSUE-002\r\n+Type: Issue | Feature # Choose one: Issue or Feature\r\n+Status: Backlog | Planned | In Progress | Blocked | Needs Review | Done | Won't Fix # Choose one\r\n+Priority: Low | Medium | High # Choose one\r\n+Labels: [gui, cli, core, blender, bug, feature, enhancement, docs, config] # Add relevant labels from the list or define new ones\r\n+Created: YYYY-MM-DD\r\n+Updated: YYYY-MM-DD\r\n+Related: # Links to other tickets (e.g., #ISSUE-YYY), relevant files, or external URLs\r\n+---\r\n+\r\n+# [TYPE-XXX]: Brief Title of Issue/Feature\r\n+\r\n+## Description\r\n+(Provide a detailed explanation of the issue or feature request. What is the problem you are trying to solve, or what is the new functionality you are proposing?)\r\n+\r\n+## Current Behavior\r\n+(Describe what happens currently. If reporting a bug, explain the steps to reproduce it. If proposing a feature, describe the current state without the feature.)\r\n+\r\n+## Desired Behavior / Goals\r\n+(Describe what *should* happen if the issue is resolved, or what the feature aims to achieve. Be specific about the desired outcome.)\r\n+\r\n+## Implementation Notes (Optional)\r\n+(Add any thoughts on how this could be implemented, potential technical challenges, relevant code sections, or ideas for a solution.)\r\n+\r\n+## Acceptance Criteria (Optional)\r\n+(Define clear, testable criteria that must be met for the ticket to be considered complete.)\r\n+* [ ] Criterion 1: The first condition that must be satisfied.\r\n+* [ ] Criterion 2: The second condition that must be satisfied.\r\n+* [ ] Add more criteria as needed.\r\n+\r\n+```\r\n+\r\n+## How to Use\r\n+\r\n+1. Create a new Markdown file in the `Tickets/` directory following the naming convention (`TYPE-ID-short-description.md`).\r\n+2. Copy the content from `_template.md` into your new file.\r\n+3. Fill in the YAML front matter and the Markdown sections with details about the issue or feature.\r\n+4. Update the `Status` and `Updated` fields as you work on the ticket.\r\n+5. Use the `Related` field to link to other relevant tickets or project files.\r\n+```\r\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745307082294,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -72,4 +72,5 @@\n 3. Fill in the YAML front matter and the Markdown sections with details about the issue or feature.\r\n 4. Update the `Status` and `Updated` fields as you work on the ticket.\r\n 5. Use the `Related` field to link to other relevant tickets or project files.\r\n ```\r\n+<line_count>78</line_count>\r\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745305637426,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Issue and Feature Tracking\r\n\r\nThis directory is used to track issues and feature ideas for the Asset Processor Tool using Markdown files.\r\n\r\n## Structure\r\n\r\nAll ticket files are stored directly within the `Tickets/` directory.\r\n\r\n```mermaid\r\ngraph TD\r\n A[Asset_processor_tool] --> B(Tickets);\r\n A --> C(...other files/dirs...);\r\n B --> D(ISSUE-XXX-....md);\r\n B --> E(FEAT-XXX-....md);\r\n B --> F(_template.md);\r\n```\r\n\r\n## File Naming Convention\r\n\r\nTicket files should follow the convention: `TYPE-ID-short-description.md`\r\n\r\n* `TYPE`: `ISSUE` for bug reports or problems, `FEAT` for new features or enhancements.\r\n* `ID`: A sequential three-digit number (e.g., `001`, `002`).\r\n* `short-description`: A brief, hyphenated summary of the ticket's content.\r\n\r\nExamples:\r\n* `ISSUE-001-gui-preview-bug.md`\r\n* `FEAT-002-add-dark-mode.md`\r\n\r\n## Ticket Template (`_template.md`)\r\n\r\nUse the `_template.md` file as a starting point for creating new tickets. It includes YAML front matter for structured metadata and standard Markdown headings for the ticket content.\r\n\r\n```markdown\r\n---\r\nID: TYPE-XXX # e.g., FEAT-001, ISSUE-002\r\nType: Issue | Feature # Choose one: Issue or Feature\r\nStatus: Backlog | Planned | In Progress | Blocked | Needs Review | Done | Won't Fix # Choose one\r\nPriority: Low | Medium | High # Choose one\r\nLabels: [gui, cli, core, blender, bug, feature, enhancement, docs, config] # Add relevant labels from the list or define new ones\r\nCreated: YYYY-MM-DD\r\nUpdated: YYYY-MM-DD\r\nRelated: # Links to other tickets (e.g., #ISSUE-YYY), relevant files, or external URLs\r\n---\r\n\r\n# [TYPE-XXX]: Brief Title of Issue/Feature\r\n\r\n## Description\r\n(Provide a detailed explanation of the issue or feature request. What is the problem you are trying to solve, or what is the new functionality you are proposing?)\r\n\r\n## Current Behavior\r\n(Describe what happens currently. If reporting a bug, explain the steps to reproduce it. If proposing a feature, describe the current state without the feature.)\r\n\r\n## Desired Behavior / Goals\r\n(Describe what *should* happen if the issue is resolved, or what the feature aims to achieve. Be specific about the desired outcome.)\r\n\r\n## Implementation Notes (Optional)\r\n(Add any thoughts on how this could be implemented, potential technical challenges, relevant code sections, or ideas for a solution.)\r\n\r\n## Acceptance Criteria (Optional)\r\n(Define clear, testable criteria that must be met for the ticket to be considered complete.)\r\n* [ ] Criterion 1: The first condition that must be satisfied.\r\n* [ ] Criterion 2: The second condition that must be satisfied.\r\n* [ ] Add more criteria as needed.\r\n\r\n```\r\n\r\n## How to Use\r\n\r\n1. Create a new Markdown file in the `Tickets/` directory following the naming convention (`TYPE-ID-short-description.md`).\r\n2. Copy the content from `_template.md` into your new file.\r\n3. Fill in the YAML front matter and the Markdown sections with details about the issue or feature.\r\n4. Update the `Status` and `Updated` fields as you work on the ticket.\r\n5. Use the `Related` field to link to other relevant tickets or project files.\r\n```\r\n<line_count>78</line_count>\r\n"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
22
.lh/Tickets/REFACTOR-001-merge-from-source.md.json
Normal file
22
.lh/Tickets/REFACTOR-001-merge-from-source.md.json
Normal file
File diff suppressed because one or more lines are too long
26
.lh/Tickets/REFACTOR-001-plan.md.json
Normal file
26
.lh/Tickets/REFACTOR-001-plan.md.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/REFACTOR-001-plan.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 2,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745343175929,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745344031618,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -51,5 +51,18 @@\n \r\n H2 -- Saves Temp Files --> I2{Processed/Merged Map Details};\r\n \r\n I2 --> J2(_generate_metadata_file);\r\n- J2 --> K2(_organize_output_files);\n\\ No newline at end of file\n+ J2 --> K2(_organize_output_files);\r\n+## Current Status (as of 2025-04-22 ~19:45 CET)\r\n+\r\n+* **DONE:** Step 1: Implemented `_load_and_transform_source` helper function (including caching logic) and inserted into `asset_processor.py`.\r\n+* **DONE:** Step 2: Implemented `_save_image` helper function and inserted into `asset_processor.py`.\r\n+* **DONE:** Step 5 (Partial): Updated `process` method to initialize `loaded_data_cache` and updated calls to use new function names (`_process_individual_maps`, `_merge_maps_from_source`) and pass the cache.\r\n+* **DONE:** Renamed function definitions: `_process_maps` -> `_process_individual_maps`, `_merge_maps` -> `_merge_maps_from_source`, and added `loaded_data_cache` parameter.\r\n+* **DONE:** Corrected syntax errors introduced during previous `apply_diff` operations (related to docstrings).\r\n+\r\n+## Remaining Steps:\r\n+\r\n+1. **Modify `_process_individual_maps` Logic:** Update the internal logic to correctly utilize `_load_and_transform_source` (with cache) and `_save_image` for maps not involved in merging.\r\n+2. **Modify `_merge_maps_from_source` Logic:** Update the internal logic to correctly utilize `_load_and_transform_source` (with cache) for *source* files, perform the channel merge, and then use `_save_image` for the merged result.\r\n+3. **Testing:** Thoroughly test the refactored code to ensure correctness, quality improvement, and acceptable performance.\n\\ No newline at end of file\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745344780240,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -62,7 +62,7 @@\n * **DONE:** Corrected syntax errors introduced during previous `apply_diff` operations (related to docstrings).\r\n \r\n ## Remaining Steps:\r\n \r\n-1. **Modify `_process_individual_maps` Logic:** Update the internal logic to correctly utilize `_load_and_transform_source` (with cache) and `_save_image` for maps not involved in merging.\r\n-2. **Modify `_merge_maps_from_source` Logic:** Update the internal logic to correctly utilize `_load_and_transform_source` (with cache) for *source* files, perform the channel merge, and then use `_save_image` for the merged result.\r\n-3. **Testing:** Thoroughly test the refactored code to ensure correctness, quality improvement, and acceptable performance.\n\\ No newline at end of file\n+1. **DONE:** Modify `_process_individual_maps` Logic: Updated the internal logic to correctly utilize `_load_and_transform_source` (with cache) and `_save_image` for maps not involved in merging.\r\n+2. **DONE:** Modify `_merge_maps_from_source` Logic: Updated the internal logic to correctly utilize `_load_and_transform_source` (with cache) for *source* files, perform the channel merge, and then use `_save_image` for the merged result.\r\n+3. **DONE:** Testing: User confirmed the refactored code works correctly.\n\\ No newline at end of file\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745343175929,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# Refactoring Plan for REFACTOR-001: Merge Maps From Source\r\n\r\nThis plan details the steps to implement the refactoring described in `Tickets/REFACTOR-001-merge-from-source.md`. The goal is to improve merged map quality by loading data directly from original source files, avoiding intermediate compression artifacts.\r\n\r\n## Final Plan Summary:\r\n\r\n1. **Implement `_load_and_transform_source` Helper:**\r\n * Loads source image, performs initial prep (BGR->RGB, gloss inversion), resizes to target resolution.\r\n * Includes an in-memory cache (passed from `process`) using a `(source_path, resolution_key)` key to store and retrieve resized results, avoiding redundant loading and resizing within a single `process` call.\r\n\r\n2. **Implement `_save_image` Helper:**\r\n * Encapsulates all saving logic: determining output format/bit depth based on rules, final data type/color space conversions, filename construction, saving with `cv2.imwrite`, and fallback logic (e.g., EXR->PNG).\r\n\r\n3. **Refactor `_process_maps` (Potential Rename):**\r\n * Modify to process only maps *not* used as inputs for any merge rule.\r\n * Calls `_load_and_transform_source` (passing cache) and `_save_image`.\r\n\r\n4. **Replace `_merge_maps` with `_merge_maps_from_source`:**\r\n * Iterates through merge rules.\r\n * Calls `_load_and_transform_source` (passing cache) for each required *source* input at target resolutions.\r\n * Merges the resulting channel data.\r\n * Calls `_save_image` to save the final merged map.\r\n\r\n5. **Update `process` Method:**\r\n * Initializes an empty cache dictionary (`loaded_data_cache = {}`) at the beginning of the method.\r\n * Passes this cache dictionary to all calls to `_load_and_transform_source` within its scope.\r\n * Coordinates calls to the refactored/new processing and merging functions.\r\n * Ensures results are collected correctly for metadata generation.\r\n\r\n## New Workflow Visualization:\r\n\r\n```mermaid\r\ngraph TD\r\n A2[Input Files] --> B2(_inventory_and_classify_files);\r\n B2 --> C2{Classified Maps Info};\r\n\r\n subgraph Processing Logic\r\n C2 --> D2(_process_individual_map);\r\n C2 --> E2(_merge_maps_from_source);\r\n D2 --> F2([_load_and_transform_source w/ Cache]);\r\n E2 --> F2;\r\n end\r\n\r\n F2 --> G2{Loaded/Transformed Data (Cached)};\r\n\r\n subgraph Saving Logic\r\n G2 --> H2([_save_image]);\r\n D2 --> H2;\r\n E2 --> H2;\r\n end\r\n\r\n H2 -- Saves Temp Files --> I2{Processed/Merged Map Details};\r\n\r\n I2 --> J2(_generate_metadata_file);\r\n J2 --> K2(_organize_output_files);"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/Tickets/_template.md.json
Normal file
18
.lh/Tickets/_template.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "Tickets/_template.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745307115578,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745307115578,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "---\r\nID: TYPE-XXX # e.g., FEAT-001, ISSUE-002\r\nType: Issue | Feature # Choose one: Issue or Feature\r\nStatus: Backlog | Planned | In Progress | Blocked | Needs Review | Done | Won't Fix # Choose one\r\nPriority: Low | Medium | High # Choose one\r\nLabels: [gui, cli, core, blender, bug, feature, enhancement, docs, config] # Add relevant labels from the list or define new ones\r\nCreated: YYYY-MM-DD\r\nUpdated: YYYY-MM-DD\r\nRelated: # Links to other tickets (e.g., #ISSUE-YYY), relevant files, or external URLs\r\n---\r\n\r\n# [TYPE-XXX]: Brief Title of Issue/Feature\r\n\r\n## Description\r\n(Provide a detailed explanation of the issue or feature request. What is the problem you are trying to solve, or what is the new functionality you are proposing?)\r\n\r\n## Current Behavior\r\n(Describe what happens currently. If reporting a bug, explain the steps to reproduce it. If proposing a feature, describe the current state without the feature.)\r\n\r\n## Desired Behavior / Goals\r\n(Describe what *should* happen if the issue is resolved, or what the feature aims to achieve. Be specific about the desired outcome.)\r\n\r\n## Implementation Notes (Optional)\r\n(Add any thoughts on how this could be implemented, potential technical challenges, relevant code sections, or ideas for a solution.)\r\n\r\n## Acceptance Criteria (Optional)\r\n(Define clear, testable criteria that must be met for the ticket to be considered complete.)\r\n* [ ] Criterion 1: The first condition that must be satisfied.\r\n* [ ] Criterion 2: The second condition that must be satisfied.\r\n* [ ] Add more criteria as needed."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
226
.lh/asset_processor.py.json
Normal file
226
.lh/asset_processor.py.json
Normal file
File diff suppressed because one or more lines are too long
22
.lh/blender_addon/material_merger/__init__.py.json
Normal file
22
.lh/blender_addon/material_merger/__init__.py.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "blender_addon/material_merger/__init__.py",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 1,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745659312702,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"date": 1745659349183,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n@@ -12,21 +12,21 @@\n \r\n import bpy\r\n \r\n # Import other modules (will be created later)\r\n-# from . import operator\r\n-# from . import panel\r\n+from . import operator\r\n+from . import panel\r\n \r\n def register():\r\n # Register classes from imported modules\r\n- # operator.register()\r\n- # panel.register()\r\n+ operator.register()\r\n+ panel.register()\r\n print(\"Material Merger Addon Registered\")\r\n \r\n def unregister():\r\n # Unregister classes from imported modules\r\n- # panel.unregister()\r\n- # operator.unregister()\r\n+ panel.unregister()\r\n+ operator.unregister()\r\n print(\"Material Merger Addon Unregistered\")\r\n \r\n if __name__ == \"__main__\":\r\n register()\n\\ No newline at end of file\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745659312702,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "bl_info = {\r\n \"name\": \"Material Merger\",\r\n \"author\": \"Your Name\", # Replace with your name\r\n \"version\": (1, 0),\r\n \"blender\": (3, 6, 0), # Minimum Blender version\r\n \"location\": \"Shader Editor > Sidebar > Material Merger\",\r\n \"description\": \"Merges two Asset Processor generated materials into a new material.\",\r\n \"warning\": \"\",\r\n \"doc_url\": \"\", # Optional documentation URL\r\n \"category\": \"Material\",\r\n}\r\n\r\nimport bpy\r\n\r\n# Import other modules (will be created later)\r\n# from . import operator\r\n# from . import panel\r\n\r\ndef register():\r\n # Register classes from imported modules\r\n # operator.register()\r\n # panel.register()\r\n print(\"Material Merger Addon Registered\")\r\n\r\ndef unregister():\r\n # Unregister classes from imported modules\r\n # panel.unregister()\r\n # operator.unregister()\r\n print(\"Material Merger Addon Unregistered\")\r\n\r\nif __name__ == \"__main__\":\r\n register()"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "blender_addon/material_merger/blender_files/utility_nodegroups.blend",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745659512531,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745659512531,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# This is a placeholder file.\r\n# Replace this file with a Blender file containing the 'MaterialMerge' node group.\r\n# The node group should have the following inputs:\r\n# - Shader A (Shader)\r\n# - Shader B (Shader)\r\n# - Displacement A (Vector)\r\n# - Displacement B (Vector)\r\n# And the following outputs:\r\n# - BSDF (Shader)\r\n# - Displacement (Vector)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
22
.lh/blender_addon/material_merger/operator.py.json
Normal file
22
.lh/blender_addon/material_merger/operator.py.json
Normal file
File diff suppressed because one or more lines are too long
18
.lh/blender_addon/material_merger/panel.py.json
Normal file
18
.lh/blender_addon/material_merger/panel.py.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "blender_addon/material_merger/panel.py",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745659339974,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745659339974,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "import bpy\r\nfrom bpy.types import Panel\r\nfrom .operator import MATERIAL_OT_merge_materials # Import the operator\r\n\r\nclass MATERIAL_PT_material_merger_panel(Panel):\r\n \"\"\"Creates a Panel in the Shader Editor sidebar\"\"\"\r\n bl_label = \"Material Merger\"\r\n bl_idname = \"MATERIAL_PT_material_merger_panel\"\r\n bl_space_type = 'NODE_EDITOR'\r\n bl_region_type = 'UI'\r\n bl_category = 'Tool' # Or 'Material' or a custom category\r\n\r\n def draw(self, context):\r\n layout = self.layout\r\n\r\n # Get the active material in the Shader Editor\r\n # This might be useful for defaulting one of the selectors\r\n # mat = context.material\r\n\r\n row = layout.row()\r\n row.label(text=\"Select Materials to Merge:\")\r\n\r\n # Use properties from the operator to store selected material names\r\n # The operator will read these when executed.\r\n # We'll use StringProperty for simplicity in the UI for now.\r\n # A more advanced UI might use PointerProperty to bpy.data.materials\r\n\r\n # Material A selection\r\n row = layout.row()\r\n row.prop(context.scene, \"material_merger_mat_a\", text=\"Material A\")\r\n\r\n # Material B selection\r\n row = layout.row()\r\n row.prop(context.scene, \"material_merger_mat_b\", text=\"Material B\")\r\n\r\n\r\n # Merge button\r\n row = layout.row()\r\n # Pass the selected material names to the operator when button is clicked\r\n row.operator(MATERIAL_OT_merge_materials.bl_idname, text=MATERIAL_OT_merge_materials.bl_label).material_a_name = context.scene.material_merger_mat_a\r\n row.operator(MATERIAL_OT_merge_materials.bl_idname, text=MATERIAL_OT_merge_materials.bl_label).material_b_name = context.scene.material_merger_mat_b\r\n\r\n\r\n# To store the selected material names, we need scene properties\r\n# These will be registered and unregistered with the addon\r\ndef register_properties():\r\n bpy.types.Scene.material_merger_mat_a = StringProperty(\r\n name=\"Material A Name\",\r\n description=\"Name of the first material to merge\",\r\n default=\"\"\r\n )\r\n bpy.types.Scene.material_merger_mat_b = StringProperty(\r\n name=\"Material B Name\",\r\n description=\"Name of the second material to merge\",\r\n default=\"\"\r\n )\r\n\r\ndef unregister_properties():\r\n del bpy.types.Scene.material_merger_mat_a\r\n del bpy.types.Scene.material_merger_mat_b\r\n\r\n\r\ndef register():\r\n register_properties()\r\n bpy.utils.register_class(MATERIAL_PT_material_merger_panel)\r\n print(\"MATERIAL_PT_material_merger_panel registered\")\r\n\r\ndef unregister():\r\n bpy.utils.unregister_class(MATERIAL_PT_material_merger_panel)\r\n unregister_properties()\r\n print(\"MATERIAL_PT_material_merger_panel unregistered\")\r\n\r\nif __name__ == \"__main__\":\r\n # This block is for running the script directly in Blender's text editor\r\n # It's useful for testing the panel layout without installing the addon\r\n register()"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
46
.lh/blenderscripts/create_materials.py.json
Normal file
46
.lh/blenderscripts/create_materials.py.json
Normal file
File diff suppressed because one or more lines are too long
130
.lh/blenderscripts/create_nodegroups.py.json
Normal file
130
.lh/blenderscripts/create_nodegroups.py.json
Normal file
File diff suppressed because one or more lines are too long
54
.lh/config.py.json
Normal file
54
.lh/config.py.json
Normal file
File diff suppressed because one or more lines are too long
26
.lh/configuration.py.json
Normal file
26
.lh/configuration.py.json
Normal file
File diff suppressed because one or more lines are too long
18
.lh/detailed_documentation_plan.md.json
Normal file
18
.lh/detailed_documentation_plan.md.json
Normal file
File diff suppressed because one or more lines are too long
30
.lh/documentation.txt.json
Normal file
30
.lh/documentation.txt.json
Normal file
File diff suppressed because one or more lines are too long
22
.lh/documentation_plan.md.json
Normal file
22
.lh/documentation_plan.md.json
Normal file
File diff suppressed because one or more lines are too long
190
.lh/gui/main_window.py.json
Normal file
190
.lh/gui/main_window.py.json
Normal file
File diff suppressed because one or more lines are too long
38
.lh/gui/prediction_handler.py.json
Normal file
38
.lh/gui/prediction_handler.py.json
Normal file
File diff suppressed because one or more lines are too long
106
.lh/gui/preview_table_model.py.json
Normal file
106
.lh/gui/preview_table_model.py.json
Normal file
File diff suppressed because one or more lines are too long
50
.lh/gui/processing_handler.py.json
Normal file
50
.lh/gui/processing_handler.py.json
Normal file
File diff suppressed because one or more lines are too long
18
.lh/llm_prototype/PLAN.md.json
Normal file
18
.lh/llm_prototype/PLAN.md.json
Normal file
File diff suppressed because one or more lines are too long
18
.lh/llm_prototype/README.md.json
Normal file
18
.lh/llm_prototype/README.md.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "llm_prototype/README.md",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745578490185,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745578490185,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# LLM Asset Classifier Prototype\r\n\r\nThis prototype demonstrates using a Large Language Model (LLM) to classify asset files and determine metadata from a list of filenames, particularly for irregularly named inputs and sources containing multiple assets.\r\n\r\n## Setup\r\n\r\n1. **Clone the repository:** If you haven't already, clone the main Asset Processor Tool repository.\r\n2. **Navigate to the prototype directory:** `cd llm_prototype/`\r\n3. **Create a Python Virtual Environment (Recommended):**\r\n ```bash\r\n python -m venv .venv\r\n ```\r\n4. **Activate the Virtual Environment:**\r\n * On Windows: `.venv\\Scripts\\activate`\r\n * On macOS/Linux: `source .venv/bin/activate`\r\n5. **Install Dependencies:**\r\n ```bash\r\n pip install -r requirements_llm.txt\r\n ```\r\n\r\n## Configuration\r\n\r\nEdit the `config_llm.py` file to configure the LLM API endpoint and other settings.\r\n\r\n* `LLM_API_ENDPOINT`: Set this to the URL of your LLM API. This could be a commercial API (like OpenAI) or a local server (like LM Studio).\r\n* `LLM_MODEL_NAME`: If your API requires a specific model name, set it here. Leave empty if not needed.\r\n* `LLM_API_KEY_ENV_VAR`: If your API requires an API key, set this to the name of the environment variable where your key is stored.\r\n\r\n**Important:** Do NOT put your API key directly in `config_llm.py`. Store it in an environment variable.\r\n\r\n**Example (Windows PowerShell):**\r\n```powershell\r\n$env:OPENAI_API_KEY=\"your_api_key_here\"\r\n```\r\n\r\n**Example (Linux/macOS Bash):**\r\n```bash\r\nexport OPENAI_API_KEY=\"your_api_key_here\"\r\n```\r\n*(Replace `OPENAI_API_KEY` and `\"your_api_key_here\"` as needed based on your `LLM_API_KEY_ENV_VAR` setting and actual key.)*\r\n\r\n## Running the Prototype\r\n\r\nThe prototype takes a JSON file containing a list of filenames as input.\r\n\r\n1. **Prepare Input:** Create a JSON file (e.g., in the `test_inputs/` directory) with a structure like this:\r\n ```json\r\n {\r\n \"files\": [\r\n \"path/to/file1.png\",\r\n \"path/to/model.fbx\",\r\n \"another_file.tif\"\r\n ]\r\n }\r\n ```\r\n The paths should be relative paths as they would appear within an extracted asset source directory.\r\n\r\n2. **Execute the script:**\r\n ```bash\r\n python llm_classifier.py <path_to_your_input_json_file>\r\n ```\r\n Replace `<path_to_your_input_json_file>` with the actual path to your input JSON file (e.g., `test_inputs/dinesen_example.json`).\r\n\r\nThe script will load the configuration, format the prompt, call the LLM API, extract and validate the JSON response, and print the validated output.\r\n\r\n## Development Notes\r\n\r\n* The LLM prompt template is in `prompt_template.txt`. Modify this file to adjust the instructions given to the LLM.\r\n* The core logic is in `llm_classifier.py`. This includes functions for loading config/input/prompt, calling the API, extracting JSON, and validating the output.\r\n* The validation logic in `llm_classifier.py` is crucial for ensuring the LLM's output conforms to the expected structure and values."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
82
.lh/llm_prototype/config_llm.py.json
Normal file
82
.lh/llm_prototype/config_llm.py.json
Normal file
File diff suppressed because one or more lines are too long
54
.lh/llm_prototype/llm_classifier.py.json
Normal file
54
.lh/llm_prototype/llm_classifier.py.json
Normal file
File diff suppressed because one or more lines are too long
86
.lh/llm_prototype/prompt_template.txt.json
Normal file
86
.lh/llm_prototype/prompt_template.txt.json
Normal file
File diff suppressed because one or more lines are too long
18
.lh/llm_prototype/requirements_llm.txt.json
Normal file
18
.lh/llm_prototype/requirements_llm.txt.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "llm_prototype/requirements_llm.txt",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745578468982,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745578468982,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "# llm_prototype/requirements_llm.txt\r\nrequests"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
.lh/llm_prototype/test_inputs/dinesen_example.json.json
Normal file
18
.lh/llm_prototype/test_inputs/dinesen_example.json.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "llm_prototype/test_inputs/dinesen_example.json",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745578497695,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745578497695,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "{\r\n \"files\": [\r\n \"3-HeartOak-RL-2-5m-300mm_COL-1_.jpg\",\r\n \"3-HeartOak-RL-2-5m-300mm_DISP_.jpg\",\r\n \"3-HeartOak-RL-2-5m-300mm_GLOSS_.jpg\",\r\n \"3-HeartOak-RL-2-5m-300mm_NRM_.jpg\",\r\n \"3-Oak-Classic-RL-2-5m-300mm_COL-1_.jpg\",\r\n \"3-Oak-Classic-RL-2-5m-300mm_DISP_.jpg\",\r\n \"3-Oak-Classic-RL-2-5m-300mm_GLOSS_.jpg\",\r\n \"3-Oak-Classic-RL-2-5m-300mm_NRM_.jpg\"\r\n ]\r\n}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "llm_prototype/test_inputs/imperfections_example.json",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745578504692,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745578504692,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "{\r\n \"files\": [\r\n \"DG-01-Smudges.tif\",\r\n \"DG-02-Scratches.tif\",\r\n \"DG-03-Smudges-Scratches.tif\",\r\n \"preview.jpg\",\r\n \"notes.txt\"\r\n ]\r\n}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
58
.lh/main.py.json
Normal file
58
.lh/main.py.json
Normal file
File diff suppressed because one or more lines are too long
18
.lh/monitor.py.json
Normal file
18
.lh/monitor.py.json
Normal file
File diff suppressed because one or more lines are too long
44
.lh/readme.md.json
Normal file
44
.lh/readme.md.json
Normal file
File diff suppressed because one or more lines are too long
18
.lh/requirements.txt.json
Normal file
18
.lh/requirements.txt.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"sourceFile": "requirements.txt",
|
||||||
|
"activeCommit": 0,
|
||||||
|
"commits": [
|
||||||
|
{
|
||||||
|
"activePatchIndex": 0,
|
||||||
|
"patches": [
|
||||||
|
{
|
||||||
|
"date": 1745506892012,
|
||||||
|
"content": "Index: \n===================================================================\n--- \n+++ \n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"date": 1745506892012,
|
||||||
|
"name": "Commit-0",
|
||||||
|
"content": "opencv-python\r\nnumpy\r\nopenexr\r\nPySide6\r\npy7zr\r\nrarfile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Binary file not shown.
BIN
.vs/Asset_processor_tool/v17/.wsuo
Normal file
BIN
.vs/Asset_processor_tool/v17/.wsuo
Normal file
Binary file not shown.
88
.vs/Asset_processor_tool/v17/DocumentLayout.backup.json
Normal file
88
.vs/Asset_processor_tool/v17/DocumentLayout.backup.json
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
{
|
||||||
|
"Version": 1,
|
||||||
|
"WorkspaceRootPath": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\",
|
||||||
|
"Documents": [
|
||||||
|
{
|
||||||
|
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\config.py||{3B902123-F8A7-4915-9F01-361F908088D0}",
|
||||||
|
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:config.py||{3B902123-F8A7-4915-9F01-361F908088D0}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\configuration.py||{3B902123-F8A7-4915-9F01-361F908088D0}",
|
||||||
|
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:configuration.py||{3B902123-F8A7-4915-9F01-361F908088D0}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\main.py||{3B902123-F8A7-4915-9F01-361F908088D0}",
|
||||||
|
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:main.py||{3B902123-F8A7-4915-9F01-361F908088D0}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\asset_processor.py||{3B902123-F8A7-4915-9F01-361F908088D0}",
|
||||||
|
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:asset_processor.py||{3B902123-F8A7-4915-9F01-361F908088D0}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"DocumentGroupContainers": [
|
||||||
|
{
|
||||||
|
"Orientation": 0,
|
||||||
|
"VerticalTabListWidth": 256,
|
||||||
|
"DocumentGroups": [
|
||||||
|
{
|
||||||
|
"DockedWidth": 200,
|
||||||
|
"SelectedChildIndex": 2,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"$type": "Document",
|
||||||
|
"DocumentIndex": 1,
|
||||||
|
"Title": "configuration.py",
|
||||||
|
"DocumentMoniker": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\configuration.py",
|
||||||
|
"RelativeDocumentMoniker": "configuration.py",
|
||||||
|
"ToolTip": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\configuration.py",
|
||||||
|
"RelativeToolTip": "configuration.py",
|
||||||
|
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHeSURBVDhPpVMxa1NRFP7ebZLSlgaltNpSVCySRUxL0NAh4FJpHWpxcZAUBEPG/AKHDsVBN5eGrCnoYKCDoDiUCKKBjtZBUZtJ2ojYJr40ue\u002B\u002B47k3VzD0hQr94OOed8853/k47z2cCETk2NAgk8mQDQMhhFjK5/Mb9vEotIDruoEsFovEzVvZbPaWLTcQ9uxCpVLp4l\u002Bk0\u002BlEPB5/wIPm7RVC9uxCMpm0UTdKpRKi0WiCQy3wUt8FCvw7VSNxbRapG4voDwucGgyjXC7bzH84ePt1HysbH/GhWoNstzA1OoSFhZuxQqFg8sfu4FutAd\u002BT8KSEYm7v7GJ0YnLClgYLaAcjU9N4Vx9Dda8OBz7OjwywSNsIXY39vEL7TxWpxv2eO3hWHUZ19xc8ti25UdvXzdpNWH0BDj8JiLOrPXfweOu9mRgRhOXUEPr7IiBfYeacB9HaBNRvQH4f6\u002BlgMERwGxJP7grEoq9shj9Uz\u002BVGpmIi4vXcwdzlcePgzLAuZPiSGw869Jg\u002Biw1Mvw50oLGcuoh71y8h1HwB1Js8UfFLnwScNnBhdYVLWsy1IwK5XM5GHaw9uu0LeSCMddZA32lz7zjOQxMcByK1SPU3O/Rjnai2fkjNz8/5L77TyQJ/AJc67LNf3QeWAAAAAElFTkSuQmCC",
|
||||||
|
"WhenOpened": "2025-04-17T16:41:15.288Z",
|
||||||
|
"EditorCaption": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$type": "Document",
|
||||||
|
"DocumentIndex": 2,
|
||||||
|
"Title": "main.py",
|
||||||
|
"DocumentMoniker": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\main.py",
|
||||||
|
"RelativeDocumentMoniker": "main.py",
|
||||||
|
"ToolTip": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\main.py",
|
||||||
|
"RelativeToolTip": "main.py",
|
||||||
|
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHeSURBVDhPpVMxa1NRFP7ebZLSlgaltNpSVCySRUxL0NAh4FJpHWpxcZAUBEPG/AKHDsVBN5eGrCnoYKCDoDiUCKKBjtZBUZtJ2ojYJr40ue\u002B\u002B47k3VzD0hQr94OOed8853/k47z2cCETk2NAgk8mQDQMhhFjK5/Mb9vEotIDruoEsFovEzVvZbPaWLTcQ9uxCpVLp4l\u002Bk0\u002BlEPB5/wIPm7RVC9uxCMpm0UTdKpRKi0WiCQy3wUt8FCvw7VSNxbRapG4voDwucGgyjXC7bzH84ePt1HysbH/GhWoNstzA1OoSFhZuxQqFg8sfu4FutAd\u002BT8KSEYm7v7GJ0YnLClgYLaAcjU9N4Vx9Dda8OBz7OjwywSNsIXY39vEL7TxWpxv2eO3hWHUZ19xc8ti25UdvXzdpNWH0BDj8JiLOrPXfweOu9mRgRhOXUEPr7IiBfYeacB9HaBNRvQH4f6\u002BlgMERwGxJP7grEoq9shj9Uz\u002BVGpmIi4vXcwdzlcePgzLAuZPiSGw869Jg\u002Biw1Mvw50oLGcuoh71y8h1HwB1Js8UfFLnwScNnBhdYVLWsy1IwK5XM5GHaw9uu0LeSCMddZA32lz7zjOQxMcByK1SPU3O/Rjnai2fkjNz8/5L77TyQJ/AJc67LNf3QeWAAAAAElFTkSuQmCC",
|
||||||
|
"WhenOpened": "2025-04-17T16:41:14.475Z",
|
||||||
|
"EditorCaption": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$type": "Document",
|
||||||
|
"DocumentIndex": 0,
|
||||||
|
"Title": "config.py",
|
||||||
|
"DocumentMoniker": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\config.py",
|
||||||
|
"RelativeDocumentMoniker": "config.py",
|
||||||
|
"ToolTip": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\config.py",
|
||||||
|
"RelativeToolTip": "config.py",
|
||||||
|
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHeSURBVDhPpVMxa1NRFP7ebZLSlgaltNpSVCySRUxL0NAh4FJpHWpxcZAUBEPG/AKHDsVBN5eGrCnoYKCDoDiUCKKBjtZBUZtJ2ojYJr40ue\u002B\u002B47k3VzD0hQr94OOed8853/k47z2cCETk2NAgk8mQDQMhhFjK5/Mb9vEotIDruoEsFovEzVvZbPaWLTcQ9uxCpVLp4l\u002Bk0\u002BlEPB5/wIPm7RVC9uxCMpm0UTdKpRKi0WiCQy3wUt8FCvw7VSNxbRapG4voDwucGgyjXC7bzH84ePt1HysbH/GhWoNstzA1OoSFhZuxQqFg8sfu4FutAd\u002BT8KSEYm7v7GJ0YnLClgYLaAcjU9N4Vx9Dda8OBz7OjwywSNsIXY39vEL7TxWpxv2eO3hWHUZ19xc8ti25UdvXzdpNWH0BDj8JiLOrPXfweOu9mRgRhOXUEPr7IiBfYeacB9HaBNRvQH4f6\u002BlgMERwGxJP7grEoq9shj9Uz\u002BVGpmIi4vXcwdzlcePgzLAuZPiSGw869Jg\u002Biw1Mvw50oLGcuoh71y8h1HwB1Js8UfFLnwScNnBhdYVLWsy1IwK5XM5GHaw9uu0LeSCMddZA32lz7zjOQxMcByK1SPU3O/Rjnai2fkjNz8/5L77TyQJ/AJc67LNf3QeWAAAAAElFTkSuQmCC",
|
||||||
|
"WhenOpened": "2025-04-17T16:41:05.778Z",
|
||||||
|
"EditorCaption": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$type": "Document",
|
||||||
|
"DocumentIndex": 3,
|
||||||
|
"Title": "asset_processor.py",
|
||||||
|
"DocumentMoniker": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\asset_processor.py",
|
||||||
|
"RelativeDocumentMoniker": "asset_processor.py",
|
||||||
|
"ToolTip": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\asset_processor.py",
|
||||||
|
"RelativeToolTip": "asset_processor.py",
|
||||||
|
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHeSURBVDhPpVMxa1NRFP7ebZLSlgaltNpSVCySRUxL0NAh4FJpHWpxcZAUBEPG/AKHDsVBN5eGrCnoYKCDoDiUCKKBjtZBUZtJ2ojYJr40ue\u002B\u002B47k3VzD0hQr94OOed8853/k47z2cCETk2NAgk8mQDQMhhFjK5/Mb9vEotIDruoEsFovEzVvZbPaWLTcQ9uxCpVLp4l\u002Bk0\u002BlEPB5/wIPm7RVC9uxCMpm0UTdKpRKi0WiCQy3wUt8FCvw7VSNxbRapG4voDwucGgyjXC7bzH84ePt1HysbH/GhWoNstzA1OoSFhZuxQqFg8sfu4FutAd\u002BT8KSEYm7v7GJ0YnLClgYLaAcjU9N4Vx9Dda8OBz7OjwywSNsIXY39vEL7TxWpxv2eO3hWHUZ19xc8ti25UdvXzdpNWH0BDj8JiLOrPXfweOu9mRgRhOXUEPr7IiBfYeacB9HaBNRvQH4f6\u002BlgMERwGxJP7grEoq9shj9Uz\u002BVGpmIi4vXcwdzlcePgzLAuZPiSGw869Jg\u002Biw1Mvw50oLGcuoh71y8h1HwB1Js8UfFLnwScNnBhdYVLWsy1IwK5XM5GHaw9uu0LeSCMddZA32lz7zjOQxMcByK1SPU3O/Rjnai2fkjNz8/5L77TyQJ/AJc67LNf3QeWAAAAAElFTkSuQmCC",
|
||||||
|
"WhenOpened": "2025-04-17T16:40:54.125Z",
|
||||||
|
"EditorCaption": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
83
.vs/Asset_processor_tool/v17/DocumentLayout.json
Normal file
83
.vs/Asset_processor_tool/v17/DocumentLayout.json
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
"Version": 1,
|
||||||
|
"WorkspaceRootPath": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\",
|
||||||
|
"Documents": [
|
||||||
|
{
|
||||||
|
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\config.py||{3B902123-F8A7-4915-9F01-361F908088D0}",
|
||||||
|
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:config.py||{3B902123-F8A7-4915-9F01-361F908088D0}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\configuration.py||{3B902123-F8A7-4915-9F01-361F908088D0}",
|
||||||
|
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:configuration.py||{3B902123-F8A7-4915-9F01-361F908088D0}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\main.py||{3B902123-F8A7-4915-9F01-361F908088D0}",
|
||||||
|
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:main.py||{3B902123-F8A7-4915-9F01-361F908088D0}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\asset_processor.py||{3B902123-F8A7-4915-9F01-361F908088D0}",
|
||||||
|
"RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:asset_processor.py||{3B902123-F8A7-4915-9F01-361F908088D0}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"DocumentGroupContainers": [
|
||||||
|
{
|
||||||
|
"Orientation": 0,
|
||||||
|
"VerticalTabListWidth": 256,
|
||||||
|
"DocumentGroups": [
|
||||||
|
{
|
||||||
|
"DockedWidth": 200,
|
||||||
|
"SelectedChildIndex": 2,
|
||||||
|
"Children": [
|
||||||
|
{
|
||||||
|
"$type": "Document",
|
||||||
|
"DocumentIndex": 1,
|
||||||
|
"Title": "configuration.py",
|
||||||
|
"DocumentMoniker": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\configuration.py",
|
||||||
|
"RelativeDocumentMoniker": "configuration.py",
|
||||||
|
"ToolTip": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\configuration.py",
|
||||||
|
"RelativeToolTip": "configuration.py",
|
||||||
|
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHeSURBVDhPpVMxa1NRFP7ebZLSlgaltNpSVCySRUxL0NAh4FJpHWpxcZAUBEPG/AKHDsVBN5eGrCnoYKCDoDiUCKKBjtZBUZtJ2ojYJr40ue\u002B\u002B47k3VzD0hQr94OOed8853/k47z2cCETk2NAgk8mQDQMhhFjK5/Mb9vEotIDruoEsFovEzVvZbPaWLTcQ9uxCpVLp4l\u002Bk0\u002BlEPB5/wIPm7RVC9uxCMpm0UTdKpRKi0WiCQy3wUt8FCvw7VSNxbRapG4voDwucGgyjXC7bzH84ePt1HysbH/GhWoNstzA1OoSFhZuxQqFg8sfu4FutAd\u002BT8KSEYm7v7GJ0YnLClgYLaAcjU9N4Vx9Dda8OBz7OjwywSNsIXY39vEL7TxWpxv2eO3hWHUZ19xc8ti25UdvXzdpNWH0BDj8JiLOrPXfweOu9mRgRhOXUEPr7IiBfYeacB9HaBNRvQH4f6\u002BlgMERwGxJP7grEoq9shj9Uz\u002BVGpmIi4vXcwdzlcePgzLAuZPiSGw869Jg\u002Biw1Mvw50oLGcuoh71y8h1HwB1Js8UfFLnwScNnBhdYVLWsy1IwK5XM5GHaw9uu0LeSCMddZA32lz7zjOQxMcByK1SPU3O/Rjnai2fkjNz8/5L77TyQJ/AJc67LNf3QeWAAAAAElFTkSuQmCC",
|
||||||
|
"WhenOpened": "2025-04-17T16:41:15.288Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$type": "Document",
|
||||||
|
"DocumentIndex": 2,
|
||||||
|
"Title": "main.py",
|
||||||
|
"DocumentMoniker": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\main.py",
|
||||||
|
"RelativeDocumentMoniker": "main.py",
|
||||||
|
"ToolTip": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\main.py",
|
||||||
|
"RelativeToolTip": "main.py",
|
||||||
|
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHeSURBVDhPpVMxa1NRFP7ebZLSlgaltNpSVCySRUxL0NAh4FJpHWpxcZAUBEPG/AKHDsVBN5eGrCnoYKCDoDiUCKKBjtZBUZtJ2ojYJr40ue\u002B\u002B47k3VzD0hQr94OOed8853/k47z2cCETk2NAgk8mQDQMhhFjK5/Mb9vEotIDruoEsFovEzVvZbPaWLTcQ9uxCpVLp4l\u002Bk0\u002BlEPB5/wIPm7RVC9uxCMpm0UTdKpRKi0WiCQy3wUt8FCvw7VSNxbRapG4voDwucGgyjXC7bzH84ePt1HysbH/GhWoNstzA1OoSFhZuxQqFg8sfu4FutAd\u002BT8KSEYm7v7GJ0YnLClgYLaAcjU9N4Vx9Dda8OBz7OjwywSNsIXY39vEL7TxWpxv2eO3hWHUZ19xc8ti25UdvXzdpNWH0BDj8JiLOrPXfweOu9mRgRhOXUEPr7IiBfYeacB9HaBNRvQH4f6\u002BlgMERwGxJP7grEoq9shj9Uz\u002BVGpmIi4vXcwdzlcePgzLAuZPiSGw869Jg\u002Biw1Mvw50oLGcuoh71y8h1HwB1Js8UfFLnwScNnBhdYVLWsy1IwK5XM5GHaw9uu0LeSCMddZA32lz7zjOQxMcByK1SPU3O/Rjnai2fkjNz8/5L77TyQJ/AJc67LNf3QeWAAAAAElFTkSuQmCC",
|
||||||
|
"WhenOpened": "2025-04-17T16:41:14.475Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$type": "Document",
|
||||||
|
"DocumentIndex": 0,
|
||||||
|
"Title": "config.py",
|
||||||
|
"DocumentMoniker": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\config.py",
|
||||||
|
"RelativeDocumentMoniker": "config.py",
|
||||||
|
"ToolTip": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\config.py",
|
||||||
|
"RelativeToolTip": "config.py",
|
||||||
|
"Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHeSURBVDhPpVMxa1NRFP7ebZLSlgaltNpSVCySRUxL0NAh4FJpHWpxcZAUBEPG/AKHDsVBN5eGrCnoYKCDoDiUCKKBjtZBUZtJ2ojYJr40ue\u002B\u002B47k3VzD0hQr94OOed8853/k47z2cCETk2NAgk8mQDQMhhFjK5/Mb9vEotIDruoEsFovEzVvZbPaWLTcQ9uxCpVLp4l\u002Bk0\u002BlEPB5/wIPm7RVC9uxCMpm0UTdKpRKi0WiCQy3wUt8FCvw7VSNxbRapG4voDwucGgyjXC7bzH84ePt1HysbH/GhWoNstzA1OoSFhZuxQqFg8sfu4FutAd\u002BT8KSEYm7v7GJ0YnLClgYLaAcjU9N4Vx9Dda8OBz7OjwywSNsIXY39vEL7TxWpxv2eO3hWHUZ19xc8ti25UdvXzdpNWH0BDj8JiLOrPXfweOu9mRgRhOXUEPr7IiBfYeacB9HaBNRvQH4f6\u002BlgMERwGxJP7grEoq9shj9Uz\u002BVGpmIi4vXcwdzlcePgzLAuZPiSGw869Jg\u002Biw1Mvw50oLGcuoh71y8h1HwB1Js8UfFLnwScNnBhdYVLWsy1IwK5XM5GHaw9uu0LeSCMddZA32lz7zjOQxMcByK1SPU3O/Rjnai2fkjNz8/5L77TyQJ/AJc67LNf3QeWAAAAAElFTkSuQmCC",
|
||||||
|
"WhenOpened": "2025-04-17T16:41:05.778Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$type": "Document",
|
||||||
|
"DocumentIndex": 3,
|
||||||
|
"Title": "asset_processor.py",
|
||||||
|
"DocumentMoniker": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\asset_processor.py",
|
||||||
|
"RelativeDocumentMoniker": "asset_processor.py",
|
||||||
|
"ToolTip": "G:\\02 Content\\10-19 Content\\13 Textures Power of Two\\Asset_processor_tool\\asset_processor.py",
|
||||||
|
"RelativeToolTip": "asset_processor.py",
|
||||||
|
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"Icon": "00000000-0000-0000-0000-000000000000.000000|iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHeSURBVDhPpVMxa1NRFP7ebZLSlgaltNpSVCySRUxL0NAh4FJpHWpxcZAUBEPG/AKHDsVBN5eGrCnoYKCDoDiUCKKBjtZBUZtJ2ojYJr40ue\u002B\u002B47k3VzD0hQr94OOed8853/k47z2cCETk2NAgk8mQDQMhhFjK5/Mb9vEotIDruoEsFovEzVvZbPaWLTcQ9uxCpVLp4l\u002Bk0\u002BlEPB5/wIPm7RVC9uxCMpm0UTdKpRKi0WiCQy3wUt8FCvw7VSNxbRapG4voDwucGgyjXC7bzH84ePt1HysbH/GhWoNstzA1OoSFhZuxQqFg8sfu4FutAd\u002BT8KSEYm7v7GJ0YnLClgYLaAcjU9N4Vx9Dda8OBz7OjwywSNsIXY39vEL7TxWpxv2eO3hWHUZ19xc8ti25UdvXzdpNWH0BDj8JiLOrPXfweOu9mRgRhOXUEPr7IiBfYeacB9HaBNRvQH4f6\u002BlgMERwGxJP7grEoq9shj9Uz\u002BVGpmIi4vXcwdzlcePgzLAuZPiSGw869Jg\u002Biw1Mvw50oLGcuoh71y8h1HwB1Js8UfFLnwScNnBhdYVLWsy1IwK5XM5GHaw9uu0LeSCMddZA32lz7zjOQxMcByK1SPU3O/Rjnai2fkjNz8/5L77TyQJ/AJc67LNf3QeWAAAAAElFTkSuQmCC",
|
||||||
|
"WhenOpened": "2025-04-17T16:40:54.125Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
3
.vs/ProjectSettings.json
Normal file
3
.vs/ProjectSettings.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"CurrentProjectSetting": null
|
||||||
|
}
|
||||||
7
.vs/VSWorkspaceState.json
Normal file
7
.vs/VSWorkspaceState.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"ExpandedNodes": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"SelectedNode": "\\config.py",
|
||||||
|
"PreviewInSolutionExplorer": false
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user