Blender Kitsu: Refactor Shot Builder #183
10
scripts/index_assets/README.md
Normal file
10
scripts/index_assets/README.md
Normal file
@ -0,0 +1,10 @@
|
||||
# Index Assets
|
||||
|
||||
This tool will create a dictionary of all data-blocks (collections only) [marked as an Asset](https://docs.blender.org/manual/en/latest/files/asset_libraries/introduction.html#asset-create) and stores this information in a JSON file at `you_project/svn/pro/assets/asset_index.json`. This JSON File is used by other tools like the Blender Kitsu Add-On to quickly discover assets to use in the shot builder.
|
||||
|
||||
To run this tool use the following command, followed by the path to your project's root folder
|
||||
|
||||
```bash
|
||||
./run_index_assets.py your_project/
|
||||
```
|
||||
|
66
scripts/index_assets/blender_index_assets.py
Normal file
66
scripts/index_assets/blender_index_assets.py
Normal file
@ -0,0 +1,66 @@
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
from pathlib import Path
|
||||
import bpy
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
def load_json_file(json_file_path: str) -> dict:
|
||||
"""Finds JSON file with asset index if any exist
|
||||
|
||||
Args:
|
||||
json_file_path (str): Path to existing JSON File
|
||||
|
||||
Returns:
|
||||
dict: Dictionary with the existing JSON File, else blank
|
||||
"""
|
||||
asset_index_json = Path(json_file_path)
|
||||
if asset_index_json.exists():
|
||||
return json.load(open(asset_index_json))
|
||||
return {}
|
||||
|
||||
|
||||
def dump_json_file(asset_dict: dict, json_file_path: str) -> None:
|
||||
"""Save Asset Index to JSON File at provided path
|
||||
|
||||
Args:
|
||||
asset_dict (dict): Dictionary of Asset Items
|
||||
json_file_path (str): Path to Save JSON File
|
||||
"""
|
||||
with open(json_file_path, 'w') as json_file:
|
||||
json.dump(asset_dict, json_file, indent=4)
|
||||
|
||||
|
||||
def find_save_assets():
|
||||
"""Find all collections marked as asset in the current
|
||||
.blend file, and add them to a dictionary, saved as a JSON"""
|
||||
|
||||
argv = sys.argv
|
||||
json_file_path = argv[argv.index("--") + 1 :][0]
|
||||
|
||||
asset_dict = load_json_file(json_file_path)
|
||||
for col in bpy.data.collections:
|
||||
if col.asset_data:
|
||||
print(f"Found Asset {col.name}")
|
||||
asset_dict[col.name] = {
|
||||
'type': type(col).bl_rna.name,
|
||||
'filepath': bpy.data.filepath,
|
||||
}
|
||||
print('Asset Index Completed')
|
||||
dump_json_file(asset_dict, json_file_path)
|
||||
|
||||
|
||||
find_save_assets()
|
110
scripts/index_assets/run_index_assets.py
Executable file
110
scripts/index_assets/run_index_assets.py
Executable file
@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def cancel_program(message: str) -> None:
|
||||
"""Cancel Execution of this file"""
|
||||
print(message)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"path",
|
||||
help="Path to a file(s) or folder(s) on which to perform crawl. In format of '{my_project}/'",
|
||||
)
|
||||
|
||||
|
||||
def get_bbatch_script_path() -> str:
|
||||
"""Returns path to script that runs with bbatch"""
|
||||
dir = Path(__file__).parent.absolute()
|
||||
return dir.joinpath("blender_index_assets.py").__str__()
|
||||
|
||||
|
||||
def get_blender_path(project_path: Path) -> str:
|
||||
"""Get the path to a project's blender executable
|
||||
|
||||
Args:
|
||||
project_path (Path): Path Object, containing project's root path
|
||||
|
||||
Returns:
|
||||
str: Path to blender executable as a string
|
||||
"""
|
||||
# TODO get this from the run_blender.py script instead (new logic needs tobe added to run_blender.py first)
|
||||
local_blender_path = project_path.joinpath('local').joinpath('blender')
|
||||
system_name = platform.system().lower()
|
||||
blender_path_base = local_blender_path / system_name
|
||||
if system_name == 'linux':
|
||||
blender_path = blender_path_base / 'blender'
|
||||
elif system_name == 'darwin':
|
||||
blender_path = (
|
||||
blender_path_base / 'Blender.app' / 'Contents' / 'MacOS' / 'Blender'
|
||||
)
|
||||
elif system_name == 'windows':
|
||||
blender_path = blender_path_base / 'blender.exe'
|
||||
return blender_path.absolute().__str__()
|
||||
|
||||
|
||||
def index_assets():
|
||||
"""Crawl the Asset Library of a provided Blender Studio Pipeline Project and
|
||||
index all assets into a dictionary using a script executed by bbatch"""
|
||||
args = parser.parse_args()
|
||||
project_path = Path(args.path)
|
||||
if not project_path.exists():
|
||||
cancel_program("Provided Path does not exist")
|
||||
asset_dir = (
|
||||
project_path.joinpath("svn").joinpath("pro").joinpath("assets").absolute()
|
||||
)
|
||||
if not asset_dir.exists():
|
||||
cancel_program("Asset Library does not exist at provided path")
|
||||
asset_dir_path = asset_dir.__str__()
|
||||
json_file_path = asset_dir.joinpath("asset_index.json").__str__()
|
||||
script_path = get_bbatch_script_path()
|
||||
project_blender = get_blender_path(project_path)
|
||||
print(project_blender)
|
||||
os.chdir("../bbatch")
|
||||
cmd_list = (
|
||||
'python',
|
||||
'-m',
|
||||
'bbatch',
|
||||
asset_dir_path,
|
||||
'--ask',
|
||||
'--exec',
|
||||
project_blender,
|
||||
"--nosave",
|
||||
"--recursive",
|
||||
'--script',
|
||||
script_path,
|
||||
"--args",
|
||||
f'{json_file_path}',
|
||||
)
|
||||
process = subprocess.Popen(cmd_list, shell=False)
|
||||
if process.wait() != 0:
|
||||
cancel_program(f"Asset Index Failed!")
|
||||
print("Asset Index Completed Successfully")
|
||||
print(f"Index File: '{json_file_path}'")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
index_assets()
|
Loading…
Reference in New Issue
Block a user