{
    "sourceFile": "Tickets/REFACTOR-001-merge-from-source.md",
    "activeCommit": 0,
    "commits": [
        {
            "activePatchIndex": 1,
            "patches": [
                {
                    "date": 1745342661771,
                    "content": "Index: \n===================================================================\n--- \n+++ \n"
                },
                {
                    "date": 1745344820191,
                    "content": "Index: \n===================================================================\n--- \n+++ \n@@ -1,12 +1,12 @@\n ---\r\n ID: REFACTOR-001\r\n Type: Refactor\r\n-Status: Proposed\r\n+Status: Resolved\r\n Priority: Medium\r\n Labels: [refactor, core, image-processing, quality]\r\n Created: 2025-04-22\r\n-Updated: 2025-04-22\r\n+Updated: 2025-04-22 # Keep original update date, or use today's? Using today's for now.\r\n Related: #ISSUE-010 #asset_processor.py #config.py\r\n ---\r\n \r\n # [REFACTOR-001]: Refactor Map Merging to Use Source Files Directly\r\n@@ -72,16 +72,20 @@\n ```\r\n \r\n **Function Changes:**\r\n \r\n-*   **`_process_maps`** will likely be renamed or refactored into `_process_individual_map`, responsible only for maps *not* used in merges. It will call `_load_and_transform_source` and `_save_image`.\r\n-*   **`_merge_maps`** will be replaced by `_merge_maps_from_source`. It will identify required source paths, call `_load_and_transform_source` for each input at each target resolution, merge the results, determine saving parameters, and call `_save_image`.\r\n-*   The main `process` loop will coordinate calls to the new functions.\r\n+*   **`_process_maps`** was renamed to `_process_individual_map`, responsible only for maps *not* used in merges. It calls `_load_and_transform_source` and `_save_image`.\r\n+*   **`_merge_maps`** was replaced by `_merge_maps_from_source`. It identifies required source paths, calls `_load_and_transform_source` for each input at each target resolution, merges the results, determines saving parameters, and calls `_save_image`.\r\n+*   The main `process` loop coordinates calls to the new functions and handles caching.\r\n \r\n+## Resolution (2025-04-22)\r\n+\r\n+The refactoring described above was implemented in `asset_processor.py`. The `_merge_maps_from_source` function now utilizes the `_load_and_transform_source` and `_save_image` helpers, loading data directly from the classified source files instead of intermediate processed files. User testing confirmed the changes work correctly and improve merged map quality.\r\n+\r\n ## Acceptance Criteria (Optional)\r\n\\ No newline at end of file\n \r\n-*   [ ] Merged maps (e.g., NRMRGH) are generated correctly using data loaded directly from selected source files.\r\n-*   [ ] Visual inspection confirms improved quality/reduced artifacts in merged maps compared to the previous method.\r\n-*   [ ] Individual maps (not part of any merge rule) are still processed and saved correctly.\r\n-*   [ ] All existing configuration options (resolutions, bit depth rules, format rules, gloss inversion) function as expected within the new structure.\r\n-*   [ ] Processing time remains within acceptable limits (potential performance impact of repeated source loading/resizing needs monitoring).\r\n-*   [ ] Code remains modular and maintainable, with minimal duplication of core logic.\n+*   [X] Merged maps (e.g., NRMRGH) are generated correctly using data loaded directly from selected source files.\r\n+*   [X] Visual inspection confirms improved quality/reduced artifacts in merged maps compared to the previous method.\r\n+*   [X] Individual maps (not part of any merge rule) are still processed and saved correctly.\r\n+*   [X] All existing configuration options (resolutions, bit depth rules, format rules, gloss inversion) function as expected within the new structure.\r\n+*   [X] Processing time remains within acceptable limits (potential performance impact of repeated source loading/resizing needs monitoring).\r\n+*   [X] Code remains modular and maintainable, with minimal duplication of core logic.\n\\ No newline at end of file\n"
                }
            ],
            "date": 1745342661771,
            "name": "Commit-0",
            "content": "---\r\nID: REFACTOR-001\r\nType: Refactor\r\nStatus: Proposed\r\nPriority: Medium\r\nLabels: [refactor, core, image-processing, quality]\r\nCreated: 2025-04-22\r\nUpdated: 2025-04-22\r\nRelated: #ISSUE-010 #asset_processor.py #config.py\r\n---\r\n\r\n# [REFACTOR-001]: Refactor Map Merging to Use Source Files Directly\r\n\r\n## Description\r\n\r\nCurrently, the `_merge_maps` function in `asset_processor.py` loads map data from temporary files that have already been processed by `_process_maps` (resized, format converted, etc.). This intermediate save/load step can introduce quality degradation, especially if the intermediate files are saved using lossy compression (e.g., JPG) or if bit depth conversions occur before merging. This is particularly noticeable in merged maps like NRMRGH where subtle details from the source Normal map might be lost or altered due to recompression.\r\n\r\n## Goals\r\n\r\n1.  **Improve Quality:** Modify the map merging process to load channel data directly from the *selected original source files* (after classification and 16-bit prioritization) instead of intermediate processed files, thus avoiding potential quality loss from recompression.\r\n2.  **Maintain Modularity:** Refactor the processing logic to avoid significant code duplication between individual map processing and the merging process.\r\n3.  **Preserve Functionality:** Ensure all existing functionality (resizing, gloss inversion, format/bit depth rules, merging logic) is retained and applied correctly in the new structure.\r\n\r\n## Proposed Solution: Restructure with Helper Functions\r\n\r\nIntroduce two helper functions within the `AssetProcessor` class:\r\n\r\n1.  **`_load_and_transform_source(source_path_rel, map_type, target_resolution_key)`:**\r\n    *   Responsible for loading the specified source file.\r\n    *   Performs initial preparation: BGR->RGB conversion, Gloss->Roughness inversion (if applicable), MASK extraction (if applicable).\r\n    *   Resizes the prepared data to the target resolution.\r\n    *   Returns the resized NumPy array and original source dtype.\r\n\r\n2.  **`_save_image(image_data, map_type, resolution_key, asset_base_name, source_info, output_bit_depth_rule, temp_dir)`:**\r\n    *   Encapsulates all logic for saving an image.\r\n    *   Determines final output format and bit depth based on rules and source info.\r\n    *   Performs final data type conversions (e.g., to uint8, uint16, float16).\r\n    *   Performs final color space conversion (RGB->BGR for non-EXR).\r\n    *   Constructs the output filename.\r\n    *   Saves the image using `cv2.imwrite`, including fallback logic (e.g., EXR->PNG).\r\n    *   Returns details of the saved temporary file.\r\n\r\n**Modified Workflow:**\r\n\r\n```mermaid\r\ngraph TD\r\n    A[Input Files] --> B(_inventory_and_classify_files);\r\n    B --> C{Selected Source Maps Info};\r\n\r\n    subgraph Core Processing Logic\r\n        C --> PIM(_process_individual_map);\r\n        C --> MFS(_merge_maps_from_source);\r\n        PIM --> LTS([_load_and_transform_source]);\r\n        MFS --> LTS;\r\n    end\r\n\r\n    LTS --> ImgData{Loaded, Prepared, Resized Image Data};\r\n\r\n    subgraph Saving Logic\r\n        PIM --> SI([_save_image]);\r\n        MFS --> SI;\r\n        ImgData --> SI; // Pass image data to save helper\r\n    end\r\n\r\n    SI --> SaveResults{Saved Temp File Details};\r\n\r\n    SaveResults --> Results(Processing Results); // Collect results from saving\r\n\r\n    Results --> Meta(_generate_metadata_file);\r\n    Meta --> Org(_organize_output_files);\r\n    Org --> Final[Final Output Structure];\r\n```\r\n\r\n**Function Changes:**\r\n\r\n*   **`_process_maps`** will likely be renamed or refactored into `_process_individual_map`, responsible only for maps *not* used in merges. It will call `_load_and_transform_source` and `_save_image`.\r\n*   **`_merge_maps`** will be replaced by `_merge_maps_from_source`. It will identify required source paths, call `_load_and_transform_source` for each input at each target resolution, merge the results, determine saving parameters, and call `_save_image`.\r\n*   The main `process` loop will coordinate calls to the new functions.\r\n\r\n## Acceptance Criteria (Optional)\r\n\r\n*   [ ] Merged maps (e.g., NRMRGH) are generated correctly using data loaded directly from selected source files.\r\n*   [ ] Visual inspection confirms improved quality/reduced artifacts in merged maps compared to the previous method.\r\n*   [ ] Individual maps (not part of any merge rule) are still processed and saved correctly.\r\n*   [ ] All existing configuration options (resolutions, bit depth rules, format rules, gloss inversion) function as expected within the new structure.\r\n*   [ ] Processing time remains within acceptable limits (potential performance impact of repeated source loading/resizing needs monitoring).\r\n*   [ ] Code remains modular and maintainable, with minimal duplication of core logic."
        }
    ]
}