Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loader support add to shot inventory #62

Open
wants to merge 25 commits into
base: production-2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
791c724
Add get_publish_path function, can get publish path without using rep…
jackyjacky1307 Jun 22, 2022
c45b772
Avalon support episode and sequence
jackyjacky1307 Aug 11, 2022
f87e52b
Avalon episode and sequence env setup
jackyjacky1307 Aug 12, 2022
311af31
Create asset support episode and sequence
jackyjacky1307 Aug 12, 2022
12f5e20
switch lut when from workio
rebeccaLinx Sep 22, 2022
8d4e6a0
Check for same name asset
jackyjacky1307 Sep 23, 2022
4adb213
compute_session_changes support for ep and seq
jackyjacky1307 Sep 27, 2022
1d15996
Add creator and createTime field
jackyjacky1307 Sep 26, 2022
7705bed
add admin permission and same name validate
jackyjacky1307 Sep 26, 2022
15b7984
add permission hint label
jackyjacky1307 Sep 27, 2022
2703604
support asset_type
jackyjacky1307 Nov 1, 2022
b672bad
show grab info in loader
jackyjacky1307 Oct 19, 2022
c29194a
show grab info in loader and scene inventory
jackyjacky1307 Nov 9, 2022
561eb72
Fix workfile get wrong path
jackyjacky1307 Dec 2, 2022
d7bce93
Add get_publish_path function, can get publish path without using rep…
jackyjacky1307 Jun 22, 2022
3c27f52
Avalon support episode and sequence
jackyjacky1307 Aug 11, 2022
4a6c25b
Avalon episode and sequence env setup
jackyjacky1307 Aug 12, 2022
ef8ad42
Add creator and createTime field
jackyjacky1307 Sep 26, 2022
23aed69
support asset_type
jackyjacky1307 Nov 1, 2022
c806791
show grab info in loader
jackyjacky1307 Oct 19, 2022
2c79d2a
show grab info in loader and scene inventory
jackyjacky1307 Nov 9, 2022
1b9bb84
Loader support renderFrames and renderDuration attribute
jackyjacky1307 Dec 8, 2022
1151465
Add usd icon
rebeccaLinx Dec 15, 2022
b5f32d2
Avalon menu add switch task
jackyjacky1307 Dec 15, 2022
07f6209
Loader support add to shot inventory
jackyjacky1307 Jan 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions avalon/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@

get_representation_context,
update_current_task,
get_session_template_data,
get_publish_path,
get_representation_path,
loaders_from_representation,

Expand Down Expand Up @@ -96,6 +98,8 @@

"get_representation_context",
"update_current_task",
"get_session_template_data",
"get_publish_path",
"get_representation_path",
"loaders_from_representation",

Expand Down
10 changes: 8 additions & 2 deletions avalon/inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def create_project(name):
}).inserted_id


def create_asset(name, silo, data, parent):
def create_asset(name, silo, data, parent, episode, sequence, asset_type):
assert isinstance(parent, io.ObjectId)
if io.find_one({"type": "asset", "name": name}):
raise RuntimeError("%s already exists" % name)
Expand All @@ -116,6 +116,9 @@ def create_asset(name, silo, data, parent):
"schema": "avalon-core:asset-2.0",
"name": name,
"silo": silo,
"episode": episode,
"sequence": sequence,
"asset_type": asset_type,
"parent": parent,
"type": "asset",
"data": data
Expand Down Expand Up @@ -313,7 +316,10 @@ def _save_inventory_1_0(project_name, data):
name=data.pop("name"),
silo=data.pop("silo"),
data=data,
parent=document["_id"]
parent=document["_id"],
episode=data.pop("episode"),
sequence=data.pop("sequence"),
asset_type=data.pop("asset_type")
)

else:
Expand Down
9 changes: 9 additions & 0 deletions avalon/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,15 @@ def _from_environment():
# Name of current Project
("AVALON_PROJECT", None),

# Name of current Episode
("AVALON_EPISODE", None),

# Name of current Sequence
("AVALON_SEQUENCE", None),

# Name of current Asset type
("AVALON_ASSET_TYPE", None),

# Name of current Asset
("AVALON_ASSET", None),

Expand Down
3 changes: 3 additions & 0 deletions avalon/maya/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ def deferred():
enable=False
)

cmds.menuItem("Switch Task",
command=lambda *args: workfiles.show_switch_task(parent=self._parent))

cmds.setParent("..", menu=True)

cmds.menuItem(divider=True)
Expand Down
3 changes: 3 additions & 0 deletions avalon/nuke/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,9 @@ def _install_menu():
# Create menu
menubar = nuke.menu("Nuke")
menu = menubar.addMenu(api.Session["AVALON_LABEL"])
menu.addCommand("Switch Task",
lambda: workfiles.show_switch_task(parent=get_main_window())
)

_add_contextmanager_menu(menu)

Expand Down
23 changes: 23 additions & 0 deletions avalon/nuke/workio.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Host API required Work Files tool"""
import os
import sys
import nuke


Expand Down Expand Up @@ -75,9 +76,31 @@ def open_file(filepath):
nuke.connectViewer(0, viewer)
nuke.callbacks.onScriptLoad()

# Set colorManagement
_set_color_management()

return True


def _set_color_management():
if os.getenv("OCIO"):
# log.info("Setup project color management to OCIO")
# nuke.knob("root.colorManagement", "OCIO")

# region === Switch colorSpace ===
project_name = os.environ.get("AVALON_PROJECT")
show_config_root = os.environ.get("MS_SHOW_CONFIG_ROOT")
if project_name and show_config_root:
project_root = r'{}/ms_show_config/show/s_{}'.format(
show_config_root, project_name)
if os.path.isfile(r'{}/switch_lut.py'.format(project_root)):
sys.path.insert(0, project_root)
import switch_lut
if hasattr(switch_lut, 'switch_viewPort_lut'):
switch_lut.switch_viewPort_lut()
# endregion


def clear_root_user_knobs(tabs=[]):
root_knobs = nuke.Root().allKnobs()

Expand Down
208 changes: 176 additions & 32 deletions avalon/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -1069,11 +1069,14 @@ def compute_session_changes(session, task=None, asset=None, app=None):
# Detect any changes compared session
mapping = {
"AVALON_ASSET": asset,
"AVALON_EPISODE": asset_document.get("episode", ""),
"AVALON_SEQUENCE": asset_document.get("sequence", ""),
"AVALON_ASSET_TYPE": asset_document.get("asset_type", ""),
"AVALON_TASK": task,
"AVALON_APP": app,
}
changes = {key: value for key, value in mapping.items()
if value and value != session.get(key)}
if value is not None and value != session.get(key)}
if not changes:
return changes

Expand Down Expand Up @@ -1155,7 +1158,14 @@ def _format_work_template(template, session=None):
if session is None:
session = Session

return template.format(**{
if session.get("AVALON_SILO") == "Assets":
template = template.replace("{category}", "{asset_type}")
elif session.get("AVALON_SILO") == "Shots":
template = template.replace("{category}", "{episode}/{sequence}")
else:
template = template.replace("{category}", "")

path = template.format(**{
"root": registered_root(),
"project": session["AVALON_PROJECT"],
"asset": session["AVALON_ASSET"],
Expand All @@ -1164,9 +1174,13 @@ def _format_work_template(template, session=None):

# Optional
"silo": session.get("AVALON_SILO"),
"episode": session.get("AVALON_EPISODE", ""),
"sequence": session.get("AVALON_SEQUENCE", ""),
"asset_type": session.get("AVALON_ASSET_TYPE", ""),
"user": session.get("AVALON_USER", getpass.getuser()),
"hierarchy": session.get("AVALON_HIERARCHY"),
})
return os.path.normpath(path).replace('\\', '/')


def _make_backwards_compatible_loader(Loader):
Expand Down Expand Up @@ -1359,6 +1373,164 @@ def switch(container, representation):
return new_loader.switch_form_loader(container, new_representation, loader)


def get_session_template_data():
project = io.find_one({"name": Session["AVALON_PROJECT"], "type": "project"})
project_root = project["data"].get("root")
root = project_root or registered_root()
silo = Session.get("AVALON_SILO", "")

category = ""
if silo == "Assets":
category = Session.get("AVALON_ASSET_TYPE", "")
elif silo == "Shots":
category = "%s/%s" % (Session.get("AVALON_EPISODE", ""), Session.get("AVALON_SEQUENCE", ""))

data = {
"root": root,
"project": Session["AVALON_PROJECT"],
"silo": silo,
"episode": Session.get("AVALON_EPISODE", ""),
"sequence": Session.get("AVALON_SEQUENCE", ""),
"asset_type": Session.get("AVALON_ASSET_TYPE", ""),
"category": category,
"asset": Session.get("AVALON_ASSET", ""),
"task": Session.get("AVALON_TASK", ""),
"subset": "",
"version": "",
"representation": "",
"user": Session.get("AVALON_USER", getpass.getuser()),
"app": Session.get("AVALON_APP", ""),
"hierarchy": Session.get("AVALON_HIERARCHY", ""),
}
return data


def get_publish_path(representation_name, version, subset, asset,
root=None, project=None):
project = project or io.find_one({"name": Session["AVALON_PROJECT"], "type": "project"})
try:
template = project["config"]["template"]["publish"]
except KeyError:
log.debug(
"No template in project %s, "
"likely a bug" % project["name"]
)
return None

project_root = project["data"].get("root")
root = root or project_root or registered_root()

if asset.get("silo") == "Assets":
template = template.replace("{category}", "{asset_type}")
elif asset.get("silo") == "Shots":
template = template.replace("{category}", "{episode}/{sequence}")
else:
template = template.replace("{category}", "")

data = {
"root": root,
"project": project.get("name"),
"asset": asset.get("name"),
"silo": asset.get("silo"),
"episode": asset.get("episode", ""),
"sequence": asset.get("sequence", ""),
"asset_type": asset.get("asset_type", ""),
"subset": subset.get("name"),
"version": version.get("name"),
"representation": representation_name,
"user": Session.get("AVALON_USER", getpass.getuser()),
"app": Session.get("AVALON_APP", ""),
"task": version.get("data", {}).get("task") or Session.get("AVALON_TASK")
}

try:
path = template.format(**data)
except KeyError as e:
log.debug("Template references unavailable data: %s" % e)
return None

return os.path.normpath(path)


def get_session_template_data():
project = io.find_one({"name": Session["AVALON_PROJECT"], "type": "project"})
project_root = project["data"].get("root")
root = project_root or registered_root()
silo = Session.get("AVALON_SILO", "")

category = ""
if silo == "Assets":
category = Session.get("AVALON_ASSET_TYPE", "")
elif silo == "Shots":
category = "%s/%s" % (Session.get("AVALON_EPISODE", ""), Session.get("AVALON_SEQUENCE", ""))

data = {
"root": root,
"project": Session["AVALON_PROJECT"],
"silo": silo,
"episode": Session.get("AVALON_EPISODE", ""),
"sequence": Session.get("AVALON_SEQUENCE", ""),
"asset_type": Session.get("AVALON_ASSET_TYPE", ""),
"category": category,
"asset": Session.get("AVALON_ASSET", ""),
"task": Session.get("AVALON_TASK", ""),
"subset": "",
"version": "",
"representation": "",
"user": Session.get("AVALON_USER", getpass.getuser()),
"app": Session.get("AVALON_APP", ""),
"hierarchy": Session.get("AVALON_HIERARCHY", ""),
}
return data


def get_publish_path(representation_name, version, subset, asset,
root=None, project=None):
project = project or io.find_one({"name": Session["AVALON_PROJECT"], "type": "project"})
try:
template = project["config"]["template"]["publish"]
except KeyError:
log.debug(
"No template in project %s, "
"likely a bug" % project["name"]
)
return None

project_root = project["data"].get("root")
root = root or project_root or registered_root()

if asset.get("silo") == "Assets":
template = template.replace("{category}", "{asset_type}")
elif asset.get("silo") == "Shots":
template = template.replace("{category}", "{episode}/{sequence}")
else:
template = template.replace("{category}", "")

data = {
"root": root,
"project": project.get("name"),
"asset": asset.get("name"),
"silo": asset.get("silo"),
"episode": asset.get("episode", ""),
"sequence": asset.get("sequence", ""),
"asset_type": asset.get("asset_type", ""),
"subset": subset.get("name"),
"version": version.get("name"),
"representation": representation_name,
"user": Session.get("AVALON_USER", getpass.getuser()),
"app": Session.get("AVALON_APP", ""),
"task": version.get("data", {}).get("task") or Session.get("AVALON_TASK")
}

try:
path = template.format(**data)
except KeyError as e:
log.debug("Template references unavailable data: %s" % e)
return None

return os.path.normpath(path)


def get_representation_path(representation):
"""Get filename from representation document

Expand Down Expand Up @@ -1406,37 +1578,9 @@ def path_from_config():
)
return None

try:
template = project["config"]["template"]["publish"]
except KeyError:
log.debug(
"No template in project %s, "
"likely a bug" % project["name"]
)
return None

# Cannot fail, required members only
data = {
"root": registered_root(),
"project": project["name"],
"asset": asset["name"],
"silo": asset.get("silo"),
"subset": subset["name"],
"version": version_["name"],
"representation": representation["name"],
"user": Session.get("AVALON_USER", getpass.getuser()),
"app": Session.get("AVALON_APP", ""),
"task": Session.get("AVALON_TASK", "")
}
repr_root = representation["data"].get("reprRoot")

try:
path = template.format(**data)
except KeyError as e:
log.debug("Template references unavailable data: %s" % e)
return None

if os.path.exists(path):
return os.path.normpath(path)
return get_publish_path(representation["name"], version_, subset, asset, root=repr_root, project=project)

def path_from_data():
if "path" not in representation["data"]:
Expand Down
12 changes: 12 additions & 0 deletions avalon/schema/asset-2.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@
"description": "Unique identifier to parent document",
"example": "592c33475f8c1b064c4d1696"
},
"episode": {
"description": "Unique identifier to episode document",
"example": "592c33475f8c1b064c4d1696"
},
"sequence": {
"description": "Unique identifier to sequence document",
"example": "592c33475f8c1b064c4d1696"
},
"asset_type": {
"description": "Unique identifier to asset_type document",
"example": "592c33475f8c1b064c4d1696"
},
"name": {
"description": "Name of asset",
"type": "string",
Expand Down
Loading