mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
add connect ornatrix rig options into the scene inventory
This commit is contained in:
parent
a56e4f7ec7
commit
89d1e61bb1
4 changed files with 129 additions and 3 deletions
|
|
@ -0,0 +1,124 @@
|
|||
import os
|
||||
import json
|
||||
from collections import defaultdict
|
||||
|
||||
from maya import cmds, mel
|
||||
|
||||
from ayon_core.pipeline import (
|
||||
InventoryAction,
|
||||
get_repres_contexts,
|
||||
get_representation_path,
|
||||
)
|
||||
|
||||
|
||||
class ConnectOrnatrixRig(InventoryAction):
|
||||
"""Connect Ornatrix Rig with an animation or pointcache."""
|
||||
|
||||
label = "Connect Ornatrix Rig"
|
||||
icon = "link"
|
||||
color = "white"
|
||||
|
||||
def process(self, containers):
|
||||
# Categorize containers by product type.
|
||||
containers_by_product_type = defaultdict(list)
|
||||
repre_ids = {
|
||||
container["representation"]
|
||||
for container in containers
|
||||
}
|
||||
repre_contexts_by_id = get_repres_contexts(repre_ids)
|
||||
for container in containers:
|
||||
repre_id = container["representation"]
|
||||
repre_context = repre_contexts_by_id[repre_id]
|
||||
|
||||
product_type = repre_context["product"]["productType"]
|
||||
|
||||
containers_by_product_type.setdefault(product_type, [])
|
||||
containers_by_product_type[product_type].append(container)
|
||||
|
||||
# Validate to only 1 source container.
|
||||
source_containers = containers_by_product_type.get("animation", [])
|
||||
source_containers += containers_by_product_type.get("pointcache", [])
|
||||
source_container_namespaces = [
|
||||
x["namespace"] for x in source_containers
|
||||
]
|
||||
message = (
|
||||
"{} animation containers selected:\n\n{}\n\nOnly select 1 of type "
|
||||
"\"animation\" or \"pointcache\".".format(
|
||||
len(source_containers), source_container_namespaces
|
||||
)
|
||||
)
|
||||
if len(source_containers) != 1:
|
||||
self.display_warning(message)
|
||||
return
|
||||
|
||||
source_container = source_containers[0]
|
||||
source_repre_id = source_container["representation"]
|
||||
source_namespace = source_container["namespace"]
|
||||
|
||||
# Validate source representation is an alembic.
|
||||
source_path = get_representation_path(
|
||||
repre_contexts_by_id[source_repre_id]["representation"]
|
||||
).replace("\\", "/")
|
||||
message = "Animation container \"{}\" is not an alembic:\n{}".format(
|
||||
source_container["namespace"], source_path
|
||||
)
|
||||
if not source_path.endswith(".abc"):
|
||||
self.display_warning(message)
|
||||
return
|
||||
|
||||
ox_rig_containers = containers_by_product_type.get("oxrig")
|
||||
if not ox_rig_containers:
|
||||
self.display_warning(
|
||||
"Select at least one oxrig container"
|
||||
)
|
||||
return
|
||||
source_nodes = []
|
||||
for container in ox_rig_containers:
|
||||
repre_id = container["representation"]
|
||||
maya_file = get_representation_path(
|
||||
repre_contexts_by_id[repre_id]["representation"]
|
||||
)
|
||||
_, ext = os.path.splitext(maya_file)
|
||||
settings_file = maya_file.replace(
|
||||
ext, ".rigsettings")
|
||||
if not os.path.exists(settings_file):
|
||||
continue
|
||||
with open(settings_file, "w") as fp:
|
||||
source_nodes.extend(
|
||||
item.get("node") for item in json.load(fp))
|
||||
grooms_file = maya_file.replace(ext, ".oxg.yaml")
|
||||
# Compare loaded connections to scene.
|
||||
for node in source_nodes:
|
||||
target_node = cmds.ls(f"{source_namespace}:{node}")[0]
|
||||
if not target_node:
|
||||
self.display_warning(
|
||||
"No target node found "
|
||||
"in \"animation\" or \"pointcache\"."
|
||||
)
|
||||
return
|
||||
mel.eval(f"OxLoadGroom -path \"{grooms_file}\";")
|
||||
|
||||
def display_warning(self, message, show_cancel=False):
|
||||
"""Show feedback to user.
|
||||
|
||||
Returns:
|
||||
bool
|
||||
"""
|
||||
|
||||
from qtpy import QtWidgets
|
||||
|
||||
accept = QtWidgets.QMessageBox.Ok
|
||||
if show_cancel:
|
||||
buttons = accept | QtWidgets.QMessageBox.Cancel
|
||||
else:
|
||||
buttons = accept
|
||||
|
||||
state = QtWidgets.QMessageBox.warning(
|
||||
None,
|
||||
"",
|
||||
message,
|
||||
buttons=buttons,
|
||||
defaultButton=accept
|
||||
)
|
||||
|
||||
return state == accept
|
||||
|
|
@ -33,7 +33,7 @@ class OxOrnatrixGrooms(plugin.Loader):
|
|||
|
||||
path = self.filepath_from_context(context)
|
||||
# TODO: load Ox Grooms
|
||||
nodes = [mel.eval(f'OxLoadGroom -path "{path}";')]
|
||||
nodes = [mel.eval(f"OxLoadGroom -path \"{path}\";")]
|
||||
|
||||
group_name = "{}:{}".format(namespace, name)
|
||||
group_node = cmds.group(nodes, name=group_name)
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ class CollectOxRig(plugin.MayaInstancePlugin):
|
|||
"(searched: %s)" % (texture))
|
||||
|
||||
item = {
|
||||
"node": node,
|
||||
"files": files,
|
||||
"source": texture,
|
||||
"texture_attribute": texture_attr
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class ExtractOxRig(plugin.MayaExtractorPlugin):
|
|||
|
||||
# Define extract output file path
|
||||
dirname = self.staging_dir(instance)
|
||||
settings_path = os.path.join(dirname, "ornatrix.rigsettings")
|
||||
settings_path = os.path.join(dirname, "ornatrix_rig.rigsettings")
|
||||
image_search_path = instance.data["resourcesDir"]
|
||||
|
||||
# add textures to transfers
|
||||
|
|
@ -89,6 +89,7 @@ class ExtractOxRig(plugin.MayaExtractorPlugin):
|
|||
preserveReferences=False,
|
||||
constructionHistory=True,
|
||||
shader=False)
|
||||
# save the groom presets
|
||||
mel.eval(f'OxSaveGroom -path "{ox_groom_path}"')
|
||||
|
||||
# Ensure files can be stored
|
||||
|
|
@ -106,7 +107,7 @@ class ExtractOxRig(plugin.MayaExtractorPlugin):
|
|||
}
|
||||
)
|
||||
|
||||
self.log.debug("OxGroom file: {}".format(ox_groom_path))
|
||||
self.log.debug("OxGrooms file: {}".format(ox_groom_path))
|
||||
instance.data["representations"].append(
|
||||
{
|
||||
'name': "yaml",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue