Blender Kitsu: New Assset Tagging System #286
BIN
docs/media/pipeline-overview/shot-production/kitsu_asset_metadata.jpg
(Stored with Git LFS)
Normal file
BIN
docs/media/pipeline-overview/shot-production/kitsu_asset_metadata.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/media/pipeline-overview/shot-production/kitsu_asset_with_asset_pipeline.jpg
(Stored with Git LFS)
Normal file
BIN
docs/media/pipeline-overview/shot-production/kitsu_asset_with_asset_pipeline.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/media/pipeline-overview/shot-production/kitsu_set_asset.jpg
(Stored with Git LFS)
Normal file
BIN
docs/media/pipeline-overview/shot-production/kitsu_set_asset.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -7,29 +7,33 @@ The next step is to create an asset and store that information into the Kitsu Se
|
|||||||
3. Follow the [asset pipeline guide](https://studio.blender.org/pipeline/addons/asset_pipeline) to create a new asset collection, ensure these assets are marked as an [Asset in Blender](https://docs.blender.org/manual/en/latest/files/asset_libraries/introduction.html#creating-an-asset).
|
3. Follow the [asset pipeline guide](https://studio.blender.org/pipeline/addons/asset_pipeline) to create a new asset collection, ensure these assets are marked as an [Asset in Blender](https://docs.blender.org/manual/en/latest/files/asset_libraries/introduction.html#creating-an-asset).
|
||||||
4. Save the above asset within the directory `your_project_name/svn/pro/assets/char` (or similar depending on type)
|
4. Save the above asset within the directory `your_project_name/svn/pro/assets/char` (or similar depending on type)
|
||||||
|
|
||||||
|
## Kitsu Casting
|
||||||
|
Casting is the process of associating a Kitsu Asset Entity with a given shot, this is how the Shot Builder knows what Assets to link into a given shot.
|
||||||
|
1. Please follow the [Kitsu Breakdown](https://kitsu.cg-wire.com/getting-started-production/) guide to Cast your assets to shots.
|
||||||
|
|
||||||
|
|
||||||
## Load Asset Data into Kitsu
|
## Load Asset Data into Kitsu
|
||||||
To match Assets File to the data on the Kitsu server, we need to first enter the data into the Kitsu server and secondly create an Asset Index. This is a json file that contains the mapping of the asset's name to the asset's filepath. Any collection Marked as an Asset in Blender in the directory your_project/svn/pro/assets will be added to this index.
|
To match Assets File to the casting breakdown on the Kitsu server, we need to tag the Asset with a filepath and collection. This can be done via the Blender Kitsu Add-On. This data will be used to match a Kitsu Asset with a Collection within a .blend file, that will be linked into all shots that have that Asset "casted in it".
|
||||||
|
|
||||||
1. Create a matching entry in Kitsu for each asset via the [Kitsu Create Assets guide](https://kitsu.cg-wire.com/first_production/#create-assets)
|
1. Open the file for a given Asset.
|
||||||
2. Follow the [Kitsu Breakdown guide](https://kitsu.cg-wire.com/first_production/#create-a-breakdown-list) to assign/cast assets to shots.
|
2. Under the Kitsu>Context Panel, check the following settings.
|
||||||
3. Create a text [Metadata Column](https://kitsu.cg-wire.com/production_advanced/#create-custom-metadata-columns) with the exact name `slug`.
|
- **Type** is set to Asset.
|
||||||
4. Populate the new `slug` column with the exact name of the asset's collection.
|
- **Asset Type** is set to the correct Asset Type (Collection, Prop, etc)
|
||||||
5. Use the [Index Assets Script](https://projects.blender.org/studio/blender-studio-pipeline/src/branch/main/scripts/index_assets) to create an `asset_index.json` file.
|
- **Asset** Field is set to the matching entry on the Kitsu server for the current file.
|
||||||
|
3. Under the Kitsu>Context>Set Asset sub-panel...
|
||||||
|
- **Collecton** is set to the Asset's parent collection.
|
||||||
|
- Run the **Set Kitsu Asset** operator to send the current filepath and selected collection to the Kitsu Server.
|
||||||
|
|
||||||
**Example of `asset_index.json*`*
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"CH-rain": {
|
|
||||||
"type": "Collection",
|
|
||||||
"filepath": "your_project/svn/pro/assets/chars/rain/rain.blend"
|
|
||||||
},
|
|
||||||
"CH-snow": {
|
|
||||||
"type": "Collection",
|
|
||||||
"filepath": "your_project/svn/pro/assets/chars/snow/snow.blend"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
![Set Kitsu Asset](/media/pipeline-overview/shot-production/kitsu_set_asset.jpg)
|
||||||
|
|
||||||
|
If you are using the Asset Pipeline, the latest publish file will be prompted to confirm using the latest Publish as the Asset target.
|
||||||
|
|
||||||
|
![Publish Asset Pipeline with Set Kitsu Asset](/media/pipeline-overview/shot-production/kitsu_asset_with_asset_pipeline.jpg)
|
||||||
|
|
||||||
|
You should now see the filepath and collection under the Asset's Metadata on the Kitsu.
|
||||||
|
|
||||||
|
![Kitsu Asset Metadata](/media/pipeline-overview/shot-production/kitsu_asset_metadata.jpg)
|
||||||
## Building your First Shot
|
## Building your First Shot
|
||||||
Before building your first shot, you will need to customize your production's Shot Builder hooks. Inside your production’s `assets/scripts/shot-builder` directory the Shot Builder hook file should be stored, based on the [example](https://projects.blender.org/studio/blender-studio-pipeline/src/branch/main/scripts-blender/addons/blender_kitsu/shot_builder/hook_examples) included in the Add-On. This file can be automatically created at the correct directory using an operator in the **Blender Kitsu** Add-On preferences. Hooks are used to extend the functionality of the shot builder, and can be customized on a per project basis.
|
Before building your first shot, you will need to customize your production's Shot Builder hooks. Inside your production’s `assets/scripts/shot-builder` directory the Shot Builder hook file should be stored, based on the [example](https://projects.blender.org/studio/blender-studio-pipeline/src/branch/main/scripts-blender/addons/blender_kitsu/shot_builder/hook_examples) included in the Add-On. This file can be automatically created at the correct directory using an operator in the **Blender Kitsu** Add-On preferences. Hooks are used to extend the functionality of the shot builder, and can be customized on a per project basis.
|
||||||
|
|
||||||
|
@ -296,31 +296,21 @@ The Shot Builder requires shot data including Name, Frame Rate, and Duration to
|
|||||||
|
|
||||||
#### Asset Setup
|
#### Asset Setup
|
||||||
##### Kitsu Server
|
##### Kitsu Server
|
||||||
The Shot Builder requires all Asset to be stored on the Kitsu Server with a [Metadata Column](https://kitsu.cg-wire.com/production_advanced/#create-custom-metadata-columns) with the exact name `slug` exactly matching the name of the asset's collection.
|
|
||||||
|
|
||||||
Assets needs to be associated with each shot in your production. Please follow the [Kitsu Breakdown](https://kitsu.cg-wire.com/getting-started-production/) guide to Cast your assets to shots.
|
Assets needs to be associated with each shot in your production. Please follow the [Kitsu Breakdown](https://kitsu.cg-wire.com/getting-started-production/) guide to Cast your assets to shots.
|
||||||
|
|
||||||
##### Asset Index
|
##### Assets
|
||||||
To match Assets File to the casting breakdown on the Kitsu server, we need to create an Asset Index. This is a json file that contains the mapping of the asset's name to the asset's filepath. Any collection Marked as an Asset in Blender in the directory `your_project/svn/pro/assets` will be added to this index.
|
To match Assets File to the casting breakdown on the Kitsu server, we need to tag the Asset with a filepath and collection. This can be done via the Blender Kitsu Add-On. This data will be used to match a Kitsu Asset with a Collection within a .blend file, that will be linked into all shots that have that Asset "casted in it".
|
||||||
|
|
||||||
##### Example `asset_index.json`
|
1. Open the file for a given Asset.
|
||||||
```json
|
2. Under the Kitsu>Context Panel, check the following settings.
|
||||||
{
|
- **Type** is set to Asset.
|
||||||
"CH-rain": {
|
- **Asset Type** is set to the correct Asset Type (Collection, Prop, etc)
|
||||||
"type": "Collection",
|
- **Asset** Field is set to the matching entry on the Kitsu server for the current file.
|
||||||
"filepath": "your_project/svn/pro/assets/chars/rain/rain.blend"
|
3. Under the Kitsu>Context>Set Asset sub-panel...
|
||||||
},
|
- **Collecton** is set to the Asset's parent collection.
|
||||||
"CH-snow": {
|
- Run the **Set Kitsu Asset** operator to send the current filepath and selected collection to the Kitsu Server.
|
||||||
"type": "Collection",
|
|
||||||
"filepath": "your_project/svn/pro/assets/chars/snow/snow.blend"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
To create/update the Asset Index:
|
You should now see the filepath and collection under the Asset's Metadata on the Kitsu Server.
|
||||||
1. Enter Asset Index directory `cd blender-studio-pipeline/scripts/index_assets`
|
|
||||||
2. Run using `./run_index_assets.py your_poduction` replace `your_production` with the path to your project's root directory
|
|
||||||
3. This will create an index file at `your_production/svn/pro/assets/asset_index.py`
|
|
||||||
|
|
||||||
#### Hooks Setup
|
#### Hooks Setup
|
||||||
Shot Builder uses hooks to extend the functionality of the shot builder. To create a hook file
|
Shot Builder uses hooks to extend the functionality of the shot builder. To create a hook file
|
||||||
|
@ -87,8 +87,14 @@ MULTI_ASSETS = [
|
|||||||
|
|
||||||
ASSET_COLL_PREFIXES = ["CH-", "PR-", "SE-", "FX-"]
|
ASSET_COLL_PREFIXES = ["CH-", "PR-", "SE-", "FX-"]
|
||||||
|
|
||||||
|
|
||||||
|
# Kitsu Constants
|
||||||
KITSU_TV_PROJECT = 'tvshow'
|
KITSU_TV_PROJECT = 'tvshow'
|
||||||
|
|
||||||
|
# Kitsu Metadata Keys
|
||||||
|
KITSU_FILEPATH_KEY = "filepath"
|
||||||
|
KITSU_COLLECTION_KEY = "collection"
|
||||||
|
|
||||||
RES_DIR_PATH = Path(os.path.abspath(__file__)).parent.joinpath("res")
|
RES_DIR_PATH = Path(os.path.abspath(__file__)).parent.joinpath("res")
|
||||||
|
|
||||||
SCENE_NAME_PLAYBLAST = "playblast_playback"
|
SCENE_NAME_PLAYBLAST = "playblast_playback"
|
||||||
|
@ -26,6 +26,7 @@ import bpy
|
|||||||
from .. import bkglobals, cache, util, prefs
|
from .. import bkglobals, cache, util, prefs
|
||||||
from ..logger import LoggerFactory
|
from ..logger import LoggerFactory
|
||||||
from ..types import TaskType, AssetType
|
from ..types import TaskType, AssetType
|
||||||
|
from ..context import core as context_core
|
||||||
|
|
||||||
logger = LoggerFactory.getLogger()
|
logger = LoggerFactory.getLogger()
|
||||||
|
|
||||||
@ -240,11 +241,107 @@ class KITSU_OT_con_detect_context(bpy.types.Operator):
|
|||||||
return mapping[key]
|
return mapping[key]
|
||||||
|
|
||||||
|
|
||||||
|
class KITSU_OT_con_set_asset(bpy.types.Operator):
|
||||||
|
bl_idname = "kitsu.con_set_asset"
|
||||||
|
bl_label = "Set Kitsu Asset"
|
||||||
|
bl_description = (
|
||||||
|
"Mark the current file & target collection as an Asset on Kitsu Server "
|
||||||
|
"Assets marked with this method will be automatically loaded by the "
|
||||||
|
"Shot Builder, if the Asset is casted to the buider's target shot"
|
||||||
|
)
|
||||||
|
|
||||||
|
_published_file_path: Path = None
|
||||||
|
|
||||||
|
use_asset_pipeline_publish: bpy.props.BoolProperty( # type: ignore
|
||||||
|
name="Use Asset Pipeline Publish",
|
||||||
|
description=(
|
||||||
|
"Find the Publish of this file in the 'Publish' folder and use it's filepath for Kitsu Asset`"
|
||||||
|
"Selected Collection must be named exactly the same between current file and Publish"
|
||||||
|
),
|
||||||
|
default=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
kitsu_props = context.scene.kitsu
|
||||||
|
if bpy.data.filepath == "":
|
||||||
|
cls.poll_message_set("Blend file must be saved")
|
||||||
|
return False
|
||||||
|
if not bpy.data.filepath.startswith(str(prefs.project_root_dir_get(context))):
|
||||||
|
cls.poll_message_set("Blend file must be saved in project structure")
|
||||||
|
return False
|
||||||
|
if not context_core.is_asset_context():
|
||||||
|
cls.poll_message_set("Kitsu Context panel must be set to 'Asset'")
|
||||||
|
return False
|
||||||
|
if kitsu_props.asset_type_active_name == "":
|
||||||
|
cls.poll_message_set("Asset Type must be set")
|
||||||
|
return False
|
||||||
|
if kitsu_props.asset_active_name == "":
|
||||||
|
cls.poll_message_set("Asset must be set")
|
||||||
|
return False
|
||||||
|
if not kitsu_props.asset_col:
|
||||||
|
cls.poll_message_set("Asset Collection must be set")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def is_asset_pipeline_enabled(self, context) -> bool:
|
||||||
|
for addon in context.preferences.addons:
|
||||||
|
if addon.module == "asset_pipeline":
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def is_asset_pipeline_folder(self, context) -> bool:
|
||||||
|
current_folder = Path(bpy.data.filepath).parent
|
||||||
|
return current_folder.joinpath("task_layers.json").exists()
|
||||||
|
|
||||||
|
def get_asset_pipeline_publish(self, context) -> Path:
|
||||||
|
from asset_pipeline.merge.publish import find_latest_publish
|
||||||
|
|
||||||
|
return find_latest_publish(Path(bpy.data.filepath))
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
if self.is_asset_pipeline_enabled(context) and self.is_asset_pipeline_folder(context):
|
||||||
|
self._published_file_path = self.get_asset_pipeline_publish(context)
|
||||||
|
if self._published_file_path.exists():
|
||||||
|
self.use_asset_pipeline_publish = True
|
||||||
|
wm = context.window_manager
|
||||||
|
return wm.invoke_props_dialog(self)
|
||||||
|
return self.execute(context)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
relative_path = self._published_file_path.relative_to(Path(bpy.data.filepath).parent)
|
||||||
|
box = layout.box()
|
||||||
|
box.enabled = self.use_asset_pipeline_publish
|
||||||
|
box.label(text=f"//{str(relative_path)}")
|
||||||
|
layout.prop(self, "use_asset_pipeline_publish")
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
project_root = prefs.project_root_dir_get(context)
|
||||||
|
if self.use_asset_pipeline_publish:
|
||||||
|
relative_path = self._published_file_path.relative_to(project_root)
|
||||||
|
else:
|
||||||
|
relative_path = Path(bpy.data.filepath).relative_to(project_root)
|
||||||
|
blender_asset = context.scene.kitsu.asset_col
|
||||||
|
kitsu_asset = cache.asset_active_get()
|
||||||
|
if not kitsu_asset:
|
||||||
|
self.report({"ERROR"}, "Failed to find active Kitsu Asset")
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
kitsu_asset.set_asset_path(str(relative_path), blender_asset.name)
|
||||||
|
self.report(
|
||||||
|
{"INFO"},
|
||||||
|
f"Kitsu Asset '{kitsu_asset.name}' set to Collection '{blender_asset.name}' at path '{relative_path}'",
|
||||||
|
)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
# ---------REGISTER ----------.
|
# ---------REGISTER ----------.
|
||||||
|
|
||||||
classes = [
|
classes = [
|
||||||
KITSU_OT_con_productions_load,
|
KITSU_OT_con_productions_load,
|
||||||
KITSU_OT_con_detect_context,
|
KITSU_OT_con_detect_context,
|
||||||
|
KITSU_OT_con_set_asset,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,9 +22,7 @@ import bpy
|
|||||||
|
|
||||||
from ..context import core as context_core
|
from ..context import core as context_core
|
||||||
from .. import cache, prefs, ui, bkglobals
|
from .. import cache, prefs, ui, bkglobals
|
||||||
from ..context.ops import (
|
from ..context.ops import KITSU_OT_con_detect_context, KITSU_OT_con_set_asset
|
||||||
KITSU_OT_con_detect_context,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class KITSU_PT_vi3d_context(bpy.types.Panel):
|
class KITSU_PT_vi3d_context(bpy.types.Panel):
|
||||||
@ -113,6 +111,34 @@ class KITSU_PT_vi3d_context(bpy.types.Panel):
|
|||||||
context_core.draw_task_type_selector(context, col)
|
context_core.draw_task_type_selector(context, col)
|
||||||
|
|
||||||
|
|
||||||
|
class KITSU_PT_set_asset(bpy.types.Panel):
|
||||||
|
"""
|
||||||
|
Panel in 3dview that enables browsing through backend data structure.
|
||||||
|
Thought of as a menu to setup a context by selecting active production
|
||||||
|
active sequence, shot etc.
|
||||||
|
"""
|
||||||
|
|
||||||
|
bl_category = "Kitsu"
|
||||||
|
bl_label = "Set Asset"
|
||||||
|
bl_space_type = "VIEW_3D"
|
||||||
|
bl_region_type = "UI"
|
||||||
|
bl_options = {"DEFAULT_CLOSED"}
|
||||||
|
bl_order = 25
|
||||||
|
bl_parent_id = "KITSU_PT_vi3d_context"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return context_core.is_asset_context()
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.use_property_split = True
|
||||||
|
layout.use_property_decorate = False
|
||||||
|
col = layout.column()
|
||||||
|
col.prop(context.scene.kitsu, "asset_col")
|
||||||
|
col.operator(KITSU_OT_con_set_asset.bl_idname)
|
||||||
|
|
||||||
|
|
||||||
class KITSU_PT_comp_context(KITSU_PT_vi3d_context):
|
class KITSU_PT_comp_context(KITSU_PT_vi3d_context):
|
||||||
bl_space_type = "NODE_EDITOR"
|
bl_space_type = "NODE_EDITOR"
|
||||||
|
|
||||||
@ -124,7 +150,12 @@ class KITSU_PT_editorial_context(KITSU_PT_vi3d_context):
|
|||||||
# ---------REGISTER ----------.
|
# ---------REGISTER ----------.
|
||||||
|
|
||||||
# Classes that inherit from another need to be registered first for some reason.
|
# Classes that inherit from another need to be registered first for some reason.
|
||||||
classes = [KITSU_PT_comp_context, KITSU_PT_editorial_context, KITSU_PT_vi3d_context]
|
classes = [
|
||||||
|
KITSU_PT_comp_context,
|
||||||
|
KITSU_PT_editorial_context,
|
||||||
|
KITSU_PT_vi3d_context,
|
||||||
|
KITSU_PT_set_asset,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
@ -279,6 +279,8 @@ class KITSU_property_group_scene(bpy.types.PropertyGroup):
|
|||||||
NOTE: It would be nice to have searchable enums instead of doing all this work manually.
|
NOTE: It would be nice to have searchable enums instead of doing all this work manually.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
asset_col: bpy.props.PointerProperty(type=bpy.types.Collection, name="Collection")
|
||||||
|
|
||||||
###########
|
###########
|
||||||
# Sequence
|
# Sequence
|
||||||
###########
|
###########
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import bpy
|
import bpy
|
||||||
from .. import prefs
|
from .. import prefs, bkglobals
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import json
|
import json
|
||||||
from ..types import Shot
|
from ..types import Shot
|
||||||
@ -33,28 +33,32 @@ def get_shot_assets(
|
|||||||
asset_index = get_assset_index()
|
asset_index = get_assset_index()
|
||||||
if asset_index is None:
|
if asset_index is None:
|
||||||
return
|
return
|
||||||
assets = shot.get_all_assets()
|
kitsu_assets = shot.get_all_assets()
|
||||||
asset_slugs = [asset.data.get("slug") for asset in assets if asset.data.get("slug") is not None]
|
|
||||||
if asset_slugs == []:
|
for kitsu_asset in kitsu_assets:
|
||||||
print("No asset slugs found on Kitsu Server. Assets will not be loaded")
|
asset_path = kitsu_asset.data.get(bkglobals.KITSU_FILEPATH_KEY)
|
||||||
for key, value in asset_index.items():
|
collection_name = kitsu_asset.data.get(bkglobals.KITSU_COLLECTION_KEY)
|
||||||
if key in asset_slugs:
|
if not asset_path or not collection_name:
|
||||||
relative_path = value.get('filepath')
|
print(
|
||||||
asset_dir = get_asset_dir()
|
f"Asset '{kitsu_asset.name}' is missing filepath or collection metadata. Skipping"
|
||||||
filepath = Path(asset_dir).joinpath(relative_path).__str__()
|
)
|
||||||
data_type = value.get('type')
|
|
||||||
if config.ASSET_TYPE_TO_OVERRIDE.get(key.split('-')[0]):
|
|
||||||
if data_type != "Collection":
|
|
||||||
print(f"Cannot load {key} because it is not a collection")
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
filepath = prefs.project_root_dir_get(bpy.context).joinpath(asset_path).absolute()
|
||||||
|
if not filepath.exists():
|
||||||
|
print(f"Asset '{kitsu_asset.name}' filepath '{str(filepath)}' does not exist. Skipping")
|
||||||
|
|
||||||
|
if config.ASSET_TYPE_TO_OVERRIDE.get(collection_name.split('-')[0]):
|
||||||
linked_collection = core.link_and_override_collection(
|
linked_collection = core.link_and_override_collection(
|
||||||
collection_name=key, file_path=filepath, scene=scene
|
collection_name=collection_name, file_path=str(filepath), scene=scene
|
||||||
)
|
)
|
||||||
core.add_action_to_armature(linked_collection, shot)
|
core.add_action_to_armature(linked_collection, shot)
|
||||||
print(f"'{key}': Succesfully Linked & Overriden")
|
print(f"'{collection_name}': Succesfully Linked & Overriden")
|
||||||
else:
|
else:
|
||||||
linked_collection = core.link_data_block(
|
linked_collection = core.link_data_block(
|
||||||
file_path=filepath, data_block_name=key, data_block_type=data_type
|
file_path=str(filepath),
|
||||||
|
data_block_name=collection_name,
|
||||||
|
data_block_type="Collection",
|
||||||
)
|
)
|
||||||
print(f"'{key}': Succesfully Linked")
|
print(f"'{collection_name}': Succesfully Linked")
|
||||||
output_collection.children.link(linked_collection)
|
output_collection.children.link(linked_collection)
|
||||||
|
@ -735,6 +735,24 @@ class Asset(Entity):
|
|||||||
asset_dict = gazu.asset.get_asset(asset_id)
|
asset_dict = gazu.asset.get_asset(asset_id)
|
||||||
return cls.from_dict(asset_dict)
|
return cls.from_dict(asset_dict)
|
||||||
|
|
||||||
|
def set_asset_path(self, filepath: str, collection_name: str) -> None:
|
||||||
|
data = {}
|
||||||
|
filepath_key = bkglobals.KITSU_FILEPATH_KEY
|
||||||
|
collection_key = bkglobals.KITSU_COLLECTION_KEY
|
||||||
|
data[filepath_key] = filepath
|
||||||
|
data[collection_key] = collection_name
|
||||||
|
updated_asset = gazu.asset.update_asset_data(asdict(self), data)
|
||||||
|
self.data = updated_asset["data"]
|
||||||
|
|
||||||
|
if not gazu.project.get_metadata_descriptor_by_field_name(self.project_id, filepath_key):
|
||||||
|
gazu.project.add_metadata_descriptor(
|
||||||
|
self.project_id, filepath_key, "Asset", data_type='string'
|
||||||
|
)
|
||||||
|
if not gazu.project.get_metadata_descriptor_by_field_name(self.project_id, collection_key):
|
||||||
|
gazu.project.add_metadata_descriptor(
|
||||||
|
self.project_id, collection_key, "Asset", data_type='string'
|
||||||
|
)
|
||||||
|
|
||||||
def get_all_task_types(self) -> List[TaskType]:
|
def get_all_task_types(self) -> List[TaskType]:
|
||||||
return [TaskType.from_dict(t) for t in gazu.task.all_task_types_for_asset(asdict(self))]
|
return [TaskType.from_dict(t) for t in gazu.task.all_task_types_for_asset(asdict(self))]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user