Asset Pipeline: Add Support for Asset Catalogs #185
43
scripts-blender/addons/asset_pipeline/asset_catalog.py
Normal file
43
scripts-blender/addons/asset_pipeline/asset_catalog.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
asset_file_cache = None
|
||||||
|
cat_data_cache = None
|
||||||
|
|
||||||
|
|
||||||
|
# TODO add refresh operator
|
||||||
|
|
||||||
|
|
||||||
|
def find_asset_cat_file(directory):
|
||||||
|
global asset_file_cache
|
||||||
|
if asset_file_cache is not None:
|
||||||
|
return asset_file_cache
|
||||||
|
asset_file = os.path.join(directory, "blender_assets.cats.txt")
|
||||||
|
if os.path.exists(asset_file):
|
||||||
|
return asset_file
|
||||||
|
|
||||||
|
parent_dir = os.path.dirname(directory)
|
||||||
|
if parent_dir == directory:
|
||||||
|
raise FileNotFoundError("blender_assets.cats.txt not found")
|
||||||
|
|
||||||
|
return find_asset_cat_file(parent_dir)
|
||||||
|
|
||||||
|
|
||||||
|
def get_asset_cat_enum_items(reload: bool = False):
|
||||||
|
global cat_data_cache
|
||||||
|
if cat_data_cache is not None and not reload:
|
||||||
|
return cat_data_cache
|
||||||
|
items = []
|
||||||
|
items.append(('NONE', 'None', ''))
|
||||||
|
asset_cat_file = find_asset_cat_file(Path(bpy.data.filepath).parent.__str__())
|
||||||
|
with (Path(asset_cat_file)).open() as file:
|
||||||
|
for line in file.readlines():
|
||||||
|
if line.startswith(("#", "VERSION", "\n")):
|
||||||
|
continue
|
||||||
|
# Each line contains : 'uuid:catalog_tree:catalog_name' + eol ('\n')
|
||||||
|
name = line.split(':', 1)[1].split(":")[-1].strip("\n")
|
||||||
|
uuid = line.split(':', 1)[0]
|
||||||
|
|
||||||
|
items.append((uuid, name, ''))
|
||||||
|
return items
|
@ -49,8 +49,25 @@ def get_next_published_file(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_asset_catalogues():
|
||||||
|
folder = Path(bpy.data.filepath).parent
|
||||||
|
target_catalog = "Catalog"
|
||||||
|
|
||||||
|
with (folder / "blender_assets.cats.txt").open() as f:
|
||||||
|
for line in f.readlines():
|
||||||
|
if line.startswith(("#", "VERSION", "\n")):
|
||||||
|
continue
|
||||||
|
# Each line contains : 'uuid:catalog_tree:catalog_name' + eol ('\n')
|
||||||
|
name = line.split(":")[2].split("\n")[0]
|
||||||
|
if name == target_catalog:
|
||||||
|
uuid = line.split(":")[0]
|
||||||
|
obj = bpy.data.objects["Suzanne"] # Object name, case-sensitive !
|
||||||
|
asset_data = obj.asset_data
|
||||||
|
asset_data.catalog_id = uuid
|
||||||
|
|
||||||
|
|
||||||
def create_next_published_file(
|
def create_next_published_file(
|
||||||
current_file: Path, publish_type=constants.ACTIVE_PUBLISH_KEY
|
current_file: Path, publish_type=constants.ACTIVE_PUBLISH_KEY, catalog_id: str = ''
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Creates new Published version of a given Publish Type
|
"""Creates new Published version of a given Publish Type
|
||||||
|
|
||||||
@ -58,11 +75,16 @@ def create_next_published_file(
|
|||||||
current_file (Path): Current file, which must be a task file at root of asset directory
|
current_file (Path): Current file, which must be a task file at root of asset directory
|
||||||
publish_type (_type_, optional): Publish type, 'publish', 'staged', 'review'. Defaults to 'publish'.
|
publish_type (_type_, optional): Publish type, 'publish', 'staged', 'review'. Defaults to 'publish'.
|
||||||
"""
|
"""
|
||||||
|
# TODO Set Catalogue here
|
||||||
|
|
||||||
new_file_path = get_next_published_file(current_file, publish_type)
|
new_file_path = get_next_published_file(current_file, publish_type)
|
||||||
|
asset_col = bpy.context.scene.asset_pipeline.asset_collection
|
||||||
if publish_type == constants.ACTIVE_PUBLISH_KEY:
|
if publish_type == constants.ACTIVE_PUBLISH_KEY:
|
||||||
bpy.context.scene.asset_pipeline.asset_collection.asset_mark()
|
asset_col.asset_mark()
|
||||||
|
if catalog_id != '' or catalog_id != 'NONE':
|
||||||
|
asset_col.asset_data.catalog_id = catalog_id
|
||||||
bpy.ops.wm.save_as_mainfile(filepath=new_file_path.__str__(), copy=True)
|
bpy.ops.wm.save_as_mainfile(filepath=new_file_path.__str__(), copy=True)
|
||||||
bpy.context.scene.asset_pipeline.asset_collection.asset_clear()
|
asset_col.asset_clear()
|
||||||
|
|
||||||
|
|
||||||
def find_all_published(current_file: Path, publish_type: str) -> list[Path]:
|
def find_all_published(current_file: Path, publish_type: str) -> list[Path]:
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
from typing import Set
|
||||||
import bpy
|
import bpy
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from . import constants
|
from . import constants
|
||||||
from . import config
|
from . import config
|
||||||
from .prefs import get_addon_prefs
|
from .prefs import get_addon_prefs
|
||||||
@ -25,6 +27,8 @@ from .sync import (
|
|||||||
sync_execute_push,
|
sync_execute_push,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from .asset_catalog import get_asset_cat_enum_items
|
||||||
|
|
||||||
|
|
||||||
class ASSETPIPE_OT_create_new_asset(bpy.types.Operator):
|
class ASSETPIPE_OT_create_new_asset(bpy.types.Operator):
|
||||||
bl_idname = "assetpipe.create_new_asset"
|
bl_idname = "assetpipe.create_new_asset"
|
||||||
@ -425,8 +429,12 @@ class ASSETPIPE_OT_publish_new_version(bpy.types.Operator):
|
|||||||
f"Only '{constants.REVIEW_PUBLISH_KEY}' Publish is supported when a version is staged",
|
f"Only '{constants.REVIEW_PUBLISH_KEY}' Publish is supported when a version is staged",
|
||||||
)
|
)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
catalog_id = context.scene.asset_pipeline.asset_catalog_id
|
||||||
create_next_published_file(Path(bpy.data.filepath), self.publish_types)
|
create_next_published_file(
|
||||||
|
current_file=Path(bpy.data.filepath),
|
||||||
|
publish_type=self.publish_types,
|
||||||
|
catalog_id=catalog_id,
|
||||||
|
)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
@ -465,7 +473,8 @@ class ASSETPIPE_OT_publish_staged_as_active(bpy.types.Operator):
|
|||||||
)
|
)
|
||||||
# Delete Staged File
|
# Delete Staged File
|
||||||
staged_file.unlink()
|
staged_file.unlink()
|
||||||
create_next_published_file(current_file)
|
catalog_id = context.scene.asset_pipeline.asset_catalog_id
|
||||||
|
create_next_published_file(current_file=current_file, catalog_id=catalog_id)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
@ -861,7 +870,6 @@ class ASSETPIPE_OT_batch_ownership_change(bpy.types.Operator):
|
|||||||
layout.row(align=True).prop(self, "data_source", expand=True)
|
layout.row(align=True).prop(self, "data_source", expand=True)
|
||||||
|
|
||||||
layout.prop(self, "data_type", expand=True)
|
layout.prop(self, "data_type", expand=True)
|
||||||
|
|
||||||
filter_owner_row = layout.row()
|
filter_owner_row = layout.row()
|
||||||
filter_owner_row.enabled = grey_out
|
filter_owner_row.enabled = grey_out
|
||||||
if advanced_mode:
|
if advanced_mode:
|
||||||
@ -940,6 +948,17 @@ class ASSETPIPE_OT_batch_ownership_change(bpy.types.Operator):
|
|||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
class ASSETPIPE_OT_refresh_asset_cat(bpy.types.Operator):
|
||||||
|
bl_idname = "assetpipe.refresh_asset_cat"
|
||||||
|
bl_label = "Refresh Asset Catalogs"
|
||||||
|
bl_description = """Refresh Asset Catalogs"""
|
||||||
|
|
||||||
|
def execute(self, context: bpy.types.Context):
|
||||||
|
get_asset_cat_enum_items()
|
||||||
|
self.report({'INFO'}, "Asset Catalogs Refreshed!")
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
ASSETPIPE_OT_update_ownership,
|
ASSETPIPE_OT_update_ownership,
|
||||||
ASSETPIPE_OT_sync_push,
|
ASSETPIPE_OT_sync_push,
|
||||||
@ -954,6 +973,7 @@ classes = (
|
|||||||
ASSETPIPE_OT_update_surrendered_object,
|
ASSETPIPE_OT_update_surrendered_object,
|
||||||
ASSETPIPE_OT_update_surrendered_transfer_data,
|
ASSETPIPE_OT_update_surrendered_transfer_data,
|
||||||
ASSETPIPE_OT_batch_ownership_change,
|
ASSETPIPE_OT_batch_ownership_change,
|
||||||
|
ASSETPIPE_OT_refresh_asset_cat,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import bpy
|
import bpy
|
||||||
|
import os
|
||||||
from typing import List
|
from typing import List
|
||||||
from . import constants
|
from . import constants
|
||||||
from .config import get_task_layer_presets_path
|
from .config import get_task_layer_presets_path
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from .prefs import get_addon_prefs
|
from .prefs import get_addon_prefs
|
||||||
|
from .asset_catalog import get_asset_cat_enum_items
|
||||||
|
|
||||||
""" NOTE Items in these properties groups should be generated by a function that finds the
|
""" NOTE Items in these properties groups should be generated by a function that finds the
|
||||||
avaliable task layers from the task_layer.json file that needs to be created.
|
avaliable task layers from the task_layer.json file that needs to be created.
|
||||||
@ -144,6 +146,15 @@ class AssetPipeline(bpy.types.PropertyGroup):
|
|||||||
)
|
)
|
||||||
file_parent_ui_bool: bpy.props.BoolProperty(name="Show/Hide Parent", default=False)
|
file_parent_ui_bool: bpy.props.BoolProperty(name="Show/Hide Parent", default=False)
|
||||||
|
|
||||||
|
def get_asset_catalogs(self, context):
|
||||||
|
return get_asset_cat_enum_items()
|
||||||
|
|
||||||
|
asset_catalog_id: bpy.props.EnumProperty(
|
||||||
|
name="Catalog",
|
||||||
|
items=get_asset_catalogs,
|
||||||
|
description="Select Asset Library Catalog for the current Asset, this value will be updated each time you Push to an 'Active' Publish",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
AssetTransferData,
|
AssetTransferData,
|
||||||
|
@ -151,8 +151,11 @@ def sync_execute_pull(self, context):
|
|||||||
|
|
||||||
|
|
||||||
def sync_execute_push(self, context):
|
def sync_execute_push(self, context):
|
||||||
|
_catalog_id = None
|
||||||
temp_file_path = create_temp_file_backup(self, context)
|
temp_file_path = create_temp_file_backup(self, context)
|
||||||
|
|
||||||
|
_catalog_id = context.scene.asset_pipeline.asset_catalog_id
|
||||||
|
|
||||||
file_path = self._sync_target.__str__()
|
file_path = self._sync_target.__str__()
|
||||||
bpy.ops.wm.open_mainfile(filepath=file_path)
|
bpy.ops.wm.open_mainfile(filepath=file_path)
|
||||||
|
|
||||||
@ -174,5 +177,10 @@ def sync_execute_push(self, context):
|
|||||||
self.report({'ERROR'}, error_msg)
|
self.report({'ERROR'}, error_msg)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
asset_pipe = context.scene.asset_pipeline
|
||||||
|
asset_col = asset_pipe.asset_collection
|
||||||
|
if _catalog_id != '' or _catalog_id != 'NONE':
|
||||||
|
asset_col.asset_data.catalog_id = _catalog_id
|
||||||
|
|
||||||
bpy.ops.wm.save_as_mainfile(filepath=file_path)
|
bpy.ops.wm.save_as_mainfile(filepath=file_path)
|
||||||
bpy.ops.wm.open_mainfile(filepath=self._current_file.__str__())
|
bpy.ops.wm.open_mainfile(filepath=self._current_file.__str__())
|
||||||
|
@ -89,6 +89,9 @@ class ASSETPIPE_PT_sync_tools(bpy.types.Panel):
|
|||||||
|
|
||||||
def draw(self, context: bpy.types.Context) -> None:
|
def draw(self, context: bpy.types.Context) -> None:
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
cat_row = layout.row(align=True)
|
||||||
|
cat_row.prop(context.scene.asset_pipeline, 'asset_catalog_id')
|
||||||
|
cat_row.operator("assetpipe.refresh_asset_cat", icon='FILE_REFRESH', text="")
|
||||||
layout.operator("assetpipe.batch_ownership_change")
|
layout.operator("assetpipe.batch_ownership_change")
|
||||||
layout.operator("assetpipe.revert_file", icon="FILE_TICK")
|
layout.operator("assetpipe.revert_file", icon="FILE_TICK")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user