Files
ProjectStructure/.specstory/history/2025-12-19_18-52Z-texture-commonality-folder-structure.md

5597 lines
194 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- Generated by SpecStory, Markdown v2.1.0 -->
<!-- cursor Session 3ab1551f-4da5-4d7f-851c-5c35715c713c (2025-12-19 18:52Z) -->
# Texture commonality folder structure (2025-12-19 18:52Z)
_**User**_
context:@.specstory/history/2025-12-19_17-59Z-texture-folder-commonality-script.md
next issue: let's make sure it scans each folder separately. it goes \\textures\[Blendfile]\[Material]
Intra-blendfile commonalities should go to `\\textures\[blendfile]\common`
Inter-blendfile commonalities should go to `\\textures\common`
sound good?
---
_**Agent (model default, mode Plan)**_
Reviewing the specstory and current implementation to understand the context.
---
<tool-use data-tool-type="read" data-tool-name="read_file_v2">
<details><summary>Tool use: **read_file_v2** • Read file: a:\1 Amazon_Active_Projects\3 ProjectStructure\.specstory\history\2025-12-19_17-59Z-texture-folder-commonality-script.md</summary>
</details>
</tool-use>
---
<tool-use data-tool-type="read" data-tool-name="read_file_v2">
<details><summary>Tool use: **read_file_v2** • Read file: a:\1 Amazon_Active_Projects\3 ProjectStructure\organize_textures.bat</summary>
</details>
</tool-use>
---
<tool-use data-tool-type="read" data-tool-name="read_file_v2">
<details><summary>Tool use: **read_file_v2** • Read file: a:\1 Amazon_Active_Projects\3 ProjectStructure\organize_textures.ps1</summary>
</details>
</tool-use>
---
Reading the specstory file in sections to understand the context:
---
<tool-use data-tool-type="read" data-tool-name="read_file_v2">
<details><summary>Tool use: **read_file_v2** • Read file: a:\1 Amazon_Active_Projects\3 ProjectStructure\.specstory\history\2025-12-19_17-59Z-texture-folder-commonality-script.md</summary>
</details>
</tool-use>
---
Checking the folder structure to understand the layout:
---
<tool-use data-tool-type="unknown" data-tool-name="semantic_search_full">
<details>
<summary>Tool use: **semantic_search_full**</summary>
Parameters:
```json
{
"query": "What is the folder structure for textures with blendfile and material subdirectories?",
"topK": 10,
"explanation": ""
}
```
Result:
```json
{
"codeResults": [
{
"codeBlock": {
"relativeWorkspacePath": ".\\components\\gitignore",
"range": {
"startPosition": {},
"endPosition": {
"line": 125,
"column": 7
}
},
"contents": "# Blender Studio Git Management - .gitignore\n\n# Blender auto-save files\n*.blend1\n*.blend2\n*.blend3\n*.blend4\n*.blend5\n*.blend6\n*.blend7\n*.blend8\n*.blend9\n*.blend10\n*.blend11\n*.blend12\n*.blend13\n*.blend14\n*.blend15\n*.blend16\n*.blend17\n*.blend18\n*.blend19\n*.blend20\n*.blend21\n*.blend22\n*.blend23\n*.blend24\n*.blend25\n*.blend26\n*.blend27\n*.blend28\n*.blend29\n*.blend30\n*.blend31\n*.blend32\n\n# Blender cache and temporary files\n*.swp\n*.swo\n*~\n*.tmp\n*.temp\n\n# OS generated files\n.DS_Store\n.DS_Store?\n._*\n.Spotlight-V100\n.Trashes\nehthumbs.db\nThumbs.db\ndesktop.ini\n\n# Editor files\n.vscode/\n.idea/\n*.swp\n*.swo\n*~\n\n# Large media files (uncomment if you want to exclude rendered outputs)\n# *.mp4\n# *.avi\n# *.mov\n# *.png\n# *.jpg\n# *.jpeg\n# *.exr\n# *.hdr\n# *.tiff\n# *.tga\n\n# Audio files (uncomment if excluding)\n# *.wav\n# *.mp3\n# *.aac\n# *.ogg\n\n# Log files\n*.log\n\n# Python cache\n__pycache__/\n*.pyc\n*.pyo\n*.pyd\n.Python\n\n# Node modules (if using any web tools)\nnode_modules/\n\n# Environment files\n.env\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\n# Backup files\n*.bak\n*.backup\n*.old\n\n# Temporary files\ntemp/\ntmp/\ncache/ \n\nRenders/**\n!Renders/_zipped/\n!Renders/_zipped/**\n!Renders/**/\n!Renders/**/*.bat\n!Renders/**/*.log\nseq/\n\n# Premiere\n*.prlock\nAdobe Premiere Pro Video Previews/\nAdobe Premiere Pro Audio Previews/\nAdobe Premiere Pro (Beta) Video Previews/\nAdobe Premiere Pro (Beta) Audio Previews/\nfootage/\nplates/\n\nPr/RnR/",
"signatures": {},
"detailedLines": [
{
"text": "# Blender Studio Git Management - .gitignore",
"lineNumber": 1
},
{
"lineNumber": 2
},
{
"text": "# Blender auto-save files",
"lineNumber": 3
},
{
"text": "*.blend1",
"lineNumber": 4
},
{
"text": "*.blend2",
"lineNumber": 5
},
{
"text": "*.blend3",
"lineNumber": 6
},
{
"text": "*.blend4",
"lineNumber": 7
},
{
"text": "*.blend5",
"lineNumber": 8
},
{
"text": "*.blend6",
"lineNumber": 9
},
{
"text": "*.blend7",
"lineNumber": 10
},
{
"text": "*.blend8",
"lineNumber": 11
},
{
"text": "*.blend9",
"lineNumber": 12
},
{
"text": "*.blend10",
"lineNumber": 13
},
{
"text": "*.blend11",
"lineNumber": 14
},
{
"text": "*.blend12",
"lineNumber": 15
},
{
"text": "*.blend13",
"lineNumber": 16
},
{
"text": "*.blend14",
"lineNumber": 17
},
{
"text": "*.blend15",
"lineNumber": 18
},
{
"text": "*.blend16",
"lineNumber": 19
},
{
"text": "*.blend17",
"lineNumber": 20
},
{
"text": "*.blend18",
"lineNumber": 21
},
{
"text": "*.blend19",
"lineNumber": 22
},
{
"text": "*.blend20",
"lineNumber": 23
},
{
"text": "*.blend21",
"lineNumber": 24
},
{
"text": "*.blend22",
"lineNumber": 25
},
{
"text": "*.blend23",
"lineNumber": 26
},
{
"text": "*.blend24",
"lineNumber": 27
},
{
"text": "*.blend25",
"lineNumber": 28
},
{
"text": "*.blend26",
"lineNumber": 29
},
{
"text": "*.blend27",
"lineNumber": 30
},
{
"text": "*.blend28",
"lineNumber": 31
},
{
"text": "*.blend29",
"lineNumber": 32
},
{
"text": "*.blend30",
"lineNumber": 33
},
{
"text": "*.blend31",
"lineNumber": 34
},
{
"text": "*.blend32",
"lineNumber": 35
},
{
"lineNumber": 36
},
{
"text": "# Blender cache and temporary files",
"lineNumber": 37
},
{
"text": "*.swp",
"lineNumber": 38
},
{
"text": "*.swo",
"lineNumber": 39
},
{
"text": "*~",
"lineNumber": 40
},
{
"text": "*.tmp",
"lineNumber": 41
},
{
"text": "*.temp",
"lineNumber": 42
},
{
"lineNumber": 43
},
{
"text": "# OS generated files",
"lineNumber": 44
},
{
"text": ".DS_Store",
"lineNumber": 45
},
{
"text": ".DS_Store?",
"lineNumber": 46
},
{
"text": "._*",
"lineNumber": 47
},
{
"text": ".Spotlight-V100",
"lineNumber": 48
},
{
"text": ".Trashes",
"lineNumber": 49
},
{
"text": "ehthumbs.db",
"lineNumber": 50
},
{
"text": "Thumbs.db",
"lineNumber": 51
},
{
"text": "desktop.ini",
"lineNumber": 52
},
{
"lineNumber": 53
},
{
"text": "# Editor files",
"lineNumber": 54
},
{
"text": ".vscode/",
"lineNumber": 55
},
{
"text": ".idea/",
"lineNumber": 56
},
{
"text": "*.swp",
"lineNumber": 57
},
{
"text": "*.swo",
"lineNumber": 58
},
{
"text": "*~",
"lineNumber": 59
},
{
"lineNumber": 60
},
{
"text": "# Large media files (uncomment if you want to exclude rendered outputs)",
"lineNumber": 61
},
{
"text": "# *.mp4",
"lineNumber": 62
},
{
"text": "# *.avi",
"lineNumber": 63
},
{
"text": "# *.mov",
"lineNumber": 64
},
{
"text": "# *.png",
"lineNumber": 65
},
{
"text": "# *.jpg",
"lineNumber": 66
},
{
"text": "# *.jpeg",
"lineNumber": 67
},
{
"text": "# *.exr",
"lineNumber": 68
},
{
"text": "# *.hdr",
"lineNumber": 69
},
{
"text": "# *.tiff",
"lineNumber": 70
},
{
"text": "# *.tga",
"lineNumber": 71
},
{
"lineNumber": 72
},
{
"text": "# Audio files (uncomment if excluding)",
"lineNumber": 73
},
{
"text": "# *.wav",
"lineNumber": 74
},
{
"text": "# *.mp3",
"lineNumber": 75
},
{
"text": "# *.aac",
"lineNumber": 76
},
{
"text": "# *.ogg",
"lineNumber": 77
},
{
"lineNumber": 78
},
{
"text": "# Log files",
"lineNumber": 79
},
{
"text": "*.log",
"lineNumber": 80
},
{
"lineNumber": 81
},
{
"text": "# Python cache",
"lineNumber": 82
},
{
"text": "__pycache__/",
"lineNumber": 83
},
{
"text": "*.pyc",
"lineNumber": 84
},
{
"text": "*.pyo",
"lineNumber": 85
},
{
"text": "*.pyd",
"lineNumber": 86
},
{
"text": ".Python",
"lineNumber": 87
},
{
"lineNumber": 88
},
{
"text": "# Node modules (if using any web tools)",
"lineNumber": 89
},
{
"text": "node_modules/",
"lineNumber": 90
},
{
"lineNumber": 91
},
{
"text": "# Environment files",
"lineNumber": 92
},
{
"text": ".env",
"lineNumber": 93
},
{
"text": ".env.local",
"lineNumber": 94
},
{
"text": ".env.development.local",
"lineNumber": 95
},
{
"text": ".env.test.local",
"lineNumber": 96
},
{
"text": ".env.production.local",
"lineNumber": 97
},
{
"lineNumber": 98
},
{
"text": "# Backup files",
"lineNumber": 99
},
{
"text": "*.bak",
"lineNumber": 100
},
{
"text": "*.backup",
"lineNumber": 101
},
{
"text": "*.old",
"lineNumber": 102
},
{
"lineNumber": 103
},
{
"text": "# Temporary files",
"lineNumber": 104
},
{
"text": "temp/",
"lineNumber": 105
},
{
"text": "tmp/",
"lineNumber": 106
},
{
"text": "cache/ ",
"lineNumber": 107
},
{
"lineNumber": 108
},
{
"text": "Renders/**",
"lineNumber": 109
},
{
"text": "!Renders/_zipped/",
"lineNumber": 110
},
{
"text": "!Renders/_zipped/**",
"lineNumber": 111
},
{
"text": "!Renders/**/",
"lineNumber": 112
},
{
"text": "!Renders/**/*.bat",
"lineNumber": 113
},
{
"text": "!Renders/**/*.log",
"lineNumber": 114
},
{
"text": "seq/",
"lineNumber": 115
},
{
"lineNumber": 116
},
{
"text": "# Premiere",
"lineNumber": 117
},
{
"text": "*.prlock",
"lineNumber": 118
},
{
"text": "Adobe Premiere Pro Video Previews/",
"lineNumber": 119
},
{
"text": "Adobe Premiere Pro Audio Previews/",
"lineNumber": 120
},
{
"text": "Adobe Premiere Pro (Beta) Video Previews/",
"lineNumber": 121
},
{
"text": "Adobe Premiere Pro (Beta) Audio Previews/",
"lineNumber": 122
},
{
"text": "footage/",
"lineNumber": 123
},
{
"text": "plates/",
"lineNumber": 124
},
{
"lineNumber": 125
},
{
"text": "Pr/RnR/",
"lineNumber": 126
}
]
},
"score": 0.354219913482666
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\NewProject.bat",
"range": {
"startPosition": {},
"endPosition": {
"line": 63
}
},
"contents": "@echo off\nsetlocal EnableExtensions\n\nset \"SCRIPT_DIR=%~dp0\"\nset \"CONFIG_LOADER=%SCRIPT_DIR%ConfigLoader.ps1\"\nset \"CONFIG_PATH=%SCRIPT_DIR%config.json\"\n\nif not exist \"%CONFIG_LOADER%\" (\n echo [ERROR] ConfigLoader.ps1 not found next to NewProject.bat.\n exit /b 1\n)\n\nif not exist \"%CONFIG_PATH%\" (\n echo [ERROR] config.json not found next to NewProject.bat.\n exit /b 1\n)\n\nfor /f \"usebackq delims=\" %%I in (&#96;powershell -NoProfile -ExecutionPolicy Bypass -Command ^\n \"Set-StrictMode -Version Latest; $loader = Resolve-Path -LiteralPath '%CONFIG_LOADER%' -ErrorAction Stop; . $loader.Path; Write-Output (Get-StructDirectory)\"&#96;) do set \"STRUCT_DIR=%%I\"\n\nif not defined STRUCT_DIR (\n echo [ERROR] Unable to resolve ProjectStructure directory from config.\n exit /b 1\n)\n\n:: Get current date in YYYY-MM-DD format\nfor /f \"tokens=2-4 delims=/ \" %%a in ('date /t') do (\n set mm=%%a\n set dd=%%b\n set yy=%%c\n)\nset yyyy=20%yy:~-2%\nset yymmdd=%yy:~-2%%mm%%dd%\n\n:: Ask for project name\nset /p projectName=\"Enter project name (press Enter for default 'NewProject'): \"\nif \"%projectName%\"==\"\" set projectName=NewProject\nset projectRoot=%yymmdd%_%projectName%\n\n:: Create main project directory\nmkdir \"%projectRoot%\"\n\n:: Create Assets structure\nmkdir \"%projectRoot%\\Assets\\ElevenLabs\"\nif exist \"%STRUCT_DIR%\\NewDaily.bat\" copy /Y \"%STRUCT_DIR%\\NewDaily.bat\" \"%projectRoot%\\Assets\\ElevenLabs\\NewDaily.bat\" &gt;nul\nmkdir \"%projectRoot%\\Assets\\Blends\"\nmkdir \"%projectRoot%\\Assets\\Mocap\"\nmkdir \"%projectRoot%\\Assets\\VO\"\nif exist \"%~dp0NewDaily.bat\" copy /Y \"%~dp0NewDaily.bat\" \"%projectRoot%\\Assets\\VO\\NewDaily.bat\" &gt;nul\n\n:: Create Blends structure\nmkdir \"%projectRoot%\\Blends\\animations\\\"\nmkdir \"%projectRoot%\\Blends\\stills\\img-BG\"\n\n:: Create Deliverable structure\nmkdir \"%projectRoot%\\Deliverable\\\"\n\n:: Create Pr structure\nmkdir \"%projectRoot%\\Pr\\RnR\\RIFE\"\n\n:: Add project root additions\nif not exist \"%projectRoot%\\Renders\" mkdir \"%projectRoot%\\Renders\"",
"signatures": {},
"detailedLines": [
{
"text": "@echo off",
"lineNumber": 1
},
{
"text": "setlocal EnableExtensions",
"lineNumber": 2
},
{
"lineNumber": 3
},
{
"text": "set \"SCRIPT_DIR=%~dp0\"",
"lineNumber": 4
},
{
"text": "set \"CONFIG_LOADER=%SCRIPT_DIR%ConfigLoader.ps1\"",
"lineNumber": 5
},
{
"text": "set \"CONFIG_PATH=%SCRIPT_DIR%config.json\"",
"lineNumber": 6
},
{
"lineNumber": 7
},
{
"text": "if not exist \"%CONFIG_LOADER%\" (",
"lineNumber": 8
},
{
"text": " echo [ERROR] ConfigLoader.ps1 not found next to NewProject.bat.",
"lineNumber": 9
},
{
"text": " exit /b 1",
"lineNumber": 10
},
{
"text": ")",
"lineNumber": 11
},
{
"lineNumber": 12
},
{
"text": "if not exist \"%CONFIG_PATH%\" (",
"lineNumber": 13
},
{
"text": " echo [ERROR] config.json not found next to NewProject.bat.",
"lineNumber": 14
},
{
"text": " exit /b 1",
"lineNumber": 15
},
{
"text": ")",
"lineNumber": 16
},
{
"lineNumber": 17
},
{
"text": "for /f \"usebackq delims=\" %%I in (&#96;powershell -NoProfile -ExecutionPolicy Bypass -Command ^",
"lineNumber": 18
},
{
"text": " \"Set-StrictMode -Version Latest; $loader = Resolve-Path -LiteralPath '%CONFIG_LOADER%' -ErrorAction Stop; . $loader.Path; Write-Output (Get-StructDirectory)\"&#96;) do set \"STRUCT_DIR=%%I\"",
"lineNumber": 19
},
{
"lineNumber": 20
},
{
"text": "if not defined STRUCT_DIR (",
"lineNumber": 21
},
{
"text": " echo [ERROR] Unable to resolve ProjectStructure directory from config.",
"lineNumber": 22
},
{
"text": " exit /b 1",
"lineNumber": 23
},
{
"text": ")",
"lineNumber": 24
},
{
"lineNumber": 25
},
{
"text": ":: Get current date in YYYY-MM-DD format",
"lineNumber": 26
},
{
"text": "for /f \"tokens=2-4 delims=/ \" %%a in ('date /t') do (",
"lineNumber": 27
},
{
"text": " set mm=%%a",
"lineNumber": 28
},
{
"text": " set dd=%%b",
"lineNumber": 29
},
{
"text": " set yy=%%c",
"lineNumber": 30
},
{
"text": ")",
"lineNumber": 31
},
{
"text": "set yyyy=20%yy:~-2%",
"lineNumber": 32
},
{
"text": "set yymmdd=%yy:~-2%%mm%%dd%",
"lineNumber": 33
},
{
"lineNumber": 34
},
{
"text": ":: Ask for project name",
"lineNumber": 35
},
{
"text": "set /p projectName=\"Enter project name (press Enter for default 'NewProject'): \"",
"lineNumber": 36
},
{
"text": "if \"%projectName%\"==\"\" set projectName=NewProject",
"lineNumber": 37
},
{
"text": "set projectRoot=%yymmdd%_%projectName%",
"lineNumber": 38
},
{
"lineNumber": 39
},
{
"text": ":: Create main project directory",
"lineNumber": 40
},
{
"text": "mkdir \"%projectRoot%\"",
"lineNumber": 41
},
{
"lineNumber": 42
},
{
"text": ":: Create Assets structure",
"lineNumber": 43
},
{
"text": "mkdir \"%projectRoot%\\Assets\\ElevenLabs\"",
"lineNumber": 44
},
{
"text": "if exist \"%STRUCT_DIR%\\NewDaily.bat\" copy /Y \"%STRUCT_DIR%\\NewDaily.bat\" \"%projectRoot%\\Assets\\ElevenLabs\\NewDaily.bat\" &gt;nul",
"lineNumber": 45
},
{
"text": "mkdir \"%projectRoot%\\Assets\\Blends\"",
"lineNumber": 46
},
{
"text": "mkdir \"%projectRoot%\\Assets\\Mocap\"",
"lineNumber": 47
},
{
"text": "mkdir \"%projectRoot%\\Assets\\VO\"",
"lineNumber": 48
},
{
"text": "if exist \"%~dp0NewDaily.bat\" copy /Y \"%~dp0NewDaily.bat\" \"%projectRoot%\\Assets\\VO\\NewDaily.bat\" &gt;nul",
"lineNumber": 49
},
{
"lineNumber": 50
},
{
"text": ":: Create Blends structure",
"lineNumber": 51
},
{
"text": "mkdir \"%projectRoot%\\Blends\\animations\\\"",
"lineNumber": 52
},
{
"text": "mkdir \"%projectRoot%\\Blends\\stills\\img-BG\"",
"lineNumber": 53
},
{
"lineNumber": 54
},
{
"text": ":: Create Deliverable structure",
"lineNumber": 55
},
{
"text": "mkdir \"%projectRoot%\\Deliverable\\\"",
"lineNumber": 56
},
{
"lineNumber": 57
},
{
"text": ":: Create Pr structure",
"lineNumber": 58
},
{
"text": "mkdir \"%projectRoot%\\Pr\\RnR\\RIFE\"",
"lineNumber": 59
},
{
"lineNumber": 60
},
{
"text": ":: Add project root additions",
"lineNumber": 61
},
{
"text": "if not exist \"%projectRoot%\\Renders\" mkdir \"%projectRoot%\\Renders\"",
"lineNumber": 62
}
]
},
"score": 0.3472631871700287
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\components\\gitattributes",
"range": {
"startPosition": {},
"endPosition": {
"line": 53
}
},
"contents": "# Git LFS attributes configuration\n# All listed file types will be tracked by Git LFS\n\n# Video files\n*.avi filter=lfs diff=lfs merge=lfs -text\n*.mkv filter=lfs diff=lfs merge=lfs -text\n*.mov filter=lfs diff=lfs merge=lfs -text\n*.MOV filter=lfs diff=lfs merge=lfs -text\n*.mp4 filter=lfs diff=lfs merge=lfs -text\n*.webm filter=lfs diff=lfs merge=lfs -text\n\n# Image files\n*.bmp filter=lfs diff=lfs merge=lfs -text\n*.exr filter=lfs diff=lfs merge=lfs -text\n*.gif filter=lfs diff=lfs merge=lfs -text\n*.hdr filter=lfs diff=lfs merge=lfs -text\n*.jpg filter=lfs diff=lfs merge=lfs -text\n*.jpeg filter=lfs diff=lfs merge=lfs -text\n*.png filter=lfs diff=lfs merge=lfs -text\n*.tga filter=lfs diff=lfs merge=lfs -text\n*.tif filter=lfs diff=lfs merge=lfs -text\n*.tiff filter=lfs diff=lfs merge=lfs -text\n*.webp filter=lfs diff=lfs merge=lfs -text\n\n# 3D/CG files\n*.3ds filter=lfs diff=lfs merge=lfs -text\n*.abc filter=lfs diff=lfs merge=lfs -text\n*.blend filter=lfs diff=lfs merge=lfs -text\n*.blend1 filter=lfs diff=lfs merge=lfs -text\n*.blend2 filter=lfs diff=lfs merge=lfs -text\n*.bvh filter=lfs diff=lfs merge=lfs -text\n*.bvh.gz filter=lfs diff=lfs merge=lfs -text\n*.c4d filter=lfs diff=lfs merge=lfs -text\n*.dae filter=lfs diff=lfs merge=lfs -text\n*.fbx filter=lfs diff=lfs merge=lfs -text\n*.fbxkey filter=lfs diff=lfs merge=lfs -text\n*.ma filter=lfs diff=lfs merge=lfs -text\n*.max filter=lfs diff=lfs merge=lfs -text\n*.mb filter=lfs diff=lfs merge=lfs -text\n*.obj filter=lfs diff=lfs merge=lfs -text\n*.usd filter=lfs diff=lfs merge=lfs -text\n*.usdz filter=lfs diff=lfs merge=lfs -text\n*.vdb filter=lfs diff=lfs merge=lfs -text\n*.bphys filter=lfs diff=lfs merge=lfs -text\n*.bobj filter=lfs diff=lfs merge=lfs -text\n*.bvel filter=lfs diff=lfs merge=lfs -text\n*.bpointcache filter=lfs diff=lfs merge=lfs -text\n*.blob filter=lfs diff=lfs merge=lfs -text\n*.unitypackage filter=lfs diff=lfs merge=lfs -text\n\n# Houdini files\n*.hiplc filter=lfs diff=lfs merge=lfs -text\n*.bgeo filter=lfs diff=lfs merge=lfs -text",
"signatures": {},
"detailedLines": [
{
"text": "# Git LFS attributes configuration",
"lineNumber": 1
},
{
"text": "# All listed file types will be tracked by Git LFS",
"lineNumber": 2
},
{
"lineNumber": 3
},
{
"text": "# Video files",
"lineNumber": 4
},
{
"text": "*.avi filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 5
},
{
"text": "*.mkv filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 6
},
{
"text": "*.mov filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 7
},
{
"text": "*.MOV filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 8
},
{
"text": "*.mp4 filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 9
},
{
"text": "*.webm filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 10
},
{
"lineNumber": 11
},
{
"text": "# Image files",
"lineNumber": 12
},
{
"text": "*.bmp filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 13
},
{
"text": "*.exr filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 14
},
{
"text": "*.gif filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 15
},
{
"text": "*.hdr filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 16
},
{
"text": "*.jpg filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 17
},
{
"text": "*.jpeg filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 18
},
{
"text": "*.png filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 19
},
{
"text": "*.tga filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 20
},
{
"text": "*.tif filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 21
},
{
"text": "*.tiff filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 22
},
{
"text": "*.webp filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 23
},
{
"lineNumber": 24
},
{
"text": "# 3D/CG files",
"lineNumber": 25
},
{
"text": "*.3ds filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 26
},
{
"text": "*.abc filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 27
},
{
"text": "*.blend filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 28
},
{
"text": "*.blend1 filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 29
},
{
"text": "*.blend2 filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 30
},
{
"text": "*.bvh filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 31
},
{
"text": "*.bvh.gz filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 32
},
{
"text": "*.c4d filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 33
},
{
"text": "*.dae filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 34
},
{
"text": "*.fbx filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 35
},
{
"text": "*.fbxkey filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 36
},
{
"text": "*.ma filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 37
},
{
"text": "*.max filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 38
},
{
"text": "*.mb filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 39
},
{
"text": "*.obj filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 40
},
{
"text": "*.usd filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 41
},
{
"text": "*.usdz filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 42
},
{
"text": "*.vdb filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 43
},
{
"text": "*.bphys filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 44
},
{
"text": "*.bobj filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 45
},
{
"text": "*.bvel filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 46
},
{
"text": "*.bpointcache filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 47
},
{
"text": "*.blob filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 48
},
{
"text": "*.unitypackage filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 49
},
{
"lineNumber": 50
},
{
"text": "# Houdini files",
"lineNumber": 51
},
{
"text": "*.hiplc filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 52
},
{
"text": "*.bgeo filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 53
}
]
},
"score": 0.3170698881149292
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\organize_textures.ps1",
"range": {
"startPosition": {},
"endPosition": {
"line": 51
}
},
"contents": "# Script to organize texture files by checksum, moving all files to \\common and duplicates to \\common\\duplicates\n# Usage: .\\organize_textures.ps1\n\n# Prompt user for texture folder path\n$textureFolderPath = Read-Host \"Enter texture folder path\"\n\n# Validate the input path\nif ([string]::IsNullOrWhiteSpace($textureFolderPath)) {\n Write-Host \"Error: No path provided.\" -ForegroundColor Red\n exit\n}\n\nif (-not (Test-Path -Path $textureFolderPath -PathType Container)) {\n Write-Host \"Error: Path does not exist or is not a directory: $textureFolderPath\" -ForegroundColor Red\n exit\n}\n\n# Resolve the full path\n$textureFolderPath = (Resolve-Path $textureFolderPath).ProviderPath\nWrite-Host \"Processing texture folder: $textureFolderPath\" -ForegroundColor Cyan\n\n# Get all files recursively, excluding the \\common folder to avoid processing already-moved files\nWrite-Host \"Collecting files...\" -ForegroundColor Yellow\n$allFiles = Get-ChildItem -Path $textureFolderPath -Recurse -File | Where-Object { $_.FullName -notlike \"*\\common\\*\" }\n\nif ($null -eq $allFiles -or $allFiles.Count -eq 0) {\n Write-Host \"No files found to process (excluding \\common folder).\" -ForegroundColor Yellow\n exit\n}\n\nWrite-Host \"Found $($allFiles.Count) files to process.\" -ForegroundColor Green\n\n# Calculate checksums for all files using parallel processing\nWrite-Host \"Calculating checksums using parallel processing (this may take a while)...\" -ForegroundColor Yellow\n$throttleLimit = [Math]::Max(1, [Environment]::ProcessorCount)\n$parallelScriptBlock = {\n try {\n $hash = Get-FileHash -Path $_.FullName -Algorithm SHA256\n [PSCustomObject]@{\n File = $_\n Hash = $hash.Hash\n }\n } catch {\n Write-Warning \"Failed to calculate checksum for: $($_.FullName) - $($_.Exception.Message)\"\n $null\n }\n}\n$filesWithChecksums = $allFiles | ForEach-Object -Parallel $parallelScriptBlock -ThrottleLimit $throttleLimit | Where-Object { $null -ne $_ }\n\nWrite-Host \"Checksum calculation complete.\" -ForegroundColor Green",
"signatures": {},
"detailedLines": [
{
"text": "# Script to organize texture files by checksum, moving all files to \\common and duplicates to \\common\\duplicates",
"lineNumber": 1
},
{
"text": "# Usage: .\\organize_textures.ps1",
"lineNumber": 2
},
{
"lineNumber": 3
},
{
"text": "# Prompt user for texture folder path",
"lineNumber": 4
},
{
"text": "$textureFolderPath = Read-Host \"Enter texture folder path\"",
"lineNumber": 5
},
{
"lineNumber": 6
},
{
"text": "# Validate the input path",
"lineNumber": 7
},
{
"text": "if ([string]::IsNullOrWhiteSpace($textureFolderPath)) {",
"lineNumber": 8
},
{
"text": " Write-Host \"Error: No path provided.\" -ForegroundColor Red",
"lineNumber": 9
},
{
"text": " exit",
"lineNumber": 10
},
{
"text": "}",
"lineNumber": 11
},
{
"lineNumber": 12
},
{
"text": "if (-not (Test-Path -Path $textureFolderPath -PathType Container)) {",
"lineNumber": 13
},
{
"text": " Write-Host \"Error: Path does not exist or is not a directory: $textureFolderPath\" -ForegroundColor Red",
"lineNumber": 14
},
{
"text": " exit",
"lineNumber": 15
},
{
"text": "}",
"lineNumber": 16
},
{
"lineNumber": 17
},
{
"text": "# Resolve the full path",
"lineNumber": 18
},
{
"text": "$textureFolderPath = (Resolve-Path $textureFolderPath).ProviderPath",
"lineNumber": 19
},
{
"text": "Write-Host \"Processing texture folder: $textureFolderPath\" -ForegroundColor Cyan",
"lineNumber": 20
},
{
"lineNumber": 21
},
{
"text": "# Get all files recursively, excluding the \\common folder to avoid processing already-moved files",
"lineNumber": 22
},
{
"text": "Write-Host \"Collecting files...\" -ForegroundColor Yellow",
"lineNumber": 23
},
{
"text": "$allFiles = Get-ChildItem -Path $textureFolderPath -Recurse -File | Where-Object { $_.FullName -notlike \"*\\common\\*\" }",
"lineNumber": 24
},
{
"lineNumber": 25
},
{
"text": "if ($null -eq $allFiles -or $allFiles.Count -eq 0) {",
"lineNumber": 26
},
{
"text": " Write-Host \"No files found to process (excluding \\common folder).\" -ForegroundColor Yellow",
"lineNumber": 27
},
{
"text": " exit",
"lineNumber": 28
},
{
"text": "}",
"lineNumber": 29
},
{
"lineNumber": 30
},
{
"text": "Write-Host \"Found $($allFiles.Count) files to process.\" -ForegroundColor Green",
"lineNumber": 31
},
{
"lineNumber": 32
},
{
"text": "# Calculate checksums for all files using parallel processing",
"lineNumber": 33
},
{
"text": "Write-Host \"Calculating checksums using parallel processing (this may take a while)...\" -ForegroundColor Yellow",
"lineNumber": 34
},
{
"text": "$throttleLimit = [Math]::Max(1, [Environment]::ProcessorCount)",
"lineNumber": 35
},
{
"text": "$parallelScriptBlock = {",
"lineNumber": 36
},
{
"text": " try {",
"lineNumber": 37
},
{
"text": " $hash = Get-FileHash -Path $_.FullName -Algorithm SHA256",
"lineNumber": 38
},
{
"text": " [PSCustomObject]@{",
"lineNumber": 39
},
{
"text": " File = $_",
"lineNumber": 40
},
{
"text": " Hash = $hash.Hash",
"lineNumber": 41
},
{
"text": " }",
"lineNumber": 42
},
{
"text": " } catch {",
"lineNumber": 43
},
{
"text": " Write-Warning \"Failed to calculate checksum for: $($_.FullName) - $($_.Exception.Message)\"",
"lineNumber": 44
},
{
"text": " $null",
"lineNumber": 45
},
{
"text": " }",
"lineNumber": 46
},
{
"text": "}",
"lineNumber": 47
},
{
"text": "$filesWithChecksums = $allFiles | ForEach-Object -Parallel $parallelScriptBlock -ThrottleLimit $throttleLimit | Where-Object { $null -ne $_ }",
"lineNumber": 48
},
{
"lineNumber": 49
},
{
"text": "Write-Host \"Checksum calculation complete.\" -ForegroundColor Green",
"lineNumber": 50
}
]
},
"score": 0.3156466484069824
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\replace_cel_with_bsdf.py",
"range": {
"startPosition": {},
"endPosition": {
"line": 106
}
},
"contents": "import bpy\nimport re\nimport os\n\ndef link_bsdf_materials():\n \"\"\"Link all materials from the BSDF library file\"\"\"\n \n library_path = r\"R:\\Creative\\artsy\\maya\\0 ProjectStructure\\1 BlenderAssets\\Amazon\\MATERIALS_BSDF_pallette_v1.0.blend\"\n \n if not os.path.exists(library_path):\n print(f\"Warning: Library file not found at {library_path}\")\n return []\n \n print(f\"Linking materials from: {library_path}\")\n \n # Get list of materials before linking\n materials_before = set(bpy.data.materials.keys())\n \n # Link all materials from the library file\n with bpy.data.libraries.load(library_path, link=True) as (data_from, data_to):\n # Link all materials\n data_to.materials = data_from.materials\n \n # Get list of newly linked materials\n materials_after = set(bpy.data.materials.keys())\n newly_linked = materials_after - materials_before\n \n print(f\"Linked {len(newly_linked)} materials from library\")\n for mat_name in sorted(newly_linked):\n print(f\" - {mat_name}\")\n \n return list(newly_linked)\n\ndef remap_appended_to_linked():\n \"\"\"Remap any appended BSDF materials to their linked counterparts\"\"\"",
"signatures": {},
"detailedLines": [
{
"text": "import bpy",
"lineNumber": 1
},
{
"text": "import re",
"lineNumber": 2
},
{
"text": "import os",
"lineNumber": 3
},
{
"lineNumber": 4
},
{
"text": "def link_bsdf_materials():",
"lineNumber": 5,
"isSignature": true
},
{
"text": " \"\"\"Link all materials from the BSDF library file\"\"\"",
"lineNumber": 6
},
{
"text": " ",
"lineNumber": 7
},
{
"text": " library_path = r\"R:\\Creative\\artsy\\maya\\0 ProjectStructure\\1 BlenderAssets\\Amazon\\MATERIALS_BSDF_pallette_v1.0.blend\"",
"lineNumber": 8
},
{
"text": " ",
"lineNumber": 9
},
{
"text": " if not os.path.exists(library_path):",
"lineNumber": 10
},
{
"text": " print(f\"Warning: Library file not found at {library_path}\")",
"lineNumber": 11
},
{
"text": " return []",
"lineNumber": 12
},
{
"text": " ",
"lineNumber": 13
},
{
"text": " print(f\"Linking materials from: {library_path}\")",
"lineNumber": 14
},
{
"text": " ",
"lineNumber": 15
},
{
"text": " # Get list of materials before linking",
"lineNumber": 16
},
{
"text": " materials_before = set(bpy.data.materials.keys())",
"lineNumber": 17
},
{
"text": " ",
"lineNumber": 18
},
{
"text": " # Link all materials from the library file",
"lineNumber": 19
},
{
"text": " with bpy.data.libraries.load(library_path, link=True) as (data_from, data_to):",
"lineNumber": 20
},
{
"text": " # Link all materials",
"lineNumber": 21
},
{
"text": " data_to.materials = data_from.materials",
"lineNumber": 22
},
{
"text": " ",
"lineNumber": 23
},
{
"text": " # Get list of newly linked materials",
"lineNumber": 24
},
{
"text": " materials_after = set(bpy.data.materials.keys())",
"lineNumber": 25
},
{
"text": " newly_linked = materials_after - materials_before",
"lineNumber": 26
},
{
"text": " ",
"lineNumber": 27
},
{
"text": " print(f\"Linked {len(newly_linked)} materials from library\")",
"lineNumber": 28
},
{
"text": " for mat_name in sorted(newly_linked):",
"lineNumber": 29
},
{
"text": " print(f\" - {mat_name}\")",
"lineNumber": 30
},
{
"text": " ",
"lineNumber": 31
},
{
"text": " return list(newly_linked)",
"lineNumber": 32,
"isSignature": true
},
{
"lineNumber": 33
},
{
"text": "def remap_appended_to_linked():",
"lineNumber": 34,
"isSignature": true
},
{
"text": " \"\"\"Remap any appended BSDF materials to their linked counterparts\"\"\"",
"lineNumber": 35
}
]
},
"score": 0.30952730774879456
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\UpgradeToGitProj.bat",
"range": {
"startPosition": {
"line": 121
},
"endPosition": {
"line": 166
}
},
"contents": " )\n )\n )\n\n if \"!foundSubmodules!\"==\"1\" (\n if \"%DRY%\"==\"1\" echo [DRY] Using submodules under Blends\\animations\n for /d %%S in (\"%animDir%\\*\") do (\n set \"name=%%~nS\"\n set \"prefix=!name:~0,6!\"\n if /I not \"!prefix!\"==\"daily_\" (\n set \"submodName=%%~nS\"\n set \"_subdir=%rendersDir%\\!submodName!\"\n rem Ensure submodule dir exists and place helper scripts there\n if \"%DRY%\"==\"1\" (\n if not exist \"!_subdir!\" echo [DRY] mkdir \"!_subdir!\"\n if exist \"%scriptDir%UpdateSequences.bat\" echo [DRY] copy \"%scriptDir%UpdateSequences.bat\" \"!_subdir!\\UpdateSequences.bat\"\n if exist \"%scriptDir%ZipSeqArchv.bat\" echo [DRY] copy \"%scriptDir%ZipSeqArchv.bat\" \"!_subdir!\\ZipSeqArchv.bat\"\n if exist \"%scriptDir%UnzipSeqArchv.bat\" echo [DRY] copy \"%scriptDir%UnzipSeqArchv.bat\" \"!_subdir!\\UnzipSeqArchv.bat\"\n ) else (\n if not exist \"!_subdir!\" mkdir \"!_subdir!\" &gt;nul 2&gt;&amp;1\n if exist \"%scriptDir%UpdateSequences.bat\" copy /Y \"%scriptDir%UpdateSequences.bat\" \"!_subdir!\\UpdateSequences.bat\" &gt;nul\n if exist \"%scriptDir%ZipSeqArchv.bat\" copy /Y \"%scriptDir%ZipSeqArchv.bat\" \"!_subdir!\\ZipSeqArchv.bat\" &gt;nul\n if exist \"%scriptDir%UnzipSeqArchv.bat\" copy /Y \"%scriptDir%UnzipSeqArchv.bat\" \"!_subdir!\\UnzipSeqArchv.bat\" &gt;nul\n )\n for /d %%D in (\"%%S\\daily_*\") do (\n set \"dailyName=%%~nD\"\n set \"_src=%%D\\seq\"\n set \"_dst=%rendersDir%\\!submodName!\\!dailyName!\"\n set /a debugTotal+=1\n if \"%DRY%\"==\"1\" (\n if exist \"!_src!\" (\n echo [DRY] WOULD copy \"!_src!\" -^&gt; \"!_dst!\"\n set /a debugPlanned+=1\n ) else (\n echo [DRY] Skip: missing \"!_src!\"\n set /a debugMissing+=1\n )\n )\n call :CopySeqToRenders \"!_src!\" \"!_dst!\"\n )\n )\n )\n set \"foundAny=1\"\n ) else (\n if \"%DRY%\"==\"1\" echo [DRY] No submodules found; using direct daily_* under animations",
"signatures": {},
"detailedLines": [
{
"text": " )",
"lineNumber": 122
},
{
"text": " )",
"lineNumber": 123
},
{
"text": " )",
"lineNumber": 124
},
{
"lineNumber": 125
},
{
"text": " if \"!foundSubmodules!\"==\"1\" (",
"lineNumber": 126
},
{
"text": " if \"%DRY%\"==\"1\" echo [DRY] Using submodules under Blends\\animations",
"lineNumber": 127
},
{
"text": " for /d %%S in (\"%animDir%\\*\") do (",
"lineNumber": 128
},
{
"text": " set \"name=%%~nS\"",
"lineNumber": 129
},
{
"text": " set \"prefix=!name:~0,6!\"",
"lineNumber": 130
},
{
"text": " if /I not \"!prefix!\"==\"daily_\" (",
"lineNumber": 131
},
{
"text": " set \"submodName=%%~nS\"",
"lineNumber": 132
},
{
"text": " set \"_subdir=%rendersDir%\\!submodName!\"",
"lineNumber": 133
},
{
"text": " rem Ensure submodule dir exists and place helper scripts there",
"lineNumber": 134
},
{
"text": " if \"%DRY%\"==\"1\" (",
"lineNumber": 135
},
{
"text": " if not exist \"!_subdir!\" echo [DRY] mkdir \"!_subdir!\"",
"lineNumber": 136
},
{
"text": " if exist \"%scriptDir%UpdateSequences.bat\" echo [DRY] copy \"%scriptDir%UpdateSequences.bat\" \"!_subdir!\\UpdateSequences.bat\"",
"lineNumber": 137
},
{
"text": " if exist \"%scriptDir%ZipSeqArchv.bat\" echo [DRY] copy \"%scriptDir%ZipSeqArchv.bat\" \"!_subdir!\\ZipSeqArchv.bat\"",
"lineNumber": 138
},
{
"text": " if exist \"%scriptDir%UnzipSeqArchv.bat\" echo [DRY] copy \"%scriptDir%UnzipSeqArchv.bat\" \"!_subdir!\\UnzipSeqArchv.bat\"",
"lineNumber": 139
},
{
"text": " ) else (",
"lineNumber": 140
},
{
"text": " if not exist \"!_subdir!\" mkdir \"!_subdir!\" &gt;nul 2&gt;&amp;1",
"lineNumber": 141
},
{
"text": " if exist \"%scriptDir%UpdateSequences.bat\" copy /Y \"%scriptDir%UpdateSequences.bat\" \"!_subdir!\\UpdateSequences.bat\" &gt;nul",
"lineNumber": 142
},
{
"text": " if exist \"%scriptDir%ZipSeqArchv.bat\" copy /Y \"%scriptDir%ZipSeqArchv.bat\" \"!_subdir!\\ZipSeqArchv.bat\" &gt;nul",
"lineNumber": 143
},
{
"text": " if exist \"%scriptDir%UnzipSeqArchv.bat\" copy /Y \"%scriptDir%UnzipSeqArchv.bat\" \"!_subdir!\\UnzipSeqArchv.bat\" &gt;nul",
"lineNumber": 144
},
{
"text": " )",
"lineNumber": 145
},
{
"text": " for /d %%D in (\"%%S\\daily_*\") do (",
"lineNumber": 146
},
{
"text": " set \"dailyName=%%~nD\"",
"lineNumber": 147
},
{
"text": " set \"_src=%%D\\seq\"",
"lineNumber": 148
},
{
"text": " set \"_dst=%rendersDir%\\!submodName!\\!dailyName!\"",
"lineNumber": 149
},
{
"text": " set /a debugTotal+=1",
"lineNumber": 150
},
{
"text": " if \"%DRY%\"==\"1\" (",
"lineNumber": 151
},
{
"text": " if exist \"!_src!\" (",
"lineNumber": 152
},
{
"text": " echo [DRY] WOULD copy \"!_src!\" -^&gt; \"!_dst!\"",
"lineNumber": 153
},
{
"text": " set /a debugPlanned+=1",
"lineNumber": 154
},
{
"text": " ) else (",
"lineNumber": 155
},
{
"text": " echo [DRY] Skip: missing \"!_src!\"",
"lineNumber": 156
},
{
"text": " set /a debugMissing+=1",
"lineNumber": 157
},
{
"text": " )",
"lineNumber": 158
},
{
"text": " )",
"lineNumber": 159
},
{
"text": " call :CopySeqToRenders \"!_src!\" \"!_dst!\"",
"lineNumber": 160
},
{
"text": " )",
"lineNumber": 161
},
{
"text": " )",
"lineNumber": 162
},
{
"text": " )",
"lineNumber": 163
},
{
"text": " set \"foundAny=1\"",
"lineNumber": 164
},
{
"text": " ) else (",
"lineNumber": 165
},
{
"text": " if \"%DRY%\"==\"1\" echo [DRY] No submodules found; using direct daily_* under animations",
"lineNumber": 166
}
]
},
"score": 0.2996269464492798
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\UpgradeToGitProj.bat",
"range": {
"startPosition": {
"line": 58
},
"endPosition": {
"line": 126,
"column": 4
}
},
"contents": "for %%F in (ConfigLoader.ps1 config.json) do (\n if exist \"%scriptDir%%%F\" (\n if \"%DRY%\"==\"1\" (\n echo [DRY] copy \"%scriptDir%%%F\" \"%rendersDir%\\%%F\"\n ) else (\n copy /Y \"%scriptDir%%%F\" \"%rendersDir%\\%%F\" &gt;nul\n )\n ) else (\n echo [WARN] Missing template: \"%scriptDir%%%F\"\n )\n)\n\n:: -----------------------------\n:: Merge .gitignore and .gitattributes from templates\n:: -----------------------------\nset \"tplGitIgnore=%scriptDir%components\\gitignore\"\nset \"dstGitIgnore=%projectDir%\\.gitignore\"\nset \"tplGitAttr=%scriptDir%components\\gitattributes\"\nset \"dstGitAttr=%projectDir%\\.gitattributes\"\n\ncall :MergeTemplate \"%tplGitIgnore%\" \"%dstGitIgnore%\"\ncall :MergeTemplate \"%tplGitAttr%\" \"%dstGitAttr%\"\n\n:: -----------------------------\n:: Initialize git and Git LFS\n:: -----------------------------\nif not exist \"%projectDir%\\.git\" (\n if \"%DRY%\"==\"1\" (\n echo [DRY] git init\n ) else (\n pushd \"%projectDir%\" &gt;nul\n git init\n popd &gt;nul\n )\n)\n\nif \"%DRY%\"==\"1\" (\n echo [DRY] git lfs install\n) else (\n pushd \"%projectDir%\" &gt;nul\n git lfs install\n popd &gt;nul\n)\n\n:: -----------------------------\n:: Collect seq outputs from daily_* into Renders\n:: -----------------------------\nset \"animDir=%projectDir%\\Blends\\animations\"\nset \"foundAny=0\"\nset \"foundSubmodules=0\"\n\nif exist \"%animDir%\" (\n if \"%DRY%\"==\"1\" echo [DRY] Scanning animations dir: \"%animDir%\"\n :: Detect submodules: first-level folders under animations that contain daily_*\n for /d %%S in (\"%animDir%\\*\") do (\n set \"name=%%~nS\"\n set \"prefix=!name:~0,6!\"\n if /I not \"!prefix!\"==\"daily_\" (\n for /d %%D in (\"%%S\\daily_*\") do (\n set \"foundSubmodules=1\"\n )\n if \"%DRY%\"==\"1\" (\n if exist \"%%S\\daily_*\" echo [DRY] Detected submodule: \"%%~nS\"\n )\n )\n )\n\n if \"!foundSubmodules!\"==\"1\" (\n ",
"signatures": {},
"detailedLines": [
{
"text": "for %%F in (ConfigLoader.ps1 config.json) do (",
"lineNumber": 59
},
{
"text": " if exist \"%scriptDir%%%F\" (",
"lineNumber": 60
},
{
"text": " if \"%DRY%\"==\"1\" (",
"lineNumber": 61
},
{
"text": " echo [DRY] copy \"%scriptDir%%%F\" \"%rendersDir%\\%%F\"",
"lineNumber": 62
},
{
"text": " ) else (",
"lineNumber": 63
},
{
"text": " copy /Y \"%scriptDir%%%F\" \"%rendersDir%\\%%F\" &gt;nul",
"lineNumber": 64
},
{
"text": " )",
"lineNumber": 65
},
{
"text": " ) else (",
"lineNumber": 66
},
{
"text": " echo [WARN] Missing template: \"%scriptDir%%%F\"",
"lineNumber": 67
},
{
"text": " )",
"lineNumber": 68
},
{
"text": ")",
"lineNumber": 69
},
{
"lineNumber": 70
},
{
"text": ":: -----------------------------",
"lineNumber": 71
},
{
"text": ":: Merge .gitignore and .gitattributes from templates",
"lineNumber": 72
},
{
"text": ":: -----------------------------",
"lineNumber": 73
},
{
"text": "set \"tplGitIgnore=%scriptDir%components\\gitignore\"",
"lineNumber": 74
},
{
"text": "set \"dstGitIgnore=%projectDir%\\.gitignore\"",
"lineNumber": 75
},
{
"text": "set \"tplGitAttr=%scriptDir%components\\gitattributes\"",
"lineNumber": 76
},
{
"text": "set \"dstGitAttr=%projectDir%\\.gitattributes\"",
"lineNumber": 77
},
{
"lineNumber": 78
},
{
"text": "call :MergeTemplate \"%tplGitIgnore%\" \"%dstGitIgnore%\"",
"lineNumber": 79
},
{
"text": "call :MergeTemplate \"%tplGitAttr%\" \"%dstGitAttr%\"",
"lineNumber": 80
},
{
"lineNumber": 81
},
{
"text": ":: -----------------------------",
"lineNumber": 82
},
{
"text": ":: Initialize git and Git LFS",
"lineNumber": 83
},
{
"text": ":: -----------------------------",
"lineNumber": 84
},
{
"text": "if not exist \"%projectDir%\\.git\" (",
"lineNumber": 85
},
{
"text": " if \"%DRY%\"==\"1\" (",
"lineNumber": 86
},
{
"text": " echo [DRY] git init",
"lineNumber": 87
},
{
"text": " ) else (",
"lineNumber": 88
},
{
"text": " pushd \"%projectDir%\" &gt;nul",
"lineNumber": 89
},
{
"text": " git init",
"lineNumber": 90
},
{
"text": " popd &gt;nul",
"lineNumber": 91
},
{
"text": " )",
"lineNumber": 92
},
{
"text": ")",
"lineNumber": 93
},
{
"lineNumber": 94
},
{
"text": "if \"%DRY%\"==\"1\" (",
"lineNumber": 95
},
{
"text": " echo [DRY] git lfs install",
"lineNumber": 96
},
{
"text": ") else (",
"lineNumber": 97
},
{
"text": " pushd \"%projectDir%\" &gt;nul",
"lineNumber": 98
},
{
"text": " git lfs install",
"lineNumber": 99
},
{
"text": " popd &gt;nul",
"lineNumber": 100
},
{
"text": ")",
"lineNumber": 101
},
{
"lineNumber": 102
},
{
"text": ":: -----------------------------",
"lineNumber": 103
},
{
"text": ":: Collect seq outputs from daily_* into Renders",
"lineNumber": 104
},
{
"text": ":: -----------------------------",
"lineNumber": 105
},
{
"text": "set \"animDir=%projectDir%\\Blends\\animations\"",
"lineNumber": 106
},
{
"text": "set \"foundAny=0\"",
"lineNumber": 107
},
{
"text": "set \"foundSubmodules=0\"",
"lineNumber": 108
},
{
"lineNumber": 109
},
{
"text": "if exist \"%animDir%\" (",
"lineNumber": 110
},
{
"text": " if \"%DRY%\"==\"1\" echo [DRY] Scanning animations dir: \"%animDir%\"",
"lineNumber": 111
},
{
"text": " :: Detect submodules: first-level folders under animations that contain daily_*",
"lineNumber": 112
},
{
"text": " for /d %%S in (\"%animDir%\\*\") do (",
"lineNumber": 113
},
{
"text": " set \"name=%%~nS\"",
"lineNumber": 114
},
{
"text": " set \"prefix=!name:~0,6!\"",
"lineNumber": 115
},
{
"text": " if /I not \"!prefix!\"==\"daily_\" (",
"lineNumber": 116
},
{
"text": " for /d %%D in (\"%%S\\daily_*\") do (",
"lineNumber": 117
},
{
"text": " set \"foundSubmodules=1\"",
"lineNumber": 118
},
{
"text": " )",
"lineNumber": 119
},
{
"text": " if \"%DRY%\"==\"1\" (",
"lineNumber": 120
},
{
"text": " if exist \"%%S\\daily_*\" echo [DRY] Detected submodule: \"%%~nS\"",
"lineNumber": 121
},
{
"text": " )",
"lineNumber": 122
},
{
"text": " )",
"lineNumber": 123
},
{
"text": " )",
"lineNumber": 124
},
{
"lineNumber": 125
},
{
"text": " if \"!foundSubmodules!\"==\"1\" (",
"lineNumber": 126
},
{
"text": " ",
"lineNumber": 127
}
]
},
"score": 0.29278281331062317
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\replace_cel_with_bsdf.py",
"range": {
"startPosition": {
"line": 186,
"column": 26
},
"endPosition": {
"line": 355
}
},
"contents": "def replace_cel_materials():\n \"\"\"Replace all CEL materials with their BSDF counterparts using Blender's user remapping\"\"\"\n \n # First, link BSDF materials from library\n linked_materials = link_bsdf_materials()\n \n # Then, remap any missing datablocks\n missing_remaps = remap_missing_datablocks()\n \n # Then, remap any appended BSDF materials to linked versions\n appended_remaps = remap_appended_to_linked()\n \n print(f\"\\n=== STARTING MATERIAL REPLACEMENT ===\")\n \n # Custom material mappings (source -&gt; target)\n custom_mappings = {\n \"bag BLACK (squid ink)\": \"BSDF_black_SQUID-INK\",\n \"bag WHITE\": \"BSDF_WHITE\",\n \"Wheel-White\": \"BSDF_WHITE\",\n \"Bag Colors\": \"BSDF_Bag Colors\",\n \"cardboard\": \"Package_Cardboard\",\n \"blue (triton)\": \"BSDF_blue-2_TRITON\",\n \"gray (snow)\": \"BSDF_gray-6_SNOW\",\n \"gray (storm)\": \"BSDF_gray-2_STORM\",\n \"gray (summit)\": \"BSDF_gray-5_SUMMIT\",\n \"light blue (prime)\": \"BSDF_blue-4_PRIME\",\n \"yellow (summer)\": \"BSDF_orange-5_SUMMER\",\n \"Accessory_CEL_gray-6_SNOW\": \"BSDF_gray-6_SNOW\",\n \"Accessory_CEL_SquidInk\": \"BSDF_black_SQUID-INK\",\n \"FingerScanner\": \"BSDF_black_SQUID-INK\",\n \"cel BLACK (squid ink)\": \"BSDF_black_SQUID-INK\",\n \"cel WHITE\": \"BSDF_WHITE\",\n \"gray (stone)\": \"BSDF_gray-3_STONE\",\n \"green (oxygen)\": \"BSDF_green-3_OXYGEN\",\n \"orange (smile)\": \"BSDF_orange-3_SMILE\",\n \"orange (blaze)\": \"BSDF_orange-1_BLAZE\"\n }\n \n # Get all materials in the scene\n materials = bpy.data.materials\n \n # Dictionary to store source -&gt; target material mapping\n material_mapping = {}\n \n # Replace all CEL materials with their BSDF counterparts, ignoring numeric suffixes\n cel_pattern = re.compile(r\"^(CEL_.+?)(\\.\\d{3})?$\")\n bsdf_pattern = re.compile(r\"^(BSDF_.+?)(\\.\\d{3})?$\")\n \n # Build a mapping from base BSDF name to BSDF material (without suffix)",
"signatures": {},
"detailedLines": [
{
"text": "def replace_cel_materials():",
"lineNumber": 189,
"isSignature": true
},
{
"text": " \"\"\"Replace all CEL materials with their BSDF counterparts using Blender's user remapping\"\"\"",
"lineNumber": 190
},
{
"text": " ",
"lineNumber": 191
},
{
"text": " # First, link BSDF materials from library",
"lineNumber": 192
},
{
"text": " linked_materials = link_bsdf_materials()",
"lineNumber": 193
},
{
"text": " ",
"lineNumber": 194
},
{
"text": " # Then, remap any missing datablocks",
"lineNumber": 195
},
{
"text": " missing_remaps = remap_missing_datablocks()",
"lineNumber": 196
},
{
"text": " ",
"lineNumber": 197
},
{
"text": " # Then, remap any appended BSDF materials to linked versions",
"lineNumber": 198
},
{
"text": " appended_remaps = remap_appended_to_linked()",
"lineNumber": 199
},
{
"text": " ",
"lineNumber": 200
},
{
"text": " print(f\"\\n=== STARTING MATERIAL REPLACEMENT ===\")",
"lineNumber": 201
},
{
"text": " ",
"lineNumber": 202
},
{
"text": " # Custom material mappings (source -&gt; target)",
"lineNumber": 203
},
{
"text": " custom_mappings = {",
"lineNumber": 204
},
{
"text": " \"bag BLACK (squid ink)\": \"BSDF_black_SQUID-INK\",",
"lineNumber": 205
},
{
"text": " \"bag WHITE\": \"BSDF_WHITE\",",
"lineNumber": 206
},
{
"text": " \"Wheel-White\": \"BSDF_WHITE\",",
"lineNumber": 207
},
{
"text": " \"Bag Colors\": \"BSDF_Bag Colors\",",
"lineNumber": 208
},
{
"text": " \"cardboard\": \"Package_Cardboard\",",
"lineNumber": 209
},
{
"text": " \"blue (triton)\": \"BSDF_blue-2_TRITON\",",
"lineNumber": 210
},
{
"text": " \"gray (snow)\": \"BSDF_gray-6_SNOW\",",
"lineNumber": 211
},
{
"text": " \"gray (storm)\": \"BSDF_gray-2_STORM\",",
"lineNumber": 212
},
{
"text": " \"gray (summit)\": \"BSDF_gray-5_SUMMIT\",",
"lineNumber": 213
},
{
"text": " \"light blue (prime)\": \"BSDF_blue-4_PRIME\",",
"lineNumber": 214
},
{
"text": " \"yellow (summer)\": \"BSDF_orange-5_SUMMER\",",
"lineNumber": 215
},
{
"text": " \"Accessory_CEL_gray-6_SNOW\": \"BSDF_gray-6_SNOW\",",
"lineNumber": 216
},
{
"text": " \"Accessory_CEL_SquidInk\": \"BSDF_black_SQUID-INK\",",
"lineNumber": 217
},
{
"text": " \"FingerScanner\": \"BSDF_black_SQUID-INK\",",
"lineNumber": 218
},
{
"text": " \"cel BLACK (squid ink)\": \"BSDF_black_SQUID-INK\",",
"lineNumber": 219
},
{
"text": " \"cel WHITE\": \"BSDF_WHITE\",",
"lineNumber": 220
},
{
"text": " \"gray (stone)\": \"BSDF_gray-3_STONE\",",
"lineNumber": 221
},
{
"text": " \"green (oxygen)\": \"BSDF_green-3_OXYGEN\",",
"lineNumber": 222
},
{
"text": " \"orange (smile)\": \"BSDF_orange-3_SMILE\",",
"lineNumber": 223
},
{
"text": " \"orange (blaze)\": \"BSDF_orange-1_BLAZE\"",
"lineNumber": 224
},
{
"text": " }",
"lineNumber": 225
},
{
"text": " ",
"lineNumber": 226
},
{
"text": " # Get all materials in the scene",
"lineNumber": 227
},
{
"text": " materials = bpy.data.materials",
"lineNumber": 228
},
{
"text": " ",
"lineNumber": 229
},
{
"text": " # Dictionary to store source -&gt; target material mapping",
"lineNumber": 230
},
{
"text": " material_mapping = {}",
"lineNumber": 231
},
{
"text": " ",
"lineNumber": 232
},
{
"text": " # Replace all CEL materials with their BSDF counterparts, ignoring numeric suffixes",
"lineNumber": 233
},
{
"text": " cel_pattern = re.compile(r\"^(CEL_.+?)(\\.\\d{3})?$\")",
"lineNumber": 234
},
{
"text": " bsdf_pattern = re.compile(r\"^(BSDF_.+?)(\\.\\d{3})?$\")",
"lineNumber": 235
},
{
"text": " ",
"lineNumber": 236
},
{
"text": " # Build a mapping from base BSDF name to BSDF material (without suffix)",
"lineNumber": 237
}
]
},
"score": 0.2842274010181427
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\CONFIG.md",
"range": {
"startPosition": {},
"endPosition": {
"line": 24
}
},
"contents": "# ProjectStructure Configuration\n\nThe repository reads user preferences from &#96;config.json&#96; in the ProjectStructure\nroot (copied alongside helper batches when they are deployed to projects).\n\n## Keys\n\n| Key | Type | Meaning |\n| --- | --- | --- |\n| &#96;dailyFormat&#96; | bool | &#96;true&#96; → daily folders named &#96;YYYY-MM-DD&#96;; &#96;false&#96; → &#96;daily_*&#96; style. |\n| &#96;structDir&#96; | string | Absolute or relative path to the canonical ProjectStructure directory. Blank values default to the folder containing &#96;config.json&#96;. |\n| &#96;projectsRoot&#96; | string (optional) | Override for the root directory scanned by &#96;UpgradeSeqBatches.ps1&#96;. Defaults to the parent of &#96;structDir&#96;. |\n| &#96;zipper&#96; | bool | &#96;true&#96; → use 7Zip (if available); &#96;false&#96; → use Pythons built-in zipfile module. |\n| &#96;compression&#96; | int | Compression level &#96;0-9&#96; (0 = store only, 9 = max). Applies to both zipfile and 7Zip. |\n\n## Notes\n\n- &#96;UpdateProjectBatches.ps1&#96; copies &#96;config.json&#96; and &#96;ConfigLoader.ps1&#96; to the\n target project so the helper &#96;.bat&#96; launchers can resolve script locations.\n- When &#96;zipper&#96; is &#96;true&#96;, the tool searches for &#96;7z&#96;/&#96;7za&#96; on &#96;PATH&#96;. If neither\n is found it logs a warning and falls back to &#96;zipfile&#96;.\n- Leaving &#96;structDir&#96; empty is safe—the scripts fall back to the directory that\n contains &#96;config.json&#96;.",
"signatures": {},
"detailedLines": [
{
"text": "# ProjectStructure Configuration",
"lineNumber": 1
},
{
"lineNumber": 2
},
{
"text": "The repository reads user preferences from &#96;config.json&#96; in the ProjectStructure",
"lineNumber": 3
},
{
"text": "root (copied alongside helper batches when they are deployed to projects).",
"lineNumber": 4
},
{
"lineNumber": 5
},
{
"text": "## Keys",
"lineNumber": 6
},
{
"lineNumber": 7
},
{
"text": "| Key | Type | Meaning |",
"lineNumber": 8
},
{
"text": "| --- | --- | --- |",
"lineNumber": 9
},
{
"text": "| &#96;dailyFormat&#96; | bool | &#96;true&#96; → daily folders named &#96;YYYY-MM-DD&#96;; &#96;false&#96; → &#96;daily_*&#96; style. |",
"lineNumber": 10
},
{
"text": "| &#96;structDir&#96; | string | Absolute or relative path to the canonical ProjectStructure directory. Blank values default to the folder containing &#96;config.json&#96;. |",
"lineNumber": 11
},
{
"text": "| &#96;projectsRoot&#96; | string (optional) | Override for the root directory scanned by &#96;UpgradeSeqBatches.ps1&#96;. Defaults to the parent of &#96;structDir&#96;. |",
"lineNumber": 12
},
{
"text": "| &#96;zipper&#96; | bool | &#96;true&#96; → use 7Zip (if available); &#96;false&#96; → use Pythons built-in zipfile module. |",
"lineNumber": 13
},
{
"text": "| &#96;compression&#96; | int | Compression level &#96;0-9&#96; (0 = store only, 9 = max). Applies to both zipfile and 7Zip. |",
"lineNumber": 14
},
{
"lineNumber": 15
},
{
"text": "## Notes",
"lineNumber": 16
},
{
"lineNumber": 17
},
{
"text": "- &#96;UpdateProjectBatches.ps1&#96; copies &#96;config.json&#96; and &#96;ConfigLoader.ps1&#96; to the",
"lineNumber": 18
},
{
"text": " target project so the helper &#96;.bat&#96; launchers can resolve script locations.",
"lineNumber": 19
},
{
"text": "- When &#96;zipper&#96; is &#96;true&#96;, the tool searches for &#96;7z&#96;/&#96;7za&#96; on &#96;PATH&#96;. If neither",
"lineNumber": 20
},
{
"text": " is found it logs a warning and falls back to &#96;zipfile&#96;.",
"lineNumber": 21
},
{
"text": "- Leaving &#96;structDir&#96; empty is safe—the scripts fall back to the directory that",
"lineNumber": 22
},
{
"text": " contains &#96;config.json&#96;.",
"lineNumber": 23
}
]
},
"score": 0.2787865400314331
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\components\\gitattributes",
"range": {
"startPosition": {
"line": 51
},
"endPosition": {
"line": 111,
"column": 40
}
},
"contents": "*.hiplc filter=lfs diff=lfs merge=lfs -text\n*.bgeo filter=lfs diff=lfs merge=lfs -text\n*.bgeo.sc filter=lfs diff=lfs merge=lfs -text\n\n# Flip Fluids cache files\n*.data filter=lfs diff=lfs merge=lfs -text\n*.sqlite3 filter=lfs diff=lfs merge=lfs -text\n*.ffp3 filter=lfs diff=lfs merge=lfs -text\n\n# Substance files\n*.sbs filter=lfs diff=lfs merge=lfs -text\n*.sbsar filter=lfs diff=lfs merge=lfs -text\n*.spp filter=lfs diff=lfs merge=lfs -text\n\n# Audio files\n*.mp3 filter=lfs diff=lfs merge=lfs -text\n*.wav filter=lfs diff=lfs merge=lfs -text\n\n# Archive/Compression files\n*.7z filter=lfs diff=lfs merge=lfs -text\n*.bz2 filter=lfs diff=lfs merge=lfs -text\n*.gz filter=lfs diff=lfs merge=lfs -text\n*.rar filter=lfs diff=lfs merge=lfs -text\n*.tar filter=lfs diff=lfs merge=lfs -text\n*.zip filter=lfs diff=lfs merge=lfs -text\n\n# Documents\n*.docx filter=lfs diff=lfs merge=lfs -text\n*.xlsx filter=lfs diff=lfs merge=lfs -text\n*.eps filter=lfs diff=lfs merge=lfs -text\n*.pdf filter=lfs diff=lfs merge=lfs -text\n\n# Adobe files\n*.aegraphic filter=lfs diff=lfs merge=lfs -text\n*.aep filter=lfs diff=lfs merge=lfs -text\n*.prel filter=lfs diff=lfs merge=lfs -text\n*.prin filter=lfs diff=lfs merge=lfs -text\n*.prmf filter=lfs diff=lfs merge=lfs -text\n*.prproj filter=lfs diff=lfs merge=lfs -text\n*.ai filter=lfs diff=lfs merge=lfs -text\n*.psd filter=lfs diff=lfs merge=lfs -text\n\n# Davinci Resolve files\n*.dpx filter=lfs diff=lfs merge=lfs -text\n*.drp filter=lfs diff=lfs merge=lfs -text\n\n# Data files\n*.h5 filter=lfs diff=lfs merge=lfs -text\n*.hdf5 filter=lfs diff=lfs merge=lfs -text\n\n# Other\n*.uni filter=lfs diff=lfs merge=lfs -text\n*.pdn filter=lfs diff=lfs merge=lfs -text\n*.pur filter=lfs diff=lfs merge=lfs -text\n\n# Python files\n*.npz filter=lfs diff=lfs merge=lfs -text\n\n# Adobe Alternatives\n*.xcf filter=lfs diff=lfs merge=lfs -text\n*.af filter=lfs diff=lfs merge=lfs -text",
"signatures": {},
"detailedLines": [
{
"text": "*.hiplc filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 52
},
{
"text": "*.bgeo filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 53
},
{
"text": "*.bgeo.sc filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 54
},
{
"lineNumber": 55
},
{
"text": "# Flip Fluids cache files",
"lineNumber": 56
},
{
"text": "*.data filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 57
},
{
"text": "*.sqlite3 filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 58
},
{
"text": "*.ffp3 filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 59
},
{
"lineNumber": 60
},
{
"text": "# Substance files",
"lineNumber": 61
},
{
"text": "*.sbs filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 62
},
{
"text": "*.sbsar filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 63
},
{
"text": "*.spp filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 64
},
{
"lineNumber": 65
},
{
"text": "# Audio files",
"lineNumber": 66
},
{
"text": "*.mp3 filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 67
},
{
"text": "*.wav filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 68
},
{
"lineNumber": 69
},
{
"text": "# Archive/Compression files",
"lineNumber": 70
},
{
"text": "*.7z filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 71
},
{
"text": "*.bz2 filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 72
},
{
"text": "*.gz filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 73
},
{
"text": "*.rar filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 74
},
{
"text": "*.tar filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 75
},
{
"text": "*.zip filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 76
},
{
"lineNumber": 77
},
{
"text": "# Documents",
"lineNumber": 78
},
{
"text": "*.docx filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 79
},
{
"text": "*.xlsx filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 80
},
{
"text": "*.eps filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 81
},
{
"text": "*.pdf filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 82
},
{
"lineNumber": 83
},
{
"text": "# Adobe files",
"lineNumber": 84
},
{
"text": "*.aegraphic filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 85
},
{
"text": "*.aep filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 86
},
{
"text": "*.prel filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 87
},
{
"text": "*.prin filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 88
},
{
"text": "*.prmf filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 89
},
{
"text": "*.prproj filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 90
},
{
"text": "*.ai filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 91
},
{
"text": "*.psd filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 92
},
{
"lineNumber": 93
},
{
"text": "# Davinci Resolve files",
"lineNumber": 94
},
{
"text": "*.dpx filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 95
},
{
"text": "*.drp filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 96
},
{
"lineNumber": 97
},
{
"text": "# Data files",
"lineNumber": 98
},
{
"text": "*.h5 filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 99
},
{
"text": "*.hdf5 filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 100
},
{
"lineNumber": 101
},
{
"text": "# Other",
"lineNumber": 102
},
{
"text": "*.uni filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 103
},
{
"text": "*.pdn filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 104
},
{
"text": "*.pur filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 105
},
{
"lineNumber": 106
},
{
"text": "# Python files",
"lineNumber": 107
},
{
"text": "*.npz filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 108
},
{
"lineNumber": 109
},
{
"text": "# Adobe Alternatives",
"lineNumber": 110
},
{
"text": "*.xcf filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 111
},
{
"text": "*.af filter=lfs diff=lfs merge=lfs -text",
"lineNumber": 112
}
]
},
"score": 0.27743393182754517
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\compress_blend_files.bat",
"range": {
"startPosition": {},
"endPosition": {
"line": 66
}
},
"contents": "@echo off\nsetlocal enabledelayedexpansion\n\necho Starting Blender file compression...\n\nREM Check if files were dragged onto the batch file\nif \"%~1\"==\"\" (\n echo.\n echo Usage: Drag .blend files onto this batch file to compress them.\n echo Output will be saved to the \\output folder.\n echo.\n pause\n exit /b 1\n)\n\nREM Create output directory if it doesn't exist\nif not exist \"output\" mkdir \"output\"\n\nREM Initialize counters and tracking\nset \"processed=0\"\nset \"crashed=0\"\nset \"skipped=0\"\nset \"deleted_similar=0\"\nset \"threshold_percent=10\"\n\nREM Create a temporary Python script for compression\nset \"TEMP_SCRIPT=compress_blend_temp.py\"\necho Creating Python script: !TEMP_SCRIPT!\n\n(\necho import bpy\necho import os\necho import sys\necho.\necho # Enable compression globally\necho bpy.context.preferences.filepaths.save_version = 0\necho bpy.context.preferences.filepaths.use_file_compression = True\necho.\necho # Create output directory if it doesn't exist\necho if not os.path.exists^(\"output\"^):\necho os.makedirs^(\"output\"^)\necho.\necho # Get command line arguments ^(the dragged files^)\necho blend_files = sys.argv[sys.argv.index^(\"--\"^) + 1:] if \"--\" in sys.argv else []\necho.\necho print^(\"Found \" + str^(len^(blend_files^)^) + \" .blend files to compress\"^)\necho.\necho def is_compressed_file^(path^):\necho try:\necho with open^(path, 'rb'^) as f:\necho header = f.read^(4^)\necho if header[:2] == b'\\x1f\\x8b': # gzip\necho return True\necho if header == b'\\x28\\xb5\\x2f\\xfd': # zstd\necho return True\necho return False\necho except Exception:\necho return False\necho.\necho for blend_file in blend_files:\necho if blend_file.lower^(^).endswith^(\".blend\"^):\necho try:\necho # Create output path in output folder\necho filename = os.path.basename^(blend_file^)\necho output_file = os.path.join^(\"output\", filename^)\necho # Check if output file already exists",
"signatures": {},
"detailedLines": [
{
"text": "@echo off",
"lineNumber": 1
},
{
"text": "setlocal enabledelayedexpansion",
"lineNumber": 2
},
{
"lineNumber": 3
},
{
"text": "echo Starting Blender file compression...",
"lineNumber": 4
},
{
"lineNumber": 5
},
{
"text": "REM Check if files were dragged onto the batch file",
"lineNumber": 6
},
{
"text": "if \"%~1\"==\"\" (",
"lineNumber": 7
},
{
"text": " echo.",
"lineNumber": 8
},
{
"text": " echo Usage: Drag .blend files onto this batch file to compress them.",
"lineNumber": 9
},
{
"text": " echo Output will be saved to the \\output folder.",
"lineNumber": 10
},
{
"text": " echo.",
"lineNumber": 11
},
{
"text": " pause",
"lineNumber": 12
},
{
"text": " exit /b 1",
"lineNumber": 13
},
{
"text": ")",
"lineNumber": 14
},
{
"lineNumber": 15
},
{
"text": "REM Create output directory if it doesn't exist",
"lineNumber": 16
},
{
"text": "if not exist \"output\" mkdir \"output\"",
"lineNumber": 17
},
{
"lineNumber": 18
},
{
"text": "REM Initialize counters and tracking",
"lineNumber": 19
},
{
"text": "set \"processed=0\"",
"lineNumber": 20
},
{
"text": "set \"crashed=0\"",
"lineNumber": 21
},
{
"text": "set \"skipped=0\"",
"lineNumber": 22
},
{
"text": "set \"deleted_similar=0\"",
"lineNumber": 23
},
{
"text": "set \"threshold_percent=10\"",
"lineNumber": 24
},
{
"lineNumber": 25
},
{
"text": "REM Create a temporary Python script for compression",
"lineNumber": 26
},
{
"text": "set \"TEMP_SCRIPT=compress_blend_temp.py\"",
"lineNumber": 27
},
{
"text": "echo Creating Python script: !TEMP_SCRIPT!",
"lineNumber": 28
},
{
"lineNumber": 29
},
{
"text": "(",
"lineNumber": 30
},
{
"text": "echo import bpy",
"lineNumber": 31
},
{
"text": "echo import os",
"lineNumber": 32
},
{
"text": "echo import sys",
"lineNumber": 33
},
{
"text": "echo.",
"lineNumber": 34
},
{
"text": "echo # Enable compression globally",
"lineNumber": 35
},
{
"text": "echo bpy.context.preferences.filepaths.save_version = 0",
"lineNumber": 36
},
{
"text": "echo bpy.context.preferences.filepaths.use_file_compression = True",
"lineNumber": 37
},
{
"text": "echo.",
"lineNumber": 38
},
{
"text": "echo # Create output directory if it doesn't exist",
"lineNumber": 39
},
{
"text": "echo if not os.path.exists^(\"output\"^):",
"lineNumber": 40
},
{
"text": "echo os.makedirs^(\"output\"^)",
"lineNumber": 41
},
{
"text": "echo.",
"lineNumber": 42
},
{
"text": "echo # Get command line arguments ^(the dragged files^)",
"lineNumber": 43
},
{
"text": "echo blend_files = sys.argv[sys.argv.index^(\"--\"^) + 1:] if \"--\" in sys.argv else []",
"lineNumber": 44
},
{
"text": "echo.",
"lineNumber": 45
},
{
"text": "echo print^(\"Found \" + str^(len^(blend_files^)^) + \" .blend files to compress\"^)",
"lineNumber": 46
},
{
"text": "echo.",
"lineNumber": 47
},
{
"text": "echo def is_compressed_file^(path^):",
"lineNumber": 48
},
{
"text": "echo try:",
"lineNumber": 49
},
{
"text": "echo with open^(path, 'rb'^) as f:",
"lineNumber": 50
},
{
"text": "echo header = f.read^(4^)",
"lineNumber": 51
},
{
"text": "echo if header[:2] == b'\\x1f\\x8b': # gzip",
"lineNumber": 52
},
{
"text": "echo return True",
"lineNumber": 53
},
{
"text": "echo if header == b'\\x28\\xb5\\x2f\\xfd': # zstd",
"lineNumber": 54
},
{
"text": "echo return True",
"lineNumber": 55
},
{
"text": "echo return False",
"lineNumber": 56
},
{
"text": "echo except Exception:",
"lineNumber": 57
},
{
"text": "echo return False",
"lineNumber": 58
},
{
"text": "echo.",
"lineNumber": 59
},
{
"text": "echo for blend_file in blend_files:",
"lineNumber": 60
},
{
"text": "echo if blend_file.lower^(^).endswith^(\".blend\"^):",
"lineNumber": 61
},
{
"text": "echo try:",
"lineNumber": 62
},
{
"text": "echo # Create output path in output folder",
"lineNumber": 63
},
{
"text": "echo filename = os.path.basename^(blend_file^)",
"lineNumber": 64
},
{
"text": "echo output_file = os.path.join^(\"output\", filename^)",
"lineNumber": 65
},
{
"text": "echo # Check if output file already exists",
"lineNumber": 66
}
]
},
"score": 0.27458083629608154
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\organize_textures.ps1",
"range": {
"startPosition": {
"line": 44
},
"endPosition": {
"line": 83,
"column": 8
}
},
"contents": " $null\n }\n}\n$filesWithChecksums = $allFiles | ForEach-Object -Parallel $parallelScriptBlock -ThrottleLimit $throttleLimit | Where-Object { $null -ne $_ }\n\nWrite-Host \"Checksum calculation complete.\" -ForegroundColor Green\n\n# Group files by checksum\nWrite-Host \"Grouping files by checksum...\" -ForegroundColor Yellow\n$groupedByChecksum = $filesWithChecksums | Group-Object -Property Hash\n\nWrite-Host \"Found $($groupedByChecksum.Count) unique checksums.\" -ForegroundColor Green\n\n# Create \\common and \\common\\duplicates directories\n$commonPath = Join-Path -Path $textureFolderPath -ChildPath \"common\"\n$duplicatesPath = Join-Path -Path $commonPath -ChildPath \"duplicates\"\n\nif (-not (Test-Path -Path $commonPath -PathType Container)) {\n New-Item -ItemType Directory -Path $commonPath | Out-Null\n Write-Host \"Created directory: $commonPath\" -ForegroundColor Green\n}\n\nif (-not (Test-Path -Path $duplicatesPath -PathType Container)) {\n New-Item -ItemType Directory -Path $duplicatesPath | Out-Null\n Write-Host \"Created directory: $duplicatesPath\" -ForegroundColor Green\n}\n\n# Track filenames already in \\common to handle name conflicts\n$filesInCommon = @{}\n\n# Process each checksum group\nWrite-Host \"Moving files to \\common and \\common\\duplicates...\" -ForegroundColor Yellow\n$movedCount = 0\n$duplicateCount = 0\n\nforeach ($group in $groupedByChecksum) {\n $files = $group.Group\n \n if ($files.Count -eq 1) {\n ",
"signatures": {},
"detailedLines": [
{
"text": " $null",
"lineNumber": 45
},
{
"text": " }",
"lineNumber": 46
},
{
"text": "}",
"lineNumber": 47
},
{
"text": "$filesWithChecksums = $allFiles | ForEach-Object -Parallel $parallelScriptBlock -ThrottleLimit $throttleLimit | Where-Object { $null -ne $_ }",
"lineNumber": 48
},
{
"lineNumber": 49
},
{
"text": "Write-Host \"Checksum calculation complete.\" -ForegroundColor Green",
"lineNumber": 50
},
{
"lineNumber": 51
},
{
"text": "# Group files by checksum",
"lineNumber": 52
},
{
"text": "Write-Host \"Grouping files by checksum...\" -ForegroundColor Yellow",
"lineNumber": 53
},
{
"text": "$groupedByChecksum = $filesWithChecksums | Group-Object -Property Hash",
"lineNumber": 54
},
{
"lineNumber": 55
},
{
"text": "Write-Host \"Found $($groupedByChecksum.Count) unique checksums.\" -ForegroundColor Green",
"lineNumber": 56
},
{
"lineNumber": 57
},
{
"text": "# Create \\common and \\common\\duplicates directories",
"lineNumber": 58
},
{
"text": "$commonPath = Join-Path -Path $textureFolderPath -ChildPath \"common\"",
"lineNumber": 59
},
{
"text": "$duplicatesPath = Join-Path -Path $commonPath -ChildPath \"duplicates\"",
"lineNumber": 60
},
{
"lineNumber": 61
},
{
"text": "if (-not (Test-Path -Path $commonPath -PathType Container)) {",
"lineNumber": 62
},
{
"text": " New-Item -ItemType Directory -Path $commonPath | Out-Null",
"lineNumber": 63
},
{
"text": " Write-Host \"Created directory: $commonPath\" -ForegroundColor Green",
"lineNumber": 64
},
{
"text": "}",
"lineNumber": 65
},
{
"lineNumber": 66
},
{
"text": "if (-not (Test-Path -Path $duplicatesPath -PathType Container)) {",
"lineNumber": 67
},
{
"text": " New-Item -ItemType Directory -Path $duplicatesPath | Out-Null",
"lineNumber": 68
},
{
"text": " Write-Host \"Created directory: $duplicatesPath\" -ForegroundColor Green",
"lineNumber": 69
},
{
"text": "}",
"lineNumber": 70
},
{
"lineNumber": 71
},
{
"text": "# Track filenames already in \\common to handle name conflicts",
"lineNumber": 72
},
{
"text": "$filesInCommon = @{}",
"lineNumber": 73
},
{
"lineNumber": 74
},
{
"text": "# Process each checksum group",
"lineNumber": 75
},
{
"text": "Write-Host \"Moving files to \\common and \\common\\duplicates...\" -ForegroundColor Yellow",
"lineNumber": 76
},
{
"text": "$movedCount = 0",
"lineNumber": 77
},
{
"text": "$duplicateCount = 0",
"lineNumber": 78
},
{
"lineNumber": 79
},
{
"text": "foreach ($group in $groupedByChecksum) {",
"lineNumber": 80
},
{
"text": " $files = $group.Group",
"lineNumber": 81
},
{
"text": " ",
"lineNumber": 82
},
{
"text": " if ($files.Count -eq 1) {",
"lineNumber": 83
},
{
"text": " ",
"lineNumber": 84
}
]
},
"score": 0.2703059911727905
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\NewProject.bat",
"range": {
"startPosition": {
"line": 61
},
"endPosition": {
"line": 83
}
},
"contents": "if not exist \"%projectRoot%\\Renders\" mkdir \"%projectRoot%\\Renders\"\n\n:: Place helper scripts into Renders\nset \"templateRoot=%STRUCT_DIR%\"\nfor %%F in (UpdateSequences.bat ZipSeqArchv.bat UnzipSeqArchv.bat ConfigLoader.ps1 config.json) do (\n if exist \"%templateRoot%\\%%F\" copy /Y \"%templateRoot%\\%%F\" \"%projectRoot%\\Renders\\%%F\" &gt;nul\n)\n\n:: Use repo-provided templates for git config files\nif exist \"%~dp0components\\gitignore\" copy /Y \"%~dp0components\\gitignore\" \"%projectRoot%\\.gitignore\" &gt;nul\nif exist \"%~dp0components\\gitattributes\" copy /Y \"%~dp0components\\gitattributes\" \"%projectRoot%\\.gitattributes\" &gt;nul\n\n:: Initialize git and install Git LFS\npushd \"%projectRoot%\" &gt;nul\ngit init\ngit lfs install\ngit add . -v\ngit commit -m \"init\"\npopd &gt;nul\n\necho Project structure created successfully in folder: %projectRoot%\npause ",
"signatures": {},
"detailedLines": [
{
"text": "if not exist \"%projectRoot%\\Renders\" mkdir \"%projectRoot%\\Renders\"",
"lineNumber": 62
},
{
"lineNumber": 63
},
{
"text": ":: Place helper scripts into Renders",
"lineNumber": 64
},
{
"text": "set \"templateRoot=%STRUCT_DIR%\"",
"lineNumber": 65
},
{
"text": "for %%F in (UpdateSequences.bat ZipSeqArchv.bat UnzipSeqArchv.bat ConfigLoader.ps1 config.json) do (",
"lineNumber": 66
},
{
"text": " if exist \"%templateRoot%\\%%F\" copy /Y \"%templateRoot%\\%%F\" \"%projectRoot%\\Renders\\%%F\" &gt;nul",
"lineNumber": 67
},
{
"text": ")",
"lineNumber": 68
},
{
"lineNumber": 69
},
{
"text": ":: Use repo-provided templates for git config files",
"lineNumber": 70
},
{
"text": "if exist \"%~dp0components\\gitignore\" copy /Y \"%~dp0components\\gitignore\" \"%projectRoot%\\.gitignore\" &gt;nul",
"lineNumber": 71
},
{
"text": "if exist \"%~dp0components\\gitattributes\" copy /Y \"%~dp0components\\gitattributes\" \"%projectRoot%\\.gitattributes\" &gt;nul",
"lineNumber": 72
},
{
"lineNumber": 73
},
{
"text": ":: Initialize git and install Git LFS",
"lineNumber": 74
},
{
"text": "pushd \"%projectRoot%\" &gt;nul",
"lineNumber": 75
},
{
"text": "git init",
"lineNumber": 76
},
{
"text": "git lfs install",
"lineNumber": 77
},
{
"text": "git add . -v",
"lineNumber": 78
},
{
"text": "git commit -m \"init\"",
"lineNumber": 79
},
{
"text": "popd &gt;nul",
"lineNumber": 80
},
{
"lineNumber": 81
},
{
"text": "echo Project structure created successfully in folder: %projectRoot%",
"lineNumber": 82
},
{
"text": "pause ",
"lineNumber": 83
}
]
},
"score": 0.2641300559043884
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\UpdateSequences.ps1",
"range": {
"startPosition": {
"line": 183
},
"endPosition": {
"line": 223,
"column": 8
}
},
"contents": "function Add-SequenceFolder {\n param(\n [Parameter(Mandatory)] [System.IO.DirectoryInfo]$Directory,\n [Parameter(Mandatory)] [hashtable]$Map\n )\n if ($Directory.Name -like '_*') { return }\n $fullPath = $Directory.FullName\n if ($Map.ContainsKey($fullPath)) { return }\n \n # Check if directory contains sequence files directly (not just subdirectories)\n $extensions = @('.png','.jpg','.jpeg','.exr','.tif','.tiff','.bmp','.tga')\n $hasSequenceFiles = Get-ChildItem -LiteralPath $fullPath -File -ErrorAction SilentlyContinue |\n Where-Object { $extensions -contains $_.Extension.ToLower() } |\n Select-Object -First 1\n \n # If it only has subdirectories and no sequence files, skip it\n $hasSubdirs = Get-ChildItem -LiteralPath $fullPath -Directory -ErrorAction SilentlyContinue |\n Select-Object -First 1\n if ($null -eq $hasSequenceFiles -and $null -ne $hasSubdirs) {\n return\n }\n \n $Map[$fullPath] = Resolve-SequenceName -Directory $Directory\n}\n\ntry {\n $root = (Get-Location).ProviderPath\n $logFile = $null\n\n if ($DebugMode) {\n $logFile = Join-Path $root (\"UpdateSequences_{0}.log\" -f (Get-Date -Format 'yyyyMMdd_HHmmss'))\n \"[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] === UpdateSequences started in '$root' ===\" | Out-File -LiteralPath $logFile -Encoding UTF8\n }\n\n $sequenceMap = @{}\n\n $primaryPattern = if ($useIsoDailyFormat) { '????-??-??' } else { 'daily_*' }\n $secondaryPattern = if ($useIsoDailyFormat) { 'daily_*' } else { '????-??-??' }\n\n $primaryDirs = Get-ChildItem -LiteralPath $root -Directory -Filter $primaryPattern -ErrorAction SilentlyContinue |\n ",
"signatures": {},
"detailedLines": [
{
"text": "function Add-SequenceFolder {",
"lineNumber": 184
},
{
"text": " param(",
"lineNumber": 185
},
{
"text": " [Parameter(Mandatory)] [System.IO.DirectoryInfo]$Directory,",
"lineNumber": 186
},
{
"text": " [Parameter(Mandatory)] [hashtable]$Map",
"lineNumber": 187
},
{
"text": " )",
"lineNumber": 188
},
{
"text": " if ($Directory.Name -like '_*') { return }",
"lineNumber": 189
},
{
"text": " $fullPath = $Directory.FullName",
"lineNumber": 190
},
{
"text": " if ($Map.ContainsKey($fullPath)) { return }",
"lineNumber": 191
},
{
"text": " ",
"lineNumber": 192
},
{
"text": " # Check if directory contains sequence files directly (not just subdirectories)",
"lineNumber": 193
},
{
"text": " $extensions = @('.png','.jpg','.jpeg','.exr','.tif','.tiff','.bmp','.tga')",
"lineNumber": 194
},
{
"text": " $hasSequenceFiles = Get-ChildItem -LiteralPath $fullPath -File -ErrorAction SilentlyContinue |",
"lineNumber": 195
},
{
"text": " Where-Object { $extensions -contains $_.Extension.ToLower() } |",
"lineNumber": 196
},
{
"text": " Select-Object -First 1",
"lineNumber": 197
},
{
"text": " ",
"lineNumber": 198
},
{
"text": " # If it only has subdirectories and no sequence files, skip it",
"lineNumber": 199
},
{
"text": " $hasSubdirs = Get-ChildItem -LiteralPath $fullPath -Directory -ErrorAction SilentlyContinue |",
"lineNumber": 200
},
{
"text": " Select-Object -First 1",
"lineNumber": 201
},
{
"text": " if ($null -eq $hasSequenceFiles -and $null -ne $hasSubdirs) {",
"lineNumber": 202
},
{
"text": " return",
"lineNumber": 203
},
{
"text": " }",
"lineNumber": 204
},
{
"text": " ",
"lineNumber": 205
},
{
"text": " $Map[$fullPath] = Resolve-SequenceName -Directory $Directory",
"lineNumber": 206
},
{
"text": "}",
"lineNumber": 207
},
{
"lineNumber": 208
},
{
"text": "try {",
"lineNumber": 209
},
{
"text": " $root = (Get-Location).ProviderPath",
"lineNumber": 210
},
{
"text": " $logFile = $null",
"lineNumber": 211
},
{
"lineNumber": 212
},
{
"text": " if ($DebugMode) {",
"lineNumber": 213
},
{
"text": " $logFile = Join-Path $root (\"UpdateSequences_{0}.log\" -f (Get-Date -Format 'yyyyMMdd_HHmmss'))",
"lineNumber": 214
},
{
"text": " \"[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] === UpdateSequences started in '$root' ===\" | Out-File -LiteralPath $logFile -Encoding UTF8",
"lineNumber": 215
},
{
"text": " }",
"lineNumber": 216
},
{
"lineNumber": 217
},
{
"text": " $sequenceMap = @{}",
"lineNumber": 218
},
{
"lineNumber": 219
},
{
"text": " $primaryPattern = if ($useIsoDailyFormat) { '????-??-??' } else { 'daily_*' }",
"lineNumber": 220
},
{
"text": " $secondaryPattern = if ($useIsoDailyFormat) { 'daily_*' } else { '????-??-??' }",
"lineNumber": 221
},
{
"lineNumber": 222
},
{
"text": " $primaryDirs = Get-ChildItem -LiteralPath $root -Directory -Filter $primaryPattern -ErrorAction SilentlyContinue |",
"lineNumber": 223
},
{
"text": " ",
"lineNumber": 224
}
]
},
"score": 0.263225793838501
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\replace_cel_with_bsdf.py",
"range": {
"startPosition": {
"line": 188
},
"endPosition": {
"line": 355
}
},
"contents": "def replace_cel_materials():\n\n \n # Build a mapping from base BSDF name to BSDF material (without suffix)\n bsdf_base_map = {bsdf_pattern.match(mat.name).group(1): mat for mat in materials if bsdf_pattern.match(mat.name)}\n \n # Build a mapping from exact material names to materials\n exact_material_map = {mat.name: mat for mat in materials}\n\n # Helpers to normalize names (case-insensitive, ignore numeric suffixes and library suffix)\n def normalize_base(name):\n base_name = name.split(\".blend\")[0] if \".blend\" in name else name\n match = re.match(r\"^(.*?)(\\.\\d{3})?$\", base_name)\n base_name = match.group(1) if match else base_name\n return base_name.strip().casefold()\n\n # Map normalized base name -&gt; list of materials\n materials_by_base = {}\n for mat in materials:\n base = normalize_base(mat.name)\n materials_by_base.setdefault(base, []).append(mat)\n\n # Normalize BSDF base name map for robust target lookups\n bsdf_base_map_normalized = {normalize_base(base): mat for base, mat in bsdf_base_map.items()}\n \n replacements_made = 0\n missing_targets = []\n \n # Process custom mappings first (case/suffix-insensitive)",
"signatures": {
"ranges": [
{
"startPosition": {
"line": 189,
"column": 1
},
"endPosition": {
"line": 190,
"column": 5
}
}
]
},
"detailedLines": [
{
"text": "def replace_cel_materials():",
"lineNumber": 189,
"isSignature": true
},
{
"lineNumber": 235
},
{
"text": " ",
"lineNumber": 236
},
{
"text": " # Build a mapping from base BSDF name to BSDF material (without suffix)",
"lineNumber": 237
},
{
"text": " bsdf_base_map = {bsdf_pattern.match(mat.name).group(1): mat for mat in materials if bsdf_pattern.match(mat.name)}",
"lineNumber": 238
},
{
"text": " ",
"lineNumber": 239
},
{
"text": " # Build a mapping from exact material names to materials",
"lineNumber": 240
},
{
"text": " exact_material_map = {mat.name: mat for mat in materials}",
"lineNumber": 241
},
{
"lineNumber": 242
},
{
"text": " # Helpers to normalize names (case-insensitive, ignore numeric suffixes and library suffix)",
"lineNumber": 243
},
{
"text": " def normalize_base(name):",
"lineNumber": 244
},
{
"text": " base_name = name.split(\".blend\")[0] if \".blend\" in name else name",
"lineNumber": 245
},
{
"text": " match = re.match(r\"^(.*?)(\\.\\d{3})?$\", base_name)",
"lineNumber": 246
},
{
"text": " base_name = match.group(1) if match else base_name",
"lineNumber": 247
},
{
"text": " return base_name.strip().casefold()",
"lineNumber": 248
},
{
"lineNumber": 249
},
{
"text": " # Map normalized base name -&gt; list of materials",
"lineNumber": 250
},
{
"text": " materials_by_base = {}",
"lineNumber": 251
},
{
"text": " for mat in materials:",
"lineNumber": 252
},
{
"text": " base = normalize_base(mat.name)",
"lineNumber": 253
},
{
"text": " materials_by_base.setdefault(base, []).append(mat)",
"lineNumber": 254
},
{
"lineNumber": 255
},
{
"text": " # Normalize BSDF base name map for robust target lookups",
"lineNumber": 256
},
{
"text": " bsdf_base_map_normalized = {normalize_base(base): mat for base, mat in bsdf_base_map.items()}",
"lineNumber": 257
},
{
"text": " ",
"lineNumber": 258
},
{
"text": " replacements_made = 0",
"lineNumber": 259
},
{
"text": " missing_targets = []",
"lineNumber": 260
},
{
"text": " ",
"lineNumber": 261
},
{
"text": " # Process custom mappings first (case/suffix-insensitive)",
"lineNumber": 262
}
]
},
"score": 0.2553691864013672
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\UpgradeToGitProj.bat",
"range": {
"startPosition": {},
"endPosition": {
"line": 61,
"column": 6
}
},
"contents": "@echo off\nsetlocal EnableExtensions EnableDelayedExpansion\n\n:: UpgradeToGitProj.bat\n:: Run this inside an existing (pre-git) project root.\n:: - Merges .gitignore and .gitattributes from components/ templates\n:: - Initializes git and installs Git LFS\n:: - Creates Renders, copies helper scripts\n:: - Collects seq/ outputs from daily_* folders under Blends\\animations (with submodule support)\n\n:: -----------------------------\n:: Arguments\n:: -----------------------------\nset \"DRY=0\"\nif /I \"%~1\"==\"/dry-run\" set \"DRY=1\"\nif /I \"%~1\"==\"--dry-run\" set \"DRY=1\"\nif /I \"%~1\"==\"-n\" set \"DRY=1\"\nif /I \"%~1\"==\"/n\" set \"DRY=1\"\n\nset \"projectDir=%CD%\"\nset \"scriptDir=%~dp0\"\nset \"RUN_ID=%RANDOM%_%RANDOM%\"\nset \"DELETE_LIST=%TEMP%\\upg_delete_%RUN_ID%.lst\"\n\nsetlocal EnableDelayedExpansion\nset /a debugTotal=0\nset /a debugPlanned=0\nset /a debugMissing=0\n\necho ==============================================\necho UpgradeToGitProj in \"%projectDir%\"\nif \"%DRY%\"==\"1\" (echo Mode: DRY-RUN) else (echo Mode: APPLY)\necho ==============================================\n\n:: -----------------------------\n:: Ensure Renders exists and copy helper scripts\n:: -----------------------------\nset \"rendersDir=%projectDir%\\Renders\"\nif not exist \"%rendersDir%\" (\n if \"%DRY%\"==\"1\" (\n echo [DRY] mkdir \"%rendersDir%\"\n ) else (\n mkdir \"%rendersDir%\" &gt;nul 2&gt;&amp;1\n )\n)\n\nfor %%F in (UpdateSequences.bat ZipSeqArchv.bat UnzipSeqArchv.bat) do (\n if exist \"%scriptDir%%%F\" (\n if \"%DRY%\"==\"1\" (\n echo [DRY] copy \"%scriptDir%%%F\" \"%rendersDir%\\%%F\"\n ) else (\n copy /Y \"%scriptDir%%%F\" \"%rendersDir%\\%%F\" &gt;nul\n )\n ) else (\n echo [WARN] Missing template: \"%scriptDir%%%F\"\n )\n)\n\nfor %%F in (ConfigLoader.ps1 config.json) do (\n if exist \"%scriptDir%%%F\" (\n if \"%DRY%\"==\"1\" (\n ",
"signatures": {},
"detailedLines": [
{
"text": "@echo off",
"lineNumber": 1
},
{
"text": "setlocal EnableExtensions EnableDelayedExpansion",
"lineNumber": 2
},
{
"lineNumber": 3
},
{
"text": ":: UpgradeToGitProj.bat",
"lineNumber": 4
},
{
"text": ":: Run this inside an existing (pre-git) project root.",
"lineNumber": 5
},
{
"text": ":: - Merges .gitignore and .gitattributes from components/ templates",
"lineNumber": 6
},
{
"text": ":: - Initializes git and installs Git LFS",
"lineNumber": 7
},
{
"text": ":: - Creates Renders, copies helper scripts",
"lineNumber": 8
},
{
"text": ":: - Collects seq/ outputs from daily_* folders under Blends\\animations (with submodule support)",
"lineNumber": 9
},
{
"lineNumber": 10
},
{
"text": ":: -----------------------------",
"lineNumber": 11
},
{
"text": ":: Arguments",
"lineNumber": 12
},
{
"text": ":: -----------------------------",
"lineNumber": 13
},
{
"text": "set \"DRY=0\"",
"lineNumber": 14
},
{
"text": "if /I \"%~1\"==\"/dry-run\" set \"DRY=1\"",
"lineNumber": 15
},
{
"text": "if /I \"%~1\"==\"--dry-run\" set \"DRY=1\"",
"lineNumber": 16
},
{
"text": "if /I \"%~1\"==\"-n\" set \"DRY=1\"",
"lineNumber": 17
},
{
"text": "if /I \"%~1\"==\"/n\" set \"DRY=1\"",
"lineNumber": 18
},
{
"lineNumber": 19
},
{
"text": "set \"projectDir=%CD%\"",
"lineNumber": 20
},
{
"text": "set \"scriptDir=%~dp0\"",
"lineNumber": 21
},
{
"text": "set \"RUN_ID=%RANDOM%_%RANDOM%\"",
"lineNumber": 22
},
{
"text": "set \"DELETE_LIST=%TEMP%\\upg_delete_%RUN_ID%.lst\"",
"lineNumber": 23
},
{
"lineNumber": 24
},
{
"text": "setlocal EnableDelayedExpansion",
"lineNumber": 25
},
{
"text": "set /a debugTotal=0",
"lineNumber": 26
},
{
"text": "set /a debugPlanned=0",
"lineNumber": 27
},
{
"text": "set /a debugMissing=0",
"lineNumber": 28
},
{
"lineNumber": 29
},
{
"text": "echo ==============================================",
"lineNumber": 30
},
{
"text": "echo UpgradeToGitProj in \"%projectDir%\"",
"lineNumber": 31
},
{
"text": "if \"%DRY%\"==\"1\" (echo Mode: DRY-RUN) else (echo Mode: APPLY)",
"lineNumber": 32
},
{
"text": "echo ==============================================",
"lineNumber": 33
},
{
"lineNumber": 34
},
{
"text": ":: -----------------------------",
"lineNumber": 35
},
{
"text": ":: Ensure Renders exists and copy helper scripts",
"lineNumber": 36
},
{
"text": ":: -----------------------------",
"lineNumber": 37
},
{
"text": "set \"rendersDir=%projectDir%\\Renders\"",
"lineNumber": 38
},
{
"text": "if not exist \"%rendersDir%\" (",
"lineNumber": 39
},
{
"text": " if \"%DRY%\"==\"1\" (",
"lineNumber": 40
},
{
"text": " echo [DRY] mkdir \"%rendersDir%\"",
"lineNumber": 41
},
{
"text": " ) else (",
"lineNumber": 42
},
{
"text": " mkdir \"%rendersDir%\" &gt;nul 2&gt;&amp;1",
"lineNumber": 43
},
{
"text": " )",
"lineNumber": 44
},
{
"text": ")",
"lineNumber": 45
},
{
"lineNumber": 46
},
{
"text": "for %%F in (UpdateSequences.bat ZipSeqArchv.bat UnzipSeqArchv.bat) do (",
"lineNumber": 47
},
{
"text": " if exist \"%scriptDir%%%F\" (",
"lineNumber": 48
},
{
"text": " if \"%DRY%\"==\"1\" (",
"lineNumber": 49
},
{
"text": " echo [DRY] copy \"%scriptDir%%%F\" \"%rendersDir%\\%%F\"",
"lineNumber": 50
},
{
"text": " ) else (",
"lineNumber": 51
},
{
"text": " copy /Y \"%scriptDir%%%F\" \"%rendersDir%\\%%F\" &gt;nul",
"lineNumber": 52
},
{
"text": " )",
"lineNumber": 53
},
{
"text": " ) else (",
"lineNumber": 54
},
{
"text": " echo [WARN] Missing template: \"%scriptDir%%%F\"",
"lineNumber": 55
},
{
"text": " )",
"lineNumber": 56
},
{
"text": ")",
"lineNumber": 57
},
{
"lineNumber": 58
},
{
"text": "for %%F in (ConfigLoader.ps1 config.json) do (",
"lineNumber": 59
},
{
"text": " if exist \"%scriptDir%%%F\" (",
"lineNumber": 60
},
{
"text": " if \"%DRY%\"==\"1\" (",
"lineNumber": 61
},
{
"text": " ",
"lineNumber": 62
}
]
},
"score": 0.25357121229171753
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\zip_sequences.py",
"range": {
"startPosition": {},
"endPosition": {
"line": 102
}
},
"contents": "#!/usr/bin/env python3\n\"\"\"Maintain zipped render sequences for Git hooks.\n\nDefault mode scans &#96;Renders/&#96;, produces ZIP archives under &#96;Renders/_zipped/&#96;,\nand stages any updated archives so commits only track compact files. Switch to\n&#96;--mode expand&#96; to inflate the tracked archives back into the ignored working\ndirectories after checkouts or pulls.\n\"\"\"\n\nfrom __future__ import annotations\n\nimport argparse\nimport json\nimport os\nimport platform\nimport shutil\nimport subprocess\nimport sys\nimport tempfile\nimport time\nimport traceback\nfrom concurrent.futures import ThreadPoolExecutor, as_completed\nfrom pathlib import Path\nfrom typing import Iterator, Sequence\n\n# Try to import psutil for cross-platform RAM detection\ntry:\n import psutil\n HAS_PSUTIL = True\nexcept ImportError:\n HAS_PSUTIL = False\n # For Windows fallback\n if platform.system() == \"Windows\":\n try:\n import ctypes\n HAS_CTYPES = True\n except ImportError:\n HAS_CTYPES = False\n else:\n HAS_CTYPES = False\n\n\nRENDER_ROOT = Path(\"Renders\")\nARCHIVE_ROOT = RENDER_ROOT / \"_zipped\"\nSEQUENCE_EXTENSIONS = {\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".tif\",\n \".tiff\",\n \".exr\",\n}\nSTATE_SUFFIX = \".meta.json\"\nDEFAULT_CONFIG = {\n \"zipper\": \"7z\",\n \"compression\": 9,\n \"compressionMethod\": \"LZMA2\", # Compression method: LZMA2 (multi-threaded), PPMd (single-threaded), BZip2, Deflate\n \"dailyFormat\": \"daily_YYMMDD\",\n \"Max7zInst\": 0, # Maximum concurrent 7z instances (0 = auto-calculate)\n}\n\n\ndef log(mode: str, message: str, *, verbose_only: bool = False, verbose: bool = False) -&gt; None:\n if verbose_only and not verbose:\n return\n print(f\"[{mode}] {message}\", flush=True)\n\n\ndef load_config() -&gt; dict:\n # First try to load from project's .config folder (current working directory)\n # Then fall back to ProjectStructure repo config (next to zip_sequences.py)\n ",
"signatures": {},
"detailedLines": [
{
"text": "#!/usr/bin/env python3",
"lineNumber": 1
},
{
"text": "\"\"\"Maintain zipped render sequences for Git hooks.",
"lineNumber": 2
},
{
"lineNumber": 3
},
{
"text": "Default mode scans &#96;Renders/&#96;, produces ZIP archives under &#96;Renders/_zipped/&#96;,",
"lineNumber": 4
},
{
"text": "and stages any updated archives so commits only track compact files. Switch to",
"lineNumber": 5
},
{
"text": "&#96;--mode expand&#96; to inflate the tracked archives back into the ignored working",
"lineNumber": 6
},
{
"text": "directories after checkouts or pulls.",
"lineNumber": 7
},
{
"text": "\"\"\"",
"lineNumber": 8
},
{
"lineNumber": 9
},
{
"text": "from __future__ import annotations",
"lineNumber": 10
},
{
"lineNumber": 11
},
{
"text": "import argparse",
"lineNumber": 12
},
{
"text": "import json",
"lineNumber": 13
},
{
"text": "import os",
"lineNumber": 14
},
{
"text": "import platform",
"lineNumber": 15
},
{
"text": "import shutil",
"lineNumber": 16
},
{
"text": "import subprocess",
"lineNumber": 17
},
{
"text": "import sys",
"lineNumber": 18
},
{
"text": "import tempfile",
"lineNumber": 19
},
{
"text": "import time",
"lineNumber": 20
},
{
"text": "import traceback",
"lineNumber": 21
},
{
"text": "from concurrent.futures import ThreadPoolExecutor, as_completed",
"lineNumber": 22
},
{
"text": "from pathlib import Path",
"lineNumber": 23
},
{
"text": "from typing import Iterator, Sequence",
"lineNumber": 24
},
{
"lineNumber": 25
},
{
"text": "# Try to import psutil for cross-platform RAM detection",
"lineNumber": 26
},
{
"text": "try:",
"lineNumber": 27
},
{
"text": " import psutil",
"lineNumber": 28
},
{
"text": " HAS_PSUTIL = True",
"lineNumber": 29
},
{
"text": "except ImportError:",
"lineNumber": 30
},
{
"text": " HAS_PSUTIL = False",
"lineNumber": 31
},
{
"text": " # For Windows fallback",
"lineNumber": 32
},
{
"text": " if platform.system() == \"Windows\":",
"lineNumber": 33
},
{
"text": " try:",
"lineNumber": 34
},
{
"text": " import ctypes",
"lineNumber": 35
},
{
"text": " HAS_CTYPES = True",
"lineNumber": 36
},
{
"text": " except ImportError:",
"lineNumber": 37
},
{
"text": " HAS_CTYPES = False",
"lineNumber": 38
},
{
"text": " else:",
"lineNumber": 39
},
{
"text": " HAS_CTYPES = False",
"lineNumber": 40
},
{
"lineNumber": 41
},
{
"lineNumber": 42
},
{
"text": "RENDER_ROOT = Path(\"Renders\")",
"lineNumber": 43
},
{
"text": "ARCHIVE_ROOT = RENDER_ROOT / \"_zipped\"",
"lineNumber": 44
},
{
"text": "SEQUENCE_EXTENSIONS = {",
"lineNumber": 45
},
{
"text": " \".png\",",
"lineNumber": 46
},
{
"text": " \".jpg\",",
"lineNumber": 47
},
{
"text": " \".jpeg\",",
"lineNumber": 48
},
{
"text": " \".tif\",",
"lineNumber": 49
},
{
"text": " \".tiff\",",
"lineNumber": 50
},
{
"text": " \".exr\",",
"lineNumber": 51
},
{
"text": "}",
"lineNumber": 52
},
{
"text": "STATE_SUFFIX = \".meta.json\"",
"lineNumber": 53
},
{
"text": "DEFAULT_CONFIG = {",
"lineNumber": 54
},
{
"text": " \"zipper\": \"7z\",",
"lineNumber": 55
},
{
"text": " \"compression\": 9,",
"lineNumber": 56
},
{
"text": " \"compressionMethod\": \"LZMA2\", # Compression method: LZMA2 (multi-threaded), PPMd (single-threaded), BZip2, Deflate",
"lineNumber": 57
},
{
"text": " \"dailyFormat\": \"daily_YYMMDD\",",
"lineNumber": 58
},
{
"text": " \"Max7zInst\": 0, # Maximum concurrent 7z instances (0 = auto-calculate)",
"lineNumber": 59
},
{
"text": "}",
"lineNumber": 60
},
{
"lineNumber": 61
},
{
"lineNumber": 62
},
{
"text": "def log(mode: str, message: str, *, verbose_only: bool = False, verbose: bool = False) -&gt; None:",
"lineNumber": 63,
"isSignature": true
},
{
"text": " if verbose_only and not verbose:",
"lineNumber": 64
},
{
"text": " return",
"lineNumber": 65
},
{
"text": " print(f\"[{mode}] {message}\", flush=True)",
"lineNumber": 66,
"isSignature": true
},
{
"lineNumber": 67
},
{
"lineNumber": 68
},
{
"text": "def load_config() -&gt; dict:",
"lineNumber": 69,
"isSignature": true
},
{
"text": " # First try to load from project's .config folder (current working directory)",
"lineNumber": 70,
"isSignature": true
},
{
"text": " # Then fall back to ProjectStructure repo config (next to zip_sequences.py)",
"lineNumber": 71,
"isSignature": true
},
{
"text": " ",
"lineNumber": 72
}
]
},
"score": 0.251534104347229
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\compress_blend_files.bat",
"range": {
"startPosition": {
"line": 64
},
"endPosition": {
"line": 118
}
},
"contents": "echo output_file = os.path.join^(\"output\", filename^)\necho # Check if output file already exists\necho if os.path.exists^(output_file^):\necho print^(\"SKIP_EXISTING:\" + blend_file^)\necho continue\necho # Skip if source is already compressed\necho if is_compressed_file^(blend_file^):\necho print^(\"SKIP_ALREADY_COMPRESSED:\" + blend_file^)\necho continue\necho print^(\"PROCESSING:\" + blend_file^)\necho # Load the blend file\necho bpy.ops.wm.open_mainfile^(filepath=blend_file^)\necho # Save with compression to output folder\necho bpy.ops.wm.save_mainfile^(filepath=output_file, compress=True^)\necho print^(\"SUCCESS:\" + blend_file + \":\" + output_file^)\necho except Exception as e:\necho print^(\"CRASH:\" + blend_file + \":\" + str^(e^)^)\necho else:\necho print^(\"SKIP_NOT_BLEND:\" + blend_file^)\necho.\necho print^(\"COMPRESSION_COMPLETE\"^)\necho bpy.ops.wm.quit_blender^(^)\n) &gt; \"!TEMP_SCRIPT!\"\n\nREM Check if script was created successfully\nif exist \"!TEMP_SCRIPT!\" (\n echo Script created successfully: !TEMP_SCRIPT!\n) else (\n echo ERROR: Failed to create script file!\n pause\n exit /b 1\n)\n\nREM Run Blender to process the dragged files\necho Processing dragged .blend files...\necho Using script: !TEMP_SCRIPT!\ndel /f /q \"blender_output.txt\" 2&gt;nul\nblender --background --factory-startup --python \"!TEMP_SCRIPT!\" -- %* 2^&gt;^&amp;1 | powershell -NoProfile -Command \"$input | Tee-Object -FilePath 'blender_output.txt'\"\n\nREM Clean up temporary script\necho Cleaning up temporary script...\ndel \"!TEMP_SCRIPT!\" 2&gt;nul\n\nREM Parse output and generate report\necho.\necho ========================================\necho COMPRESSION REPORT\necho ========================================\necho.\n\nREM Count processed files and get file info\nfor /f \"tokens=1,2,3 delims=:\" %%a in (blender_output.txt) do (\n if \"%%a\"==\"SUCCESS\" (\n set /a processed+=1",
"signatures": {},
"detailedLines": [
{
"text": "echo output_file = os.path.join^(\"output\", filename^)",
"lineNumber": 65
},
{
"text": "echo # Check if output file already exists",
"lineNumber": 66
},
{
"text": "echo if os.path.exists^(output_file^):",
"lineNumber": 67
},
{
"text": "echo print^(\"SKIP_EXISTING:\" + blend_file^)",
"lineNumber": 68
},
{
"text": "echo continue",
"lineNumber": 69
},
{
"text": "echo # Skip if source is already compressed",
"lineNumber": 70
},
{
"text": "echo if is_compressed_file^(blend_file^):",
"lineNumber": 71
},
{
"text": "echo print^(\"SKIP_ALREADY_COMPRESSED:\" + blend_file^)",
"lineNumber": 72
},
{
"text": "echo continue",
"lineNumber": 73
},
{
"text": "echo print^(\"PROCESSING:\" + blend_file^)",
"lineNumber": 74
},
{
"text": "echo # Load the blend file",
"lineNumber": 75
},
{
"text": "echo bpy.ops.wm.open_mainfile^(filepath=blend_file^)",
"lineNumber": 76
},
{
"text": "echo # Save with compression to output folder",
"lineNumber": 77
},
{
"text": "echo bpy.ops.wm.save_mainfile^(filepath=output_file, compress=True^)",
"lineNumber": 78
},
{
"text": "echo print^(\"SUCCESS:\" + blend_file + \":\" + output_file^)",
"lineNumber": 79
},
{
"text": "echo except Exception as e:",
"lineNumber": 80
},
{
"text": "echo print^(\"CRASH:\" + blend_file + \":\" + str^(e^)^)",
"lineNumber": 81
},
{
"text": "echo else:",
"lineNumber": 82
},
{
"text": "echo print^(\"SKIP_NOT_BLEND:\" + blend_file^)",
"lineNumber": 83
},
{
"text": "echo.",
"lineNumber": 84
},
{
"text": "echo print^(\"COMPRESSION_COMPLETE\"^)",
"lineNumber": 85
},
{
"text": "echo bpy.ops.wm.quit_blender^(^)",
"lineNumber": 86
},
{
"text": ") &gt; \"!TEMP_SCRIPT!\"",
"lineNumber": 87
},
{
"lineNumber": 88
},
{
"text": "REM Check if script was created successfully",
"lineNumber": 89
},
{
"text": "if exist \"!TEMP_SCRIPT!\" (",
"lineNumber": 90
},
{
"text": " echo Script created successfully: !TEMP_SCRIPT!",
"lineNumber": 91
},
{
"text": ") else (",
"lineNumber": 92
},
{
"text": " echo ERROR: Failed to create script file!",
"lineNumber": 93
},
{
"text": " pause",
"lineNumber": 94
},
{
"text": " exit /b 1",
"lineNumber": 95
},
{
"text": ")",
"lineNumber": 96
},
{
"lineNumber": 97
},
{
"text": "REM Run Blender to process the dragged files",
"lineNumber": 98
},
{
"text": "echo Processing dragged .blend files...",
"lineNumber": 99
},
{
"text": "echo Using script: !TEMP_SCRIPT!",
"lineNumber": 100
},
{
"text": "del /f /q \"blender_output.txt\" 2&gt;nul",
"lineNumber": 101
},
{
"text": "blender --background --factory-startup --python \"!TEMP_SCRIPT!\" -- %* 2^&gt;^&amp;1 | powershell -NoProfile -Command \"$input | Tee-Object -FilePath 'blender_output.txt'\"",
"lineNumber": 102
},
{
"lineNumber": 103
},
{
"text": "REM Clean up temporary script",
"lineNumber": 104
},
{
"text": "echo Cleaning up temporary script...",
"lineNumber": 105
},
{
"text": "del \"!TEMP_SCRIPT!\" 2&gt;nul",
"lineNumber": 106
},
{
"lineNumber": 107
},
{
"text": "REM Parse output and generate report",
"lineNumber": 108
},
{
"text": "echo.",
"lineNumber": 109
},
{
"text": "echo ========================================",
"lineNumber": 110
},
{
"text": "echo COMPRESSION REPORT",
"lineNumber": 111
},
{
"text": "echo ========================================",
"lineNumber": 112
},
{
"text": "echo.",
"lineNumber": 113
},
{
"lineNumber": 114
},
{
"text": "REM Count processed files and get file info",
"lineNumber": 115
},
{
"text": "for /f \"tokens=1,2,3 delims=:\" %%a in (blender_output.txt) do (",
"lineNumber": 116
},
{
"text": " if \"%%a\"==\"SUCCESS\" (",
"lineNumber": 117
},
{
"text": " set /a processed+=1",
"lineNumber": 118
}
]
},
"score": 0.24592049419879913
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\ConfigLoader.ps1",
"range": {
"startPosition": {
"line": 226
},
"endPosition": {
"line": 268
}
},
"contents": " exit 1\n }\n\n if (-not (Test-Path -LiteralPath $resolvedProject -PathType Container)) {\n Write-Error \"Project path is not a directory: $resolvedProject\"\n exit 1\n }\n\n Write-Host \"&#96;nDeploying to: $resolvedProject\" -ForegroundColor Cyan\n Write-Host \"Struct directory: $structDir\" -ForegroundColor Cyan\n\n $specs = @(\n @{ Name = 'UpdateSequences.bat'; Source = Join-Path -Path $structDir -ChildPath 'UpdateSequences.bat' },\n @{ Name = 'UpdateAllSequences.bat'; Source = Join-Path -Path $structDir -ChildPath 'UpdateAllSequences.bat' },\n @{ Name = 'ZipSeqArchv.bat'; Source = Join-Path -Path $structDir -ChildPath 'ZipSeqArchv.bat' },\n @{ Name = 'UnzipSeqArchv.bat'; Source = Join-Path -Path $structDir -ChildPath 'UnzipSeqArchv.bat' },\n @{ Name = 'NewDaily.bat'; Source = Join-Path -Path $structDir -ChildPath 'NewDaily.bat' },\n @{ Name = '.gitattributes'; Source = Join-Path -Path $structDir -ChildPath 'components\\gitattributes' },\n @{ Name = '.gitignore'; Source = Join-Path -Path $structDir -ChildPath 'components\\gitignore' }\n )\n\n # Config files to deploy to projectroot\\.config\\\n $configAssets = @(\n @{ Name = 'config.json'; Source = Join-Path -Path $structDir -ChildPath 'config.json' },\n @{ Name = 'GetStructDir.ps1'; Source = Join-Path -Path $structDir -ChildPath 'GetStructDir.ps1' }\n )\n\n foreach ($spec in $specs) {\n if (-not (Test-Path -LiteralPath $spec.Source -PathType Leaf)) {\n Write-Error \"Source file not found: $($spec.Source)\"\n exit 1\n }\n }\n\n foreach ($asset in $configAssets) {\n if (-not (Test-Path -LiteralPath $asset.Source -PathType Leaf)) {\n Write-Error \"Config asset not found: $($asset.Source)\"\n exit 1\n }\n }\n\n # Ensure .config directory exists in project root and is hidden",
"signatures": {},
"detailedLines": [
{
"text": " exit 1",
"lineNumber": 227
},
{
"text": " }",
"lineNumber": 228
},
{
"lineNumber": 229
},
{
"text": " if (-not (Test-Path -LiteralPath $resolvedProject -PathType Container)) {",
"lineNumber": 230
},
{
"text": " Write-Error \"Project path is not a directory: $resolvedProject\"",
"lineNumber": 231
},
{
"text": " exit 1",
"lineNumber": 232
},
{
"text": " }",
"lineNumber": 233
},
{
"lineNumber": 234
},
{
"text": " Write-Host \"&#96;nDeploying to: $resolvedProject\" -ForegroundColor Cyan",
"lineNumber": 235
},
{
"text": " Write-Host \"Struct directory: $structDir\" -ForegroundColor Cyan",
"lineNumber": 236
},
{
"lineNumber": 237
},
{
"text": " $specs = @(",
"lineNumber": 238
},
{
"text": " @{ Name = 'UpdateSequences.bat'; Source = Join-Path -Path $structDir -ChildPath 'UpdateSequences.bat' },",
"lineNumber": 239
},
{
"text": " @{ Name = 'UpdateAllSequences.bat'; Source = Join-Path -Path $structDir -ChildPath 'UpdateAllSequences.bat' },",
"lineNumber": 240
},
{
"text": " @{ Name = 'ZipSeqArchv.bat'; Source = Join-Path -Path $structDir -ChildPath 'ZipSeqArchv.bat' },",
"lineNumber": 241
},
{
"text": " @{ Name = 'UnzipSeqArchv.bat'; Source = Join-Path -Path $structDir -ChildPath 'UnzipSeqArchv.bat' },",
"lineNumber": 242
},
{
"text": " @{ Name = 'NewDaily.bat'; Source = Join-Path -Path $structDir -ChildPath 'NewDaily.bat' },",
"lineNumber": 243
},
{
"text": " @{ Name = '.gitattributes'; Source = Join-Path -Path $structDir -ChildPath 'components\\gitattributes' },",
"lineNumber": 244
},
{
"text": " @{ Name = '.gitignore'; Source = Join-Path -Path $structDir -ChildPath 'components\\gitignore' }",
"lineNumber": 245
},
{
"text": " )",
"lineNumber": 246
},
{
"lineNumber": 247
},
{
"text": " # Config files to deploy to projectroot\\.config\\",
"lineNumber": 248
},
{
"text": " $configAssets = @(",
"lineNumber": 249
},
{
"text": " @{ Name = 'config.json'; Source = Join-Path -Path $structDir -ChildPath 'config.json' },",
"lineNumber": 250
},
{
"text": " @{ Name = 'GetStructDir.ps1'; Source = Join-Path -Path $structDir -ChildPath 'GetStructDir.ps1' }",
"lineNumber": 251
},
{
"text": " )",
"lineNumber": 252
},
{
"lineNumber": 253
},
{
"text": " foreach ($spec in $specs) {",
"lineNumber": 254
},
{
"text": " if (-not (Test-Path -LiteralPath $spec.Source -PathType Leaf)) {",
"lineNumber": 255
},
{
"text": " Write-Error \"Source file not found: $($spec.Source)\"",
"lineNumber": 256
},
{
"text": " exit 1",
"lineNumber": 257
},
{
"text": " }",
"lineNumber": 258
},
{
"text": " }",
"lineNumber": 259
},
{
"lineNumber": 260
},
{
"text": " foreach ($asset in $configAssets) {",
"lineNumber": 261
},
{
"text": " if (-not (Test-Path -LiteralPath $asset.Source -PathType Leaf)) {",
"lineNumber": 262
},
{
"text": " Write-Error \"Config asset not found: $($asset.Source)\"",
"lineNumber": 263
},
{
"text": " exit 1",
"lineNumber": 264
},
{
"text": " }",
"lineNumber": 265
},
{
"text": " }",
"lineNumber": 266
},
{
"lineNumber": 267
},
{
"text": " # Ensure .config directory exists in project root and is hidden",
"lineNumber": 268
}
]
},
"score": 0.24059920012950897
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\UpdateSequences.ps1",
"range": {
"startPosition": {
"line": 221
},
"endPosition": {
"line": 266,
"column": 8
}
},
"contents": " $primaryDirs = Get-ChildItem -LiteralPath $root -Directory -Filter $primaryPattern -ErrorAction SilentlyContinue |\n Where-Object { $_.Name -notlike '_*' }\n foreach ($d in $primaryDirs) {\n $seqDirs = @(Get-ChildItem -LiteralPath $d.FullName -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -notlike '_*' })\n if ($seqDirs.Count -eq 0) {\n Add-SequenceFolder -Directory $d -Map $sequenceMap\n } else {\n foreach ($s in $seqDirs) {\n Add-SequenceFolder -Directory $s -Map $sequenceMap\n }\n }\n }\n\n $secondaryDirs = Get-ChildItem -LiteralPath $root -Directory -Filter $secondaryPattern -ErrorAction SilentlyContinue |\n Where-Object { $_.Name -notlike '_*' }\n foreach ($d in $secondaryDirs) {\n $seqDirs = @(Get-ChildItem -LiteralPath $d.FullName -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -notlike '_*' })\n if ($seqDirs.Count -eq 0) {\n Add-SequenceFolder -Directory $d -Map $sequenceMap\n } else {\n foreach ($s in $seqDirs) {\n Add-SequenceFolder -Directory $s -Map $sequenceMap\n }\n }\n }\n\n $directSeqs = Get-ChildItem -LiteralPath $root -Directory -ErrorAction SilentlyContinue |\n Where-Object {\n $_.Name -notlike '_*' -and\n $_.Name -notlike 'daily_*' -and\n $_.Name -notmatch '^\\d{4}-\\d{2}-\\d{2}$'\n }\n foreach ($seq in $directSeqs) {\n Add-SequenceFolder -Directory $seq -Map $sequenceMap\n }\n\n $sequenceFolders = $sequenceMap.GetEnumerator() | ForEach-Object {\n [pscustomobject]@{\n Path = $_.Key\n Name = $_.Value\n }\n } | Sort-Object -Property Path\n\n if (-not $sequenceFolders) {\n ",
"signatures": {},
"detailedLines": [
{
"text": " $primaryDirs = Get-ChildItem -LiteralPath $root -Directory -Filter $primaryPattern -ErrorAction SilentlyContinue |",
"lineNumber": 223
},
{
"text": " Where-Object { $_.Name -notlike '_*' }",
"lineNumber": 224
},
{
"text": " foreach ($d in $primaryDirs) {",
"lineNumber": 225
},
{
"text": " $seqDirs = @(Get-ChildItem -LiteralPath $d.FullName -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -notlike '_*' })",
"lineNumber": 226
},
{
"text": " if ($seqDirs.Count -eq 0) {",
"lineNumber": 227
},
{
"text": " Add-SequenceFolder -Directory $d -Map $sequenceMap",
"lineNumber": 228
},
{
"text": " } else {",
"lineNumber": 229
},
{
"text": " foreach ($s in $seqDirs) {",
"lineNumber": 230
},
{
"text": " Add-SequenceFolder -Directory $s -Map $sequenceMap",
"lineNumber": 231
},
{
"text": " }",
"lineNumber": 232
},
{
"text": " }",
"lineNumber": 233
},
{
"text": " }",
"lineNumber": 234
},
{
"lineNumber": 235
},
{
"text": " $secondaryDirs = Get-ChildItem -LiteralPath $root -Directory -Filter $secondaryPattern -ErrorAction SilentlyContinue |",
"lineNumber": 236
},
{
"text": " Where-Object { $_.Name -notlike '_*' }",
"lineNumber": 237
},
{
"text": " foreach ($d in $secondaryDirs) {",
"lineNumber": 238
},
{
"text": " $seqDirs = @(Get-ChildItem -LiteralPath $d.FullName -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -notlike '_*' })",
"lineNumber": 239
},
{
"text": " if ($seqDirs.Count -eq 0) {",
"lineNumber": 240
},
{
"text": " Add-SequenceFolder -Directory $d -Map $sequenceMap",
"lineNumber": 241
},
{
"text": " } else {",
"lineNumber": 242
},
{
"text": " foreach ($s in $seqDirs) {",
"lineNumber": 243
},
{
"text": " Add-SequenceFolder -Directory $s -Map $sequenceMap",
"lineNumber": 244
},
{
"text": " }",
"lineNumber": 245
},
{
"text": " }",
"lineNumber": 246
},
{
"text": " }",
"lineNumber": 247
},
{
"lineNumber": 248
},
{
"text": " $directSeqs = Get-ChildItem -LiteralPath $root -Directory -ErrorAction SilentlyContinue |",
"lineNumber": 249
},
{
"text": " Where-Object {",
"lineNumber": 250
},
{
"text": " $_.Name -notlike '_*' -and",
"lineNumber": 251
},
{
"text": " $_.Name -notlike 'daily_*' -and",
"lineNumber": 252
},
{
"text": " $_.Name -notmatch '^\\d{4}-\\d{2}-\\d{2}$'",
"lineNumber": 253
},
{
"text": " }",
"lineNumber": 254
},
{
"text": " foreach ($seq in $directSeqs) {",
"lineNumber": 255
},
{
"text": " Add-SequenceFolder -Directory $seq -Map $sequenceMap",
"lineNumber": 256
},
{
"text": " }",
"lineNumber": 257
},
{
"lineNumber": 258
},
{
"text": " $sequenceFolders = $sequenceMap.GetEnumerator() | ForEach-Object {",
"lineNumber": 259
},
{
"text": " [pscustomobject]@{",
"lineNumber": 260
},
{
"text": " Path = $_.Key",
"lineNumber": 261
},
{
"text": " Name = $_.Value",
"lineNumber": 262
},
{
"text": " }",
"lineNumber": 263
},
{
"text": " } | Sort-Object -Property Path",
"lineNumber": 264
},
{
"lineNumber": 265
},
{
"text": " if (-not $sequenceFolders) {",
"lineNumber": 266
},
{
"text": " ",
"lineNumber": 267
}
]
},
"score": 0.2402079999446869
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\zip_sequences.py",
"range": {
"startPosition": {
"line": 645,
"column": 42
},
"endPosition": {
"line": 661,
"column": 63
}
},
"contents": "def sequence_dir_for(zip_path: Path) -&gt; Path:\n rel = zip_path.relative_to(ARCHIVE_ROOT)\n # Remove the archive suffix (.7z or .zip) from the end\n # Handle both .7z and .zip extensions\n rel_str = str(rel)\n if rel_str.endswith(\".7z\"):\n rel_str = rel_str[:-3]\n elif rel_str.endswith(\".zip\"):\n rel_str = rel_str[:-4]\n return RENDER_ROOT / rel_str\n\n\ndef state_path_for(zip_path: Path) -&gt; Path:\n return zip_path.with_suffix(zip_path.suffix + STATE_SUFFIX)",
"signatures": {},
"detailedLines": [
{
"text": "def sequence_dir_for(zip_path: Path) -&gt; Path:",
"lineNumber": 649,
"isSignature": true
},
{
"text": " rel = zip_path.relative_to(ARCHIVE_ROOT)",
"lineNumber": 650
},
{
"text": " # Remove the archive suffix (.7z or .zip) from the end",
"lineNumber": 651
},
{
"text": " # Handle both .7z and .zip extensions",
"lineNumber": 652
},
{
"text": " rel_str = str(rel)",
"lineNumber": 653
},
{
"text": " if rel_str.endswith(\".7z\"):",
"lineNumber": 654
},
{
"text": " rel_str = rel_str[:-3]",
"lineNumber": 655
},
{
"text": " elif rel_str.endswith(\".zip\"):",
"lineNumber": 656
},
{
"text": " rel_str = rel_str[:-4]",
"lineNumber": 657
},
{
"text": " return RENDER_ROOT / rel_str",
"lineNumber": 658,
"isSignature": true
},
{
"lineNumber": 659
},
{
"lineNumber": 660
},
{
"text": "def state_path_for(zip_path: Path) -&gt; Path:",
"lineNumber": 661,
"isSignature": true
},
{
"text": " return zip_path.with_suffix(zip_path.suffix + STATE_SUFFIX)",
"lineNumber": 662,
"isSignature": true
}
]
},
"score": 0.23667949438095093
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\organize_textures.bat",
"range": {
"startPosition": {},
"endPosition": {
"line": 22,
"column": 12
}
},
"contents": "@echo off\nsetlocal EnableExtensions\n\nset \"script_dir=%~dp0\"\nset \"ps1_path=%script_dir%organize_textures.ps1\"\n\nif not exist \"%ps1_path%\" (\n echo [ERROR] organize_textures.ps1 not found at %ps1_path%\n exit /b 1\n)\n\necho Running texture organizer...\npwsh -NoProfile -ExecutionPolicy Bypass -File \"%ps1_path%\"\nset \"rc=%errorlevel%\"\n\nif %rc% neq 0 (\n echo.\n echo Script exited with error code %rc%\n)\n\necho.\npause\nexit /b %rc%",
"signatures": {},
"detailedLines": [
{
"text": "@echo off",
"lineNumber": 1
},
{
"text": "setlocal EnableExtensions",
"lineNumber": 2
},
{
"lineNumber": 3
},
{
"text": "set \"script_dir=%~dp0\"",
"lineNumber": 4
},
{
"text": "set \"ps1_path=%script_dir%organize_textures.ps1\"",
"lineNumber": 5
},
{
"lineNumber": 6
},
{
"text": "if not exist \"%ps1_path%\" (",
"lineNumber": 7
},
{
"text": " echo [ERROR] organize_textures.ps1 not found at %ps1_path%",
"lineNumber": 8
},
{
"text": " exit /b 1",
"lineNumber": 9
},
{
"text": ")",
"lineNumber": 10
},
{
"lineNumber": 11
},
{
"text": "echo Running texture organizer...",
"lineNumber": 12
},
{
"text": "pwsh -NoProfile -ExecutionPolicy Bypass -File \"%ps1_path%\"",
"lineNumber": 13
},
{
"text": "set \"rc=%errorlevel%\"",
"lineNumber": 14
},
{
"lineNumber": 15
},
{
"text": "if %rc% neq 0 (",
"lineNumber": 16
},
{
"text": " echo.",
"lineNumber": 17
},
{
"text": " echo Script exited with error code %rc%",
"lineNumber": 18
},
{
"text": ")",
"lineNumber": 19
},
{
"lineNumber": 20
},
{
"text": "echo.",
"lineNumber": 21
},
{
"text": "pause",
"lineNumber": 22
},
{
"text": "exit /b %rc%",
"lineNumber": 23
}
]
},
"score": 0.23035340011119843
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\UpdateProjectBatches.ps1",
"range": {
"startPosition": {
"line": 55
},
"endPosition": {
"line": 115
}
},
"contents": ")\n\n# Config files to deploy to projectroot\\.config\\\n$configAssets = @(\n @{ Name = 'config.json'; Source = Join-Path -Path $structDir -ChildPath 'config.json' },\n @{ Name = 'GetStructDir.ps1'; Source = Join-Path -Path $structDir -ChildPath 'GetStructDir.ps1' }\n)\n\nforeach ($spec in $specs) {\n if (-not (Test-Path -LiteralPath $spec.Source -PathType Leaf)) {\n Write-Error \"Source file not found: $($spec.Source)\"\n exit 1\n }\n}\n\nforeach ($asset in $configAssets) {\n if (-not (Test-Path -LiteralPath $asset.Source -PathType Leaf)) {\n Write-Error \"Config asset not found: $($asset.Source)\"\n exit 1\n }\n}\n\n# Ensure .config directory exists in project root\n$projectConfigDir = Join-Path -Path $resolvedProject -ChildPath '.config'\nif (-not (Test-Path -LiteralPath $projectConfigDir -PathType Container)) {\n New-Item -Path $projectConfigDir -ItemType Directory -Force | Out-Null\n Write-Host \"Created .config directory: $projectConfigDir\" -ForegroundColor Cyan\n}\n\n$touchedDirs = @{}\n$summary = @()\n\nforeach ($spec in $specs) {\n Write-Host \"&#96;n=== Updating $($spec.Name) ===\" -ForegroundColor Magenta\n\n $targets = Get-ChildItem -LiteralPath $resolvedProject -Recurse -Filter $spec.Name -File -ErrorAction SilentlyContinue\n $targets = $targets | Where-Object { $_.FullName -ne $spec.Source }\n\n if (-not $targets) {\n Write-Host \"No targets found.\" -ForegroundColor Yellow\n $summary += [pscustomobject]@{\n Name = $spec.Name\n Updated = 0\n Failed = 0\n Skipped = 0\n Total = 0\n }\n continue\n }\n\n $updated = 0\n $failed = 0\n\n foreach ($target in $targets) {\n try {\n Copy-Item -Path $spec.Source -Destination $target.FullName -Force\n Write-Host \"[OK] $($target.FullName)\" -ForegroundColor Green\n $updated++\n\n $targetDir = $target.Directory.FullName",
"signatures": {},
"detailedLines": [
{
"text": ")",
"lineNumber": 56
},
{
"lineNumber": 57
},
{
"text": "# Config files to deploy to projectroot\\.config\\",
"lineNumber": 58
},
{
"text": "$configAssets = @(",
"lineNumber": 59
},
{
"text": " @{ Name = 'config.json'; Source = Join-Path -Path $structDir -ChildPath 'config.json' },",
"lineNumber": 60
},
{
"text": " @{ Name = 'GetStructDir.ps1'; Source = Join-Path -Path $structDir -ChildPath 'GetStructDir.ps1' }",
"lineNumber": 61
},
{
"text": ")",
"lineNumber": 62
},
{
"lineNumber": 63
},
{
"text": "foreach ($spec in $specs) {",
"lineNumber": 64
},
{
"text": " if (-not (Test-Path -LiteralPath $spec.Source -PathType Leaf)) {",
"lineNumber": 65
},
{
"text": " Write-Error \"Source file not found: $($spec.Source)\"",
"lineNumber": 66
},
{
"text": " exit 1",
"lineNumber": 67
},
{
"text": " }",
"lineNumber": 68
},
{
"text": "}",
"lineNumber": 69
},
{
"lineNumber": 70
},
{
"text": "foreach ($asset in $configAssets) {",
"lineNumber": 71
},
{
"text": " if (-not (Test-Path -LiteralPath $asset.Source -PathType Leaf)) {",
"lineNumber": 72
},
{
"text": " Write-Error \"Config asset not found: $($asset.Source)\"",
"lineNumber": 73
},
{
"text": " exit 1",
"lineNumber": 74
},
{
"text": " }",
"lineNumber": 75
},
{
"text": "}",
"lineNumber": 76
},
{
"lineNumber": 77
},
{
"text": "# Ensure .config directory exists in project root",
"lineNumber": 78
},
{
"text": "$projectConfigDir = Join-Path -Path $resolvedProject -ChildPath '.config'",
"lineNumber": 79
},
{
"text": "if (-not (Test-Path -LiteralPath $projectConfigDir -PathType Container)) {",
"lineNumber": 80
},
{
"text": " New-Item -Path $projectConfigDir -ItemType Directory -Force | Out-Null",
"lineNumber": 81
},
{
"text": " Write-Host \"Created .config directory: $projectConfigDir\" -ForegroundColor Cyan",
"lineNumber": 82
},
{
"text": "}",
"lineNumber": 83
},
{
"lineNumber": 84
},
{
"text": "$touchedDirs = @{}",
"lineNumber": 85
},
{
"text": "$summary = @()",
"lineNumber": 86
},
{
"lineNumber": 87
},
{
"text": "foreach ($spec in $specs) {",
"lineNumber": 88
},
{
"text": " Write-Host \"&#96;n=== Updating $($spec.Name) ===\" -ForegroundColor Magenta",
"lineNumber": 89
},
{
"lineNumber": 90
},
{
"text": " $targets = Get-ChildItem -LiteralPath $resolvedProject -Recurse -Filter $spec.Name -File -ErrorAction SilentlyContinue",
"lineNumber": 91
},
{
"text": " $targets = $targets | Where-Object { $_.FullName -ne $spec.Source }",
"lineNumber": 92
},
{
"lineNumber": 93
},
{
"text": " if (-not $targets) {",
"lineNumber": 94
},
{
"text": " Write-Host \"No targets found.\" -ForegroundColor Yellow",
"lineNumber": 95
},
{
"text": " $summary += [pscustomobject]@{",
"lineNumber": 96
},
{
"text": " Name = $spec.Name",
"lineNumber": 97
},
{
"text": " Updated = 0",
"lineNumber": 98
},
{
"text": " Failed = 0",
"lineNumber": 99
},
{
"text": " Skipped = 0",
"lineNumber": 100
},
{
"text": " Total = 0",
"lineNumber": 101
},
{
"text": " }",
"lineNumber": 102
},
{
"text": " continue",
"lineNumber": 103
},
{
"text": " }",
"lineNumber": 104
},
{
"lineNumber": 105
},
{
"text": " $updated = 0",
"lineNumber": 106
},
{
"text": " $failed = 0",
"lineNumber": 107
},
{
"lineNumber": 108
},
{
"text": " foreach ($target in $targets) {",
"lineNumber": 109
},
{
"text": " try {",
"lineNumber": 110
},
{
"text": " Copy-Item -Path $spec.Source -Destination $target.FullName -Force",
"lineNumber": 111
},
{
"text": " Write-Host \"[OK] $($target.FullName)\" -ForegroundColor Green",
"lineNumber": 112
},
{
"text": " $updated++",
"lineNumber": 113
},
{
"lineNumber": 114
},
{
"text": " $targetDir = $target.Directory.FullName",
"lineNumber": 115
}
]
},
"score": 0.22555430233478546
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\remove_action_fake_users.bat",
"range": {
"startPosition": {},
"endPosition": {
"line": 66
}
},
"contents": "@echo off\nsetlocal enabledelayedexpansion\n\necho Starting fake user removal for actions...\n\nREM Check if files were dragged onto the batch file\nif \"%~1\"==\"\" (\n\techo.\n\techo Usage: Drag .blend files onto this batch file to remove fake users from actions.\n\techo Output will be saved to the \\output folder.\n\techo.\n\tpause\n\texit /b 1\n)\n\nREM Create output directory if it doesn't exist\nif not exist \"output\" mkdir \"output\"\n\nREM Initialize counters and tracking\nset \"processed=0\"\nset \"crashed=0\"\nset \"skipped=0\"\nset \"deleted_similar=0\"\nset \"threshold_percent=10\"\nset \"updated_total=0\"\n\nREM Create a temporary Python script for processing\nset \"TEMP_SCRIPT=remove_action_fake_users_temp.py\"\necho Creating Python script: !TEMP_SCRIPT!\n\n(\necho import bpy\necho import os\necho import sys\necho.\necho # Create output directory if it doesn't exist\necho if not os.path.exists^(\"output\"^):\necho \tos.makedirs^(\"output\"^)\necho.\necho # Get command line arguments ^(the dragged files^)\necho blend_files = sys.argv[sys.argv.index^(\"--\"^) + 1:] if \"--\" in sys.argv else []\necho.\necho print^(\"Found \" + str^(len^(blend_files^)^) + \" .blend files to process\"^)\necho.\necho for blend_file in blend_files:\necho ^\tif blend_file.lower^(^).endswith^(\".blend\"^):\necho ^\t\ttry:\necho ^\t\t\t# Create output path in output folder\necho ^\t\t\tfilename = os.path.basename^(blend_file^)\necho ^\t\t\toutput_file = os.path.join^(\"output\", filename^)\necho ^\t\t\t# Check if output file already exists\necho ^\t\t\tif os.path.exists^(output_file^):\necho ^\t\t\t\tprint^(\"SKIP_EXISTING:\" + blend_file^)\necho ^\t\t\t\tcontinue\necho ^\t\t\tprint^(\"PROCESSING:\" + blend_file^)\necho ^\t\t\t# Load the blend file\necho ^\t\t\tbpy.ops.wm.open_mainfile^(filepath=blend_file^)\necho ^\t\t\t# Remove fake users from all actions\necho ^\t\t\tchanged = 0\necho ^\t\t\tfor action in bpy.data.actions:\necho ^\t\t\t\tif getattr^(action, \"use_fake_user\", False^):\necho ^\t\t\t\t\taction.use_fake_user = False\necho ^\t\t\t\t\tchanged += 1\necho ^\t\t\tprint^(\"UPDATED:\" + blend_file + \":\" + str^(changed^)^)\necho ^\t\t\t# Save to output folder\necho ^\t\t\tbpy.ops.wm.save_mainfile^(filepath=output_file, compress=True^)",
"signatures": {},
"detailedLines": [
{
"text": "@echo off",
"lineNumber": 1
},
{
"text": "setlocal enabledelayedexpansion",
"lineNumber": 2
},
{
"lineNumber": 3
},
{
"text": "echo Starting fake user removal for actions...",
"lineNumber": 4
},
{
"lineNumber": 5
},
{
"text": "REM Check if files were dragged onto the batch file",
"lineNumber": 6
},
{
"text": "if \"%~1\"==\"\" (",
"lineNumber": 7
},
{
"text": "\techo.",
"lineNumber": 8
},
{
"text": "\techo Usage: Drag .blend files onto this batch file to remove fake users from actions.",
"lineNumber": 9
},
{
"text": "\techo Output will be saved to the \\output folder.",
"lineNumber": 10
},
{
"text": "\techo.",
"lineNumber": 11
},
{
"text": "\tpause",
"lineNumber": 12
},
{
"text": "\texit /b 1",
"lineNumber": 13
},
{
"text": ")",
"lineNumber": 14
},
{
"lineNumber": 15
},
{
"text": "REM Create output directory if it doesn't exist",
"lineNumber": 16
},
{
"text": "if not exist \"output\" mkdir \"output\"",
"lineNumber": 17
},
{
"lineNumber": 18
},
{
"text": "REM Initialize counters and tracking",
"lineNumber": 19
},
{
"text": "set \"processed=0\"",
"lineNumber": 20
},
{
"text": "set \"crashed=0\"",
"lineNumber": 21
},
{
"text": "set \"skipped=0\"",
"lineNumber": 22
},
{
"text": "set \"deleted_similar=0\"",
"lineNumber": 23
},
{
"text": "set \"threshold_percent=10\"",
"lineNumber": 24
},
{
"text": "set \"updated_total=0\"",
"lineNumber": 25
},
{
"lineNumber": 26
},
{
"text": "REM Create a temporary Python script for processing",
"lineNumber": 27
},
{
"text": "set \"TEMP_SCRIPT=remove_action_fake_users_temp.py\"",
"lineNumber": 28
},
{
"text": "echo Creating Python script: !TEMP_SCRIPT!",
"lineNumber": 29
},
{
"lineNumber": 30
},
{
"text": "(",
"lineNumber": 31
},
{
"text": "echo import bpy",
"lineNumber": 32
},
{
"text": "echo import os",
"lineNumber": 33
},
{
"text": "echo import sys",
"lineNumber": 34
},
{
"text": "echo.",
"lineNumber": 35
},
{
"text": "echo # Create output directory if it doesn't exist",
"lineNumber": 36
},
{
"text": "echo if not os.path.exists^(\"output\"^):",
"lineNumber": 37
},
{
"text": "echo \tos.makedirs^(\"output\"^)",
"lineNumber": 38
},
{
"text": "echo.",
"lineNumber": 39
},
{
"text": "echo # Get command line arguments ^(the dragged files^)",
"lineNumber": 40
},
{
"text": "echo blend_files = sys.argv[sys.argv.index^(\"--\"^) + 1:] if \"--\" in sys.argv else []",
"lineNumber": 41
},
{
"text": "echo.",
"lineNumber": 42
},
{
"text": "echo print^(\"Found \" + str^(len^(blend_files^)^) + \" .blend files to process\"^)",
"lineNumber": 43
},
{
"text": "echo.",
"lineNumber": 44
},
{
"text": "echo for blend_file in blend_files:",
"lineNumber": 45
},
{
"text": "echo ^\tif blend_file.lower^(^).endswith^(\".blend\"^):",
"lineNumber": 46
},
{
"text": "echo ^\t\ttry:",
"lineNumber": 47
},
{
"text": "echo ^\t\t\t# Create output path in output folder",
"lineNumber": 48
},
{
"text": "echo ^\t\t\tfilename = os.path.basename^(blend_file^)",
"lineNumber": 49
},
{
"text": "echo ^\t\t\toutput_file = os.path.join^(\"output\", filename^)",
"lineNumber": 50
},
{
"text": "echo ^\t\t\t# Check if output file already exists",
"lineNumber": 51
},
{
"text": "echo ^\t\t\tif os.path.exists^(output_file^):",
"lineNumber": 52
},
{
"text": "echo ^\t\t\t\tprint^(\"SKIP_EXISTING:\" + blend_file^)",
"lineNumber": 53
},
{
"text": "echo ^\t\t\t\tcontinue",
"lineNumber": 54
},
{
"text": "echo ^\t\t\tprint^(\"PROCESSING:\" + blend_file^)",
"lineNumber": 55
},
{
"text": "echo ^\t\t\t# Load the blend file",
"lineNumber": 56
},
{
"text": "echo ^\t\t\tbpy.ops.wm.open_mainfile^(filepath=blend_file^)",
"lineNumber": 57
},
{
"text": "echo ^\t\t\t# Remove fake users from all actions",
"lineNumber": 58
},
{
"text": "echo ^\t\t\tchanged = 0",
"lineNumber": 59
},
{
"text": "echo ^\t\t\tfor action in bpy.data.actions:",
"lineNumber": 60
},
{
"text": "echo ^\t\t\t\tif getattr^(action, \"use_fake_user\", False^):",
"lineNumber": 61
},
{
"text": "echo ^\t\t\t\t\taction.use_fake_user = False",
"lineNumber": 62
},
{
"text": "echo ^\t\t\t\t\tchanged += 1",
"lineNumber": 63
},
{
"text": "echo ^\t\t\tprint^(\"UPDATED:\" + blend_file + \":\" + str^(changed^)^)",
"lineNumber": 64
},
{
"text": "echo ^\t\t\t# Save to output folder",
"lineNumber": 65
},
{
"text": "echo ^\t\t\tbpy.ops.wm.save_mainfile^(filepath=output_file, compress=True^)",
"lineNumber": 66
}
]
},
"score": 0.2200496941804886
},
{
"codeBlock": {
"relativeWorkspacePath": ".\\ConfigLoader.ps1",
"range": {
"startPosition": {},
"endPosition": {
"line": 64
}
},
"contents": "Set-StrictMode -Version Latest\n$ErrorActionPreference = 'Stop'\n\n$script:LoaderRoot = Split-Path -Parent $MyInvocation.MyCommand.Path\n$script:ConfigPath = Join-Path -Path $script:LoaderRoot -ChildPath 'config.json'\n$script:ConfigCache = $null\n\nfunction Get-ProjectStructureConfig {\n if ($null -ne $script:ConfigCache) {\n return $script:ConfigCache\n }\n\n if (Test-Path -LiteralPath $script:ConfigPath) {\n try {\n $raw = Get-Content -LiteralPath $script:ConfigPath -Raw -ErrorAction Stop\n if ($raw.Trim().Length -gt 0) {\n $script:ConfigCache = $raw | ConvertFrom-Json\n return $script:ConfigCache\n }\n }\n catch {\n Write-Warning \"Failed to parse config.json: $($_.Exception.Message)\"\n }\n }\n\n $script:ConfigCache = [pscustomobject]@{}\n return $script:ConfigCache\n}\n\nfunction Get-ConfigValue {\n param(\n [Parameter(Mandatory)] [string]$Name,\n $Default = $null\n )\n\n $config = Get-ProjectStructureConfig\n if ($config.PSObject.Properties.Name -contains $Name) {\n $value = $config.$Name\n if ($null -ne $value -and ($value -isnot [string] -or $value.Trim().Length -gt 0)) {\n return $value\n }\n }\n\n return $Default\n}\n\nfunction Get-StructDirectory {\n # When script is run directly (not dot-sourced), always use script's directory for portability\n if ($MyInvocation.InvocationName -ne '.') {\n return $script:LoaderRoot\n }\n\n $value = Get-ConfigValue -Name 'structDir'\n if ($null -eq $value -or [string]::IsNullOrWhiteSpace($value)) {\n return $script:LoaderRoot\n }\n\n if ([System.IO.Path]::IsPathRooted($value)) {\n $resolved = Resolve-Path -LiteralPath $value -ErrorAction SilentlyContinue\n if ($null -ne $resolved) { return $resolved.Path }\n return $value\n }\n\n $candidate = Join-Path -Path $script:LoaderRoot -ChildPath $value",
"signatures": {},
"detailedLines": [
{
"text": "Set-StrictMode -Version Latest",
"lineNumber": 1
},
{
"text": "$ErrorActionPreference = 'Stop'",
"lineNumber": 2
},
{
"lineNumber": 3
},
{
"text": "$script:LoaderRoot = Split-Path -Parent $MyInvocation.MyCommand.Path",
"lineNumber": 4
},
{
"text": "$script:ConfigPath = Join-Path -Path $script:LoaderRoot -ChildPath 'config.json'",
"lineNumber": 5
},
{
"text": "$script:ConfigCache = $null",
"lineNumber": 6
},
{
"lineNumber": 7
},
{
"text": "function Get-ProjectStructureConfig {",
"lineNumber": 8
},
{
"text": " if ($null -ne $script:ConfigCache) {",
"lineNumber": 9
},
{
"text": " return $script:ConfigCache",
"lineNumber": 10
},
{
"text": " }",
"lineNumber": 11
},
{
"lineNumber": 12
},
{
"text": " if (Test-Path -LiteralPath $script:ConfigPath) {",
"lineNumber": 13
},
{
"text": " try {",
"lineNumber": 14
},
{
"text": " $raw = Get-Content -LiteralPath $script:ConfigPath -Raw -ErrorAction Stop",
"lineNumber": 15
},
{
"text": " if ($raw.Trim().Length -gt 0) {",
"lineNumber": 16
},
{
"text": " $script:ConfigCache = $raw | ConvertFrom-Json",
"lineNumber": 17
},
{
"text": " return $script:ConfigCache",
"lineNumber": 18
},
{
"text": " }",
"lineNumber": 19
},
{
"text": " }",
"lineNumber": 20
},
{
"text": " catch {",
"lineNumber": 21
},
{
"text": " Write-Warning \"Failed to parse config.json: $($_.Exception.Message)\"",
"lineNumber": 22
},
{
"text": " }",
"lineNumber": 23
},
{
"text": " }",
"lineNumber": 24
},
{
"lineNumber": 25
},
{
"text": " $script:ConfigCache = [pscustomobject]@{}",
"lineNumber": 26
},
{
"text": " return $script:ConfigCache",
"lineNumber": 27
},
{
"text": "}",
"lineNumber": 28
},
{
"lineNumber": 29
},
{
"text": "function Get-ConfigValue {",
"lineNumber": 30
},
{
"text": " param(",
"lineNumber": 31
},
{
"text": " [Parameter(Mandatory)] [string]$Name,",
"lineNumber": 32
},
{
"text": " $Default = $null",
"lineNumber": 33
},
{
"text": " )",
"lineNumber": 34
},
{
"lineNumber": 35
},
{
"text": " $config = Get-ProjectStructureConfig",
"lineNumber": 36
},
{
"text": " if ($config.PSObject.Properties.Name -contains $Name) {",
"lineNumber": 37
},
{
"text": " $value = $config.$Name",
"lineNumber": 38
},
{
"text": " if ($null -ne $value -and ($value -isnot [string] -or $value.Trim().Length -gt 0)) {",
"lineNumber": 39
},
{
"text": " return $value",
"lineNumber": 40
},
{
"text": " }",
"lineNumber": 41
},
{
"text": " }",
"lineNumber": 42
},
{
"lineNumber": 43
},
{
"text": " return $Default",
"lineNumber": 44
},
{
"text": "}",
"lineNumber": 45
},
{
"lineNumber": 46
},
{
"text": "function Get-StructDirectory {",
"lineNumber": 47
},
{
"text": " # When script is run directly (not dot-sourced), always use script's directory for portability",
"lineNumber": 48
},
{
"text": " if ($MyInvocation.InvocationName -ne '.') {",
"lineNumber": 49
},
{
"text": " return $script:LoaderRoot",
"lineNumber": 50
},
{
"text": " }",
"lineNumber": 51
},
{
"lineNumber": 52
},
{
"text": " $value = Get-ConfigValue -Name 'structDir'",
"lineNumber": 53
},
{
"text": " if ($null -eq $value -or [string]::IsNullOrWhiteSpace($value)) {",
"lineNumber": 54
},
{
"text": " return $script:LoaderRoot",
"lineNumber": 55
},
{
"text": " }",
"lineNumber": 56
},
{
"lineNumber": 57
},
{
"text": " if ([System.IO.Path]::IsPathRooted($value)) {",
"lineNumber": 58
},
{
"text": " $resolved = Resolve-Path -LiteralPath $value -ErrorAction SilentlyContinue",
"lineNumber": 59
},
{
"text": " if ($null -ne $resolved) { return $resolved.Path }",
"lineNumber": 60
},
{
"text": " return $value",
"lineNumber": 61
},
{
"text": " }",
"lineNumber": 62
},
{
"lineNumber": 63
},
{
"text": " $candidate = Join-Path -Path $script:LoaderRoot -ChildPath $value",
"lineNumber": 64
}
]
},
"score": 0.21668344736099243
}
]
}
```
Status: **completed**
</details>
</tool-use>
---
Creating a plan to update the script for two-level duplicate detection:
---
<tool-use data-tool-type="unknown" data-tool-name="create_plan">
<details>
<summary>Tool use: **create_plan**</summary>
Parameters:
```json
{
"plan": "# Two-Level Texture Organization Script\n\n## Current Behavior\nThe script currently processes all files recursively and moves everything to a single &#96;\\common&#96; folder at the texture root level.\n\n## New Requirements\nThe texture folder structure is: &#96;\\\\textures\\[Blendfile]\\[Material]&#96;\n\nThe script needs to:\n1. **Intra-blendfile commonalities**: Files that appear in multiple materials within the same blendfile → &#96;\\\\textures\\[blendfile]\\common&#96;\n2. **Inter-blendfile commonalities**: Files that appear across multiple blendfiles → &#96;\\\\textures\\common&#96;\n\n## Implementation Plan\n\n### File: &#96;organize_textures.ps1&#96;\n\n**Two-Pass Approach:**\n\n#### Pass 1: Intra-Blendfile Processing\n1. Get all direct subdirectories of the texture folder (these are blendfile folders)\n2. For each blendfile folder:\n - Get all files recursively within that blendfile folder (excluding &#96;\\common&#96; folders)\n - Calculate checksums for all files in that blendfile\n - Group files by checksum\n - For each checksum group:\n - If multiple files (duplicates within blendfile):\n - Move first file to &#96;[blendfile]\\common&#96;\n - Move remaining files to &#96;[blendfile]\\common\\duplicates&#96; with numbered suffixes\n - If single file: leave it in place (will be processed in Pass 2)\n\n#### Pass 2: Inter-Blendfile Processing\n1. After Pass 1 completes, get all remaining files (excluding all &#96;\\common&#96; folders)\n2. Calculate checksums for all remaining files\n3. Group files by checksum\n4. For each checksum group:\n - If multiple files (duplicates across blendfiles):\n - Move first file to &#96;\\textures\\common&#96;\n - Move remaining files to &#96;\\textures\\common\\duplicates&#96; with numbered suffixes\n - If single file: leave it in place (unique file)\n\n**Key Changes:**\n- Identify blendfile folders as direct subdirectories of the texture root\n- Process each blendfile folder independently in Pass 1\n- Exclude &#96;\\common&#96; folders from file collection in both passes\n- Create &#96;[blendfile]\\common&#96; and &#96;[blendfile]\\common\\duplicates&#96; directories as needed\n- Create &#96;\\textures\\common&#96; and &#96;\\textures\\common\\duplicates&#96; directories for Pass 2\n- Handle filename conflicts when moving files\n- Provide progress feedback for each blendfile and overall progress\n\n**Structure Detection:**\n- Assume texture folder structure: &#96;[textureRoot]\\[Blendfile]\\[Material]\\...&#96;\n- Blendfile folders are direct children of the texture root\n- Material folders are children of blendfile folders\n\n**Edge Cases:**\n- Handle blendfile folders that already have &#96;\\common&#96; subdirectories\n- Skip processing if a blendfile folder has no files\n- Handle files directly in blendfile folder (not in material subfolders)",
"name": "Two-level texture organization",
"todos": [
{
"content": "Add logic to identify blendfile folders as direct subdirectories of texture root",
"status": "pending",
"id": "identify_blendfile_folders"
},
{
"content": "Implement Pass 1: Process each blendfile folder separately, finding duplicates within each blendfile and moving to [blendfile]\\common",
"status": "pending",
"id": "pass1_intra_blendfile"
},
{
"content": "Implement Pass 2: Process remaining files across all blendfiles, finding duplicates across blendfiles and moving to \\textures\\common",
"status": "pending",
"id": "pass2_inter_blendfile"
},
{
"content": "Update file collection to exclude all \\common folders (both blendfile-level and root-level)",
"status": "pending",
"id": "update_exclusions"
},
{
"content": "Ensure proper directory creation for both [blendfile]\\common and \\textures\\common paths",
"status": "pending",
"id": "handle_directory_creation"
}
],
"overview": "Update organize_textures.ps1 to scan each blendfile folder separately, moving intra-blendfile duplicates to [blendfile]\\common and inter-blendfile duplicates to \\textures\\common"
}
```
Additional data:
```json
{
"reviewData": {
"status": "Requested",
"selectedOption": "none",
"isShowingInput": false
},
"planUri": "c:\\Users\\Nathan\\.cursor\\plans\\two-level_texture_organization_df41b675.plan.md",
"hasOpenedEditor": true
}
```
Result:
```json
{
"rejected": {}
}
```
Status: **completed**
</details>
</tool-use>
---
_**User**_
Implement the plan as specified, it is attached for your reference. Do NOT edit the plan file itself.
To-do's from the plan have already been created. Do not create them again. Mark them as in_progress as you work, starting with the first one. Don't stop until you have completed all the to-dos.
---
_**Agent (model default, mode Agent)**_
Implementing the plan. Reviewing the current script, then updating it for two-level duplicate detection.
---
<tool-use data-tool-type="unknown" data-tool-name="read_file_v2">
<details>
<summary>Tool use: **read_file_v2**</summary>
Status: **loading**
</details>
</tool-use>
---