3dsmax use folder and task entity

This commit is contained in:
Jakub Trllo 2024-03-04 16:11:10 +01:00
parent 3c880d5e66
commit e2494b6f23
5 changed files with 71 additions and 65 deletions

View file

@ -6,11 +6,12 @@ import json
from typing import Any, Dict, Union
import six
import ayon_api
from ayon_core.pipeline import get_current_project_name, colorspace
from ayon_core.settings import get_project_settings
from ayon_core.pipeline.context_tools import (
get_current_project_entity,
get_current_project_asset,
get_current_project_folder,
)
from ayon_core.style import load_stylesheet
from pymxs import runtime as rt
@ -217,49 +218,44 @@ def set_scene_resolution(width: int, height: int):
def reset_scene_resolution():
"""Apply the scene resolution from the project definition
scene resolution can be overwritten by an asset if the asset.data contains
any information regarding scene resolution .
Returns:
None
scene resolution can be overwritten by a folder if the folder.attrib
contains any information regarding scene resolution.
"""
fields = ["attrib.resolutionWidth", "attrib.resolutionHeight"]
project_entity = get_current_project_entity(fields=fields)
project_attribs = project_entity["attrib"]
asset_doc = get_current_project_asset(fields=fields)
asset_data = asset_doc["data"]
# Set project resolution
project_width = int(project_attribs.get("resolutionWidth", 1920))
project_height = int(project_attribs.get("resolutionHeight", 1080))
width = int(asset_data.get("resolutionWidth", project_width))
height = int(asset_data.get("resolutionHeight", project_height))
folder_entity = get_current_project_folder(
fields={"attrib.resolutionWidth", "attrib.resolutionHeight"}
)
folder_attributes = folder_entity["attrib"]
width = int(folder_attributes["resolutionWidth"])
height = int(folder_attributes["resolutionHeight"])
set_scene_resolution(width, height)
def get_frame_range(asset_doc=None) -> Union[Dict[str, Any], None]:
"""Get the current assets frame range and handles.
def get_frame_range(folder_entiy=None) -> Union[Dict[str, Any], None]:
"""Get the current folder frame range and handles.
Args:
asset_doc (dict): Asset Entity Data
folder_entiy (dict): Folder eneity.
Returns:
dict: with frame start, frame end, handle start, handle end.
"""
# Set frame start/end
if asset_doc is None:
asset_doc = get_current_project_asset()
if folder_entiy is None:
folder_entiy = get_current_project_folder()
data = asset_doc["data"]
frame_start = data.get("frameStart")
frame_end = data.get("frameEnd")
folder_attributes = folder_entiy["attrib"]
frame_start = folder_attributes.get("frameStart")
frame_end = folder_attributes.get("frameEnd")
if frame_start is None or frame_end is None:
return {}
frame_start = int(frame_start)
frame_end = int(frame_end)
handle_start = int(data.get("handleStart", 0))
handle_end = int(data.get("handleEnd", 0))
handle_start = int(folder_attributes.get("handleStart", 0))
handle_end = int(folder_attributes.get("handleEnd", 0))
frame_start_handle = frame_start - handle_start
frame_end_handle = frame_end + handle_end
@ -274,7 +270,7 @@ def get_frame_range(asset_doc=None) -> Union[Dict[str, Any], None]:
def reset_frame_range(fps: bool = True):
"""Set frame range to current asset.
"""Set frame range to current folder.
This is part of 3dsmax documentation:
animationRange: A System Global variable which lets you get and
@ -285,8 +281,9 @@ def reset_frame_range(fps: bool = True):
scene frame rate in frames-per-second.
"""
if fps:
data_fps = get_current_project(fields=["data.fps"])
fps_number = float(data_fps["data"]["fps"])
project_name = get_current_project_name()
project_entity = ayon_api.get_project(project_name)
fps_number = float(project_entity["attrib"].get("fps"))
rt.frameRate = fps_number
frame_range = get_frame_range()
@ -330,7 +327,7 @@ def convert_unit_scale():
def set_context_setting():
"""Apply the project settings from the project definition
Settings can be overwritten by an asset if the asset.data contains
Settings can be overwritten by an folder if the folder.attrib contains
any information regarding those settings.
Examples of settings:

View file

@ -3,7 +3,7 @@ from pymxs import runtime as rt
from ayon_core.lib import Logger
from ayon_core.settings import get_project_settings
from ayon_core.pipeline import get_current_project_name
from ayon_core.pipeline.context_tools import get_current_project_asset
from ayon_core.pipeline.context_tools import get_current_project_folder
from ayon_core.hosts.max.api.lib import (
set_render_frame_range,
@ -57,14 +57,14 @@ class RenderSettings(object):
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# hard-coded, should be customized in the setting
context = get_current_project_asset()
folder_attributes = get_current_project_folder()["attrib"]
# get project resolution
width = context["data"].get("resolutionWidth")
height = context["data"].get("resolutionHeight")
width = folder_attributes.get("resolutionWidth")
height = folder_attributes.get("resolutionHeight")
# Set Frame Range
frame_start = context["data"].get("frame_start")
frame_end = context["data"].get("frame_end")
frame_start = folder_attributes.get("frame_start")
frame_end = folder_attributes.get("frame_end")
set_render_frame_range(frame_start, frame_end)
# get the production render
renderer_class = get_current_renderer()

View file

@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
"""Creator plugin for creating workfiles."""
import ayon_api
from ayon_core.pipeline import CreatedInstance, AutoCreator
from ayon_core.client import get_asset_by_name, get_asset_name_identifier
from ayon_core.hosts.max.api import plugin
from ayon_core.hosts.max.api.lib import read, imprint
from pymxs import runtime as rt
@ -24,21 +25,26 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator):
if instance.creator_identifier == self.identifier
), None)
project_name = self.project_name
asset_name = self.create_context.get_current_folder_path()
folder_path = self.create_context.get_current_folder_path()
task_name = self.create_context.get_current_task_name()
host_name = self.create_context.host_name
if current_instance is None:
asset_doc = get_asset_by_name(project_name, asset_name)
folder_entity = ayon_api.get_folder_by_path(
project_name, folder_path
)
task_entity = ayon_api.get_task_by_name(
project_name, folder_entity["id"], task_name
)
product_name = self.get_product_name(
project_name,
asset_doc,
task_name,
folder_entity,
task_entity,
variant,
host_name,
)
data = {
"folderPath": asset_name,
"folderPath": folder_path,
"task": task_name,
"variant": variant
}
@ -46,8 +52,8 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator):
data.update(
self.get_dynamic_data(
project_name,
asset_doc,
task_name,
folder_entity,
task_entity,
variant,
host_name,
current_instance)
@ -61,21 +67,25 @@ class CreateWorkfile(plugin.MaxCreatorBase, AutoCreator):
self._add_instance_to_context(current_instance)
imprint(instance_node.name, current_instance.data)
elif (
current_instance["folderPath"] != asset_name
current_instance["folderPath"] != folder_path
or current_instance["task"] != task_name
):
# Update instance context if is not the same
asset_doc = get_asset_by_name(project_name, asset_name)
folder_entity = ayon_api.get_folder_by_path(
project_name, folder_path
)
task_entity = ayon_api.get_task_by_name(
project_name, folder_entity["id"], task_name
)
product_name = self.get_product_name(
project_name,
asset_doc,
task_name,
folder_entity,
task_entity,
variant,
host_name,
)
asset_name = get_asset_name_identifier(asset_doc)
current_instance["folderPath"] = asset_name
current_instance["folderPath"] = folder_entity["path"]
current_instance["task"] = task_name
current_instance["productName"] = product_name

View file

@ -18,11 +18,11 @@ class ValidateFrameRange(pyblish.api.InstancePlugin,
"""Validates the frame ranges.
This is an optional validator checking if the frame range on instance
matches the frame range specified for the asset.
matches the frame range specified for the folder.
It also validates render frame ranges of render layers.
Repair action will change everything to match the asset frame range.
Repair action will change everything to match the folder frame range.
This can be turned off by the artist to allow custom ranges.
"""
@ -42,7 +42,7 @@ class ValidateFrameRange(pyblish.api.InstancePlugin,
return
frame_range = get_frame_range(
asset_doc=instance.data["assetEntity"])
instance.data["folderEntity"])
inst_frame_start = instance.data.get("frameStartHandle")
inst_frame_end = instance.data.get("frameEndHandle")
@ -57,12 +57,12 @@ class ValidateFrameRange(pyblish.api.InstancePlugin,
if frame_start_handle != inst_frame_start:
errors.append(
f"Start frame ({inst_frame_start}) on instance does not match " # noqa
f"with the start frame ({frame_start_handle}) set on the asset data. ") # noqa
f"with the start frame ({frame_start_handle}) set on the folder attributes. ") # noqa
if frame_end_handle != inst_frame_end:
errors.append(
f"End frame ({inst_frame_end}) on instance does not match "
f"with the end frame ({frame_end_handle}) "
"from the asset data. ")
"from the folder attributes. ")
if errors:
bullet_point_errors = "\n".join(

View file

@ -24,7 +24,7 @@ class ValidateResolutionSetting(pyblish.api.InstancePlugin,
def process(self, instance):
if not self.is_active(instance.data):
return
width, height = self.get_db_resolution(instance)
width, height = self.get_folder_resolution(instance)
current_width = rt.renderWidth
current_height = rt.renderHeight
if current_width != width and current_height != height:
@ -41,16 +41,15 @@ class ValidateResolutionSetting(pyblish.api.InstancePlugin,
"not matching resolution set "
"on asset or shot.")
def get_db_resolution(self, instance):
asset_doc = instance.data["assetEntity"]
project_entity = instance.context.data["projectEntity"]
for data in [asset_doc["data"], project_entity["attrib"]]:
if "resolutionWidth" in data and "resolutionHeight" in data:
width = data["resolutionWidth"]
height = data["resolutionHeight"]
return int(width), int(height)
def get_folder_resolution(self, instance):
folder_entity = instance.data["folderEntity"]
if folder_entity:
folder_attributes = folder_entity["attrib"]
width = folder_attributes["resolutionWidth"]
height = folder_attributes["resolutionHeight"]
return int(width), int(height)
# Defaults if not found in asset document or project document
# Defaults if not found in folder entity
return 1920, 1080
@classmethod